[USBSTOR]

- Add error handling to USBSTOR_CSWCompletionRoutine for errors that can be recovered via reset of pipe/port/controller. Only pipe reset is attempted. WIP.

svn path=/branches/usb-bringup/; revision=51808
This commit is contained in:
Michael Martin 2011-05-17 11:26:25 +00:00
parent a5d0b5fdef
commit ff208f7adb
3 changed files with 83 additions and 6 deletions

View file

@ -103,7 +103,7 @@ USBSTOR_HandleTransferError(
break;
}
DPRINT1("Failed to reset pipe %x\n");
DPRINT1("Failed to reset pipe %x\n", Status);
//
// FIXME: Reset of pipe failed, attempt to reset port

View file

@ -102,6 +102,9 @@ USBSTOR_CSWCompletionRoutine(
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);
@ -153,16 +156,75 @@ USBSTOR_CSWCompletionRoutine(
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
//

View file

@ -35,6 +35,9 @@
((((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,
@ -278,6 +281,13 @@ typedef struct
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;
//---------------------------------------------------------------------
@ -424,6 +434,11 @@ VOID
USBSTOR_QueueInitialize(
PFDO_DEVICE_EXTENSION FDODeviceExtension);
VOID
NTAPI
ErrorHandlerWorkItemRoutine(
PVOID Context);
VOID
USBSTOR_QueueNextRequest(
IN PDEVICE_OBJECT DeviceObject);
@ -431,4 +446,4 @@ USBSTOR_QueueNextRequest(
VOID
USBSTOR_QueueTerminateRequest(
IN PDEVICE_OBJECT DeviceObject,
IN BOOLEAN ModifySrbState);
IN BOOLEAN ModifySrbState);