[USBSTOR]

- Fix broken IRP error handling and leaking memory

svn path=/branches/usb-bringup-trunk/; revision=55155
This commit is contained in:
Cameron Gutman 2012-01-24 22:28:44 +00:00
parent 75947d6708
commit 2f5db208de
3 changed files with 99 additions and 85 deletions

View file

@ -22,14 +22,14 @@ USBSTOR_ResetPipeWithHandle(
// //
// allocate urb // allocate urb
// //
DPRINT1("Allocating URB\n"); DPRINT1("Allocating URB\n");
Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST)); Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
if (!Urb) if (!Urb)
{ {
// //
// out of memory // out of memory
// //
DPRINT1("OutofMemory!\n"); DPRINT1("OutofMemory!\n");
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
@ -43,7 +43,7 @@ USBSTOR_ResetPipeWithHandle(
// //
// send the request // send the request
// //
DPRINT1("Sending Request DeviceObject %x, Urb %x\n", DeviceObject, Urb); DPRINT1("Sending Request DeviceObject %x, Urb %x\n", DeviceObject, Urb);
Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb); Status = USBSTOR_SyncUrbRequest(DeviceObject, Urb);
// //
@ -59,19 +59,19 @@ USBSTOR_ResetPipeWithHandle(
NTSTATUS NTSTATUS
USBSTOR_HandleTransferError( USBSTOR_HandleTransferError(
PDEVICE_OBJECT DeviceObject, PDEVICE_OBJECT DeviceObject,
PIRP Irp, PIRP_CONTEXT Context)
PIRP_CONTEXT Context)
{ {
NTSTATUS Status; NTSTATUS Status;
PIO_STACK_LOCATION Stack; PIO_STACK_LOCATION Stack;
USBD_PIPE_HANDLE PipeHandle; USBD_PIPE_HANDLE PipeHandle;
PSCSI_REQUEST_BLOCK Request; PSCSI_REQUEST_BLOCK Request;
PCDB pCDB;
DPRINT1("Entered Handle Transfer Error\n"); DPRINT1("Entered Handle Transfer Error\n");
// //
// Determine pipehandle // Determine pipehandle
// //
if (Context->cbw->CommandBlock[0] == SCSIOP_WRITE) if (Context->cbw->CommandBlock[0] == SCSIOP_WRITE)
{ {
// //
@ -87,72 +87,93 @@ USBSTOR_HandleTransferError(
PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle; PipeHandle = Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle;
} }
switch (Context->Urb.UrbHeader.Status) switch (Context->Urb.UrbHeader.Status)
{ {
case USBD_STATUS_STALL_PID: case USBD_STATUS_STALL_PID:
{ {
// //
// First attempt to reset the pipe // First attempt to reset the pipe
// //
DPRINT1("Resetting Pipe\n"); DPRINT1("Resetting Pipe\n");
Status = USBSTOR_ResetPipeWithHandle(DeviceObject, PipeHandle); Status = USBSTOR_ResetPipeWithHandle(DeviceObject, PipeHandle);
if (NT_SUCCESS(Status)) if (NT_SUCCESS(Status))
{ {
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;
break; break;
} }
DPRINT1("Failed to reset pipe %x\n", Status); 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
// //
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
break; break;
} }
// //
// FIXME: Handle more errors // FIXME: Handle more errors
// //
default: default:
{ {
DPRINT1("Error not handled\n"); DPRINT1("Error not handled\n");
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
} }
} }
if (Status != STATUS_SUCCESS) Stack = IoGetCurrentIrpStackLocation(Context->Irp);
{ Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
Irp->IoStatus.Status = Status; pCDB = (PCDB)Request->Cdb;
Irp->IoStatus.Information = 0; if (Status != STATUS_SUCCESS)
} {
else /* Complete the master IRP */
{ Context->Irp->IoStatus.Status = Status;
Stack = IoGetCurrentIrpStackLocation(Context->Irp); Context->Irp->IoStatus.Information = 0;
// IoCompleteRequest(Context->Irp, IO_NO_INCREMENT);
// Retry the operation
//
Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
DPRINT1("Retrying\n");
Status = USBSTOR_HandleExecuteSCSI(DeviceObject, Context->Irp);
}
DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status); /* Start the next request */
return Status; USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, TRUE);
USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject);
/* Signal the context event */
if (Context->Event)
KeSetEvent(Context->Event, 0, FALSE);
/* Cleanup the IRP context */
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
FreeItem(Context->TransferData);
FreeItem(Context->cbw);
FreeItem(Context);
}
else
{
DPRINT1("Retrying\n");
Status = USBSTOR_HandleExecuteSCSI(DeviceObject, Context->Irp);
/* Cleanup the old IRP context */
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY)
FreeItem(Context->TransferData);
FreeItem(Context->cbw);
FreeItem(Context);
}
DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status);
return Status;
} }
VOID VOID
NTAPI NTAPI
ErrorHandlerWorkItemRoutine( ErrorHandlerWorkItemRoutine(
PVOID Context) PVOID Context)
{ {
NTSTATUS Status; NTSTATUS Status;
PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context; PERRORHANDLER_WORKITEM_DATA WorkItemData = (PERRORHANDLER_WORKITEM_DATA)Context;
Status = USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Irp, WorkItemData->Context); Status = USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Context);
// //
// Free Work Item Data // Free Work Item Data
// //
ExFreePool(WorkItemData); ExFreePool(WorkItemData);
} }

View file

@ -181,18 +181,9 @@ USBSTOR_CSWCompletionRoutine(
{ {
DPRINT1("Attempting Error Recovery\n"); DPRINT1("Attempting Error Recovery\n");
// //
// If a Read Capacity Request free TransferBuffer // free the allocated irp
// //
if (pCDB->AsByte[0] == SCSIOP_READ_CAPACITY) IoFreeIrp(Irp);
{
FreeItem(Context->TransferData);
}
//
// Clean up the rest
//
FreeItem(Context->cbw);
FreeItem(Context);
// //
// Allocate Work Item Data // Allocate Work Item Data
@ -213,7 +204,6 @@ USBSTOR_CSWCompletionRoutine(
ErrorHandlerWorkItemData); ErrorHandlerWorkItemData);
ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject; ErrorHandlerWorkItemData->DeviceObject = Context->FDODeviceExtension->FunctionalDeviceObject;
ErrorHandlerWorkItemData->Irp = Irp;
ErrorHandlerWorkItemData->Context = Context; ErrorHandlerWorkItemData->Context = Context;
DPRINT1("Queuing WorkItemROutine\n"); DPRINT1("Queuing WorkItemROutine\n");
ExQueueWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem, DelayedWorkQueue); ExQueueWorkItem(&ErrorHandlerWorkItemData->WorkQueueItem, DelayedWorkQueue);
@ -315,6 +305,10 @@ USBSTOR_CSWCompletionRoutine(
KeSetEvent(Context->Event, 0, FALSE); KeSetEvent(Context->Event, 0, FALSE);
} }
//
// free our allocated irp
//
IoFreeIrp(Irp);
// //
// free context // free context

View file

@ -278,7 +278,6 @@ typedef struct
typedef struct _ERRORHANDLER_WORKITEM_DATA typedef struct _ERRORHANDLER_WORKITEM_DATA
{ {
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject;
PIRP Irp;
PIRP_CONTEXT Context; PIRP_CONTEXT Context;
WORK_QUEUE_ITEM WorkQueueItem; WORK_QUEUE_ITEM WorkQueueItem;
} ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA; } ERRORHANDLER_WORKITEM_DATA, *PERRORHANDLER_WORKITEM_DATA;