mirror of
https://github.com/reactos/reactos.git
synced 2024-10-07 18:04:41 +00:00
[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:
parent
a5d0b5fdef
commit
ff208f7adb
|
@ -103,7 +103,7 @@ USBSTOR_HandleTransferError(
|
||||||
break;
|
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
|
// FIXME: Reset of pipe failed, attempt to reset port
|
||||||
|
|
|
@ -102,6 +102,9 @@ USBSTOR_CSWCompletionRoutine(
|
||||||
PREAD_CAPACITY_DATA_EX CapacityDataEx;
|
PREAD_CAPACITY_DATA_EX CapacityDataEx;
|
||||||
PREAD_CAPACITY_DATA CapacityData;
|
PREAD_CAPACITY_DATA CapacityData;
|
||||||
PUFI_CAPACITY_RESPONSE Response;
|
PUFI_CAPACITY_RESPONSE Response;
|
||||||
|
PERRORHANDLER_WORKITEM_DATA ErrorHandlerWorkItemData;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PURB Urb;
|
||||||
|
|
||||||
DPRINT("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
|
DPRINT("USBSTOR_CSWCompletionRoutine Irp %p Ctx %p\n", Irp, Ctx);
|
||||||
|
|
||||||
|
@ -153,16 +156,75 @@ USBSTOR_CSWCompletionRoutine(
|
||||||
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
|
Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
|
||||||
ASSERT(Request);
|
ASSERT(Request);
|
||||||
|
|
||||||
//
|
Status = Irp->IoStatus.Status;
|
||||||
// FIXME: check status
|
|
||||||
//
|
Urb = &Context->Urb;
|
||||||
Request->SrbStatus = SRB_STATUS_SUCCESS;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// get SCSI command data block
|
// get SCSI command data block
|
||||||
//
|
//
|
||||||
pCDB = (PCDB)Request->Cdb;
|
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
|
// read capacity needs special work
|
||||||
//
|
//
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
((((unsigned long)(n) & 0xFF0000)) >> 8) | \
|
((((unsigned long)(n) & 0xFF0000)) >> 8) | \
|
||||||
((((unsigned long)(n) & 0xFF000000)) >> 24))
|
((((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
|
NTSTATUS NTAPI
|
||||||
IoAttachDeviceToDeviceStackSafe(
|
IoAttachDeviceToDeviceStackSafe(
|
||||||
IN PDEVICE_OBJECT SourceDevice,
|
IN PDEVICE_OBJECT SourceDevice,
|
||||||
|
@ -278,6 +281,13 @@ typedef struct
|
||||||
PKEVENT Event;
|
PKEVENT Event;
|
||||||
}IRP_CONTEXT, *PIRP_CONTEXT;
|
}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(
|
USBSTOR_QueueInitialize(
|
||||||
PFDO_DEVICE_EXTENSION FDODeviceExtension);
|
PFDO_DEVICE_EXTENSION FDODeviceExtension);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
ErrorHandlerWorkItemRoutine(
|
||||||
|
PVOID Context);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
USBSTOR_QueueNextRequest(
|
USBSTOR_QueueNextRequest(
|
||||||
IN PDEVICE_OBJECT DeviceObject);
|
IN PDEVICE_OBJECT DeviceObject);
|
||||||
|
|
Loading…
Reference in a new issue