2 * PROJECT: ReactOS Universal Serial Bus Bulk Storage Driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/usb/usbstor/error.c
5 * PURPOSE: USB block storage device driver.
8 * Michael Martin (michael.martin@reactos.org)
9 * Johannes Anderwald (johannes.anderwald@reactos.org)
15 USBSTOR_ResetPipeWithHandle(
16 IN PDEVICE_OBJECT DeviceObject
,
17 IN USBD_PIPE_HANDLE PipeHandle
)
25 DPRINT1("Allocating URB\n");
26 Urb
= (PURB
)AllocateItem(NonPagedPool
, sizeof(struct _URB_PIPE_REQUEST
));
32 DPRINT1("OutofMemory!\n");
33 return STATUS_INSUFFICIENT_RESOURCES
;
39 Urb
->UrbPipeRequest
.Hdr
.Length
= sizeof(struct _URB_PIPE_REQUEST
);
40 Urb
->UrbPipeRequest
.Hdr
.Function
= URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
;
41 Urb
->UrbPipeRequest
.PipeHandle
= PipeHandle
;
46 DPRINT1("Sending Request DeviceObject %x, Urb %x\n", DeviceObject
, Urb
);
47 Status
= USBSTOR_SyncUrbRequest(DeviceObject
, Urb
);
61 USBSTOR_HandleTransferError(
62 PDEVICE_OBJECT DeviceObject
,
66 PIO_STACK_LOCATION Stack
;
67 USBD_PIPE_HANDLE PipeHandle
;
68 PSCSI_REQUEST_BLOCK Request
;
71 DPRINT1("Entered Handle Transfer Error\n");
73 // Determine pipehandle
75 if (Context
->cbw
->CommandBlock
[0] == SCSIOP_WRITE
)
78 // write request used bulk out pipe
80 PipeHandle
= Context
->FDODeviceExtension
->InterfaceInformation
->Pipes
[Context
->FDODeviceExtension
->BulkOutPipeIndex
].PipeHandle
;
85 // default bulk in pipe
87 PipeHandle
= Context
->FDODeviceExtension
->InterfaceInformation
->Pipes
[Context
->FDODeviceExtension
->BulkInPipeIndex
].PipeHandle
;
90 switch (Context
->Urb
.UrbHeader
.Status
)
92 case USBD_STATUS_STALL_PID
:
95 // First attempt to reset the pipe
97 DPRINT1("Resetting Pipe\n");
98 Status
= USBSTOR_ResetPipeWithHandle(DeviceObject
, PipeHandle
);
99 if (NT_SUCCESS(Status
))
101 Status
= STATUS_SUCCESS
;
105 DPRINT1("Failed to reset pipe %x\n", Status
);
108 // FIXME: Reset of pipe failed, attempt to reset port
111 Status
= STATUS_UNSUCCESSFUL
;
115 // FIXME: Handle more errors
119 DPRINT1("Error not handled\n");
120 Status
= STATUS_UNSUCCESSFUL
;
124 Stack
= IoGetCurrentIrpStackLocation(Context
->Irp
);
125 Request
= (PSCSI_REQUEST_BLOCK
)Stack
->Parameters
.Others
.Argument1
;
126 pCDB
= (PCDB
)Request
->Cdb
;
127 if (Status
!= STATUS_SUCCESS
)
129 /* Complete the master IRP */
130 Context
->Irp
->IoStatus
.Status
= Status
;
131 Context
->Irp
->IoStatus
.Information
= 0;
132 IoCompleteRequest(Context
->Irp
, IO_NO_INCREMENT
);
134 /* Start the next request */
135 USBSTOR_QueueTerminateRequest(Context
->PDODeviceExtension
->LowerDeviceObject
, TRUE
);
136 USBSTOR_QueueNextRequest(Context
->PDODeviceExtension
->LowerDeviceObject
);
138 /* Signal the context event */
140 KeSetEvent(Context
->Event
, 0, FALSE
);
142 /* Cleanup the IRP context */
143 if (pCDB
->AsByte
[0] == SCSIOP_READ_CAPACITY
)
144 FreeItem(Context
->TransferData
);
145 FreeItem(Context
->cbw
);
151 DPRINT1("Retrying\n");
152 Status
= USBSTOR_HandleExecuteSCSI(DeviceObject
, Context
->Irp
);
154 /* Cleanup the old IRP context */
155 if (pCDB
->AsByte
[0] == SCSIOP_READ_CAPACITY
)
156 FreeItem(Context
->TransferData
);
157 FreeItem(Context
->cbw
);
161 DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status
);
167 ErrorHandlerWorkItemRoutine(
171 PERRORHANDLER_WORKITEM_DATA WorkItemData
= (PERRORHANDLER_WORKITEM_DATA
)Context
;
173 Status
= USBSTOR_HandleTransferError(WorkItemData
->DeviceObject
, WorkItemData
->Context
);
176 // Free Work Item Data
178 ExFreePool(WorkItemData
);