?? usbio.c
字號:
--*/
DWORD DeviceObject;
PDCB Dcb;
PIOR Ior;
PUSBDDB Ddb;
SCSI_REQUEST_BLOCK *Srb;
PIOPACKET IoPacket;
USBSTOR_DebugPrintf(DBG_MAX, ("Enter USBSTOR_StartIo()\n"));
DeviceObject = (DWORD)((pDCB_cd_entry)Iop->IOP_calldown_ptr)->DCB_cd_ddb;
Dcb = (PDCB)Iop->IOP_physical_dcb;
Ddb = (PUSBDDB)((pDCB_cd_entry)Iop->IOP_calldown_ptr)->DCB_cd_ddb;
Ior = &(Iop->IOP_ior);
Srb = (PSCSI_REQUEST_BLOCK)Iop->IOP_srb;
// Get address of IOPACKET that we send to WDM driver
IoPacket = &(Ddb->IoPacket);
USBSTOR_DebugPrintf(DBG_MAX, ("USBSTOR_StartIo - IOP=%x, IOPACKET=%x\n", Iop, IoPacket));
if (Ior->IOR_flags & IORF_SRB_VALID)
{
USBSTOR_DebugPrintf(DBG_MAX, ("Calling WDM driver\n"));
Srb->DataBuffer = (PVOID)Ior->IOR_buffer_ptr;
// Populate the IOPACKET structure
IoPacket->Fdo = Ddb->Fdo;
IoPacket->Cdb = Srb->Cdb;
IoPacket->CdbLength = Srb->CdbLength;
IoPacket->DataBuffer = Srb->DataBuffer;
IoPacket->DataLength = Srb->DataTransferLength;
IoPacket->Iop = (PVOID)Iop;
IoPacket->Flags = 0;
IoPacket->Status = IO_STATUS_PENDING;
IoPacket->BlockSize = Dcb->DCB_bdd.DCB_apparent_blk_size;
if (Ior->IOR_flags & IORF_SCATTER_GATHER)
IoPacket->Flags |= IO_FLAGS_SCATTER_GATHER;
if (Srb->SrbFlags & SRB_FLAGS_DATA_IN)
IoPacket->Flags |= IO_FLAGS_DATA_IN;
else if (Srb->SrbFlags & SRB_FLAGS_DATA_OUT)
IoPacket->Flags |= IO_FLAGS_DATA_OUT;
// Call WDM driver
pfnStartRequest(IoPacket);
}
else
{
USBSTOR_DebugPrintf(DBG_DEFAULT, ("IOP with no SRB, IOR_func=%x\n",
Ior->IOR_func));
// We only handle request with valid SRBs
Ior->IOR_status = IORS_INVALID_COMMAND;
USBSTOR_CompleteIOP(Iop);
}
}
void _stdcall
USBSTOR_CompleteRequest(
PIOPACKET IoPacket
)
{
/*++
Routine Description:
I/O completion handler for the USB device.
Arguments:
IoPacket - IOPACKET containing request info
Return Value:
None
--*/
PSCSI_REQUEST_BLOCK Srb;
PUSBDDB Ddb;
int i;
pIOP Iop;
USBSTOR_DebugPrintf(DBG_MAX, ("Enter USBSTOR_CompleteRequest\n"));
Iop = (pIOP)IoPacket->Iop;
Ddb = (PUSBDDB)((pDCB_cd_entry)Iop->IOP_calldown_ptr)->DCB_cd_ddb;
Srb = (PSCSI_REQUEST_BLOCK)Iop->IOP_srb;
USBSTOR_DebugPrintf(DBG_MAX, ("USBSTOR_CompleteRequest - IOP=%x, IOPACKET=%x\n", Iop, IoPacket));
// Are we completing a REQUEST SENSE command?
if (Ddb->Flags & USBDDB_FLAG_ERROR)
{
USBSTOR_DebugPrintf(DBG_MAX, ("REQUEST SENSE complete\n"));
if (IoPacket->Status == IO_STATUS_DEVICE_ERROR)
{
USBSTOR_DebugPrintf(DBG_MIN, ("REQUEST SENSE Failed!\n"));
// Our request sense failed, so just return error without
// sense data.
Srb->SrbStatus = SRB_STATUS_ERROR;
Trap();
}
else
if (IoPacket->Status == IO_STATUS_SUCCESS)
{
//BUGBUG - put in debug code to dump sense info
Srb->SrbStatus = SRB_STATUS_ERROR | SRB_STATUS_AUTOSENSE_VALID;
}
Ddb->Flags &= ~USBDDB_FLAG_ERROR;
}
// Normal I/O request
else switch (IoPacket->Status)
{
case IO_STATUS_DEVICE_ERROR:
USBSTOR_DebugPrintf(DBG_DEFAULT, ("I/O request failed\n"));
// Call error handler for REQUEST SENSE handling
USBSTOR_ErrorHandler(Iop);
return;
case IO_STATUS_OUT_OF_MEMORY:
USBSTOR_DebugPrintf(DBG_MIN, ("I/O request failed with memory error\n"));
Srb->SrbStatus = SRB_STATUS_ERROR;
Trap();
break;
case IO_STATUS_SUCCESS:
USBSTOR_DebugPrintf(DBG_MAX, ("I/O request succeeded\n"));
// I/O request succeeded
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
default:
USBSTOR_DebugPrintf(DBG_MIN, ("Unknown error occurred!\n"));
// This should never happen
Srb->SrbStatus = SRB_STATUS_ERROR;
Trap();
}
// Complete the request
USBSTOR_CompleteIOP(Iop);
}
VOID
USBSTOR_ErrorHandler(
pIOP Iop
)
{
/*++
Routine Description:
Error handler for failed I/O requests. Will send a REQUEST SENSE
command to the device to find out why it failed, if SRB indicates
autosense.
Arguments:
Iop - IOP for failed request
Return Value:
None
--*/
SCSI_REQUEST_BLOCK *Srb;
PUSBDDB Ddb;
PIOPACKET IoPacket;
USBSTOR_DebugPrintf(DBG_DEFAULT, ("Enter USBSTOR_ErrorHandler()\n"));
Srb = (PSCSI_REQUEST_BLOCK)Iop->IOP_srb;
Ddb = (PUSBDDB)((pDCB_cd_entry)Iop->IOP_calldown_ptr)->DCB_cd_ddb;
if (Srb->SrbFlags & SRB_FLAGS_DISABLE_AUTOSENSE)
{
// Client does not want sense data, so just set error status
// and complete the request.
Srb->SrbStatus = SRB_STATUS_ERROR;
// Complete the request
USBSTOR_CompleteIOP(Iop);
return;
}
if ((NULL == Srb->SenseInfoBuffer) || (0 == Srb->SenseInfoBufferLength))
{
USBSTOR_DebugPrintf(DBG_MIN, ("Invalid Sense Info buffer\n"));
// Invalid Sense Info buffer without the
// SRB_FLAGS_DISABLE_AUTOSENSE flag. This shouldn't happen.
Srb->SrbStatus = SRB_STATUS_ERROR;
Trap();
// Complete the request
USBSTOR_CompleteIOP(Iop);
return;
}
// Indicate that we are processing an error
Ddb->Flags |= USBDDB_FLAG_ERROR;
// Build a REQUEST SENSE CDB
Ddb->Cdb[0] = SCSIOP_REQUEST_SENSE;
Ddb->Cdb[1] = 0x00;
Ddb->Cdb[2] = 0x00;
Ddb->Cdb[3] = 0x00;
Ddb->Cdb[4] = Srb->SenseInfoBufferLength;
Ddb->Cdb[5] = 0x00;
Ddb->Cdb[6] = 0x00;
Ddb->Cdb[7] = 0x00;
Ddb->Cdb[8] = 0x00;
Ddb->Cdb[9] = 0x00;
Ddb->Cdb[10] = 0x00;
Ddb->Cdb[11] = 0x00;
IoPacket = &(Ddb->IoPacket);
// Populate the IOPACKET structure sent to our WDM driver
IoPacket->Fdo = Ddb->Fdo;
IoPacket->Cdb = Ddb->Cdb;
IoPacket->CdbLength = 12;
IoPacket->DataBuffer = Srb->SenseInfoBuffer;
IoPacket->DataLength = Srb->SenseInfoBufferLength;
IoPacket->Iop = (PVOID)Iop;
IoPacket->Flags = IO_FLAGS_DATA_IN;
IoPacket->Status = IO_STATUS_PENDING;
IoPacket->BlockSize = 512;
// Call the WDM driver
pfnStartRequest(IoPacket);
}
VOID
USBSTOR_CompleteIOP(
pIOP Iop
)
{
/*++
Routine Description:
Completes IOP request
Arguments:
Iop - IOP to complete
Return Value:
None
--*/
IOP_callback_entry * IopCB;
pIOP NextIop;
PUSBDDB Ddb;
PDCB Dcb;
USBSTOR_DebugPrintf(DBG_MAX, ("Enter USBSTOR_CompleteIOP\n"));
Ddb = (PUSBDDB)((pDCB_cd_entry)Iop->IOP_calldown_ptr)->DCB_cd_ddb;
Dcb = (PDCB)Iop->IOP_physical_dcb;
// Find address of first callback handler
Iop->IOP_callback_ptr -= sizeof (IOP_callback_entry);
IopCB = (IOP_callback_entry *)(Iop->IOP_callback_ptr);
// Complete the IOP by calling the first entry in the callback chain
SaveEbx();
IOPCallBack(IopCB, Iop);
RestoreEbx();
// We are no longer busy
Ddb->Flags &= ~USBDDB_FLAG_BUSY;
// See if there are any queued requests
NextIop = ILBDequeueIop(Dcb);
if (NextIop)
{
Ddb->Flags |= USBDDB_FLAG_BUSY;
// There is a queued IOP, so go process it
USBSTOR_StartIo(NextIop);
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -