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