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
:
32 Overhead
= USB2_FS_ISOCHRONOUS_OVERHEAD
;
35 case USBPORT_TRANSFER_TYPE_INTERRUPT
:
36 Overhead
= USB2_FS_INTERRUPT_OVERHEAD
;
39 default: //USBPORT_TRANSFER_TYPE_CONTROL or USBPORT_TRANSFER_TYPE_BULK
50 Bandwidth
= (EndpointProperties
->TotalMaxPacketSize
+ Overhead
) * 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
;
474 PUSBPORT_REGISTRATION_PACKET Packet
;
475 PUSB2_TT_EXTENSION TtExtension
;
480 DPRINT("USBPORT_ClosePipe \n");
482 FdoExtension
= FdoDevice
->DeviceExtension
;
484 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_CLOSED
)
487 USBPORT_RemovePipeHandle(DeviceHandle
, PipeHandle
);
489 PipeHandle
->Flags
|= PIPE_HANDLE_FLAG_CLOSED
;
491 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
)
493 PipeHandle
->Flags
&= ~PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
;
497 Endpoint
= PipeHandle
->Endpoint
;
499 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
501 if ((Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
) &&
502 (Endpoint
->EndpointProperties
.TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
))
504 PdoExtension
= FdoExtension
->RootHubPdo
->DeviceExtension
;
505 PdoExtension
->Endpoint
= NULL
;
508 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
514 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
515 &Endpoint
->EndpointOldIrql
);
517 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
520 if (!IsListEmpty(&Endpoint
->TransferList
))
523 if (!IsListEmpty(&Endpoint
->CancelList
))
526 if (!IsListEmpty(&Endpoint
->AbortList
))
529 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
530 if (Endpoint
->StateLast
!= Endpoint
->StateNext
)
532 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
534 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
535 Endpoint
->EndpointOldIrql
);
537 if (InterlockedIncrement(&Endpoint
->LockCounter
))
539 InterlockedDecrement(&Endpoint
->LockCounter
);
544 USBPORT_Wait(FdoDevice
, 1);
547 Endpoint
->DeviceHandle
= NULL
;
548 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
550 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
552 USBPORT_FreeBandwidthUSB2(FdoDevice
, Endpoint
);
554 KeAcquireSpinLock(&FdoExtension
->TtSpinLock
, &OldIrql
);
556 TtExtension
= Endpoint
->TtExtension
;
560 RemoveEntryList(&Endpoint
->TtLink
);
562 Endpoint
->TtLink
.Flink
= NULL
;
563 Endpoint
->TtLink
.Blink
= NULL
;
565 if (TtExtension
->Flags
& USB2_TT_EXTENSION_FLAG_DELETED
)
567 if (IsListEmpty(&TtExtension
->EndpointList
))
569 USBPORT_UpdateAllocatedBwTt(TtExtension
);
571 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
573 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
576 ExFreePool(TtExtension
);
581 KeReleaseSpinLock(&FdoExtension
->TtSpinLock
, OldIrql
);
585 USBPORT_FreeBandwidth(FdoDevice
, Endpoint
);
588 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
589 USBPORT_SetEndpointState(Endpoint
, USBPORT_ENDPOINT_REMOVE
);
590 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
592 USBPORT_SignalWorkerThread(FdoDevice
);
597 MiniportOpenEndpoint(IN PDEVICE_OBJECT FdoDevice
,
598 IN PUSBPORT_ENDPOINT Endpoint
)
600 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
601 PUSBPORT_REGISTRATION_PACKET Packet
;
606 DPRINT("MiniportOpenEndpoint: Endpoint - %p\n", Endpoint
);
608 FdoExtension
= FdoDevice
->DeviceExtension
;
609 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
611 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
613 Endpoint
->Flags
&= ~ENDPOINT_FLAG_CLOSED
;
615 MpStatus
= Packet
->OpenEndpoint(FdoExtension
->MiniPortExt
,
616 &Endpoint
->EndpointProperties
,
621 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
623 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
||
624 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
626 ++FdoExtension
->PeriodicEndpoints
;
629 Endpoint
->Flags
|= ENDPOINT_FLAG_OPENED
;
632 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
638 USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice
,
639 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
640 IN PUSBPORT_PIPE_HANDLE PipeHandle
,
641 IN OUT PUSBD_STATUS UsbdStatus
)
643 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
644 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
645 PUSBPORT_REGISTRATION_PACKET Packet
;
647 PUSBPORT_ENDPOINT Endpoint
;
648 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
649 PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
653 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
= {0};
654 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
656 USBD_STATUS USBDStatus
;
659 USHORT MaxPacketSize
;
660 USHORT AdditionalTransaction
;
661 BOOLEAN IsAllocatedBandwidth
;
663 DPRINT("USBPORT_OpenPipe: DeviceHandle - %p, FdoDevice - %p, PipeHandle - %p\n",
668 FdoExtension
= FdoDevice
->DeviceExtension
;
669 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
671 EndpointSize
= sizeof(USBPORT_ENDPOINT
) + Packet
->MiniPortEndpointSize
;
673 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
675 EndpointSize
+= sizeof(USB2_TT_ENDPOINT
);
678 if (PipeHandle
->EndpointDescriptor
.wMaxPacketSize
== 0)
680 USBPORT_AddPipeHandle(DeviceHandle
, PipeHandle
);
682 PipeHandle
->Flags
= (PipeHandle
->Flags
& ~PIPE_HANDLE_FLAG_CLOSED
) |
683 PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
;
685 PipeHandle
->Endpoint
= (PUSBPORT_ENDPOINT
)-1;
687 return STATUS_SUCCESS
;
690 Endpoint
= ExAllocatePoolWithTag(NonPagedPool
, EndpointSize
, USB_PORT_TAG
);
694 DPRINT1("USBPORT_OpenPipe: Not allocated Endpoint!\n");
695 Status
= STATUS_INSUFFICIENT_RESOURCES
;
699 RtlZeroMemory(Endpoint
, EndpointSize
);
701 Endpoint
->FdoDevice
= FdoDevice
;
702 Endpoint
->DeviceHandle
= DeviceHandle
;
703 Endpoint
->LockCounter
= -1;
705 Endpoint
->TtExtension
= DeviceHandle
->TtExtension
;
707 if (DeviceHandle
->TtExtension
)
709 ExInterlockedInsertTailList(&DeviceHandle
->TtExtension
->EndpointList
,
711 &FdoExtension
->TtSpinLock
);
714 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
716 Endpoint
->TtEndpoint
= (PUSB2_TT_ENDPOINT
)((ULONG_PTR
)Endpoint
+
717 sizeof(USBPORT_ENDPOINT
) +
718 Packet
->MiniPortEndpointSize
);
722 Endpoint
->TtEndpoint
= NULL
;
725 KeInitializeSpinLock(&Endpoint
->EndpointSpinLock
);
726 KeInitializeSpinLock(&Endpoint
->StateChangeSpinLock
);
728 InitializeListHead(&Endpoint
->PendingTransferList
);
729 InitializeListHead(&Endpoint
->TransferList
);
730 InitializeListHead(&Endpoint
->CancelList
);
731 InitializeListHead(&Endpoint
->AbortList
);
733 EndpointProperties
= &Endpoint
->EndpointProperties
;
734 EndpointDescriptor
= &PipeHandle
->EndpointDescriptor
;
736 MaxPacketSize
= EndpointDescriptor
->wMaxPacketSize
& 0x7FF;
737 AdditionalTransaction
= (EndpointDescriptor
->wMaxPacketSize
>> 11) & 3;
739 EndpointProperties
->DeviceAddress
= DeviceHandle
->DeviceAddress
;
740 EndpointProperties
->DeviceSpeed
= DeviceHandle
->DeviceSpeed
;
741 EndpointProperties
->Period
= 0;
742 EndpointProperties
->EndpointAddress
= EndpointDescriptor
->bEndpointAddress
;
743 EndpointProperties
->TransactionPerMicroframe
= AdditionalTransaction
+ 1;
744 EndpointProperties
->MaxPacketSize
= MaxPacketSize
;
745 EndpointProperties
->TotalMaxPacketSize
= MaxPacketSize
*
746 (AdditionalTransaction
+ 1);
748 if (Endpoint
->TtExtension
)
750 EndpointProperties
->HubAddr
= Endpoint
->TtExtension
->DeviceAddress
;
754 EndpointProperties
->HubAddr
= -1;
757 EndpointProperties
->PortNumber
= DeviceHandle
->PortNumber
;
759 switch (EndpointDescriptor
->bmAttributes
& USB_ENDPOINT_TYPE_MASK
)
761 case USB_ENDPOINT_TYPE_CONTROL
:
762 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_CONTROL
;
764 if (EndpointProperties
->EndpointAddress
== 0)
766 EndpointProperties
->MaxTransferSize
= 0x1000; // OUT Ep0
770 EndpointProperties
->MaxTransferSize
= 0x10000;
775 case USB_ENDPOINT_TYPE_ISOCHRONOUS
:
776 DPRINT1("USBPORT_OpenPipe: USB_ENDPOINT_TYPE_ISOCHRONOUS UNIMPLEMENTED. FIXME. \n");
777 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_ISOCHRONOUS
;
778 EndpointProperties
->MaxTransferSize
= 0x1000000;
781 case USB_ENDPOINT_TYPE_BULK
:
782 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_BULK
;
783 EndpointProperties
->MaxTransferSize
= 0x10000;
786 case USB_ENDPOINT_TYPE_INTERRUPT
:
787 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_INTERRUPT
;
788 EndpointProperties
->MaxTransferSize
= 0x400;
792 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
794 if (EndpointProperties
->DeviceSpeed
== UsbHighSpeed
)
796 Interval
= USBPORT_NormalizeHsInterval(EndpointDescriptor
->bInterval
);
800 Interval
= EndpointDescriptor
->bInterval
;
803 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_32ms
;
805 if (Interval
&& (Interval
< USB2_FRAMES
))
807 if ((EndpointProperties
->DeviceSpeed
!= UsbLowSpeed
) ||
808 (Interval
>= ENDPOINT_INTERRUPT_8ms
))
810 if (!(Interval
& ENDPOINT_INTERRUPT_32ms
))
812 Period
= EndpointProperties
->Period
;
818 while (!(Period
& Interval
));
820 EndpointProperties
->Period
= Period
;
825 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_8ms
;
830 if (EndpointProperties
->TransferType
== USB_ENDPOINT_TYPE_ISOCHRONOUS
)
832 if (EndpointProperties
->DeviceSpeed
== UsbHighSpeed
)
834 EndpointProperties
->Period
=
835 USBPORT_NormalizeHsInterval(EndpointDescriptor
->bInterval
);
839 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_1ms
;
843 if ((DeviceHandle
->Flags
& DEVICE_HANDLE_FLAG_ROOTHUB
) != 0)
845 Endpoint
->Flags
|= ENDPOINT_FLAG_ROOTHUB_EP0
;
848 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
850 IsAllocatedBandwidth
= USBPORT_AllocateBandwidthUSB2(FdoDevice
, Endpoint
);
854 EndpointProperties
->UsbBandwidth
= USBPORT_CalculateUsbBandwidth(FdoDevice
,
857 IsAllocatedBandwidth
= USBPORT_AllocateBandwidth(FdoDevice
, Endpoint
);
860 if (!IsAllocatedBandwidth
)
862 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBD_STATUS_NO_BANDWIDTH
);
866 *UsbdStatus
= USBD_STATUS_NO_BANDWIDTH
;
872 Direction
= USB_ENDPOINT_DIRECTION_OUT(EndpointDescriptor
->bEndpointAddress
);
873 EndpointProperties
->Direction
= Direction
;
875 if (DeviceHandle
->IsRootHub
)
877 Endpoint
->EndpointWorker
= 0; // USBPORT_RootHubEndpointWorker;
879 Endpoint
->Flags
|= ENDPOINT_FLAG_ROOTHUB_EP0
;
881 Endpoint
->StateLast
= USBPORT_ENDPOINT_ACTIVE
;
882 Endpoint
->StateNext
= USBPORT_ENDPOINT_ACTIVE
;
884 PdoExtension
= FdoExtension
->RootHubPdo
->DeviceExtension
;
886 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
888 PdoExtension
->Endpoint
= Endpoint
;
891 USBDStatus
= USBD_STATUS_SUCCESS
;
895 Endpoint
->EndpointWorker
= 1; // USBPORT_DmaEndpointWorker;
897 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
899 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
900 &Endpoint
->EndpointProperties
,
901 &EndpointRequirements
);
903 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
905 if ((EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_BULK
) ||
906 (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
))
908 EndpointProperties
->MaxTransferSize
= EndpointRequirements
.MaxTransferSize
;
911 if (EndpointRequirements
.HeaderBufferSize
)
913 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
914 EndpointRequirements
.HeaderBufferSize
);
921 if (HeaderBuffer
|| (EndpointRequirements
.HeaderBufferSize
== 0))
923 Endpoint
->HeaderBuffer
= HeaderBuffer
;
927 EndpointProperties
->BufferVA
= HeaderBuffer
->VirtualAddress
;
928 EndpointProperties
->BufferPA
= HeaderBuffer
->PhysicalAddress
;
929 EndpointProperties
->BufferLength
= HeaderBuffer
->BufferLength
; // BufferLength + LengthPadded;
932 MpStatus
= MiniportOpenEndpoint(FdoDevice
, Endpoint
);
934 Endpoint
->Flags
|= ENDPOINT_FLAG_DMA_TYPE
;
935 Endpoint
->Flags
|= ENDPOINT_FLAG_QUEUENE_EMPTY
;
941 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
942 &Endpoint
->EndpointOldIrql
);
944 Endpoint
->StateLast
= USBPORT_ENDPOINT_PAUSED
;
945 Endpoint
->StateNext
= USBPORT_ENDPOINT_PAUSED
;
947 USBPORT_SetEndpointState(Endpoint
, USBPORT_ENDPOINT_ACTIVE
);
949 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
950 Endpoint
->EndpointOldIrql
);
954 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
955 &Endpoint
->EndpointOldIrql
);
957 State
= USBPORT_GetEndpointState(Endpoint
);
959 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
960 Endpoint
->EndpointOldIrql
);
962 if (State
== USBPORT_ENDPOINT_ACTIVE
)
967 USBPORT_Wait(FdoDevice
, 1); // 1 msec.
973 MpStatus
= MP_STATUS_NO_RESOURCES
;
974 Endpoint
->HeaderBuffer
= NULL
;
979 USBDStatus
= USBD_STATUS_INSUFFICIENT_RESOURCES
;
983 USBDStatus
= USBD_STATUS_SUCCESS
;
989 *UsbdStatus
= USBDStatus
;
992 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBDStatus
);
994 if (NT_SUCCESS(Status
))
996 USBPORT_AddPipeHandle(DeviceHandle
, PipeHandle
);
998 ExInterlockedInsertTailList(&FdoExtension
->EndpointList
,
999 &Endpoint
->EndpointLink
,
1000 &FdoExtension
->EndpointListSpinLock
);
1002 PipeHandle
->Endpoint
= Endpoint
;
1003 PipeHandle
->Flags
&= ~PIPE_HANDLE_FLAG_CLOSED
;
1012 if (IsAllocatedBandwidth
)
1014 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1016 USBPORT_FreeBandwidthUSB2(FdoDevice
, Endpoint
);
1020 USBPORT_FreeBandwidth(FdoDevice
, Endpoint
);
1024 if (Endpoint
->TtExtension
)
1026 KeAcquireSpinLock(&FdoExtension
->TtSpinLock
, &OldIrql
);
1027 RemoveEntryList(&Endpoint
->TtLink
);
1028 KeReleaseSpinLock(&FdoExtension
->TtSpinLock
, OldIrql
);
1031 ExFreePoolWithTag(Endpoint
, USB_PORT_TAG
);
1034 DPRINT1("USBPORT_OpenPipe: Status - %lx\n", Status
);
1040 USBPORT_ReopenPipe(IN PDEVICE_OBJECT FdoDevice
,
1041 IN PUSBPORT_ENDPOINT Endpoint
)
1043 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1044 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
1045 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
= {0};
1046 PUSBPORT_REGISTRATION_PACKET Packet
;
1047 KIRQL MiniportOldIrql
;
1050 DPRINT("USBPORT_ReopenPipe ... \n");
1052 FdoExtension
= FdoDevice
->DeviceExtension
;
1053 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1057 if (!InterlockedIncrement(&Endpoint
->LockCounter
))
1060 InterlockedDecrement(&Endpoint
->LockCounter
);
1061 USBPORT_Wait(FdoDevice
, 1);
1064 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &MiniportOldIrql
);
1066 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1068 USBPORT_ENDPOINT_REMOVE
);
1070 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, MiniportOldIrql
);
1072 USBPORT_Wait(FdoDevice
, 2);
1074 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
1076 RtlZeroMemory(Endpoint
+ 1,
1077 Packet
->MiniPortEndpointSize
);
1079 if (Endpoint
->HeaderBuffer
)
1081 USBPORT_FreeCommonBuffer(FdoDevice
, Endpoint
->HeaderBuffer
);
1082 Endpoint
->HeaderBuffer
= NULL
;
1085 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &MiniportOldIrql
);
1087 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
1088 &Endpoint
->EndpointProperties
,
1089 &EndpointRequirements
);
1091 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, MiniportOldIrql
);
1093 if (EndpointRequirements
.HeaderBufferSize
)
1095 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
1096 EndpointRequirements
.HeaderBufferSize
);
1100 HeaderBuffer
= NULL
;
1103 if (HeaderBuffer
|| EndpointRequirements
.HeaderBufferSize
== 0)
1105 Endpoint
->HeaderBuffer
= HeaderBuffer
;
1106 Status
= STATUS_SUCCESS
;
1110 Endpoint
->HeaderBuffer
= 0;
1111 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1114 if (Endpoint
->HeaderBuffer
&& HeaderBuffer
)
1116 Endpoint
->EndpointProperties
.BufferVA
= HeaderBuffer
->VirtualAddress
;
1117 Endpoint
->EndpointProperties
.BufferPA
= HeaderBuffer
->PhysicalAddress
;
1118 Endpoint
->EndpointProperties
.BufferLength
= HeaderBuffer
->BufferLength
;
1121 if (NT_SUCCESS(Status
))
1123 MiniportOpenEndpoint(FdoDevice
, Endpoint
);
1125 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1126 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1128 if (Endpoint
->StateLast
== USBPORT_ENDPOINT_ACTIVE
)
1130 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1132 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1134 USBPORT_ENDPOINT_ACTIVE
);
1136 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1139 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1140 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1143 InterlockedDecrement(&Endpoint
->LockCounter
);
1150 USBPORT_FlushClosedEndpointList(IN PDEVICE_OBJECT FdoDevice
)
1152 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1154 PLIST_ENTRY ClosedList
;
1155 PUSBPORT_ENDPOINT Endpoint
;
1157 DPRINT("USBPORT_FlushClosedEndpointList: ... \n");
1159 FdoExtension
= FdoDevice
->DeviceExtension
;
1161 KeAcquireSpinLock(&FdoExtension
->EndpointClosedSpinLock
, &OldIrql
);
1162 ClosedList
= &FdoExtension
->EndpointClosedList
;
1164 while (!IsListEmpty(ClosedList
))
1166 Endpoint
= CONTAINING_RECORD(ClosedList
->Flink
,
1170 RemoveHeadList(ClosedList
);
1171 Endpoint
->CloseLink
.Flink
= NULL
;
1172 Endpoint
->CloseLink
.Blink
= NULL
;
1174 KeReleaseSpinLock(&FdoExtension
->EndpointClosedSpinLock
, OldIrql
);
1176 USBPORT_DeleteEndpoint(FdoDevice
, Endpoint
);
1178 KeAcquireSpinLock(&FdoExtension
->EndpointClosedSpinLock
, &OldIrql
);
1181 KeReleaseSpinLock(&FdoExtension
->EndpointClosedSpinLock
, OldIrql
);
1186 USBPORT_InvalidateEndpointHandler(IN PDEVICE_OBJECT FdoDevice
,
1187 IN PUSBPORT_ENDPOINT Endpoint
,
1190 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1191 PUSBPORT_REGISTRATION_PACKET Packet
;
1193 PLIST_ENTRY WorkerLink
;
1194 PUSBPORT_ENDPOINT endpoint
;
1196 BOOLEAN IsAddEntry
= FALSE
;
1198 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: Endpoint - %p, Type - %x\n",
1202 FdoExtension
= FdoDevice
->DeviceExtension
;
1203 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1207 WorkerLink
= &Endpoint
->WorkerLink
;
1208 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1209 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: KeAcquireSpinLock \n");
1211 if ((!WorkerLink
->Flink
|| !WorkerLink
->Blink
) &&
1212 !(Endpoint
->Flags
& ENDPOINT_FLAG_IDLE
) &&
1213 USBPORT_GetEndpointState(Endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1215 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1216 InsertTailList(&FdoExtension
->WorkerList
, WorkerLink
);
1220 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1222 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
1223 Type
= INVALIDATE_ENDPOINT_WORKER_THREAD
;
1227 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1229 Entry
= &FdoExtension
->EndpointList
;
1231 while (Entry
&& Entry
!= &FdoExtension
->EndpointList
)
1233 endpoint
= CONTAINING_RECORD(Entry
,
1237 if (!endpoint
->WorkerLink
.Flink
|| !endpoint
->WorkerLink
.Blink
)
1239 if (!(endpoint
->Flags
& ENDPOINT_FLAG_IDLE
) &&
1240 !(endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
) &&
1241 USBPORT_GetEndpointState(endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1243 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1244 InsertTailList(&FdoExtension
->WorkerList
, &endpoint
->WorkerLink
);
1249 Entry
= endpoint
->EndpointLink
.Flink
;
1252 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1255 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
)
1257 Type
= INVALIDATE_ENDPOINT_WORKER_THREAD
;
1259 else if (IsAddEntry
== FALSE
&& Type
== INVALIDATE_ENDPOINT_INT_NEXT_SOF
)
1261 Type
= INVALIDATE_ENDPOINT_ONLY
;
1266 case INVALIDATE_ENDPOINT_WORKER_THREAD
:
1267 USBPORT_SignalWorkerThread(FdoDevice
);
1270 case INVALIDATE_ENDPOINT_WORKER_DPC
:
1271 KeInsertQueueDpc(&FdoExtension
->WorkerRequestDpc
, NULL
, NULL
);
1274 case INVALIDATE_ENDPOINT_INT_NEXT_SOF
:
1275 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1276 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
1277 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1284 USBPORT_DmaEndpointPaused(IN PDEVICE_OBJECT FdoDevice
,
1285 IN PUSBPORT_ENDPOINT Endpoint
)
1287 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1288 PUSBPORT_REGISTRATION_PACKET Packet
;
1290 PUSBPORT_TRANSFER Transfer
;
1294 ULONG CompletedLen
= 0;
1297 DPRINT_CORE("USBPORT_DmaEndpointPaused \n");
1299 FdoExtension
= FdoDevice
->DeviceExtension
;
1300 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1302 Entry
= Endpoint
->TransferList
.Flink
;
1304 if (Entry
== &Endpoint
->TransferList
)
1305 return USBPORT_ENDPOINT_ACTIVE
;
1307 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
1309 Transfer
= CONTAINING_RECORD(Entry
,
1313 if (Transfer
->Flags
& (TRANSFER_FLAG_CANCELED
| TRANSFER_FLAG_ABORTED
))
1315 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
&&
1316 Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
&&
1317 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1319 Urb
= Transfer
->Urb
;
1321 Frame
= Urb
->UrbIsochronousTransfer
.StartFrame
+
1322 Urb
->UrbIsochronousTransfer
.NumberOfPackets
;
1324 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1325 CurrentFrame
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
1326 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1328 if (Frame
+ 1 > CurrentFrame
)
1330 return USBPORT_GetEndpointState(Endpoint
);
1334 if ((Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
) &&
1335 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1337 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1339 Packet
->AbortTransfer(FdoExtension
->MiniPortExt
,
1341 Transfer
->MiniportTransfer
,
1344 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1346 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1348 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_FlushIsoTransfer\n");
1349 ASSERT(FALSE
); //USBPORT_FlushIsoTransfer();
1353 Transfer
->CompletedTransferLen
= CompletedLen
;
1357 RemoveEntryList(&Transfer
->TransferLink
);
1358 Entry
= Transfer
->TransferLink
.Flink
;
1360 if (Transfer
->Flags
& TRANSFER_FLAG_SPLITED
)
1362 USBPORT_CancelSplitTransfer(Transfer
);
1366 InsertTailList(&Endpoint
->CancelList
, &Transfer
->TransferLink
);
1371 Entry
= Transfer
->TransferLink
.Flink
;
1375 return USBPORT_ENDPOINT_ACTIVE
;
1380 USBPORT_DmaEndpointActive(IN PDEVICE_OBJECT FdoDevice
,
1381 IN PUSBPORT_ENDPOINT Endpoint
)
1383 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1384 PUSBPORT_REGISTRATION_PACKET Packet
;
1386 PUSBPORT_TRANSFER Transfer
;
1387 LARGE_INTEGER TimeOut
;
1391 DPRINT_CORE("USBPORT_DmaEndpointActive \n");
1393 FdoExtension
= FdoDevice
->DeviceExtension
;
1395 Entry
= Endpoint
->TransferList
.Flink
;
1397 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
1399 Transfer
= CONTAINING_RECORD(Entry
,
1403 if (!(Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
) &&
1404 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1406 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1408 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1410 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1412 DPRINT1("USBPORT_DmaEndpointActive: FIXME call SubmitIsoTransfer\n");
1414 MpStatus
= Packet
->SubmitIsoTransfer(FdoExtension
->MiniPortExt
,
1416 &Transfer
->TransferParameters
,
1417 Transfer
->MiniportTransfer
,
1418 NULL
);//&Transfer->IsoTransferParameters);
1422 MpStatus
= Packet
->SubmitTransfer(FdoExtension
->MiniPortExt
,
1424 &Transfer
->TransferParameters
,
1425 Transfer
->MiniportTransfer
,
1429 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1433 if ((MpStatus
!= MP_STATUS_FAILURE
) && Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1435 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_ErrorCompleteIsoTransfer\n");
1436 ASSERT(FALSE
); //USBPORT_ErrorCompleteIsoTransfer();
1439 return USBPORT_ENDPOINT_ACTIVE
;
1442 Transfer
->Flags
|= TRANSFER_FLAG_SUBMITED
;
1443 KeQuerySystemTime(&Transfer
->Time
);
1445 TimeOut
.QuadPart
= 10000 * Transfer
->TimeOut
;
1446 Transfer
->Time
.QuadPart
+= TimeOut
.QuadPart
;
1449 if (Transfer
->Flags
& (TRANSFER_FLAG_CANCELED
| TRANSFER_FLAG_ABORTED
))
1451 return USBPORT_ENDPOINT_PAUSED
;
1454 Entry
= Transfer
->TransferLink
.Flink
;
1457 return USBPORT_ENDPOINT_ACTIVE
;
1462 USBPORT_DmaEndpointWorker(IN PUSBPORT_ENDPOINT Endpoint
)
1464 PDEVICE_OBJECT FdoDevice
;
1466 ULONG EndpointState
;
1467 BOOLEAN IsPaused
= FALSE
;
1469 DPRINT_CORE("USBPORT_DmaEndpointWorker ... \n");
1471 FdoDevice
= Endpoint
->FdoDevice
;
1473 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1475 PrevState
= USBPORT_GetEndpointState(Endpoint
);
1477 if (PrevState
== USBPORT_ENDPOINT_PAUSED
)
1479 EndpointState
= USBPORT_DmaEndpointPaused(FdoDevice
, Endpoint
);
1481 else if (PrevState
== USBPORT_ENDPOINT_ACTIVE
)
1483 EndpointState
= USBPORT_DmaEndpointActive(FdoDevice
, Endpoint
);
1487 #ifndef NDEBUG_USBPORT_CORE
1488 DPRINT1("USBPORT_DmaEndpointWorker: DbgBreakPoint. EndpointState - %x\n",
1492 EndpointState
= USBPORT_ENDPOINT_UNKNOWN
;
1495 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1497 USBPORT_FlushCancelList(Endpoint
);
1499 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1501 if (EndpointState
== PrevState
)
1503 if (EndpointState
== USBPORT_ENDPOINT_PAUSED
)
1510 USBPORT_SetEndpointState(Endpoint
, EndpointState
);
1513 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1517 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1519 INVALIDATE_ENDPOINT_WORKER_THREAD
);
1522 DPRINT_CORE("USBPORT_DmaEndpointWorker exit \n");
1527 USBPORT_EndpointWorker(IN PUSBPORT_ENDPOINT Endpoint
,
1528 IN BOOLEAN LockNotChecked
)
1530 PDEVICE_OBJECT FdoDevice
;
1531 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1532 PUSBPORT_REGISTRATION_PACKET Packet
;
1533 ULONG EndpointState
;
1535 DPRINT_CORE("USBPORT_EndpointWorker: Endpoint - %p, LockNotChecked - %x\n",
1539 FdoDevice
= Endpoint
->FdoDevice
;
1540 FdoExtension
= FdoDevice
->DeviceExtension
;
1541 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1543 if (LockNotChecked
== FALSE
)
1545 if (InterlockedIncrement(&Endpoint
->LockCounter
))
1547 InterlockedDecrement(&Endpoint
->LockCounter
);
1548 DPRINT_CORE("USBPORT_EndpointWorker: LockCounter > 0\n");
1553 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1555 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
1557 if (USBPORT_GetEndpointState(Endpoint
) == USBPORT_ENDPOINT_CLOSED
)
1559 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1560 InterlockedDecrement(&Endpoint
->LockCounter
);
1561 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_CLOSED. return FALSE\n");
1565 if ((Endpoint
->Flags
& (ENDPOINT_FLAG_ROOTHUB_EP0
| ENDPOINT_FLAG_NUKE
)) == 0)
1567 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1568 Packet
->PollEndpoint(FdoExtension
->MiniPortExt
, Endpoint
+ 1);
1569 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1572 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
1574 if (EndpointState
== USBPORT_ENDPOINT_REMOVE
)
1576 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1577 Endpoint
->StateLast
= USBPORT_ENDPOINT_CLOSED
;
1578 Endpoint
->StateNext
= USBPORT_ENDPOINT_CLOSED
;
1579 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1581 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1583 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1585 ExInterlockedInsertTailList(&FdoExtension
->EndpointClosedList
,
1586 &Endpoint
->CloseLink
,
1587 &FdoExtension
->EndpointClosedSpinLock
);
1589 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1591 InterlockedDecrement(&Endpoint
->LockCounter
);
1592 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_REMOVE. return FALSE\n");
1596 if (!IsListEmpty(&Endpoint
->PendingTransferList
) ||
1597 !IsListEmpty(&Endpoint
->TransferList
) ||
1598 !IsListEmpty(&Endpoint
->CancelList
))
1600 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1602 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
1604 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1605 if (EndpointState
== Endpoint
->StateNext
)
1607 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1609 if (Endpoint
->EndpointWorker
)
1611 USBPORT_DmaEndpointWorker(Endpoint
);
1615 USBPORT_RootHubEndpointWorker(Endpoint
);
1618 USBPORT_FlushAbortList(Endpoint
);
1620 InterlockedDecrement(&Endpoint
->LockCounter
);
1621 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");
1625 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1626 InterlockedDecrement(&Endpoint
->LockCounter
);
1628 DPRINT_CORE("USBPORT_EndpointWorker: return TRUE\n");
1632 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1634 USBPORT_FlushAbortList(Endpoint
);
1636 InterlockedDecrement(&Endpoint
->LockCounter
);
1637 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");