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 ULONG MaxBandwidth
= 0;
76 LONG ScheduleOffset
= -1;
81 DPRINT("USBPORT_AllocateBandwidth: FdoDevice - %p, Endpoint - %p\n",
85 FdoExtension
= FdoDevice
->DeviceExtension
;
86 EndpointProperties
= &Endpoint
->EndpointProperties
;
87 TransferType
= EndpointProperties
->TransferType
;
89 if (TransferType
== USBPORT_TRANSFER_TYPE_BULK
||
90 TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
91 Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
93 EndpointProperties
->ScheduleOffset
= 0;
97 TotalBusBandwidth
= FdoExtension
->TotalBusBandwidth
;
98 EndpointBandwidth
= EndpointProperties
->UsbBandwidth
;
100 Period
= EndpointProperties
->Period
;
102 Factor
= USB2_FRAMES
/ Period
;
104 for (Offset
= 0; Offset
< Period
; Offset
++)
106 MinBandwidth
= TotalBusBandwidth
;
107 Bandwidth
= &FdoExtension
->Bandwidth
[Offset
* Factor
];
109 for (ix
= 1; *Bandwidth
>= EndpointBandwidth
; ix
++)
111 MinBandwidth
= min(MinBandwidth
, *Bandwidth
);
117 if (MinBandwidth
> MaxBandwidth
)
119 MaxBandwidth
= MinBandwidth
;
120 ScheduleOffset
= Offset
;
122 DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n",
131 DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n", ScheduleOffset
);
133 if (ScheduleOffset
!= -1)
135 EndpointProperties
->ScheduleOffset
= ScheduleOffset
;
137 Bandwidth
= &FdoExtension
->Bandwidth
[ScheduleOffset
* Factor
];
139 for (Factor
= USB2_FRAMES
/ Period
; Factor
; Factor
--)
141 FdoExtension
->Bandwidth
[ScheduleOffset
* Factor
] -= EndpointBandwidth
;
144 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
146 for (Bit
= 0x80; Bit
!= 0; Bit
>>= 1)
148 if ((Period
& Bit
) != 0)
155 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedInterrupt_XXms\n");
159 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedIso\n");
163 DPRINT("USBPORT_AllocateBandwidth: FIXME USBPORT_UpdateAllocatedBw\n");
165 DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n", ScheduleOffset
);
166 return ScheduleOffset
!= -1;
171 USBPORT_FreeBandwidth(IN PDEVICE_OBJECT FdoDevice
,
172 IN PUSBPORT_ENDPOINT Endpoint
)
174 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
175 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
178 ULONG EndpointBandwidth
;
183 DPRINT("USBPORT_FreeBandwidth: FdoDevice - %p, Endpoint - %p\n",
187 FdoExtension
= FdoDevice
->DeviceExtension
;
189 EndpointProperties
= &Endpoint
->EndpointProperties
;
190 TransferType
= EndpointProperties
->TransferType
;
192 if (TransferType
== USBPORT_TRANSFER_TYPE_BULK
||
193 TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
194 (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
199 Offset
= Endpoint
->EndpointProperties
.ScheduleOffset
;
200 EndpointBandwidth
= Endpoint
->EndpointProperties
.UsbBandwidth
;
202 Period
= Endpoint
->EndpointProperties
.Period
;
205 for (Factor
= USB2_FRAMES
/ Period
; Factor
; Factor
--)
207 FdoExtension
->Bandwidth
[Offset
* Factor
] += EndpointBandwidth
;
210 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
212 for (Bit
= 0x80; Bit
!= 0; Bit
>>= 1)
214 if ((Period
& Bit
) != 0)
223 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedInterrupt_XXms\n");
227 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocatedIso\n");
230 DPRINT1("USBPORT_FreeBandwidth: FIXME USBPORT_UpdateAllocatedBw\n");
235 USBPORT_NormalizeHsInterval(UCHAR Interval
)
239 DPRINT("USBPORT_NormalizeHsInterval: Interval - %x\n", Interval
);
244 interval
= Interval
- 1;
249 return 1 << interval
;
254 USBPORT_EndpointHasQueuedTransfers(IN PDEVICE_OBJECT FdoDevice
,
255 IN PUSBPORT_ENDPOINT Endpoint
,
256 IN PULONG TransferCount
)
259 PUSBPORT_TRANSFER Transfer
;
260 BOOLEAN Result
= FALSE
;
262 DPRINT_CORE("USBPORT_EndpointHasQueuedTransfers: ... \n");
264 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
266 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
269 if (!IsListEmpty(&Endpoint
->TransferList
))
277 for (Entry
= Endpoint
->TransferList
.Flink
;
278 Entry
&& Entry
!= &Endpoint
->TransferList
;
279 Entry
= Transfer
->TransferLink
.Flink
)
281 Transfer
= CONTAINING_RECORD(Entry
,
285 if (Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
)
293 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
300 USBPORT_NukeAllEndpoints(IN PDEVICE_OBJECT FdoDevice
)
302 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
303 PLIST_ENTRY EndpointList
;
304 PUSBPORT_ENDPOINT Endpoint
;
307 DPRINT("USBPORT_NukeAllEndpoints \n");
309 FdoExtension
= FdoDevice
->DeviceExtension
;
311 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
313 EndpointList
= FdoExtension
->EndpointList
.Flink
;
315 while (EndpointList
&& (EndpointList
!= &FdoExtension
->EndpointList
))
317 Endpoint
= CONTAINING_RECORD(EndpointList
,
321 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
322 Endpoint
->Flags
|= ENDPOINT_FLAG_NUKE
;
324 EndpointList
= Endpoint
->EndpointLink
.Flink
;
327 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
332 USBPORT_GetEndpointState(IN PUSBPORT_ENDPOINT Endpoint
)
336 //DPRINT("USBPORT_GetEndpointState \n");
338 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
340 if (Endpoint
->StateLast
!= Endpoint
->StateNext
)
342 State
= USBPORT_ENDPOINT_UNKNOWN
;
346 State
= Endpoint
->StateLast
;
349 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
351 if (State
!= USBPORT_ENDPOINT_ACTIVE
)
353 DPRINT("USBPORT_GetEndpointState: Endpoint - %p, State - %x\n",
363 USBPORT_SetEndpointState(IN PUSBPORT_ENDPOINT Endpoint
,
366 PDEVICE_OBJECT FdoDevice
;
367 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
368 PUSBPORT_REGISTRATION_PACKET Packet
;
371 DPRINT("USBPORT_SetEndpointState: Endpoint - %p, State - %x\n",
375 FdoDevice
= Endpoint
->FdoDevice
;
376 FdoExtension
= FdoDevice
->DeviceExtension
;
377 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
379 KeAcquireSpinLock(&Endpoint
->StateChangeSpinLock
,
380 &Endpoint
->EndpointStateOldIrql
);
382 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
384 if (Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
)
386 Endpoint
->StateLast
= State
;
387 Endpoint
->StateNext
= State
;
389 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
390 Endpoint
->EndpointStateOldIrql
);
392 USBPORT_InvalidateEndpointHandler(FdoDevice
,
394 INVALIDATE_ENDPOINT_WORKER_THREAD
);
398 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
399 Endpoint
->EndpointStateOldIrql
);
401 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
402 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
405 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
407 Endpoint
->StateNext
= State
;
409 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
410 Endpoint
->FrameNumber
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
411 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
413 ExInterlockedInsertTailList(&FdoExtension
->EpStateChangeList
,
414 &Endpoint
->StateChangeLink
,
415 &FdoExtension
->EpStateChangeSpinLock
);
417 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
418 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
419 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
423 Endpoint
->StateLast
= State
;
424 Endpoint
->StateNext
= State
;
426 if (State
== USBPORT_ENDPOINT_REMOVE
)
428 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
429 Endpoint
->EndpointStateOldIrql
);
431 USBPORT_InvalidateEndpointHandler(FdoDevice
,
433 INVALIDATE_ENDPOINT_WORKER_THREAD
);
437 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
438 Endpoint
->EndpointStateOldIrql
);
444 USBPORT_AddPipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
445 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
447 DPRINT("USBPORT_AddPipeHandle: DeviceHandle - %p, PipeHandle - %p\n",
451 InsertTailList(&DeviceHandle
->PipeHandleList
, &PipeHandle
->PipeLink
);
456 USBPORT_RemovePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
457 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
459 DPRINT("USBPORT_RemovePipeHandle: PipeHandle - %p\n", PipeHandle
);
461 RemoveEntryList(&PipeHandle
->PipeLink
);
463 PipeHandle
->PipeLink
.Flink
= NULL
;
464 PipeHandle
->PipeLink
.Blink
= NULL
;
469 USBPORT_ValidatePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
470 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
472 PLIST_ENTRY HandleList
;
473 PUSBPORT_PIPE_HANDLE CurrentHandle
;
475 //DPRINT("USBPORT_ValidatePipeHandle: DeviceHandle - %p, PipeHandle - %p\n",
479 HandleList
= DeviceHandle
->PipeHandleList
.Flink
;
481 while (HandleList
!= &DeviceHandle
->PipeHandleList
)
483 CurrentHandle
= CONTAINING_RECORD(HandleList
,
487 HandleList
= HandleList
->Flink
;
489 if (CurrentHandle
== PipeHandle
)
498 USBPORT_DeleteEndpoint(IN PDEVICE_OBJECT FdoDevice
,
499 IN PUSBPORT_ENDPOINT Endpoint
)
501 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
505 DPRINT1("USBPORT_DeleteEndpoint: Endpoint - %p\n", Endpoint
);
507 FdoExtension
= FdoDevice
->DeviceExtension
;
509 if ((Endpoint
->WorkerLink
.Flink
&& Endpoint
->WorkerLink
.Blink
) ||
510 Endpoint
->LockCounter
!= -1)
512 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
514 ExInterlockedInsertTailList(&FdoExtension
->EndpointClosedList
,
515 &Endpoint
->CloseLink
,
516 &FdoExtension
->EndpointClosedSpinLock
);
518 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
524 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
526 RemoveEntryList(&Endpoint
->EndpointLink
);
527 Endpoint
->EndpointLink
.Flink
= NULL
;
528 Endpoint
->EndpointLink
.Blink
= NULL
;
530 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
532 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
534 if (Endpoint
->HeaderBuffer
)
536 USBPORT_FreeCommonBuffer(FdoDevice
, Endpoint
->HeaderBuffer
);
539 ExFreePoolWithTag(Endpoint
, USB_PORT_TAG
);
549 MiniportCloseEndpoint(IN PDEVICE_OBJECT FdoDevice
,
550 IN PUSBPORT_ENDPOINT Endpoint
)
552 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
553 PUSBPORT_REGISTRATION_PACKET Packet
;
554 BOOLEAN IsDoDisablePeriodic
;
558 DPRINT("MiniportCloseEndpoint: Endpoint - %p\n", Endpoint
);
560 FdoExtension
= FdoDevice
->DeviceExtension
;
561 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
563 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
565 if (Endpoint
->Flags
& ENDPOINT_FLAG_OPENED
)
567 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
569 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
||
570 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
572 --FdoExtension
->PeriodicEndpoints
;
575 IsDoDisablePeriodic
= FdoExtension
->PeriodicEndpoints
== 0;
577 Packet
->CloseEndpoint(FdoExtension
->MiniPortExt
,
579 IsDoDisablePeriodic
);
581 Endpoint
->Flags
&= ~ENDPOINT_FLAG_OPENED
;
582 Endpoint
->Flags
|= ENDPOINT_FLAG_CLOSED
;
585 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
590 USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
591 IN PDEVICE_OBJECT FdoDevice
,
592 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
594 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
595 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
596 PUSBPORT_ENDPOINT Endpoint
;
597 PUSBPORT_REGISTRATION_PACKET Packet
;
598 PUSB2_TT_EXTENSION TtExtension
;
603 DPRINT1("USBPORT_ClosePipe \n");
605 FdoExtension
= FdoDevice
->DeviceExtension
;
607 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_CLOSED
)
610 USBPORT_RemovePipeHandle(DeviceHandle
, PipeHandle
);
612 PipeHandle
->Flags
|= PIPE_HANDLE_FLAG_CLOSED
;
614 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
)
616 PipeHandle
->Flags
&= ~PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
;
620 Endpoint
= PipeHandle
->Endpoint
;
622 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
624 if ((Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
) &&
625 (Endpoint
->EndpointProperties
.TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
))
627 PdoExtension
= FdoExtension
->RootHubPdo
->DeviceExtension
;
628 PdoExtension
->Endpoint
= NULL
;
631 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
637 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
638 &Endpoint
->EndpointOldIrql
);
640 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
643 if (!IsListEmpty(&Endpoint
->TransferList
))
646 if (!IsListEmpty(&Endpoint
->CancelList
))
649 if (!IsListEmpty(&Endpoint
->AbortList
))
652 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
653 if (Endpoint
->StateLast
!= Endpoint
->StateNext
)
655 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
657 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
658 Endpoint
->EndpointOldIrql
);
660 if (InterlockedIncrement(&Endpoint
->LockCounter
))
662 InterlockedDecrement(&Endpoint
->LockCounter
);
667 USBPORT_Wait(FdoDevice
, 1);
670 Endpoint
->DeviceHandle
= NULL
;
671 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
673 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
675 USBPORT_FreeBandwidthUSB2(FdoDevice
, Endpoint
);
677 KeAcquireSpinLock(&FdoExtension
->TtSpinLock
, &OldIrql
);
679 TtExtension
= Endpoint
->TtExtension
;
680 DPRINT1("USBPORT_ClosePipe: TtExtension - %p\n", TtExtension
);
684 RemoveEntryList(&Endpoint
->TtLink
);
686 Endpoint
->TtLink
.Flink
= NULL
;
687 Endpoint
->TtLink
.Blink
= NULL
;
689 if (TtExtension
->Flags
& USB2_TT_EXTENSION_FLAG_DELETED
)
691 if (IsListEmpty(&TtExtension
->EndpointList
))
693 USBPORT_UpdateAllocatedBwTt(TtExtension
);
695 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
697 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
700 DPRINT1("USBPORT_ClosePipe: ExFreePoolWithTag TtExtension - %p\n", TtExtension
);
701 ExFreePoolWithTag(TtExtension
, USB_PORT_TAG
);
706 KeReleaseSpinLock(&FdoExtension
->TtSpinLock
, OldIrql
);
710 USBPORT_FreeBandwidth(FdoDevice
, Endpoint
);
713 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
714 USBPORT_SetEndpointState(Endpoint
, USBPORT_ENDPOINT_REMOVE
);
715 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
717 USBPORT_SignalWorkerThread(FdoDevice
);
722 MiniportOpenEndpoint(IN PDEVICE_OBJECT FdoDevice
,
723 IN PUSBPORT_ENDPOINT Endpoint
)
725 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
726 PUSBPORT_REGISTRATION_PACKET Packet
;
731 DPRINT("MiniportOpenEndpoint: Endpoint - %p\n", Endpoint
);
733 FdoExtension
= FdoDevice
->DeviceExtension
;
734 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
736 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
738 Endpoint
->Flags
&= ~ENDPOINT_FLAG_CLOSED
;
740 MpStatus
= Packet
->OpenEndpoint(FdoExtension
->MiniPortExt
,
741 &Endpoint
->EndpointProperties
,
746 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
748 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
||
749 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
751 ++FdoExtension
->PeriodicEndpoints
;
754 Endpoint
->Flags
|= ENDPOINT_FLAG_OPENED
;
757 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
763 USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice
,
764 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
765 IN PUSBPORT_PIPE_HANDLE PipeHandle
,
766 IN OUT PUSBD_STATUS UsbdStatus
)
768 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
769 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
770 PUSBPORT_REGISTRATION_PACKET Packet
;
772 PUSBPORT_ENDPOINT Endpoint
;
773 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
774 PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
778 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
= {0};
779 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
781 USBD_STATUS USBDStatus
;
784 USHORT MaxPacketSize
;
785 USHORT AdditionalTransaction
;
786 BOOLEAN IsAllocatedBandwidth
;
788 DPRINT1("USBPORT_OpenPipe: DeviceHandle - %p, FdoDevice - %p, PipeHandle - %p\n",
793 FdoExtension
= FdoDevice
->DeviceExtension
;
794 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
796 EndpointSize
= sizeof(USBPORT_ENDPOINT
) + Packet
->MiniPortEndpointSize
;
798 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
800 EndpointSize
+= sizeof(USB2_TT_ENDPOINT
);
803 if (PipeHandle
->EndpointDescriptor
.wMaxPacketSize
== 0)
805 USBPORT_AddPipeHandle(DeviceHandle
, PipeHandle
);
807 PipeHandle
->Flags
= (PipeHandle
->Flags
& ~PIPE_HANDLE_FLAG_CLOSED
) |
808 PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
;
810 PipeHandle
->Endpoint
= (PUSBPORT_ENDPOINT
)-1;
812 return STATUS_SUCCESS
;
815 Endpoint
= ExAllocatePoolWithTag(NonPagedPool
, EndpointSize
, USB_PORT_TAG
);
819 DPRINT1("USBPORT_OpenPipe: Not allocated Endpoint!\n");
820 Status
= STATUS_INSUFFICIENT_RESOURCES
;
824 RtlZeroMemory(Endpoint
, EndpointSize
);
826 Endpoint
->FdoDevice
= FdoDevice
;
827 Endpoint
->DeviceHandle
= DeviceHandle
;
828 Endpoint
->LockCounter
= -1;
830 Endpoint
->TtExtension
= DeviceHandle
->TtExtension
;
832 if (DeviceHandle
->TtExtension
)
834 ExInterlockedInsertTailList(&DeviceHandle
->TtExtension
->EndpointList
,
836 &FdoExtension
->TtSpinLock
);
839 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
841 Endpoint
->TtEndpoint
= (PUSB2_TT_ENDPOINT
)((ULONG_PTR
)Endpoint
+
842 sizeof(USBPORT_ENDPOINT
) +
843 Packet
->MiniPortEndpointSize
);
847 Endpoint
->TtEndpoint
= NULL
;
850 KeInitializeSpinLock(&Endpoint
->EndpointSpinLock
);
851 KeInitializeSpinLock(&Endpoint
->StateChangeSpinLock
);
853 InitializeListHead(&Endpoint
->PendingTransferList
);
854 InitializeListHead(&Endpoint
->TransferList
);
855 InitializeListHead(&Endpoint
->CancelList
);
856 InitializeListHead(&Endpoint
->AbortList
);
858 EndpointProperties
= &Endpoint
->EndpointProperties
;
859 EndpointDescriptor
= &PipeHandle
->EndpointDescriptor
;
861 MaxPacketSize
= EndpointDescriptor
->wMaxPacketSize
& 0x7FF;
862 AdditionalTransaction
= (EndpointDescriptor
->wMaxPacketSize
>> 11) & 3;
864 EndpointProperties
->DeviceAddress
= DeviceHandle
->DeviceAddress
;
865 EndpointProperties
->DeviceSpeed
= DeviceHandle
->DeviceSpeed
;
866 EndpointProperties
->Period
= 0;
867 EndpointProperties
->EndpointAddress
= EndpointDescriptor
->bEndpointAddress
;
868 EndpointProperties
->TransactionPerMicroframe
= AdditionalTransaction
+ 1;
869 EndpointProperties
->MaxPacketSize
= MaxPacketSize
;
870 EndpointProperties
->TotalMaxPacketSize
= MaxPacketSize
*
871 (AdditionalTransaction
+ 1);
873 if (Endpoint
->TtExtension
)
875 EndpointProperties
->HubAddr
= Endpoint
->TtExtension
->DeviceAddress
;
879 EndpointProperties
->HubAddr
= -1;
882 EndpointProperties
->PortNumber
= DeviceHandle
->PortNumber
;
884 switch (EndpointDescriptor
->bmAttributes
& USB_ENDPOINT_TYPE_MASK
)
886 case USB_ENDPOINT_TYPE_CONTROL
:
887 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_CONTROL
;
889 if (EndpointProperties
->EndpointAddress
== 0)
891 EndpointProperties
->MaxTransferSize
= 0x1000; // OUT Ep0
895 EndpointProperties
->MaxTransferSize
= 0x10000;
900 case USB_ENDPOINT_TYPE_ISOCHRONOUS
:
901 DPRINT1("USBPORT_OpenPipe: USB_ENDPOINT_TYPE_ISOCHRONOUS UNIMPLEMENTED. FIXME. \n");
902 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_ISOCHRONOUS
;
903 EndpointProperties
->MaxTransferSize
= 0x1000000;
906 case USB_ENDPOINT_TYPE_BULK
:
907 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_BULK
;
908 EndpointProperties
->MaxTransferSize
= 0x10000;
911 case USB_ENDPOINT_TYPE_INTERRUPT
:
912 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_INTERRUPT
;
913 EndpointProperties
->MaxTransferSize
= 0x400;
917 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
919 if (EndpointProperties
->DeviceSpeed
== UsbHighSpeed
)
921 Interval
= USBPORT_NormalizeHsInterval(EndpointDescriptor
->bInterval
);
925 Interval
= EndpointDescriptor
->bInterval
;
928 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_32ms
;
930 if (Interval
&& (Interval
< USB2_FRAMES
))
932 if ((EndpointProperties
->DeviceSpeed
!= UsbLowSpeed
) ||
933 (Interval
>= ENDPOINT_INTERRUPT_8ms
))
935 if (!(Interval
& ENDPOINT_INTERRUPT_32ms
))
937 Period
= EndpointProperties
->Period
;
943 while (!(Period
& Interval
));
945 EndpointProperties
->Period
= Period
;
950 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_8ms
;
955 if (EndpointProperties
->TransferType
== USB_ENDPOINT_TYPE_ISOCHRONOUS
)
957 if (EndpointProperties
->DeviceSpeed
== UsbHighSpeed
)
959 EndpointProperties
->Period
=
960 USBPORT_NormalizeHsInterval(EndpointDescriptor
->bInterval
);
964 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_1ms
;
968 if ((DeviceHandle
->Flags
& DEVICE_HANDLE_FLAG_ROOTHUB
) != 0)
970 Endpoint
->Flags
|= ENDPOINT_FLAG_ROOTHUB_EP0
;
973 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
975 IsAllocatedBandwidth
= USBPORT_AllocateBandwidthUSB2(FdoDevice
, Endpoint
);
979 EndpointProperties
->UsbBandwidth
= USBPORT_CalculateUsbBandwidth(FdoDevice
,
982 IsAllocatedBandwidth
= USBPORT_AllocateBandwidth(FdoDevice
, Endpoint
);
985 if (!IsAllocatedBandwidth
)
987 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBD_STATUS_NO_BANDWIDTH
);
991 *UsbdStatus
= USBD_STATUS_NO_BANDWIDTH
;
997 Direction
= USB_ENDPOINT_DIRECTION_OUT(EndpointDescriptor
->bEndpointAddress
);
998 EndpointProperties
->Direction
= Direction
;
1000 if (DeviceHandle
->IsRootHub
)
1002 Endpoint
->EndpointWorker
= 0; // USBPORT_RootHubEndpointWorker;
1004 Endpoint
->Flags
|= ENDPOINT_FLAG_ROOTHUB_EP0
;
1006 Endpoint
->StateLast
= USBPORT_ENDPOINT_ACTIVE
;
1007 Endpoint
->StateNext
= USBPORT_ENDPOINT_ACTIVE
;
1009 PdoExtension
= FdoExtension
->RootHubPdo
->DeviceExtension
;
1011 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
1013 PdoExtension
->Endpoint
= Endpoint
;
1016 USBDStatus
= USBD_STATUS_SUCCESS
;
1020 Endpoint
->EndpointWorker
= 1; // USBPORT_DmaEndpointWorker;
1022 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1024 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
1025 &Endpoint
->EndpointProperties
,
1026 &EndpointRequirements
);
1028 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1030 if ((EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_BULK
) ||
1031 (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
))
1033 EndpointProperties
->MaxTransferSize
= EndpointRequirements
.MaxTransferSize
;
1036 if (EndpointRequirements
.HeaderBufferSize
)
1038 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
1039 EndpointRequirements
.HeaderBufferSize
);
1043 HeaderBuffer
= NULL
;
1046 if (HeaderBuffer
|| (EndpointRequirements
.HeaderBufferSize
== 0))
1048 Endpoint
->HeaderBuffer
= HeaderBuffer
;
1052 EndpointProperties
->BufferVA
= HeaderBuffer
->VirtualAddress
;
1053 EndpointProperties
->BufferPA
= HeaderBuffer
->PhysicalAddress
;
1054 EndpointProperties
->BufferLength
= HeaderBuffer
->BufferLength
; // BufferLength + LengthPadded;
1057 MpStatus
= MiniportOpenEndpoint(FdoDevice
, Endpoint
);
1059 Endpoint
->Flags
|= ENDPOINT_FLAG_DMA_TYPE
;
1060 Endpoint
->Flags
|= ENDPOINT_FLAG_QUEUENE_EMPTY
;
1066 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
1067 &Endpoint
->EndpointOldIrql
);
1069 Endpoint
->StateLast
= USBPORT_ENDPOINT_PAUSED
;
1070 Endpoint
->StateNext
= USBPORT_ENDPOINT_PAUSED
;
1072 USBPORT_SetEndpointState(Endpoint
, USBPORT_ENDPOINT_ACTIVE
);
1074 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1075 Endpoint
->EndpointOldIrql
);
1079 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
1080 &Endpoint
->EndpointOldIrql
);
1082 State
= USBPORT_GetEndpointState(Endpoint
);
1084 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1085 Endpoint
->EndpointOldIrql
);
1087 if (State
== USBPORT_ENDPOINT_ACTIVE
)
1092 USBPORT_Wait(FdoDevice
, 1); // 1 msec.
1098 MpStatus
= MP_STATUS_NO_RESOURCES
;
1099 Endpoint
->HeaderBuffer
= NULL
;
1104 USBDStatus
= USBD_STATUS_INSUFFICIENT_RESOURCES
;
1108 USBDStatus
= USBD_STATUS_SUCCESS
;
1114 *UsbdStatus
= USBDStatus
;
1117 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBDStatus
);
1119 if (NT_SUCCESS(Status
))
1121 USBPORT_AddPipeHandle(DeviceHandle
, PipeHandle
);
1123 ExInterlockedInsertTailList(&FdoExtension
->EndpointList
,
1124 &Endpoint
->EndpointLink
,
1125 &FdoExtension
->EndpointListSpinLock
);
1127 PipeHandle
->Endpoint
= Endpoint
;
1128 PipeHandle
->Flags
&= ~PIPE_HANDLE_FLAG_CLOSED
;
1137 if (IsAllocatedBandwidth
)
1139 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1141 USBPORT_FreeBandwidthUSB2(FdoDevice
, Endpoint
);
1145 USBPORT_FreeBandwidth(FdoDevice
, Endpoint
);
1149 if (Endpoint
->TtExtension
)
1151 KeAcquireSpinLock(&FdoExtension
->TtSpinLock
, &OldIrql
);
1152 RemoveEntryList(&Endpoint
->TtLink
);
1153 KeReleaseSpinLock(&FdoExtension
->TtSpinLock
, OldIrql
);
1156 ExFreePoolWithTag(Endpoint
, USB_PORT_TAG
);
1159 DPRINT1("USBPORT_OpenPipe: Status - %lx\n", Status
);
1165 USBPORT_ReopenPipe(IN PDEVICE_OBJECT FdoDevice
,
1166 IN PUSBPORT_ENDPOINT Endpoint
)
1168 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1169 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
1170 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
= {0};
1171 PUSBPORT_REGISTRATION_PACKET Packet
;
1172 KIRQL MiniportOldIrql
;
1175 DPRINT1("USBPORT_ReopenPipe ... \n");
1177 FdoExtension
= FdoDevice
->DeviceExtension
;
1178 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1182 if (!InterlockedIncrement(&Endpoint
->LockCounter
))
1185 InterlockedDecrement(&Endpoint
->LockCounter
);
1186 USBPORT_Wait(FdoDevice
, 1);
1189 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &MiniportOldIrql
);
1191 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1193 USBPORT_ENDPOINT_REMOVE
);
1195 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, MiniportOldIrql
);
1197 USBPORT_Wait(FdoDevice
, 2);
1199 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
1201 RtlZeroMemory(Endpoint
+ 1,
1202 Packet
->MiniPortEndpointSize
);
1204 if (Endpoint
->HeaderBuffer
)
1206 USBPORT_FreeCommonBuffer(FdoDevice
, Endpoint
->HeaderBuffer
);
1207 Endpoint
->HeaderBuffer
= NULL
;
1210 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &MiniportOldIrql
);
1212 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
1213 &Endpoint
->EndpointProperties
,
1214 &EndpointRequirements
);
1216 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, MiniportOldIrql
);
1218 if (EndpointRequirements
.HeaderBufferSize
)
1220 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
1221 EndpointRequirements
.HeaderBufferSize
);
1225 HeaderBuffer
= NULL
;
1228 if (HeaderBuffer
|| EndpointRequirements
.HeaderBufferSize
== 0)
1230 Endpoint
->HeaderBuffer
= HeaderBuffer
;
1231 Status
= STATUS_SUCCESS
;
1235 Endpoint
->HeaderBuffer
= 0;
1236 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1239 if (Endpoint
->HeaderBuffer
&& HeaderBuffer
)
1241 Endpoint
->EndpointProperties
.BufferVA
= HeaderBuffer
->VirtualAddress
;
1242 Endpoint
->EndpointProperties
.BufferPA
= HeaderBuffer
->PhysicalAddress
;
1243 Endpoint
->EndpointProperties
.BufferLength
= HeaderBuffer
->BufferLength
;
1246 if (NT_SUCCESS(Status
))
1248 MiniportOpenEndpoint(FdoDevice
, Endpoint
);
1250 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1251 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1253 if (Endpoint
->StateLast
== USBPORT_ENDPOINT_ACTIVE
)
1255 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1257 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1259 USBPORT_ENDPOINT_ACTIVE
);
1261 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1264 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1265 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1268 InterlockedDecrement(&Endpoint
->LockCounter
);
1275 USBPORT_FlushClosedEndpointList(IN PDEVICE_OBJECT FdoDevice
)
1277 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1279 PLIST_ENTRY ClosedList
;
1280 PUSBPORT_ENDPOINT Endpoint
;
1282 DPRINT("USBPORT_FlushClosedEndpointList: ... \n");
1284 FdoExtension
= FdoDevice
->DeviceExtension
;
1286 KeAcquireSpinLock(&FdoExtension
->EndpointClosedSpinLock
, &OldIrql
);
1287 ClosedList
= &FdoExtension
->EndpointClosedList
;
1289 while (!IsListEmpty(ClosedList
))
1291 Endpoint
= CONTAINING_RECORD(ClosedList
->Flink
,
1295 RemoveHeadList(ClosedList
);
1296 Endpoint
->CloseLink
.Flink
= NULL
;
1297 Endpoint
->CloseLink
.Blink
= NULL
;
1299 KeReleaseSpinLock(&FdoExtension
->EndpointClosedSpinLock
, OldIrql
);
1301 USBPORT_DeleteEndpoint(FdoDevice
, Endpoint
);
1303 KeAcquireSpinLock(&FdoExtension
->EndpointClosedSpinLock
, &OldIrql
);
1306 KeReleaseSpinLock(&FdoExtension
->EndpointClosedSpinLock
, OldIrql
);
1311 USBPORT_InvalidateEndpointHandler(IN PDEVICE_OBJECT FdoDevice
,
1312 IN PUSBPORT_ENDPOINT Endpoint
,
1315 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1316 PUSBPORT_REGISTRATION_PACKET Packet
;
1318 PLIST_ENTRY WorkerLink
;
1319 PUSBPORT_ENDPOINT endpoint
;
1321 BOOLEAN IsAddEntry
= FALSE
;
1323 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: Endpoint - %p, Type - %x\n",
1327 FdoExtension
= FdoDevice
->DeviceExtension
;
1328 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1332 WorkerLink
= &Endpoint
->WorkerLink
;
1333 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1334 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: KeAcquireSpinLock \n");
1336 if ((!WorkerLink
->Flink
|| !WorkerLink
->Blink
) &&
1337 !(Endpoint
->Flags
& ENDPOINT_FLAG_IDLE
) &&
1338 USBPORT_GetEndpointState(Endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1340 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1341 InsertTailList(&FdoExtension
->WorkerList
, WorkerLink
);
1345 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1347 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
1348 Type
= INVALIDATE_ENDPOINT_WORKER_THREAD
;
1352 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1354 Entry
= &FdoExtension
->EndpointList
;
1356 while (Entry
&& Entry
!= &FdoExtension
->EndpointList
)
1358 endpoint
= CONTAINING_RECORD(Entry
,
1362 if (!endpoint
->WorkerLink
.Flink
|| !endpoint
->WorkerLink
.Blink
)
1364 if (!(endpoint
->Flags
& ENDPOINT_FLAG_IDLE
) &&
1365 !(endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
) &&
1366 USBPORT_GetEndpointState(endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1368 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1369 InsertTailList(&FdoExtension
->WorkerList
, &endpoint
->WorkerLink
);
1374 Entry
= endpoint
->EndpointLink
.Flink
;
1377 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1380 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
)
1382 Type
= INVALIDATE_ENDPOINT_WORKER_THREAD
;
1384 else if (IsAddEntry
== FALSE
&& Type
== INVALIDATE_ENDPOINT_INT_NEXT_SOF
)
1386 Type
= INVALIDATE_ENDPOINT_ONLY
;
1391 case INVALIDATE_ENDPOINT_WORKER_THREAD
:
1392 USBPORT_SignalWorkerThread(FdoDevice
);
1395 case INVALIDATE_ENDPOINT_WORKER_DPC
:
1396 KeInsertQueueDpc(&FdoExtension
->WorkerRequestDpc
, NULL
, NULL
);
1399 case INVALIDATE_ENDPOINT_INT_NEXT_SOF
:
1400 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1401 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
1402 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1409 USBPORT_DmaEndpointPaused(IN PDEVICE_OBJECT FdoDevice
,
1410 IN PUSBPORT_ENDPOINT Endpoint
)
1412 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1413 PUSBPORT_REGISTRATION_PACKET Packet
;
1415 PUSBPORT_TRANSFER Transfer
;
1419 ULONG CompletedLen
= 0;
1422 DPRINT_CORE("USBPORT_DmaEndpointPaused \n");
1424 FdoExtension
= FdoDevice
->DeviceExtension
;
1425 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1427 Entry
= Endpoint
->TransferList
.Flink
;
1429 if (Entry
== &Endpoint
->TransferList
)
1430 return USBPORT_ENDPOINT_ACTIVE
;
1432 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
1434 Transfer
= CONTAINING_RECORD(Entry
,
1438 if (Transfer
->Flags
& (TRANSFER_FLAG_CANCELED
| TRANSFER_FLAG_ABORTED
))
1440 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
&&
1441 Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
&&
1442 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1444 Urb
= Transfer
->Urb
;
1446 Frame
= Urb
->UrbIsochronousTransfer
.StartFrame
+
1447 Urb
->UrbIsochronousTransfer
.NumberOfPackets
;
1449 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1450 CurrentFrame
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
1451 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1453 if (Frame
+ 1 > CurrentFrame
)
1455 return USBPORT_GetEndpointState(Endpoint
);
1459 if ((Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
) &&
1460 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1462 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1464 Packet
->AbortTransfer(FdoExtension
->MiniPortExt
,
1466 Transfer
->MiniportTransfer
,
1469 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1471 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1473 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_FlushIsoTransfer\n");
1474 ASSERT(FALSE
); //USBPORT_FlushIsoTransfer();
1478 Transfer
->CompletedTransferLen
= CompletedLen
;
1482 RemoveEntryList(&Transfer
->TransferLink
);
1483 Entry
= Transfer
->TransferLink
.Flink
;
1485 if (Transfer
->Flags
& TRANSFER_FLAG_SPLITED
)
1487 USBPORT_CancelSplitTransfer(Transfer
);
1491 InsertTailList(&Endpoint
->CancelList
, &Transfer
->TransferLink
);
1496 Entry
= Transfer
->TransferLink
.Flink
;
1500 return USBPORT_ENDPOINT_ACTIVE
;
1505 USBPORT_DmaEndpointActive(IN PDEVICE_OBJECT FdoDevice
,
1506 IN PUSBPORT_ENDPOINT Endpoint
)
1508 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1509 PUSBPORT_REGISTRATION_PACKET Packet
;
1511 PUSBPORT_TRANSFER Transfer
;
1512 LARGE_INTEGER TimeOut
;
1516 DPRINT_CORE("USBPORT_DmaEndpointActive \n");
1518 FdoExtension
= FdoDevice
->DeviceExtension
;
1520 Entry
= Endpoint
->TransferList
.Flink
;
1522 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
1524 Transfer
= CONTAINING_RECORD(Entry
,
1528 if (!(Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
) &&
1529 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1531 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1533 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1535 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1537 DPRINT1("USBPORT_DmaEndpointActive: FIXME call SubmitIsoTransfer\n");
1539 MpStatus
= Packet
->SubmitIsoTransfer(FdoExtension
->MiniPortExt
,
1541 &Transfer
->TransferParameters
,
1542 Transfer
->MiniportTransfer
,
1543 NULL
);//&Transfer->IsoTransferParameters);
1547 MpStatus
= Packet
->SubmitTransfer(FdoExtension
->MiniPortExt
,
1549 &Transfer
->TransferParameters
,
1550 Transfer
->MiniportTransfer
,
1554 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1558 if ((MpStatus
!= MP_STATUS_FAILURE
) && Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1560 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_ErrorCompleteIsoTransfer\n");
1561 ASSERT(FALSE
); //USBPORT_ErrorCompleteIsoTransfer();
1564 return USBPORT_ENDPOINT_ACTIVE
;
1567 Transfer
->Flags
|= TRANSFER_FLAG_SUBMITED
;
1568 KeQuerySystemTime(&Transfer
->Time
);
1570 TimeOut
.QuadPart
= 10000 * Transfer
->TimeOut
;
1571 Transfer
->Time
.QuadPart
+= TimeOut
.QuadPart
;
1574 if (Transfer
->Flags
& (TRANSFER_FLAG_CANCELED
| TRANSFER_FLAG_ABORTED
))
1576 return USBPORT_ENDPOINT_PAUSED
;
1579 Entry
= Transfer
->TransferLink
.Flink
;
1582 return USBPORT_ENDPOINT_ACTIVE
;
1587 USBPORT_DmaEndpointWorker(IN PUSBPORT_ENDPOINT Endpoint
)
1589 PDEVICE_OBJECT FdoDevice
;
1591 ULONG EndpointState
;
1592 BOOLEAN IsPaused
= FALSE
;
1594 DPRINT_CORE("USBPORT_DmaEndpointWorker ... \n");
1596 FdoDevice
= Endpoint
->FdoDevice
;
1598 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1600 PrevState
= USBPORT_GetEndpointState(Endpoint
);
1602 if (PrevState
== USBPORT_ENDPOINT_PAUSED
)
1604 EndpointState
= USBPORT_DmaEndpointPaused(FdoDevice
, Endpoint
);
1606 else if (PrevState
== USBPORT_ENDPOINT_ACTIVE
)
1608 EndpointState
= USBPORT_DmaEndpointActive(FdoDevice
, Endpoint
);
1612 #ifndef NDEBUG_USBPORT_CORE
1613 DPRINT1("USBPORT_DmaEndpointWorker: DbgBreakPoint. EndpointState - %x\n",
1617 EndpointState
= USBPORT_ENDPOINT_UNKNOWN
;
1620 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1622 USBPORT_FlushCancelList(Endpoint
);
1624 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1626 if (EndpointState
== PrevState
)
1628 if (EndpointState
== USBPORT_ENDPOINT_PAUSED
)
1635 USBPORT_SetEndpointState(Endpoint
, EndpointState
);
1638 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1642 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1644 INVALIDATE_ENDPOINT_WORKER_THREAD
);
1647 DPRINT_CORE("USBPORT_DmaEndpointWorker exit \n");
1652 USBPORT_EndpointWorker(IN PUSBPORT_ENDPOINT Endpoint
,
1653 IN BOOLEAN LockNotChecked
)
1655 PDEVICE_OBJECT FdoDevice
;
1656 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1657 PUSBPORT_REGISTRATION_PACKET Packet
;
1658 ULONG EndpointState
;
1660 DPRINT_CORE("USBPORT_EndpointWorker: Endpoint - %p, LockNotChecked - %x\n",
1664 FdoDevice
= Endpoint
->FdoDevice
;
1665 FdoExtension
= FdoDevice
->DeviceExtension
;
1666 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1668 if (LockNotChecked
== FALSE
)
1670 if (InterlockedIncrement(&Endpoint
->LockCounter
))
1672 InterlockedDecrement(&Endpoint
->LockCounter
);
1673 DPRINT_CORE("USBPORT_EndpointWorker: LockCounter > 0\n");
1678 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1680 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
1682 if (USBPORT_GetEndpointState(Endpoint
) == USBPORT_ENDPOINT_CLOSED
)
1684 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1685 InterlockedDecrement(&Endpoint
->LockCounter
);
1686 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_CLOSED. return FALSE\n");
1690 if ((Endpoint
->Flags
& (ENDPOINT_FLAG_ROOTHUB_EP0
| ENDPOINT_FLAG_NUKE
)) == 0)
1692 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1693 Packet
->PollEndpoint(FdoExtension
->MiniPortExt
, Endpoint
+ 1);
1694 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1697 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
1699 if (EndpointState
== USBPORT_ENDPOINT_REMOVE
)
1701 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1702 Endpoint
->StateLast
= USBPORT_ENDPOINT_CLOSED
;
1703 Endpoint
->StateNext
= USBPORT_ENDPOINT_CLOSED
;
1704 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1706 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1708 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1710 ExInterlockedInsertTailList(&FdoExtension
->EndpointClosedList
,
1711 &Endpoint
->CloseLink
,
1712 &FdoExtension
->EndpointClosedSpinLock
);
1714 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1716 InterlockedDecrement(&Endpoint
->LockCounter
);
1717 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_REMOVE. return FALSE\n");
1721 if (!IsListEmpty(&Endpoint
->PendingTransferList
) ||
1722 !IsListEmpty(&Endpoint
->TransferList
) ||
1723 !IsListEmpty(&Endpoint
->CancelList
))
1725 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1727 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
1729 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1730 if (EndpointState
== Endpoint
->StateNext
)
1732 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1734 if (Endpoint
->EndpointWorker
)
1736 USBPORT_DmaEndpointWorker(Endpoint
);
1740 USBPORT_RootHubEndpointWorker(Endpoint
);
1743 USBPORT_FlushAbortList(Endpoint
);
1745 InterlockedDecrement(&Endpoint
->LockCounter
);
1746 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");
1750 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1751 InterlockedDecrement(&Endpoint
->LockCounter
);
1753 DPRINT_CORE("USBPORT_EndpointWorker: return TRUE\n");
1757 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1759 USBPORT_FlushAbortList(Endpoint
);
1761 InterlockedDecrement(&Endpoint
->LockCounter
);
1762 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");