mirror of
https://github.com/reactos/reactos.git
synced 2024-07-28 07:08:59 +00:00
[USBSTOR]
- Fix broken IRP error handling and leaking memory svn path=/branches/usb-bringup-trunk/; revision=55155
This commit is contained in:
parent
75947d6708
commit
2f5db208de
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue