ReactOS  0.4.14-dev-384-g5b37caa
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)
 
NTSTATUS USBSTOR_HandleTransferError (PDEVICE_OBJECT DeviceObject, PIRP_CONTEXT Context)
 
VOID NTAPI USBSTOR_ResetHandlerWorkItemRoutine (PVOID Context)
 
VOID NTAPI ErrorHandlerWorkItemRoutine (PVOID Context)
 
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 14 of file error.c.

Function Documentation

◆ ErrorHandlerWorkItemRoutine()

VOID NTAPI ErrorHandlerWorkItemRoutine ( PVOID  Context)

Definition at line 248 of file error.c.

250 {
252 
253  if (WorkItemData->Context->ErrorIndex == 2)
254  {
255  //
256  // reset device
257  //
258  USBSTOR_HandleTransferError(WorkItemData->DeviceObject, WorkItemData->Context);
259  }
260  else
261  {
262  //
263  // clear stall
264  //
266  }
267 
268  //
269  // Free Work Item Data
270  //
271  ExFreePoolWithTag(WorkItemData, USB_STOR_TAG);
272 }
struct _ERRORHANDLER_WORKITEM_DATA * PERRORHANDLER_WORKITEM_DATA
PDEVICE_OBJECT DeviceObject
Definition: usbstor.h:313
ULONG ErrorIndex
Definition: usbstor.h:300
#define USB_STOR_TAG
Definition: usbstor.h:10
VOID NTAPI USBSTOR_ResetHandlerWorkItemRoutine(PVOID Context)
Definition: error.c:228
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
NTSTATUS USBSTOR_HandleTransferError(PDEVICE_OBJECT DeviceObject, PIRP_CONTEXT Context)
Definition: error.c:112

Referenced by USBSTOR_QueueWorkItem().

◆ 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  //
27  // allocate urb
28  //
29  DPRINT("Allocating URB\n");
31  if (!Urb)
32  {
33  //
34  // out of memory
35  //
36  DPRINT1("OutofMemory!\n");
38  }
39 
40  //
41  // build status
42  //
44 
45  //
46  // send the request
47  //
48  DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb);
50 
51  //
52  // free urb
53  //
54  FreeItem(Urb);
55 
56  //
57  // done
58  //
59  return Status;
60 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define UsbBuildGetStatusRequest(urb, op, index, transferBuffer, transferBufferMDL, link)
Definition: usbdlib.h:35
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
LONG NTSTATUS
Definition: precomp.h:26
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define URB_FUNCTION_GET_STATUS_FROM_ENDPOINT
Definition: usb.h:107
struct _URB * PURB
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
Definition: usb.h:529
NTSTATUS USBSTOR_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:107
#define DPRINT1
Definition: precomp.h:8

◆ USBSTOR_HandleTransferError()

NTSTATUS USBSTOR_HandleTransferError ( PDEVICE_OBJECT  DeviceObject,
PIRP_CONTEXT  Context 
)

Definition at line 112 of file error.c.

115 {
117  PIO_STACK_LOCATION Stack;
119  PCDB pCDB;
120 
121  //
122  // sanity checks
123  //
124  ASSERT(Context);
125  ASSERT(Context->PDODeviceExtension);
126  ASSERT(Context->PDODeviceExtension->Self);
127  ASSERT(Context->Irp);
128 
129  //
130  // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
131  //
132  Status = USBSTOR_ResetDevice(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension);
133  if (NT_SUCCESS(Status))
134  {
135  //
136  // step 2 reset bulk in pipe section 5.3.4
137  //
138  Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle);
139  if (NT_SUCCESS(Status))
140  {
141  //
142  // finally reset bulk out pipe
143  //
144  Status = USBSTOR_ResetPipeWithHandle(Context->FDODeviceExtension->LowerDeviceObject, Context->FDODeviceExtension->InterfaceInformation->Pipes[Context->FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
145  }
146  }
147 
148  //
149  // get next stack location
150  //
152 
153  //
154  // get request block
155  //
156  Request = (PSCSI_REQUEST_BLOCK)Stack->Parameters.Others.Argument1;
157  ASSERT(Request);
158 
159  //
160  // obtain request type
161  //
162  pCDB = (PCDB)Request->Cdb;
163  ASSERT(pCDB);
164 
165  if (Status != STATUS_SUCCESS || Context->RetryCount >= 1)
166  {
167  //
168  // Complete the master IRP
169  //
170  Context->Irp->IoStatus.Status = Status;
171  Context->Irp->IoStatus.Information = 0;
172  USBSTOR_QueueTerminateRequest(Context->PDODeviceExtension->LowerDeviceObject, Context->Irp);
174 
175  //
176  // Start the next request
177  //
178  USBSTOR_QueueNextRequest(Context->PDODeviceExtension->LowerDeviceObject);
179 
180  //
181  // srb handling finished
182  //
183  Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
184 
185  //
186  // clear timer srb
187  //
188  Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
189  }
190  else
191  {
192  DPRINT1("Retrying Count %lu %p\n", Context->RetryCount, Context->PDODeviceExtension->Self);
193 
194  //
195  // re-schedule request
196  //
197  USBSTOR_HandleExecuteSCSI(Context->PDODeviceExtension->Self, Context->Irp, Context->RetryCount + 1);
198 
199  //
200  // srb error handling finished
201  //
202  Context->FDODeviceExtension->SrbErrorHandlingActive = FALSE;
203 
204  //
205  // srb error handling finished
206  //
207  Context->FDODeviceExtension->TimerWorkQueueEnabled = TRUE;
208 
209  //
210  // clear timer srb
211  //
212  Context->FDODeviceExtension->LastTimerActiveSrb = NULL;
213  }
214 
215  //
216  // cleanup irp context
217  //
218  FreeItem(Context->cbw);
219  FreeItem(Context);
220 
221 
222  DPRINT1("USBSTOR_HandleTransferError returning with Status %x\n", Status);
223  return Status;
224 }
#define TRUE
Definition: types.h:120
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS USBSTOR_HandleExecuteSCSI(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: scsi.c:560
_In_ NDIS_HANDLE _In_ PNDIS_REQUEST Request
Definition: ndis.h:5173
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
VOID USBSTOR_QueueNextRequest(IN PDEVICE_OBJECT DeviceObject)
Definition: queue.c:220
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:251
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
#define IoCompleteRequest
Definition: irp.c:1240
VOID USBSTOR_QueueTerminateRequest(IN PDEVICE_OBJECT FDODeviceObject, IN PIRP Irp)
Definition: queue.c:186
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define DPRINT1
Definition: precomp.h:8
#define IO_NO_INCREMENT
Definition: iotypes.h:566
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by ErrorHandlerWorkItemRoutine().

◆ USBSTOR_ResetHandlerWorkItemRoutine()

VOID NTAPI USBSTOR_ResetHandlerWorkItemRoutine ( PVOID  Context)

Definition at line 228 of file error.c.

230 {
233 
234  //
235  // clear stall on BulkIn pipe
236  //
237  Status = USBSTOR_ResetPipeWithHandle(WorkItemData->Context->FDODeviceExtension->LowerDeviceObject, WorkItemData->Context->FDODeviceExtension->InterfaceInformation->Pipes[WorkItemData->Context->FDODeviceExtension->BulkInPipeIndex].PipeHandle);
238  DPRINT1("USBSTOR_ResetPipeWithHandle Status %x\n", Status);
239 
240  //
241  // now resend the csw as the stall got cleared
242  //
243  USBSTOR_SendCSW(WorkItemData->Context, WorkItemData->Irp);
244 }
struct _ERRORHANDLER_WORKITEM_DATA * PERRORHANDLER_WORKITEM_DATA
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS USBSTOR_ResetPipeWithHandle(IN PDEVICE_OBJECT DeviceObject, IN USBD_PIPE_HANDLE PipeHandle)
Definition: error.c:46
PFDO_DEVICE_EXTENSION FDODeviceExtension
Definition: usbstor.h:299
Status
Definition: gdiplustypes.h:24
#define DPRINT1
Definition: precomp.h:8
VOID USBSTOR_SendCSW(PIRP_CONTEXT Context, PIRP Irp)
Definition: scsi.c:379

Referenced by ErrorHandlerWorkItemRoutine().

◆ USBSTOR_ResetPipeWithHandle()

NTSTATUS USBSTOR_ResetPipeWithHandle ( IN PDEVICE_OBJECT  DeviceObject,
IN USBD_PIPE_HANDLE  PipeHandle 
)

Definition at line 65 of file error.c.

68 {
69  PURB Urb;
71 
72  //
73  // allocate urb
74  //
75  DPRINT("Allocating URB\n");
76  Urb = (PURB)AllocateItem(NonPagedPool, sizeof(struct _URB_PIPE_REQUEST));
77  if (!Urb)
78  {
79  //
80  // out of memory
81  //
82  DPRINT1("OutofMemory!\n");
84  }
85 
86  //
87  // initialize the urb
88  //
89  Urb->UrbPipeRequest.Hdr.Length = sizeof(struct _URB_PIPE_REQUEST);
91  Urb->UrbPipeRequest.PipeHandle = PipeHandle;
92 
93  //
94  // send the request
95  //
96  DPRINT1("Sending Request DeviceObject %p, Urb %p\n", DeviceObject, Urb);
98 
99  //
100  // free urb
101  //
102  FreeItem(Urb);
103 
104  //
105  // done
106  //
107  return Status;
108 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
LONG NTSTATUS
Definition: precomp.h:26
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
void DPRINT(...)
Definition: polytest.cpp:61
#define URB_FUNCTION_SYNC_RESET_PIPE_AND_CLEAR_STALL
Definition: usb.h:116
struct _URB_PIPE_REQUEST UrbPipeRequest
Definition: usb.h:534
struct _URB * PURB
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
Definition: usb.h:529
static HANDLE PipeHandle
Definition: dhcpcsvc.c:21
NTSTATUS USBSTOR_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:107
#define DPRINT1
Definition: precomp.h:8

◆ USBSTOR_TimerRoutine()

VOID NTAPI USBSTOR_TimerRoutine ( PDEVICE_OBJECT  DeviceObject,
PVOID  Context 
)

Definition at line 335 of file error.c.

338 {
339  PFDO_DEVICE_EXTENSION FDODeviceExtension;
341  PERRORHANDLER_WORKITEM_DATA WorkItemData;
342 
343  //
344  // get device extension
345  //
346  FDODeviceExtension = (PFDO_DEVICE_EXTENSION)Context;
347  DPRINT1("[USBSTOR] TimerRoutine entered\n");
348  DPRINT1("[USBSTOR] ActiveSrb %p ResetInProgress %x LastTimerActiveSrb %p\n", FDODeviceExtension->ActiveSrb, FDODeviceExtension->ResetInProgress, FDODeviceExtension->LastTimerActiveSrb);
349 
350  //
351  // acquire spinlock
352  //
353  KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock);
354 
355  //
356  // is there an active srb and no global reset is in progress
357  //
358  if (FDODeviceExtension->ActiveSrb && FDODeviceExtension->ResetInProgress == FALSE && FDODeviceExtension->TimerWorkQueueEnabled)
359  {
360  if (FDODeviceExtension->LastTimerActiveSrb != NULL && FDODeviceExtension->LastTimerActiveSrb == FDODeviceExtension->ActiveSrb)
361  {
362  //
363  // check if empty
364  //
365  DPRINT1("[USBSTOR] ActiveSrb %p hang detected\n", FDODeviceExtension->ActiveSrb);
366  ResetDevice = TRUE;
367  }
368  else
369  {
370  //
371  // update pointer
372  //
373  FDODeviceExtension->LastTimerActiveSrb = FDODeviceExtension->ActiveSrb;
374  }
375  }
376  else
377  {
378  //
379  // reset srb
380  //
381  FDODeviceExtension->LastTimerActiveSrb = NULL;
382  }
383 
384  //
385  // release lock
386  //
387  KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock);
388 
389 
390  if (ResetDevice && FDODeviceExtension->TimerWorkQueueEnabled && FDODeviceExtension->SrbErrorHandlingActive == FALSE)
391  {
392  WorkItemData = ExAllocatePoolWithTag(NonPagedPool,
394  USB_STOR_TAG);
395  if (WorkItemData)
396  {
397  //
398  // Initialize and queue the work item to handle the error
399  //
400  ExInitializeWorkItem(&WorkItemData->WorkQueueItem,
402  WorkItemData);
403 
404  WorkItemData->DeviceObject = FDODeviceExtension->FunctionalDeviceObject;
405 
406  DPRINT1("[USBSTOR] Queing Timer WorkItem\n");
408  }
409  }
410 }
#define TRUE
Definition: types.h:120
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
DWORD ResetDevice(DWORD private_handle)
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
WORK_QUEUE_ITEM WorkQueueItem
Definition: usbstor.h:315
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
PDEVICE_OBJECT DeviceObject
Definition: usbstor.h:313
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265
VOID NTAPI KeReleaseSpinLockFromDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:215
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define USB_STOR_TAG
Definition: usbstor.h:10
#define DPRINT1
Definition: precomp.h:8
VOID NTAPI USBSTOR_TimerWorkerRoutine(IN PVOID Context)
Definition: error.c:168

◆ USBSTOR_TimerWorkerRoutine()

VOID NTAPI USBSTOR_TimerWorkerRoutine ( IN PVOID  Context)

Definition at line 276 of file error.c.

278 {
279  PFDO_DEVICE_EXTENSION FDODeviceExtension;
282 
283  //
284  // get device extension
285  //
286  FDODeviceExtension = (PFDO_DEVICE_EXTENSION)WorkItemData->DeviceObject->DeviceExtension;
287  ASSERT(FDODeviceExtension->Common.IsFDO);
288 
289  //
290  // first perform a mass storage reset step 1 in 5.3.4 USB Mass Storage Bulk Only Specification
291  //
292  Status = USBSTOR_ResetDevice(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension);
293  if (NT_SUCCESS(Status))
294  {
295  //
296  // step 2 reset bulk in pipe section 5.3.4
297  //
298  Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkInPipeIndex].PipeHandle);
299  if (NT_SUCCESS(Status))
300  {
301  //
302  // finally reset bulk out pipe
303  //
304  Status = USBSTOR_ResetPipeWithHandle(FDODeviceExtension->LowerDeviceObject, FDODeviceExtension->InterfaceInformation->Pipes[FDODeviceExtension->BulkOutPipeIndex].PipeHandle);
305  }
306  }
307  DPRINT1("Status %x\n", Status);
308 
309  //
310  // clear timer srb
311  //
312  FDODeviceExtension->LastTimerActiveSrb = NULL;
313 
314  //
315  // re-schedule request
316  //
317  //USBSTOR_HandleExecuteSCSI(WorkItemData->Context->PDODeviceExtension->Self, WorkItemData->Context->Irp, Context->RetryCount + 1);
318 
319 
320 
321  //
322  // do not retry for the same packet again
323  //
324  FDODeviceExtension->TimerWorkQueueEnabled = FALSE;
325 
326  //
327  // Free Work Item Data
328  //
329  ExFreePoolWithTag(WorkItemData, USB_STOR_TAG);
330 }
struct _ERRORHANDLER_WORKITEM_DATA * PERRORHANDLER_WORKITEM_DATA
LONG NTSTATUS
Definition: precomp.h:26
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
PDEVICE_OBJECT DeviceObject
Definition: usbstor.h:313
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:251
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define USB_STOR_TAG
Definition: usbstor.h:10
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:80
Status
Definition: gdiplustypes.h:24
#define DPRINT1
Definition: precomp.h:8
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099