ReactOS 0.4.15-dev-7889-g76290a6
queue.c File Reference
#include "usbstor.h"
#include <debug.h>
Include dependency graph for queue.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID USBSTOR_QueueInitialize (PFDO_DEVICE_EXTENSION FDODeviceExtension)
 
VOID NTAPI USBSTOR_CancelIo (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
VOID NTAPI USBSTOR_Cancel (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
BOOLEAN USBSTOR_QueueAddIrp (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 
PIRP USBSTOR_RemoveIrp (IN PDEVICE_OBJECT DeviceObject)
 
VOID USBSTOR_QueueWaitForPendingRequests (IN PDEVICE_OBJECT DeviceObject)
 
VOID USBSTOR_QueueTerminateRequest (IN PDEVICE_OBJECT FDODeviceObject, IN PIRP Irp)
 
VOID USBSTOR_QueueNextRequest (IN PDEVICE_OBJECT DeviceObject)
 
VOID USBSTOR_QueueRelease (IN PDEVICE_OBJECT DeviceObject)
 
VOID NTAPI USBSTOR_StartIo (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file queue.c.

Function Documentation

◆ USBSTOR_Cancel()

VOID NTAPI USBSTOR_Cancel ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 51 of file queue.c.

54{
55 PFDO_DEVICE_EXTENSION FDODeviceExtension;
56
57 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
59 ASSERT(FDODeviceExtension->Common.IsFDO);
60
61 KeAcquireSpinLockAtDpcLevel(&FDODeviceExtension->IrpListLock);
62 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
63 KeReleaseSpinLockFromDpcLevel(&FDODeviceExtension->IrpListLock);
64
65 IoReleaseCancelSpinLock(Irp->CancelIrql);
66 Irp->IoStatus.Status = STATUS_CANCELLED;
67
70
72}
_In_ PIRP Irp
Definition: csq.h:116
struct _FDO_DEVICE_EXTENSION * PFDO_DEVICE_EXTENSION
#define ASSERT_IRQL_EQUAL(x)
Definition: debug.h:43
VOID USBSTOR_QueueTerminateRequest(IN PDEVICE_OBJECT FDODeviceObject, IN PIRP Irp)
Definition: queue.c:186
VOID USBSTOR_QueueNextRequest(IN PDEVICE_OBJECT DeviceObject)
Definition: queue.c:220
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define ASSERT(a)
Definition: mode.c:44
#define IoCompleteRequest
Definition: irp.c:1240
VOID NTAPI IoReleaseCancelSpinLock(IN KIRQL Irql)
Definition: util.c:150
#define KeAcquireSpinLockAtDpcLevel(SpinLock)
Definition: ke.h:125
#define KeReleaseSpinLockFromDpcLevel(SpinLock)
Definition: ke.h:135
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:84
#define STATUS_CANCELLED
Definition: udferr_usr.h:170
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
#define IO_NO_INCREMENT
Definition: iotypes.h:598

Referenced by USBSTOR_QueueAddIrp().

◆ USBSTOR_CancelIo()

VOID NTAPI USBSTOR_CancelIo ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 28 of file queue.c.

31{
32 PFDO_DEVICE_EXTENSION FDODeviceExtension;
33
34 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
36 ASSERT(FDODeviceExtension->Common.IsFDO);
37
38 // this IRP isn't in our list here
39 // now release the cancel lock
40 IoReleaseCancelSpinLock(Irp->CancelIrql);
41 Irp->IoStatus.Status = STATUS_CANCELLED;
42
45
47}

Referenced by USBSTOR_HandleInternalDeviceControl(), USBSTOR_QueueAddIrp(), USBSTOR_QueueNextRequest(), and USBSTOR_QueueRelease().

◆ USBSTOR_QueueAddIrp()

BOOLEAN USBSTOR_QueueAddIrp ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 75 of file queue.c.

78{
79 PDRIVER_CANCEL OldDriverCancel;
80 KIRQL OldLevel;
81 PFDO_DEVICE_EXTENSION FDODeviceExtension;
82 BOOLEAN IrpListFreeze;
83 BOOLEAN SrbProcessing;
86
87 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
88 ASSERT(FDODeviceExtension->Common.IsFDO);
89
91
92 KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
93
94 SrbProcessing = FDODeviceExtension->IrpPendingCount != 0;
95
96 if (SrbProcessing)
97 {
98 // add irp to queue
99 InsertTailList(&FDODeviceExtension->IrpListHead, &Irp->Tail.Overlay.ListEntry);
100 }
101
102 FDODeviceExtension->IrpPendingCount++;
103 KeClearEvent(&FDODeviceExtension->NoPendingRequests);
104
105 // check if queue is freezed
106 IrpListFreeze = BooleanFlagOn(FDODeviceExtension->Flags, USBSTOR_FDO_FLAGS_IRP_LIST_FREEZE);
107
108 KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
109
110 // synchronize with cancellations by holding the cancel lock
111 IoAcquireCancelSpinLock(&Irp->CancelIrql);
112
113 if (SrbProcessing)
114 {
115 ASSERT(FDODeviceExtension->ActiveSrb != NULL);
116
117 OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_Cancel);
118 }
119 else
120 {
121 ASSERT(FDODeviceExtension->ActiveSrb == NULL);
122
123 FDODeviceExtension->ActiveSrb = Request;
124 OldDriverCancel = IoSetCancelRoutine(Irp, USBSTOR_CancelIo);
125 }
126
127 // check if the irp has already been cancelled
128 if (Irp->Cancel && OldDriverCancel == NULL)
129 {
130 // cancel irp
131 Irp->CancelRoutine(DeviceObject, Irp);
132 return FALSE;
133 }
134
135 IoReleaseCancelSpinLock(Irp->CancelIrql);
136
137 // if list is freezed, dont start this packet
138 DPRINT("IrpListFreeze: %lu IrpPendingCount %lu\n", IrpListFreeze, FDODeviceExtension->IrpPendingCount);
139
140 return (IrpListFreeze || SrbProcessing);
141}
static PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(PIRP Irp)
unsigned char BOOLEAN
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
struct _SCSI_REQUEST_BLOCK * PSCSI_REQUEST_BLOCK
VOID NTAPI USBSTOR_Cancel(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: queue.c:51
VOID NTAPI USBSTOR_CancelIo(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: queue.c:28
#define InsertTailList(ListHead, Entry)
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 KeClearEvent(IN PKEVENT Event)
Definition: eventobj.c:22
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IoMarkIrpPending(Irp)
IoSetCancelRoutine(Irp, CancelRoutine)
VOID NTAPI IoAcquireCancelSpinLock(OUT PKIRQL Irql)
Definition: util.c:56
#define DPRINT
Definition: sndvol32.h:71
LIST_ENTRY ListEntry
Definition: pci.h:86
struct _IO_STACK_LOCATION::@3978::@4017 Others
union _IO_STACK_LOCATION::@1564 Parameters
#define USBSTOR_FDO_FLAGS_IRP_LIST_FREEZE
Definition: usbstor.h:118
_In_ WDFREQUEST Request
Definition: wdfdevice.h:547
DRIVER_CANCEL * PDRIVER_CANCEL
Definition: iotypes.h:2759

Referenced by USBSTOR_HandleInternalDeviceControl().

◆ USBSTOR_QueueInitialize()

VOID USBSTOR_QueueInitialize ( PFDO_DEVICE_EXTENSION  FDODeviceExtension)

Definition at line 17 of file queue.c.

19{
20 ASSERT(FDODeviceExtension->Common.IsFDO);
21 KeInitializeSpinLock(&FDODeviceExtension->IrpListLock);
22 InitializeListHead(&FDODeviceExtension->IrpListHead);
23 KeInitializeEvent(&FDODeviceExtension->NoPendingRequests, NotificationEvent, TRUE);
24}
#define TRUE
Definition: types.h:120
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
@ NotificationEvent

Referenced by USBSTOR_FdoHandleStartDevice().

◆ USBSTOR_QueueNextRequest()

VOID USBSTOR_QueueNextRequest ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 220 of file queue.c.

222{
223 PFDO_DEVICE_EXTENSION FDODeviceExtension;
224 PIRP Irp;
225 PIO_STACK_LOCATION IoStack;
227
228 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
229 ASSERT(FDODeviceExtension->Common.IsFDO);
230
231 // check first if there's already a request pending or the queue is frozen
232 if (FDODeviceExtension->ActiveSrb != NULL ||
234 {
235 // no work to do yet
236 return;
237 }
238
239 // remove first irp from list
241
242 // is there an irp pending
243 if (!Irp)
244 {
245 // no work to do
247 return;
248 }
249
251 Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
253
254 FDODeviceExtension->ActiveSrb = Request;
255
256 // start next packet
259}
PIRP USBSTOR_RemoveIrp(IN PDEVICE_OBJECT DeviceObject)
Definition: queue.c:144
VOID NTAPI IoStartPacket(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PULONG Key, IN PDRIVER_CANCEL CancelFunction)
Definition: device.c:1876
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847

Referenced by USBSTOR_Cancel(), USBSTOR_CancelIo(), USBSTOR_CSWCompletionRoutine(), USBSTOR_HandleExecuteSCSI(), USBSTOR_HandleTransferError(), USBSTOR_ResetDeviceWorkItemRoutine(), USBSTOR_SendModeSense(), and USBSTOR_StartIo().

◆ USBSTOR_QueueRelease()

VOID USBSTOR_QueueRelease ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 262 of file queue.c.

264{
265 PFDO_DEVICE_EXTENSION FDODeviceExtension;
266 PIRP Irp;
267 KIRQL OldLevel;
268 PIO_STACK_LOCATION IoStack;
270
271 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
272 ASSERT(FDODeviceExtension->Common.IsFDO);
273
274 KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
275
276 // clear freezed status
277 FDODeviceExtension->Flags &= ~USBSTOR_FDO_FLAGS_IRP_LIST_FREEZE;
278
279 KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
280
281 // grab newest irp
283
284 if (!Irp)
285 {
286 return;
287 }
288
290 Request = (PSCSI_REQUEST_BLOCK)IoStack->Parameters.Others.Argument1;
291
293 Irp,
294 &Request->QueueSortKey,
296}

Referenced by USBSTOR_HandleInternalDeviceControl().

◆ USBSTOR_QueueTerminateRequest()

VOID USBSTOR_QueueTerminateRequest ( IN PDEVICE_OBJECT  FDODeviceObject,
IN PIRP  Irp 
)

Definition at line 186 of file queue.c.

189{
190 KIRQL OldLevel;
191 PFDO_DEVICE_EXTENSION FDODeviceExtension;
194
195 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)FDODeviceObject->DeviceExtension;
196 ASSERT(FDODeviceExtension->Common.IsFDO);
197
198 KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
199
200 FDODeviceExtension->IrpPendingCount--;
201
202 // check if this was our current active SRB
203 if (FDODeviceExtension->ActiveSrb == Request)
204 {
205 // indicate processing is completed
206 FDODeviceExtension->ActiveSrb = NULL;
207 }
208
209 // Set the event if nothing else is pending
210 if (FDODeviceExtension->IrpPendingCount == 0 &&
211 FDODeviceExtension->ActiveSrb == NULL)
212 {
213 KeSetEvent(&FDODeviceExtension->NoPendingRequests, IO_NO_INCREMENT, FALSE);
214 }
215
216 KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
217}
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476

Referenced by USBSTOR_Cancel(), USBSTOR_CancelIo(), USBSTOR_CBWCompletionRoutine(), USBSTOR_CSWCompletionRoutine(), USBSTOR_DataCompletionRoutine(), USBSTOR_HandleExecuteSCSI(), USBSTOR_HandleTransferError(), USBSTOR_SendModeSense(), and USBSTOR_StartIo().

◆ USBSTOR_QueueWaitForPendingRequests()

VOID USBSTOR_QueueWaitForPendingRequests ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 171 of file queue.c.

173{
174 PFDO_DEVICE_EXTENSION FDODeviceExtension;
175
176 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
177
178 KeWaitForSingleObject(&FDODeviceExtension->NoPendingRequests,
179 Executive,
181 FALSE,
182 NULL);
183}
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KernelMode
Definition: asm.h:34
@ Executive
Definition: ketypes.h:415

Referenced by USBSTOR_HandleInternalDeviceControl().

◆ USBSTOR_RemoveIrp()

PIRP USBSTOR_RemoveIrp ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 144 of file queue.c.

146{
147 KIRQL OldLevel;
148 PFDO_DEVICE_EXTENSION FDODeviceExtension;
150 PIRP Irp = NULL;
151
152 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
153 ASSERT(FDODeviceExtension->Common.IsFDO);
154
155 KeAcquireSpinLock(&FDODeviceExtension->IrpListLock, &OldLevel);
156
157 if (!IsListEmpty(&FDODeviceExtension->IrpListHead))
158 {
159 Entry = RemoveHeadList(&FDODeviceExtension->IrpListHead);
160
161 // get offset to start of irp
162 Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
163 }
164
165 KeReleaseSpinLock(&FDODeviceExtension->IrpListLock, OldLevel);
166
167 return Irp;
168}
struct _IRP * PIRP
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

Referenced by USBSTOR_QueueNextRequest(), and USBSTOR_QueueRelease().

◆ USBSTOR_StartIo()

VOID NTAPI USBSTOR_StartIo ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 300 of file queue.c.

303{
304 PIO_STACK_LOCATION IoStack;
306 PFDO_DEVICE_EXTENSION FDODeviceExtension;
307 PPDO_DEVICE_EXTENSION PDODeviceExtension;
308 KIRQL OldLevel;
309 BOOLEAN ResetInProgress;
310
311 DPRINT("USBSTOR_StartIo\n");
312
313 FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
314 ASSERT(FDODeviceExtension->Common.IsFDO);
315
316 IoAcquireCancelSpinLock(&OldLevel);
317
319
320 // check if the irp has been cancelled
321 if (Irp->Cancel)
322 {
323 IoReleaseCancelSpinLock(OldLevel);
324
325 Irp->IoStatus.Status = STATUS_CANCELLED;
326 Irp->IoStatus.Information = 0;
327
331 return;
332 }
333
334 IoReleaseCancelSpinLock(OldLevel);
335
336 KeAcquireSpinLock(&FDODeviceExtension->CommonLock, &OldLevel);
337 ResetInProgress = BooleanFlagOn(FDODeviceExtension->Flags, USBSTOR_FDO_FLAGS_DEVICE_RESETTING);
338 KeReleaseSpinLock(&FDODeviceExtension->CommonLock, OldLevel);
339
341
342 PDODeviceExtension = (PPDO_DEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
343 Request = IoStack->Parameters.Scsi.Srb;
344 ASSERT(PDODeviceExtension->Common.IsFDO == FALSE);
345
346 if (ResetInProgress)
347 {
348 // hard reset is in progress
349 Request->SrbStatus = SRB_STATUS_NO_DEVICE;
350 Request->DataTransferLength = 0;
351 Irp->IoStatus.Information = 0;
352 Irp->IoStatus.Status = STATUS_DEVICE_DOES_NOT_EXIST;
356 return;
357 }
358
360
361 // FIXME: handle error
362}
struct _PDO_DEVICE_EXTENSION * PPDO_DEVICE_EXTENSION
#define SRB_STATUS_NO_DEVICE
Definition: srb.h:348
#define STATUS_DEVICE_DOES_NOT_EXIST
Definition: ntstatus.h:428
PVOID DeviceExtension
Definition: env_spec_w32.h:418
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3223
struct _IO_STACK_LOCATION::@3978::@4000 Scsi
COMMON_DEVICE_EXTENSION Common
Definition: pci.h:59
NTSTATUS USBSTOR_HandleExecuteSCSI(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: scsi.c:540
#define USBSTOR_FDO_FLAGS_DEVICE_RESETTING
Definition: usbstor.h:117

Referenced by DriverEntry().