2 * PROJECT: ReactOS USB Port Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBPort endpoint functions
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
13 #define NDEBUG_USBPORT_CORE
18 USBPORT_CalculateUsbBandwidth(IN PDEVICE_OBJECT FdoDevice
,
19 IN PUSBPORT_ENDPOINT Endpoint
)
21 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
25 DPRINT("USBPORT_CalculateUsbBandwidth ... \n");
27 EndpointProperties
= &Endpoint
->EndpointProperties
;
29 switch (EndpointProperties
->TransferType
)
31 case USBPORT_TRANSFER_TYPE_ISOCHRONOUS
:
35 case USBPORT_TRANSFER_TYPE_INTERRUPT
:
39 default: //USBPORT_TRANSFER_TYPE_CONTROL or USBPORT_TRANSFER_TYPE_BULK
50 Bandwidth
= (EndpointProperties
->TotalMaxPacketSize
+ Additional
) * 8 * 7 / 6;
53 if (EndpointProperties
->DeviceSpeed
== UsbLowSpeed
)
63 USBPORT_AllocateBandwidth(IN PDEVICE_OBJECT FdoDevice
,
64 IN PUSBPORT_ENDPOINT Endpoint
)
66 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
67 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
69 ULONG TotalBusBandwidth
;
70 ULONG EndpointBandwidth
;
73 DPRINT("USBPORT_AllocateBandwidth: ... \n");
75 FdoExtension
= FdoDevice
->DeviceExtension
;
76 EndpointProperties
= &Endpoint
->EndpointProperties
;
77 TransferType
= EndpointProperties
->TransferType
;
79 if (TransferType
== USBPORT_TRANSFER_TYPE_BULK
||
80 TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
81 Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
83 EndpointProperties
->ScheduleOffset
= 0;
87 TotalBusBandwidth
= FdoExtension
->TotalBusBandwidth
;
88 EndpointBandwidth
= EndpointProperties
->UsbBandwidth
;
89 Period
= EndpointProperties
->Period
;
91 DPRINT1("USBPORT_AllocateBandwidth: FIXME. \n");
92 DPRINT1("USBPORT_AllocateBandwidth: Endpoint - %p, Type - %x, TotalBandwidth - %x, EpBandwidth - %x, Period - %x\n",
104 USBPORT_FreeBandwidth(IN PDEVICE_OBJECT FdoDevice
,
105 IN PUSBPORT_ENDPOINT Endpoint
)
107 DPRINT1("USBPORT_FreeBandwidth: UNIMPLEMENTED. FIXME. \n");
112 USBPORT_NormalizeHsInterval(UCHAR Interval
)
116 DPRINT("USBPORT_NormalizeHsInterval: Interval - %x\n", Interval
);
121 interval
= Interval
- 1;
126 return 1 << interval
;
131 USBPORT_EndpointHasQueuedTransfers(IN PDEVICE_OBJECT FdoDevice
,
132 IN PUSBPORT_ENDPOINT Endpoint
,
133 IN PULONG TransferCount
)
136 PUSBPORT_TRANSFER Transfer
;
137 BOOLEAN Result
= FALSE
;
139 DPRINT_CORE("USBPORT_EndpointHasQueuedTransfers: ... \n");
141 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
143 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
146 if (!IsListEmpty(&Endpoint
->TransferList
))
154 for (Entry
= Endpoint
->TransferList
.Flink
;
155 Entry
&& Entry
!= &Endpoint
->TransferList
;
156 Entry
= Transfer
->TransferLink
.Flink
)
158 Transfer
= CONTAINING_RECORD(Entry
,
162 if (Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
)
170 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
177 USBPORT_NukeAllEndpoints(IN PDEVICE_OBJECT FdoDevice
)
179 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
180 PLIST_ENTRY EndpointList
;
181 PUSBPORT_ENDPOINT Endpoint
;
184 DPRINT("USBPORT_NukeAllEndpoints \n");
186 FdoExtension
= FdoDevice
->DeviceExtension
;
188 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
190 EndpointList
= FdoExtension
->EndpointList
.Flink
;
192 while (EndpointList
&& (EndpointList
!= &FdoExtension
->EndpointList
))
194 Endpoint
= CONTAINING_RECORD(EndpointList
,
198 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
199 Endpoint
->Flags
|= ENDPOINT_FLAG_NUKE
;
201 EndpointList
= Endpoint
->EndpointLink
.Flink
;
204 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
209 USBPORT_GetEndpointState(IN PUSBPORT_ENDPOINT Endpoint
)
213 //DPRINT("USBPORT_GetEndpointState \n");
215 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
217 if (Endpoint
->StateLast
!= Endpoint
->StateNext
)
219 State
= USBPORT_ENDPOINT_UNKNOWN
;
223 State
= Endpoint
->StateLast
;
226 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
228 if (State
!= USBPORT_ENDPOINT_ACTIVE
)
230 DPRINT("USBPORT_GetEndpointState: Endpoint - %p, State - %x\n",
240 USBPORT_SetEndpointState(IN PUSBPORT_ENDPOINT Endpoint
,
243 PDEVICE_OBJECT FdoDevice
;
244 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
245 PUSBPORT_REGISTRATION_PACKET Packet
;
248 DPRINT("USBPORT_SetEndpointState: Endpoint - %p, State - %x\n",
252 FdoDevice
= Endpoint
->FdoDevice
;
253 FdoExtension
= FdoDevice
->DeviceExtension
;
254 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
256 KeAcquireSpinLock(&Endpoint
->StateChangeSpinLock
,
257 &Endpoint
->EndpointStateOldIrql
);
259 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
261 if (Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
)
263 Endpoint
->StateLast
= State
;
264 Endpoint
->StateNext
= State
;
266 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
267 Endpoint
->EndpointStateOldIrql
);
269 USBPORT_InvalidateEndpointHandler(FdoDevice
,
271 INVALIDATE_ENDPOINT_WORKER_THREAD
);
275 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
276 Endpoint
->EndpointStateOldIrql
);
278 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
279 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
282 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
284 Endpoint
->StateNext
= State
;
286 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
287 Endpoint
->FrameNumber
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
288 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
290 ExInterlockedInsertTailList(&FdoExtension
->EpStateChangeList
,
291 &Endpoint
->StateChangeLink
,
292 &FdoExtension
->EpStateChangeSpinLock
);
294 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
295 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
296 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
300 Endpoint
->StateLast
= State
;
301 Endpoint
->StateNext
= State
;
303 if (State
== USBPORT_ENDPOINT_REMOVE
)
305 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
306 Endpoint
->EndpointStateOldIrql
);
308 USBPORT_InvalidateEndpointHandler(FdoDevice
,
310 INVALIDATE_ENDPOINT_WORKER_THREAD
);
314 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
315 Endpoint
->EndpointStateOldIrql
);
321 USBPORT_AddPipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
322 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
324 DPRINT("USBPORT_AddPipeHandle: DeviceHandle - %p, PipeHandle - %p\n",
328 InsertTailList(&DeviceHandle
->PipeHandleList
, &PipeHandle
->PipeLink
);
333 USBPORT_RemovePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
334 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
336 DPRINT("USBPORT_RemovePipeHandle: PipeHandle - %p\n", PipeHandle
);
338 RemoveEntryList(&PipeHandle
->PipeLink
);
340 PipeHandle
->PipeLink
.Flink
= NULL
;
341 PipeHandle
->PipeLink
.Blink
= NULL
;
346 USBPORT_ValidatePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
347 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
349 PLIST_ENTRY HandleList
;
350 PUSBPORT_PIPE_HANDLE CurrentHandle
;
352 //DPRINT("USBPORT_ValidatePipeHandle: DeviceHandle - %p, PipeHandle - %p\n",
356 HandleList
= DeviceHandle
->PipeHandleList
.Flink
;
358 while (HandleList
!= &DeviceHandle
->PipeHandleList
)
360 CurrentHandle
= CONTAINING_RECORD(HandleList
,
364 HandleList
= HandleList
->Flink
;
366 if (CurrentHandle
== PipeHandle
)
375 USBPORT_DeleteEndpoint(IN PDEVICE_OBJECT FdoDevice
,
376 IN PUSBPORT_ENDPOINT Endpoint
)
378 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
382 DPRINT("USBPORT_DeleteEndpoint: Endpoint - %p\n", Endpoint
);
384 FdoExtension
= FdoDevice
->DeviceExtension
;
386 if ((Endpoint
->WorkerLink
.Flink
&& Endpoint
->WorkerLink
.Blink
) ||
387 Endpoint
->LockCounter
!= -1)
389 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
391 ExInterlockedInsertTailList(&FdoExtension
->EndpointClosedList
,
392 &Endpoint
->CloseLink
,
393 &FdoExtension
->EndpointClosedSpinLock
);
395 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
401 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
403 RemoveEntryList(&Endpoint
->EndpointLink
);
404 Endpoint
->EndpointLink
.Flink
= NULL
;
405 Endpoint
->EndpointLink
.Blink
= NULL
;
407 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
409 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
411 if (Endpoint
->HeaderBuffer
)
413 USBPORT_FreeCommonBuffer(FdoDevice
, Endpoint
->HeaderBuffer
);
416 ExFreePoolWithTag(Endpoint
, USB_PORT_TAG
);
426 MiniportCloseEndpoint(IN PDEVICE_OBJECT FdoDevice
,
427 IN PUSBPORT_ENDPOINT Endpoint
)
429 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
430 PUSBPORT_REGISTRATION_PACKET Packet
;
431 BOOLEAN IsDoDisablePeriodic
;
435 DPRINT("MiniportCloseEndpoint: Endpoint - %p\n", Endpoint
);
437 FdoExtension
= FdoDevice
->DeviceExtension
;
438 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
440 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
442 if (Endpoint
->Flags
& ENDPOINT_FLAG_OPENED
)
444 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
446 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
||
447 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
449 --FdoExtension
->PeriodicEndpoints
;
452 IsDoDisablePeriodic
= FdoExtension
->PeriodicEndpoints
== 0;
454 Packet
->CloseEndpoint(FdoExtension
->MiniPortExt
,
456 IsDoDisablePeriodic
);
458 Endpoint
->Flags
&= ~ENDPOINT_FLAG_OPENED
;
459 Endpoint
->Flags
|= ENDPOINT_FLAG_CLOSED
;
462 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
467 USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
468 IN PDEVICE_OBJECT FdoDevice
,
469 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
471 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
472 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
473 PUSBPORT_ENDPOINT Endpoint
;
477 DPRINT("USBPORT_ClosePipe \n");
479 FdoExtension
= FdoDevice
->DeviceExtension
;
481 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_CLOSED
)
484 USBPORT_RemovePipeHandle(DeviceHandle
, PipeHandle
);
486 PipeHandle
->Flags
|= PIPE_HANDLE_FLAG_CLOSED
;
488 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
)
490 PipeHandle
->Flags
&= ~PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
;
494 Endpoint
= PipeHandle
->Endpoint
;
495 DPRINT("USBPORT_ClosePipe: Endpoint - %p\n", Endpoint
);
497 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
499 if ((Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
) &&
500 (Endpoint
->EndpointProperties
.TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
))
502 PdoExtension
= FdoExtension
->RootHubPdo
->DeviceExtension
;
503 PdoExtension
->Endpoint
= NULL
;
506 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
512 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
513 &Endpoint
->EndpointOldIrql
);
515 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
518 if (!IsListEmpty(&Endpoint
->TransferList
))
521 if (!IsListEmpty(&Endpoint
->CancelList
))
524 if (!IsListEmpty(&Endpoint
->AbortList
))
527 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
528 if (Endpoint
->StateLast
!= Endpoint
->StateNext
)
530 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
532 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
533 Endpoint
->EndpointOldIrql
);
535 if (InterlockedIncrement(&Endpoint
->LockCounter
))
537 InterlockedDecrement(&Endpoint
->LockCounter
);
542 USBPORT_Wait(FdoDevice
, 1);
545 Endpoint
->DeviceHandle
= NULL
;
547 if (FdoExtension
->MiniPortInterface
->Packet
.MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
549 DPRINT("USBPORT_ClosePipe: FIXME USBPORT_FreeBandwidthUSB20\n");
550 //USBPORT_FreeBandwidthUSB20();
554 DPRINT("USBPORT_ClosePipe: FIXME USBPORT_FreeBandwidthUSB11\n");
555 //USBPORT_FreeBandwidthUSB11();
558 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
559 USBPORT_SetEndpointState(Endpoint
, USBPORT_ENDPOINT_REMOVE
);
560 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
562 USBPORT_SignalWorkerThread(FdoDevice
);
567 MiniportOpenEndpoint(IN PDEVICE_OBJECT FdoDevice
,
568 IN PUSBPORT_ENDPOINT Endpoint
)
570 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
571 PUSBPORT_REGISTRATION_PACKET Packet
;
576 DPRINT("MiniportOpenEndpoint: Endpoint - %p\n", Endpoint
);
578 FdoExtension
= FdoDevice
->DeviceExtension
;
579 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
581 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
583 Endpoint
->Flags
&= ~ENDPOINT_FLAG_CLOSED
;
585 MpStatus
= Packet
->OpenEndpoint(FdoExtension
->MiniPortExt
,
586 &Endpoint
->EndpointProperties
,
591 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
593 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
||
594 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
596 ++FdoExtension
->PeriodicEndpoints
;
599 Endpoint
->Flags
|= ENDPOINT_FLAG_OPENED
;
602 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
608 USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice
,
609 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
610 IN PUSBPORT_PIPE_HANDLE PipeHandle
,
611 IN OUT PUSBD_STATUS UsbdStatus
)
613 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
614 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
615 PUSBPORT_REGISTRATION_PACKET Packet
;
617 PUSBPORT_ENDPOINT Endpoint
;
618 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
619 PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
623 ULONG TransferParams
[2] = {0};
624 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
626 USBD_STATUS USBDStatus
;
629 USHORT MaxPacketSize
;
630 USHORT AdditionalTransaction
;
631 BOOLEAN IsAllocatedBandwidth
;
633 DPRINT("USBPORT_OpenPipe: DeviceHandle - %p, FdoDevice - %p, PipeHandle - %p\n",
638 FdoExtension
= FdoDevice
->DeviceExtension
;
639 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
641 EndpointSize
= sizeof(USBPORT_ENDPOINT
) + Packet
->MiniPortEndpointSize
;
643 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
645 DPRINT1("USBPORT_OpenPipe: FIXME USB2 EndpointSize\n");
648 if (PipeHandle
->EndpointDescriptor
.wMaxPacketSize
== 0)
650 USBPORT_AddPipeHandle(DeviceHandle
, PipeHandle
);
652 PipeHandle
->Flags
= (PipeHandle
->Flags
& ~PIPE_HANDLE_FLAG_CLOSED
) |
653 PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
;
655 PipeHandle
->Endpoint
= (PUSBPORT_ENDPOINT
)-1;
657 return STATUS_SUCCESS
;
660 Endpoint
= ExAllocatePoolWithTag(NonPagedPool
, EndpointSize
, USB_PORT_TAG
);
664 DPRINT1("USBPORT_OpenPipe: Not allocated Endpoint!\n");
665 Status
= STATUS_INSUFFICIENT_RESOURCES
;
669 RtlZeroMemory(Endpoint
, EndpointSize
);
671 Endpoint
->FdoDevice
= FdoDevice
;
672 Endpoint
->DeviceHandle
= DeviceHandle
;
673 Endpoint
->LockCounter
= -1;
675 KeInitializeSpinLock(&Endpoint
->EndpointSpinLock
);
676 KeInitializeSpinLock(&Endpoint
->StateChangeSpinLock
);
678 InitializeListHead(&Endpoint
->PendingTransferList
);
679 InitializeListHead(&Endpoint
->TransferList
);
680 InitializeListHead(&Endpoint
->CancelList
);
681 InitializeListHead(&Endpoint
->AbortList
);
683 EndpointProperties
= &Endpoint
->EndpointProperties
;
684 EndpointDescriptor
= &PipeHandle
->EndpointDescriptor
;
686 MaxPacketSize
= EndpointDescriptor
->wMaxPacketSize
& 0x7FF;
687 AdditionalTransaction
= (EndpointDescriptor
->wMaxPacketSize
>> 11) & 3;
689 EndpointProperties
->DeviceAddress
= DeviceHandle
->DeviceAddress
;
690 EndpointProperties
->DeviceSpeed
= DeviceHandle
->DeviceSpeed
;
691 EndpointProperties
->Period
= 0;
692 EndpointProperties
->EndpointAddress
= EndpointDescriptor
->bEndpointAddress
;
693 EndpointProperties
->TransactionPerMicroframe
= AdditionalTransaction
+ 1;
694 EndpointProperties
->MaxPacketSize
= MaxPacketSize
;
695 EndpointProperties
->TotalMaxPacketSize
= MaxPacketSize
*
696 (AdditionalTransaction
+ 1);
698 switch (EndpointDescriptor
->bmAttributes
& USB_ENDPOINT_TYPE_MASK
)
700 case USB_ENDPOINT_TYPE_CONTROL
:
701 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_CONTROL
;
703 if (EndpointProperties
->EndpointAddress
== 0)
705 EndpointProperties
->MaxTransferSize
= 0x1000; // OUT Ep0
709 EndpointProperties
->MaxTransferSize
= 0x10000;
714 case USB_ENDPOINT_TYPE_ISOCHRONOUS
:
715 DPRINT1("USBPORT_OpenPipe: USB_ENDPOINT_TYPE_ISOCHRONOUS UNIMPLEMENTED. FIXME. \n");
716 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_ISOCHRONOUS
;
717 EndpointProperties
->MaxTransferSize
= 0x1000000;
720 case USB_ENDPOINT_TYPE_BULK
:
721 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_BULK
;
722 EndpointProperties
->MaxTransferSize
= 0x10000;
725 case USB_ENDPOINT_TYPE_INTERRUPT
:
726 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_INTERRUPT
;
727 EndpointProperties
->MaxTransferSize
= 0x400;
731 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
733 if (EndpointProperties
->DeviceSpeed
== UsbHighSpeed
)
735 Interval
= USBPORT_NormalizeHsInterval(EndpointDescriptor
->bInterval
);
739 Interval
= EndpointDescriptor
->bInterval
;
742 EndpointProperties
->Period
= 32;
744 if (Interval
&& (Interval
< 32))
746 if ((EndpointProperties
->DeviceSpeed
!= UsbLowSpeed
) ||
749 if (!(Interval
& 0x20))
751 Period
= EndpointProperties
->Period
;
757 while (!(Period
& Interval
));
759 EndpointProperties
->Period
= Period
;
764 EndpointProperties
->Period
= 8;
769 if (EndpointProperties
->TransferType
== USB_ENDPOINT_TYPE_ISOCHRONOUS
)
771 if (EndpointProperties
->DeviceSpeed
== UsbHighSpeed
)
773 EndpointProperties
->Period
=
774 USBPORT_NormalizeHsInterval(EndpointDescriptor
->bInterval
);
778 EndpointProperties
->Period
= 1;
782 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
784 IsAllocatedBandwidth
= USBPORT_AllocateBandwidthUSB2(FdoDevice
, Endpoint
);
788 EndpointProperties
->UsbBandwidth
= USBPORT_CalculateUsbBandwidth(FdoDevice
,
791 IsAllocatedBandwidth
= USBPORT_AllocateBandwidth(FdoDevice
, Endpoint
);
794 if (!IsAllocatedBandwidth
)
796 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBD_STATUS_NO_BANDWIDTH
);
800 *UsbdStatus
= USBD_STATUS_NO_BANDWIDTH
;
806 Direction
= USB_ENDPOINT_DIRECTION_OUT(EndpointDescriptor
->bEndpointAddress
);
807 EndpointProperties
->Direction
= Direction
;
809 if (DeviceHandle
->IsRootHub
)
811 Endpoint
->EndpointWorker
= 0; // USBPORT_RootHubEndpointWorker;
813 Endpoint
->Flags
|= ENDPOINT_FLAG_ROOTHUB_EP0
;
815 Endpoint
->StateLast
= USBPORT_ENDPOINT_ACTIVE
;
816 Endpoint
->StateNext
= USBPORT_ENDPOINT_ACTIVE
;
818 PdoExtension
= FdoExtension
->RootHubPdo
->DeviceExtension
;
820 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
822 PdoExtension
->Endpoint
= Endpoint
;
825 USBDStatus
= USBD_STATUS_SUCCESS
;
829 Endpoint
->EndpointWorker
= 1; // USBPORT_DmaEndpointWorker;
831 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
833 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
834 &Endpoint
->EndpointProperties
,
837 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
839 if ((EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_BULK
) ||
840 (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
))
842 EndpointProperties
->MaxTransferSize
= TransferParams
[1];
845 if (TransferParams
[0])
847 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
855 if (HeaderBuffer
|| (TransferParams
[0] == 0))
857 Endpoint
->HeaderBuffer
= HeaderBuffer
;
861 EndpointProperties
->BufferVA
= HeaderBuffer
->VirtualAddress
;
862 EndpointProperties
->BufferPA
= HeaderBuffer
->PhysicalAddress
;
863 EndpointProperties
->BufferLength
= HeaderBuffer
->BufferLength
; // BufferLength + LengthPadded;
866 MpStatus
= MiniportOpenEndpoint(FdoDevice
, Endpoint
);
868 Endpoint
->Flags
|= ENDPOINT_FLAG_DMA_TYPE
;
869 Endpoint
->Flags
|= ENDPOINT_FLAG_QUEUENE_EMPTY
;
875 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
876 &Endpoint
->EndpointOldIrql
);
878 Endpoint
->StateLast
= USBPORT_ENDPOINT_PAUSED
;
879 Endpoint
->StateNext
= USBPORT_ENDPOINT_PAUSED
;
881 USBPORT_SetEndpointState(Endpoint
, USBPORT_ENDPOINT_ACTIVE
);
883 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
884 Endpoint
->EndpointOldIrql
);
888 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
889 &Endpoint
->EndpointOldIrql
);
891 State
= USBPORT_GetEndpointState(Endpoint
);
893 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
894 Endpoint
->EndpointOldIrql
);
896 if (State
== USBPORT_ENDPOINT_ACTIVE
)
901 USBPORT_Wait(FdoDevice
, 1); // 1 msec.
907 MpStatus
= MP_STATUS_NO_RESOURCES
;
908 Endpoint
->HeaderBuffer
= NULL
;
913 USBDStatus
= USBD_STATUS_INSUFFICIENT_RESOURCES
;
917 USBDStatus
= USBD_STATUS_SUCCESS
;
923 *UsbdStatus
= USBDStatus
;
926 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBDStatus
);
928 if (NT_SUCCESS(Status
))
930 USBPORT_AddPipeHandle(DeviceHandle
, PipeHandle
);
932 ExInterlockedInsertTailList(&FdoExtension
->EndpointList
,
933 &Endpoint
->EndpointLink
,
934 &FdoExtension
->EndpointListSpinLock
);
936 PipeHandle
->Endpoint
= Endpoint
;
937 PipeHandle
->Flags
&= ~PIPE_HANDLE_FLAG_CLOSED
;
946 if (IsAllocatedBandwidth
)
948 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
950 USBPORT_FreeBandwidthUSB2(FdoDevice
, Endpoint
);
954 USBPORT_FreeBandwidth(FdoDevice
, Endpoint
);
958 ExFreePoolWithTag(Endpoint
, USB_PORT_TAG
);
961 DPRINT1("USBPORT_OpenPipe: Status - %lx\n", Status
);
967 USBPORT_ReopenPipe(IN PDEVICE_OBJECT FdoDevice
,
968 IN PUSBPORT_ENDPOINT Endpoint
)
970 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
971 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
972 ULONG EndpointRequirements
[2] = {0};
973 PUSBPORT_REGISTRATION_PACKET Packet
;
974 KIRQL MiniportOldIrql
;
977 DPRINT("USBPORT_ReopenPipe ... \n");
979 FdoExtension
= FdoDevice
->DeviceExtension
;
980 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
984 if (!InterlockedIncrement(&Endpoint
->LockCounter
))
987 InterlockedDecrement(&Endpoint
->LockCounter
);
988 USBPORT_Wait(FdoDevice
, 1);
991 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &MiniportOldIrql
);
993 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
995 USBPORT_ENDPOINT_REMOVE
);
997 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, MiniportOldIrql
);
999 USBPORT_Wait(FdoDevice
, 2);
1001 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
1003 RtlZeroMemory(Endpoint
+ 1,
1004 Packet
->MiniPortEndpointSize
);
1006 if (Endpoint
->HeaderBuffer
)
1008 USBPORT_FreeCommonBuffer(FdoDevice
, Endpoint
->HeaderBuffer
);
1009 Endpoint
->HeaderBuffer
= NULL
;
1012 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &MiniportOldIrql
);
1014 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
1015 &Endpoint
->EndpointProperties
,
1016 EndpointRequirements
);
1018 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, MiniportOldIrql
);
1020 if (EndpointRequirements
[0])
1022 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
1023 EndpointRequirements
[0]);
1027 HeaderBuffer
= NULL
;
1030 if (HeaderBuffer
|| EndpointRequirements
[0] == 0)
1032 Endpoint
->HeaderBuffer
= HeaderBuffer
;
1033 Status
= STATUS_SUCCESS
;
1037 Endpoint
->HeaderBuffer
= 0;
1038 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1041 if (Endpoint
->HeaderBuffer
&& HeaderBuffer
)
1043 Endpoint
->EndpointProperties
.BufferVA
= HeaderBuffer
->VirtualAddress
;
1044 Endpoint
->EndpointProperties
.BufferPA
= HeaderBuffer
->PhysicalAddress
;
1045 Endpoint
->EndpointProperties
.BufferLength
= HeaderBuffer
->BufferLength
;
1048 if (NT_SUCCESS(Status
))
1050 MiniportOpenEndpoint(FdoDevice
, Endpoint
);
1052 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1053 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1055 if (Endpoint
->StateLast
== USBPORT_ENDPOINT_ACTIVE
)
1057 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1059 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1061 USBPORT_ENDPOINT_ACTIVE
);
1063 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1066 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1067 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1070 InterlockedDecrement(&Endpoint
->LockCounter
);
1077 USBPORT_FlushClosedEndpointList(IN PDEVICE_OBJECT FdoDevice
)
1079 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1081 PLIST_ENTRY ClosedList
;
1082 PUSBPORT_ENDPOINT Endpoint
;
1084 DPRINT("USBPORT_FlushClosedEndpointList: ... \n");
1086 FdoExtension
= FdoDevice
->DeviceExtension
;
1088 KeAcquireSpinLock(&FdoExtension
->EndpointClosedSpinLock
, &OldIrql
);
1089 ClosedList
= &FdoExtension
->EndpointClosedList
;
1091 while (!IsListEmpty(ClosedList
))
1093 Endpoint
= CONTAINING_RECORD(ClosedList
->Flink
,
1097 RemoveHeadList(ClosedList
);
1098 Endpoint
->CloseLink
.Flink
= NULL
;
1099 Endpoint
->CloseLink
.Blink
= NULL
;
1101 KeReleaseSpinLock(&FdoExtension
->EndpointClosedSpinLock
, OldIrql
);
1103 USBPORT_DeleteEndpoint(FdoDevice
, Endpoint
);
1105 KeAcquireSpinLock(&FdoExtension
->EndpointClosedSpinLock
, &OldIrql
);
1108 KeReleaseSpinLock(&FdoExtension
->EndpointClosedSpinLock
, OldIrql
);
1113 USBPORT_InvalidateEndpointHandler(IN PDEVICE_OBJECT FdoDevice
,
1114 IN PUSBPORT_ENDPOINT Endpoint
,
1117 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1118 PUSBPORT_REGISTRATION_PACKET Packet
;
1120 PLIST_ENTRY WorkerLink
;
1121 PUSBPORT_ENDPOINT endpoint
;
1123 BOOLEAN IsAddEntry
= FALSE
;
1125 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: Endpoint - %p, Type - %x\n",
1129 FdoExtension
= FdoDevice
->DeviceExtension
;
1130 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1134 WorkerLink
= &Endpoint
->WorkerLink
;
1135 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1136 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: KeAcquireSpinLock \n");
1138 if ((!WorkerLink
->Flink
|| !WorkerLink
->Blink
) &&
1139 !(Endpoint
->Flags
& ENDPOINT_FLAG_IDLE
) &&
1140 USBPORT_GetEndpointState(Endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1142 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1143 InsertTailList(&FdoExtension
->WorkerList
, WorkerLink
);
1147 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1149 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
1150 Type
= INVALIDATE_ENDPOINT_WORKER_THREAD
;
1154 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1156 Entry
= &FdoExtension
->EndpointList
;
1158 while (Entry
&& Entry
!= &FdoExtension
->EndpointList
)
1160 endpoint
= CONTAINING_RECORD(Entry
,
1164 if (!endpoint
->WorkerLink
.Flink
|| !endpoint
->WorkerLink
.Blink
)
1166 if (!(endpoint
->Flags
& ENDPOINT_FLAG_IDLE
) &&
1167 !(endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
) &&
1168 USBPORT_GetEndpointState(endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1170 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1171 InsertTailList(&FdoExtension
->WorkerList
, &endpoint
->WorkerLink
);
1176 Entry
= endpoint
->EndpointLink
.Flink
;
1179 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1182 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
)
1184 Type
= INVALIDATE_ENDPOINT_WORKER_THREAD
;
1186 else if (IsAddEntry
== FALSE
&& Type
== INVALIDATE_ENDPOINT_INT_NEXT_SOF
)
1188 Type
= INVALIDATE_ENDPOINT_ONLY
;
1193 case INVALIDATE_ENDPOINT_WORKER_THREAD
:
1194 USBPORT_SignalWorkerThread(FdoDevice
);
1197 case INVALIDATE_ENDPOINT_WORKER_DPC
:
1198 KeInsertQueueDpc(&FdoExtension
->WorkerRequestDpc
, NULL
, NULL
);
1201 case INVALIDATE_ENDPOINT_INT_NEXT_SOF
:
1202 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1203 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
1204 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1211 USBPORT_DmaEndpointPaused(IN PDEVICE_OBJECT FdoDevice
,
1212 IN PUSBPORT_ENDPOINT Endpoint
)
1214 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1215 PUSBPORT_REGISTRATION_PACKET Packet
;
1217 PUSBPORT_TRANSFER Transfer
;
1221 ULONG CompletedLen
= 0;
1224 DPRINT_CORE("USBPORT_DmaEndpointPaused \n");
1226 FdoExtension
= FdoDevice
->DeviceExtension
;
1227 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1229 Entry
= Endpoint
->TransferList
.Flink
;
1231 if (Entry
== &Endpoint
->TransferList
)
1232 return USBPORT_ENDPOINT_ACTIVE
;
1234 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
1236 Transfer
= CONTAINING_RECORD(Entry
,
1240 if (Transfer
->Flags
& (TRANSFER_FLAG_CANCELED
| TRANSFER_FLAG_ABORTED
))
1242 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
&&
1243 Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
&&
1244 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1246 Urb
= Transfer
->Urb
;
1248 Frame
= Urb
->UrbIsochronousTransfer
.StartFrame
+
1249 Urb
->UrbIsochronousTransfer
.NumberOfPackets
;
1251 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1252 CurrentFrame
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
1253 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1255 if (Frame
+ 1 > CurrentFrame
)
1257 return USBPORT_GetEndpointState(Endpoint
);
1261 if ((Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
) &&
1262 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1264 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1266 Packet
->AbortTransfer(FdoExtension
->MiniPortExt
,
1268 Transfer
->MiniportTransfer
,
1271 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1273 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1275 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_FlushIsoTransfer\n");
1276 ASSERT(FALSE
); //USBPORT_FlushIsoTransfer();
1280 Transfer
->CompletedTransferLen
= CompletedLen
;
1284 RemoveEntryList(&Transfer
->TransferLink
);
1285 Entry
= Transfer
->TransferLink
.Flink
;
1287 if (Transfer
->Flags
& TRANSFER_FLAG_SPLITED
)
1289 USBPORT_CancelSplitTransfer(Transfer
);
1293 InsertTailList(&Endpoint
->CancelList
, &Transfer
->TransferLink
);
1298 Entry
= Transfer
->TransferLink
.Flink
;
1302 return USBPORT_ENDPOINT_ACTIVE
;
1307 USBPORT_DmaEndpointActive(IN PDEVICE_OBJECT FdoDevice
,
1308 IN PUSBPORT_ENDPOINT Endpoint
)
1310 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1311 PUSBPORT_REGISTRATION_PACKET Packet
;
1313 PUSBPORT_TRANSFER Transfer
;
1314 LARGE_INTEGER TimeOut
;
1318 DPRINT_CORE("USBPORT_DmaEndpointActive \n");
1320 FdoExtension
= FdoDevice
->DeviceExtension
;
1322 Entry
= Endpoint
->TransferList
.Flink
;
1324 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
1326 Transfer
= CONTAINING_RECORD(Entry
,
1330 if (!(Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
) &&
1331 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1333 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1335 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1337 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1339 DPRINT1("USBPORT_DmaEndpointActive: FIXME call SubmitIsoTransfer\n");
1341 MpStatus
= Packet
->SubmitIsoTransfer(FdoExtension
->MiniPortExt
,
1343 &Transfer
->TransferParameters
,
1344 Transfer
->MiniportTransfer
,
1345 NULL
);//&Transfer->IsoTransferParameters);
1349 MpStatus
= Packet
->SubmitTransfer(FdoExtension
->MiniPortExt
,
1351 &Transfer
->TransferParameters
,
1352 Transfer
->MiniportTransfer
,
1356 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1360 if ((MpStatus
!= MP_STATUS_FAILURE
) && Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1362 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_ErrorCompleteIsoTransfer\n");
1363 ASSERT(FALSE
); //USBPORT_ErrorCompleteIsoTransfer();
1366 return USBPORT_ENDPOINT_ACTIVE
;
1369 Transfer
->Flags
|= TRANSFER_FLAG_SUBMITED
;
1370 KeQuerySystemTime(&Transfer
->Time
);
1372 TimeOut
.QuadPart
= 10000 * Transfer
->TimeOut
;
1373 Transfer
->Time
.QuadPart
+= TimeOut
.QuadPart
;
1376 if (Transfer
->Flags
& (TRANSFER_FLAG_CANCELED
| TRANSFER_FLAG_ABORTED
))
1378 return USBPORT_ENDPOINT_PAUSED
;
1381 Entry
= Transfer
->TransferLink
.Flink
;
1384 return USBPORT_ENDPOINT_ACTIVE
;
1389 USBPORT_DmaEndpointWorker(IN PUSBPORT_ENDPOINT Endpoint
)
1391 PDEVICE_OBJECT FdoDevice
;
1393 ULONG EndpointState
;
1394 BOOLEAN IsPaused
= FALSE
;
1396 DPRINT_CORE("USBPORT_DmaEndpointWorker ... \n");
1398 FdoDevice
= Endpoint
->FdoDevice
;
1400 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1402 PrevState
= USBPORT_GetEndpointState(Endpoint
);
1404 if (PrevState
== USBPORT_ENDPOINT_PAUSED
)
1406 EndpointState
= USBPORT_DmaEndpointPaused(FdoDevice
, Endpoint
);
1408 else if (PrevState
== USBPORT_ENDPOINT_ACTIVE
)
1410 EndpointState
= USBPORT_DmaEndpointActive(FdoDevice
, Endpoint
);
1414 #ifndef NDEBUG_USBPORT_CORE
1415 DPRINT1("USBPORT_DmaEndpointWorker: DbgBreakPoint. EndpointState - %x\n",
1419 EndpointState
= USBPORT_ENDPOINT_UNKNOWN
;
1422 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1424 USBPORT_FlushCancelList(Endpoint
);
1426 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1428 if (EndpointState
== PrevState
)
1430 if (EndpointState
== USBPORT_ENDPOINT_PAUSED
)
1437 USBPORT_SetEndpointState(Endpoint
, EndpointState
);
1440 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1444 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1446 INVALIDATE_ENDPOINT_WORKER_THREAD
);
1449 DPRINT_CORE("USBPORT_DmaEndpointWorker exit \n");
1454 USBPORT_EndpointWorker(IN PUSBPORT_ENDPOINT Endpoint
,
1455 IN BOOLEAN LockNotChecked
)
1457 PDEVICE_OBJECT FdoDevice
;
1458 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1459 PUSBPORT_REGISTRATION_PACKET Packet
;
1460 ULONG EndpointState
;
1462 DPRINT_CORE("USBPORT_EndpointWorker: Endpoint - %p, LockNotChecked - %x\n",
1466 FdoDevice
= Endpoint
->FdoDevice
;
1467 FdoExtension
= FdoDevice
->DeviceExtension
;
1468 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1470 if (LockNotChecked
== FALSE
)
1472 if (InterlockedIncrement(&Endpoint
->LockCounter
))
1474 InterlockedDecrement(&Endpoint
->LockCounter
);
1475 DPRINT_CORE("USBPORT_EndpointWorker: LockCounter > 0\n");
1480 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1482 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
1484 if (USBPORT_GetEndpointState(Endpoint
) == USBPORT_ENDPOINT_CLOSED
)
1486 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1487 InterlockedDecrement(&Endpoint
->LockCounter
);
1488 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_CLOSED. return FALSE\n");
1492 if ((Endpoint
->Flags
& (ENDPOINT_FLAG_ROOTHUB_EP0
| ENDPOINT_FLAG_NUKE
)) == 0)
1494 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1495 Packet
->PollEndpoint(FdoExtension
->MiniPortExt
, Endpoint
+ 1);
1496 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1499 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
1501 if (EndpointState
== USBPORT_ENDPOINT_REMOVE
)
1503 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1504 Endpoint
->StateLast
= USBPORT_ENDPOINT_CLOSED
;
1505 Endpoint
->StateNext
= USBPORT_ENDPOINT_CLOSED
;
1506 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1508 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1510 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1512 ExInterlockedInsertTailList(&FdoExtension
->EndpointClosedList
,
1513 &Endpoint
->CloseLink
,
1514 &FdoExtension
->EndpointClosedSpinLock
);
1516 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1518 InterlockedDecrement(&Endpoint
->LockCounter
);
1519 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_REMOVE. return FALSE\n");
1523 if (!IsListEmpty(&Endpoint
->PendingTransferList
) ||
1524 !IsListEmpty(&Endpoint
->TransferList
) ||
1525 !IsListEmpty(&Endpoint
->CancelList
))
1527 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1529 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
1531 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1532 if (EndpointState
== Endpoint
->StateNext
)
1534 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1536 if (Endpoint
->EndpointWorker
)
1538 USBPORT_DmaEndpointWorker(Endpoint
);
1542 USBPORT_RootHubEndpointWorker(Endpoint
);
1545 USBPORT_FlushAbortList(Endpoint
);
1547 InterlockedDecrement(&Endpoint
->LockCounter
);
1548 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");
1552 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1553 InterlockedDecrement(&Endpoint
->LockCounter
);
1555 DPRINT_CORE("USBPORT_EndpointWorker: return TRUE\n");
1559 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1561 USBPORT_FlushAbortList(Endpoint
);
1563 InterlockedDecrement(&Endpoint
->LockCounter
);
1564 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");