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
= 0; *Bandwidth
>= EndpointBandwidth
; ix
++)
110 if (MinBandwidth
> *Bandwidth
)
112 MinBandwidth
= *Bandwidth
;
117 if (Factor
<= (ix
+ 1))
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 DPRINT1("USBPORT_FreeBandwidth: UNIMPLEMENTED. FIXME. \n");
181 USBPORT_NormalizeHsInterval(UCHAR Interval
)
185 DPRINT("USBPORT_NormalizeHsInterval: Interval - %x\n", Interval
);
190 interval
= Interval
- 1;
195 return 1 << interval
;
200 USBPORT_EndpointHasQueuedTransfers(IN PDEVICE_OBJECT FdoDevice
,
201 IN PUSBPORT_ENDPOINT Endpoint
,
202 IN PULONG TransferCount
)
205 PUSBPORT_TRANSFER Transfer
;
206 BOOLEAN Result
= FALSE
;
208 DPRINT_CORE("USBPORT_EndpointHasQueuedTransfers: ... \n");
210 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
212 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
215 if (!IsListEmpty(&Endpoint
->TransferList
))
223 for (Entry
= Endpoint
->TransferList
.Flink
;
224 Entry
&& Entry
!= &Endpoint
->TransferList
;
225 Entry
= Transfer
->TransferLink
.Flink
)
227 Transfer
= CONTAINING_RECORD(Entry
,
231 if (Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
)
239 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
246 USBPORT_NukeAllEndpoints(IN PDEVICE_OBJECT FdoDevice
)
248 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
249 PLIST_ENTRY EndpointList
;
250 PUSBPORT_ENDPOINT Endpoint
;
253 DPRINT("USBPORT_NukeAllEndpoints \n");
255 FdoExtension
= FdoDevice
->DeviceExtension
;
257 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
259 EndpointList
= FdoExtension
->EndpointList
.Flink
;
261 while (EndpointList
&& (EndpointList
!= &FdoExtension
->EndpointList
))
263 Endpoint
= CONTAINING_RECORD(EndpointList
,
267 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
268 Endpoint
->Flags
|= ENDPOINT_FLAG_NUKE
;
270 EndpointList
= Endpoint
->EndpointLink
.Flink
;
273 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
278 USBPORT_GetEndpointState(IN PUSBPORT_ENDPOINT Endpoint
)
282 //DPRINT("USBPORT_GetEndpointState \n");
284 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
286 if (Endpoint
->StateLast
!= Endpoint
->StateNext
)
288 State
= USBPORT_ENDPOINT_UNKNOWN
;
292 State
= Endpoint
->StateLast
;
295 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
297 if (State
!= USBPORT_ENDPOINT_ACTIVE
)
299 DPRINT("USBPORT_GetEndpointState: Endpoint - %p, State - %x\n",
309 USBPORT_SetEndpointState(IN PUSBPORT_ENDPOINT Endpoint
,
312 PDEVICE_OBJECT FdoDevice
;
313 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
314 PUSBPORT_REGISTRATION_PACKET Packet
;
317 DPRINT("USBPORT_SetEndpointState: Endpoint - %p, State - %x\n",
321 FdoDevice
= Endpoint
->FdoDevice
;
322 FdoExtension
= FdoDevice
->DeviceExtension
;
323 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
325 KeAcquireSpinLock(&Endpoint
->StateChangeSpinLock
,
326 &Endpoint
->EndpointStateOldIrql
);
328 if (!(Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
330 if (Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
)
332 Endpoint
->StateLast
= State
;
333 Endpoint
->StateNext
= State
;
335 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
336 Endpoint
->EndpointStateOldIrql
);
338 USBPORT_InvalidateEndpointHandler(FdoDevice
,
340 INVALIDATE_ENDPOINT_WORKER_THREAD
);
344 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
345 Endpoint
->EndpointStateOldIrql
);
347 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
348 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
351 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
353 Endpoint
->StateNext
= State
;
355 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
356 Endpoint
->FrameNumber
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
357 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
359 ExInterlockedInsertTailList(&FdoExtension
->EpStateChangeList
,
360 &Endpoint
->StateChangeLink
,
361 &FdoExtension
->EpStateChangeSpinLock
);
363 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
364 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
365 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
369 Endpoint
->StateLast
= State
;
370 Endpoint
->StateNext
= State
;
372 if (State
== USBPORT_ENDPOINT_REMOVE
)
374 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
375 Endpoint
->EndpointStateOldIrql
);
377 USBPORT_InvalidateEndpointHandler(FdoDevice
,
379 INVALIDATE_ENDPOINT_WORKER_THREAD
);
383 KeReleaseSpinLock(&Endpoint
->StateChangeSpinLock
,
384 Endpoint
->EndpointStateOldIrql
);
390 USBPORT_AddPipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
391 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
393 DPRINT("USBPORT_AddPipeHandle: DeviceHandle - %p, PipeHandle - %p\n",
397 InsertTailList(&DeviceHandle
->PipeHandleList
, &PipeHandle
->PipeLink
);
402 USBPORT_RemovePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
403 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
405 DPRINT("USBPORT_RemovePipeHandle: PipeHandle - %p\n", PipeHandle
);
407 RemoveEntryList(&PipeHandle
->PipeLink
);
409 PipeHandle
->PipeLink
.Flink
= NULL
;
410 PipeHandle
->PipeLink
.Blink
= NULL
;
415 USBPORT_ValidatePipeHandle(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
416 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
418 PLIST_ENTRY HandleList
;
419 PUSBPORT_PIPE_HANDLE CurrentHandle
;
421 //DPRINT("USBPORT_ValidatePipeHandle: DeviceHandle - %p, PipeHandle - %p\n",
425 HandleList
= DeviceHandle
->PipeHandleList
.Flink
;
427 while (HandleList
!= &DeviceHandle
->PipeHandleList
)
429 CurrentHandle
= CONTAINING_RECORD(HandleList
,
433 HandleList
= HandleList
->Flink
;
435 if (CurrentHandle
== PipeHandle
)
444 USBPORT_DeleteEndpoint(IN PDEVICE_OBJECT FdoDevice
,
445 IN PUSBPORT_ENDPOINT Endpoint
)
447 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
451 DPRINT("USBPORT_DeleteEndpoint: Endpoint - %p\n", Endpoint
);
453 FdoExtension
= FdoDevice
->DeviceExtension
;
455 if ((Endpoint
->WorkerLink
.Flink
&& Endpoint
->WorkerLink
.Blink
) ||
456 Endpoint
->LockCounter
!= -1)
458 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
460 ExInterlockedInsertTailList(&FdoExtension
->EndpointClosedList
,
461 &Endpoint
->CloseLink
,
462 &FdoExtension
->EndpointClosedSpinLock
);
464 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
470 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
472 RemoveEntryList(&Endpoint
->EndpointLink
);
473 Endpoint
->EndpointLink
.Flink
= NULL
;
474 Endpoint
->EndpointLink
.Blink
= NULL
;
476 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
478 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
480 if (Endpoint
->HeaderBuffer
)
482 USBPORT_FreeCommonBuffer(FdoDevice
, Endpoint
->HeaderBuffer
);
485 ExFreePoolWithTag(Endpoint
, USB_PORT_TAG
);
495 MiniportCloseEndpoint(IN PDEVICE_OBJECT FdoDevice
,
496 IN PUSBPORT_ENDPOINT Endpoint
)
498 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
499 PUSBPORT_REGISTRATION_PACKET Packet
;
500 BOOLEAN IsDoDisablePeriodic
;
504 DPRINT("MiniportCloseEndpoint: Endpoint - %p\n", Endpoint
);
506 FdoExtension
= FdoDevice
->DeviceExtension
;
507 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
509 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
511 if (Endpoint
->Flags
& ENDPOINT_FLAG_OPENED
)
513 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
515 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
||
516 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
518 --FdoExtension
->PeriodicEndpoints
;
521 IsDoDisablePeriodic
= FdoExtension
->PeriodicEndpoints
== 0;
523 Packet
->CloseEndpoint(FdoExtension
->MiniPortExt
,
525 IsDoDisablePeriodic
);
527 Endpoint
->Flags
&= ~ENDPOINT_FLAG_OPENED
;
528 Endpoint
->Flags
|= ENDPOINT_FLAG_CLOSED
;
531 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
536 USBPORT_ClosePipe(IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
537 IN PDEVICE_OBJECT FdoDevice
,
538 IN PUSBPORT_PIPE_HANDLE PipeHandle
)
540 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
541 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
542 PUSBPORT_ENDPOINT Endpoint
;
543 PUSBPORT_REGISTRATION_PACKET Packet
;
544 PUSB2_TT_EXTENSION TtExtension
;
549 DPRINT("USBPORT_ClosePipe \n");
551 FdoExtension
= FdoDevice
->DeviceExtension
;
553 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_CLOSED
)
556 USBPORT_RemovePipeHandle(DeviceHandle
, PipeHandle
);
558 PipeHandle
->Flags
|= PIPE_HANDLE_FLAG_CLOSED
;
560 if (PipeHandle
->Flags
& PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
)
562 PipeHandle
->Flags
&= ~PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
;
566 Endpoint
= PipeHandle
->Endpoint
;
568 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
570 if ((Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
) &&
571 (Endpoint
->EndpointProperties
.TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
))
573 PdoExtension
= FdoExtension
->RootHubPdo
->DeviceExtension
;
574 PdoExtension
->Endpoint
= NULL
;
577 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
583 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
584 &Endpoint
->EndpointOldIrql
);
586 if (!IsListEmpty(&Endpoint
->PendingTransferList
))
589 if (!IsListEmpty(&Endpoint
->TransferList
))
592 if (!IsListEmpty(&Endpoint
->CancelList
))
595 if (!IsListEmpty(&Endpoint
->AbortList
))
598 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
599 if (Endpoint
->StateLast
!= Endpoint
->StateNext
)
601 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
603 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
604 Endpoint
->EndpointOldIrql
);
606 if (InterlockedIncrement(&Endpoint
->LockCounter
))
608 InterlockedDecrement(&Endpoint
->LockCounter
);
613 USBPORT_Wait(FdoDevice
, 1);
616 Endpoint
->DeviceHandle
= NULL
;
617 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
619 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
621 USBPORT_FreeBandwidthUSB2(FdoDevice
, Endpoint
);
623 KeAcquireSpinLock(&FdoExtension
->TtSpinLock
, &OldIrql
);
625 TtExtension
= Endpoint
->TtExtension
;
629 RemoveEntryList(&Endpoint
->TtLink
);
631 Endpoint
->TtLink
.Flink
= NULL
;
632 Endpoint
->TtLink
.Blink
= NULL
;
634 if (TtExtension
->Flags
& USB2_TT_EXTENSION_FLAG_DELETED
)
636 if (IsListEmpty(&TtExtension
->EndpointList
))
638 USBPORT_UpdateAllocatedBwTt(TtExtension
);
640 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
642 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
645 ExFreePool(TtExtension
);
650 KeReleaseSpinLock(&FdoExtension
->TtSpinLock
, OldIrql
);
654 USBPORT_FreeBandwidth(FdoDevice
, Endpoint
);
657 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
658 USBPORT_SetEndpointState(Endpoint
, USBPORT_ENDPOINT_REMOVE
);
659 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
661 USBPORT_SignalWorkerThread(FdoDevice
);
666 MiniportOpenEndpoint(IN PDEVICE_OBJECT FdoDevice
,
667 IN PUSBPORT_ENDPOINT Endpoint
)
669 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
670 PUSBPORT_REGISTRATION_PACKET Packet
;
675 DPRINT("MiniportOpenEndpoint: Endpoint - %p\n", Endpoint
);
677 FdoExtension
= FdoDevice
->DeviceExtension
;
678 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
680 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
682 Endpoint
->Flags
&= ~ENDPOINT_FLAG_CLOSED
;
684 MpStatus
= Packet
->OpenEndpoint(FdoExtension
->MiniPortExt
,
685 &Endpoint
->EndpointProperties
,
690 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
692 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
||
693 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
695 ++FdoExtension
->PeriodicEndpoints
;
698 Endpoint
->Flags
|= ENDPOINT_FLAG_OPENED
;
701 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
707 USBPORT_OpenPipe(IN PDEVICE_OBJECT FdoDevice
,
708 IN PUSBPORT_DEVICE_HANDLE DeviceHandle
,
709 IN PUSBPORT_PIPE_HANDLE PipeHandle
,
710 IN OUT PUSBD_STATUS UsbdStatus
)
712 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
713 PUSBPORT_RHDEVICE_EXTENSION PdoExtension
;
714 PUSBPORT_REGISTRATION_PACKET Packet
;
716 PUSBPORT_ENDPOINT Endpoint
;
717 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
718 PUSB_ENDPOINT_DESCRIPTOR EndpointDescriptor
;
722 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
= {0};
723 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
725 USBD_STATUS USBDStatus
;
728 USHORT MaxPacketSize
;
729 USHORT AdditionalTransaction
;
730 BOOLEAN IsAllocatedBandwidth
;
732 DPRINT("USBPORT_OpenPipe: DeviceHandle - %p, FdoDevice - %p, PipeHandle - %p\n",
737 FdoExtension
= FdoDevice
->DeviceExtension
;
738 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
740 EndpointSize
= sizeof(USBPORT_ENDPOINT
) + Packet
->MiniPortEndpointSize
;
742 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
744 EndpointSize
+= sizeof(USB2_TT_ENDPOINT
);
747 if (PipeHandle
->EndpointDescriptor
.wMaxPacketSize
== 0)
749 USBPORT_AddPipeHandle(DeviceHandle
, PipeHandle
);
751 PipeHandle
->Flags
= (PipeHandle
->Flags
& ~PIPE_HANDLE_FLAG_CLOSED
) |
752 PIPE_HANDLE_FLAG_NULL_PACKET_SIZE
;
754 PipeHandle
->Endpoint
= (PUSBPORT_ENDPOINT
)-1;
756 return STATUS_SUCCESS
;
759 Endpoint
= ExAllocatePoolWithTag(NonPagedPool
, EndpointSize
, USB_PORT_TAG
);
763 DPRINT1("USBPORT_OpenPipe: Not allocated Endpoint!\n");
764 Status
= STATUS_INSUFFICIENT_RESOURCES
;
768 RtlZeroMemory(Endpoint
, EndpointSize
);
770 Endpoint
->FdoDevice
= FdoDevice
;
771 Endpoint
->DeviceHandle
= DeviceHandle
;
772 Endpoint
->LockCounter
= -1;
774 Endpoint
->TtExtension
= DeviceHandle
->TtExtension
;
776 if (DeviceHandle
->TtExtension
)
778 ExInterlockedInsertTailList(&DeviceHandle
->TtExtension
->EndpointList
,
780 &FdoExtension
->TtSpinLock
);
783 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
785 Endpoint
->TtEndpoint
= (PUSB2_TT_ENDPOINT
)((ULONG_PTR
)Endpoint
+
786 sizeof(USBPORT_ENDPOINT
) +
787 Packet
->MiniPortEndpointSize
);
791 Endpoint
->TtEndpoint
= NULL
;
794 KeInitializeSpinLock(&Endpoint
->EndpointSpinLock
);
795 KeInitializeSpinLock(&Endpoint
->StateChangeSpinLock
);
797 InitializeListHead(&Endpoint
->PendingTransferList
);
798 InitializeListHead(&Endpoint
->TransferList
);
799 InitializeListHead(&Endpoint
->CancelList
);
800 InitializeListHead(&Endpoint
->AbortList
);
802 EndpointProperties
= &Endpoint
->EndpointProperties
;
803 EndpointDescriptor
= &PipeHandle
->EndpointDescriptor
;
805 MaxPacketSize
= EndpointDescriptor
->wMaxPacketSize
& 0x7FF;
806 AdditionalTransaction
= (EndpointDescriptor
->wMaxPacketSize
>> 11) & 3;
808 EndpointProperties
->DeviceAddress
= DeviceHandle
->DeviceAddress
;
809 EndpointProperties
->DeviceSpeed
= DeviceHandle
->DeviceSpeed
;
810 EndpointProperties
->Period
= 0;
811 EndpointProperties
->EndpointAddress
= EndpointDescriptor
->bEndpointAddress
;
812 EndpointProperties
->TransactionPerMicroframe
= AdditionalTransaction
+ 1;
813 EndpointProperties
->MaxPacketSize
= MaxPacketSize
;
814 EndpointProperties
->TotalMaxPacketSize
= MaxPacketSize
*
815 (AdditionalTransaction
+ 1);
817 if (Endpoint
->TtExtension
)
819 EndpointProperties
->HubAddr
= Endpoint
->TtExtension
->DeviceAddress
;
823 EndpointProperties
->HubAddr
= -1;
826 EndpointProperties
->PortNumber
= DeviceHandle
->PortNumber
;
828 switch (EndpointDescriptor
->bmAttributes
& USB_ENDPOINT_TYPE_MASK
)
830 case USB_ENDPOINT_TYPE_CONTROL
:
831 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_CONTROL
;
833 if (EndpointProperties
->EndpointAddress
== 0)
835 EndpointProperties
->MaxTransferSize
= 0x1000; // OUT Ep0
839 EndpointProperties
->MaxTransferSize
= 0x10000;
844 case USB_ENDPOINT_TYPE_ISOCHRONOUS
:
845 DPRINT1("USBPORT_OpenPipe: USB_ENDPOINT_TYPE_ISOCHRONOUS UNIMPLEMENTED. FIXME. \n");
846 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_ISOCHRONOUS
;
847 EndpointProperties
->MaxTransferSize
= 0x1000000;
850 case USB_ENDPOINT_TYPE_BULK
:
851 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_BULK
;
852 EndpointProperties
->MaxTransferSize
= 0x10000;
855 case USB_ENDPOINT_TYPE_INTERRUPT
:
856 EndpointProperties
->TransferType
= USBPORT_TRANSFER_TYPE_INTERRUPT
;
857 EndpointProperties
->MaxTransferSize
= 0x400;
861 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
863 if (EndpointProperties
->DeviceSpeed
== UsbHighSpeed
)
865 Interval
= USBPORT_NormalizeHsInterval(EndpointDescriptor
->bInterval
);
869 Interval
= EndpointDescriptor
->bInterval
;
872 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_32ms
;
874 if (Interval
&& (Interval
< USB2_FRAMES
))
876 if ((EndpointProperties
->DeviceSpeed
!= UsbLowSpeed
) ||
877 (Interval
>= ENDPOINT_INTERRUPT_8ms
))
879 if (!(Interval
& ENDPOINT_INTERRUPT_32ms
))
881 Period
= EndpointProperties
->Period
;
887 while (!(Period
& Interval
));
889 EndpointProperties
->Period
= Period
;
894 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_8ms
;
899 if (EndpointProperties
->TransferType
== USB_ENDPOINT_TYPE_ISOCHRONOUS
)
901 if (EndpointProperties
->DeviceSpeed
== UsbHighSpeed
)
903 EndpointProperties
->Period
=
904 USBPORT_NormalizeHsInterval(EndpointDescriptor
->bInterval
);
908 EndpointProperties
->Period
= ENDPOINT_INTERRUPT_1ms
;
912 if ((DeviceHandle
->Flags
& DEVICE_HANDLE_FLAG_ROOTHUB
) != 0)
914 Endpoint
->Flags
|= ENDPOINT_FLAG_ROOTHUB_EP0
;
917 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
919 IsAllocatedBandwidth
= USBPORT_AllocateBandwidthUSB2(FdoDevice
, Endpoint
);
923 EndpointProperties
->UsbBandwidth
= USBPORT_CalculateUsbBandwidth(FdoDevice
,
926 IsAllocatedBandwidth
= USBPORT_AllocateBandwidth(FdoDevice
, Endpoint
);
929 if (!IsAllocatedBandwidth
)
931 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBD_STATUS_NO_BANDWIDTH
);
935 *UsbdStatus
= USBD_STATUS_NO_BANDWIDTH
;
941 Direction
= USB_ENDPOINT_DIRECTION_OUT(EndpointDescriptor
->bEndpointAddress
);
942 EndpointProperties
->Direction
= Direction
;
944 if (DeviceHandle
->IsRootHub
)
946 Endpoint
->EndpointWorker
= 0; // USBPORT_RootHubEndpointWorker;
948 Endpoint
->Flags
|= ENDPOINT_FLAG_ROOTHUB_EP0
;
950 Endpoint
->StateLast
= USBPORT_ENDPOINT_ACTIVE
;
951 Endpoint
->StateNext
= USBPORT_ENDPOINT_ACTIVE
;
953 PdoExtension
= FdoExtension
->RootHubPdo
->DeviceExtension
;
955 if (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
957 PdoExtension
->Endpoint
= Endpoint
;
960 USBDStatus
= USBD_STATUS_SUCCESS
;
964 Endpoint
->EndpointWorker
= 1; // USBPORT_DmaEndpointWorker;
966 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
968 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
969 &Endpoint
->EndpointProperties
,
970 &EndpointRequirements
);
972 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
974 if ((EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_BULK
) ||
975 (EndpointProperties
->TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
))
977 EndpointProperties
->MaxTransferSize
= EndpointRequirements
.MaxTransferSize
;
980 if (EndpointRequirements
.HeaderBufferSize
)
982 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
983 EndpointRequirements
.HeaderBufferSize
);
990 if (HeaderBuffer
|| (EndpointRequirements
.HeaderBufferSize
== 0))
992 Endpoint
->HeaderBuffer
= HeaderBuffer
;
996 EndpointProperties
->BufferVA
= HeaderBuffer
->VirtualAddress
;
997 EndpointProperties
->BufferPA
= HeaderBuffer
->PhysicalAddress
;
998 EndpointProperties
->BufferLength
= HeaderBuffer
->BufferLength
; // BufferLength + LengthPadded;
1001 MpStatus
= MiniportOpenEndpoint(FdoDevice
, Endpoint
);
1003 Endpoint
->Flags
|= ENDPOINT_FLAG_DMA_TYPE
;
1004 Endpoint
->Flags
|= ENDPOINT_FLAG_QUEUENE_EMPTY
;
1010 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
1011 &Endpoint
->EndpointOldIrql
);
1013 Endpoint
->StateLast
= USBPORT_ENDPOINT_PAUSED
;
1014 Endpoint
->StateNext
= USBPORT_ENDPOINT_PAUSED
;
1016 USBPORT_SetEndpointState(Endpoint
, USBPORT_ENDPOINT_ACTIVE
);
1018 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1019 Endpoint
->EndpointOldIrql
);
1023 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
1024 &Endpoint
->EndpointOldIrql
);
1026 State
= USBPORT_GetEndpointState(Endpoint
);
1028 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
1029 Endpoint
->EndpointOldIrql
);
1031 if (State
== USBPORT_ENDPOINT_ACTIVE
)
1036 USBPORT_Wait(FdoDevice
, 1); // 1 msec.
1042 MpStatus
= MP_STATUS_NO_RESOURCES
;
1043 Endpoint
->HeaderBuffer
= NULL
;
1048 USBDStatus
= USBD_STATUS_INSUFFICIENT_RESOURCES
;
1052 USBDStatus
= USBD_STATUS_SUCCESS
;
1058 *UsbdStatus
= USBDStatus
;
1061 Status
= USBPORT_USBDStatusToNtStatus(NULL
, USBDStatus
);
1063 if (NT_SUCCESS(Status
))
1065 USBPORT_AddPipeHandle(DeviceHandle
, PipeHandle
);
1067 ExInterlockedInsertTailList(&FdoExtension
->EndpointList
,
1068 &Endpoint
->EndpointLink
,
1069 &FdoExtension
->EndpointListSpinLock
);
1071 PipeHandle
->Endpoint
= Endpoint
;
1072 PipeHandle
->Flags
&= ~PIPE_HANDLE_FLAG_CLOSED
;
1081 if (IsAllocatedBandwidth
)
1083 if (Packet
->MiniPortFlags
& USB_MINIPORT_FLAGS_USB2
)
1085 USBPORT_FreeBandwidthUSB2(FdoDevice
, Endpoint
);
1089 USBPORT_FreeBandwidth(FdoDevice
, Endpoint
);
1093 if (Endpoint
->TtExtension
)
1095 KeAcquireSpinLock(&FdoExtension
->TtSpinLock
, &OldIrql
);
1096 RemoveEntryList(&Endpoint
->TtLink
);
1097 KeReleaseSpinLock(&FdoExtension
->TtSpinLock
, OldIrql
);
1100 ExFreePoolWithTag(Endpoint
, USB_PORT_TAG
);
1103 DPRINT1("USBPORT_OpenPipe: Status - %lx\n", Status
);
1109 USBPORT_ReopenPipe(IN PDEVICE_OBJECT FdoDevice
,
1110 IN PUSBPORT_ENDPOINT Endpoint
)
1112 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1113 PUSBPORT_COMMON_BUFFER_HEADER HeaderBuffer
;
1114 USBPORT_ENDPOINT_REQUIREMENTS EndpointRequirements
= {0};
1115 PUSBPORT_REGISTRATION_PACKET Packet
;
1116 KIRQL MiniportOldIrql
;
1119 DPRINT("USBPORT_ReopenPipe ... \n");
1121 FdoExtension
= FdoDevice
->DeviceExtension
;
1122 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1126 if (!InterlockedIncrement(&Endpoint
->LockCounter
))
1129 InterlockedDecrement(&Endpoint
->LockCounter
);
1130 USBPORT_Wait(FdoDevice
, 1);
1133 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &MiniportOldIrql
);
1135 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1137 USBPORT_ENDPOINT_REMOVE
);
1139 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, MiniportOldIrql
);
1141 USBPORT_Wait(FdoDevice
, 2);
1143 MiniportCloseEndpoint(FdoDevice
, Endpoint
);
1145 RtlZeroMemory(Endpoint
+ 1,
1146 Packet
->MiniPortEndpointSize
);
1148 if (Endpoint
->HeaderBuffer
)
1150 USBPORT_FreeCommonBuffer(FdoDevice
, Endpoint
->HeaderBuffer
);
1151 Endpoint
->HeaderBuffer
= NULL
;
1154 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &MiniportOldIrql
);
1156 Packet
->QueryEndpointRequirements(FdoExtension
->MiniPortExt
,
1157 &Endpoint
->EndpointProperties
,
1158 &EndpointRequirements
);
1160 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, MiniportOldIrql
);
1162 if (EndpointRequirements
.HeaderBufferSize
)
1164 HeaderBuffer
= USBPORT_AllocateCommonBuffer(FdoDevice
,
1165 EndpointRequirements
.HeaderBufferSize
);
1169 HeaderBuffer
= NULL
;
1172 if (HeaderBuffer
|| EndpointRequirements
.HeaderBufferSize
== 0)
1174 Endpoint
->HeaderBuffer
= HeaderBuffer
;
1175 Status
= STATUS_SUCCESS
;
1179 Endpoint
->HeaderBuffer
= 0;
1180 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1183 if (Endpoint
->HeaderBuffer
&& HeaderBuffer
)
1185 Endpoint
->EndpointProperties
.BufferVA
= HeaderBuffer
->VirtualAddress
;
1186 Endpoint
->EndpointProperties
.BufferPA
= HeaderBuffer
->PhysicalAddress
;
1187 Endpoint
->EndpointProperties
.BufferLength
= HeaderBuffer
->BufferLength
;
1190 if (NT_SUCCESS(Status
))
1192 MiniportOpenEndpoint(FdoDevice
, Endpoint
);
1194 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1195 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1197 if (Endpoint
->StateLast
== USBPORT_ENDPOINT_ACTIVE
)
1199 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1201 Packet
->SetEndpointState(FdoExtension
->MiniPortExt
,
1203 USBPORT_ENDPOINT_ACTIVE
);
1205 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1208 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1209 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1212 InterlockedDecrement(&Endpoint
->LockCounter
);
1219 USBPORT_FlushClosedEndpointList(IN PDEVICE_OBJECT FdoDevice
)
1221 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1223 PLIST_ENTRY ClosedList
;
1224 PUSBPORT_ENDPOINT Endpoint
;
1226 DPRINT("USBPORT_FlushClosedEndpointList: ... \n");
1228 FdoExtension
= FdoDevice
->DeviceExtension
;
1230 KeAcquireSpinLock(&FdoExtension
->EndpointClosedSpinLock
, &OldIrql
);
1231 ClosedList
= &FdoExtension
->EndpointClosedList
;
1233 while (!IsListEmpty(ClosedList
))
1235 Endpoint
= CONTAINING_RECORD(ClosedList
->Flink
,
1239 RemoveHeadList(ClosedList
);
1240 Endpoint
->CloseLink
.Flink
= NULL
;
1241 Endpoint
->CloseLink
.Blink
= NULL
;
1243 KeReleaseSpinLock(&FdoExtension
->EndpointClosedSpinLock
, OldIrql
);
1245 USBPORT_DeleteEndpoint(FdoDevice
, Endpoint
);
1247 KeAcquireSpinLock(&FdoExtension
->EndpointClosedSpinLock
, &OldIrql
);
1250 KeReleaseSpinLock(&FdoExtension
->EndpointClosedSpinLock
, OldIrql
);
1255 USBPORT_InvalidateEndpointHandler(IN PDEVICE_OBJECT FdoDevice
,
1256 IN PUSBPORT_ENDPOINT Endpoint
,
1259 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1260 PUSBPORT_REGISTRATION_PACKET Packet
;
1262 PLIST_ENTRY WorkerLink
;
1263 PUSBPORT_ENDPOINT endpoint
;
1265 BOOLEAN IsAddEntry
= FALSE
;
1267 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: Endpoint - %p, Type - %x\n",
1271 FdoExtension
= FdoDevice
->DeviceExtension
;
1272 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1276 WorkerLink
= &Endpoint
->WorkerLink
;
1277 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1278 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: KeAcquireSpinLock \n");
1280 if ((!WorkerLink
->Flink
|| !WorkerLink
->Blink
) &&
1281 !(Endpoint
->Flags
& ENDPOINT_FLAG_IDLE
) &&
1282 USBPORT_GetEndpointState(Endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1284 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1285 InsertTailList(&FdoExtension
->WorkerList
, WorkerLink
);
1289 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1291 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
1292 Type
= INVALIDATE_ENDPOINT_WORKER_THREAD
;
1296 KeAcquireSpinLock(&FdoExtension
->EndpointListSpinLock
, &OldIrql
);
1298 Entry
= &FdoExtension
->EndpointList
;
1300 while (Entry
&& Entry
!= &FdoExtension
->EndpointList
)
1302 endpoint
= CONTAINING_RECORD(Entry
,
1306 if (!endpoint
->WorkerLink
.Flink
|| !endpoint
->WorkerLink
.Blink
)
1308 if (!(endpoint
->Flags
& ENDPOINT_FLAG_IDLE
) &&
1309 !(endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
) &&
1310 USBPORT_GetEndpointState(endpoint
) != USBPORT_ENDPOINT_CLOSED
)
1312 DPRINT_CORE("USBPORT_InvalidateEndpointHandler: InsertTailList \n");
1313 InsertTailList(&FdoExtension
->WorkerList
, &endpoint
->WorkerLink
);
1318 Entry
= endpoint
->EndpointLink
.Flink
;
1321 KeReleaseSpinLock(&FdoExtension
->EndpointListSpinLock
, OldIrql
);
1324 if (FdoExtension
->Flags
& USBPORT_FLAG_HC_SUSPEND
)
1326 Type
= INVALIDATE_ENDPOINT_WORKER_THREAD
;
1328 else if (IsAddEntry
== FALSE
&& Type
== INVALIDATE_ENDPOINT_INT_NEXT_SOF
)
1330 Type
= INVALIDATE_ENDPOINT_ONLY
;
1335 case INVALIDATE_ENDPOINT_WORKER_THREAD
:
1336 USBPORT_SignalWorkerThread(FdoDevice
);
1339 case INVALIDATE_ENDPOINT_WORKER_DPC
:
1340 KeInsertQueueDpc(&FdoExtension
->WorkerRequestDpc
, NULL
, NULL
);
1343 case INVALIDATE_ENDPOINT_INT_NEXT_SOF
:
1344 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1345 Packet
->InterruptNextSOF(FdoExtension
->MiniPortExt
);
1346 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1353 USBPORT_DmaEndpointPaused(IN PDEVICE_OBJECT FdoDevice
,
1354 IN PUSBPORT_ENDPOINT Endpoint
)
1356 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1357 PUSBPORT_REGISTRATION_PACKET Packet
;
1359 PUSBPORT_TRANSFER Transfer
;
1363 ULONG CompletedLen
= 0;
1366 DPRINT_CORE("USBPORT_DmaEndpointPaused \n");
1368 FdoExtension
= FdoDevice
->DeviceExtension
;
1369 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1371 Entry
= Endpoint
->TransferList
.Flink
;
1373 if (Entry
== &Endpoint
->TransferList
)
1374 return USBPORT_ENDPOINT_ACTIVE
;
1376 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
1378 Transfer
= CONTAINING_RECORD(Entry
,
1382 if (Transfer
->Flags
& (TRANSFER_FLAG_CANCELED
| TRANSFER_FLAG_ABORTED
))
1384 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
&&
1385 Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
&&
1386 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1388 Urb
= Transfer
->Urb
;
1390 Frame
= Urb
->UrbIsochronousTransfer
.StartFrame
+
1391 Urb
->UrbIsochronousTransfer
.NumberOfPackets
;
1393 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1394 CurrentFrame
= Packet
->Get32BitFrameNumber(FdoExtension
->MiniPortExt
);
1395 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1397 if (Frame
+ 1 > CurrentFrame
)
1399 return USBPORT_GetEndpointState(Endpoint
);
1403 if ((Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
) &&
1404 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1406 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1408 Packet
->AbortTransfer(FdoExtension
->MiniPortExt
,
1410 Transfer
->MiniportTransfer
,
1413 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1415 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1417 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_FlushIsoTransfer\n");
1418 ASSERT(FALSE
); //USBPORT_FlushIsoTransfer();
1422 Transfer
->CompletedTransferLen
= CompletedLen
;
1426 RemoveEntryList(&Transfer
->TransferLink
);
1427 Entry
= Transfer
->TransferLink
.Flink
;
1429 if (Transfer
->Flags
& TRANSFER_FLAG_SPLITED
)
1431 USBPORT_CancelSplitTransfer(Transfer
);
1435 InsertTailList(&Endpoint
->CancelList
, &Transfer
->TransferLink
);
1440 Entry
= Transfer
->TransferLink
.Flink
;
1444 return USBPORT_ENDPOINT_ACTIVE
;
1449 USBPORT_DmaEndpointActive(IN PDEVICE_OBJECT FdoDevice
,
1450 IN PUSBPORT_ENDPOINT Endpoint
)
1452 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1453 PUSBPORT_REGISTRATION_PACKET Packet
;
1455 PUSBPORT_TRANSFER Transfer
;
1456 LARGE_INTEGER TimeOut
;
1460 DPRINT_CORE("USBPORT_DmaEndpointActive \n");
1462 FdoExtension
= FdoDevice
->DeviceExtension
;
1464 Entry
= Endpoint
->TransferList
.Flink
;
1466 while (Entry
&& Entry
!= &Endpoint
->TransferList
)
1468 Transfer
= CONTAINING_RECORD(Entry
,
1472 if (!(Transfer
->Flags
& TRANSFER_FLAG_SUBMITED
) &&
1473 !(Endpoint
->Flags
& ENDPOINT_FLAG_NUKE
))
1475 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
1477 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1479 if (Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1481 DPRINT1("USBPORT_DmaEndpointActive: FIXME call SubmitIsoTransfer\n");
1483 MpStatus
= Packet
->SubmitIsoTransfer(FdoExtension
->MiniPortExt
,
1485 &Transfer
->TransferParameters
,
1486 Transfer
->MiniportTransfer
,
1487 NULL
);//&Transfer->IsoTransferParameters);
1491 MpStatus
= Packet
->SubmitTransfer(FdoExtension
->MiniPortExt
,
1493 &Transfer
->TransferParameters
,
1494 Transfer
->MiniportTransfer
,
1498 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
1502 if ((MpStatus
!= MP_STATUS_FAILURE
) && Transfer
->Flags
& TRANSFER_FLAG_ISO
)
1504 DPRINT1("USBPORT_DmaEndpointActive: FIXME call USBPORT_ErrorCompleteIsoTransfer\n");
1505 ASSERT(FALSE
); //USBPORT_ErrorCompleteIsoTransfer();
1508 return USBPORT_ENDPOINT_ACTIVE
;
1511 Transfer
->Flags
|= TRANSFER_FLAG_SUBMITED
;
1512 KeQuerySystemTime(&Transfer
->Time
);
1514 TimeOut
.QuadPart
= 10000 * Transfer
->TimeOut
;
1515 Transfer
->Time
.QuadPart
+= TimeOut
.QuadPart
;
1518 if (Transfer
->Flags
& (TRANSFER_FLAG_CANCELED
| TRANSFER_FLAG_ABORTED
))
1520 return USBPORT_ENDPOINT_PAUSED
;
1523 Entry
= Transfer
->TransferLink
.Flink
;
1526 return USBPORT_ENDPOINT_ACTIVE
;
1531 USBPORT_DmaEndpointWorker(IN PUSBPORT_ENDPOINT Endpoint
)
1533 PDEVICE_OBJECT FdoDevice
;
1535 ULONG EndpointState
;
1536 BOOLEAN IsPaused
= FALSE
;
1538 DPRINT_CORE("USBPORT_DmaEndpointWorker ... \n");
1540 FdoDevice
= Endpoint
->FdoDevice
;
1542 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1544 PrevState
= USBPORT_GetEndpointState(Endpoint
);
1546 if (PrevState
== USBPORT_ENDPOINT_PAUSED
)
1548 EndpointState
= USBPORT_DmaEndpointPaused(FdoDevice
, Endpoint
);
1550 else if (PrevState
== USBPORT_ENDPOINT_ACTIVE
)
1552 EndpointState
= USBPORT_DmaEndpointActive(FdoDevice
, Endpoint
);
1556 #ifndef NDEBUG_USBPORT_CORE
1557 DPRINT1("USBPORT_DmaEndpointWorker: DbgBreakPoint. EndpointState - %x\n",
1561 EndpointState
= USBPORT_ENDPOINT_UNKNOWN
;
1564 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1566 USBPORT_FlushCancelList(Endpoint
);
1568 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
, &Endpoint
->EndpointOldIrql
);
1570 if (EndpointState
== PrevState
)
1572 if (EndpointState
== USBPORT_ENDPOINT_PAUSED
)
1579 USBPORT_SetEndpointState(Endpoint
, EndpointState
);
1582 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
, Endpoint
->EndpointOldIrql
);
1586 USBPORT_InvalidateEndpointHandler(FdoDevice
,
1588 INVALIDATE_ENDPOINT_WORKER_THREAD
);
1591 DPRINT_CORE("USBPORT_DmaEndpointWorker exit \n");
1596 USBPORT_EndpointWorker(IN PUSBPORT_ENDPOINT Endpoint
,
1597 IN BOOLEAN LockNotChecked
)
1599 PDEVICE_OBJECT FdoDevice
;
1600 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1601 PUSBPORT_REGISTRATION_PACKET Packet
;
1602 ULONG EndpointState
;
1604 DPRINT_CORE("USBPORT_EndpointWorker: Endpoint - %p, LockNotChecked - %x\n",
1608 FdoDevice
= Endpoint
->FdoDevice
;
1609 FdoExtension
= FdoDevice
->DeviceExtension
;
1610 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
1612 if (LockNotChecked
== FALSE
)
1614 if (InterlockedIncrement(&Endpoint
->LockCounter
))
1616 InterlockedDecrement(&Endpoint
->LockCounter
);
1617 DPRINT_CORE("USBPORT_EndpointWorker: LockCounter > 0\n");
1622 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1624 KeAcquireSpinLockAtDpcLevel(&Endpoint
->EndpointSpinLock
);
1626 if (USBPORT_GetEndpointState(Endpoint
) == USBPORT_ENDPOINT_CLOSED
)
1628 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1629 InterlockedDecrement(&Endpoint
->LockCounter
);
1630 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_CLOSED. return FALSE\n");
1634 if ((Endpoint
->Flags
& (ENDPOINT_FLAG_ROOTHUB_EP0
| ENDPOINT_FLAG_NUKE
)) == 0)
1636 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->MiniportSpinLock
);
1637 Packet
->PollEndpoint(FdoExtension
->MiniPortExt
, Endpoint
+ 1);
1638 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->MiniportSpinLock
);
1641 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
1643 if (EndpointState
== USBPORT_ENDPOINT_REMOVE
)
1645 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1646 Endpoint
->StateLast
= USBPORT_ENDPOINT_CLOSED
;
1647 Endpoint
->StateNext
= USBPORT_ENDPOINT_CLOSED
;
1648 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1650 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1652 KeAcquireSpinLockAtDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1654 ExInterlockedInsertTailList(&FdoExtension
->EndpointClosedList
,
1655 &Endpoint
->CloseLink
,
1656 &FdoExtension
->EndpointClosedSpinLock
);
1658 KeReleaseSpinLockFromDpcLevel(&FdoExtension
->EndpointListSpinLock
);
1660 InterlockedDecrement(&Endpoint
->LockCounter
);
1661 DPRINT_CORE("USBPORT_EndpointWorker: State == USBPORT_ENDPOINT_REMOVE. return FALSE\n");
1665 if (!IsListEmpty(&Endpoint
->PendingTransferList
) ||
1666 !IsListEmpty(&Endpoint
->TransferList
) ||
1667 !IsListEmpty(&Endpoint
->CancelList
))
1669 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1671 EndpointState
= USBPORT_GetEndpointState(Endpoint
);
1673 KeAcquireSpinLockAtDpcLevel(&Endpoint
->StateChangeSpinLock
);
1674 if (EndpointState
== Endpoint
->StateNext
)
1676 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1678 if (Endpoint
->EndpointWorker
)
1680 USBPORT_DmaEndpointWorker(Endpoint
);
1684 USBPORT_RootHubEndpointWorker(Endpoint
);
1687 USBPORT_FlushAbortList(Endpoint
);
1689 InterlockedDecrement(&Endpoint
->LockCounter
);
1690 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");
1694 KeReleaseSpinLockFromDpcLevel(&Endpoint
->StateChangeSpinLock
);
1695 InterlockedDecrement(&Endpoint
->LockCounter
);
1697 DPRINT_CORE("USBPORT_EndpointWorker: return TRUE\n");
1701 KeReleaseSpinLockFromDpcLevel(&Endpoint
->EndpointSpinLock
);
1703 USBPORT_FlushAbortList(Endpoint
);
1705 InterlockedDecrement(&Endpoint
->LockCounter
);
1706 DPRINT_CORE("USBPORT_EndpointWorker: return FALSE\n");