ReactOS  0.4.15-dev-1203-g0e5a4d5
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 }
#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
IN UCHAR Value
Definition: halp.h:394
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
Status
Definition: gdiplustypes.h:24
struct _URB * PURB
Definition: usb.h:529
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
NTSTATUS USBSTOR_SyncUrbRequest(IN PDEVICE_OBJECT DeviceObject, OUT PURB UrbRequest)
Definition: misc.c:107
#define DPRINT1
Definition: precomp.h:8

◆ USBSTOR_QueueResetDevice()

VOID NTAPI USBSTOR_QueueResetDevice ( IN PFDO_DEVICE_EXTENSION  FDODeviceExtension)

Definition at line 148 of file error.c.

150 {
151  KIRQL OldIrql;
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 }
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID NTAPI USBSTOR_ResetDeviceWorkItemRoutine(IN PDEVICE_OBJECT FdoDevice, IN PVOID Context)
Definition: error.c:93
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define USBSTOR_FDO_FLAGS_DEVICE_RESETTING
Definition: usbstor.h:116
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 KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627

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
void DPRINT(...)
Definition: polytest.cpp:61
VOID NTAPI IoQueueWorkItem(IN PIO_WORKITEM IoWorkItem, IN PIO_WORKITEM_ROUTINE WorkerRoutine, IN WORK_QUEUE_TYPE QueueType, IN PVOID Context)
Definition: iowork.c:40

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;
100  KIRQL OldIrql;
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 }
LONG NTSTATUS
Definition: precomp.h:26
UCHAR KIRQL
Definition: env_spec_w32.h:591
VOID USBSTOR_QueueNextRequest(IN PDEVICE_OBJECT DeviceObject)
Definition: queue.c:220
unsigned int UINT32
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:250
void DPRINT(...)
Definition: polytest.cpp:61
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
Status
Definition: gdiplustypes.h:24
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define USBSTOR_FDO_FLAGS_DEVICE_RESETTING
Definition: usbstor.h:116
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627

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 }
#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
Status
Definition: gdiplustypes.h:24
struct _URB * PURB
Definition: usb.h:529
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
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

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 }
LONG NTSTATUS
Definition: precomp.h:26
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
NTSTATUS USBSTOR_SendCSWRequest(PFDO_DEVICE_EXTENSION FDODeviceExtension, PIRP Irp)
Definition: scsi.c:242
NTSTATUS USBSTOR_ResetPipeWithHandle(IN PDEVICE_OBJECT DeviceObject, IN USBD_PIPE_HANDLE PipeHandle)
Definition: error.c:46
Status
Definition: gdiplustypes.h:24
#define DPRINT1
Definition: precomp.h:8

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);
226  ResetDevice = TRUE;
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,
247  USB_STOR_TAG);
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 }
VOID NTAPI ExQueueWorkItem(IN PWORK_QUEUE_ITEM WorkItem, IN WORK_QUEUE_TYPE QueueType)
Definition: work.c:717
#define TRUE
Definition: types.h:120
DWORD ResetDevice(DWORD private_handle)
VOID NTAPI KeAcquireSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock)
Definition: spinlock.c:192
WORK_QUEUE_ITEM WorkQueueItem
Definition: usbstor.h:168
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
PDEVICE_OBJECT DeviceObject
Definition: usbstor.h:166
#define FALSE
Definition: types.h:117
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:167

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 }
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:166
#define FALSE
Definition: types.h:117
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:250
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)
Status
Definition: gdiplustypes.h:24
#define USB_STOR_TAG
Definition: usbstor.h:10
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:81
#define DPRINT1
Definition: precomp.h:8
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by USBSTOR_TimerRoutine().