2 * PROJECT: ReactOS USB Port Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: USBPort USB 2.0 functions
5 * COPYRIGHT: Copyright 2017 Vadim Galyant <vgal@rambler.ru>
13 static const UCHAR CMASKS
[USB2_MICROFRAMES
] = {
14 0x1C, 0x38, 0x70, 0xE0, 0xC1, 0x83, 0x07, 0x0E
19 USB2_AllocateCheck(IN OUT PULONG OutTimeUsed
,
21 IN ULONG LimitAllocation
)
24 BOOLEAN Result
= TRUE
;
26 BusTime
= *OutTimeUsed
+ CalcBusTime
;
27 *OutTimeUsed
+= CalcBusTime
;
29 if (BusTime
> LimitAllocation
)
31 DPRINT("USB2_AllocateCheck: BusTime > LimitAllocation\n");
40 USB2_AddDataBitStuff(IN USHORT DataTime
)
42 return (DataTime
+ (DataTime
/ 16));
47 USB2_IncMicroFrame(OUT PUCHAR frame
,
52 if (*uframe
> (USB2_MICROFRAMES
- 1))
55 *frame
= (*frame
+ 1) & (USB2_FRAMES
- 1);
61 USB2_GetPrevMicroFrame(OUT PUCHAR frame
,
64 *uframe
= USB2_MICROFRAMES
- 1;
69 *frame
= USB2_FRAMES
- 1;
74 USB2_CheckTtEndpointInsert(IN PUSB2_TT_ENDPOINT nextTtEndpoint
,
75 IN PUSB2_TT_ENDPOINT TtEndpoint
)
79 DPRINT("USB2_CheckTtEndpointInsert: nextTtEndpoint - %p, TtEndpoint - %p\n",
85 if (TtEndpoint
->CalcBusTime
>= (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
87 DPRINT1("USB2_CheckTtEndpointInsert: Result - FALSE\n");
93 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
97 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
99 if (nextTtEndpoint
->ActualPeriod
< TtEndpoint
->ActualPeriod
&&
100 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
102 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
106 if ((nextTtEndpoint
->ActualPeriod
<= TtEndpoint
->ActualPeriod
&&
107 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
) ||
108 nextTtEndpoint
== TtEndpoint
)
110 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
114 DPRINT("USB2_CheckTtEndpointInsert: Result - FALSE\n");
120 USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint
)
128 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
129 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
130 DeviceSpeed
= TtEndpoint
->TtEndpointParams
.DeviceSpeed
;
132 HostDelay
= TtEndpoint
->Tt
->HcExtension
->HcDelayTime
;
134 if (DeviceSpeed
== UsbHighSpeed
)
136 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
138 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
139 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_OUT_OVERHEAD
;
141 Overhead
= HostDelay
+ USB2_HS_INTERRUPT_OUT_OVERHEAD
;
145 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
146 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_IN_OVERHEAD
;
148 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_OUT_OVERHEAD
;
151 else if (DeviceSpeed
== UsbFullSpeed
)
153 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
154 Overhead
= HostDelay
+ USB2_FS_ISOCHRONOUS_OVERHEAD
;
156 Overhead
= HostDelay
+ USB2_FS_INTERRUPT_OVERHEAD
;
160 Overhead
= HostDelay
+ USB2_LS_INTERRUPT_OVERHEAD
;
168 USB2_GetHsOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint
,
169 IN PULONG OverheadSS
,
170 IN PULONG OverheadCS
)
176 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
177 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
179 HostDelay
= TtEndpoint
->Tt
->HcExtension
->HcDelayTime
;
181 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
183 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
185 *OverheadSS
= HostDelay
+ USB2_HS_SS_ISOCHRONOUS_OUT_OVERHEAD
;
190 *OverheadSS
= HostDelay
+ USB2_HS_SS_INTERRUPT_OUT_OVERHEAD
;
191 *OverheadCS
= HostDelay
+ USB2_HS_CS_INTERRUPT_OUT_OVERHEAD
;
196 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
198 *OverheadSS
= HostDelay
+ USB2_HS_SS_ISOCHRONOUS_IN_OVERHEAD
;
199 *OverheadCS
= HostDelay
+ USB2_HS_CS_ISOCHRONOUS_IN_OVERHEAD
;
203 *OverheadSS
= HostDelay
+ USB2_HS_SS_INTERRUPT_IN_OVERHEAD
;
204 *OverheadCS
= HostDelay
+ USB2_HS_CS_INTERRUPT_IN_OVERHEAD
;
211 USB2_GetLastIsoTime(IN PUSB2_TT_ENDPOINT TtEndpoint
,
214 PUSB2_TT_ENDPOINT nextTtEndpoint
;
217 //DPRINT("USB2_GetLastIsoTime: TtEndpoint - %p, Frame - %X\n",
221 nextTtEndpoint
= TtEndpoint
->Tt
->FrameBudget
[Frame
].IsoEndpoint
->NextTtEndpoint
;
223 if (nextTtEndpoint
||
224 (nextTtEndpoint
= TtEndpoint
->Tt
->FrameBudget
[Frame
].AltEndpoint
) != NULL
)
226 Result
= nextTtEndpoint
->StartTime
+ nextTtEndpoint
->CalcBusTime
;
230 Result
= USB2_FS_SOF_TIME
;
238 USB2_GetStartTime(IN PUSB2_TT_ENDPOINT nextTtEndpoint
,
239 IN PUSB2_TT_ENDPOINT TtEndpoint
,
240 IN PUSB2_TT_ENDPOINT prevTtEndpoint
,
243 PUSB2_TT_ENDPOINT ttEndpoint
;
246 DPRINT("USB2_GetStartTime: nextTtEndpoint - %p, TtEndpoint - %p, prevTtEndpoint - %p, Frame - %X\n",
252 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
254 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
257 return nextTtEndpoint
->StartTime
+ nextTtEndpoint
->CalcBusTime
;
259 ttEndpoint
= TtEndpoint
->Tt
->FrameBudget
[Frame
].AltEndpoint
;
262 return ttEndpoint
->StartTime
+ ttEndpoint
->CalcBusTime
;
264 return USB2_FS_SOF_TIME
;
268 ttEndpoint
= prevTtEndpoint
;
270 if (ttEndpoint
== TtEndpoint
->Tt
->FrameBudget
[Frame
].IntEndpoint
)
271 return USB2_GetLastIsoTime(TtEndpoint
, Frame
);
273 return ttEndpoint
->StartTime
+ ttEndpoint
->CalcBusTime
;
279 USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
280 IN UCHAR TransferType
,
282 IN UCHAR DeviceSpeed
,
284 IN USHORT MaxPacketSize
,
287 TtEndpoint
->TtEndpointParams
.TransferType
= TransferType
;
288 TtEndpoint
->TtEndpointParams
.Direction
= Direction
;
289 TtEndpoint
->TtEndpointParams
.DeviceSpeed
= DeviceSpeed
;
291 TtEndpoint
->Period
= Period
;
292 TtEndpoint
->MaxPacketSize
= MaxPacketSize
;
295 TtEndpoint
->CalcBusTime
= 0;
296 TtEndpoint
->StartTime
= 0;
297 TtEndpoint
->ActualPeriod
= 0;
298 TtEndpoint
->StartFrame
= 0;
299 TtEndpoint
->StartMicroframe
= 0;
301 TtEndpoint
->Nums
.AsULONG
= 0;
302 TtEndpoint
->NextTtEndpoint
= NULL
;
303 TtEndpoint
->Reserved2
= 0;
304 TtEndpoint
->PreviosPeriod
= 0;
305 TtEndpoint
->IsPromoted
= FALSE
;
310 USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint
,
313 PUSB2_HC_EXTENSION HcExtension
;
319 ULONG RemainDataTime
;
324 USHORT PktSizeBitStuff
;
329 DPRINT("USB2_AllocateHS: TtEndpoint - %p, Frame - %X, StartFrame - %X\n",
332 TtEndpoint
->StartFrame
);
335 HcExtension
= Tt
->HcExtension
;
337 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
338 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
342 TtEndpoint
->StartMicroframe
=
343 TtEndpoint
->StartTime
/ USB2_FS_RAW_BYTES_IN_MICROFRAME
- 1;
345 DPRINT("USB2_AllocateHS: TtEndpoint->StartMicroframe - %X\n",
346 TtEndpoint
->StartMicroframe
);
349 USB2_GetHsOverhead(TtEndpoint
, &OverheadSS
, &OverheadCS
);
351 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
355 TtEndpoint
->Nums
.NumStarts
= 1;
357 if ((CHAR
)TtEndpoint
->StartMicroframe
< (USB2_MICROFRAMES
- 3))
358 TtEndpoint
->Nums
.NumCompletes
= 3;
360 TtEndpoint
->Nums
.NumCompletes
= 2;
365 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
367 DPRINT("USB2_AllocateHS: ISO UNIMPLEMENTED\n");
372 DPRINT("USB2_AllocateHS: ISO UNIMPLEMENTED\n");
377 frame
= TtEndpoint
->StartFrame
+ Frame
;
378 uframe
= TtEndpoint
->StartMicroframe
;
380 if (TtEndpoint
->StartMicroframe
== USB2_PREV_MICROFRAME
)
381 USB2_GetPrevMicroFrame(&frame
, &uframe
);
383 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumStarts
; ix
++)
385 if (!USB2_AllocateCheck(&HcExtension
->TimeUsed
[frame
][uframe
],
387 USB2_MAX_MICROFRAME_ALLOCATION
))
392 if (Tt
->NumStartSplits
[frame
][uframe
] >
393 (USB2_MAX_FS_LS_TRANSACTIONS_IN_UFRAME
- 1))
395 DPRINT1("USB2_AllocateHS: Num Start Splits - %X\n",
396 Tt
->NumStartSplits
[frame
][uframe
] + 1);
402 ++Tt
->NumStartSplits
[frame
][uframe
];
403 USB2_IncMicroFrame(&frame
, &uframe
);
406 frame
= TtEndpoint
->StartFrame
+ Frame
;
407 uframe
= TtEndpoint
->StartMicroframe
+ TtEndpoint
->Nums
.NumStarts
+ 1;
409 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumCompletes
; ix
++)
411 if (!USB2_AllocateCheck(&HcExtension
->TimeUsed
[frame
][uframe
],
413 USB2_MAX_MICROFRAME_ALLOCATION
))
418 USB2_IncMicroFrame(&frame
, &uframe
);
421 PktSize
= TtEndpoint
->MaxPacketSize
;
422 PktSizeBitStuff
= USB2_AddDataBitStuff(PktSize
);
424 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
426 frame
= TtEndpoint
->StartFrame
+ Frame
;
427 uframe
= TtEndpoint
->StartMicroframe
;
429 if (uframe
== USB2_PREV_MICROFRAME
)
430 USB2_GetPrevMicroFrame(&frame
, &uframe
);
434 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumStarts
; ix
++)
436 DataSize
= PktSizeBitStuff
- DataTime
;
438 if (DataSize
<= USB2_FS_RAW_BYTES_IN_MICROFRAME
)
441 DataTime
= USB2_FS_RAW_BYTES_IN_MICROFRAME
;
443 DPRINT("USB2_AllocateHS: ix - %X, frame - %X, uframe - %X, TimeUsed - %X\n",
447 HcExtension
->TimeUsed
[frame
][uframe
]);
449 if (!USB2_AllocateCheck(&HcExtension
->TimeUsed
[frame
][uframe
],
451 USB2_MAX_MICROFRAME_ALLOCATION
))
456 USB2_IncMicroFrame(&frame
, &uframe
);
457 DataTime
+= USB2_FS_RAW_BYTES_IN_MICROFRAME
;
462 frame
= TtEndpoint
->StartFrame
+ Frame
;
463 uframe
= TtEndpoint
->StartMicroframe
+ TtEndpoint
->Nums
.NumStarts
+ 1;
465 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumCompletes
; ix
++)
467 if (Tt
->TimeCS
[frame
][uframe
] < USB2_FS_RAW_BYTES_IN_MICROFRAME
)
469 RemainDataTime
= USB2_FS_RAW_BYTES_IN_MICROFRAME
-
470 Tt
->TimeCS
[frame
][uframe
];
472 if (RemainDataTime
>= PktSizeBitStuff
)
474 DataTime
= PktSizeBitStuff
;
476 else if (RemainDataTime
> 0)
478 DataTime
= RemainDataTime
;
485 if (!USB2_AllocateCheck(&HcExtension
->TimeUsed
[frame
][uframe
],
487 USB2_MAX_MICROFRAME_ALLOCATION
))
493 if (PktSizeBitStuff
< USB2_FS_RAW_BYTES_IN_MICROFRAME
)
494 Tt
->TimeCS
[frame
][uframe
] += PktSizeBitStuff
;
496 Tt
->TimeCS
[frame
][uframe
] += USB2_FS_RAW_BYTES_IN_MICROFRAME
;
498 USB2_IncMicroFrame(&frame
, &uframe
);
502 DPRINT("USB2_AllocateHS: Result - %X\n", Result
);
508 USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint
,
512 PUSB2_HC_EXTENSION HcExtension
;
517 ULONG CurrentDataTime
;
518 ULONG RemainDataTime
;
522 USHORT PktSizeBitStuff
;
526 DPRINT("USB2_DeallocateHS: TtEndpoint - %p, Frame - %X\n",
531 HcExtension
= Tt
->HcExtension
;
533 USB2_GetHsOverhead(TtEndpoint
, &OverheadSS
, &OverheadCS
);
535 frame
= TtEndpoint
->StartFrame
+ Frame
;
536 uframe
= TtEndpoint
->StartMicroframe
;
538 if (TtEndpoint
->StartMicroframe
== USB2_PREV_MICROFRAME
)
539 USB2_GetPrevMicroFrame(&frame
, &uframe
);
541 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumStarts
; ix
++)
543 HcExtension
->TimeUsed
[frame
][uframe
] -= OverheadSS
;
544 --Tt
->NumStartSplits
[frame
][uframe
];
545 USB2_IncMicroFrame(&frame
, &uframe
);
548 frame
= TtEndpoint
->StartFrame
+ Frame
;
549 uframe
= TtEndpoint
->StartMicroframe
+ TtEndpoint
->Nums
.NumStarts
+ 1;
551 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumCompletes
; ix
++)
553 HcExtension
->TimeUsed
[frame
][uframe
] -= OverheadCS
;
554 USB2_IncMicroFrame(&frame
, &uframe
);
557 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
558 PktSize
= TtEndpoint
->MaxPacketSize
;
559 PktSizeBitStuff
= USB2_AddDataBitStuff(PktSize
);
561 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
563 frame
= TtEndpoint
->StartFrame
+ Frame
;
564 uframe
= TtEndpoint
->StartMicroframe
;
566 if (TtEndpoint
->StartMicroframe
== USB2_PREV_MICROFRAME
)
567 USB2_GetPrevMicroFrame(&frame
, &uframe
);
571 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumStarts
; ix
++)
573 DataSize
= PktSizeBitStuff
- DataTime
;
575 if (DataSize
<= USB2_FS_RAW_BYTES_IN_MICROFRAME
)
576 CurrentDataTime
= PktSizeBitStuff
- DataTime
;
578 CurrentDataTime
= USB2_FS_RAW_BYTES_IN_MICROFRAME
;
580 HcExtension
->TimeUsed
[frame
][uframe
] -= CurrentDataTime
;
581 USB2_IncMicroFrame(&frame
, &uframe
);
582 DataTime
+= USB2_FS_RAW_BYTES_IN_MICROFRAME
;
587 frame
= TtEndpoint
->StartFrame
+ Frame
;
588 uframe
= TtEndpoint
->StartMicroframe
+ TtEndpoint
->Nums
.NumStarts
+ 1;
590 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumCompletes
; ix
++)
592 if (PktSizeBitStuff
>= USB2_FS_RAW_BYTES_IN_MICROFRAME
)
593 CurrentDataTime
= USB2_FS_RAW_BYTES_IN_MICROFRAME
;
595 CurrentDataTime
= PktSizeBitStuff
;
597 Tt
->TimeCS
[frame
][uframe
] -= CurrentDataTime
;
599 if (Tt
->TimeCS
[frame
][uframe
] < USB2_FS_RAW_BYTES_IN_MICROFRAME
)
601 RemainDataTime
= USB2_FS_RAW_BYTES_IN_MICROFRAME
-
602 Tt
->TimeCS
[frame
][uframe
];
604 if (RemainDataTime
>= PktSizeBitStuff
)
605 RemainDataTime
= PktSizeBitStuff
;
607 HcExtension
->TimeUsed
[frame
][uframe
] -= RemainDataTime
;
610 USB2_IncMicroFrame(&frame
, &uframe
);
619 USB2_MoveTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
621 IN PUSB2_REBALANCE Rebalance
,
622 IN ULONG RebalanceListEntries
,
623 OUT BOOLEAN
* OutResult
)
630 DPRINT("USB2_MoveTtEndpoint: TtEndpoint - %p, BusTime - %X\n",
636 for (Num
= 0; Rebalance
->RebalanceEndpoint
[Num
]; Num
++)
638 if (Rebalance
->RebalanceEndpoint
[Num
] == TtEndpoint
)
642 DPRINT("USB2_MoveTtEndpoint: Num - %X\n", Num
);
644 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
646 if (Rebalance
->RebalanceEndpoint
[Num
] &&
647 TtEndpoint
->TtEndpointParams
.EndpointMoved
== TRUE
&&
648 ((TransferType
!= USBPORT_TRANSFER_TYPE_INTERRUPT
) || BusTime
>= 0))
650 DPRINT("USB2_MoveTtEndpoint: result - FALSE\n");
655 (TtEndpoint
->StartFrame
+ ix
) < USB2_FRAMES
;
656 ix
+= TtEndpoint
->ActualPeriod
)
658 USB2_DeallocateHS(TtEndpoint
, ix
);
661 TtEndpoint
->StartTime
+= BusTime
;
663 EndBusTime
= TtEndpoint
->StartTime
+ TtEndpoint
->CalcBusTime
;
665 if (EndBusTime
> USB2_FS_MAX_PERIODIC_ALLOCATION
)
667 DPRINT("USB2_MoveTtEndpoint: EndBusTime is too large!\n");
671 TtEndpoint
->TtEndpointParams
.EndpointMoved
= TRUE
;
673 if (Rebalance
->RebalanceEndpoint
[Num
] == NULL
)
675 if (Num
>= RebalanceListEntries
)
677 DPRINT("USB2_MoveTtEndpoint: Too many changes!\n");
682 Rebalance
->RebalanceEndpoint
[Num
] = TtEndpoint
;
683 Rebalance
->RebalanceEndpoint
[Num
+ 1] = NULL
;
688 (TtEndpoint
->StartFrame
+ ix
) < USB2_FRAMES
;
689 ix
+= TtEndpoint
->ActualPeriod
)
691 if (!USB2_AllocateHS(TtEndpoint
, ix
))
693 DPRINT("USB2_MoveTtEndpoint: OutResult - FALSE\n");
698 DPRINT("USB2_MoveTtEndpoint: result - TRUE\n");
704 USB2_CommonFrames(IN PUSB2_TT_ENDPOINT NextTtEndpoint
,
705 IN PUSB2_TT_ENDPOINT TtEndpoint
)
709 DPRINT("USB2_CommonFrames: \n");
711 if (NextTtEndpoint
->ActualPeriod
== ENDPOINT_INTERRUPT_1ms
||
712 TtEndpoint
->ActualPeriod
== ENDPOINT_INTERRUPT_1ms
)
717 if (NextTtEndpoint
->ActualPeriod
< TtEndpoint
->ActualPeriod
)
718 Frame
= TtEndpoint
->StartFrame
% TtEndpoint
->ActualPeriod
;
720 Frame
= NextTtEndpoint
->StartFrame
% TtEndpoint
->ActualPeriod
;
722 return (Frame
== TtEndpoint
->StartFrame
);
727 USB2_ConvertFrame(IN UCHAR Frame
,
730 OUT PUCHAR HcMicroframe
)
732 DPRINT("USB2_ConvertFrame: Frame - %x, Microframe - %x\n",
736 if (Microframe
== USB2_PREV_MICROFRAME
)
742 if (Microframe
>= 0 &&
743 Microframe
<= (USB2_MICROFRAMES
- 2))
746 *HcMicroframe
= Microframe
+ 1;
749 if (Microframe
== (USB2_MICROFRAMES
- 1))
751 *HcFrame
= Frame
+ 1;
758 USB2_GetSMASK(IN PUSB2_TT_ENDPOINT TtEndpoint
)
765 if (TtEndpoint
->TtEndpointParams
.DeviceSpeed
== UsbHighSpeed
)
767 SMask
= (1 << TtEndpoint
->StartMicroframe
);
771 USB2_ConvertFrame(TtEndpoint
->StartFrame
,
772 TtEndpoint
->StartMicroframe
,
776 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumStarts
; ix
++)
778 SMask
|= (1 << HcMicroFrame
);
788 USB2_GetCMASK(IN PUSB2_TT_ENDPOINT TtEndpoint
)
800 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
801 DeviceSpeed
= TtEndpoint
->TtEndpointParams
.DeviceSpeed
;
802 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
804 if (DeviceSpeed
== UsbHighSpeed
)
807 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
809 USB2_ConvertFrame(TtEndpoint
->StartFrame
,
810 TtEndpoint
->StartMicroframe
,
814 Result
= CMASKS
[HcMicroFrame
];
818 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
821 USB2_ConvertFrame(TtEndpoint
->StartFrame
,
822 TtEndpoint
->StartMicroframe
,
826 NumCompletes
= TtEndpoint
->Nums
.NumCompletes
;
828 for (MicroFrameCS
= HcMicroFrame
+ 2;
829 MicroFrameCS
< USB2_MICROFRAMES
;
832 MaskCS
|= (1 << MicroFrameCS
);
839 for (; NumCompletes
; NumCompletes
--)
841 MaskCS
|= (1 << (MicroFrameCS
- USB2_MICROFRAMES
));
852 USB2_RebalanceEndpoint(IN PDEVICE_OBJECT FdoDevice
,
855 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
856 PUSBPORT_REGISTRATION_PACKET Packet
;
857 PUSBPORT_ENDPOINT Endpoint
;
859 ULONG AllocedBusTime
;
860 ULONG EndpointBandwidth
;
862 ULONG ScheduleOffset
;
871 FdoExtension
= FdoDevice
->DeviceExtension
;
872 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
874 while (!IsListEmpty(List
))
876 Entry
= RemoveHeadList(List
);
878 Endpoint
= CONTAINING_RECORD(Entry
,
880 RebalanceLink
.Flink
);
882 DPRINT("USB2_RebalanceEndpoint: Endpoint - %p\n", Endpoint
);
884 Endpoint
->RebalanceLink
.Flink
= NULL
;
885 Endpoint
->RebalanceLink
.Blink
= NULL
;
887 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
888 &Endpoint
->EndpointOldIrql
);
890 SMask
= USB2_GetSMASK(Endpoint
->TtEndpoint
);
891 CMask
= USB2_GetCMASK(Endpoint
->TtEndpoint
);
893 ScheduleOffset
= Endpoint
->TtEndpoint
->StartFrame
;
894 NewPeriod
= Endpoint
->TtEndpoint
->ActualPeriod
;
896 AllocedBusTime
= Endpoint
->TtEndpoint
->CalcBusTime
;
897 EndpointBandwidth
= USB2_MICROFRAMES
* AllocedBusTime
;
899 Endpoint
->EndpointProperties
.InterruptScheduleMask
= SMask
;
900 Endpoint
->EndpointProperties
.SplitCompletionMask
= CMask
;
902 if (Endpoint
->EndpointProperties
.Period
!= NewPeriod
)
904 ASSERT(Endpoint
->EndpointProperties
.Period
);
905 Factor
= USB2_FRAMES
/ Endpoint
->EndpointProperties
.Period
;
907 for (ix
= 0; ix
< Factor
; ix
++)
909 Bandwidth
= Endpoint
->EndpointProperties
.UsbBandwidth
;
910 n
= Factor
* Endpoint
->EndpointProperties
.ScheduleOffset
;
911 Endpoint
->TtExtension
->Bandwidth
[n
+ ix
] += Bandwidth
;
914 Endpoint
->EndpointProperties
.Period
= NewPeriod
;
915 Endpoint
->EndpointProperties
.ScheduleOffset
= ScheduleOffset
;
916 Endpoint
->EndpointProperties
.UsbBandwidth
= EndpointBandwidth
;
919 Factor
= USB2_FRAMES
/ NewPeriod
;
921 for (ix
= 0; ix
< Factor
; ix
++)
923 n
= Factor
* ScheduleOffset
;
924 Endpoint
->TtExtension
->Bandwidth
[n
+ ix
] += EndpointBandwidth
;
928 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
930 Packet
->RebalanceEndpoint(FdoExtension
->MiniPortExt
,
931 &Endpoint
->EndpointProperties
,
932 (PVOID
)((ULONG_PTR
)Endpoint
+ sizeof(USBPORT_ENDPOINT
)));
934 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
936 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
937 Endpoint
->EndpointOldIrql
);
943 USB2_Rebalance(IN PDEVICE_OBJECT FdoDevice
,
944 IN PLIST_ENTRY RebalanceList
)
946 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
947 PUSBPORT_ENDPOINT Endpoint
;
949 LIST_ENTRY BalanceListInt1
;
950 LIST_ENTRY BalanceListInt2
;
952 ULONG ScheduleOffset
;
957 DPRINT("USB2_Rebalance: FdoDevice - %p, RebalanceList - %p\n",
961 InitializeListHead(&BalanceListInt1
);
962 InitializeListHead(&BalanceListInt2
);
964 while (!IsListEmpty(RebalanceList
))
966 Entry
= RebalanceList
->Flink
;
968 Endpoint
= CONTAINING_RECORD(Entry
,
970 RebalanceLink
.Flink
);
972 DPRINT("USBPORT_Rebalance: Entry - %p, Endpoint - %p\n",
976 RemoveHeadList(RebalanceList
);
980 SMask
= USB2_GetSMASK(Endpoint
->TtEndpoint
);
981 CMask
= USB2_GetCMASK(Endpoint
->TtEndpoint
);
983 ScheduleOffset
= Endpoint
->TtEndpoint
->StartFrame
;
984 ActualPeriod
= Endpoint
->TtEndpoint
->ActualPeriod
;
986 EndpointProperties
= &Endpoint
->EndpointProperties
;
987 TransferType
= EndpointProperties
->TransferType
;
989 switch (TransferType
)
991 case USBPORT_TRANSFER_TYPE_ISOCHRONOUS
:
992 DPRINT("USBPORT_Rebalance: USBPORT_TRANSFER_TYPE_ISOCHRONOUS. FIXME\n");
996 case USBPORT_TRANSFER_TYPE_INTERRUPT
:
997 if (SMask
!= EndpointProperties
->InterruptScheduleMask
||
998 CMask
!= EndpointProperties
->SplitCompletionMask
||
999 ScheduleOffset
!= EndpointProperties
->ScheduleOffset
||
1000 ActualPeriod
!= EndpointProperties
->Period
)
1002 if (ActualPeriod
== EndpointProperties
->Period
&&
1003 ScheduleOffset
== EndpointProperties
->ScheduleOffset
)
1005 InsertTailList(&BalanceListInt1
, Entry
);
1009 InsertTailList(&BalanceListInt2
, Entry
);
1020 USB2_RebalanceEndpoint(FdoDevice
, &BalanceListInt2
);
1021 USB2_RebalanceEndpoint(FdoDevice
, &BalanceListInt1
);
1022 //USB2_RebalanceEndpoint(FdoDevice, &BalanceListIso);
1027 USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint
,
1028 IN PUSB2_REBALANCE Rebalance
,
1029 IN PULONG RebalanceListEntries
,
1033 PUSB2_HC_EXTENSION HcExtension
;
1037 ULONG StartMicroframe
;
1039 PUSB2_TT_ENDPOINT endpoint
;
1040 PUSB2_TT_ENDPOINT nextEndpoint
;
1041 PUSB2_TT_ENDPOINT lastEndpoint
;
1042 PUSB2_TT_ENDPOINT tmpEndpoint
;
1051 BOOLEAN IsMoved
= FALSE
;
1053 DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint - %p, MaxFrames - %X, CalcBusTime - %X\n",
1056 TtEndpoint
->CalcBusTime
);
1058 if (TtEndpoint
->CalcBusTime
== 0)
1060 DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint not allocated!\n");
1064 Tt
= TtEndpoint
->Tt
;
1065 HcExtension
= Tt
->HcExtension
;
1067 Speed
= TtEndpoint
->TtEndpointParams
.DeviceSpeed
;
1068 DPRINT("USB2_DeallocateEndpointBudget: DeviceSpeed - %X\n", Speed
);
1070 StartMicroframe
= TtEndpoint
->StartFrame
* USB2_MICROFRAMES
+
1071 TtEndpoint
->StartMicroframe
;
1073 if (Speed
== UsbHighSpeed
)
1075 for (ix
= StartMicroframe
;
1076 ix
< USB2_MAX_MICROFRAMES
;
1077 ix
+= TtEndpoint
->ActualPeriod
)
1079 frame
= ix
/ USB2_MICROFRAMES
;
1080 uframe
= ix
% (USB2_MICROFRAMES
- 1);
1082 HcExtension
->TimeUsed
[frame
][uframe
] -= TtEndpoint
->CalcBusTime
;
1085 TtEndpoint
->CalcBusTime
= 0;
1087 DPRINT("USB2_DeallocateEndpointBudget: return TRUE\n");
1091 /* Speed != UsbHighSpeed (FS/LS) */
1093 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
1095 for (ix
= MaxFrames
, Frame
= (MaxFrames
- 1) - TtEndpoint
->StartFrame
;
1099 frame
= TtEndpoint
->StartFrame
+ Frame
;
1101 DPRINT("USB2_DeallocateEndpointBudget: frame - %X, Frame - %X, StartFrame - %X\n",
1104 TtEndpoint
->StartFrame
);
1106 if ((Frame
% TtEndpoint
->ActualPeriod
) == 0)
1108 USB2_DeallocateHS(TtEndpoint
, Frame
);
1109 Tt
->FrameBudget
[frame
].TimeUsed
-= TtEndpoint
->CalcBusTime
;
1112 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
1113 endpoint
= Tt
->FrameBudget
[frame
].IntEndpoint
;
1115 endpoint
= Tt
->FrameBudget
[frame
].IsoEndpoint
;
1117 nextEndpoint
= endpoint
->NextTtEndpoint
;
1119 DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint - %p, nextEndpoint - %p\n",
1123 if (TtEndpoint
->CalcBusTime
> (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
1125 while (nextEndpoint
)
1127 endpoint
= nextEndpoint
;
1128 nextEndpoint
= nextEndpoint
->NextTtEndpoint
;
1131 nextEndpoint
= TtEndpoint
;
1133 DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
1139 while (nextEndpoint
&&
1140 !USB2_CheckTtEndpointInsert(nextEndpoint
, TtEndpoint
))
1142 endpoint
= nextEndpoint
;
1143 nextEndpoint
= nextEndpoint
->NextTtEndpoint
;
1146 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
&&
1149 DPRINT1("USB2_DeallocateEndpointBudget: Iso Ep UNIMPLEMENTED. FIXME\n");
1153 DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
1158 if ((Frame
% TtEndpoint
->ActualPeriod
) == 0)
1160 if (TtEndpoint
->CalcBusTime
> (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
1162 Tt
->FrameBudget
[frame
].AltEndpoint
= NULL
;
1164 else if (nextEndpoint
)
1166 nextEndpoint
= nextEndpoint
->NextTtEndpoint
;
1167 endpoint
->NextTtEndpoint
= nextEndpoint
;
1169 DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
1175 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
1177 if (endpoint
== Tt
->FrameBudget
[frame
].IntEndpoint
)
1179 if (Tt
->FrameBudget
[frame
].IsoEndpoint
->NextTtEndpoint
)
1181 endpoint
= Tt
->FrameBudget
[frame
].IsoEndpoint
->NextTtEndpoint
;
1183 else if (Tt
->FrameBudget
[frame
].AltEndpoint
)
1185 endpoint
= Tt
->FrameBudget
[frame
].AltEndpoint
;
1191 DPRINT1("USB2_DeallocateEndpointBudget: Iso Ep UNIMPLEMENTED. FIXME\n");
1195 Period
= TtEndpoint
->ActualPeriod
;
1199 endpoint
= nextEndpoint
,
1200 nextEndpoint
= nextEndpoint
->NextTtEndpoint
)
1202 DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
1206 endTime
= endpoint
->StartTime
+ endpoint
->CalcBusTime
;
1207 maxEndTime
= endTime
;
1209 if (Period
> nextEndpoint
->ActualPeriod
||
1210 TtEndpoint
->StartFrame
!= nextEndpoint
->StartFrame
)
1212 if (USB2_CommonFrames(nextEndpoint
, TtEndpoint
))
1213 Factor
= Period
/ nextEndpoint
->ActualPeriod
;
1215 Factor
= USB2_FRAMES
/ nextEndpoint
->ActualPeriod
;
1217 maxEndTime
= endTime
;
1219 for (jx
= 0, frame
= nextEndpoint
->StartFrame
;
1221 jx
++, frame
+= nextEndpoint
->ActualPeriod
)
1223 if (nextEndpoint
->StartFrame
!= TtEndpoint
->StartFrame
)
1225 lastEndpoint
= Tt
->FrameBudget
[frame
].IntEndpoint
;
1227 if (Tt
->FrameBudget
[frame
].IsoEndpoint
->NextTtEndpoint
)
1229 lastEndpoint
= Tt
->FrameBudget
[frame
].IsoEndpoint
->NextTtEndpoint
;
1231 else if (Tt
->FrameBudget
[frame
].AltEndpoint
)
1233 lastEndpoint
= Tt
->FrameBudget
[frame
].AltEndpoint
;
1236 for (tmpEndpoint
= Tt
->FrameBudget
[frame
].IntEndpoint
->NextTtEndpoint
;
1237 tmpEndpoint
&& tmpEndpoint
!= nextEndpoint
;
1238 tmpEndpoint
= tmpEndpoint
->NextTtEndpoint
)
1240 lastEndpoint
= tmpEndpoint
;
1243 lastEndTime
= lastEndpoint
->StartTime
+ lastEndpoint
->CalcBusTime
;
1245 if (endTime
< (lastEndTime
- 1))
1247 maxEndTime
= lastEndTime
;
1248 endTime
= maxEndTime
;
1250 if (nextEndpoint
->StartTime
== maxEndTime
)
1255 maxEndTime
= endTime
;
1261 if (maxEndTime
>= nextEndpoint
->StartTime
)
1264 if (!USB2_MoveTtEndpoint(nextEndpoint
,
1265 maxEndTime
- nextEndpoint
->StartTime
,
1267 *RebalanceListEntries
,
1272 DPRINT("USB2_DeallocateEndpointBudget: Not moved!\n");
1278 if (Period
> nextEndpoint
->ActualPeriod
)
1279 Period
= nextEndpoint
->ActualPeriod
;
1283 TtEndpoint
->CalcBusTime
= 0;
1285 DPRINT("USB2_DeallocateEndpointBudget: return TRUE\n");
1291 USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
1292 IN PUSB2_REBALANCE Rebalance
,
1293 IN PULONG RebalanceListEntries
)
1296 PUSB2_HC_EXTENSION HcExtension
;
1307 PUSB2_TT_ENDPOINT prevEndpoint
;
1308 PUSB2_TT_ENDPOINT nextEndpoint
;
1309 PUSB2_TT_ENDPOINT IntEndpoint
;
1312 BOOLEAN Result
= TRUE
;
1314 DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p\n", TtEndpoint
);
1316 Tt
= TtEndpoint
->Tt
;
1317 HcExtension
= Tt
->HcExtension
;
1319 TtEndpoint
->Nums
.NumStarts
= 0;
1320 TtEndpoint
->Nums
.NumCompletes
= 0;
1322 TtEndpoint
->StartFrame
= 0;
1323 TtEndpoint
->StartMicroframe
= 0;
1325 if (TtEndpoint
->CalcBusTime
)
1327 DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint already allocated!\n");
1331 Speed
= TtEndpoint
->TtEndpointParams
.DeviceSpeed
;
1333 if (Speed
== UsbHighSpeed
)
1335 if (TtEndpoint
->Period
> USB2_MAX_MICROFRAMES
)
1336 TtEndpoint
->ActualPeriod
= USB2_MAX_MICROFRAMES
;
1338 TtEndpoint
->ActualPeriod
= TtEndpoint
->Period
;
1340 MinTimeUsed
= HcExtension
->TimeUsed
[0][0];
1342 for (ix
= 1; ix
< TtEndpoint
->ActualPeriod
; ix
++)
1344 frame
= ix
/ USB2_MICROFRAMES
;
1345 uframe
= ix
% (USB2_MICROFRAMES
- 1);
1347 TimeUsed
= HcExtension
->TimeUsed
[frame
][uframe
];
1349 if (TimeUsed
< MinTimeUsed
)
1351 MinTimeUsed
= TimeUsed
;
1352 TtEndpoint
->StartFrame
= frame
;
1353 TtEndpoint
->StartMicroframe
= uframe
;
1357 TtEndpoint
->CalcBusTime
= USB2_GetOverhead(TtEndpoint
) +
1358 USB2_AddDataBitStuff(TtEndpoint
->MaxPacketSize
);
1360 DPRINT("USB2_AllocateTimeForEndpoint: StartFrame - %X, StartMicroframe - %X, CalcBusTime - %X\n",
1361 TtEndpoint
->StartFrame
,
1362 TtEndpoint
->StartMicroframe
,
1363 TtEndpoint
->CalcBusTime
);
1365 Microframe
= TtEndpoint
->StartFrame
* USB2_MICROFRAMES
+
1366 TtEndpoint
->StartMicroframe
;
1368 if (Microframe
>= USB2_MAX_MICROFRAMES
)
1370 DPRINT("USB2_AllocateTimeForEndpoint: Microframe >= 256. Result - TRUE\n");
1374 for (ix
= Microframe
;
1375 ix
< USB2_MAX_MICROFRAMES
;
1376 ix
+= TtEndpoint
->ActualPeriod
)
1378 frame
= ix
/ USB2_MICROFRAMES
;
1379 uframe
= ix
% (USB2_MICROFRAMES
- 1);
1381 DPRINT("USB2_AllocateTimeForEndpoint: frame - %X, uframe - %X, TimeUsed[f][uf] - %X\n",
1384 HcExtension
->TimeUsed
[frame
][uframe
]);
1386 if (!USB2_AllocateCheck(&HcExtension
->TimeUsed
[frame
][uframe
],
1387 TtEndpoint
->CalcBusTime
,
1388 USB2_MAX_MICROFRAME_ALLOCATION
))
1390 DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n");
1397 for (ix
= Microframe
;
1398 ix
< USB2_MAX_MICROFRAMES
;
1399 ix
+= TtEndpoint
->ActualPeriod
)
1401 frame
= ix
/ USB2_MICROFRAMES
;
1402 uframe
= ix
% (USB2_MICROFRAMES
- 1);
1404 HcExtension
->TimeUsed
[frame
][uframe
] -= TtEndpoint
->CalcBusTime
;
1408 DPRINT("USB2_AllocateTimeForEndpoint: Result - TRUE\n");
1412 /* Speed != UsbHighSpeed (FS/LS) */
1414 if (TtEndpoint
->Period
> USB2_FRAMES
)
1415 TtEndpoint
->ActualPeriod
= USB2_FRAMES
;
1417 TtEndpoint
->ActualPeriod
= TtEndpoint
->Period
;
1419 MinTimeUsed
= Tt
->FrameBudget
[0].TimeUsed
;
1421 for (ix
= 1; ix
< TtEndpoint
->ActualPeriod
; ix
++)
1423 if ((Tt
->FrameBudget
[ix
].TimeUsed
) < MinTimeUsed
)
1425 MinTimeUsed
= Tt
->FrameBudget
[ix
].TimeUsed
;
1426 TtEndpoint
->StartFrame
= ix
;
1430 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
1432 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
1434 if (Speed
== UsbFullSpeed
)
1436 Overhead
= USB2_FS_ISOCHRONOUS_OVERHEAD
+ Tt
->DelayTime
;
1440 DPRINT("USB2_AllocateTimeForEndpoint: ISO can not be on a LS bus!\n");
1446 if (Speed
== UsbFullSpeed
)
1447 Overhead
= USB2_FS_INTERRUPT_OVERHEAD
+ Tt
->DelayTime
;
1449 Overhead
= USB2_LS_INTERRUPT_OVERHEAD
+ Tt
->DelayTime
;
1452 if (Speed
== UsbLowSpeed
)
1453 TtEndpoint
->CalcBusTime
= TtEndpoint
->MaxPacketSize
* 8 + Overhead
;
1455 TtEndpoint
->CalcBusTime
= TtEndpoint
->MaxPacketSize
+ Overhead
;
1457 LatestStart
= USB2_HUB_DELAY
+ USB2_FS_SOF_TIME
;
1460 (TtEndpoint
->StartFrame
+ ix
) < USB2_FRAMES
;
1461 ix
+= TtEndpoint
->ActualPeriod
)
1463 frame
= TtEndpoint
->StartFrame
+ ix
;
1465 if (Tt
->FrameBudget
[frame
].AltEndpoint
&&
1466 TtEndpoint
->CalcBusTime
>= (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
1468 DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n");
1472 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
1473 prevEndpoint
= Tt
->FrameBudget
[frame
].IsoEndpoint
;
1475 prevEndpoint
= Tt
->FrameBudget
[frame
].IntEndpoint
;
1477 for (nextEndpoint
= prevEndpoint
->NextTtEndpoint
;
1479 nextEndpoint
= nextEndpoint
->NextTtEndpoint
)
1481 if (USB2_CheckTtEndpointInsert(nextEndpoint
, TtEndpoint
))
1484 prevEndpoint
= nextEndpoint
;
1487 StartTime
= USB2_GetStartTime(nextEndpoint
,
1492 LatestStart
= max(LatestStart
, StartTime
);
1495 TtEndpoint
->StartTime
= LatestStart
;
1497 if ((LatestStart
+ TtEndpoint
->CalcBusTime
) > USB2_FS_MAX_PERIODIC_ALLOCATION
)
1499 TtEndpoint
->CalcBusTime
= 0;
1500 DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n");
1504 for (ix
= 0, frame
= -TtEndpoint
->StartFrame
;
1508 DPRINT("USB2_AllocateTimeForEndpoint: ix - %X, frame - %X, StartFrame - %X\n",
1511 TtEndpoint
->StartFrame
);
1513 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
1515 DPRINT1("USB2_AllocateTimeForEndpoint: Iso Ep UNIMPLEMENTED. FIXME\n");
1520 IntEndpoint
= Tt
->FrameBudget
[ix
].IntEndpoint
;
1521 nextEndpoint
= IntEndpoint
->NextTtEndpoint
;
1523 for (nextEndpoint
= IntEndpoint
->NextTtEndpoint
;
1525 nextEndpoint
= nextEndpoint
->NextTtEndpoint
)
1527 if (USB2_CheckTtEndpointInsert(nextEndpoint
, TtEndpoint
))
1529 IntEndpoint
= nextEndpoint
;
1532 if ((frame
% TtEndpoint
->ActualPeriod
) == 0)
1540 calcBusTime
= LatestStart
+ TtEndpoint
->CalcBusTime
-
1541 nextEndpoint
->StartTime
;
1545 calcBusTime
= TtEndpoint
->CalcBusTime
;
1548 if (calcBusTime
> 0)
1550 TimeUsed
= Tt
->FrameBudget
[ix
].TimeUsed
;
1552 if (!USB2_AllocateCheck(&TimeUsed
,
1554 USB2_FS_MAX_PERIODIC_ALLOCATION
))
1556 DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n");
1562 if (nextEndpoint
!= TtEndpoint
)
1564 if ((frame
% TtEndpoint
->ActualPeriod
) == 0)
1568 DPRINT("USB2_AllocateTimeForEndpoint: frame == 0\n");
1569 TtEndpoint
->NextTtEndpoint
= nextEndpoint
;
1572 IntEndpoint
->NextTtEndpoint
= TtEndpoint
;
1574 DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p, nextEndpoint - %p\n",
1579 if (calcBusTime
> 0)
1584 DPRINT("USB2_AllocateTimeForEndpoint: nextEndpoint - %p, calcBusTime - %X\n",
1590 nextEndpoint
= nextEndpoint
->NextTtEndpoint
)
1592 MoveResult
= USB2_MoveTtEndpoint(nextEndpoint
,
1595 *RebalanceListEntries
,
1600 DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n");
1611 if ((frame
% TtEndpoint
->ActualPeriod
) == 0)
1613 if (!USB2_AllocateHS(TtEndpoint
, frame
))
1615 DPRINT1("USB2_AllocateTimeForEndpoint: USB2_AllocateHS return FALSE\n");
1619 Tt
->FrameBudget
[ix
].TimeUsed
+= TtEndpoint
->CalcBusTime
;
1622 if (Result
== FALSE
)
1624 USB2_DeallocateEndpointBudget(TtEndpoint
,
1626 RebalanceListEntries
,
1629 DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n");
1634 DPRINT("USB2_AllocateTimeForEndpoint: Result - %X\n", Result
);
1640 USB2_ChangePeriod(IN PUSB2_TT_ENDPOINT TtEndpoint
,
1641 IN PUSB2_REBALANCE Rebalance
,
1642 IN PULONG RebalanceListEntries
)
1646 DPRINT("USB2_ChangePeriod: RebalanceListEntries - %X\n",
1647 *RebalanceListEntries
);
1649 USB2_DeallocateEndpointBudget(TtEndpoint
,
1651 RebalanceListEntries
,
1654 TtEndpoint
->PreviosPeriod
= TtEndpoint
->Period
;
1655 TtEndpoint
->Period
= ENDPOINT_INTERRUPT_1ms
;
1657 Result
= USB2_AllocateTimeForEndpoint(TtEndpoint
,
1659 RebalanceListEntries
);
1666 USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint
,
1667 IN PUSB2_REBALANCE Rebalance
,
1668 IN PULONG RebalanceListEntries
)
1670 PUSB2_TT_ENDPOINT ttEndpoint
;
1674 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
1676 if (TtEndpoint
->ActualPeriod
!= ENDPOINT_INTERRUPT_1ms
&&
1677 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
&&
1678 (CHAR
)TtEndpoint
->StartMicroframe
> 2 &&
1679 !USB2_ChangePeriod(TtEndpoint
, Rebalance
, RebalanceListEntries
))
1681 DPRINT("USB2_PromotePeriods: return FALSE\n");
1685 if (Rebalance
->RebalanceEndpoint
[0] == NULL
)
1687 DPRINT("USB2_PromotePeriods: return TRUE\n");
1691 DPRINT("USB2_PromotePeriods: RebalanceListEntries - %X\n",
1692 *RebalanceListEntries
);
1694 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
1696 Rebalance
->RebalanceEndpoint
[ix
]->IsPromoted
= FALSE
;
1699 for (ix
= 0; ; ix
++)
1701 ttEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
1702 TransferType
= ttEndpoint
->TtEndpointParams
.TransferType
;
1704 if (ttEndpoint
->ActualPeriod
!= ENDPOINT_INTERRUPT_1ms
&&
1705 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
&&
1706 (CHAR
)ttEndpoint
->StartMicroframe
> 2)
1708 USB2_DeallocateEndpointBudget(ttEndpoint
,
1710 RebalanceListEntries
,
1713 ttEndpoint
->IsPromoted
= TRUE
;
1714 ttEndpoint
->PreviosPeriod
= ttEndpoint
->Period
;
1715 ttEndpoint
->Period
= ENDPOINT_INTERRUPT_1ms
;
1717 if (!USB2_AllocateTimeForEndpoint(ttEndpoint
,
1719 RebalanceListEntries
))
1725 if (Rebalance
->RebalanceEndpoint
[ix
+ 1] == NULL
)
1727 DPRINT("USB2_PromotePeriods: return TRUE\n");
1732 USB2_DeallocateEndpointBudget(TtEndpoint
,
1734 RebalanceListEntries
,
1737 TtEndpoint
->Period
= TtEndpoint
->PreviosPeriod
;
1738 TtEndpoint
->PreviosPeriod
= 0;
1740 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
1742 ttEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
1744 if (ttEndpoint
->IsPromoted
)
1746 if (ttEndpoint
->CalcBusTime
)
1748 USB2_DeallocateEndpointBudget(ttEndpoint
,
1750 RebalanceListEntries
,
1754 TtEndpoint
->Period
= TtEndpoint
->PreviosPeriod
;
1755 TtEndpoint
->PreviosPeriod
= 0;
1757 USB2_AllocateTimeForEndpoint(ttEndpoint
,
1759 RebalanceListEntries
);
1763 DPRINT("USB2_PromotePeriods: return FALSE\n");
1769 USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension
)
1772 ULONG NewBusBandwidth
;
1773 ULONG MaxBusBandwidth
= 0;
1774 ULONG MinBusBandwidth
;
1777 DPRINT("USBPORT_UpdateAllocatedBwTt: TtExtension - %p\n", TtExtension
);
1779 BusBandwidth
= TtExtension
->BusBandwidth
;
1780 MinBusBandwidth
= BusBandwidth
;
1782 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
1784 NewBusBandwidth
= BusBandwidth
- TtExtension
->Bandwidth
[ix
];
1786 MaxBusBandwidth
= max(MaxBusBandwidth
, NewBusBandwidth
);
1787 MinBusBandwidth
= min(MinBusBandwidth
, NewBusBandwidth
);
1790 TtExtension
->MaxBandwidth
= MaxBusBandwidth
;
1792 if (MinBusBandwidth
== BusBandwidth
)
1793 TtExtension
->MinBandwidth
= 0;
1795 TtExtension
->MinBandwidth
= MinBusBandwidth
;
1800 USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
1801 IN PUSBPORT_ENDPOINT Endpoint
)
1803 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1804 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
1805 PUSB2_TT_EXTENSION TtExtension
;
1807 PUSB2_REBALANCE Rebalance
;
1808 LIST_ENTRY RebalanceList
;
1809 ULONG RebalanceListEntries
;
1810 PUSB2_TT_ENDPOINT TtEndpoint
;
1811 PUSB2_TT_ENDPOINT RebalanceTtEndpoint
;
1813 USB_DEVICE_SPEED DeviceSpeed
;
1815 ULONG AllocedBusTime
;
1816 ULONG EndpointBandwidth
;
1817 ULONG ScheduleOffset
;
1827 DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n",
1831 EndpointProperties
= &Endpoint
->EndpointProperties
;
1832 EndpointProperties
->ScheduleOffset
= 0;
1834 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
1836 DPRINT("USBPORT_AllocateBandwidthUSB2: ENDPOINT_FLAG_ROOTHUB_EP0\n");
1840 FdoExtension
= FdoDevice
->DeviceExtension
;
1842 TransferType
= EndpointProperties
->TransferType
;
1843 DPRINT("USBPORT_AllocateBandwidthUSB2: TransferType - %X\n", TransferType
);
1845 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
1846 TransferType
== USBPORT_TRANSFER_TYPE_BULK
)
1851 if (Endpoint
->TtExtension
)
1852 TtExtension
= Endpoint
->TtExtension
;
1856 InitializeListHead(&RebalanceList
);
1858 Rebalance
= ExAllocatePoolWithTag(NonPagedPool
,
1859 sizeof(USB2_REBALANCE
),
1862 DPRINT("USBPORT_AllocateBandwidthUSB2: Rebalance - %p, TtExtension - %p\n",
1868 RtlZeroMemory(Rebalance
, sizeof(USB2_REBALANCE
));
1870 TtEndpoint
= Endpoint
->TtEndpoint
;
1871 TtEndpoint
->Endpoint
= Endpoint
;
1873 Direction
= EndpointProperties
->Direction
== USBPORT_TRANSFER_DIRECTION_OUT
;
1874 DeviceSpeed
= EndpointProperties
->DeviceSpeed
;
1876 switch (DeviceSpeed
)
1881 Tt
= &TtExtension
->Tt
;
1882 Period
= USB2_FRAMES
;
1884 while (Period
> 0 && Period
> EndpointProperties
->Period
)
1889 DPRINT("USBPORT_AllocateBandwidthUSB2: Period - %X\n", Period
);
1895 Tt
= &FdoExtension
->Usb2Extension
->HcTt
;
1897 if (EndpointProperties
->Period
> USB2_MAX_MICROFRAMES
)
1898 Period
= USB2_MAX_MICROFRAMES
;
1900 Period
= EndpointProperties
->Period
;
1907 DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n",
1912 Tt
= &TtExtension
->Tt
;
1917 USB2_InitTtEndpoint(TtEndpoint
,
1922 EndpointProperties
->MaxPacketSize
,
1925 RebalanceListEntries
= USB2_FRAMES
- 2;
1927 Result
= USB2_AllocateTimeForEndpoint(TtEndpoint
,
1929 &RebalanceListEntries
);
1933 Result
= USB2_PromotePeriods(TtEndpoint
,
1935 &RebalanceListEntries
);
1938 RebalanceListEntries
= 0;
1940 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
1942 RebalanceListEntries
= ix
+ 1;
1947 RebalanceListEntries
= 0;
1951 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceListEntries - %X, Result - %X\n",
1952 RebalanceListEntries
,
1955 for (ix
= 0; ix
< RebalanceListEntries
; ix
++)
1957 RebalanceTtEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
1959 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceTtEndpoint[%X] - %p, RebalanceTtEndpoint - %p, RebalanceLink - %p\n",
1961 RebalanceTtEndpoint
,
1962 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
1964 InsertTailList(&RebalanceList
,
1965 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
1969 ExFreePoolWithTag(Rebalance
, USB_PORT_TAG
);
1973 SMask
= USB2_GetSMASK(Endpoint
->TtEndpoint
);
1974 EndpointProperties
->InterruptScheduleMask
= SMask
;
1976 CMask
= USB2_GetCMASK(Endpoint
->TtEndpoint
);
1977 EndpointProperties
->SplitCompletionMask
= CMask
;
1979 AllocedBusTime
= TtEndpoint
->CalcBusTime
;
1981 EndpointBandwidth
= USB2_MICROFRAMES
* AllocedBusTime
;
1982 EndpointProperties
->UsbBandwidth
= EndpointBandwidth
;
1984 ActualPeriod
= Endpoint
->TtEndpoint
->ActualPeriod
;
1985 EndpointProperties
->Period
= ActualPeriod
;
1987 ScheduleOffset
= Endpoint
->TtEndpoint
->StartFrame
;
1988 EndpointProperties
->ScheduleOffset
= ScheduleOffset
;
1990 ASSERT(ActualPeriod
);
1991 Factor
= USB2_FRAMES
/ ActualPeriod
;
1992 n
= ScheduleOffset
* Factor
;
1996 for (ix
= 0; ix
< Factor
; ix
++)
1998 TtExtension
->Bandwidth
[n
+ ix
] -= EndpointBandwidth
;
2003 for (ix
= 1; ix
< Factor
; ix
++)
2005 FdoExtension
->Bandwidth
[n
+ ix
] -= EndpointBandwidth
;
2009 USBPORT_DumpingEndpointProperties(EndpointProperties
);
2010 USBPORT_DumpingTtEndpoint(Endpoint
->TtEndpoint
);
2012 if (AllocedBusTime
>= (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
2014 DPRINT1("USBPORT_AllocateBandwidthUSB2: AllocedBusTime >= 0.5 * MAX_ALLOCATION \n");
2018 USB2_Rebalance(FdoDevice
, &RebalanceList
);
2022 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
2026 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2028 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
2031 USBPORT_UpdateAllocatedBwTt(TtExtension
);
2033 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2035 FdoExtension
->Bandwidth
[ix
] -= TtExtension
->MaxBandwidth
;
2038 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
2045 USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
2046 IN PUSBPORT_ENDPOINT Endpoint
)
2048 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2050 ULONG ScheduleOffset
;
2051 ULONG EndpointBandwidth
;
2052 LIST_ENTRY RebalanceList
;
2054 PUSB2_REBALANCE Rebalance
;
2055 ULONG RebalanceListEntries
;
2059 PUSB2_TT_EXTENSION TtExtension
;
2060 PUSB2_TT_ENDPOINT RebalanceTtEndpoint
;
2062 DPRINT("USBPORT_FreeBandwidthUSB2: Endpoint - %p\n", Endpoint
);
2064 FdoExtension
= FdoDevice
->DeviceExtension
;
2066 Period
= Endpoint
->EndpointProperties
.Period
;
2067 ScheduleOffset
= Endpoint
->EndpointProperties
.ScheduleOffset
;
2068 EndpointBandwidth
= Endpoint
->EndpointProperties
.UsbBandwidth
;
2070 InitializeListHead(&RebalanceList
);
2072 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
2074 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
2075 TransferType
== USBPORT_TRANSFER_TYPE_BULK
||
2076 (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
2081 Rebalance
= ExAllocatePoolWithTag(NonPagedPool
,
2082 sizeof(USB2_REBALANCE
),
2087 DPRINT1("USBPORT_FreeBandwidthUSB2: Rebalance == NULL!\n");
2091 RtlZeroMemory(Rebalance
, sizeof(USB2_REBALANCE
));
2093 ASSERT(Period
!= 0);
2094 Factor
= USB2_FRAMES
/ Period
;
2095 n
= ScheduleOffset
* Factor
;
2097 TtExtension
= Endpoint
->TtExtension
;
2101 for (ix
= 0; ix
< Factor
; ix
++)
2103 TtExtension
->Bandwidth
[n
+ ix
] += EndpointBandwidth
;
2108 for (ix
= 1; ix
< Factor
; ix
++)
2110 FdoExtension
->Bandwidth
[n
+ ix
] += EndpointBandwidth
;
2114 RebalanceListEntries
= USB2_FRAMES
- 2;
2116 USB2_DeallocateEndpointBudget(Endpoint
->TtEndpoint
,
2118 &RebalanceListEntries
,
2121 RebalanceListEntries
= 0;
2123 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
2125 RebalanceListEntries
= ix
+ 1;
2128 for (ix
= 0; ix
< RebalanceListEntries
; ix
++)
2130 RebalanceTtEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
2132 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceTtEndpoint[%X] - %p, RebalanceTtEndpoint - %p, RebalanceLink - %p\n",
2134 RebalanceTtEndpoint
,
2135 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
2137 InsertTailList(&RebalanceList
,
2138 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
2141 ExFreePoolWithTag(Rebalance
, USB_PORT_TAG
);
2143 USB2_Rebalance(FdoDevice
, &RebalanceList
);
2148 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2150 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
2153 USBPORT_UpdateAllocatedBwTt(TtExtension
);
2155 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2157 FdoExtension
->Bandwidth
[ix
] -= TtExtension
->MaxBandwidth
;
2160 DPRINT1("USBPORT_FreeBandwidthUSB2: exit\n");
2165 USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension
,
2171 DPRINT("USB2_InitTT: HcExtension - %p, Tt - %p\n", HcExtension
, Tt
);
2173 Tt
->HcExtension
= HcExtension
;
2175 Tt
->MaxTime
= USB2_FS_MAX_PERIODIC_ALLOCATION
;
2177 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2179 Tt
->FrameBudget
[ix
].TimeUsed
= USB2_MAX_MICROFRAMES
;
2180 Tt
->FrameBudget
[ix
].AltEndpoint
= NULL
;
2182 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
2184 Tt
->TimeCS
[ix
][jx
] = 0;
2185 Tt
->NumStartSplits
[ix
][jx
] = 0;
2188 Tt
->FrameBudget
[ix
].IsoEndpoint
= &Tt
->IsoEndpoint
[ix
];
2190 USB2_InitTtEndpoint(&Tt
->IsoEndpoint
[ix
],
2191 USBPORT_TRANSFER_TYPE_ISOCHRONOUS
,
2192 USBPORT_TRANSFER_DIRECTION_OUT
,
2198 Tt
->IsoEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
2199 Tt
->IsoEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
2200 Tt
->IsoEndpoint
[ix
].StartFrame
= ix
;
2201 Tt
->IsoEndpoint
[ix
].StartMicroframe
= USB2_PREV_MICROFRAME
;
2203 Tt
->FrameBudget
[ix
].IntEndpoint
= &Tt
->IntEndpoint
[ix
];
2205 USB2_InitTtEndpoint(&Tt
->IntEndpoint
[ix
],
2206 USBPORT_TRANSFER_TYPE_INTERRUPT
,
2207 USBPORT_TRANSFER_DIRECTION_OUT
,
2213 Tt
->IntEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
2214 Tt
->IntEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
2215 Tt
->IntEndpoint
[ix
].StartFrame
= ix
;
2216 Tt
->IntEndpoint
[ix
].StartMicroframe
= USB2_PREV_MICROFRAME
;
2222 USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension
)
2227 DPRINT("USB2_InitController: HcExtension - %p\n", HcExtension
);
2229 HcExtension
->MaxHsBusAllocation
= USB2_MAX_MICROFRAME_ALLOCATION
;
2231 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2233 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
2235 HcExtension
->TimeUsed
[ix
][jx
] = 0;
2239 HcExtension
->HcDelayTime
= USB2_CONTROLLER_DELAY
;
2241 USB2_InitTT(HcExtension
, &HcExtension
->HcTt
);