PREAD_CAPACITY_DATA_EX CapacityDataEx;
PREAD_CAPACITY_DATA CapacityData;
PUFI_CAPACITY_RESPONSE Response;
+ PERRORHANDLER_WORKITEM_DATA ErrorHandlerWorkItemData;
+ NTSTATUS Status;
+ PURB Urb;
DPRINT("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
ASSERT(Request);
- //
- // FIXME: check status
- //
- Request->SrbStatus = SRB_STATUS_SUCCESS;
+ Status = Irp->IoStatus.Status;
+
+ Urb = &Context->Urb;
//
// get SCSI command data block
//
pCDB = (PCDB)Request->Cdb;
+ //
+ // check status
+ //
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Status %x\n", Status);
+ DPRINT1("UrbStatus %x\n", Urb->UrbHeader.Status);
+
+ //
+ // Check for errors that can be handled
+ // FIXME: Verify all usb errors that can be recovered via pipe reset/port reset/controller reset
+ //
+ if ((Urb->UrbHeader.Status & USB_RECOVERABLE_ERRORS) == Urb->UrbHeader.Status)
+ {
+ DPRINT1("Attempting Error Recovery\n");
+ //
+ // If a Read Capacity Request free TransferBuffer
+ //
+ if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
+ {
+ FreeItem(Context->TransferData);
+ }
+
+ //
+ // Clean up the rest
+ //
+ FreeItem(Context->cbw);
+ FreeItem(Context);
+
+ //
+ // Allocate Work Item Data
+ //
+ ErrorHandlerWorkItemData = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERRORHANDLER_WORKITEM_DATA), USB_STOR_TAG);
+ if (!ErrorHandlerWorkItemData)
+ {
+ DPRINT1("Failed to allocate memory\n");
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ //
+ // Initialize and queue the work item to handle the error
+ //
+ ExInitializeWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem,
+ ErrorHandlerWorkItemRoutine,
+ ErrorHandlerWorkItemData);
+
+ ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject;
+ ErrorHandlerWorkItemData->Irp = Irp;
+ ErrorHandlerWorkItemData->Context = Context;
+ DPRINT1("Queuing WorkItemROutine\n");
+ ExQueueWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem, DelayedWorkQueue);
+
+ return STATUS_MORE_PROCESSING_REQUIRED;
+ }
+ }
+ }
+
+ Request->SrbStatus = SRB_STATUS_SUCCESS;
+
//
// read capacity needs special work
//
((((unsigned long)(n) & 0xFF0000)) >> 8) | \
((((unsigned long)(n) & 0xFF000000)) >> 24))
+#define USB_RECOVERABLE_ERRORS (USBD_STATUS_STALL_PID | USBD_STATUS_DEV_NOT_RESPONDING \
+ | USBD_STATUS_ENDPOINT_HALTED | USBD_STATUS_NO_BANDWIDTH)
+
NTSTATUS NTAPI
IoAttachDeviceToDeviceStackSafe(
IN PDEVICE_OBJECT SourceDevice,
PKEVENT Event;
}IRP_CONTEXT, *PIRP_CONTEXT;
+typedef struct _ERRORHANDLER_WORKITEM_DATA
+{
+ PDEVICE_OBJECT DeviceObject;
+ PIRP Irp;
+ PIRP_CONTEXT Context;
+ WORK_QUEUE_ITEM WorkQueueItem;
+} ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA;
//---------------------------------------------------------------------
USBSTOR_QueueInitialize(
PFDO_DEVICE_EXTENSION FDODeviceExtension);
+VOID
+NTAPI
+ErrorHandlerWorkItemRoutine(
+ PVOID Context);
+
VOID
USBSTOR_QueueNextRequest(
IN PDEVICE_OBJECT DeviceObject);
VOID
USBSTOR_QueueTerminateRequest(
IN PDEVICE_OBJECT DeviceObject,
- IN BOOLEAN ModifySrbState);
\ No newline at end of file
+ IN BOOLEAN ModifySrbState);