1 /*
2 * PROJECT: ReactOS USB Port Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBPort queue implementation
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
6 */
7
8 #include "usbport.h"
9
10 #define NDEBUG
11 #include <debug.h>
12
13 #define NDEBUG_USBPORT_CORE
14 #define NDEBUG_USBPORT_QUEUE
15 #define NDEBUG_USBPORT_URB
16 #include "usbdebug.h"
17
18 VOID
19 NTAPI
USBPORT_InsertIdleIrp(IN PIO_CSQ Csq,IN PIRP Irp)20 USBPORT_InsertIdleIrp(IN PIO_CSQ Csq,
21 IN PIRP Irp)
22 {
23 PUSBPORT_DEVICE_EXTENSION FdoExtension;
24
25 DPRINT_QUEUE("USBPORT_InsertIdleIrp: Irp - %p\n", Irp);
26
27 FdoExtension = CONTAINING_RECORD(Csq,
28 USBPORT_DEVICE_EXTENSION,
29 IdleIoCsq);
30
31 InsertTailList(&FdoExtension->IdleIrpList,
32 &Irp->Tail.Overlay.ListEntry);
33 }
34
35 VOID
36 NTAPI
USBPORT_RemoveIdleIrp(IN PIO_CSQ Csq,IN PIRP Irp)37 USBPORT_RemoveIdleIrp(IN PIO_CSQ Csq,
38 IN PIRP Irp)
39 {
40 DPRINT_QUEUE("USBPORT_RemoveIdleIrp: Irp - %p\n", Irp);
41 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
42 }
43
44 PIRP
45 NTAPI
USBPORT_PeekNextIdleIrp(IN PIO_CSQ Csq,IN PIRP Irp,IN PVOID PeekContext)46 USBPORT_PeekNextIdleIrp(IN PIO_CSQ Csq,
47 IN PIRP Irp,
48 IN PVOID PeekContext)
49 {
50 PUSBPORT_DEVICE_EXTENSION FdoExtension;
51 PLIST_ENTRY NextEntry;
52 PLIST_ENTRY ListHead;
53 PIRP NextIrp = NULL;
54
55 DPRINT_QUEUE("USBPORT_PeekNextIdleIrp: Irp - %p, PeekContext - %p\n",
56 Irp,
57 PeekContext);
58
59 FdoExtension = CONTAINING_RECORD(Csq,
60 USBPORT_DEVICE_EXTENSION,
61 IdleIoCsq);
62
63 ListHead = &FdoExtension->IdleIrpList;
64
65 if (Irp)
66 {
67 NextEntry = Irp->Tail.Overlay.ListEntry.Flink;
68 }
69 else
70 {
71 NextEntry = ListHead->Flink;
72 }
73
74 while (NextEntry != ListHead)
75 {
76 NextIrp = CONTAINING_RECORD(NextEntry,
77 IRP,
78 Tail.Overlay.ListEntry);
79
80 if (!PeekContext)
81 break;
82
83 NextEntry = NextEntry->Flink;
84 }
85
86 return NextIrp;
87 }
88
89 VOID
90 NTAPI
USBPORT_AcquireIdleLock(IN PIO_CSQ Csq,IN PKIRQL Irql)91 USBPORT_AcquireIdleLock(IN PIO_CSQ Csq,
92 IN PKIRQL Irql)
93 {
94 PUSBPORT_DEVICE_EXTENSION FdoExtension;
95
96 DPRINT_QUEUE("USBPORT_AcquireIdleLock: ... \n");
97
98 FdoExtension = CONTAINING_RECORD(Csq,
99 USBPORT_DEVICE_EXTENSION,
100 IdleIoCsq);
101
102 KeAcquireSpinLock(&FdoExtension->IdleIoCsqSpinLock, Irql);
103 }
104
105 VOID
106 NTAPI
USBPORT_ReleaseIdleLock(IN PIO_CSQ Csq,IN KIRQL Irql)107 USBPORT_ReleaseIdleLock(IN PIO_CSQ Csq,
108 IN KIRQL Irql)
109 {
110 PUSBPORT_DEVICE_EXTENSION FdoExtension;
111
112 DPRINT_QUEUE("USBPORT_ReleaseIdleLock: ... \n");
113
114 FdoExtension = CONTAINING_RECORD(Csq,
115 USBPORT_DEVICE_EXTENSION,
116 IdleIoCsq);
117
118 KeReleaseSpinLock(&FdoExtension->IdleIoCsqSpinLock, Irql);
119 }
120
121 VOID
122 NTAPI
USBPORT_CompleteCanceledIdleIrp(IN PIO_CSQ Csq,IN PIRP Irp)123 USBPORT_CompleteCanceledIdleIrp(IN PIO_CSQ Csq,
124 IN PIRP Irp)
125 {
126 PUSBPORT_DEVICE_EXTENSION FdoExtension;
127
128 DPRINT_QUEUE("USBPORT_CompleteCanceledIdleIrp: ... \n");
129
130 FdoExtension = CONTAINING_RECORD(Csq,
131 USBPORT_DEVICE_EXTENSION,
132 IdleIoCsq);
133
134 InterlockedDecrement(&FdoExtension->IdleLockCounter);
135
136 Irp->IoStatus.Status = STATUS_CANCELLED;
137 Irp->IoStatus.Information = 0;
138 IoCompleteRequest(Irp, IO_NO_INCREMENT);
139 }
140
141 VOID
142 NTAPI
USBPORT_InsertBadRequest(IN PIO_CSQ Csq,IN PIRP Irp)143 USBPORT_InsertBadRequest(IN PIO_CSQ Csq,
144 IN PIRP Irp)
145 {
146 PUSBPORT_DEVICE_EXTENSION FdoExtension;
147
148 DPRINT_QUEUE("USBPORT_InsertBadRequest: Irp - %p\n", Irp);
149
150 FdoExtension = CONTAINING_RECORD(Csq,
151 USBPORT_DEVICE_EXTENSION,
152 BadRequestIoCsq);
153
154 InsertTailList(&FdoExtension->BadRequestList,
155 &Irp->Tail.Overlay.ListEntry);
156 }
157
158 VOID
159 NTAPI
USBPORT_RemoveBadRequest(IN PIO_CSQ Csq,IN PIRP Irp)160 USBPORT_RemoveBadRequest(IN PIO_CSQ Csq,
161 IN PIRP Irp)
162 {
163 DPRINT_QUEUE("USBPORT_RemoveBadRequest: Irp - %p\n", Irp);
164 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
165 }
166
167 PIRP
168 NTAPI
USBPORT_PeekNextBadRequest(IN PIO_CSQ Csq,IN PIRP Irp,IN PVOID PeekContext)169 USBPORT_PeekNextBadRequest(IN PIO_CSQ Csq,
170 IN PIRP Irp,
171 IN PVOID PeekContext)
172 {
173 PUSBPORT_DEVICE_EXTENSION FdoExtension;
174 PLIST_ENTRY NextEntry;
175 PLIST_ENTRY ListHead;
176 PIRP NextIrp = NULL;
177
178 DPRINT_QUEUE("USBPORT_PeekNextBadRequest: Irp - %p, PeekContext - %p\n",
179 Irp,
180 PeekContext);
181
182 FdoExtension = CONTAINING_RECORD(Csq,
183 USBPORT_DEVICE_EXTENSION,
184 BadRequestIoCsq);
185
186 ListHead = &FdoExtension->BadRequestList;
187
188 if (Irp)
189 {
190 NextEntry = Irp->Tail.Overlay.ListEntry.Flink;
191 }
192 else
193 {
194 NextEntry = ListHead->Flink;
195 }
196
197 while (NextEntry != ListHead)
198 {
199 NextIrp = CONTAINING_RECORD(NextEntry,
200 IRP,
201 Tail.Overlay.ListEntry);
202
203 if (!PeekContext)
204 break;
205
206 NextEntry = NextEntry->Flink;
207 }
208
209 return NextIrp;
210 }
211
212 VOID
213 NTAPI
USBPORT_AcquireBadRequestLock(IN PIO_CSQ Csq,IN PKIRQL Irql)214 USBPORT_AcquireBadRequestLock(IN PIO_CSQ Csq,
215 IN PKIRQL Irql)
216 {
217 PUSBPORT_DEVICE_EXTENSION FdoExtension;
218
219 DPRINT_QUEUE("USBPORT_AcquireBadRequestLock: ... \n");
220
221 FdoExtension = CONTAINING_RECORD(Csq,
222 USBPORT_DEVICE_EXTENSION,
223 BadRequestIoCsq);
224
225 KeAcquireSpinLock(&FdoExtension->BadRequestIoCsqSpinLock, Irql);
226 }
227
228 VOID
229 NTAPI
USBPORT_ReleaseBadRequestLock(IN PIO_CSQ Csq,IN KIRQL Irql)230 USBPORT_ReleaseBadRequestLock(IN PIO_CSQ Csq,
231 IN KIRQL Irql)
232 {
233 PUSBPORT_DEVICE_EXTENSION FdoExtension;
234
235 DPRINT_QUEUE("USBPORT_ReleaseBadRequestLock: ... \n");
236
237 FdoExtension = CONTAINING_RECORD(Csq,
238 USBPORT_DEVICE_EXTENSION,
239 BadRequestIoCsq);
240
241 KeReleaseSpinLock(&FdoExtension->BadRequestIoCsqSpinLock, Irql);
242 }
243
244 VOID
245 NTAPI
USBPORT_CompleteCanceledBadRequest(IN PIO_CSQ Csq,IN PIRP Irp)246 USBPORT_CompleteCanceledBadRequest(IN PIO_CSQ Csq,
247 IN PIRP Irp)
248 {
249 PUSBPORT_DEVICE_EXTENSION FdoExtension;
250
251 DPRINT_QUEUE("USBPORT_CompleteCanceledBadRequest: Irp - %p\n", Irp);
252
253 FdoExtension = CONTAINING_RECORD(Csq,
254 USBPORT_DEVICE_EXTENSION,
255 BadRequestIoCsq);
256
257 InterlockedDecrement(&FdoExtension->BadRequestLockCounter);
258
259 Irp->IoStatus.Status = STATUS_CANCELLED;
260 Irp->IoStatus.Information = 0;
261 IoCompleteRequest(Irp, IO_NO_INCREMENT);
262 }
263
264 VOID
265 NTAPI
USBPORT_InsertIrpInTable(IN PUSBPORT_IRP_TABLE IrpTable,IN PIRP Irp)266 USBPORT_InsertIrpInTable(IN PUSBPORT_IRP_TABLE IrpTable,
267 IN PIRP Irp)
268 {
269 ULONG ix;
270
271 DPRINT_CORE("USBPORT_InsertIrpInTable: IrpTable - %p, Irp - %p\n",
272 IrpTable,
273 Irp);
274
275 ASSERT(IrpTable != NULL);
276
277 while (TRUE)
278 {
279 for (ix = 0; ix < 0x200; ix++)
280 {
281 if (IrpTable->irp[ix] == NULL)
282 {
283 IrpTable->irp[ix] = Irp;
284
285 if (ix > 0)
286 {
287 DPRINT_CORE("USBPORT_InsertIrpInTable: ix - %x\n", ix);
288 }
289
290 return;
291 }
292 }
293
294 if (ix != 0x200)
295 {
296 KeBugCheckEx(BUGCODE_USB_DRIVER, 1, 0, 0, 0);
297 }
298
299 IrpTable->LinkNextTable = ExAllocatePoolWithTag(NonPagedPool,
300 sizeof(USBPORT_IRP_TABLE),
301 USB_PORT_TAG);
302
303 if (IrpTable->LinkNextTable == NULL)
304 {
305 KeBugCheckEx(BUGCODE_USB_DRIVER, 1, 0, 0, 0);
306 }
307
308 RtlZeroMemory(IrpTable->LinkNextTable, sizeof(USBPORT_IRP_TABLE));
309
310 IrpTable = IrpTable->LinkNextTable;
311 }
312 }
313
314 PIRP
315 NTAPI
USBPORT_RemoveIrpFromTable(IN PUSBPORT_IRP_TABLE IrpTable,IN PIRP Irp)316 USBPORT_RemoveIrpFromTable(IN PUSBPORT_IRP_TABLE IrpTable,
317 IN PIRP Irp)
318 {
319 ULONG ix;
320
321 DPRINT_CORE("USBPORT_RemoveIrpFromTable: IrpTable - %p, Irp - %p\n",
322 IrpTable,
323 Irp);
324
325 ASSERT(IrpTable != NULL);
326
327 while (TRUE)
328 {
329 for (ix = 0; ix < 0x200; ix++)
330 {
331 if (IrpTable->irp[ix] == Irp)
332 {
333 IrpTable->irp[ix] = NULL;
334
335 if (ix > 0)
336 {
337 DPRINT_CORE("USBPORT_RemoveIrpFromTable: ix - %x\n", ix);
338 }
339
340 return Irp;
341 }
342 }
343
344 if (IrpTable->LinkNextTable == NULL)
345 break;
346
347 IrpTable = IrpTable->LinkNextTable;
348 continue;
349 }
350
351 DPRINT1("USBPORT_RemoveIrpFromTable: return NULL. ix - %x\n", ix);
352 return NULL;
353 }
354
355 PIRP
356 NTAPI
USBPORT_RemoveActiveTransferIrp(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp)357 USBPORT_RemoveActiveTransferIrp(IN PDEVICE_OBJECT FdoDevice,
358 IN PIRP Irp)
359 {
360 PUSBPORT_DEVICE_EXTENSION FdoExtension;
361
362 DPRINT_CORE("USBPORT_RemoveActiveTransferIrp: Irp - %p\n", Irp);
363 FdoExtension = FdoDevice->DeviceExtension;
364 return USBPORT_RemoveIrpFromTable(FdoExtension->ActiveIrpTable, Irp);
365 }
366
367 PIRP
368 NTAPI
USBPORT_RemovePendingTransferIrp(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp)369 USBPORT_RemovePendingTransferIrp(IN PDEVICE_OBJECT FdoDevice,
370 IN PIRP Irp)
371 {
372 PUSBPORT_DEVICE_EXTENSION FdoExtension;
373
374 DPRINT_CORE("USBPORT_RemovePendingTransferIrp: Irp - %p\n", Irp);
375 FdoExtension = FdoDevice->DeviceExtension;
376 return USBPORT_RemoveIrpFromTable(FdoExtension->PendingIrpTable, Irp);
377 }
378
379 VOID
380 NTAPI
USBPORT_FindUrbInIrpTable(IN PUSBPORT_IRP_TABLE IrpTable,IN PURB Urb,IN PIRP Irp)381 USBPORT_FindUrbInIrpTable(IN PUSBPORT_IRP_TABLE IrpTable,
382 IN PURB Urb,
383 IN PIRP Irp)
384 {
385 ULONG ix;
386 PIRP irp;
387 PURB urbIn;
388
389 DPRINT_CORE("USBPORT_FindUrbInIrpTable: IrpTable - %p, Urb - %p, Irp - %p\n",
390 IrpTable,
391 Urb,
392 Irp);
393
394 ASSERT(IrpTable != NULL);
395
396 do
397 {
398 for (ix = 0; ix < 0x200; ix++)
399 {
400 irp = IrpTable->irp[ix];
401
402 if (irp)
403 {
404 urbIn = URB_FROM_IRP(irp);
405
406 if (urbIn == Urb)
407 {
408 if (irp == Irp)
409 {
410 KeBugCheckEx(BUGCODE_USB_DRIVER,
411 4,
412 (ULONG_PTR)irp,
413 (ULONG_PTR)urbIn,
414 0);
415 }
416
417 KeBugCheckEx(BUGCODE_USB_DRIVER,
418 2,
419 (ULONG_PTR)irp,
420 (ULONG_PTR)Irp,
421 (ULONG_PTR)urbIn);
422 }
423 }
424 }
425
426 IrpTable = IrpTable->LinkNextTable;
427 }
428 while (IrpTable);
429 }
430
431 PIRP
432 NTAPI
USBPORT_FindIrpInTable(IN PUSBPORT_IRP_TABLE IrpTable,IN PIRP Irp)433 USBPORT_FindIrpInTable(IN PUSBPORT_IRP_TABLE IrpTable,
434 IN PIRP Irp)
435 {
436 ULONG ix;
437 PIRP irp;
438
439 DPRINT_CORE("USBPORT_FindIrpInTable: IrpTable - %p, Irp - %p\n",
440 IrpTable,
441 Irp);
442
443 ASSERT(IrpTable != NULL);
444
445 do
446 {
447 for (ix = 0; ix < 0x200; ix++)
448 {
449 irp = IrpTable->irp[ix];
450
451 if (irp && irp == Irp)
452 {
453 return irp;
454 }
455 }
456
457 IrpTable = IrpTable->LinkNextTable;
458 }
459 while (IrpTable->LinkNextTable);
460
461 DPRINT_CORE("USBPORT_FindIrpInTable: Not found!!!\n");
462 return NULL;
463 }
464
465 PIRP
466 NTAPI
USBPORT_FindActiveTransferIrp(IN PDEVICE_OBJECT FdoDevice,IN PIRP Irp)467 USBPORT_FindActiveTransferIrp(IN PDEVICE_OBJECT FdoDevice,
468 IN PIRP Irp)
469 {
470 PUSBPORT_DEVICE_EXTENSION FdoExtension;
471
472 DPRINT_CORE("USBPORT_FindActiveTransferIrp: Irp - %p\n", Irp);
473 FdoExtension = FdoDevice->DeviceExtension;
474 return USBPORT_FindIrpInTable(FdoExtension->ActiveIrpTable, Irp);
475 }
476
477 VOID
478 NTAPI
USBPORT_CancelPendingTransferIrp(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)479 USBPORT_CancelPendingTransferIrp(IN PDEVICE_OBJECT DeviceObject,
480 IN PIRP Irp)
481 {
482 PURB Urb;
483 PUSBPORT_TRANSFER Transfer;
484 PUSBPORT_ENDPOINT Endpoint;
485 PDEVICE_OBJECT FdoDevice;
486 PUSBPORT_DEVICE_EXTENSION FdoExtension;
487 KIRQL OldIrql;
488 PIRP irp;
489
490 DPRINT_CORE("USBPORT_CancelPendingTransferIrp: DeviceObject - %p, Irp - %p\n",
491 DeviceObject,
492 Irp);
493
494 Urb = URB_FROM_IRP(Irp);
495 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0];
496 Endpoint = Transfer->Endpoint;
497
498 FdoDevice = Endpoint->FdoDevice;
499 FdoExtension = DeviceObject->DeviceExtension;
500
501 IoReleaseCancelSpinLock(Irp->CancelIrql);
502
503 KeAcquireSpinLock(&FdoExtension->FlushPendingTransferSpinLock, &OldIrql);
504
505 irp = USBPORT_RemovePendingTransferIrp(FdoDevice, Irp);
506
507 if (!irp)
508 {
509 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock,
510 OldIrql);
511 return;
512 }
513
514 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock);
515
516 RemoveEntryList(&Transfer->TransferLink);
517
518 Transfer->TransferLink.Flink = NULL;
519 Transfer->TransferLink.Blink = NULL;
520
521 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
522 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock, OldIrql);
523
524 USBPORT_CompleteTransfer(Transfer->Urb, USBD_STATUS_CANCELED);
525 }
526
527 VOID
528 NTAPI
USBPORT_CancelActiveTransferIrp(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)529 USBPORT_CancelActiveTransferIrp(IN PDEVICE_OBJECT DeviceObject,
530 IN PIRP Irp)
531 {
532 PUSBPORT_RHDEVICE_EXTENSION PdoExtension;
533 PDEVICE_OBJECT FdoDevice;
534 PUSBPORT_DEVICE_EXTENSION FdoExtension;
535 PURB Urb;
536 PUSBPORT_TRANSFER Transfer;
537 PUSBPORT_ENDPOINT Endpoint;
538 PIRP irp;
539 PUSBPORT_TRANSFER SplitTransfer;
540 PLIST_ENTRY Entry;
541 KIRQL OldIrql;
542
543 DPRINT_CORE("USBPORT_CancelActiveTransferIrp: Irp - %p\n", Irp);
544
545 PdoExtension = DeviceObject->DeviceExtension;
546 FdoDevice = PdoExtension->FdoDevice;
547 FdoExtension = FdoDevice->DeviceExtension;
548
549 IoReleaseCancelSpinLock(Irp->CancelIrql);
550
551 KeAcquireSpinLock(&FdoExtension->FlushTransferSpinLock, &OldIrql);
552
553 irp = USBPORT_FindActiveTransferIrp(FdoDevice, Irp);
554
555 if (!irp)
556 {
557 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql);
558 return;
559 }
560
561 Urb = URB_FROM_IRP(irp);
562 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0];
563 Endpoint = Transfer->Endpoint;
564
565 DPRINT_CORE("USBPORT_CancelActiveTransferIrp: irp - %p, Urb - %p, Transfer - %p\n",
566 irp,
567 Urb,
568 Transfer);
569
570 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock);
571
572 Transfer->Flags |= TRANSFER_FLAG_CANCELED;
573
574 if (Transfer->Flags & TRANSFER_FLAG_PARENT)
575 {
576 KeAcquireSpinLockAtDpcLevel(&Transfer->TransferSpinLock);
577
578 Entry = Transfer->SplitTransfersList.Flink;
579
580 while (Entry && Entry != &Transfer->SplitTransfersList)
581 {
582 SplitTransfer = CONTAINING_RECORD(Entry,
583 USBPORT_TRANSFER,
584 SplitLink);
585
586 SplitTransfer->Flags |= TRANSFER_FLAG_CANCELED;
587
588 Entry = Entry->Flink;
589 }
590
591 KeReleaseSpinLockFromDpcLevel(&Transfer->TransferSpinLock);
592 }
593
594 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
595 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql);
596
597 USBPORT_InvalidateEndpointHandler(FdoDevice,
598 Endpoint,
599 INVALIDATE_ENDPOINT_WORKER_THREAD);
600 return;
601 }
602
603 VOID
604 NTAPI
USBPORT_FlushAbortList(IN PUSBPORT_ENDPOINT Endpoint)605 USBPORT_FlushAbortList(IN PUSBPORT_ENDPOINT Endpoint)
606 {
607 PLIST_ENTRY Entry;
608 PUSBPORT_TRANSFER Transfer;
609 PLIST_ENTRY AbortList;
610 LIST_ENTRY List;
611 NTSTATUS Status;
612 PIRP Irp;
613 PURB Urb;
614 PUSBPORT_DEVICE_HANDLE DeviceHandle = NULL;
615
616 DPRINT_CORE("USBPORT_FlushAbortList: Endpoint - %p\n", Endpoint);
617
618 InitializeListHead(&List);
619
620 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql);
621
622 if (IsListEmpty(&Endpoint->AbortList))
623 {
624 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
625 Endpoint->EndpointOldIrql);
626 return;
627 }
628
629 Entry = Endpoint->PendingTransferList.Flink;
630
631 while (Entry && Entry != &Endpoint->PendingTransferList)
632 {
633 Transfer = CONTAINING_RECORD(Entry,
634 USBPORT_TRANSFER,
635 TransferLink);
636
637 if (Transfer->Flags & TRANSFER_FLAG_ABORTED)
638 {
639 DPRINT_CORE("USBPORT_FlushAbortList: Aborted PendingTransfer - %p\n",
640 Transfer);
641
642 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
643 Endpoint->EndpointOldIrql);
644 return;
645 }
646
647 Entry = Transfer->TransferLink.Flink;
648 }
649
650 Entry = Endpoint->TransferList.Flink;
651
652 while (Entry && Entry != &Endpoint->TransferList)
653 {
654 Transfer = CONTAINING_RECORD(Entry,
655 USBPORT_TRANSFER,
656 TransferLink);
657
658 if (Transfer->Flags & TRANSFER_FLAG_ABORTED)
659 {
660 DPRINT_CORE("USBPORT_FlushAbortList: Aborted ActiveTransfer - %p\n",
661 Transfer);
662
663 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
664 Endpoint->EndpointOldIrql);
665 return;
666 }
667
668 Entry = Transfer->TransferLink.Flink;
669 }
670
671 AbortList = &Endpoint->AbortList;
672
673 while (!IsListEmpty(AbortList))
674 {
675 //DbgBreakPoint();
676
677 Irp = CONTAINING_RECORD(AbortList->Flink,
678 IRP,
679 Tail.Overlay.ListEntry);
680
681 RemoveHeadList(AbortList);
682 InsertTailList(&List, &Irp->Tail.Overlay.ListEntry);
683 }
684
685 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
686
687 while (!IsListEmpty(&List))
688 {
689 //DbgBreakPoint();
690
691 Irp = CONTAINING_RECORD(List.Flink,
692 IRP,
693 Tail.Overlay.ListEntry);
694
695 RemoveHeadList(&List);
696
697 Urb = URB_FROM_IRP(Irp);
698
699 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
700 InterlockedDecrement(&DeviceHandle->DeviceHandleLock);
701
702 Status = USBPORT_USBDStatusToNtStatus(Urb, USBD_STATUS_SUCCESS);
703
704 DPRINT_CORE("USBPORT_FlushAbortList: complete Irp - %p\n", Irp);
705
706 Irp->IoStatus.Status = Status;
707 Irp->IoStatus.Information = 0;
708 IoCompleteRequest(Irp, IO_NO_INCREMENT);
709 }
710 }
711
712 VOID
713 NTAPI
USBPORT_FlushCancelList(IN PUSBPORT_ENDPOINT Endpoint)714 USBPORT_FlushCancelList(IN PUSBPORT_ENDPOINT Endpoint)
715 {
716 PDEVICE_OBJECT FdoDevice;
717 PUSBPORT_DEVICE_EXTENSION FdoExtension;
718 PUSBPORT_TRANSFER Transfer;
719 PIRP Irp;
720 KIRQL OldIrql;
721 KIRQL PrevIrql;
722
723 DPRINT_CORE("USBPORT_FlushCancelList: ... \n");
724
725 FdoDevice = Endpoint->FdoDevice;
726 FdoExtension = FdoDevice->DeviceExtension;
727
728 KeAcquireSpinLock(&FdoExtension->FlushTransferSpinLock, &OldIrql);
729 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock);
730
731 while (!IsListEmpty(&Endpoint->CancelList))
732 {
733 Transfer = CONTAINING_RECORD(Endpoint->CancelList.Flink,
734 USBPORT_TRANSFER,
735 TransferLink);
736
737 RemoveHeadList(&Endpoint->CancelList);
738
739 Irp = Transfer->Irp;
740
741 if (Irp)
742 {
743 DPRINT("USBPORT_FlushCancelList: Irp - %p\n", Irp);
744
745 IoAcquireCancelSpinLock(&PrevIrql);
746 IoSetCancelRoutine(Irp, NULL);
747 IoReleaseCancelSpinLock(PrevIrql);
748
749 USBPORT_RemoveActiveTransferIrp(FdoDevice, Irp);
750 }
751
752 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
753 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql);
754
755 if (Endpoint->Flags & ENDPOINT_FLAG_NUKE)
756 {
757 USBPORT_CompleteTransfer(Transfer->Urb, USBD_STATUS_DEVICE_GONE);
758 }
759 else
760 {
761 if (Transfer->Flags & TRANSFER_FLAG_DEVICE_GONE)
762 {
763 USBPORT_CompleteTransfer(Transfer->Urb,
764 USBD_STATUS_DEVICE_GONE);
765 }
766 else
767 {
768 USBPORT_CompleteTransfer(Transfer->Urb,
769 USBD_STATUS_CANCELED);
770 }
771 }
772
773 KeAcquireSpinLock(&FdoExtension->FlushTransferSpinLock, &OldIrql);
774 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock);
775 }
776
777 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
778 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql);
779
780 USBPORT_FlushAbortList(Endpoint);
781 }
782
783 VOID
784 NTAPI
USBPORT_FlushPendingTransfers(IN PUSBPORT_ENDPOINT Endpoint)785 USBPORT_FlushPendingTransfers(IN PUSBPORT_ENDPOINT Endpoint)
786 {
787 PDEVICE_OBJECT FdoDevice;
788 PUSBPORT_DEVICE_EXTENSION FdoExtension;
789 BOOLEAN IsMapTransfer;
790 BOOLEAN IsEnd = FALSE;
791 PLIST_ENTRY List;
792 PUSBPORT_TRANSFER Transfer;
793 PURB Urb;
794 PIRP Irp;
795 KIRQL OldIrql;
796 BOOLEAN Result;
797
798 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint - %p\n", Endpoint);
799
800 FdoDevice = Endpoint->FdoDevice;
801 FdoExtension = FdoDevice->DeviceExtension;
802
803 if (InterlockedCompareExchange(&Endpoint->FlushPendingLock, 1, 0))
804 {
805 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint Locked \n");
806 return;
807 }
808
809 while (TRUE)
810 {
811 IsMapTransfer = 0;
812
813 KeAcquireSpinLock(&FdoExtension->FlushPendingTransferSpinLock,
814 &OldIrql);
815
816 KeAcquireSpinLockAtDpcLevel(&Endpoint->EndpointSpinLock);
817
818 if (FdoExtension->Flags & USBPORT_FLAG_HC_SUSPEND)
819 {
820 IsEnd = TRUE;
821
822 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
823 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock,
824 OldIrql);
825 goto Next;
826 }
827
828 if (!(Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0))
829 {
830 if (!IsListEmpty(&Endpoint->TransferList))
831 {
832 List = Endpoint->TransferList.Flink;
833
834 while (List && List != &Endpoint->TransferList)
835 {
836 Transfer = CONTAINING_RECORD(List,
837 USBPORT_TRANSFER,
838 TransferLink);
839
840 if (!(Transfer->Flags & TRANSFER_FLAG_SUBMITED))
841 {
842 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
843 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock,
844 OldIrql);
845
846 IsEnd = TRUE;
847 goto Worker;
848 }
849
850 List = Transfer->TransferLink.Flink;
851 }
852 }
853 }
854
855 List = Endpoint->PendingTransferList.Flink;
856
857 if (List == NULL || IsListEmpty(&Endpoint->PendingTransferList))
858 {
859 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
860 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock,
861 OldIrql);
862
863 IsEnd = TRUE;
864 goto Worker;
865 }
866
867 Transfer = CONTAINING_RECORD(List,
868 USBPORT_TRANSFER,
869 TransferLink);
870
871 if (Transfer->Irp)
872 {
873 DPRINT_CORE("USBPORT_FlushPendingTransfers: Transfer->Irp->CancelRoutine - %p\n",
874 Transfer->Irp->CancelRoutine);
875 }
876
877 if (Transfer->Irp &&
878 (IoSetCancelRoutine(Transfer->Irp, NULL) == NULL))
879 {
880 DPRINT_CORE("USBPORT_FlushPendingTransfers: Transfer->Irp - %p\n",
881 Transfer->Irp);
882
883 Transfer = NULL;
884 IsEnd = TRUE;
885 }
886
887 if (!Transfer)
888 {
889 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
890 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock,
891 OldIrql);
892
893 if (IsMapTransfer)
894 {
895 USBPORT_FlushMapTransfers(FdoDevice);
896 goto Next;
897 }
898
899 goto Worker;
900 }
901
902 Irp = Transfer->Irp;
903 Urb = Transfer->Urb;
904
905 RemoveEntryList(&Transfer->TransferLink);
906 Transfer->TransferLink.Flink = NULL;
907 Transfer->TransferLink.Blink = NULL;
908
909 if (Irp)
910 {
911 Irp = USBPORT_RemovePendingTransferIrp(FdoDevice, Irp);
912 }
913
914 KeReleaseSpinLockFromDpcLevel(&Endpoint->EndpointSpinLock);
915 KeReleaseSpinLock(&FdoExtension->FlushPendingTransferSpinLock,
916 OldIrql);
917
918 KeAcquireSpinLock(&FdoExtension->FlushTransferSpinLock, &OldIrql);
919
920 if (Irp)
921 {
922 IoSetCancelRoutine(Irp, USBPORT_CancelActiveTransferIrp);
923
924 if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
925 {
926 DPRINT_CORE("USBPORT_FlushPendingTransfers: irp - %p\n", Irp);
927
928 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock,
929 OldIrql);
930
931 USBPORT_CompleteTransfer(Transfer->Urb, USBD_STATUS_CANCELED);
932 goto Worker;
933 }
934
935 USBPORT_FindUrbInIrpTable(FdoExtension->ActiveIrpTable, Urb, Irp);
936 USBPORT_InsertIrpInTable(FdoExtension->ActiveIrpTable, Irp);
937 }
938
939 IsMapTransfer = USBPORT_QueueActiveUrbToEndpoint(Endpoint, Urb);
940
941 KeReleaseSpinLock(&FdoExtension->FlushTransferSpinLock, OldIrql);
942
943 if (IsMapTransfer)
944 {
945 USBPORT_FlushMapTransfers(FdoDevice);
946 goto Next;
947 }
948
949 Worker:
950 KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
951 Result = USBPORT_EndpointWorker(Endpoint, FALSE);
952 KeLowerIrql(OldIrql);
953
954 if (Result)
955 USBPORT_InvalidateEndpointHandler(FdoDevice,
956 Endpoint,
957 INVALIDATE_ENDPOINT_WORKER_THREAD);
958
959 Next:
960 if (IsEnd)
961 {
962 InterlockedDecrement(&Endpoint->FlushPendingLock);
963 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint Unlocked. Exit\n");
964 return;
965 }
966 }
967 }
968
969 VOID
970 NTAPI
USBPORT_QueuePendingUrbToEndpoint(IN PUSBPORT_ENDPOINT Endpoint,IN PURB Urb)971 USBPORT_QueuePendingUrbToEndpoint(IN PUSBPORT_ENDPOINT Endpoint,
972 IN PURB Urb)
973 {
974 PUSBPORT_TRANSFER Transfer;
975
976 DPRINT_CORE("USBPORT_QueuePendingUrbToEndpoint: Endpoint - %p, Urb - %p\n",
977 Endpoint,
978 Urb);
979
980 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0];
981 //FIXME USBPORT_ResetEndpointIdle();
982 InsertTailList(&Endpoint->PendingTransferList, &Transfer->TransferLink);
983 Urb->UrbHeader.Status = USBD_STATUS_PENDING;
984 }
985
986 BOOLEAN
987 NTAPI
USBPORT_QueueActiveUrbToEndpoint(IN PUSBPORT_ENDPOINT Endpoint,IN PURB Urb)988 USBPORT_QueueActiveUrbToEndpoint(IN PUSBPORT_ENDPOINT Endpoint,
989 IN PURB Urb)
990 {
991 PUSBPORT_TRANSFER Transfer;
992 PDEVICE_OBJECT FdoDevice;
993 PUSBPORT_DEVICE_EXTENSION FdoExtension;
994 PUSBPORT_DEVICE_HANDLE DeviceHandle;
995 KIRQL OldIrql;
996
997 DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: Endpoint - %p, Urb - %p\n",
998 Endpoint,
999 Urb);
1000
1001 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0];
1002 FdoDevice = Endpoint->FdoDevice;
1003 FdoExtension = FdoDevice->DeviceExtension;
1004
1005 KeAcquireSpinLock(&Endpoint->EndpointSpinLock,
1006 &Endpoint->EndpointOldIrql);
1007
1008 if ((Endpoint->Flags & ENDPOINT_FLAG_NUKE) ||
1009 (Transfer->Flags & TRANSFER_FLAG_ABORTED))
1010 {
1011 InsertTailList(&Endpoint->CancelList, &Transfer->TransferLink);
1012
1013 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
1014 Endpoint->EndpointOldIrql);
1015
1016 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return FALSE\n");
1017 return FALSE;
1018 }
1019
1020 if (Transfer->TransferParameters.TransferBufferLength == 0 ||
1021 !(Endpoint->Flags & ENDPOINT_FLAG_DMA_TYPE))
1022 {
1023 InsertTailList(&Endpoint->TransferList, &Transfer->TransferLink);
1024
1025 KeReleaseSpinLock(&Endpoint->EndpointSpinLock,
1026 Endpoint->EndpointOldIrql);
1027
1028 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return FALSE\n");
1029 return FALSE;
1030 }
1031
1032 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
1033
1034 KeAcquireSpinLock(&FdoExtension->MapTransferSpinLock, &OldIrql);
1035
1036 InsertTailList(&FdoExtension->MapTransferList, &Transfer->TransferLink);
1037
1038 DeviceHandle = Transfer->Urb->UrbHeader.UsbdDeviceHandle;
1039 InterlockedIncrement(&DeviceHandle->DeviceHandleLock);
1040
1041 KeReleaseSpinLock(&FdoExtension->MapTransferSpinLock, OldIrql);
1042
1043 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return TRUE\n");
1044 return TRUE;
1045 }
1046
1047 VOID
1048 NTAPI
USBPORT_QueuePendingTransferIrp(IN PIRP Irp)1049 USBPORT_QueuePendingTransferIrp(IN PIRP Irp)
1050 {
1051 PURB Urb;
1052 PUSBPORT_TRANSFER Transfer;
1053 PUSBPORT_ENDPOINT Endpoint;
1054 PDEVICE_OBJECT FdoDevice;
1055 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1056
1057 DPRINT_CORE("USBPORT_QueuePendingTransferIrp: Irp - %p\n", Irp);
1058
1059 Urb = URB_FROM_IRP(Irp);
1060
1061 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0];
1062 Endpoint = Transfer->Endpoint;
1063
1064 FdoDevice = Endpoint->FdoDevice;
1065 FdoExtension = FdoDevice->DeviceExtension;
1066
1067 Irp->IoStatus.Status = STATUS_PENDING;
1068 IoMarkIrpPending(Irp);
1069
1070 IoSetCancelRoutine(Irp, USBPORT_CancelPendingTransferIrp);
1071
1072 if (Irp->Cancel && IoSetCancelRoutine(Irp, NULL))
1073 {
1074 USBPORT_CompleteTransfer(Urb, USBD_STATUS_CANCELED);
1075 }
1076 else
1077 {
1078 USBPORT_InsertIrpInTable(FdoExtension->PendingIrpTable, Irp);
1079 USBPORT_QueuePendingUrbToEndpoint(Endpoint, Urb);
1080 }
1081 }
1082
1083 VOID
1084 NTAPI
USBPORT_QueueTransferUrb(IN PURB Urb)1085 USBPORT_QueueTransferUrb(IN PURB Urb)
1086 {
1087 PUSBPORT_TRANSFER Transfer;
1088 PUSBPORT_ENDPOINT Endpoint;
1089 PIRP Irp;
1090 PUSBPORT_DEVICE_HANDLE DeviceHandle;
1091 PUSBPORT_TRANSFER_PARAMETERS Parameters;
1092
1093 DPRINT_CORE("USBPORT_QueueTransferUrb: Urb - %p\n", Urb);
1094
1095 if (Urb->UrbControlTransfer.TransferFlags & USBD_DEFAULT_PIPE_TRANSFER)
1096 Urb->UrbHeader.Function = URB_FUNCTION_CONTROL_TRANSFER;
1097
1098 Transfer = Urb->UrbControlTransfer.hca.Reserved8[0];
1099 Parameters = &Transfer->TransferParameters;
1100
1101 Endpoint = Transfer->Endpoint;
1102 Endpoint->Flags &= ~ENDPOINT_FLAG_QUEUENE_EMPTY;
1103
1104 Parameters->TransferBufferLength = Urb->UrbControlTransfer.TransferBufferLength;
1105 Parameters->TransferFlags = Urb->UrbControlTransfer.TransferFlags;
1106
1107 Transfer->TransferBufferMDL = Urb->UrbControlTransfer.TransferBufferMDL;
1108
1109 if (Urb->UrbControlTransfer.TransferFlags & USBD_TRANSFER_DIRECTION_IN)
1110 {
1111 Transfer->Direction = USBPORT_DMA_DIRECTION_FROM_DEVICE;
1112 }
1113 else
1114 {
1115 Transfer->Direction = USBPORT_DMA_DIRECTION_TO_DEVICE;
1116 }
1117
1118 if (Endpoint->EndpointProperties.TransferType == USBPORT_TRANSFER_TYPE_CONTROL)
1119 {
1120 RtlCopyMemory(&Parameters->SetupPacket,
1121 Urb->UrbControlTransfer.SetupPacket,
1122 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET));
1123 }
1124
1125 DPRINT_URB("... URB TransferBufferLength - %x\n",
1126 Urb->UrbControlTransfer.TransferBufferLength);
1127
1128 Urb->UrbControlTransfer.TransferBufferLength = 0;
1129
1130 Irp = Transfer->Irp;
1131
1132 if (Irp)
1133 {
1134 USBPORT_QueuePendingTransferIrp(Irp);
1135 }
1136 else
1137 {
1138 USBPORT_QueuePendingUrbToEndpoint(Endpoint, Urb);
1139 }
1140
1141 DeviceHandle = Urb->UrbHeader.UsbdDeviceHandle;
1142 InterlockedDecrement(&DeviceHandle->DeviceHandleLock);
1143
1144 USBPORT_FlushPendingTransfers(Endpoint);
1145
1146 DPRINT_URB("... URB TransferBufferLength - %x\n",
1147 Urb->UrbControlTransfer.TransferBufferLength);
1148
1149 if (Urb->UrbControlTransfer.TransferBufferLength)
1150 {
1151 PULONG Buffer;
1152 ULONG BufferLength;
1153 ULONG_PTR BufferEnd;
1154 ULONG ix;
1155
1156 Buffer = Urb->UrbControlTransfer.TransferBuffer;
1157 BufferLength = Urb->UrbControlTransfer.TransferBufferLength;
1158 BufferEnd = (ULONG_PTR)Buffer + BufferLength;
1159
1160 DPRINT_URB("URB TransferBuffer - %p\n", Buffer);
1161
1162 for (ix = 0; (ULONG_PTR)(Buffer + ix) < BufferEnd; ix++)
1163 {
1164 DPRINT_URB("Buffer[%02X] - %p\n", ix, Buffer[ix]);
1165 }
1166 }
1167 }
1168
1169 VOID
1170 NTAPI
USBPORT_FlushAllEndpoints(IN PDEVICE_OBJECT FdoDevice)1171 USBPORT_FlushAllEndpoints(IN PDEVICE_OBJECT FdoDevice)
1172 {
1173 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1174 PLIST_ENTRY Entry;
1175 PUSBPORT_ENDPOINT Endpoint;
1176 LIST_ENTRY List;
1177 KIRQL OldIrql;
1178
1179 DPRINT_CORE("USBPORT_FlushAllEndpoints: ... \n");
1180
1181 FdoExtension = FdoDevice->DeviceExtension;
1182
1183 KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql);
1184
1185 InitializeListHead(&List);
1186
1187 Entry = FdoExtension->EndpointList.Flink;
1188
1189 while (Entry && Entry != &FdoExtension->EndpointList)
1190 {
1191 Endpoint = CONTAINING_RECORD(Entry,
1192 USBPORT_ENDPOINT,
1193 EndpointLink);
1194
1195 if (USBPORT_GetEndpointState(Endpoint) != USBPORT_ENDPOINT_CLOSED)
1196 {
1197 InsertTailList(&List, &Endpoint->FlushLink);
1198 }
1199
1200 Entry = Endpoint->EndpointLink.Flink;
1201 }
1202
1203 KeReleaseSpinLock(&FdoExtension->EndpointListSpinLock, OldIrql);
1204
1205 while (!IsListEmpty(&List))
1206 {
1207 Endpoint = CONTAINING_RECORD(List.Flink,
1208 USBPORT_ENDPOINT,
1209 FlushLink);
1210
1211 RemoveHeadList(&List);
1212
1213 Endpoint->FlushLink.Flink = NULL;
1214 Endpoint->FlushLink.Blink = NULL;
1215
1216 if (!IsListEmpty(&Endpoint->PendingTransferList))
1217 {
1218 USBPORT_FlushPendingTransfers(Endpoint);
1219 }
1220 }
1221
1222 DPRINT_CORE("USBPORT_FlushAllEndpoints: exit\n");
1223 }
1224
1225 ULONG
1226 NTAPI
USBPORT_KillEndpointActiveTransfers(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint)1227 USBPORT_KillEndpointActiveTransfers(IN PDEVICE_OBJECT FdoDevice,
1228 IN PUSBPORT_ENDPOINT Endpoint)
1229 {
1230 PLIST_ENTRY ActiveList;
1231 PUSBPORT_TRANSFER Transfer;
1232 ULONG KilledTransfers = 0;
1233
1234 DPRINT_CORE("USBPORT_KillEndpointActiveTransfers \n");
1235
1236 ActiveList = Endpoint->TransferList.Flink;
1237
1238 while (ActiveList && ActiveList != &Endpoint->TransferList)
1239 {
1240 ++KilledTransfers;
1241
1242 Transfer = CONTAINING_RECORD(ActiveList,
1243 USBPORT_TRANSFER,
1244 TransferLink);
1245
1246 Transfer->Flags |= TRANSFER_FLAG_ABORTED;
1247
1248 ActiveList = Transfer->TransferLink.Flink;
1249 }
1250
1251 USBPORT_FlushPendingTransfers(Endpoint);
1252 USBPORT_FlushCancelList(Endpoint);
1253
1254 return KilledTransfers;
1255 }
1256
1257 VOID
1258 NTAPI
USBPORT_FlushController(IN PDEVICE_OBJECT FdoDevice)1259 USBPORT_FlushController(IN PDEVICE_OBJECT FdoDevice)
1260 {
1261 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1262 PLIST_ENTRY Entry;
1263 PUSBPORT_ENDPOINT Endpoint;
1264 ULONG KilledTransfers;
1265 PLIST_ENTRY EndpointList;
1266 KIRQL OldIrql;
1267 LIST_ENTRY FlushList;
1268
1269 DPRINT_CORE("USBPORT_FlushController \n");
1270
1271 FdoExtension = FdoDevice->DeviceExtension;
1272
1273 EndpointList = &FdoExtension->EndpointList;
1274
1275 while (TRUE)
1276 {
1277 KeAcquireSpinLock(&FdoExtension->EndpointListSpinLock, &OldIrql);
1278
1279 InitializeListHead(&FlushList);
1280
1281 Entry = EndpointList->Flink;
1282
1283 if (!IsListEmpty(EndpointList))
1284 {
1285 while (Entry && Entry != EndpointList)
1286 {
1287 Endpoint = CONTAINING_RECORD(Entry,
1288 USBPORT_ENDPOINT,
1289 EndpointLink);
1290
1291 if (Endpoint->StateLast != USBPORT_ENDPOINT_REMOVE &&
1292 Endpoint->StateLast != USBPORT_ENDPOINT_CLOSED)
1293 {
1294 InterlockedIncrement(&Endpoint->LockCounter);
1295 InsertTailList(&FlushList, &Endpoint->FlushControllerLink);
1296 }
1297
1298 Entry = Endpoint->EndpointLink.Flink;
1299 }
1300 }
1301
1302 KeReleaseSpinLock(&FdoExtension->EndpointListSpinLock, OldIrql);
1303
1304 KilledTransfers = 0;
1305 while (!IsListEmpty(&FlushList))
1306 {
1307 Endpoint = CONTAINING_RECORD(FlushList.Flink,
1308 USBPORT_ENDPOINT,
1309 FlushControllerLink);
1310
1311 RemoveHeadList(&FlushList);
1312
1313 KilledTransfers += USBPORT_KillEndpointActiveTransfers(FdoDevice,
1314 Endpoint);
1315
1316 InterlockedDecrement(&Endpoint->LockCounter);
1317 }
1318
1319 if (!KilledTransfers)
1320 break;
1321
1322 USBPORT_Wait(FdoDevice, 100);
1323 }
1324 }
1325
1326 VOID
1327 NTAPI
USBPORT_BadRequestFlush(IN PDEVICE_OBJECT FdoDevice)1328 USBPORT_BadRequestFlush(IN PDEVICE_OBJECT FdoDevice)
1329 {
1330 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1331 PIRP Irp;
1332
1333 DPRINT_QUEUE("USBPORT_BadRequestFlush: ... \n");
1334
1335 FdoExtension = FdoDevice->DeviceExtension;
1336
1337 while (TRUE)
1338 {
1339 Irp = IoCsqRemoveNextIrp(&FdoExtension->BadRequestIoCsq, 0);
1340
1341 if (!Irp)
1342 break;
1343
1344 DPRINT1("USBPORT_BadRequestFlush: Irp - %p\n", Irp);
1345
1346 Irp->IoStatus.Status = STATUS_DEVICE_NOT_CONNECTED;
1347 Irp->IoStatus.Information = 0;
1348 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1349 }
1350 }
1351
1352 VOID
1353 NTAPI
USBPORT_AbortEndpoint(IN PDEVICE_OBJECT FdoDevice,IN PUSBPORT_ENDPOINT Endpoint,IN PIRP Irp)1354 USBPORT_AbortEndpoint(IN PDEVICE_OBJECT FdoDevice,
1355 IN PUSBPORT_ENDPOINT Endpoint,
1356 IN PIRP Irp)
1357 {
1358 PLIST_ENTRY PendingList;
1359 PUSBPORT_TRANSFER PendingTransfer;
1360 PLIST_ENTRY ActiveList;
1361 PUSBPORT_TRANSFER ActiveTransfer;
1362
1363 DPRINT_CORE("USBPORT_AbortEndpoint: Irp - %p\n", Irp);
1364
1365 KeAcquireSpinLock(&Endpoint->EndpointSpinLock, &Endpoint->EndpointOldIrql);
1366
1367 if (Irp)
1368 {
1369 InsertTailList(&Endpoint->AbortList, &Irp->Tail.Overlay.ListEntry);
1370 }
1371
1372 PendingList = Endpoint->PendingTransferList.Flink;
1373
1374 while (PendingList && PendingList != &Endpoint->PendingTransferList)
1375 {
1376 PendingTransfer = CONTAINING_RECORD(PendingList,
1377 USBPORT_TRANSFER,
1378 TransferLink);
1379
1380 DPRINT_CORE("USBPORT_AbortEndpoint: Abort PendingTransfer - %p\n",
1381 PendingTransfer);
1382
1383 PendingTransfer->Flags |= TRANSFER_FLAG_ABORTED;
1384
1385 PendingList = PendingTransfer->TransferLink.Flink;
1386 }
1387
1388 ActiveList = Endpoint->TransferList.Flink;
1389
1390 while (ActiveList && ActiveList != &Endpoint->TransferList)
1391 {
1392 ActiveTransfer = CONTAINING_RECORD(ActiveList,
1393 USBPORT_TRANSFER,
1394 TransferLink);
1395
1396 DPRINT_CORE("USBPORT_AbortEndpoint: Abort ActiveTransfer - %p\n",
1397 ActiveTransfer);
1398
1399 ActiveTransfer->Flags |= TRANSFER_FLAG_ABORTED;
1400
1401 if (Endpoint->Flags & ENDPOINT_FLAG_ABORTING)
1402 {
1403 ActiveTransfer->Flags |= TRANSFER_FLAG_DEVICE_GONE;
1404 }
1405
1406 ActiveList = ActiveTransfer->TransferLink.Flink;
1407 }
1408
1409 KeReleaseSpinLock(&Endpoint->EndpointSpinLock, Endpoint->EndpointOldIrql);
1410
1411 USBPORT_InvalidateEndpointHandler(FdoDevice,
1412 Endpoint,
1413 INVALIDATE_ENDPOINT_INT_NEXT_SOF);
1414
1415 USBPORT_FlushPendingTransfers(Endpoint);
1416 USBPORT_FlushCancelList(Endpoint);
1417 }
1418