?? usbaer.c
字號:
/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
Usbaer.c
Abstract:
IOS port driver for USB LS-120 drive
Async Event Handler module
Environment:
kernel mode only
Notes:
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
PURPOSE.
Copyright (c) 1999 Microsoft Corporation. All Rights Reserved.
Revision History:
03/19/99: MRB Original
--*/
#define WANTVXDWRAPS
#include <basedef.h>
#include <vmm.h>
#include <debug.h>
#include <vxdwraps.h>
#include <winerror.h>
#include <aep.h>
#include <drp.h>
#include <isp.h>
#include <ior.h>
#include <iop.h>
#include <dcb.h>
#include <ilb.h>
#include <configmg.h>
#include <ntkern.h>
#include "usbstor.h"
#include "usbdebug.h"
#pragma VxD_LOCKED_CODE_SEG
#pragma VxD_LOCKED_DATA_SEG
BYTE DcbCount=0;
void
USBSTOR_AER (
PAEP Aep
)
{
/*++
Routine Description:
Asychronous event handler.
Arguments:
Aep - Asychronous Event Packet. Structure varies depending
on AER type.
Return Value:
Status returned in Aep->AEP_result
--*/
USBSTOR_DebugPrintf(DBG_MAX, ("Enter USBSTOR_AER\n\r"));
// presume success
Aep->AEP_result = AEP_SUCCESS;
switch (Aep->AEP_func)
{
case AEP_INITIALIZE:
USBSTOR_DebugPrintf(DBG_MAX, ("AEP_INITIALIZE\n\r"));
Aep->AEP_result = USBSTOR_AEP_Init((PAEP_bi_init)Aep);
break;
case AEP_UNINITIALIZE:
USBSTOR_DebugPrintf(DBG_MAX, ("AEP_UNINITIALIZE\n\r"));
break;
case AEP_DEVICE_INQUIRY:
USBSTOR_DebugPrintf(DBG_MAX, ("AEP_DEVICE_INQUIRY\n\r"));
Aep->AEP_result = USBSTOR_Device_Inquiry((PAEP_inquiry_device)Aep);
// Make sure we didn't record the inquiry DCB in our DDB. If we did,
// erase it and decrement our DCB count.
if (((PAEP_inquiry_device)Aep)->AEP_i_d_dcb == ((PUSBDDB)Aep->AEP_ddb)->Dcb1)
{
((PUSBDDB)Aep->AEP_ddb)->Dcb1 = NULL;
DcbCount--;
}
else if (((PAEP_inquiry_device)Aep)->AEP_i_d_dcb == ((PUSBDDB)Aep->AEP_ddb)->Dcb2)
{
((PUSBDDB)Aep->AEP_ddb)->Dcb2 = NULL;
DcbCount--;
}
break;
case AEP_CONFIG_DCB:
USBSTOR_DebugPrintf(DBG_MAX, ("AEP_CONFIG_DCB\n\r"));
Aep->AEP_result = USBSTOR_Config_DCB((PAEP_dcb_config)Aep);
if (AEP_SUCCESS == Aep->AEP_result)
{
// Store the DCB in our DDB
if (((PUSBDDB)Aep->AEP_ddb)->Dcb1 == NULL)
{
((PUSBDDB)Aep->AEP_ddb)->Dcb1 = ((PAEP_dcb_config)Aep)->AEP_d_c_dcb;
DcbCount++;
}
else if (((PUSBDDB)Aep->AEP_ddb)->Dcb2 == NULL)
{
((PUSBDDB)Aep->AEP_ddb)->Dcb2 = ((PAEP_dcb_config)Aep)->AEP_d_c_dcb;
DcbCount++;
}
else
{
USBSTOR_DebugPrintf(DBG_MIN, ("ERROR! - Configured more DCBs than we expected\n\r"));
USBSTOR_DebugPrintf(DBG_MIN, (" This should not happen!\n\r"));
}
}
break;
case AEP_UNCONFIG_DCB:
USBSTOR_DebugPrintf(DBG_MAX, ("AEP_UNCONFIG_DCB\n\r"));
{
DWORD pdcb = ((PAEP_dcb_unconfig)Aep)->AEP_d_u_dcb;
PUSBDDB UsbDdb = (PUSBDDB)Aep->AEP_ddb;
// Make sure it's our DCB
if (UsbDdb->Dcb1 == pdcb)
{
//Zero out Dcb field
UsbDdb->Dcb1 = NULL;
DcbCount--;
}
else if (UsbDdb->Dcb2 == pdcb)
{
//Zero out Dcb field
UsbDdb->Dcb2 = NULL;
DcbCount--;
}
}
break;
case AEP_IOP_TIMEOUT:
USBSTOR_DebugPrintf(DBG_MAX, ("AEP_IOP_TIMEOUT\n\r"));
break;
case AEP_1_SEC:
USBSTOR_DebugPrintf(DBG_MAX, ("AEP_1_SEC\n\r"));
break;
#ifdef DEBUG
case AEP_DBG_DOT_CMD:
USBSTOR_DebugPrintf(DBG_MAX, ("AEP_DBG_DOT_CMD\n\r"));
break;
#endif
case AEP_BOOT_COMPLETE:
USBSTOR_DebugPrintf(DBG_MAX, ("AEP_BOOT_COMPLETE\n\r"));
if (0 == DcbCount)
Aep->AEP_result = AEP_FAILURE;
break;
default:
USBSTOR_DebugPrintf(DBG_DEFAULT, ("Unhandled AEP - %x\n\r",Aep->AEP_func));
Aep->AEP_result = AEP_FAILURE;
break;
} // end switch on AEP function
return;
}
USHORT
USBSTOR_AEP_Init(
PAEP_bi_init Aep
)
{
/*++
Routine Description:
Initialization routine.
Arguments:
Aep - AEP_bi_init structure.
Return Value:
AEP_SUCCESS if successful,
AEP_FAILURE otherwise
--*/
DWORD Pdo, Fdo=0;
DEVNODE ParentDevNode;
ISP_ddb_create Isp;
PUSBDDB UsbDdb;
// We need to find the FDO created by USBLS120.SYS for the USB storage
// device. This will be passed as a parameter to USBLS120.SYS when we
// do I/O calls so it knows which device to talk to.
// To identify the correct FDO, we call an exported function in
// USBLS120.SYS that enumerates each PDO/FDO pair attached to USBLS120.SYS.
// We can then use an exported service from NTKERN.VXD to translate
// the PDO to a DevNode handle, and compare it to our parent's DevNode
// handle (we are loaded via a psuedo-child device created by USBLS120.SYS,
// so our parent is the real USB device).
// First, get our parent's DevNode handle
if (CM_Get_Parent(&ParentDevNode, (DEVNODE)Aep->AEP_bi_i_hdevnode, 0) != CR_SUCCESS)
{
USBSTOR_DebugPrintf(DBG_MIN, ("Can't find our parent DevNode!\n\r"));
return AEP_FAILURE;
}
//Loop thru all the PDO/FDO pairs looking for a match to our parent DevNode
while ((Pdo = pfnGetNextPdo(&Fdo)) && (_NtKernPhysicalDeviceObjectToDevNode(Pdo) != ParentDevNode));
if (!Pdo)
{
USBSTOR_DebugPrintf(DBG_MIN, ("Can't PDO for our parent DevNode!\n\r"));
return AEP_FAILURE;
}
// Found our PDO, so allocate our DDB
Isp.ISP_ddb_hdr.ISP_func = ISP_CREATE_DDB;
Isp.ISP_ddb_size = sizeof(USBDDB);
Isp.ISP_ddb_flags = 0;
ILBService(&Isp);
if (Isp.ISP_ddb_hdr.ISP_result)
{
USBSTOR_DebugPrintf(DBG_MIN, ("Can't allocate DDB!\n\r"));
return AEP_FAILURE;
}
UsbDdb = (PUSBDDB)(Isp.ISP_ddb_ptr);
// Store pertinent information in our DDB.
UsbDdb->Ddb.DDB_number_buses = 1;
UsbDdb->Ddb.DDB_devnode_ptr = Aep->AEP_bi_i_hdevnode;
UsbDdb->Fdo = Fdo;
UsbDdb->Flags = 0;
// Register our I/O completion handler with USBLS120.SYS
pfnRegisterCompletionHandler(Fdo, USBSTOR_CompleteRequest);
return AEP_SUCCESS;
}
USHORT
USBSTOR_Config_DCB(
PAEP_dcb_config Aep
)
{
/*++
Routine Description:
Configuration handler for new DCBs.
Arguments:
Aep - AEP_dcb_config structure.
Return Value:
Aep->AEP_result = AEP_SUCCESS if successful,
Aep->AEP_result = AEP_FAILURE otherwise
--*/
PDCB Dcb;
ISP_calldown_insert Isp;
Dcb = (PDCB)Aep->AEP_d_c_dcb;
//Set maximum scatter gather elements to 17
Dcb->DCB_max_sg_elements = 17;
//Set max transfer size to 64k
Dcb->DCB_max_xfer_len = 0x10000;
// DCB_DEV2_IDE_FLOPTICAL is set specifically if we are a
// LS-120 device. This flag tells DISKVSD.VXD to special
// handle this drive. It causes the device type to change
// from a hard-disk to a floppy.
// This flag should only be set for LS-120 devices, as it
// relies on capacity information being returned in the
// vendor specific INQUIRY data, and assumes SFF-8070i
// compatibility. Devices that wish to appear as normal
// hard-drives should *not* set the DCB_DEV2_IDE_FLOPTICAL
// flag.
Dcb->DCB_cmn.DCB_device_flags2 |= DCB_DEV2_ATAPI_DEVICE |
DCB_DEV2_IDE_FLOPTICAL;
// Insert ourselves into the calldown stack for this device
Isp.ISP_i_cd_hdr.ISP_func = ISP_INSERT_CALLDOWN;
Isp.ISP_i_cd_dcb = (ULONG)Dcb;
Isp.ISP_i_cd_req = USBSTOR_Request;
Isp.ISP_i_cd_expan_len = 0;
Isp.ISP_i_cd_lgn = Aep->AEP_d_c_hdr.AEP_lgn;
Isp.ISP_i_cd_ddb = (ULONG)Aep->AEP_d_c_hdr.AEP_ddb;
//BUGBUG - what are the correct flags for this device?
Isp.ISP_i_cd_flags = DCB_dmd_srb_cdb |
DCB_dmd_pageability;
// Call IOS
ILBService(&Isp);
return AEP_SUCCESS;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -