6 #define NDEBUG_USBPORT_CORE
7 #define NDEBUG_USBPORT_QUEUE
8 #define NDEBUG_USBPORT_URB
13 USBPORT_InsertIdleIrp(IN PIO_CSQ Csq
,
16 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
18 DPRINT_QUEUE("USBPORT_InsertIdleIrp: Irp - %p\n", Irp
);
20 FdoExtension
= CONTAINING_RECORD(Csq
,
21 USBPORT_DEVICE_EXTENSION
,
24 InsertTailList(&FdoExtension
->IdleIrpList
,
25 &Irp
->Tail
.Overlay
.ListEntry
);
30 USBPORT_RemoveIdleIrp(IN PIO_CSQ Csq
,
33 DPRINT_QUEUE("USBPORT_RemoveIdleIrp: Irp - %p\n", Irp
);
34 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
39 USBPORT_PeekNextIdleIrp(IN PIO_CSQ Csq
,
43 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
44 PLIST_ENTRY NextEntry
;
48 DPRINT_QUEUE("USBPORT_PeekNextIdleIrp: Irp - %p, PeekContext - %p\n",
52 FdoExtension
= CONTAINING_RECORD(Csq
,
53 USBPORT_DEVICE_EXTENSION
,
56 ListHead
= &FdoExtension
->IdleIrpList
;
60 NextEntry
= Irp
->Tail
.Overlay
.ListEntry
.Flink
;
64 NextEntry
= ListHead
->Flink
;
67 while (NextEntry
!= ListHead
)
69 NextIrp
= CONTAINING_RECORD(NextEntry
,
71 Tail
.Overlay
.ListEntry
);
76 NextEntry
= NextEntry
->Flink
;
84 USBPORT_AcquireIdleLock(IN PIO_CSQ Csq
,
87 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
89 DPRINT_QUEUE("USBPORT_AcquireIdleLock: ... \n");
91 FdoExtension
= CONTAINING_RECORD(Csq
,
92 USBPORT_DEVICE_EXTENSION
,
95 KeAcquireSpinLock(&FdoExtension
->IdleIoCsqSpinLock
, Irql
);
100 USBPORT_ReleaseIdleLock(IN PIO_CSQ Csq
,
103 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
105 DPRINT_QUEUE("USBPORT_ReleaseIdleLock: ... \n");
107 FdoExtension
= CONTAINING_RECORD(Csq
,
108 USBPORT_DEVICE_EXTENSION
,
111 KeReleaseSpinLock(&FdoExtension
->IdleIoCsqSpinLock
, Irql
);
116 USBPORT_CompleteCanceledIdleIrp(IN PIO_CSQ Csq
,
119 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
121 DPRINT_QUEUE("USBPORT_CompleteCanceledIdleIrp: ... \n");
123 FdoExtension
= CONTAINING_RECORD(Csq
,
124 USBPORT_DEVICE_EXTENSION
,
127 InterlockedDecrement(&FdoExtension
->IdleLockCounter
);
129 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
130 Irp
->IoStatus
.Information
= 0;
131 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
136 USBPORT_InsertBadRequest(IN PIO_CSQ Csq
,
139 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
141 DPRINT_QUEUE("USBPORT_InsertBadRequest: Irp - %p\n", Irp
);
143 FdoExtension
= CONTAINING_RECORD(Csq
,
144 USBPORT_DEVICE_EXTENSION
,
147 InsertTailList(&FdoExtension
->BadRequestList
,
148 &Irp
->Tail
.Overlay
.ListEntry
);
153 USBPORT_RemoveBadRequest(IN PIO_CSQ Csq
,
156 DPRINT_QUEUE("USBPORT_RemoveBadRequest: Irp - %p\n", Irp
);
157 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
162 USBPORT_PeekNextBadRequest(IN PIO_CSQ Csq
,
164 IN PVOID PeekContext
)
166 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
167 PLIST_ENTRY NextEntry
;
168 PLIST_ENTRY ListHead
;
171 DPRINT_QUEUE("USBPORT_PeekNextBadRequest: Irp - %p, PeekContext - %p\n",
175 FdoExtension
= CONTAINING_RECORD(Csq
,
176 USBPORT_DEVICE_EXTENSION
,
179 ListHead
= &FdoExtension
->BadRequestList
;
183 NextEntry
= Irp
->Tail
.Overlay
.ListEntry
.Flink
;
187 NextEntry
= ListHead
->Flink
;
190 while (NextEntry
!= ListHead
)
192 NextIrp
= CONTAINING_RECORD(NextEntry
,
194 Tail
.Overlay
.ListEntry
);
199 NextEntry
= NextEntry
->Flink
;
207 USBPORT_AcquireBadRequestLock(IN PIO_CSQ Csq
,
210 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
212 DPRINT_QUEUE("USBPORT_AcquireBadRequestLock: ... \n");
214 FdoExtension
= CONTAINING_RECORD(Csq
,
215 USBPORT_DEVICE_EXTENSION
,
218 KeAcquireSpinLock(&FdoExtension
->BadRequestIoCsqSpinLock
, Irql
);
223 USBPORT_ReleaseBadRequestLock(IN PIO_CSQ Csq
,
226 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
228 DPRINT_QUEUE("USBPORT_ReleaseBadRequestLock: ... \n");
230 FdoExtension
= CONTAINING_RECORD(Csq
,
231 USBPORT_DEVICE_EXTENSION
,
234 KeReleaseSpinLock(&FdoExtension
->BadRequestIoCsqSpinLock
, Irql
);
239 USBPORT_CompleteCanceledBadRequest(IN PIO_CSQ Csq
,
242 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
244 DPRINT_QUEUE("USBPORT_CompleteCanceledBadRequest: Irp - %p\n", Irp
);
246 FdoExtension
= CONTAINING_RECORD(Csq
,
247 USBPORT_DEVICE_EXTENSION
,
250 InterlockedDecrement(&FdoExtension
->BadRequestLockCounter
);
252 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
253 Irp
->IoStatus
.Information
= 0;
254 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
259 USBPORT_InsertIrpInTable(IN PUSBPORT_IRP_TABLE IrpTable
,
264 DPRINT_CORE("USBPORT_InsertIrpInTable: IrpTable - %p, Irp - %p\n",
268 ASSERT(IrpTable
!= NULL
);
272 for (ix
= 0; ix
< 0x200; ix
++)
274 if (IrpTable
->irp
[ix
] == NULL
)
276 IrpTable
->irp
[ix
] = Irp
;
280 DPRINT_CORE("USBPORT_InsertIrpInTable: ix - %x\n", ix
);
289 KeBugCheckEx(BUGCODE_USB_DRIVER
, 1, 0, 0, 0);
292 IrpTable
->LinkNextTable
= ExAllocatePoolWithTag(NonPagedPool
,
293 sizeof(USBPORT_IRP_TABLE
),
296 if (IrpTable
->LinkNextTable
== NULL
)
298 KeBugCheckEx(BUGCODE_USB_DRIVER
, 1, 0, 0, 0);
301 RtlZeroMemory(IrpTable
->LinkNextTable
, sizeof(USBPORT_IRP_TABLE
));
303 IrpTable
= IrpTable
->LinkNextTable
;
309 USBPORT_RemoveIrpFromTable(IN PUSBPORT_IRP_TABLE IrpTable
,
314 DPRINT_CORE("USBPORT_RemoveIrpFromTable: IrpTable - %p, Irp - %p\n",
318 ASSERT(IrpTable
!= NULL
);
322 for (ix
= 0; ix
< 0x200; ix
++)
324 if (IrpTable
->irp
[ix
] == Irp
)
326 IrpTable
->irp
[ix
] = NULL
;
330 DPRINT_CORE("USBPORT_RemoveIrpFromTable: ix - %x\n", ix
);
337 if (IrpTable
->LinkNextTable
== NULL
)
340 IrpTable
= IrpTable
->LinkNextTable
;
344 DPRINT1("USBPORT_RemoveIrpFromTable: return NULL. ix - %x\n", ix
);
350 USBPORT_RemoveActiveTransferIrp(IN PDEVICE_OBJECT FdoDevice
,
353 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
355 DPRINT_CORE("USBPORT_RemoveActiveTransferIrp: Irp - %p\n", Irp
);
356 FdoExtension
= FdoDevice
->DeviceExtension
;
357 return USBPORT_RemoveIrpFromTable(FdoExtension
->ActiveIrpTable
, Irp
);
362 USBPORT_RemovePendingTransferIrp(IN PDEVICE_OBJECT FdoDevice
,
365 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
367 DPRINT_CORE("USBPORT_RemovePendingTransferIrp: Irp - %p\n", Irp
);
368 FdoExtension
= FdoDevice
->DeviceExtension
;
369 return USBPORT_RemoveIrpFromTable(FdoExtension
->PendingIrpTable
, Irp
);
374 USBPORT_FindUrbInIrpTable(IN PUSBPORT_IRP_TABLE IrpTable
,
382 DPRINT_CORE("USBPORT_FindUrbInIrpTable: IrpTable - %p, Urb - %p, Irp - %p\n",
387 ASSERT(IrpTable
!= NULL
);
391 for (ix
= 0; ix
< 0x200; ix
++)
393 irp
= IrpTable
->irp
[ix
];
397 urbIn
= URB_FROM_IRP(irp
);
403 KeBugCheckEx(BUGCODE_USB_DRIVER
,
410 KeBugCheckEx(BUGCODE_USB_DRIVER
,
419 IrpTable
= IrpTable
->LinkNextTable
;
426 USBPORT_FindIrpInTable(IN PUSBPORT_IRP_TABLE IrpTable
,
432 DPRINT_CORE("USBPORT_FindIrpInTable: IrpTable - %p, Irp - %p\n",
436 ASSERT(IrpTable
!= NULL
);
440 for (ix
= 0; ix
< 0x200; ix
++)
442 irp
= IrpTable
->irp
[ix
];
444 if (irp
&& irp
== Irp
)
450 IrpTable
= IrpTable
->LinkNextTable
;
452 while (IrpTable
->LinkNextTable
);
454 DPRINT_CORE("USBPORT_FindIrpInTable: Not found!!!\n");
460 USBPORT_FindActiveTransferIrp(IN PDEVICE_OBJECT FdoDevice
,
463 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
465 DPRINT_CORE("USBPORT_FindActiveTransferIrp: Irp - %p\n", Irp
);
466 FdoExtension
= FdoDevice
->DeviceExtension
;
467 return USBPORT_FindIrpInTable(FdoExtension
->ActiveIrpTable
, Irp
);
472 USBPORT_CancelPendingTransferIrp(IN PDEVICE_OBJECT DeviceObject
,
476 PUSBPORT_TRANSFER Transfer
;
477 PUSBPORT_ENDPOINT Endpoint
;
478 PDEVICE_OBJECT FdoDevice
;
479 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
483 DPRINT_CORE("USBPORT_CancelPendingTransferIrp: DeviceObject - %p, Irp - %p\n",
487 Urb
= URB_FROM_IRP(Irp
);
488 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
489 Endpoint
= Transfer
->Endpoint
;
491 FdoDevice
= Endpoint
->FdoDevice
;
492 FdoExtension
= DeviceObject
->DeviceExtension
;
494 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
496 KeAcquireSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
, &OldIrql
);
498 irp
= USBPORT_RemovePendingTransferIrp(FdoDevice
, Irp
);
502 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
507 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
509 RemoveEntryList(&Transfer
->TransferLink
);
511 Transfer
->TransferLink
.Flink
= NULL
;
512 Transfer
->TransferLink
.Blink
= NULL
;
514 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
515 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
, OldIrql
);
517 USBPORT_CompleteTransfer(Transfer
->Urb
, USBD_STATUS_CANCELED
);
522 USBPORT_CancelActiveTransferIrp(IN PDEVICE_OBJECT DeviceObject
,
525 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
526 PDEVICE_OBJECT FdoDevice
;
527 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
529 PUSBPORT_TRANSFER Transfer
;
530 PUSBPORT_ENDPOINT Endpoint
;
532 PUSBPORT_TRANSFER SplitTransfer
;
536 DPRINT_CORE("USBPORT_CancelActiveTransferIrp: Irp - %p\n", Irp
);
538 PdoExtension
= DeviceObject
->DeviceExtension
;
539 FdoDevice
= PdoExtension
->FdoDevice
;
540 FdoExtension
= FdoDevice
->DeviceExtension
;
542 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
544 KeAcquireSpinLock(&FdoExtension
->FlushTransferSpinLock
, &OldIrql
);
546 irp
= USBPORT_FindActiveTransferIrp(FdoDevice
, Irp
);
550 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
554 Urb
= URB_FROM_IRP(irp
);
555 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
556 Endpoint
= Transfer
->Endpoint
;
558 DPRINT_CORE("USBPORT_CancelActiveTransferIrp: irp - %p, Urb - %p, Transfer - %p\n",
563 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
565 Transfer
->Flags
|= TRANSFER_FLAG_CANCELED
;
567 if (Transfer
->Flags
& TRANSFER_FLAG_PARENT
)
569 KeAcquireSpinLockAtDpcLevel(&Transfer
->TransferSpinLock
);
571 Entry
= Transfer
->SplitTransfersList
.Flink
;
573 while (Entry
&& Entry
!= &Transfer
->SplitTransfersList
)
575 SplitTransfer
= CONTAINING_RECORD(Entry
,
579 SplitTransfer
->Flags
|= TRANSFER_FLAG_CANCELED
;
581 Entry
= Entry
->Flink
;
584 KeReleaseSpinLockFromDpcLevel(&Transfer
->TransferSpinLock
);
587 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
588 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
590 USBPORT_InvalidateEndpointHandler(FdoDevice
,
592 INVALIDATE_ENDPOINT_WORKER_THREAD
);
598 USBPORT_FlushAbortList(IN PUSBPORT_ENDPOINT Endpoint
)
601 PUSBPORT_TRANSFER Transfer
;
602 PLIST_ENTRY AbortList
;
607 PUSBPORT_DEVICE_HANDLE DeviceHandle
= NULL
;
609 DPRINT_CORE("USBPORT_FlushAbortList: Endpoint - %p\n", Endpoint
);
611 InitializeListHead(&List
);
613 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
615 if (IsListEmpty(&Endpoint
->AbortList
))
617 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
618 Endpoint
->EndpointOldIrql
);
622 Entry
= Endpoint
->PendingTransferList
.Flink
;
624 while (Entry
&& Entry
!= &Endpoint
->PendingTransferList
)
626 Transfer
= CONTAINING_RECORD(Entry
,
630 if (Transfer
->Flags
& TRANSFER_FLAG_ABORTED
)
632 DPRINT_CORE("USBPORT_FlushAbortList: Aborted PendingTransfer - %p\n",
635 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
636 Endpoint
->EndpointOldIrql
);
640 Entry
= Transfer
->TransferLink
.Flink
;
643 Entry
= Endpoint
->TransferList
.Flink
;
645 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
647 Transfer
= CONTAINING_RECORD(Entry
,
651 if (Transfer
->Flags
& TRANSFER_FLAG_ABORTED
)
653 DPRINT_CORE("USBPORT_FlushAbortList: Aborted ActiveTransfer - %p\n",
656 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
657 Endpoint
->EndpointOldIrql
);
661 Entry
= Transfer
->TransferLink
.Flink
;
664 AbortList
= &Endpoint
->AbortList
;
666 while (!IsListEmpty(AbortList
))
670 Irp
= CONTAINING_RECORD(AbortList
->Flink
,
672 Tail
.Overlay
.ListEntry
);
674 RemoveHeadList(AbortList
);
675 InsertTailList(&List
, &Irp
->Tail
.Overlay
.ListEntry
);
678 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
680 while (!IsListEmpty(&List
))
684 Irp
= CONTAINING_RECORD(List
.Flink
,
686 Tail
.Overlay
.ListEntry
);
688 RemoveHeadList(&List
);
690 Urb
= URB_FROM_IRP(Irp
);
692 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
693 InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
);
695 Status
= USBPORT_USBDStatusToNtStatus(Urb
, USBD_STATUS_SUCCESS
);
697 DPRINT_CORE("USBPORT_FlushAbortList: complete Irp - %p\n", Irp
);
699 Irp
->IoStatus
.Status
= Status
;
700 Irp
->IoStatus
.Information
= 0;
701 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
707 USBPORT_FlushCancelList(IN PUSBPORT_ENDPOINT Endpoint
)
709 PDEVICE_OBJECT FdoDevice
;
710 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
711 PUSBPORT_TRANSFER Transfer
;
716 DPRINT_CORE("USBPORT_FlushCancelList: ... \n");
718 FdoDevice
= Endpoint
->FdoDevice
;
719 FdoExtension
= FdoDevice
->DeviceExtension
;
721 KeAcquireSpinLock(&FdoExtension
->FlushTransferSpinLock
, &OldIrql
);
722 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
724 while (!IsListEmpty(&Endpoint
->CancelList
))
726 Transfer
= CONTAINING_RECORD(Endpoint
->CancelList
.Flink
,
730 RemoveHeadList(&Endpoint
->CancelList
);
736 DPRINT("USBPORT_FlushCancelList: Irp - %p\n", Irp
);
738 IoAcquireCancelSpinLock(&PrevIrql
);
739 IoSetCancelRoutine(Irp
, NULL
);
740 IoReleaseCancelSpinLock(PrevIrql
);
742 USBPORT_RemoveActiveTransferIrp(FdoDevice
, Irp
);
745 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
746 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
748 if (Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
)
750 USBPORT_CompleteTransfer(Transfer
->Urb
, USBD_STATUS_DEVICE_GONE
);
754 if (Transfer
->Flags
& TRANSFER_FLAG_DEVICE_GONE
)
756 USBPORT_CompleteTransfer(Transfer
->Urb
,
757 USBD_STATUS_DEVICE_GONE
);
761 USBPORT_CompleteTransfer(Transfer
->Urb
,
762 USBD_STATUS_CANCELED
);
766 KeAcquireSpinLock(&FdoExtension
->FlushTransferSpinLock
, &OldIrql
);
767 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
770 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
771 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
773 USBPORT_FlushAbortList(Endpoint
);
778 USBPORT_FlushPendingTransfers(IN PUSBPORT_ENDPOINT Endpoint
)
780 PDEVICE_OBJECT FdoDevice
;
781 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
782 BOOLEAN IsMapTransfer
;
783 BOOLEAN IsEnd
= FALSE
;
785 PUSBPORT_TRANSFER Transfer
;
791 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint - %p\n", Endpoint
);
793 FdoDevice
= Endpoint
->FdoDevice
;
794 FdoExtension
= FdoDevice
->DeviceExtension
;
796 if (InterlockedCompareExchange(&Endpoint
->FlushPendingLock
, 1, 0))
798 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint Locked \n");
806 KeAcquireSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
809 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
811 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
)
815 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
816 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
821 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
823 if (!IsListEmpty(&Endpoint
->TransferList
))
825 List
= Endpoint
->TransferList
.Flink
;
827 while (List
&& List
!= &Endpoint
->TransferList
)
829 Transfer
= CONTAINING_RECORD(List
,
833 if (!(Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
))
835 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
836 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
843 List
= Transfer
->TransferLink
.Flink
;
848 List
= Endpoint
->PendingTransferList
.Flink
;
850 if (List
== NULL
|| IsListEmpty(&Endpoint
->PendingTransferList
))
852 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
853 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
860 Transfer
= CONTAINING_RECORD(List
,
866 DPRINT_CORE("USBPORT_FlushPendingTransfers: Transfer->Irp->CancelRoutine - %p\n",
867 Transfer
->Irp
->CancelRoutine
);
871 (IoSetCancelRoutine(Transfer
->Irp
, NULL
) == NULL
))
873 DPRINT_CORE("USBPORT_FlushPendingTransfers: Transfer->Irp - %p\n",
882 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
883 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
888 USBPORT_FlushMapTransfers(FdoDevice
);
898 RemoveEntryList(&Transfer
->TransferLink
);
899 Transfer
->TransferLink
.Flink
= NULL
;
900 Transfer
->TransferLink
.Blink
= NULL
;
904 Irp
= USBPORT_RemovePendingTransferIrp(FdoDevice
, Irp
);
907 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
908 KeReleaseSpinLock(&FdoExtension
->FlushPendingTransferSpinLock
,
911 KeAcquireSpinLock(&FdoExtension
->FlushTransferSpinLock
, &OldIrql
);
915 IoSetCancelRoutine(Irp
, USBPORT_CancelActiveTransferIrp
);
917 if (Irp
->Cancel
&& IoSetCancelRoutine(Irp
, NULL
))
919 DPRINT_CORE("USBPORT_FlushPendingTransfers: irp - %p\n", Irp
);
921 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
,
924 USBPORT_CompleteTransfer(Transfer
->Urb
, USBD_STATUS_CANCELED
);
928 USBPORT_FindUrbInIrpTable(FdoExtension
->ActiveIrpTable
, Urb
, Irp
);
929 USBPORT_InsertIrpInTable(FdoExtension
->ActiveIrpTable
, Irp
);
932 IsMapTransfer
= USBPORT_QueueActiveUrbToEndpoint(Endpoint
, Urb
);
934 KeReleaseSpinLock(&FdoExtension
->FlushTransferSpinLock
, OldIrql
);
938 USBPORT_FlushMapTransfers(FdoDevice
);
943 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
944 Result
= USBPORT_EndpointWorker(Endpoint
, FALSE
);
945 KeLowerIrql(OldIrql
);
948 USBPORT_InvalidateEndpointHandler(FdoDevice
,
950 INVALIDATE_ENDPOINT_WORKER_THREAD
);
955 InterlockedDecrement(&Endpoint
->FlushPendingLock
);
956 DPRINT_CORE("USBPORT_FlushPendingTransfers: Endpoint Unlocked. Exit\n");
964 USBPORT_QueuePendingUrbToEndpoint(IN PUSBPORT_ENDPOINT Endpoint
,
967 PUSBPORT_TRANSFER Transfer
;
969 DPRINT_CORE("USBPORT_QueuePendingUrbToEndpoint: Endpoint - %p, Urb - %p\n",
973 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
974 //FIXME USBPORT_ResetEndpointIdle();
975 InsertTailList(&Endpoint
->PendingTransferList
, &Transfer
->TransferLink
);
976 Urb
->UrbHeader
.Status
= USBD_STATUS_PENDING
;
981 USBPORT_QueueActiveUrbToEndpoint(IN PUSBPORT_ENDPOINT Endpoint
,
984 PUSBPORT_TRANSFER Transfer
;
985 PDEVICE_OBJECT FdoDevice
;
986 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
987 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
990 DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: Endpoint - %p, Urb - %p\n",
994 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
995 FdoDevice
= Endpoint
->FdoDevice
;
996 FdoExtension
= FdoDevice
->DeviceExtension
;
998 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
999 &Endpoint
->EndpointOldIrql
);
1001 if ((Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
) ||
1002 (Transfer
->Flags
& TRANSFER_FLAG_ABORTED
))
1004 InsertTailList(&Endpoint
->CancelList
, &Transfer
->TransferLink
);
1006 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1007 Endpoint
->EndpointOldIrql
);
1009 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return FALSE\n");
1013 if (Transfer
->TransferParameters
.TransferBufferLength
== 0 ||
1014 !(Endpoint
->Flags
& ENDPOINT_FLAG_DMA_TYPE
))
1016 InsertTailList(&Endpoint
->TransferList
, &Transfer
->TransferLink
);
1018 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1019 Endpoint
->EndpointOldIrql
);
1021 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return FALSE\n");
1025 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1027 KeAcquireSpinLock(&FdoExtension
->MapTransferSpinLock
, &OldIrql
);
1029 InsertTailList(&FdoExtension
->MapTransferList
, &Transfer
->TransferLink
);
1031 DeviceHandle
= Transfer
->Urb
->UrbHeader
.UsbdDeviceHandle
;
1032 InterlockedIncrement(&DeviceHandle
->DeviceHandleLock
);
1034 KeReleaseSpinLock(&FdoExtension
->MapTransferSpinLock
, OldIrql
);
1036 //DPRINT_CORE("USBPORT_QueueActiveUrbToEndpoint: return TRUE\n");
1042 USBPORT_QueuePendingTransferIrp(IN PIRP Irp
)
1045 PUSBPORT_TRANSFER Transfer
;
1046 PUSBPORT_ENDPOINT Endpoint
;
1047 PDEVICE_OBJECT FdoDevice
;
1048 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1050 DPRINT_CORE("USBPORT_QueuePendingTransferIrp: Irp - %p\n", Irp
);
1052 Urb
= URB_FROM_IRP(Irp
);
1054 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
1055 Endpoint
= Transfer
->Endpoint
;
1057 FdoDevice
= Endpoint
->FdoDevice
;
1058 FdoExtension
= FdoDevice
->DeviceExtension
;
1060 Irp
->IoStatus
.Status
= STATUS_PENDING
;
1061 IoMarkIrpPending(Irp
);
1063 IoSetCancelRoutine(Irp
, USBPORT_CancelPendingTransferIrp
);
1065 if (Irp
->Cancel
&& IoSetCancelRoutine(Irp
, NULL
))
1067 USBPORT_CompleteTransfer(Urb
, USBD_STATUS_CANCELED
);
1071 USBPORT_InsertIrpInTable(FdoExtension
->PendingIrpTable
, Irp
);
1072 USBPORT_QueuePendingUrbToEndpoint(Endpoint
, Urb
);
1078 USBPORT_QueueTransferUrb(IN PURB Urb
)
1080 PUSBPORT_TRANSFER Transfer
;
1081 PUSBPORT_ENDPOINT Endpoint
;
1083 PUSBPORT_DEVICE_HANDLE DeviceHandle
;
1084 PUSBPORT_TRANSFER_PARAMETERS Parameters
;
1086 DPRINT_CORE("USBPORT_QueueTransferUrb: Urb - %p\n", Urb
);
1088 if (Urb
->UrbControlTransfer
.TransferFlags
& USBD_DEFAULT_PIPE_TRANSFER
)
1089 Urb
->UrbHeader
.Function
= URB_FUNCTION_CONTROL_TRANSFER
;
1091 Transfer
= Urb
->UrbControlTransfer
.hca
.Reserved8
[0];
1092 Parameters
= &Transfer
->TransferParameters
;
1094 Endpoint
= Transfer
->Endpoint
;
1095 Endpoint
->Flags
&= ~ENDPOINT_FLAG_QUEUENE_EMPTY
;
1097 Parameters
->TransferBufferLength
= Urb
->UrbControlTransfer
.TransferBufferLength
;
1098 Parameters
->TransferFlags
= Urb
->UrbControlTransfer
.TransferFlags
;
1100 Transfer
->TransferBufferMDL
= Urb
->UrbControlTransfer
.TransferBufferMDL
;
1102 if (Urb
->UrbControlTransfer
.TransferFlags
& USBD_TRANSFER_DIRECTION_IN
)
1104 Transfer
->Direction
= USBPORT_DMA_DIRECTION_FROM_DEVICE
;
1108 Transfer
->Direction
= USBPORT_DMA_DIRECTION_TO_DEVICE
;
1111 if (Endpoint
->EndpointProperties
.TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
)
1113 RtlCopyMemory(&Parameters
->SetupPacket
,
1114 Urb
->UrbControlTransfer
.SetupPacket
,
1115 sizeof(USB_DEFAULT_PIPE_SETUP_PACKET
));
1118 DPRINT_URB("... URB TransferBufferLength - %x\n",
1119 Urb
->UrbControlTransfer
.TransferBufferLength
);
1121 Urb
->UrbControlTransfer
.TransferBufferLength
= 0;
1123 Irp
= Transfer
->Irp
;
1127 USBPORT_QueuePendingTransferIrp(Irp
);
1131 USBPORT_QueuePendingUrbToEndpoint(Endpoint
, Urb
);
1134 DeviceHandle
= Urb
->UrbHeader
.UsbdDeviceHandle
;
1135 InterlockedDecrement(&DeviceHandle
->DeviceHandleLock
);
1137 USBPORT_FlushPendingTransfers(Endpoint
);
1139 DPRINT_URB("... URB TransferBufferLength - %x\n",
1140 Urb
->UrbControlTransfer
.TransferBufferLength
);
1142 if (Urb
->UrbControlTransfer
.TransferBufferLength
)
1146 ULONG_PTR BufferEnd
;
1149 Buffer
= Urb
->UrbControlTransfer
.TransferBuffer
;
1150 BufferLength
= Urb
->UrbControlTransfer
.TransferBufferLength
;
1151 BufferEnd
= (ULONG_PTR
)Buffer
+ BufferLength
;
1153 DPRINT_URB("URB TransferBuffer - %p\n", Buffer
);
1155 for (ix
= 0; (ULONG_PTR
)(Buffer
+ ix
) < BufferEnd
; ix
++)
1157 DPRINT_URB("Buffer[%02X] - %p\n", ix
, Buffer
[ix
]);
1164 USBPORT_FlushAllEndpoints(IN PDEVICE_OBJECT FdoDevice
)
1166 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1168 PUSBPORT_ENDPOINT Endpoint
;
1172 DPRINT_CORE("USBPORT_FlushAllEndpoints: ... \n");
1174 FdoExtension
= FdoDevice
->DeviceExtension
;
1176 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1178 InitializeListHead(&List
);
1180 Entry
= FdoExtension
->EndpointList
.Flink
;
1182 while (Entry
&& Entry
!= &FdoExtension
->EndpointList
)
1184 Endpoint
= CONTAINING_RECORD(Entry
,
1188 if (USBPORT_GetEndpointState(Endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1190 InsertTailList(&List
, &Endpoint
->FlushLink
);
1193 Entry
= Endpoint
->EndpointLink
.Flink
;
1196 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1198 while (!IsListEmpty(&List
))
1200 Endpoint
= CONTAINING_RECORD(List
.Flink
,
1204 RemoveHeadList(&List
);
1206 Endpoint
->FlushLink
.Flink
= NULL
;
1207 Endpoint
->FlushLink
.Blink
= NULL
;
1209 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
1211 USBPORT_FlushPendingTransfers(Endpoint
);
1215 DPRINT_CORE("USBPORT_FlushAllEndpoints: exit\n");
1220 USBPORT_KillEndpointActiveTransfers(IN PDEVICE_OBJECT FdoDevice
,
1221 IN PUSBPORT_ENDPOINT Endpoint
)
1223 PLIST_ENTRY ActiveList
;
1224 PUSBPORT_TRANSFER Transfer
;
1225 ULONG KilledTransfers
= 0;
1227 DPRINT_CORE("USBPORT_KillEndpointActiveTransfers \n");
1229 ActiveList
= Endpoint
->TransferList
.Flink
;
1231 while (ActiveList
&& ActiveList
!= &Endpoint
->TransferList
)
1235 Transfer
= CONTAINING_RECORD(ActiveList
,
1239 Transfer
->Flags
|= TRANSFER_FLAG_ABORTED
;
1241 ActiveList
= Transfer
->TransferLink
.Flink
;
1244 USBPORT_FlushPendingTransfers(Endpoint
);
1245 USBPORT_FlushCancelList(Endpoint
);
1247 return KilledTransfers
;
1252 USBPORT_FlushController(IN PDEVICE_OBJECT FdoDevice
)
1254 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1256 PUSBPORT_ENDPOINT Endpoint
;
1257 ULONG KilledTransfers
= 0;
1258 PLIST_ENTRY EndpointList
;
1260 LIST_ENTRY FlushList
;
1262 DPRINT_CORE("USBPORT_FlushController \n");
1264 FdoExtension
= FdoDevice
->DeviceExtension
;
1266 EndpointList
= &FdoExtension
->EndpointList
;
1270 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1272 InitializeListHead(&FlushList
);
1274 Entry
= EndpointList
->Flink
;
1276 if (!IsListEmpty(EndpointList
))
1278 while (Entry
&& Entry
!= EndpointList
)
1280 Endpoint
= CONTAINING_RECORD(Entry
,
1284 if (Endpoint
->StateLast
!= USBPORT_ENDPOINT_REMOVE
&&
1285 Endpoint
->StateLast
!= USBPORT_ENDPOINT_CLOSED
)
1287 InterlockedIncrement(&Endpoint
->LockCounter
);
1288 InsertTailList(&FlushList
, &Endpoint
->FlushControllerLink
);
1291 Entry
= Endpoint
->EndpointLink
.Flink
;
1295 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1297 while (!IsListEmpty(&FlushList
))
1299 Endpoint
= CONTAINING_RECORD(FlushList
.Flink
,
1301 FlushControllerLink
);
1303 RemoveHeadList(&FlushList
);
1305 KilledTransfers
+= USBPORT_KillEndpointActiveTransfers(FdoDevice
,
1308 InterlockedDecrement(&Endpoint
->LockCounter
);
1311 if (!KilledTransfers
)
1314 USBPORT_Wait(FdoDevice
, 100);
1320 USBPORT_BadRequestFlush(IN PDEVICE_OBJECT FdoDevice
)
1322 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1325 DPRINT_QUEUE("USBPORT_BadRequestFlush: ... \n");
1327 FdoExtension
= FdoDevice
->DeviceExtension
;
1331 Irp
= IoCsqRemoveNextIrp(&FdoExtension
->BadRequestIoCsq
, 0);
1336 DPRINT1("USBPORT_BadRequestFlush: Irp - %p\n", Irp
);
1338 Irp
->IoStatus
.Status
= STATUS_DEVICE_NOT_CONNECTED
;
1339 Irp
->IoStatus
.Information
= 0;
1340 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1346 USBPORT_AbortEndpoint(IN PDEVICE_OBJECT FdoDevice
,
1347 IN PUSBPORT_ENDPOINT Endpoint
,
1350 PLIST_ENTRY PendingList
;
1351 PUSBPORT_TRANSFER PendingTransfer
;
1352 PLIST_ENTRY ActiveList
;
1353 PUSBPORT_TRANSFER ActiveTransfer
;
1355 DPRINT_CORE("USBPORT_AbortEndpoint: Irp - %p\n", Irp
);
1357 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1361 InsertTailList(&Endpoint
->AbortList
, &Irp
->Tail
.Overlay
.ListEntry
);
1364 PendingList
= Endpoint
->PendingTransferList
.Flink
;
1366 while (PendingList
&& PendingList
!= &Endpoint
->PendingTransferList
)
1368 PendingTransfer
= CONTAINING_RECORD(PendingList
,
1372 DPRINT_CORE("USBPORT_AbortEndpoint: Abort PendingTransfer - %p\n",
1375 PendingTransfer
->Flags
|= TRANSFER_FLAG_ABORTED
;
1377 PendingList
= PendingTransfer
->TransferLink
.Flink
;
1380 ActiveList
= Endpoint
->TransferList
.Flink
;
1382 while (ActiveList
&& ActiveList
!= &Endpoint
->TransferList
)
1384 ActiveTransfer
= CONTAINING_RECORD(ActiveList
,
1388 DPRINT_CORE("USBPORT_AbortEndpoint: Abort ActiveTransfer - %p\n",
1391 ActiveTransfer
->Flags
|= TRANSFER_FLAG_ABORTED
;
1393 if (Endpoint
->Flags
& ENDPOINT_FLAG_ABORTING
)
1395 ActiveTransfer
->Flags
|= TRANSFER_FLAG_DEVICE_GONE
;
1398 ActiveList
= ActiveTransfer
->TransferLink
.Flink
;
1401 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1403 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1405 INVALIDATE_ENDPOINT_INT_NEXT_SOF
);
1407 USBPORT_FlushPendingTransfers(Endpoint
);
1408 USBPORT_FlushCancelList(Endpoint
);