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>
13 #define NDEBUG_USBPORT_CORE
14 #define NDEBUG_USBPORT_QUEUE
15 #define NDEBUG_USBPORT_URB
20 USBPORT_InsertIdleIrp(IN PIO_CSQ Csq
,
23 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
25 DPRINT_QUEUE("USBPORT_InsertIdleIrp: Irp - %p\n", Irp
);
27 FdoExtension
= CONTAINING_RECORD(Csq
,
28 USBPORT_DEVICE_EXTENSION
,
31 InsertTailList(&FdoExtension
->IdleIrpList
,
32 &Irp
->Tail
.Overlay
.ListEntry
);
37 USBPORT_RemoveIdleIrp(IN PIO_CSQ Csq
,
40 DPRINT_QUEUE("USBPORT_RemoveIdleIrp: Irp - %p\n", Irp
);
41 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
46 USBPORT_PeekNextIdleIrp(IN PIO_CSQ Csq
,
50 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
51 PLIST_ENTRY NextEntry
;
55 DPRINT_QUEUE("USBPORT_PeekNextIdleIrp: Irp - %p, PeekContext - %p\n",
59 FdoExtension
= CONTAINING_RECORD(Csq
,
60 USBPORT_DEVICE_EXTENSION
,
63 ListHead
= &FdoExtension
->IdleIrpList
;
67 NextEntry
= Irp
->Tail
.Overlay
.ListEntry
.Flink
;
71 NextEntry
= ListHead
->Flink
;
74 while (NextEntry
!= ListHead
)
76 NextIrp
= CONTAINING_RECORD(NextEntry
,
78 Tail
.Overlay
.ListEntry
);
83 NextEntry
= NextEntry
->Flink
;
91 USBPORT_AcquireIdleLock(IN PIO_CSQ Csq
,
94 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
96 DPRINT_QUEUE("USBPORT_AcquireIdleLock: ... \n");
98 FdoExtension
= CONTAINING_RECORD(Csq
,
99 USBPORT_DEVICE_EXTENSION
,
102 KeAcquireSpinLock(&FdoExtension
->IdleIoCsqSpinLock
, Irql
);
107 USBPORT_ReleaseIdleLock(IN PIO_CSQ Csq
,
110 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
112 DPRINT_QUEUE("USBPORT_ReleaseIdleLock: ... \n");
114 FdoExtension
= CONTAINING_RECORD(Csq
,
115 USBPORT_DEVICE_EXTENSION
,
118 KeReleaseSpinLock(&FdoExtension
->IdleIoCsqSpinLock
, Irql
);
123 USBPORT_CompleteCanceledIdleIrp(IN PIO_CSQ Csq
,
126 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
128 DPRINT_QUEUE("USBPORT_CompleteCanceledIdleIrp: ... \n");
130 FdoExtension
= CONTAINING_RECORD(Csq
,
131 USBPORT_DEVICE_EXTENSION
,
134 InterlockedDecrement(&FdoExtension
->IdleLockCounter
);
136 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
137 Irp
->IoStatus
.Information
= 0;
138 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
143 USBPORT_InsertBadRequest(IN PIO_CSQ Csq
,
146 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
148 DPRINT_QUEUE("USBPORT_InsertBadRequest: Irp - %p\n", Irp
);
150 FdoExtension
= CONTAINING_RECORD(Csq
,
151 USBPORT_DEVICE_EXTENSION
,
154 InsertTailList(&FdoExtension
->BadRequestList
,
155 &Irp
->Tail
.Overlay
.ListEntry
);
160 USBPORT_RemoveBadRequest(IN PIO_CSQ Csq
,
163 DPRINT_QUEUE("USBPORT_RemoveBadRequest: Irp - %p\n", Irp
);
164 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
169 USBPORT_PeekNextBadRequest(IN PIO_CSQ Csq
,
171 IN PVOID PeekContext
)
173 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
174 PLIST_ENTRY NextEntry
;
175 PLIST_ENTRY ListHead
;
178 DPRINT_QUEUE("USBPORT_PeekNextBadRequest: Irp - %p, PeekContext - %p\n",
182 FdoExtension
= CONTAINING_RECORD(Csq
,
183 USBPORT_DEVICE_EXTENSION
,
186 ListHead
= &FdoExtension
->BadRequestList
;
190 NextEntry
= Irp
->Tail
.Overlay
.ListEntry
.Flink
;
194 NextEntry
= ListHead
->Flink
;
197 while (NextEntry
!= ListHead
)
199 NextIrp
= CONTAINING_RECORD(NextEntry
,
201 Tail
.Overlay
.ListEntry
);
206 NextEntry
= NextEntry
->Flink
;
214 USBPORT_AcquireBadRequestLock(IN PIO_CSQ Csq
,
217 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
219 DPRINT_QUEUE("USBPORT_AcquireBadRequestLock: ... \n");
221 FdoExtension
= CONTAINING_RECORD(Csq
,
222 USBPORT_DEVICE_EXTENSION
,
225 KeAcquireSpinLock(&FdoExtension
->BadRequestIoCsqSpinLock
, Irql
);
230 USBPORT_ReleaseBadRequestLock(IN PIO_CSQ Csq
,
233 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
235 DPRINT_QUEUE("USBPORT_ReleaseBadRequestLock: ... \n");
237 FdoExtension
= CONTAINING_RECORD(Csq
,
238 USBPORT_DEVICE_EXTENSION
,
241 KeReleaseSpinLock(&FdoExtension
->BadRequestIoCsqSpinLock
, Irql
);
246 USBPORT_CompleteCanceledBadRequest(IN PIO_CSQ Csq
,
249 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
251 DPRINT_QUEUE("USBPORT_CompleteCanceledBadRequest: Irp - %p\n", Irp
);
253 FdoExtension
= CONTAINING_RECORD(Csq
,
254 USBPORT_DEVICE_EXTENSION
,
257 InterlockedDecrement(&FdoExtension
->BadRequestLockCounter
);
259 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
260 Irp
->IoStatus
.Information
= 0;
261 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
266 USBPORT_InsertIrpInTable(IN PUSBPORT_IRP_TABLE IrpTable
,
271 DPRINT_CORE("USBPORT_InsertIrpInTable: IrpTable - %p, Irp - %p\n",
275 ASSERT(IrpTable
!= NULL
);
279 for (ix
= 0; ix
< 0x200; ix
++)
281 if (IrpTable
->irp
[ix
] == NULL
)
283 IrpTable
->irp
[ix
] = Irp
;
287 DPRINT_CORE("USBPORT_InsertIrpInTable: ix - %x\n", ix
);
296 KeBugCheckEx(BUGCODE_USB_DRIVER
, 1, 0, 0, 0);
299 IrpTable
->LinkNextTable
= ExAllocatePoolWithTag(NonPagedPool
,
300 sizeof(USBPORT_IRP_TABLE
),
303 if (IrpTable
->LinkNextTable
== NULL
)
305 KeBugCheckEx(BUGCODE_USB_DRIVER
, 1, 0, 0, 0);
308 RtlZeroMemory(IrpTable
->LinkNextTable
, sizeof(USBPORT_IRP_TABLE
));
310 IrpTable
= IrpTable
->LinkNextTable
;
316 USBPORT_RemoveIrpFromTable(IN PUSBPORT_IRP_TABLE IrpTable
,
321 DPRINT_CORE("USBPORT_RemoveIrpFromTable: IrpTable - %p, Irp - %p\n",
325 ASSERT(IrpTable
!= NULL
);
329 for (ix
= 0; ix
< 0x200; ix
++)
331 if (IrpTable
->irp
[ix
] == Irp
)
333 IrpTable
->irp
[ix
] = NULL
;
337 DPRINT_CORE("USBPORT_RemoveIrpFromTable: ix - %x\n", ix
);
344 if (IrpTable
->LinkNextTable
== NULL
)
347 IrpTable
= IrpTable
->LinkNextTable
;
351 DPRINT1("USBPORT_RemoveIrpFromTable: return NULL. ix - %x\n", ix
);
357 USBPORT_RemoveActiveTransferIrp(IN PDEVICE_OBJECT FdoDevice
,
360 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
362 DPRINT_CORE("USBPORT_RemoveActiveTransferIrp: Irp - %p\n", Irp
);
363 FdoExtension
= FdoDevice
->DeviceExtension
;
364 return USBPORT_RemoveIrpFromTable(FdoExtension
->ActiveIrpTable
, Irp
);
369 USBPORT_RemovePendingTransferIrp(IN PDEVICE_OBJECT FdoDevice
,
372 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
374 DPRINT_CORE("USBPORT_RemovePendingTransferIrp: Irp - %p\n", Irp
);
375 FdoExtension
= FdoDevice
->DeviceExtension
;
376 return USBPORT_RemoveIrpFromTable(FdoExtension
->PendingIrpTable
, Irp
);
381 USBPORT_FindUrbInIrpTable(IN PUSBPORT_IRP_TABLE IrpTable
,
389 DPRINT_CORE("USBPORT_FindUrbInIrpTable: IrpTable - %p, Urb - %p, Irp - %p\n",
394 ASSERT(IrpTable
!= NULL
);
398 for (ix
= 0; ix
< 0x200; ix
++)
400 irp
= IrpTable
->irp
[ix
];
404 urbIn
= URB_FROM_IRP(irp
);
410 KeBugCheckEx(BUGCODE_USB_DRIVER
,
417 KeBugCheckEx(BUGCODE_USB_DRIVER
,
426 IrpTable
= IrpTable
->LinkNextTable
;
433 USBPORT_FindIrpInTable(IN PUSBPORT_IRP_TABLE IrpTable
,
439 DPRINT_CORE("USBPORT_FindIrpInTable: IrpTable - %p, Irp - %p\n",
443 ASSERT(IrpTable
!= NULL
);
447 for (ix
= 0; ix
< 0x200; ix
++)
449 irp
= IrpTable
->irp
[ix
];
451 if (irp
&& irp
== Irp
)
457 IrpTable
= IrpTable
->LinkNextTable
;
459 while (IrpTable
->LinkNextTable
);
461 DPRINT_CORE("USBPORT_FindIrpInTable: Not found!!!\n");
467 USBPORT_FindActiveTransferIrp(IN PDEVICE_OBJECT FdoDevice
,
470 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
472 DPRINT_CORE("USBPORT_FindActiveTransferIrp: Irp - %p\n", Irp
);
473 FdoExtension
= FdoDevice
->DeviceExtension
;
474 return USBPORT_FindIrpInTable(FdoExtension
->ActiveIrpTable
, Irp
);
479 USBPORT_CancelPendingTransferIrp(IN PDEVICE_OBJECT DeviceObject
,
483 PUSBPORT_TRANSFER Transfer
;
484 PUSBPORT_ENDPOINT Endpoint
;
485 PDEVICE_OBJECT FdoDevice
;
486 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
490 DPRINT_CORE("USBPORT_CancelPendingTransferIrp: DeviceObject - %p, Irp - %p\n",
494 Urb
= URB_FROM_IRP(Irp
);
495 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
496 Endpoint
= Transfer
->Endpoint
;
498 FdoDevice
= Endpoint
->FdoDevice
;
499 FdoExtension
= DeviceObject
->DeviceExtension
;
501 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
503 KeAcquireSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
, &OldIrql
);
505 irp
= USBPORT_RemovePendingTransferIrp(FdoDevice
, Irp
);
509 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
514 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
516 RemoveEntryList(&Transfer
->TransferLink
);
518 Transfer
->TransferLink
.Flink
= NULL
;
519 Transfer
->TransferLink
.Blink
= NULL
;
521 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
522 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
, OldIrql
);
524 USBPORT_CompleteTransfer(Transfer
->Urb
, USBD_STATUS_CANCELED
);
529 USBPORT_CancelActiveTransferIrp(IN PDEVICE_OBJECT DeviceObject
,
532 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
533 PDEVICE_OBJECT FdoDevice
;
534 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
536 PUSBPORT_TRANSFER Transfer
;
537 PUSBPORT_ENDPOINT Endpoint
;
539 PUSBPORT_TRANSFER SplitTransfer
;
543 DPRINT_CORE("USBPORT_CancelActiveTransferIrp: Irp - %p\n", Irp
);
545 PdoExtension
= DeviceObject
->DeviceExtension
;
546 FdoDevice
= PdoExtension
->FdoDevice
;
547 FdoExtension
= FdoDevice
->DeviceExtension
;
549 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
551 KeAcquireSpinLock(&FdoExtension
->FlushTransferSpinLock
, &OldIrql
);
553 irp
= USBPORT_FindActiveTransferIrp(FdoDevice
, Irp
);
557 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
561 Urb
= URB_FROM_IRP(irp
);
562 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
563 Endpoint
= Transfer
->Endpoint
;
565 DPRINT_CORE("USBPORT_CancelActiveTransferIrp: irp - %p, Urb - %p, Transfer - %p\n",
570 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
572 Transfer
->Flags
|= TRANSFER_FLAG_CANCELED
;
574 if (Transfer
->Flags
& TRANSFER_FLAG_PARENT
)
576 KeAcquireSpinLockAtDpcLevel(&Transfer
->TransferSpinLock
);
578 Entry
= Transfer
->SplitTransfersList
.Flink
;
580 while (Entry
&& Entry
!= &Transfer
->SplitTransfersList
)
582 SplitTransfer
= CONTAINING_RECORD(Entry
,
586 SplitTransfer
->Flags
|= TRANSFER_FLAG_CANCELED
;
588 Entry
= Entry
->Flink
;
591 KeReleaseSpinLockFromDpcLevel(&Transfer
->TransferSpinLock
);
594 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
595 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
597 USBPORT_InvalidateEndpointHandler(FdoDevice
,
599 INVALIDATE_ENDPOINT_WORKER_THREAD
);
605 USBPORT_FlushAbortList(IN PUSBPORT_ENDPOINT Endpoint
)
608 PUSBPORT_TRANSFER Transfer
;
609 PLIST_ENTRY AbortList
;
614 PUSBPORT_DEVICE_HANDLE DeviceHandle
= NULL
;
616 DPRINT_CORE("USBPORT_FlushAbortList: Endpoint - %p\n", Endpoint
);
618 InitializeListHead(&List
);
620 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
622 if (IsListEmpty(&Endpoint
->AbortList
))
624 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
625 Endpoint
->EndpointOldIrql
);
629 Entry
= Endpoint
->PendingTransferList
.Flink
;
631 while (Entry
&& Entry
!= &Endpoint
->PendingTransferList
)
633 Transfer
= CONTAINING_RECORD(Entry
,
637 if (Transfer
->Flags
& TRANSFER_FLAG_ABORTED
)
639 DPRINT_CORE("USBPORT_FlushAbortList: Aborted PendingTransfer - %p\n",
642 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
643 Endpoint
->EndpointOldIrql
);
647 Entry
= Transfer
->TransferLink
.Flink
;
650 Entry
= Endpoint
->TransferList
.Flink
;
652 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
654 Transfer
= CONTAINING_RECORD(Entry
,
658 if (Transfer
->Flags
& TRANSFER_FLAG_ABORTED
)
660 DPRINT_CORE("USBPORT_FlushAbortList: Aborted ActiveTransfer - %p\n",
663 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
664 Endpoint
->EndpointOldIrql
);
668 Entry
= Transfer
->TransferLink
.Flink
;
671 AbortList
= &Endpoint
->AbortList
;
673 while (!IsListEmpty(AbortList
))
677 Irp
= CONTAINING_RECORD(AbortList
->Flink
,
679 Tail
.Overlay
.ListEntry
);
681 RemoveHeadList(AbortList
);
682 InsertTailList(&List
, &Irp
->Tail
.Overlay
.ListEntry
);
685 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
687 while (!IsListEmpty(&List
))
691 Irp
= CONTAINING_RECORD(List
.Flink
,
693 Tail
.Overlay
.ListEntry
);
695 RemoveHeadList(&List
);
697 Urb
= URB_FROM_IRP(Irp
);
699 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
700 InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
);
702 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_SUCCESS
);
704 DPRINT_CORE("USBPORT_FlushAbortList: complete Irp - %p\n", Irp
);
706 Irp
->IoStatus
.Status
= Status
;
707 Irp
->IoStatus
.Information
= 0;
708 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
714 USBPORT_FlushCancelList(IN PUSBPORT_ENDPOINT Endpoint
)
716 PDEVICE_OBJECT FdoDevice
;
717 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
718 PUSBPORT_TRANSFER Transfer
;
723 DPRINT_CORE("USBPORT_FlushCancelList: ... \n");
725 FdoDevice
= Endpoint
->FdoDevice
;
726 FdoExtension
= FdoDevice
->DeviceExtension
;
728 KeAcquireSpinLock(&FdoExtension
->FlushTransferSpinLock
, &OldIrql
);
729 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
731 while (!IsListEmpty(&Endpoint
->CancelList
))
733 Transfer
= CONTAINING_RECORD(Endpoint
->CancelList
.Flink
,
737 RemoveHeadList(&Endpoint
->CancelList
);
743 DPRINT("USBPORT_FlushCancelList: Irp - %p\n", Irp
);
745 IoAcquireCancelSpinLock(&PrevIrql
);
746 IoSetCancelRoutine(Irp
, NULL
);
747 IoReleaseCancelSpinLock(PrevIrql
);
749 USBPORT_RemoveActiveTransferIrp(FdoDevice
, Irp
);
752 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
753 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
755 if (Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
)
757 USBPORT_CompleteTransfer(Transfer
->Urb
, USBD_STATUS_DEVICE_GONE
);
761 if (Transfer
->Flags
& TRANSFER_FLAG_DEVICE_GONE
)
763 USBPORT_CompleteTransfer(Transfer
->Urb
,
764 USBD_STATUS_DEVICE_GONE
);
768 USBPORT_CompleteTransfer(Transfer
->Urb
,
769 USBD_STATUS_CANCELED
);
773 KeAcquireSpinLock(&FdoExtension
->FlushTransferSpinLock
, &OldIrql
);
774 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
777 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
778 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
780 USBPORT_FlushAbortList(Endpoint
);
785 USBPORT_FlushPendingTransfers(IN PUSBPORT_ENDPOINT Endpoint
)
787 PDEVICE_OBJECT FdoDevice
;
788 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
789 BOOLEAN IsMapTransfer
;
790 BOOLEAN IsEnd
= FALSE
;
792 PUSBPORT_TRANSFER Transfer
;
798 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint - %p\n", Endpoint
);
800 FdoDevice
= Endpoint
->FdoDevice
;
801 FdoExtension
= FdoDevice
->DeviceExtension
;
803 if (InterlockedCompareExchange(&Endpoint
->FlushPendingLock
, 1, 0))
805 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint Locked \n");
813 KeAcquireSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
816 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
818 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
)
822 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
823 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
828 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
830 if (!IsListEmpty(&Endpoint
->TransferList
))
832 List
= Endpoint
->TransferList
.Flink
;
834 while (List
&& List
!= &Endpoint
->TransferList
)
836 Transfer
= CONTAINING_RECORD(List
,
840 if (!(Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
))
842 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
843 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
850 List
= Transfer
->TransferLink
.Flink
;
855 List
= Endpoint
->PendingTransferList
.Flink
;
857 if (List
== NULL
|| IsListEmpty(&Endpoint
->PendingTransferList
))
859 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
860 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
867 Transfer
= CONTAINING_RECORD(List
,
873 DPRINT_CORE("USBPORT_FlushPendingTransfers: Transfer->Irp->CancelRoutine - %p\n",
874 Transfer
->Irp
->CancelRoutine
);
878 (IoSetCancelRoutine(Transfer
->Irp
, NULL
) == NULL
))
880 DPRINT_CORE("USBPORT_FlushPendingTransfers: Transfer->Irp - %p\n",
889 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
890 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
895 USBPORT_FlushMapTransfers(FdoDevice
);
905 RemoveEntryList(&Transfer
->TransferLink
);
906 Transfer
->TransferLink
.Flink
= NULL
;
907 Transfer
->TransferLink
.Blink
= NULL
;
911 Irp
= USBPORT_RemovePendingTransferIrp(FdoDevice
, Irp
);
914 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
915 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
918 KeAcquireSpinLock(&FdoExtension
->FlushTransferSpinLock
, &OldIrql
);
922 IoSetCancelRoutine(Irp
, USBPORT_CancelActiveTransferIrp
);
924 if (Irp
->Cancel
&& IoSetCancelRoutine(Irp
, NULL
))
926 DPRINT_CORE("USBPORT_FlushPendingTransfers: irp - %p\n", Irp
);
928 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
,
931 USBPORT_CompleteTransfer(Transfer
->Urb
, USBD_STATUS_CANCELED
);
935 USBPORT_FindUrbInIrpTable(FdoExtension
->ActiveIrpTable
, Urb
, Irp
);
936 USBPORT_InsertIrpInTable(FdoExtension
->ActiveIrpTable
, Irp
);
939 IsMapTransfer
= USBPORT_QueueActiveUrbToEndpoint(Endpoint
, Urb
);
941 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
945 USBPORT_FlushMapTransfers(FdoDevice
);
950 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
951 Result
= USBPORT_EndpointWorker(Endpoint
, FALSE
);
952 KeLowerIrql(OldIrql
);
955 USBPORT_InvalidateEndpointHandler(FdoDevice
,
957 INVALIDATE_ENDPOINT_WORKER_THREAD
);
962 InterlockedDecrement(&Endpoint
->FlushPendingLock
);
963 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint Unlocked. Exit\n");
971 USBPORT_QueuePendingUrbToEndpoint(IN PUSBPORT_ENDPOINT Endpoint
,
974 PUSBPORT_TRANSFER Transfer
;
976 DPRINT_CORE("USBPORT_QueuePendingUrbToEndpoint: Endpoint - %p, Urb - %p\n",
980 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
981 //FIXME USBPORT_ResetEndpointIdle();
982 InsertTailList(&Endpoint
->PendingTransferList
, &Transfer
->TransferLink
);
983 Urb
->UrbHeader
.Status
= USBD_STATUS_PENDING
;
988 USBPORT_QueueActiveUrbToEndpoint(IN PUSBPORT_ENDPOINT Endpoint
,
991 PUSBPORT_TRANSFER Transfer
;
992 PDEVICE_OBJECT FdoDevice
;
993 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
994 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
997 DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: Endpoint - %p, Urb - %p\n",
1001 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
1002 FdoDevice
= Endpoint
->FdoDevice
;
1003 FdoExtension
= FdoDevice
->DeviceExtension
;
1005 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
1006 &Endpoint
->EndpointOldIrql
);
1008 if ((Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
) ||
1009 (Transfer
->Flags
& TRANSFER_FLAG_ABORTED
))
1011 InsertTailList(&Endpoint
->CancelList
, &Transfer
->TransferLink
);
1013 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1014 Endpoint
->EndpointOldIrql
);
1016 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return FALSE\n");
1020 if (Transfer
->TransferParameters
.TransferBufferLength
== 0 ||
1021 !(Endpoint
->Flags
& ENDPOINT_FLAG_DMA_TYPE
))
1023 InsertTailList(&Endpoint
->TransferList
, &Transfer
->TransferLink
);
1025 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1026 Endpoint
->EndpointOldIrql
);
1028 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return FALSE\n");
1032 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1034 KeAcquireSpinLock(&FdoExtension
->MapTransferSpinLock
, &OldIrql
);
1036 InsertTailList(&FdoExtension
->MapTransferList
, &Transfer
->TransferLink
);
1038 DeviceHandle
= Transfer
->Urb
->UrbHeader
.UsbdDeviceHandle
;
1039 InterlockedIncrement(&DeviceHandle
->DeviceHandleLock
);
1041 KeReleaseSpinLock(&FdoExtension
->MapTransferSpinLock
, OldIrql
);
1043 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return TRUE\n");
1049 USBPORT_QueuePendingTransferIrp(IN PIRP Irp
)
1052 PUSBPORT_TRANSFER Transfer
;
1053 PUSBPORT_ENDPOINT Endpoint
;
1054 PDEVICE_OBJECT FdoDevice
;
1055 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1057 DPRINT_CORE("USBPORT_QueuePendingTransferIrp: Irp - %p\n", Irp
);
1059 Urb
= URB_FROM_IRP(Irp
);
1061 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
1062 Endpoint
= Transfer
->Endpoint
;
1064 FdoDevice
= Endpoint
->FdoDevice
;
1065 FdoExtension
= FdoDevice
->DeviceExtension
;
1067 Irp
->IoStatus
.Status
= STATUS_PENDING
;
1068 IoMarkIrpPending(Irp
);
1070 IoSetCancelRoutine(Irp
, USBPORT_CancelPendingTransferIrp
);
1072 if (Irp
->Cancel
&& IoSetCancelRoutine(Irp
, NULL
))
1074 USBPORT_CompleteTransfer(Urb
, USBD_STATUS_CANCELED
);
1078 USBPORT_InsertIrpInTable(FdoExtension
->PendingIrpTable
, Irp
);
1079 USBPORT_QueuePendingUrbToEndpoint(Endpoint
, Urb
);
1085 USBPORT_QueueTransferUrb(IN PURB Urb
)
1087 PUSBPORT_TRANSFER Transfer
;
1088 PUSBPORT_ENDPOINT Endpoint
;
1090 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
1091 PUSBPORT_TRANSFER_PARAMETERS Parameters
;
1093 DPRINT_CORE("USBPORT_QueueTransferUrb: Urb - %p\n", Urb
);
1095 if (Urb
->UrbControlTransfer
.TransferFlags
& USBD_DEFAULT_PIPE_TRANSFER
)
1096 Urb
->UrbHeader
.Function
= URB_FUNCTION_CONTROL_TRANSFER
;
1098 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
1099 Parameters
= &Transfer
->TransferParameters
;
1101 Endpoint
= Transfer
->Endpoint
;
1102 Endpoint
->Flags
&= ~ENDPOINT_FLAG_QUEUENE_EMPTY
;
1104 Parameters
->TransferBufferLength
= Urb
->UrbControlTransfer
.TransferBufferLength
;
1105 Parameters
->TransferFlags
= Urb
->UrbControlTransfer
.TransferFlags
;
1107 Transfer
->TransferBufferMDL
= Urb
->UrbControlTransfer
.TransferBufferMDL
;
1109 if (Urb
->UrbControlTransfer
.TransferFlags
& USBD_TRANSFER_DIRECTION_IN
)
1111 Transfer
->Direction
= USBPORT_DMA_DIRECTION_FROM_DEVICE
;
1115 Transfer
->Direction
= USBPORT_DMA_DIRECTION_TO_DEVICE
;
1118 if (Endpoint
->EndpointProperties
.TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
)
1120 RtlCopyMemory(&Parameters
->SetupPacket
,
1121 Urb
->UrbControlTransfer
.SetupPacket
,
1122 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1125 DPRINT_URB("... URB TransferBufferLength - %x\n",
1126 Urb
->UrbControlTransfer
.TransferBufferLength
);
1128 Urb
->UrbControlTransfer
.TransferBufferLength
= 0;
1130 Irp
= Transfer
->Irp
;
1134 USBPORT_QueuePendingTransferIrp(Irp
);
1138 USBPORT_QueuePendingUrbToEndpoint(Endpoint
, Urb
);
1141 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
1142 InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
);
1144 USBPORT_FlushPendingTransfers(Endpoint
);
1146 DPRINT_URB("... URB TransferBufferLength - %x\n",
1147 Urb
->UrbControlTransfer
.TransferBufferLength
);
1149 if (Urb
->UrbControlTransfer
.TransferBufferLength
)
1153 ULONG_PTR BufferEnd
;
1156 Buffer
= Urb
->UrbControlTransfer
.TransferBuffer
;
1157 BufferLength
= Urb
->UrbControlTransfer
.TransferBufferLength
;
1158 BufferEnd
= (ULONG_PTR
)Buffer
+ BufferLength
;
1160 DPRINT_URB("URB TransferBuffer - %p\n", Buffer
);
1162 for (ix
= 0; (ULONG_PTR
)(Buffer
+ ix
) < BufferEnd
; ix
++)
1164 DPRINT_URB("Buffer[%02X] - %p\n", ix
, Buffer
[ix
]);
1171 USBPORT_FlushAllEndpoints(IN PDEVICE_OBJECT FdoDevice
)
1173 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1175 PUSBPORT_ENDPOINT Endpoint
;
1179 DPRINT_CORE("USBPORT_FlushAllEndpoints: ... \n");
1181 FdoExtension
= FdoDevice
->DeviceExtension
;
1183 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1185 InitializeListHead(&List
);
1187 Entry
= FdoExtension
->EndpointList
.Flink
;
1189 while (Entry
&& Entry
!= &FdoExtension
->EndpointList
)
1191 Endpoint
= CONTAINING_RECORD(Entry
,
1195 if (USBPORT_GetEndpointState(Endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1197 InsertTailList(&List
, &Endpoint
->FlushLink
);
1200 Entry
= Endpoint
->EndpointLink
.Flink
;
1203 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1205 while (!IsListEmpty(&List
))
1207 Endpoint
= CONTAINING_RECORD(List
.Flink
,
1211 RemoveHeadList(&List
);
1213 Endpoint
->FlushLink
.Flink
= NULL
;
1214 Endpoint
->FlushLink
.Blink
= NULL
;
1216 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
1218 USBPORT_FlushPendingTransfers(Endpoint
);
1222 DPRINT_CORE("USBPORT_FlushAllEndpoints: exit\n");
1227 USBPORT_KillEndpointActiveTransfers(IN PDEVICE_OBJECT FdoDevice
,
1228 IN PUSBPORT_ENDPOINT Endpoint
)
1230 PLIST_ENTRY ActiveList
;
1231 PUSBPORT_TRANSFER Transfer
;
1232 ULONG KilledTransfers
= 0;
1234 DPRINT_CORE("USBPORT_KillEndpointActiveTransfers \n");
1236 ActiveList
= Endpoint
->TransferList
.Flink
;
1238 while (ActiveList
&& ActiveList
!= &Endpoint
->TransferList
)
1242 Transfer
= CONTAINING_RECORD(ActiveList
,
1246 Transfer
->Flags
|= TRANSFER_FLAG_ABORTED
;
1248 ActiveList
= Transfer
->TransferLink
.Flink
;
1251 USBPORT_FlushPendingTransfers(Endpoint
);
1252 USBPORT_FlushCancelList(Endpoint
);
1254 return KilledTransfers
;
1259 USBPORT_FlushController(IN PDEVICE_OBJECT FdoDevice
)
1261 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1263 PUSBPORT_ENDPOINT Endpoint
;
1264 ULONG KilledTransfers
= 0;
1265 PLIST_ENTRY EndpointList
;
1267 LIST_ENTRY FlushList
;
1269 DPRINT_CORE("USBPORT_FlushController \n");
1271 FdoExtension
= FdoDevice
->DeviceExtension
;
1273 EndpointList
= &FdoExtension
->EndpointList
;
1277 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1279 InitializeListHead(&FlushList
);
1281 Entry
= EndpointList
->Flink
;
1283 if (!IsListEmpty(EndpointList
))
1285 while (Entry
&& Entry
!= EndpointList
)
1287 Endpoint
= CONTAINING_RECORD(Entry
,
1291 if (Endpoint
->StateLast
!= USBPORT_ENDPOINT_REMOVE
&&
1292 Endpoint
->StateLast
!= USBPORT_ENDPOINT_CLOSED
)
1294 InterlockedIncrement(&Endpoint
->LockCounter
);
1295 InsertTailList(&FlushList
, &Endpoint
->FlushControllerLink
);
1298 Entry
= Endpoint
->EndpointLink
.Flink
;
1302 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1304 while (!IsListEmpty(&FlushList
))
1306 Endpoint
= CONTAINING_RECORD(FlushList
.Flink
,
1308 FlushControllerLink
);
1310 RemoveHeadList(&FlushList
);
1312 KilledTransfers
+= USBPORT_KillEndpointActiveTransfers(FdoDevice
,
1315 InterlockedDecrement(&Endpoint
->LockCounter
);
1318 if (!KilledTransfers
)
1321 USBPORT_Wait(FdoDevice
, 100);
1327 USBPORT_BadRequestFlush(IN PDEVICE_OBJECT FdoDevice
)
1329 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1332 DPRINT_QUEUE("USBPORT_BadRequestFlush: ... \n");
1334 FdoExtension
= FdoDevice
->DeviceExtension
;
1338 Irp
= IoCsqRemoveNextIrp(&FdoExtension
->BadRequestIoCsq
, 0);
1343 DPRINT1("USBPORT_BadRequestFlush: Irp - %p\n", Irp
);
1345 Irp
->IoStatus
.Status
= STATUS_DEVICE_NOT_CONNECTED
;
1346 Irp
->IoStatus
.Information
= 0;
1347 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1353 USBPORT_AbortEndpoint(IN PDEVICE_OBJECT FdoDevice
,
1354 IN PUSBPORT_ENDPOINT Endpoint
,
1357 PLIST_ENTRY PendingList
;
1358 PUSBPORT_TRANSFER PendingTransfer
;
1359 PLIST_ENTRY ActiveList
;
1360 PUSBPORT_TRANSFER ActiveTransfer
;
1362 DPRINT_CORE("USBPORT_AbortEndpoint: Irp - %p\n", Irp
);
1364 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1368 InsertTailList(&Endpoint
->AbortList
, &Irp
->Tail
.Overlay
.ListEntry
);
1371 PendingList
= Endpoint
->PendingTransferList
.Flink
;
1373 while (PendingList
&& PendingList
!= &Endpoint
->PendingTransferList
)
1375 PendingTransfer
= CONTAINING_RECORD(PendingList
,
1379 DPRINT_CORE("USBPORT_AbortEndpoint: Abort PendingTransfer - %p\n",
1382 PendingTransfer
->Flags
|= TRANSFER_FLAG_ABORTED
;
1384 PendingList
= PendingTransfer
->TransferLink
.Flink
;
1387 ActiveList
= Endpoint
->TransferList
.Flink
;
1389 while (ActiveList
&& ActiveList
!= &Endpoint
->TransferList
)
1391 ActiveTransfer
= CONTAINING_RECORD(ActiveList
,
1395 DPRINT_CORE("USBPORT_AbortEndpoint: Abort ActiveTransfer - %p\n",
1398 ActiveTransfer
->Flags
|= TRANSFER_FLAG_ABORTED
;
1400 if (Endpoint
->Flags
& ENDPOINT_FLAG_ABORTING
)
1402 ActiveTransfer
->Flags
|= TRANSFER_FLAG_DEVICE_GONE
;
1405 ActiveList
= ActiveTransfer
->TransferLink
.Flink
;
1408 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1410 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1412 INVALIDATE_ENDPOINT_INT_NEXT_SOF
);
1414 USBPORT_FlushPendingTransfers(Endpoint
);
1415 USBPORT_FlushCancelList(Endpoint
);