ReactOS 0.4.16-dev-197-g92996da
error.c File Reference
#include "usbstor.h"
#include <debug.h>
Include dependency graph for error.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS USBSTOR_GetEndpointStatus (IN PDEVICE_OBJECT DeviceObject, IN UCHAR bEndpointAddress, OUT PUSHORT Value)
 
NTSTATUS USBSTOR_ResetPipeWithHandle (IN PDEVICE_OBJECT DeviceObject, IN USBD_PIPE_HANDLE PipeHandle)
 
VOID NTAPI USBSTOR_ResetPipeWorkItemRoutine (IN PDEVICE_OBJECT FdoDevice, IN PVOID Ctx)
 
VOID NTAPI USBSTOR_ResetDeviceWorkItemRoutine (IN PDEVICE_OBJECT FdoDevice, IN PVOID Context)
 
VOID NTAPI USBSTOR_QueueResetPipe (IN PFDO_DEVICE_EXTENSION FDODeviceExtension)
 
VOID NTAPI USBSTOR_QueueResetDevice (IN PFDO_DEVICE_EXTENSION FDODeviceExtension)
 
VOID NTAPI USBSTOR_TimerWorkerRoutine (IN PVOID Context)
 
VOID NTAPI USBSTOR_TimerRoutine (PDEVICE_OBJECT DeviceObject, PVOID Context)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file error.c.

Function Documentation

◆ USBSTOR_GetEndpointStatus()

NTSTATUS USBSTOR_GetEndpointStatus ( IN PDEVICE_OBJECT  DeviceObject,
IN UCHAR  bEndpointAddress,
OUT PUSHORT  Value 
)

Definition at line 18 of file error.c.

22{
23 PURB Urb;
25
26 DPRINT("Allocating URB\n");
28 if (!Urb)
29 {
30 DPRINT1("OutofMemory!\n");
32 }
33
34 // build status
36
37 // send the request
38 DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb);
40
41 FreeItem(Urb);
42 return Status;
43}
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define NULL
Definition: types.h:112
NTSTATUS USBSTOR_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:83
#define NonPagedPool
Definition: env_spec_w32.h:307
Status
Definition: gdiplustypes.h:25
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:29
VOID FreeItem(IN PVOID Item)
Definition: misc.c:37
#define DPRINT
Definition: sndvol32.h:73
Definition: usb.h:529
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
struct _URB * PURB
#define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT
Definition: usb.h:107
#define UsbBuildGetStatusRequest(urb, op, index, transferBuffer, transferBufferMDL, link)
Definition: usbdlib.h:35
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

◆ USBSTOR_QueueResetDevice()

VOID NTAPI USBSTOR_QueueResetDevice ( IN PFDO_DEVICE_EXTENSION  FDODeviceExtension)

Definition at line 148 of file error.c.

150{
152
153 DPRINT("USBSTOR_QueueResetDevice\n");
154
155 KeAcquireSpinLock(&FDODeviceExtension->CommonLock, &OldIrql);
156 FDODeviceExtension->Flags |= USBSTOR_FDO_FLAGS_DEVICE_RESETTING;
157 KeReleaseSpinLock(&FDODeviceExtension->CommonLock, OldIrql);
158
159 IoQueueWorkItem(FDODeviceExtension->ResetDeviceWorkItem,
162 NULL);
163}
VOID NTAPI USBSTOR_ResetDeviceWorkItemRoutine(IN PDEVICE_OBJECT FdoDevice, IN PVOID Context)
Definition: error.c:93
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40
#define USBSTOR_FDO_FLAGS_DEVICE_RESETTING
Definition: usbstor.h:117
@ CriticalWorkQueue
Definition: extypes.h:189
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778

Referenced by USBSTOR_CBWCompletionRoutine(), USBSTOR_CSWCompletionRoutine(), and USBSTOR_DataCompletionRoutine().

◆ USBSTOR_QueueResetPipe()

VOID NTAPI USBSTOR_QueueResetPipe ( IN PFDO_DEVICE_EXTENSION  FDODeviceExtension)

Definition at line 135 of file error.c.

137{
138 DPRINT("USBSTOR_QueueResetPipe\n");
139
140 IoQueueWorkItem(FDODeviceExtension->ResetDeviceWorkItem,
143 FDODeviceExtension);
144}
VOID NTAPI USBSTOR_ResetPipeWorkItemRoutine(IN PDEVICE_OBJECT FdoDevice, IN PVOID Ctx)
Definition: error.c:75

Referenced by USBSTOR_CSWCompletionRoutine(), and USBSTOR_DataCompletionRoutine().

◆ USBSTOR_ResetDeviceWorkItemRoutine()

VOID NTAPI USBSTOR_ResetDeviceWorkItemRoutine ( IN PDEVICE_OBJECT  FdoDevice,
IN PVOID  Context 
)

Definition at line 93 of file error.c.

96{
97 PFDO_DEVICE_EXTENSION FDODeviceExtension;
98 UINT32 ix;
101
102 DPRINT("USBSTOR_ResetDeviceWorkItemRoutine\n");
103
104 FDODeviceExtension = FdoDevice->DeviceExtension;
105
106 for (ix = 0; ix < 3; ++ix)
107 {
108 // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
109 Status = USBSTOR_ResetDevice(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension);
110 if (NT_SUCCESS(Status))
111 {
112 // step 2 reset bulk in pipe section 5.3.4
113 Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle);
114 if (NT_SUCCESS(Status))
115 {
116 // finally reset bulk out pipe
117 Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
118 if (NT_SUCCESS(Status))
119 {
120 break;
121 }
122 }
123 }
124 }
125
126 KeAcquireSpinLock(&FDODeviceExtension->CommonLock, &OldIrql);
127 FDODeviceExtension->Flags &= ~USBSTOR_FDO_FLAGS_DEVICE_RESETTING;
128 KeReleaseSpinLock(&FDODeviceExtension->CommonLock, OldIrql);
129
130 USBSTOR_QueueNextRequest(FdoDevice);
131}
unsigned int UINT32
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSTATUS USBSTOR_ResetPipeWithHandle(IN PDEVICE_OBJECT DeviceObject, IN USBD_PIPE_HANDLE PipeHandle)
Definition: error.c:46
NTSTATUS USBSTOR_ResetDevice(IN PDEVICE_OBJECT DeviceObject, IN PFDO_DEVICE_EXTENSION DeviceExtension)
Definition: misc.c:219
VOID USBSTOR_QueueNextRequest(IN PDEVICE_OBJECT DeviceObject)
Definition: queue.c:220

Referenced by USBSTOR_QueueResetDevice().

◆ USBSTOR_ResetPipeWithHandle()

NTSTATUS USBSTOR_ResetPipeWithHandle ( IN PDEVICE_OBJECT  DeviceObject,
IN USBD_PIPE_HANDLE  PipeHandle 
)

Definition at line 46 of file error.c.

49{
50 PURB Urb;
52
53 DPRINT("Allocating URB\n");
54 Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
55 if (!Urb)
56 {
57 DPRINT1("OutofMemory!\n");
59 }
60
61 Urb->UrbPipeRequest.Hdr.Length = sizeof(struct _URB_PIPE_REQUEST);
63 Urb->UrbPipeRequest.PipeHandle = PipeHandle;
64
65 // send the request
66 DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb);
68
69 FreeItem(Urb);
70 return Status;
71}
static HANDLE PipeHandle
Definition: dhcpcsvc.c:22
struct _URB_PIPE_REQUEST UrbPipeRequest
Definition: usb.h:534
#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
Definition: usb.h:116

Referenced by USBSTOR_HandleTransferError(), USBSTOR_ResetDeviceWorkItemRoutine(), USBSTOR_ResetHandlerWorkItemRoutine(), USBSTOR_ResetPipeWorkItemRoutine(), and USBSTOR_TimerWorkerRoutine().

◆ USBSTOR_ResetPipeWorkItemRoutine()

VOID NTAPI USBSTOR_ResetPipeWorkItemRoutine ( IN PDEVICE_OBJECT  FdoDevice,
IN PVOID  Ctx 
)

Definition at line 75 of file error.c.

78{
80 PFDO_DEVICE_EXTENSION FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Ctx;
81 PIRP_CONTEXT Context = &FDODeviceExtension->CurrentIrpContext;
82
83 // clear stall on the corresponding pipe
84 Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, Context->Urb.UrbBulkOrInterruptTransfer.PipeHandle);
85 DPRINT1("USBSTOR_ResetPipeWithHandle Status %x\n", Status);
86
87 // now resend the csw as the stall got cleared
88 USBSTOR_SendCSWRequest(FDODeviceExtension, Context->Irp);
89}
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
NTSTATUS USBSTOR_SendCSWRequest(PFDO_DEVICE_EXTENSION FDODeviceExtension, PIRP Irp)
Definition: scsi.c:242

Referenced by USBSTOR_QueueResetPipe().

◆ USBSTOR_TimerRoutine()

VOID NTAPI USBSTOR_TimerRoutine ( PDEVICE_OBJECT  DeviceObject,
PVOID  Context 
)

Definition at line 205 of file error.c.

208{
209 PFDO_DEVICE_EXTENSION FDODeviceExtension;
211 PERRORHANDLER_WORKITEM_DATA WorkItemData;
212
213 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Context;
214 DPRINT1("[USBSTOR] TimerRoutine entered\n");
215 // DPRINT1("[USBSTOR] ActiveSrb %p ResetInProgress %x LastTimerActiveSrb %p\n", FDODeviceExtension->ActiveSrb, FDODeviceExtension->ResetInProgress, FDODeviceExtension->LastTimerActiveSrb);
216
217 KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock);
218
219 // is there an active srb and no global reset is in progress
220 if (FDODeviceExtension->ActiveSrb && /* FDODeviceExtension->ResetInProgress == FALSE && */ FDODeviceExtension->TimerWorkQueueEnabled)
221 {
222 if (FDODeviceExtension->LastTimerActiveSrb != NULL && FDODeviceExtension->LastTimerActiveSrb == FDODeviceExtension->ActiveSrb)
223 {
224 // check if empty
225 DPRINT1("[USBSTOR] ActiveSrb %p hang detected\n", FDODeviceExtension->ActiveSrb);
227 }
228 else
229 {
230 // update pointer
231 FDODeviceExtension->LastTimerActiveSrb = FDODeviceExtension->ActiveSrb;
232 }
233 }
234 else
235 {
236 // reset srb
237 FDODeviceExtension->LastTimerActiveSrb = NULL;
238 }
239
240 KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock);
241
242
243 if (ResetDevice && FDODeviceExtension->TimerWorkQueueEnabled && FDODeviceExtension->SrbErrorHandlingActive == FALSE)
244 {
245 WorkItemData = ExAllocatePoolWithTag(NonPagedPool,
248 if (WorkItemData)
249 {
250 // Initialize and queue the work item to handle the error
251 ExInitializeWorkItem(&WorkItemData->WorkQueueItem,
253 WorkItemData);
254
255 WorkItemData->DeviceObject = FDODeviceExtension->FunctionalDeviceObject;
256
257 DPRINT1("[USBSTOR] Queing Timer WorkItem\n");
259 }
260 }
261}
unsigned char BOOLEAN
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID NTAPI USBSTOR_TimerWorkerRoutine(IN PVOID Context)
Definition: error.c:167
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
DWORD ResetDevice(DWORD private_handle)
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
PDEVICE_OBJECT DeviceObject
Definition: usbstor.h:167
WORK_QUEUE_ITEM WorkQueueItem
Definition: usbstor.h:169
#define USB_STOR_TAG
Definition: usbstor.h:11
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:723
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
@ DelayedWorkQueue
Definition: extypes.h:190

Referenced by USBSTOR_AddDevice().

◆ USBSTOR_TimerWorkerRoutine()

VOID NTAPI USBSTOR_TimerWorkerRoutine ( IN PVOID  Context)

Definition at line 167 of file error.c.

169{
170 PFDO_DEVICE_EXTENSION FDODeviceExtension;
173
174 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)WorkItemData->DeviceObject->DeviceExtension;
175 ASSERT(FDODeviceExtension->Common.IsFDO);
176
177 // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
178 Status = USBSTOR_ResetDevice(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension);
179 if (NT_SUCCESS(Status))
180 {
181 // step 2 reset bulk in pipe section 5.3.4
182 Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle);
183 if (NT_SUCCESS(Status))
184 {
185 // finally reset bulk out pipe
186 Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
187 }
188 }
189 DPRINT1("Status %x\n", Status);
190
191 // clear timer srb
192 FDODeviceExtension->LastTimerActiveSrb = NULL;
193
194 // re-schedule request
195 //USBSTOR_HandleExecuteSCSI(WorkItemData->Context->PDODeviceExtension->Self, WorkItemData->Context->Irp, Context->RetryCount + 1);
196
197 // do not retry for the same packet again
198 FDODeviceExtension->TimerWorkQueueEnabled = FALSE;
199
200 ExFreePoolWithTag(WorkItemData, USB_STOR_TAG);
201}
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
PVOID DeviceExtension
Definition: env_spec_w32.h:418
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:84
struct _ERRORHANDLER_WORKITEM_DATA * PERRORHANDLER_WORKITEM_DATA

Referenced by USBSTOR_TimerRoutine().