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
;
99 Period
= EndpointProperties
->Period
;
100 Factor
= USB2_FRAMES
/ Period
;
103 for (Offset
= 0; Offset
< Period
; Offset
++)
105 MinBandwidth
= TotalBusBandwidth
;
106 Bandwidth
= &FdoExtension
->Bandwidth
[Offset
* Factor
];
108 for (ix
= 1; *Bandwidth
>= EndpointBandwidth
; ix
++)
110 if (MinBandwidth
> *Bandwidth
)
112 MinBandwidth
= *Bandwidth
;
119 if (MinBandwidth
> MaxBandwidth
)
121 MaxBandwidth
= MinBandwidth
;
122 ScheduleOffset
= Offset
;
124 DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n",
133 DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n", ScheduleOffset
);
135 if (ScheduleOffset
!= -1)
137 EndpointProperties
->ScheduleOffset
= ScheduleOffset
;
139 Bandwidth
= &FdoExtension
->Bandwidth
[ScheduleOffset
* Factor
];
141 for (Factor
= USB2_FRAMES
/ Period
; Factor
; Factor
--)
143 FdoExtension
->Bandwidth
[ScheduleOffset
* Factor
] -= EndpointBandwidth
;
146 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
148 for (Bit
= 0x80; Bit
!= 0; Bit
>>= 1)
150 if ((Period
& Bit
) != 0)
157 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedInterrupt_XXms\n");
161 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedIso\n");
165 DPRINT("USBPORT_AllocateBandwidth: FIXME USBPORT_UpdateAllocatedBw\n");
167 DPRINT("USBPORT_AllocateBandwidth: ScheduleOffset - %X\n", ScheduleOffset
);
168 return ScheduleOffset
!= -1;
173 USBPORT_FreeBandwidth(IN PDEVICE_OBJECT FdoDevice
,
174 IN PUSBPORT_ENDPOINT Endpoint
)
176 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
177 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
180 ULONG EndpointBandwidth
;
185 DPRINT("USBPORT_FreeBandwidth: FdoDevice - %p, Endpoint - %p\n",
189 FdoExtension
= FdoDevice
->DeviceExtension
;
191 EndpointProperties
= &Endpoint
->EndpointProperties
;
192 TransferType
= EndpointProperties
->TransferType
;
194 if (TransferType
== USBPORT_TRANSFER_TYPE_BULK
||
195 TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
196 (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
201 Offset
= Endpoint
->EndpointProperties
.ScheduleOffset
;
202 EndpointBandwidth
= Endpoint
->EndpointProperties
.UsbBandwidth
;
203 Period
= Endpoint
->EndpointProperties
.Period
;
205 ASSERT(USB2_FRAMES
/ Period
);
207 for (Factor
= USB2_FRAMES
/ Period
; Factor
; Factor
--)
209 FdoExtension
->Bandwidth
[Offset
* Factor
] += EndpointBandwidth
;
212 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
214 for (Bit
= 0x80; Bit
!= 0; Bit
>>= 1)
216 if ((Period
& Bit
) != 0)
225 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedInterrupt_XXms\n");
229 DPRINT("USBPORT_AllocateBandwidth: FIXME AllocedIso\n");
232 DPRINT1("USBPORT_FreeBandwidth: FIXME USBPORT_UpdateAllocatedBw\n");
237 USBPORT_NormalizeHsInterval(UCHAR Interval
)
241 DPRINT("USBPORT_NormalizeHsInterval: Interval - %x\n", Interval
);
246 interval
= Interval
- 1;
251 return 1 << interval
;
256 USBPORT_EndpointHasQueuedTransfers(IN PDEVICE_OBJECT FdoDevice
,
257 IN PUSBPORT_ENDPOINT Endpoint
,
258 IN PULONG TransferCount
)
261 PUSBPORT_TRANSFER Transfer
;
262 BOOLEAN Result
= FALSE
;
264 DPRINT_CORE("USBPORT_EndpointHasQueuedTransfers: ... \n");
266 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
268 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
271 if (!IsListEmpty(&Endpoint
->TransferList
))
279 for (Entry
= Endpoint
->TransferList
.Flink
;
280 Entry
&& Entry
!= &Endpoint
->TransferList
;
281 Entry
= Transfer
->TransferLink
.Flink
)
283 Transfer
= CONTAINING_RECORD(Entry
,
287 if (Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
)
295 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
302 USBPORT_NukeAllEndpoints(IN PDEVICE_OBJECT FdoDevice
)
304 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
305 PLIST_ENTRY EndpointList
;
306 PUSBPORT_ENDPOINT Endpoint
;
309 DPRINT("USBPORT_NukeAllEndpoints \n");
311 FdoExtension
= FdoDevice
->DeviceExtension
;
313 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
315 EndpointList
= FdoExtension
->EndpointList
.Flink
;
317 while (EndpointList
&& (EndpointList
!= &FdoExtension
->EndpointList
))
319 Endpoint
= CONTAINING_RECORD(EndpointList
,
323 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
324 Endpoint
->Flags
|= ENDPOINT_FLAG_NUKE
;
326 EndpointList
= Endpoint
->EndpointLink
.Flink
;
329 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
334 USBPORT_GetEndpointState(IN PUSBPORT_ENDPOINT Endpoint
)
338 //DPRINT("USBPORT_GetEndpointState \n");
340 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
342 if (Endpoint
->StateLast
!= Endpoint
->StateNext
)
344 State
= USBPORT_ENDPOINT_UNKNOWN
;
348 State
= Endpoint
->StateLast
;
351 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
353 if (State
!= USBPORT_ENDPOINT_ACTIVE
)
355 DPRINT("USBPORT_GetEndpointState: Endpoint - %p, State - %x\n",
365 USBPORT_SetEndpointState(IN PUSBPORT_ENDPOINT Endpoint
,
368 PDEVICE_OBJECT FdoDevice
;
369 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
370 PUSBPORT_REGISTRATION_PACKET Packet
;
373 DPRINT("USBPORT_SetEndpointState: Endpoint - %p, State - %x\n",
377 FdoDevice
= Endpoint
->FdoDevice
;
378 FdoExtension
= FdoDevice
->DeviceExtension
;
379 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
381 KeAcquireSpinLock(&Endpoint
->StateChangeSpinLock
,
382 &Endpoint
->EndpointStateOldIrql
);
384 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
386 if (Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
)
388 Endpoint
->StateLast
= State
;
389 Endpoint
->StateNext
= State
;
391 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
392 Endpoint
->EndpointStateOldIrql
);
394 USBPORT_InvalidateEndpointHandler(FdoDevice
,
396 INVALIDATE_ENDPOINT_WORKER_THREAD
);
400 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
401 Endpoint
->EndpointStateOldIrql
);
403 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
404 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
407 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
409 Endpoint
->StateNext
= State
;
411 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
412 Endpoint
->FrameNumber
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
413 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
415 ExInterlockedInsertTailList(&FdoExtension
->EpStateChangeList
,
416 &Endpoint
->StateChangeLink
,
417 &FdoExtension
->EpStateChangeSpinLock
);
419 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
420 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
421 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
425 Endpoint
->StateLast
= State
;
426 Endpoint
->StateNext
= State
;
428 if (State
== USBPORT_ENDPOINT_REMOVE
)
430 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
431 Endpoint
->EndpointStateOldIrql
);
433 USBPORT_InvalidateEndpointHandler(FdoDevice
,
435 INVALIDATE_ENDPOINT_WORKER_THREAD
);
439 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
440 Endpoint
->EndpointStateOldIrql
);
446 USBPORT_AddPipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
447 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
449 DPRINT("USBPORT_AddPipeHandle: DeviceHandle - %p, PipeHandle - %p\n",
453 InsertTailList(&DeviceHandle
->PipeHandleList
, &PipeHandle
->PipeLink
);
458 USBPORT_RemovePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
459 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
461 DPRINT("USBPORT_RemovePipeHandle: PipeHandle - %p\n", PipeHandle
);
463 RemoveEntryList(&PipeHandle
->PipeLink
);
465 PipeHandle
->PipeLink
.Flink
= NULL
;
466 PipeHandle
->PipeLink
.Blink
= NULL
;
471 USBPORT_ValidatePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
472 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
474 PLIST_ENTRY HandleList
;
475 PUSBPORT_PIPE_HANDLE CurrentHandle
;
477 //DPRINT("USBPORT_ValidatePipeHandle: DeviceHandle - %p, PipeHandle - %p\n",
481 HandleList
= DeviceHandle
->PipeHandleList
.Flink
;
483 while (HandleList
!= &DeviceHandle
->PipeHandleList
)
485 CurrentHandle
= CONTAINING_RECORD(HandleList
,
489 HandleList
= HandleList
->Flink
;
491 if (CurrentHandle
== PipeHandle
)
500 USBPORT_DeleteEndpoint(IN PDEVICE_OBJECT FdoDevice
,
501 IN PUSBPORT_ENDPOINT Endpoint
)
503 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
507 DPRINT1("USBPORT_DeleteEndpoint: Endpoint - %p\n", Endpoint
);
509 FdoExtension
= FdoDevice
->DeviceExtension
;
511 if ((Endpoint
->WorkerLink
.Flink
&& Endpoint
->WorkerLink
.Blink
) ||
512 Endpoint
->LockCounter
!= -1)
514 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
516 ExInterlockedInsertTailList(&FdoExtension
->EndpointClosedList
,
517 &Endpoint
->CloseLink
,
518 &FdoExtension
->EndpointClosedSpinLock
);
520 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
526 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
528 RemoveEntryList(&Endpoint
->EndpointLink
);
529 Endpoint
->EndpointLink
.Flink
= NULL
;
530 Endpoint
->EndpointLink
.Blink
= NULL
;
532 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
534 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
536 if (Endpoint
->HeaderBuffer
)
538 USBPORT_FreeCommonBuffer(FdoDevice
, Endpoint
->HeaderBuffer
);
541 ExFreePoolWithTag(Endpoint
, USB_PORT_TAG
);
551 MiniportCloseEndpoint(IN PDEVICE_OBJECT FdoDevice
,
552 IN PUSBPORT_ENDPOINT Endpoint
)
554 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
555 PUSBPORT_REGISTRATION_PACKET Packet
;
556 BOOLEAN IsDoDisablePeriodic
;
560 DPRINT("MiniportCloseEndpoint: Endpoint - %p\n", Endpoint
);
562 FdoExtension
= FdoDevice
->DeviceExtension
;
563 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
565 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
567 if (Endpoint
->Flags
& ENDPOINT_FLAG_OPENED
)
569 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
571 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
||
572 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
574 --FdoExtension
->PeriodicEndpoints
;
577 IsDoDisablePeriodic
= FdoExtension
->PeriodicEndpoints
== 0;
579 Packet
->CloseEndpoint(FdoExtension
->MiniPortExt
,
581 IsDoDisablePeriodic
);
583 Endpoint
->Flags
&= ~ENDPOINT_FLAG_OPENED
;
584 Endpoint
->Flags
|= ENDPOINT_FLAG_CLOSED
;
587 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
592 USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
593 IN PDEVICE_OBJECT FdoDevice
,
594 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
596 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
597 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
598 PUSBPORT_ENDPOINT Endpoint
;
599 PUSBPORT_REGISTRATION_PACKET Packet
;
600 PUSB2_TT_EXTENSION TtExtension
;
605 DPRINT1("USBPORT_ClosePipe \n");
607 FdoExtension
= FdoDevice
->DeviceExtension
;
609 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_CLOSED
)
612 USBPORT_RemovePipeHandle(DeviceHandle
, PipeHandle
);
614 PipeHandle
->Flags
|= PIPE_HANDLE_FLAG_CLOSED
;
616 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
)
618 PipeHandle
->Flags
&= ~PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
;
622 Endpoint
= PipeHandle
->Endpoint
;
624 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
626 if ((Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
) &&
627 (Endpoint
->EndpointProperties
.TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
))
629 PdoExtension
= FdoExtension
->RootHubPdo
->DeviceExtension
;
630 PdoExtension
->Endpoint
= NULL
;
633 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
639 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
640 &Endpoint
->EndpointOldIrql
);
642 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
645 if (!IsListEmpty(&Endpoint
->TransferList
))
648 if (!IsListEmpty(&Endpoint
->CancelList
))
651 if (!IsListEmpty(&Endpoint
->AbortList
))
654 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
655 if (Endpoint
->StateLast
!= Endpoint
->StateNext
)
657 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
659 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
660 Endpoint
->EndpointOldIrql
);
662 if (InterlockedIncrement(&Endpoint
->LockCounter
))
664 InterlockedDecrement(&Endpoint
->LockCounter
);
669 USBPORT_Wait(FdoDevice
, 1);
672 Endpoint
->DeviceHandle
= NULL
;
673 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
675 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
677 USBPORT_FreeBandwidthUSB2(FdoDevice
, Endpoint
);
679 KeAcquireSpinLock(&FdoExtension
->TtSpinLock
, &OldIrql
);
681 TtExtension
= Endpoint
->TtExtension
;
682 DPRINT1("USBPORT_ClosePipe: TtExtension - %p\n", TtExtension
);
686 RemoveEntryList(&Endpoint
->TtLink
);
688 Endpoint
->TtLink
.Flink
= NULL
;
689 Endpoint
->TtLink
.Blink
= NULL
;
691 if (TtExtension
->Flags
& USB2_TT_EXTENSION_FLAG_DELETED
)
693 if (IsListEmpty(&TtExtension
->EndpointList
))
695 USBPORT_UpdateAllocatedBwTt(TtExtension
);
697 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
699 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
702 DPRINT1("USBPORT_ClosePipe: ExFreePoolWithTag TtExtension - %p\n", TtExtension
);
703 ExFreePoolWithTag(TtExtension
, USB_PORT_TAG
);
708 KeReleaseSpinLock(&FdoExtension
->TtSpinLock
, OldIrql
);
712 USBPORT_FreeBandwidth(FdoDevice
, Endpoint
);
715 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
716 USBPORT_SetEndpointState(Endpoint
, USBPORT_ENDPOINT_REMOVE
);
717 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
719 USBPORT_SignalWorkerThread(FdoDevice
);
724 MiniportOpenEndpoint(IN PDEVICE_OBJECT FdoDevice
,
725 IN PUSBPORT_ENDPOINT Endpoint
)
727 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
728 PUSBPORT_REGISTRATION_PACKET Packet
;
733 DPRINT("MiniportOpenEndpoint: Endpoint - %p\n", Endpoint
);
735 FdoExtension
= FdoDevice
->DeviceExtension
;
736 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
738 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
740 Endpoint
->Flags
&= ~ENDPOINT_FLAG_CLOSED
;
742 MpStatus
= Packet
->OpenEndpoint(FdoExtension
->MiniPortExt
,
743 &Endpoint
->EndpointProperties
,
748 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
750 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
||
751 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
753 ++FdoExtension
->PeriodicEndpoints
;
756 Endpoint
->Flags
|= ENDPOINT_FLAG_OPENED
;
759 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
765 USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice
,
766 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
767 IN PUSBPORT_PIPE_HANDLE PipeHandle
,
768 IN OUT PUSBD_STATUS UsbdStatus
)
770 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
771 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
772 PUSBPORT_REGISTRATION_PACKET Packet
;
774 PUSBPORT_ENDPOINT Endpoint
;
775 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
776 PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
780 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
= {0};
781 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
783 USBD_STATUS USBDStatus
;
786 USHORT MaxPacketSize
;
787 USHORT AdditionalTransaction
;
788 BOOLEAN IsAllocatedBandwidth
;
790 DPRINT1("USBPORT_OpenPipe: DeviceHandle - %p, FdoDevice - %p, PipeHandle - %p\n",
795 FdoExtension
= FdoDevice
->DeviceExtension
;
796 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
798 EndpointSize
= sizeof(USBPORT_ENDPOINT
) + Packet
->MiniPortEndpointSize
;
800 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
802 EndpointSize
+= sizeof(USB2_TT_ENDPOINT
);
805 if (PipeHandle
->EndpointDescriptor
.wMaxPacketSize
== 0)
807 USBPORT_AddPipeHandle(DeviceHandle
, PipeHandle
);
809 PipeHandle
->Flags
= (PipeHandle
->Flags
& ~PIPE_HANDLE_FLAG_CLOSED
) |
810 PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
;
812 PipeHandle
->Endpoint
= (PUSBPORT_ENDPOINT
)-1;
814 return STATUS_SUCCESS
;
817 Endpoint
= ExAllocatePoolWithTag(NonPagedPool
, EndpointSize
, USB_PORT_TAG
);
821 DPRINT1("USBPORT_OpenPipe: Not allocated Endpoint!\n");
822 Status
= STATUS_INSUFFICIENT_RESOURCES
;
826 RtlZeroMemory(Endpoint
, EndpointSize
);
828 Endpoint
->FdoDevice
= FdoDevice
;
829 Endpoint
->DeviceHandle
= DeviceHandle
;
830 Endpoint
->LockCounter
= -1;
832 Endpoint
->TtExtension
= DeviceHandle
->TtExtension
;
834 if (DeviceHandle
->TtExtension
)
836 ExInterlockedInsertTailList(&DeviceHandle
->TtExtension
->EndpointList
,
838 &FdoExtension
->TtSpinLock
);
841 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
843 Endpoint
->TtEndpoint
= (PUSB2_TT_ENDPOINT
)((ULONG_PTR
)Endpoint
+
844 sizeof(USBPORT_ENDPOINT
) +
845 Packet
->MiniPortEndpointSize
);
849 Endpoint
->TtEndpoint
= NULL
;
852 KeInitializeSpinLock(&Endpoint
->EndpointSpinLock
);
853 KeInitializeSpinLock(&Endpoint
->StateChangeSpinLock
);
855 InitializeListHead(&Endpoint
->PendingTransferList
);
856 InitializeListHead(&Endpoint
->TransferList
);
857 InitializeListHead(&Endpoint
->CancelList
);
858 InitializeListHead(&Endpoint
->AbortList
);
860 EndpointProperties
= &Endpoint
->EndpointProperties
;
861 EndpointDescriptor
= &PipeHandle
->EndpointDescriptor
;
863 MaxPacketSize
= EndpointDescriptor
->wMaxPacketSize
& 0x7FF;
864 AdditionalTransaction
= (EndpointDescriptor
->wMaxPacketSize
>> 11) & 3;
866 EndpointProperties
->DeviceAddress
= DeviceHandle
->DeviceAddress
;
867 EndpointProperties
->DeviceSpeed
= DeviceHandle
->DeviceSpeed
;
868 EndpointProperties
->Period
= 0;
869 EndpointProperties
->EndpointAddress
= EndpointDescriptor
->bEndpointAddress
;
870 EndpointProperties
->TransactionPerMicroframe
= AdditionalTransaction
+ 1;
871 EndpointProperties
->MaxPacketSize
= MaxPacketSize
;
872 EndpointProperties
->TotalMaxPacketSize
= MaxPacketSize
*
873 (AdditionalTransaction
+ 1);
875 if (Endpoint
->TtExtension
)
877 EndpointProperties
->HubAddr
= Endpoint
->TtExtension
->DeviceAddress
;
881 EndpointProperties
->HubAddr
= -1;
884 EndpointProperties
->PortNumber
= DeviceHandle
->PortNumber
;
886 switch (EndpointDescriptor
->bmAttributes
& USB_ENDPOINT_TYPE_MASK
)
888 case USB_ENDPOINT_TYPE_CONTROL
:
889 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_CONTROL
;
891 if (EndpointProperties
->EndpointAddress
== 0)
893 EndpointProperties
->MaxTransferSize
= 0x1000; // OUT Ep0
897 EndpointProperties
->MaxTransferSize
= 0x10000;
902 case USB_ENDPOINT_TYPE_ISOCHRONOUS
:
903 DPRINT1("USBPORT_OpenPipe: USB_ENDPOINT_TYPE_ISOCHRONOUS UNIMPLEMENTED. FIXME. \n");
904 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_ISOCHRONOUS
;
905 EndpointProperties
->MaxTransferSize
= 0x1000000;
908 case USB_ENDPOINT_TYPE_BULK
:
909 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_BULK
;
910 EndpointProperties
->MaxTransferSize
= 0x10000;
913 case USB_ENDPOINT_TYPE_INTERRUPT
:
914 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_INTERRUPT
;
915 EndpointProperties
->MaxTransferSize
= 0x400;
919 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
921 if (EndpointProperties
->DeviceSpeed
== UsbHighSpeed
)
923 Interval
= USBPORT_NormalizeHsInterval(EndpointDescriptor
->bInterval
);
927 Interval
= EndpointDescriptor
->bInterval
;
930 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_32ms
;
932 if (Interval
&& (Interval
< USB2_FRAMES
))
934 if ((EndpointProperties
->DeviceSpeed
!= UsbLowSpeed
) ||
935 (Interval
>= ENDPOINT_INTERRUPT_8ms
))
937 if (!(Interval
& ENDPOINT_INTERRUPT_32ms
))
939 Period
= EndpointProperties
->Period
;
945 while (!(Period
& Interval
));
947 EndpointProperties
->Period
= Period
;
952 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_8ms
;
957 if (EndpointProperties
->TransferType
== USB_ENDPOINT_TYPE_ISOCHRONOUS
)
959 if (EndpointProperties
->DeviceSpeed
== UsbHighSpeed
)
961 EndpointProperties
->Period
=
962 USBPORT_NormalizeHsInterval(EndpointDescriptor
->bInterval
);
966 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_1ms
;
970 if ((DeviceHandle
->Flags
& DEVICE_HANDLE_FLAG_ROOTHUB
) != 0)
972 Endpoint
->Flags
|= ENDPOINT_FLAG_ROOTHUB_EP0
;
975 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
977 IsAllocatedBandwidth
= USBPORT_AllocateBandwidthUSB2(FdoDevice
, Endpoint
);
981 EndpointProperties
->UsbBandwidth
= USBPORT_CalculateUsbBandwidth(FdoDevice
,
984 IsAllocatedBandwidth
= USBPORT_AllocateBandwidth(FdoDevice
, Endpoint
);
987 if (!IsAllocatedBandwidth
)
989 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBD_STATUS_NO_BANDWIDTH
);
993 *UsbdStatus
= USBD_STATUS_NO_BANDWIDTH
;
999 Direction
= USB_ENDPOINT_DIRECTION_OUT(EndpointDescriptor
->bEndpointAddress
);
1000 EndpointProperties
->Direction
= Direction
;
1002 if (DeviceHandle
->IsRootHub
)
1004 Endpoint
->EndpointWorker
= 0; // USBPORT_RootHubEndpointWorker;
1006 Endpoint
->Flags
|= ENDPOINT_FLAG_ROOTHUB_EP0
;
1008 Endpoint
->StateLast
= USBPORT_ENDPOINT_ACTIVE
;
1009 Endpoint
->StateNext
= USBPORT_ENDPOINT_ACTIVE
;
1011 PdoExtension
= FdoExtension
->RootHubPdo
->DeviceExtension
;
1013 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
1015 PdoExtension
->Endpoint
= Endpoint
;
1018 USBDStatus
= USBD_STATUS_SUCCESS
;
1022 Endpoint
->EndpointWorker
= 1; // USBPORT_DmaEndpointWorker;
1024 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1026 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
1027 &Endpoint
->EndpointProperties
,
1028 &EndpointRequirements
);
1030 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1032 if ((EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_BULK
) ||
1033 (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
))
1035 EndpointProperties
->MaxTransferSize
= EndpointRequirements
.MaxTransferSize
;
1038 if (EndpointRequirements
.HeaderBufferSize
)
1040 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
1041 EndpointRequirements
.HeaderBufferSize
);
1045 HeaderBuffer
= NULL
;
1048 if (HeaderBuffer
|| (EndpointRequirements
.HeaderBufferSize
== 0))
1050 Endpoint
->HeaderBuffer
= HeaderBuffer
;
1054 EndpointProperties
->BufferVA
= HeaderBuffer
->VirtualAddress
;
1055 EndpointProperties
->BufferPA
= HeaderBuffer
->PhysicalAddress
;
1056 EndpointProperties
->BufferLength
= HeaderBuffer
->BufferLength
; // BufferLength + LengthPadded;
1059 MpStatus
= MiniportOpenEndpoint(FdoDevice
, Endpoint
);
1061 Endpoint
->Flags
|= ENDPOINT_FLAG_DMA_TYPE
;
1062 Endpoint
->Flags
|= ENDPOINT_FLAG_QUEUENE_EMPTY
;
1068 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
1069 &Endpoint
->EndpointOldIrql
);
1071 Endpoint
->StateLast
= USBPORT_ENDPOINT_PAUSED
;
1072 Endpoint
->StateNext
= USBPORT_ENDPOINT_PAUSED
;
1074 USBPORT_SetEndpointState(Endpoint
, USBPORT_ENDPOINT_ACTIVE
);
1076 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1077 Endpoint
->EndpointOldIrql
);
1081 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
1082 &Endpoint
->EndpointOldIrql
);
1084 State
= USBPORT_GetEndpointState(Endpoint
);
1086 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1087 Endpoint
->EndpointOldIrql
);
1089 if (State
== USBPORT_ENDPOINT_ACTIVE
)
1094 USBPORT_Wait(FdoDevice
, 1); // 1 msec.
1100 MpStatus
= MP_STATUS_NO_RESOURCES
;
1101 Endpoint
->HeaderBuffer
= NULL
;
1106 USBDStatus
= USBD_STATUS_INSUFFICIENT_RESOURCES
;
1110 USBDStatus
= USBD_STATUS_SUCCESS
;
1116 *UsbdStatus
= USBDStatus
;
1119 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBDStatus
);
1121 if (NT_SUCCESS(Status
))
1123 USBPORT_AddPipeHandle(DeviceHandle
, PipeHandle
);
1125 ExInterlockedInsertTailList(&FdoExtension
->EndpointList
,
1126 &Endpoint
->EndpointLink
,
1127 &FdoExtension
->EndpointListSpinLock
);
1129 PipeHandle
->Endpoint
= Endpoint
;
1130 PipeHandle
->Flags
&= ~PIPE_HANDLE_FLAG_CLOSED
;
1139 if (IsAllocatedBandwidth
)
1141 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1143 USBPORT_FreeBandwidthUSB2(FdoDevice
, Endpoint
);
1147 USBPORT_FreeBandwidth(FdoDevice
, Endpoint
);
1151 if (Endpoint
->TtExtension
)
1153 KeAcquireSpinLock(&FdoExtension
->TtSpinLock
, &OldIrql
);
1154 RemoveEntryList(&Endpoint
->TtLink
);
1155 KeReleaseSpinLock(&FdoExtension
->TtSpinLock
, OldIrql
);
1158 ExFreePoolWithTag(Endpoint
, USB_PORT_TAG
);
1161 DPRINT1("USBPORT_OpenPipe: Status - %lx\n", Status
);
1167 USBPORT_ReopenPipe(IN PDEVICE_OBJECT FdoDevice
,
1168 IN PUSBPORT_ENDPOINT Endpoint
)
1170 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1171 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
1172 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
= {0};
1173 PUSBPORT_REGISTRATION_PACKET Packet
;
1174 KIRQL MiniportOldIrql
;
1177 DPRINT1("USBPORT_ReopenPipe ... \n");
1179 FdoExtension
= FdoDevice
->DeviceExtension
;
1180 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1184 if (!InterlockedIncrement(&Endpoint
->LockCounter
))
1187 InterlockedDecrement(&Endpoint
->LockCounter
);
1188 USBPORT_Wait(FdoDevice
, 1);
1191 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &MiniportOldIrql
);
1193 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1195 USBPORT_ENDPOINT_REMOVE
);
1197 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, MiniportOldIrql
);
1199 USBPORT_Wait(FdoDevice
, 2);
1201 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
1203 RtlZeroMemory(Endpoint
+ 1,
1204 Packet
->MiniPortEndpointSize
);
1206 if (Endpoint
->HeaderBuffer
)
1208 USBPORT_FreeCommonBuffer(FdoDevice
, Endpoint
->HeaderBuffer
);
1209 Endpoint
->HeaderBuffer
= NULL
;
1212 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &MiniportOldIrql
);
1214 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
1215 &Endpoint
->EndpointProperties
,
1216 &EndpointRequirements
);
1218 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, MiniportOldIrql
);
1220 if (EndpointRequirements
.HeaderBufferSize
)
1222 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
1223 EndpointRequirements
.HeaderBufferSize
);
1227 HeaderBuffer
= NULL
;
1230 if (HeaderBuffer
|| EndpointRequirements
.HeaderBufferSize
== 0)
1232 Endpoint
->HeaderBuffer
= HeaderBuffer
;
1233 Status
= STATUS_SUCCESS
;
1237 Endpoint
->HeaderBuffer
= 0;
1238 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1241 if (Endpoint
->HeaderBuffer
&& HeaderBuffer
)
1243 Endpoint
->EndpointProperties
.BufferVA
= HeaderBuffer
->VirtualAddress
;
1244 Endpoint
->EndpointProperties
.BufferPA
= HeaderBuffer
->PhysicalAddress
;
1245 Endpoint
->EndpointProperties
.BufferLength
= HeaderBuffer
->BufferLength
;
1248 if (NT_SUCCESS(Status
))
1250 MiniportOpenEndpoint(FdoDevice
, Endpoint
);
1252 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1253 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1255 if (Endpoint
->StateLast
== USBPORT_ENDPOINT_ACTIVE
)
1257 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1259 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1261 USBPORT_ENDPOINT_ACTIVE
);
1263 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1266 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1267 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1270 InterlockedDecrement(&Endpoint
->LockCounter
);
1277 USBPORT_FlushClosedEndpointList(IN PDEVICE_OBJECT FdoDevice
)
1279 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1281 PLIST_ENTRY ClosedList
;
1282 PUSBPORT_ENDPOINT Endpoint
;
1284 DPRINT("USBPORT_FlushClosedEndpointList: ... \n");
1286 FdoExtension
= FdoDevice
->DeviceExtension
;
1288 KeAcquireSpinLock(&FdoExtension
->EndpointClosedSpinLock
, &OldIrql
);
1289 ClosedList
= &FdoExtension
->EndpointClosedList
;
1291 while (!IsListEmpty(ClosedList
))
1293 Endpoint
= CONTAINING_RECORD(ClosedList
->Flink
,
1297 RemoveHeadList(ClosedList
);
1298 Endpoint
->CloseLink
.Flink
= NULL
;
1299 Endpoint
->CloseLink
.Blink
= NULL
;
1301 KeReleaseSpinLock(&FdoExtension
->EndpointClosedSpinLock
, OldIrql
);
1303 USBPORT_DeleteEndpoint(FdoDevice
, Endpoint
);
1305 KeAcquireSpinLock(&FdoExtension
->EndpointClosedSpinLock
, &OldIrql
);
1308 KeReleaseSpinLock(&FdoExtension
->EndpointClosedSpinLock
, OldIrql
);
1313 USBPORT_InvalidateEndpointHandler(IN PDEVICE_OBJECT FdoDevice
,
1314 IN PUSBPORT_ENDPOINT Endpoint
,
1317 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1318 PUSBPORT_REGISTRATION_PACKET Packet
;
1320 PLIST_ENTRY WorkerLink
;
1321 PUSBPORT_ENDPOINT endpoint
;
1323 BOOLEAN IsAddEntry
= FALSE
;
1325 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: Endpoint - %p, Type - %x\n",
1329 FdoExtension
= FdoDevice
->DeviceExtension
;
1330 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1334 WorkerLink
= &Endpoint
->WorkerLink
;
1335 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1336 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: KeAcquireSpinLock \n");
1338 if ((!WorkerLink
->Flink
|| !WorkerLink
->Blink
) &&
1339 !(Endpoint
->Flags
& ENDPOINT_FLAG_IDLE
) &&
1340 USBPORT_GetEndpointState(Endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1342 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1343 InsertTailList(&FdoExtension
->WorkerList
, WorkerLink
);
1347 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1349 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
1350 Type
= INVALIDATE_ENDPOINT_WORKER_THREAD
;
1354 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1356 Entry
= &FdoExtension
->EndpointList
;
1358 while (Entry
&& Entry
!= &FdoExtension
->EndpointList
)
1360 endpoint
= CONTAINING_RECORD(Entry
,
1364 if (!endpoint
->WorkerLink
.Flink
|| !endpoint
->WorkerLink
.Blink
)
1366 if (!(endpoint
->Flags
& ENDPOINT_FLAG_IDLE
) &&
1367 !(endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
) &&
1368 USBPORT_GetEndpointState(endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1370 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1371 InsertTailList(&FdoExtension
->WorkerList
, &endpoint
->WorkerLink
);
1376 Entry
= endpoint
->EndpointLink
.Flink
;
1379 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1382 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
)
1384 Type
= INVALIDATE_ENDPOINT_WORKER_THREAD
;
1386 else if (IsAddEntry
== FALSE
&& Type
== INVALIDATE_ENDPOINT_INT_NEXT_SOF
)
1388 Type
= INVALIDATE_ENDPOINT_ONLY
;
1393 case INVALIDATE_ENDPOINT_WORKER_THREAD
:
1394 USBPORT_SignalWorkerThread(FdoDevice
);
1397 case INVALIDATE_ENDPOINT_WORKER_DPC
:
1398 KeInsertQueueDpc(&FdoExtension
->WorkerRequestDpc
, NULL
, NULL
);
1401 case INVALIDATE_ENDPOINT_INT_NEXT_SOF
:
1402 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1403 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
1404 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1411 USBPORT_DmaEndpointPaused(IN PDEVICE_OBJECT FdoDevice
,
1412 IN PUSBPORT_ENDPOINT Endpoint
)
1414 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1415 PUSBPORT_REGISTRATION_PACKET Packet
;
1417 PUSBPORT_TRANSFER Transfer
;
1421 ULONG CompletedLen
= 0;
1424 DPRINT_CORE("USBPORT_DmaEndpointPaused \n");
1426 FdoExtension
= FdoDevice
->DeviceExtension
;
1427 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1429 Entry
= Endpoint
->TransferList
.Flink
;
1431 if (Entry
== &Endpoint
->TransferList
)
1432 return USBPORT_ENDPOINT_ACTIVE
;
1434 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
1436 Transfer
= CONTAINING_RECORD(Entry
,
1440 if (Transfer
->Flags
& (TRANSFER_FLAG_CANCELED
| TRANSFER_FLAG_ABORTED
))
1442 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
&&
1443 Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
&&
1444 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1446 Urb
= Transfer
->Urb
;
1448 Frame
= Urb
->UrbIsochronousTransfer
.StartFrame
+
1449 Urb
->UrbIsochronousTransfer
.NumberOfPackets
;
1451 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1452 CurrentFrame
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
1453 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1455 if (Frame
+ 1 > CurrentFrame
)
1457 return USBPORT_GetEndpointState(Endpoint
);
1461 if ((Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
) &&
1462 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1464 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1466 Packet
->AbortTransfer(FdoExtension
->MiniPortExt
,
1468 Transfer
->MiniportTransfer
,
1471 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1473 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1475 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_FlushIsoTransfer\n");
1476 ASSERT(FALSE
); //USBPORT_FlushIsoTransfer();
1480 Transfer
->CompletedTransferLen
= CompletedLen
;
1484 RemoveEntryList(&Transfer
->TransferLink
);
1485 Entry
= Transfer
->TransferLink
.Flink
;
1487 if (Transfer
->Flags
& TRANSFER_FLAG_SPLITED
)
1489 USBPORT_CancelSplitTransfer(Transfer
);
1493 InsertTailList(&Endpoint
->CancelList
, &Transfer
->TransferLink
);
1498 Entry
= Transfer
->TransferLink
.Flink
;
1502 return USBPORT_ENDPOINT_ACTIVE
;
1507 USBPORT_DmaEndpointActive(IN PDEVICE_OBJECT FdoDevice
,
1508 IN PUSBPORT_ENDPOINT Endpoint
)
1510 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1511 PUSBPORT_REGISTRATION_PACKET Packet
;
1513 PUSBPORT_TRANSFER Transfer
;
1514 LARGE_INTEGER TimeOut
;
1518 DPRINT_CORE("USBPORT_DmaEndpointActive \n");
1520 FdoExtension
= FdoDevice
->DeviceExtension
;
1522 Entry
= Endpoint
->TransferList
.Flink
;
1524 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
1526 Transfer
= CONTAINING_RECORD(Entry
,
1530 if (!(Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
) &&
1531 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1533 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1535 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1537 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1539 DPRINT1("USBPORT_DmaEndpointActive: FIXME call SubmitIsoTransfer\n");
1541 MpStatus
= Packet
->SubmitIsoTransfer(FdoExtension
->MiniPortExt
,
1543 &Transfer
->TransferParameters
,
1544 Transfer
->MiniportTransfer
,
1545 NULL
);//&Transfer->IsoTransferParameters);
1549 MpStatus
= Packet
->SubmitTransfer(FdoExtension
->MiniPortExt
,
1551 &Transfer
->TransferParameters
,
1552 Transfer
->MiniportTransfer
,
1556 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1560 if ((MpStatus
!= MP_STATUS_FAILURE
) && Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1562 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_ErrorCompleteIsoTransfer\n");
1563 ASSERT(FALSE
); //USBPORT_ErrorCompleteIsoTransfer();
1566 return USBPORT_ENDPOINT_ACTIVE
;
1569 Transfer
->Flags
|= TRANSFER_FLAG_SUBMITED
;
1570 KeQuerySystemTime(&Transfer
->Time
);
1572 TimeOut
.QuadPart
= 10000 * Transfer
->TimeOut
;
1573 Transfer
->Time
.QuadPart
+= TimeOut
.QuadPart
;
1576 if (Transfer
->Flags
& (TRANSFER_FLAG_CANCELED
| TRANSFER_FLAG_ABORTED
))
1578 return USBPORT_ENDPOINT_PAUSED
;
1581 Entry
= Transfer
->TransferLink
.Flink
;
1584 return USBPORT_ENDPOINT_ACTIVE
;
1589 USBPORT_DmaEndpointWorker(IN PUSBPORT_ENDPOINT Endpoint
)
1591 PDEVICE_OBJECT FdoDevice
;
1593 ULONG EndpointState
;
1594 BOOLEAN IsPaused
= FALSE
;
1596 DPRINT_CORE("USBPORT_DmaEndpointWorker ... \n");
1598 FdoDevice
= Endpoint
->FdoDevice
;
1600 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1602 PrevState
= USBPORT_GetEndpointState(Endpoint
);
1604 if (PrevState
== USBPORT_ENDPOINT_PAUSED
)
1606 EndpointState
= USBPORT_DmaEndpointPaused(FdoDevice
, Endpoint
);
1608 else if (PrevState
== USBPORT_ENDPOINT_ACTIVE
)
1610 EndpointState
= USBPORT_DmaEndpointActive(FdoDevice
, Endpoint
);
1614 #ifndef NDEBUG_USBPORT_CORE
1615 DPRINT1("USBPORT_DmaEndpointWorker: DbgBreakPoint. EndpointState - %x\n",
1619 EndpointState
= USBPORT_ENDPOINT_UNKNOWN
;
1622 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1624 USBPORT_FlushCancelList(Endpoint
);
1626 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1628 if (EndpointState
== PrevState
)
1630 if (EndpointState
== USBPORT_ENDPOINT_PAUSED
)
1637 USBPORT_SetEndpointState(Endpoint
, EndpointState
);
1640 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1644 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1646 INVALIDATE_ENDPOINT_WORKER_THREAD
);
1649 DPRINT_CORE("USBPORT_DmaEndpointWorker exit \n");
1654 USBPORT_EndpointWorker(IN PUSBPORT_ENDPOINT Endpoint
,
1655 IN BOOLEAN LockNotChecked
)
1657 PDEVICE_OBJECT FdoDevice
;
1658 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1659 PUSBPORT_REGISTRATION_PACKET Packet
;
1660 ULONG EndpointState
;
1662 DPRINT_CORE("USBPORT_EndpointWorker: Endpoint - %p, LockNotChecked - %x\n",
1666 FdoDevice
= Endpoint
->FdoDevice
;
1667 FdoExtension
= FdoDevice
->DeviceExtension
;
1668 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1670 if (LockNotChecked
== FALSE
)
1672 if (InterlockedIncrement(&Endpoint
->LockCounter
))
1674 InterlockedDecrement(&Endpoint
->LockCounter
);
1675 DPRINT_CORE("USBPORT_EndpointWorker: LockCounter > 0\n");
1680 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1682 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
1684 if (USBPORT_GetEndpointState(Endpoint
) == USBPORT_ENDPOINT_CLOSED
)
1686 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1687 InterlockedDecrement(&Endpoint
->LockCounter
);
1688 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_CLOSED. return FALSE\n");
1692 if ((Endpoint
->Flags
& (ENDPOINT_FLAG_ROOTHUB_EP0
| ENDPOINT_FLAG_NUKE
)) == 0)
1694 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1695 Packet
->PollEndpoint(FdoExtension
->MiniPortExt
, Endpoint
+ 1);
1696 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1699 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
1701 if (EndpointState
== USBPORT_ENDPOINT_REMOVE
)
1703 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1704 Endpoint
->StateLast
= USBPORT_ENDPOINT_CLOSED
;
1705 Endpoint
->StateNext
= USBPORT_ENDPOINT_CLOSED
;
1706 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1708 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1710 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1712 ExInterlockedInsertTailList(&FdoExtension
->EndpointClosedList
,
1713 &Endpoint
->CloseLink
,
1714 &FdoExtension
->EndpointClosedSpinLock
);
1716 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1718 InterlockedDecrement(&Endpoint
->LockCounter
);
1719 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_REMOVE. return FALSE\n");
1723 if (!IsListEmpty(&Endpoint
->PendingTransferList
) ||
1724 !IsListEmpty(&Endpoint
->TransferList
) ||
1725 !IsListEmpty(&Endpoint
->CancelList
))
1727 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1729 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
1731 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1732 if (EndpointState
== Endpoint
->StateNext
)
1734 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1736 if (Endpoint
->EndpointWorker
)
1738 USBPORT_DmaEndpointWorker(Endpoint
);
1742 USBPORT_RootHubEndpointWorker(Endpoint
);
1745 USBPORT_FlushAbortList(Endpoint
);
1747 InterlockedDecrement(&Endpoint
->LockCounter
);
1748 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");
1752 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1753 InterlockedDecrement(&Endpoint
->LockCounter
);
1755 DPRINT_CORE("USBPORT_EndpointWorker: return TRUE\n");
1759 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1761 USBPORT_FlushAbortList(Endpoint
);
1763 InterlockedDecrement(&Endpoint
->LockCounter
);
1764 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");