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>
15 USB2_AllocateCheck(IN OUT PULONG OutTimeUsed
,
17 IN ULONG LimitAllocation
)
20 BOOLEAN Result
= TRUE
;
22 BusTime
= *OutTimeUsed
+ CalcBusTime
;
23 *OutTimeUsed
+= CalcBusTime
;
25 if (BusTime
> LimitAllocation
)
27 DPRINT("USB2_AllocateCheck: BusTime > LimitAllocation\n");
36 USB2_AddDataBitStuff(IN USHORT DataTime
)
38 return (DataTime
+ (DataTime
/ 16));
43 USB2_IncMicroFrame(OUT PUCHAR frame
,
48 if (*uframe
> (USB2_MICROFRAMES
- 1))
51 *frame
= (*frame
+ 1) & (USB2_FRAMES
- 1);
57 USB2_GetPrevMicroFrame(OUT PUCHAR frame
,
60 *uframe
= USB2_MICROFRAMES
- 1;
65 *frame
= USB2_FRAMES
- 1;
70 USB2_CheckTtEndpointInsert(IN PUSB2_TT_ENDPOINT nextTtEndpoint
,
71 IN PUSB2_TT_ENDPOINT TtEndpoint
)
75 DPRINT("USB2_CheckTtEndpointInsert: nextTtEndpoint - %p, TtEndpoint - %p\n",
81 if (TtEndpoint
->CalcBusTime
>= (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
83 DPRINT1("USB2_CheckTtEndpointInsert: Result - FALSE\n");
89 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
93 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
95 if (nextTtEndpoint
->ActualPeriod
< TtEndpoint
->ActualPeriod
&&
96 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
98 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
102 if ((nextTtEndpoint
->ActualPeriod
<= TtEndpoint
->ActualPeriod
&&
103 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
) ||
104 nextTtEndpoint
== TtEndpoint
)
106 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
110 DPRINT("USB2_CheckTtEndpointInsert: Result - FALSE\n");
116 USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint
)
124 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
125 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
126 DeviceSpeed
= TtEndpoint
->TtEndpointParams
.Direction
;
128 HostDelay
= TtEndpoint
->Tt
->HcExtension
->HcDelayTime
;
130 if (DeviceSpeed
== UsbHighSpeed
)
132 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
134 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
135 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_OUT_OVERHEAD
;
137 Overhead
= HostDelay
+ USB2_HS_INTERRUPT_OUT_OVERHEAD
;
141 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
142 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_IN_OVERHEAD
;
144 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_OUT_OVERHEAD
;
147 else if (DeviceSpeed
== UsbFullSpeed
)
149 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
150 Overhead
= HostDelay
+ USB2_FS_ISOCHRONOUS_OVERHEAD
;
152 Overhead
= HostDelay
+ USB2_FS_INTERRUPT_OVERHEAD
;
156 Overhead
= HostDelay
+ USB2_LS_INTERRUPT_OVERHEAD
;
164 USB2_GetHsOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint
,
165 IN PULONG OverheadSS
,
166 IN PULONG OverheadCS
)
172 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
173 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
175 HostDelay
= TtEndpoint
->Tt
->HcExtension
->HcDelayTime
;
177 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
179 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
181 *OverheadSS
= HostDelay
+ USB2_HS_SS_ISOCHRONOUS_OUT_OVERHEAD
;
186 *OverheadSS
= HostDelay
+ USB2_HS_SS_INTERRUPT_OUT_OVERHEAD
;
187 *OverheadCS
= HostDelay
+ USB2_HS_CS_INTERRUPT_OUT_OVERHEAD
;
192 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
194 *OverheadSS
= HostDelay
+ USB2_HS_SS_ISOCHRONOUS_IN_OVERHEAD
;
195 *OverheadCS
= HostDelay
+ USB2_HS_CS_ISOCHRONOUS_IN_OVERHEAD
;
199 *OverheadSS
= HostDelay
+ USB2_HS_SS_INTERRUPT_IN_OVERHEAD
;
200 *OverheadCS
= HostDelay
+ USB2_HS_CS_INTERRUPT_IN_OVERHEAD
;
203 //DPRINT("USB2_GetHsOverhead: *OverheadSS - %X, *OverheadCS - %X\n",
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
== 0xFF)
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
;
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
== 0xFF)
540 USB2_GetPrevMicroFrame(&frame
, &uframe
);
543 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumStarts
; ix
++)
545 HcExtension
->TimeUsed
[frame
][uframe
] -= OverheadSS
;
546 --Tt
->NumStartSplits
[frame
][uframe
];
547 USB2_IncMicroFrame(&frame
, &uframe
);
550 frame
= TtEndpoint
->StartFrame
+ Frame
;
551 uframe
= TtEndpoint
->StartMicroframe
+ TtEndpoint
->Nums
.NumStarts
+ 1;
553 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumCompletes
; ix
++)
555 HcExtension
->TimeUsed
[frame
][uframe
] -= OverheadCS
;
556 USB2_IncMicroFrame(&frame
, &uframe
);
559 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
560 PktSize
= TtEndpoint
->MaxPacketSize
;
561 PktSizeBitStuff
= USB2_AddDataBitStuff(PktSize
);
563 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
565 frame
= TtEndpoint
->StartFrame
+ Frame
;
566 uframe
= TtEndpoint
->StartMicroframe
;
568 if (TtEndpoint
->StartMicroframe
== 0xFF)
570 USB2_GetPrevMicroFrame(&frame
, &uframe
);
575 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumStarts
; ix
++)
577 DataSize
= PktSizeBitStuff
- DataTime
;
579 if (DataSize
<= USB2_FS_RAW_BYTES_IN_MICROFRAME
)
581 CurrentDataTime
= PktSizeBitStuff
- DataTime
;
585 CurrentDataTime
= USB2_FS_RAW_BYTES_IN_MICROFRAME
;
588 HcExtension
->TimeUsed
[frame
][uframe
] -= CurrentDataTime
;
589 USB2_IncMicroFrame(&frame
, &uframe
);
590 DataTime
+= USB2_FS_RAW_BYTES_IN_MICROFRAME
;
595 frame
= TtEndpoint
->StartFrame
+ Frame
;
596 uframe
= TtEndpoint
->StartMicroframe
+ TtEndpoint
->Nums
.NumStarts
+ 1;
598 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumCompletes
; ix
++)
600 if (PktSizeBitStuff
>= USB2_FS_RAW_BYTES_IN_MICROFRAME
)
602 CurrentDataTime
= USB2_FS_RAW_BYTES_IN_MICROFRAME
;
606 CurrentDataTime
= PktSizeBitStuff
;
609 Tt
->TimeCS
[frame
][uframe
] -= CurrentDataTime
;
611 if (Tt
->TimeCS
[frame
][uframe
] < USB2_FS_RAW_BYTES_IN_MICROFRAME
)
613 RemainDataTime
= USB2_FS_RAW_BYTES_IN_MICROFRAME
-
614 Tt
->TimeCS
[frame
][uframe
];
616 if (RemainDataTime
>= PktSizeBitStuff
)
617 RemainDataTime
= PktSizeBitStuff
;
619 HcExtension
->TimeUsed
[frame
][uframe
] -= RemainDataTime
;
622 USB2_IncMicroFrame(&frame
, &uframe
);
631 USB2_MoveTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
633 IN PUSB2_REBALANCE Rebalance
,
634 IN ULONG RebalanceListEntries
,
635 OUT BOOLEAN
* OutResult
)
642 DPRINT("USB2_MoveTtEndpoint: TtEndpoint - %p, BusTime - %X\n",
648 for (Num
= 0; Rebalance
->RebalanceEndpoint
[Num
]; Num
++)
650 if (Rebalance
->RebalanceEndpoint
[Num
] == TtEndpoint
)
654 DPRINT("USB2_MoveTtEndpoint: Num - %X\n", Num
);
656 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
658 if (Rebalance
->RebalanceEndpoint
[Num
] &&
659 TtEndpoint
->TtEndpointParams
.EndpointMoved
== TRUE
&&
660 (TransferType
!= USBPORT_TRANSFER_TYPE_INTERRUPT
|| BusTime
>= 0))
662 DPRINT("USB2_MoveTtEndpoint: result - FALSE\n");
667 (TtEndpoint
->StartFrame
+ ix
) < USB2_FRAMES
;
668 ix
+= TtEndpoint
->ActualPeriod
)
670 USB2_DeallocateHS(TtEndpoint
, ix
);
673 TtEndpoint
->StartTime
+= BusTime
;
675 EndBusTime
= TtEndpoint
->StartTime
+ TtEndpoint
->CalcBusTime
;
677 if (EndBusTime
> USB2_FS_MAX_PERIODIC_ALLOCATION
)
679 DPRINT("USB2_MoveTtEndpoint: EndBusTime is too large!\n");
683 TtEndpoint
->TtEndpointParams
.EndpointMoved
= TRUE
;
685 if (Rebalance
->RebalanceEndpoint
[Num
] == NULL
)
687 if (Num
>= RebalanceListEntries
)
689 DPRINT("USB2_MoveTtEndpoint: Too many changes!\n");
694 Rebalance
->RebalanceEndpoint
[Num
] = TtEndpoint
;
695 Rebalance
->RebalanceEndpoint
[Num
+ 1] = NULL
;
700 (TtEndpoint
->StartFrame
+ ix
) < USB2_FRAMES
;
701 ix
+= TtEndpoint
->ActualPeriod
)
703 if (!USB2_AllocateHS(TtEndpoint
, ix
))
705 DPRINT("USB2_MoveTtEndpoint: OutResult - FALSE\n");
710 DPRINT("USB2_MoveTtEndpoint: result - TRUE\n");
716 USB2_CommonFrames(IN PUSB2_TT_ENDPOINT NextTtEndpoint
,
717 IN PUSB2_TT_ENDPOINT TtEndpoint
)
721 DPRINT("USB2_CommonFrames: \n");
723 if (NextTtEndpoint
->ActualPeriod
== ENDPOINT_INTERRUPT_1ms
||
724 TtEndpoint
->ActualPeriod
== ENDPOINT_INTERRUPT_1ms
)
729 if (NextTtEndpoint
->ActualPeriod
< TtEndpoint
->ActualPeriod
)
731 Frame
= TtEndpoint
->StartFrame
% TtEndpoint
->ActualPeriod
;
735 Frame
= NextTtEndpoint
->StartFrame
% TtEndpoint
->ActualPeriod
;
738 return (Frame
== TtEndpoint
->StartFrame
);
743 USB2_ConvertFrame(IN UCHAR Frame
,
746 OUT PUCHAR HcMicroframe
)
748 DPRINT("USB2_ConvertFrame: Frame - %x, Microframe - %x\n",
752 if (Microframe
== 0xFF)
758 if (Microframe
>= 0 &&
759 Microframe
<= (USB2_MICROFRAMES
- 2))
762 *HcMicroframe
= Microframe
+ 1;
765 if (Microframe
== (USB2_MICROFRAMES
- 1))
767 *HcFrame
= Frame
+ 1;
774 USB2_GetSMASK(IN PUSB2_TT_ENDPOINT TtEndpoint
)
781 if (TtEndpoint
->TtEndpointParams
.DeviceSpeed
== UsbHighSpeed
)
783 SMask
= (1 << TtEndpoint
->StartMicroframe
);
787 USB2_ConvertFrame(TtEndpoint
->StartFrame
,
788 TtEndpoint
->StartMicroframe
,
792 for (ix
= 0; ix
< TtEndpoint
->Nums
.NumStarts
; ix
++)
794 SMask
|= (1 << HcMicroFrame
);
804 USB2_GetCMASK(IN PUSB2_TT_ENDPOINT TtEndpoint
)
815 static const UCHAR CMASKS
[USB2_MICROFRAMES
] = {
816 0x1C, 0x38, 0x70, 0xE0, 0xC1, 0x83, 0x07, 0x0E
819 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
820 DeviceSpeed
= TtEndpoint
->TtEndpointParams
.DeviceSpeed
;
821 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
823 if (DeviceSpeed
== UsbHighSpeed
)
828 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
830 USB2_ConvertFrame(TtEndpoint
->StartFrame
,
831 TtEndpoint
->StartMicroframe
,
835 Result
= CMASKS
[HcMicroFrame
];
839 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
844 USB2_ConvertFrame(TtEndpoint
->StartFrame
,
845 TtEndpoint
->StartMicroframe
,
849 NumCompletes
= TtEndpoint
->Nums
.NumCompletes
;
851 for (MicroFrameCS
= HcMicroFrame
+ 2;
852 MicroFrameCS
< USB2_MICROFRAMES
;
855 MaskCS
|= (1 << MicroFrameCS
);
864 for (; NumCompletes
; NumCompletes
--)
866 MaskCS
|= (1 << (MicroFrameCS
- USB2_MICROFRAMES
));
877 USB2_RebalanceEndpoint(IN PDEVICE_OBJECT FdoDevice
,
880 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
881 PUSBPORT_REGISTRATION_PACKET Packet
;
882 PUSBPORT_ENDPOINT Endpoint
;
884 ULONG AllocedBusTime
;
885 ULONG EndpointBandwidth
;
887 ULONG ScheduleOffset
;
896 FdoExtension
= FdoDevice
->DeviceExtension
;
897 Packet
= &FdoExtension
->MiniPortInterface
->Packet
;
899 while (!IsListEmpty(List
))
901 Entry
= RemoveHeadList(List
);
903 Endpoint
= CONTAINING_RECORD(Entry
,
905 RebalanceLink
.Flink
);
907 DPRINT("USB2_RebalanceEndpoint: Endpoint - %p\n", Endpoint
);
909 Endpoint
->RebalanceLink
.Flink
= NULL
;
910 Endpoint
->RebalanceLink
.Blink
= NULL
;
912 KeAcquireSpinLock(&Endpoint
->EndpointSpinLock
,
913 &Endpoint
->EndpointOldIrql
);
915 SMask
= USB2_GetSMASK(Endpoint
->TtEndpoint
);
916 CMask
= USB2_GetCMASK(Endpoint
->TtEndpoint
);
918 ScheduleOffset
= Endpoint
->TtEndpoint
->StartFrame
;
919 NewPeriod
= Endpoint
->TtEndpoint
->ActualPeriod
;
921 AllocedBusTime
= Endpoint
->TtEndpoint
->CalcBusTime
;
922 EndpointBandwidth
= USB2_MICROFRAMES
* AllocedBusTime
;
924 Endpoint
->EndpointProperties
.InterruptScheduleMask
= SMask
;
925 Endpoint
->EndpointProperties
.SplitCompletionMask
= CMask
;
927 if (Endpoint
->EndpointProperties
.Period
!= NewPeriod
)
929 Factor
= USB2_FRAMES
/ Endpoint
->EndpointProperties
.Period
;
932 for (ix
= 0; ix
< Factor
; ix
++)
934 Bandwidth
= Endpoint
->EndpointProperties
.UsbBandwidth
;
935 n
= Factor
* Endpoint
->EndpointProperties
.ScheduleOffset
;
936 Endpoint
->TtExtension
->Bandwidth
[n
+ ix
] += Bandwidth
;
939 Endpoint
->EndpointProperties
.Period
= NewPeriod
;
940 Endpoint
->EndpointProperties
.ScheduleOffset
= ScheduleOffset
;
941 Endpoint
->EndpointProperties
.UsbBandwidth
= EndpointBandwidth
;
943 Factor
= USB2_FRAMES
/ NewPeriod
;
946 for (ix
= 0; ix
< Factor
; ix
++)
948 n
= Factor
* ScheduleOffset
;
949 Endpoint
->TtExtension
->Bandwidth
[n
+ ix
] += EndpointBandwidth
;
953 KeAcquireSpinLock(&FdoExtension
->MiniportSpinLock
, &OldIrql
);
955 Packet
->RebalanceEndpoint(FdoExtension
->MiniPortExt
,
956 &Endpoint
->EndpointProperties
,
957 (PVOID
)((ULONG_PTR
)Endpoint
+ sizeof(USBPORT_ENDPOINT
)));
959 KeReleaseSpinLock(&FdoExtension
->MiniportSpinLock
, OldIrql
);
961 KeReleaseSpinLock(&Endpoint
->EndpointSpinLock
,
962 Endpoint
->EndpointOldIrql
);
968 USB2_Rebalance(IN PDEVICE_OBJECT FdoDevice
,
969 IN PLIST_ENTRY RebalanceList
)
971 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
972 PUSBPORT_ENDPOINT Endpoint
;
974 LIST_ENTRY BalanceListInt1
;
975 LIST_ENTRY BalanceListInt2
;
977 ULONG ScheduleOffset
;
982 DPRINT("USB2_Rebalance: FdoDevice - %p, RebalanceList - %p\n",
986 InitializeListHead(&BalanceListInt1
);
987 InitializeListHead(&BalanceListInt2
);
989 while (!IsListEmpty(RebalanceList
))
991 Entry
= RebalanceList
->Flink
;
993 Endpoint
= CONTAINING_RECORD(Entry
,
995 RebalanceLink
.Flink
);
997 DPRINT("USBPORT_Rebalance: Entry - %p, Endpoint - %p\n",
1001 RemoveHeadList(RebalanceList
);
1002 Entry
->Flink
= NULL
;
1003 Entry
->Blink
= NULL
;
1005 SMask
= USB2_GetSMASK(Endpoint
->TtEndpoint
);
1006 CMask
= USB2_GetCMASK(Endpoint
->TtEndpoint
);
1008 ScheduleOffset
= Endpoint
->TtEndpoint
->StartFrame
;
1009 ActualPeriod
= Endpoint
->TtEndpoint
->ActualPeriod
;
1011 EndpointProperties
= &Endpoint
->EndpointProperties
;
1012 TransferType
= EndpointProperties
->TransferType
;
1014 switch (TransferType
)
1016 case USBPORT_TRANSFER_TYPE_ISOCHRONOUS
:
1017 DPRINT("USBPORT_Rebalance: USBPORT_TRANSFER_TYPE_ISOCHRONOUS. FIXME\n");
1021 case USBPORT_TRANSFER_TYPE_INTERRUPT
:
1022 if (SMask
!= EndpointProperties
->InterruptScheduleMask
||
1023 CMask
!= EndpointProperties
->SplitCompletionMask
||
1024 ScheduleOffset
!= EndpointProperties
->ScheduleOffset
||
1025 ActualPeriod
!= EndpointProperties
->Period
)
1027 if (ActualPeriod
== EndpointProperties
->Period
&&
1028 ScheduleOffset
== EndpointProperties
->ScheduleOffset
)
1030 InsertTailList(&BalanceListInt1
, Entry
);
1034 InsertTailList(&BalanceListInt2
, Entry
);
1045 USB2_RebalanceEndpoint(FdoDevice
, &BalanceListInt2
);
1046 USB2_RebalanceEndpoint(FdoDevice
, &BalanceListInt1
);
1047 //USB2_RebalanceEndpoint(FdoDevice, &BalanceListIso);
1052 USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint
,
1053 IN PUSB2_REBALANCE Rebalance
,
1054 IN PULONG RebalanceListEntries
,
1058 PUSB2_HC_EXTENSION HcExtension
;
1062 ULONG StartMicroframe
;
1064 PUSB2_TT_ENDPOINT endpoint
;
1065 PUSB2_TT_ENDPOINT nextEndpoint
;
1066 PUSB2_TT_ENDPOINT lastEndpoint
;
1067 PUSB2_TT_ENDPOINT tmpEndpoint
;
1076 BOOLEAN IsMoved
= FALSE
;
1078 DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint - %p, MaxFrames - %X, CalcBusTime - %X\n",
1081 TtEndpoint
->CalcBusTime
);
1083 if (TtEndpoint
->CalcBusTime
== 0)
1085 DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint not allocated!\n");
1089 Tt
= TtEndpoint
->Tt
;
1090 HcExtension
= Tt
->HcExtension
;
1092 Speed
= TtEndpoint
->TtEndpointParams
.DeviceSpeed
;
1093 DPRINT("USB2_DeallocateEndpointBudget: DeviceSpeed - %X\n", Speed
);
1095 StartMicroframe
= TtEndpoint
->StartFrame
* USB2_MICROFRAMES
+
1096 TtEndpoint
->StartMicroframe
;
1098 if (Speed
== UsbHighSpeed
)
1100 for (ix
= StartMicroframe
;
1101 ix
< USB2_MAX_MICROFRAMES
;
1102 ix
+= TtEndpoint
->ActualPeriod
)
1104 frame
= ix
/ USB2_MICROFRAMES
;
1105 uframe
= ix
% (USB2_MICROFRAMES
- 1);
1107 HcExtension
->TimeUsed
[frame
][uframe
] -= TtEndpoint
->CalcBusTime
;
1110 TtEndpoint
->CalcBusTime
= 0;
1112 DPRINT("USB2_DeallocateEndpointBudget: return TRUE\n");
1116 /* Speed != UsbHighSpeed (FS/LS) */
1118 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
1120 for (ix
= MaxFrames
, Frame
= (MaxFrames
- 1) - TtEndpoint
->StartFrame
;
1124 frame
= TtEndpoint
->StartFrame
+ Frame
;
1126 DPRINT("USB2_DeallocateEndpointBudget: frame - %X, Frame - %X, StartFrame - %X\n",
1129 TtEndpoint
->StartFrame
);
1131 if ((Frame
% TtEndpoint
->ActualPeriod
) == 0)
1133 USB2_DeallocateHS(TtEndpoint
, Frame
);
1134 Tt
->FrameBudget
[frame
].TimeUsed
-= TtEndpoint
->CalcBusTime
;
1137 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
1139 endpoint
= Tt
->FrameBudget
[frame
].IntEndpoint
;
1143 endpoint
= Tt
->FrameBudget
[frame
].IsoEndpoint
;
1146 nextEndpoint
= endpoint
->NextTtEndpoint
;
1148 DPRINT("USB2_DeallocateEndpointBudget: TtEndpoint - %p, nextEndpoint - %p\n",
1152 if (TtEndpoint
->CalcBusTime
> (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
1154 while (nextEndpoint
)
1156 endpoint
= nextEndpoint
;
1157 nextEndpoint
= nextEndpoint
->NextTtEndpoint
;
1160 nextEndpoint
= TtEndpoint
;
1162 DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
1168 while (nextEndpoint
&&
1169 !USB2_CheckTtEndpointInsert(nextEndpoint
, TtEndpoint
))
1171 endpoint
= nextEndpoint
;
1172 nextEndpoint
= nextEndpoint
->NextTtEndpoint
;
1175 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
&&
1178 DPRINT1("USB2_DeallocateEndpointBudget: Iso Ep UNIMPLEMENTED. FIXME\n");
1182 DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
1187 if ((Frame
% TtEndpoint
->ActualPeriod
) == 0)
1189 if (TtEndpoint
->CalcBusTime
> (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
1191 Tt
->FrameBudget
[frame
].AltEndpoint
= NULL
;
1193 else if (nextEndpoint
)
1195 nextEndpoint
= nextEndpoint
->NextTtEndpoint
;
1196 endpoint
->NextTtEndpoint
= nextEndpoint
;
1198 DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
1204 if (TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
1206 if (endpoint
== Tt
->FrameBudget
[frame
].IntEndpoint
)
1208 if (Tt
->FrameBudget
[frame
].IsoEndpoint
->NextTtEndpoint
)
1210 endpoint
= Tt
->FrameBudget
[frame
].IsoEndpoint
->NextTtEndpoint
;
1211 DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p\n", endpoint
);
1213 else if (Tt
->FrameBudget
[frame
].AltEndpoint
)
1215 endpoint
= Tt
->FrameBudget
[frame
].AltEndpoint
;
1216 DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p\n", endpoint
);
1222 DPRINT1("USB2_DeallocateEndpointBudget: Iso Ep UNIMPLEMENTED. FIXME\n");
1226 Period
= TtEndpoint
->ActualPeriod
;
1230 endpoint
= nextEndpoint
,
1231 nextEndpoint
= nextEndpoint
->NextTtEndpoint
)
1233 DPRINT("USB2_DeallocateEndpointBudget: endpoint - %p, nextEndpoint - %p\n",
1237 endTime
= endpoint
->StartTime
+ endpoint
->CalcBusTime
;
1238 maxEndTime
= endTime
;
1240 if (Period
> nextEndpoint
->ActualPeriod
||
1241 TtEndpoint
->StartFrame
!= nextEndpoint
->StartFrame
)
1243 if (USB2_CommonFrames(nextEndpoint
, TtEndpoint
))
1244 Factor
= Period
/ nextEndpoint
->ActualPeriod
;
1246 Factor
= USB2_FRAMES
/ nextEndpoint
->ActualPeriod
;
1248 maxEndTime
= endTime
;
1250 for (jx
= 0, frame
= nextEndpoint
->StartFrame
;
1252 jx
++, frame
+= nextEndpoint
->ActualPeriod
)
1254 if (nextEndpoint
->StartFrame
!= TtEndpoint
->StartFrame
)
1256 lastEndpoint
= Tt
->FrameBudget
[frame
].IntEndpoint
;
1258 if (Tt
->FrameBudget
[frame
].IsoEndpoint
->NextTtEndpoint
)
1260 lastEndpoint
= Tt
->FrameBudget
[frame
].IsoEndpoint
->NextTtEndpoint
;
1262 else if (Tt
->FrameBudget
[frame
].AltEndpoint
)
1264 lastEndpoint
= Tt
->FrameBudget
[frame
].AltEndpoint
;
1267 for (tmpEndpoint
= Tt
->FrameBudget
[frame
].IntEndpoint
->NextTtEndpoint
;
1268 tmpEndpoint
&& tmpEndpoint
!= nextEndpoint
;
1269 tmpEndpoint
= tmpEndpoint
->NextTtEndpoint
)
1271 lastEndpoint
= tmpEndpoint
;
1274 lastEndTime
= lastEndpoint
->StartTime
+ lastEndpoint
->CalcBusTime
;
1276 if (endTime
< (lastEndTime
- 1))
1278 maxEndTime
= lastEndTime
;
1279 endTime
= maxEndTime
;
1281 if (nextEndpoint
->StartTime
== maxEndTime
)
1286 maxEndTime
= endTime
;
1292 if (maxEndTime
>= nextEndpoint
->StartTime
)
1295 if (!USB2_MoveTtEndpoint(nextEndpoint
,
1296 maxEndTime
- nextEndpoint
->StartTime
,
1298 *RebalanceListEntries
,
1303 DPRINT("USB2_DeallocateEndpointBudget: Not moved!\n");
1309 if (Period
> nextEndpoint
->ActualPeriod
)
1310 Period
= nextEndpoint
->ActualPeriod
;
1314 TtEndpoint
->CalcBusTime
= 0;
1316 DPRINT("USB2_DeallocateEndpointBudget: return TRUE\n");
1322 USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
1323 IN PUSB2_REBALANCE Rebalance
,
1324 IN PULONG RebalanceListEntries
)
1327 PUSB2_HC_EXTENSION HcExtension
;
1338 PUSB2_TT_ENDPOINT prevEndpoint
;
1339 PUSB2_TT_ENDPOINT nextEndpoint
;
1340 PUSB2_TT_ENDPOINT IntEndpoint
;
1343 BOOLEAN Result
= TRUE
;
1345 DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p\n", TtEndpoint
);
1347 Tt
= TtEndpoint
->Tt
;
1348 HcExtension
= Tt
->HcExtension
;
1350 TtEndpoint
->Nums
.NumStarts
= 0;
1351 TtEndpoint
->Nums
.NumCompletes
= 0;
1353 TtEndpoint
->StartFrame
= 0;
1354 TtEndpoint
->StartMicroframe
= 0;
1356 if (TtEndpoint
->CalcBusTime
)
1358 DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint already allocated!\n");
1362 Speed
= TtEndpoint
->TtEndpointParams
.DeviceSpeed
;
1364 if (Speed
== UsbHighSpeed
)
1366 if (TtEndpoint
->Period
> USB2_MAX_MICROFRAMES
)
1367 TtEndpoint
->ActualPeriod
= USB2_MAX_MICROFRAMES
;
1369 TtEndpoint
->ActualPeriod
= TtEndpoint
->Period
;
1371 MinTimeUsed
= HcExtension
->TimeUsed
[0][0];
1373 for (ix
= 1; ix
< TtEndpoint
->ActualPeriod
; ix
++)
1375 frame
= ix
/ USB2_MICROFRAMES
;
1376 uframe
= ix
% (USB2_MICROFRAMES
- 1);
1378 TimeUsed
= HcExtension
->TimeUsed
[frame
][uframe
];
1380 if (TimeUsed
< MinTimeUsed
)
1382 MinTimeUsed
= TimeUsed
;
1383 TtEndpoint
->StartFrame
= frame
;
1384 TtEndpoint
->StartMicroframe
= uframe
;
1388 TtEndpoint
->CalcBusTime
= USB2_GetOverhead(TtEndpoint
) +
1389 USB2_AddDataBitStuff(TtEndpoint
->MaxPacketSize
);
1391 DPRINT("USB2_AllocateTimeForEndpoint: StartFrame - %X, StartMicroframe - %X, CalcBusTime - %X\n",
1392 TtEndpoint
->StartFrame
,
1393 TtEndpoint
->StartMicroframe
,
1394 TtEndpoint
->CalcBusTime
);
1396 Microframe
= TtEndpoint
->StartFrame
* USB2_MICROFRAMES
+
1397 TtEndpoint
->StartMicroframe
;
1399 if (Microframe
>= USB2_MAX_MICROFRAMES
)
1401 DPRINT("USB2_AllocateTimeForEndpoint: Microframe >= 256. Result - TRUE\n");
1405 for (ix
= Microframe
;
1406 ix
< USB2_MAX_MICROFRAMES
;
1407 ix
+= TtEndpoint
->ActualPeriod
)
1409 frame
= ix
/ USB2_MICROFRAMES
;
1410 uframe
= ix
% (USB2_MICROFRAMES
- 1);
1412 DPRINT("USB2_AllocateTimeForEndpoint: frame - %X, uframe - %X, TimeUsed[f][uf] - %X\n",
1415 HcExtension
->TimeUsed
[frame
][uframe
]);
1417 if (!USB2_AllocateCheck(&HcExtension
->TimeUsed
[frame
][uframe
],
1418 TtEndpoint
->CalcBusTime
,
1419 USB2_MAX_MICROFRAME_ALLOCATION
))
1421 DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n");
1428 for (ix
= Microframe
;
1429 ix
< USB2_MAX_MICROFRAMES
;
1430 ix
+= TtEndpoint
->ActualPeriod
)
1432 frame
= ix
/ USB2_MICROFRAMES
;
1433 uframe
= ix
% (USB2_MICROFRAMES
- 1);
1435 HcExtension
->TimeUsed
[frame
][uframe
] -= TtEndpoint
->CalcBusTime
;
1439 DPRINT("USB2_AllocateTimeForEndpoint: Result - TRUE\n");
1443 /* Speed != UsbHighSpeed (FS/LS) */
1445 if (TtEndpoint
->Period
> USB2_FRAMES
)
1446 TtEndpoint
->ActualPeriod
= USB2_FRAMES
;
1448 TtEndpoint
->ActualPeriod
= TtEndpoint
->Period
;
1450 MinTimeUsed
= Tt
->FrameBudget
[0].TimeUsed
;
1452 for (ix
= 1; ix
< TtEndpoint
->ActualPeriod
; ix
++)
1454 if ((Tt
->FrameBudget
[ix
].TimeUsed
) < MinTimeUsed
)
1456 MinTimeUsed
= Tt
->FrameBudget
[ix
].TimeUsed
;
1457 TtEndpoint
->StartFrame
= ix
;
1461 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
1463 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
1465 if (Speed
== UsbFullSpeed
)
1467 Overhead
= USB2_FS_ISOCHRONOUS_OVERHEAD
+ Tt
->DelayTime
;
1471 DPRINT("USB2_AllocateTimeForEndpoint: ISO can not be on a LS bus!\n");
1477 if (Speed
== UsbFullSpeed
)
1478 Overhead
= USB2_FS_INTERRUPT_OVERHEAD
+ Tt
->DelayTime
;
1480 Overhead
= USB2_LS_INTERRUPT_OVERHEAD
+ Tt
->DelayTime
;
1483 if (Speed
== UsbLowSpeed
)
1485 TtEndpoint
->CalcBusTime
= TtEndpoint
->MaxPacketSize
* 8 + Overhead
;
1489 TtEndpoint
->CalcBusTime
= TtEndpoint
->MaxPacketSize
+ Overhead
;
1492 LatestStart
= USB2_HUB_DELAY
+ USB2_FS_SOF_TIME
;
1495 (TtEndpoint
->StartFrame
+ ix
) < USB2_FRAMES
;
1496 ix
+= TtEndpoint
->ActualPeriod
)
1498 frame
= TtEndpoint
->StartFrame
+ ix
;
1500 if (Tt
->FrameBudget
[frame
].AltEndpoint
&&
1501 TtEndpoint
->CalcBusTime
>= (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
1503 DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n");
1507 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
1508 prevEndpoint
= Tt
->FrameBudget
[frame
].IsoEndpoint
;
1510 prevEndpoint
= Tt
->FrameBudget
[frame
].IntEndpoint
;
1512 for (nextEndpoint
= prevEndpoint
->NextTtEndpoint
;
1514 nextEndpoint
= nextEndpoint
->NextTtEndpoint
)
1516 if (USB2_CheckTtEndpointInsert(nextEndpoint
, TtEndpoint
))
1521 prevEndpoint
= nextEndpoint
;
1524 StartTime
= USB2_GetStartTime(nextEndpoint
,
1529 if (StartTime
> LatestStart
)
1530 LatestStart
= StartTime
;
1533 TtEndpoint
->StartTime
= LatestStart
;
1535 if ((LatestStart
+ TtEndpoint
->CalcBusTime
) > USB2_FS_MAX_PERIODIC_ALLOCATION
)
1537 TtEndpoint
->CalcBusTime
= 0;
1538 DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n");
1542 for (ix
= 0, frame
= -TtEndpoint
->StartFrame
;
1546 DPRINT("USB2_AllocateTimeForEndpoint: ix - %X, frame - %X, StartFrame - %X\n",
1549 TtEndpoint
->StartFrame
);
1551 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
1553 DPRINT1("USB2_AllocateTimeForEndpoint: Iso Ep UNIMPLEMENTED. FIXME\n");
1558 IntEndpoint
= Tt
->FrameBudget
[ix
].IntEndpoint
;
1559 nextEndpoint
= IntEndpoint
->NextTtEndpoint
;
1561 for (nextEndpoint
= IntEndpoint
->NextTtEndpoint
;
1563 nextEndpoint
= nextEndpoint
->NextTtEndpoint
)
1565 if (USB2_CheckTtEndpointInsert(nextEndpoint
, TtEndpoint
))
1567 IntEndpoint
= nextEndpoint
;
1570 if ((frame
% TtEndpoint
->ActualPeriod
) == 0)
1578 calcBusTime
= LatestStart
+ TtEndpoint
->CalcBusTime
-
1579 nextEndpoint
->StartTime
;
1583 calcBusTime
= TtEndpoint
->CalcBusTime
;
1586 if (calcBusTime
> 0)
1588 TimeUsed
= Tt
->FrameBudget
[ix
].TimeUsed
;
1590 if (!USB2_AllocateCheck(&TimeUsed
,
1592 USB2_FS_MAX_PERIODIC_ALLOCATION
))
1594 DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n");
1600 if (nextEndpoint
!= TtEndpoint
)
1602 if ((frame
% TtEndpoint
->ActualPeriod
) == 0)
1606 DPRINT("USB2_AllocateTimeForEndpoint: frame == 0\n");
1607 TtEndpoint
->NextTtEndpoint
= nextEndpoint
;
1610 IntEndpoint
->NextTtEndpoint
= TtEndpoint
;
1612 DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p, nextEndpoint - %p\n",
1617 if (calcBusTime
> 0)
1622 DPRINT("USB2_AllocateTimeForEndpoint: nextEndpoint - %p, calcBusTime - %X\n",
1628 nextEndpoint
= nextEndpoint
->NextTtEndpoint
)
1630 MoveResult
= USB2_MoveTtEndpoint(nextEndpoint
,
1633 *RebalanceListEntries
,
1638 DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n");
1649 if ((frame
% TtEndpoint
->ActualPeriod
) == 0)
1651 if (!USB2_AllocateHS(TtEndpoint
, frame
))
1653 DPRINT1("USB2_AllocateTimeForEndpoint: USB2_AllocateHS return FALSE\n");
1657 Tt
->FrameBudget
[ix
].TimeUsed
+= TtEndpoint
->CalcBusTime
;
1660 if (Result
== FALSE
)
1662 USB2_DeallocateEndpointBudget(TtEndpoint
,
1664 RebalanceListEntries
,
1667 DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n");
1672 DPRINT("USB2_AllocateTimeForEndpoint: Result - %X\n", Result
);
1678 USB2_ChangePeriod(IN PUSB2_TT_ENDPOINT TtEndpoint
,
1679 IN PUSB2_REBALANCE Rebalance
,
1680 IN PULONG RebalanceListEntries
)
1684 DPRINT("USB2_ChangePeriod: RebalanceListEntries - %X\n",
1685 *RebalanceListEntries
);
1687 USB2_DeallocateEndpointBudget(TtEndpoint
,
1689 RebalanceListEntries
,
1692 TtEndpoint
->PreviosPeriod
= TtEndpoint
->Period
;
1693 TtEndpoint
->Period
= ENDPOINT_INTERRUPT_1ms
;
1695 Result
= USB2_AllocateTimeForEndpoint(TtEndpoint
,
1697 RebalanceListEntries
);
1704 USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint
,
1705 IN PUSB2_REBALANCE Rebalance
,
1706 IN PULONG RebalanceListEntries
)
1708 PUSB2_TT_ENDPOINT ttEndpoint
;
1712 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
1714 if (TtEndpoint
->ActualPeriod
!= ENDPOINT_INTERRUPT_1ms
&&
1715 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
&&
1716 (CHAR
)TtEndpoint
->StartMicroframe
> 2 &&
1717 !USB2_ChangePeriod(TtEndpoint
, Rebalance
, RebalanceListEntries
))
1719 DPRINT("USB2_PromotePeriods: return FALSE\n");
1723 if (Rebalance
->RebalanceEndpoint
[0] == NULL
)
1725 DPRINT("USB2_PromotePeriods: return TRUE\n");
1729 DPRINT("USB2_PromotePeriods: RebalanceListEntries - %X\n",
1730 *RebalanceListEntries
);
1732 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
1734 Rebalance
->RebalanceEndpoint
[ix
]->IsPromoted
= FALSE
;
1737 for (ix
= 0; ; ix
++)
1739 ttEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
1740 TransferType
= ttEndpoint
->TtEndpointParams
.TransferType
;
1742 if (ttEndpoint
->ActualPeriod
!= ENDPOINT_INTERRUPT_1ms
&&
1743 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
&&
1744 ttEndpoint
->StartMicroframe
> 2)
1746 USB2_DeallocateEndpointBudget(ttEndpoint
,
1748 RebalanceListEntries
,
1751 ttEndpoint
->IsPromoted
= TRUE
;
1752 ttEndpoint
->PreviosPeriod
= ttEndpoint
->Period
;
1753 ttEndpoint
->Period
= ENDPOINT_INTERRUPT_1ms
;
1755 if (!USB2_AllocateTimeForEndpoint(ttEndpoint
,
1757 RebalanceListEntries
))
1763 if (Rebalance
->RebalanceEndpoint
[ix
+ 1] == NULL
)
1765 DPRINT("USB2_PromotePeriods: return TRUE\n");
1770 USB2_DeallocateEndpointBudget(TtEndpoint
,
1772 RebalanceListEntries
,
1775 TtEndpoint
->Period
= TtEndpoint
->PreviosPeriod
;
1776 TtEndpoint
->PreviosPeriod
= 0;
1778 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
1780 ttEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
1782 if (ttEndpoint
->IsPromoted
)
1784 if (ttEndpoint
->CalcBusTime
)
1786 USB2_DeallocateEndpointBudget(ttEndpoint
,
1788 RebalanceListEntries
,
1792 TtEndpoint
->Period
= TtEndpoint
->PreviosPeriod
;
1793 TtEndpoint
->PreviosPeriod
= 0;
1795 USB2_AllocateTimeForEndpoint(ttEndpoint
,
1797 RebalanceListEntries
);
1801 DPRINT("USB2_PromotePeriods: return FALSE\n");
1807 USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension
)
1810 ULONG NewBusBandwidth
;
1811 ULONG MaxBusBandwidth
= 0;
1812 ULONG MinBusBandwidth
;
1815 DPRINT("USBPORT_UpdateAllocatedBwTt: TtExtension - %p\n", TtExtension
);
1817 BusBandwidth
= TtExtension
->BusBandwidth
;
1818 MinBusBandwidth
= BusBandwidth
;
1820 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
1822 NewBusBandwidth
= BusBandwidth
- TtExtension
->Bandwidth
[ix
];
1824 MaxBusBandwidth
= max(MaxBusBandwidth
, NewBusBandwidth
);
1825 MinBusBandwidth
= min(MinBusBandwidth
, NewBusBandwidth
);
1828 TtExtension
->MaxBandwidth
= MaxBusBandwidth
;
1830 if (MinBusBandwidth
== BusBandwidth
)
1831 TtExtension
->MinBandwidth
= 0;
1833 TtExtension
->MinBandwidth
= MinBusBandwidth
;
1838 USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
1839 IN PUSBPORT_ENDPOINT Endpoint
)
1841 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
1842 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
1843 PUSB2_TT_EXTENSION TtExtension
;
1845 PUSB2_REBALANCE Rebalance
;
1846 LIST_ENTRY RebalanceList
;
1847 ULONG RebalanceListEntries
;
1848 PUSB2_TT_ENDPOINT TtEndpoint
;
1849 PUSB2_TT_ENDPOINT RebalanceTtEndpoint
;
1851 USB_DEVICE_SPEED DeviceSpeed
;
1853 ULONG AllocedBusTime
;
1854 ULONG EndpointBandwidth
;
1855 ULONG ScheduleOffset
;
1865 DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n",
1869 EndpointProperties
= &Endpoint
->EndpointProperties
;
1870 EndpointProperties
->ScheduleOffset
= 0;
1872 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
1874 DPRINT("USBPORT_AllocateBandwidthUSB2: ENDPOINT_FLAG_ROOTHUB_EP0\n");
1878 FdoExtension
= FdoDevice
->DeviceExtension
;
1880 TransferType
= EndpointProperties
->TransferType
;
1881 DPRINT("USBPORT_AllocateBandwidthUSB2: TransferType - %X\n", TransferType
);
1883 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
1884 TransferType
== USBPORT_TRANSFER_TYPE_BULK
)
1889 if (Endpoint
->TtExtension
)
1890 TtExtension
= Endpoint
->TtExtension
;
1894 InitializeListHead(&RebalanceList
);
1896 Rebalance
= ExAllocatePoolWithTag(NonPagedPool
,
1897 sizeof(USB2_REBALANCE
),
1900 DPRINT("USBPORT_AllocateBandwidthUSB2: Rebalance - %p, TtExtension - %p\n",
1906 RtlZeroMemory(Rebalance
, sizeof(USB2_REBALANCE
));
1908 TtEndpoint
= Endpoint
->TtEndpoint
;
1909 TtEndpoint
->Endpoint
= Endpoint
;
1911 Direction
= EndpointProperties
->Direction
== USBPORT_TRANSFER_DIRECTION_OUT
;
1912 DeviceSpeed
= EndpointProperties
->DeviceSpeed
;
1914 switch (DeviceSpeed
)
1919 Tt
= &TtExtension
->Tt
;
1921 Period
= USB2_FRAMES
;
1923 while (Period
> 0 && Period
> EndpointProperties
->Period
)
1928 DPRINT("USBPORT_AllocateBandwidthUSB2: Period - %X\n", Period
);
1934 Tt
= &FdoExtension
->Usb2Extension
->HcTt
;
1936 if (EndpointProperties
->Period
> USB2_MAX_MICROFRAMES
)
1937 Period
= USB2_MAX_MICROFRAMES
;
1939 Period
= EndpointProperties
->Period
;
1946 DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n",
1951 Tt
= &TtExtension
->Tt
;
1956 USB2_InitTtEndpoint(TtEndpoint
,
1961 EndpointProperties
->MaxPacketSize
,
1964 RebalanceListEntries
= USB2_FRAMES
- 2;
1966 Result
= USB2_AllocateTimeForEndpoint(TtEndpoint
,
1968 &RebalanceListEntries
);
1972 Result
= USB2_PromotePeriods(TtEndpoint
,
1974 &RebalanceListEntries
);
1977 RebalanceListEntries
= 0;
1979 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
1981 RebalanceListEntries
= ix
+ 1;
1986 RebalanceListEntries
= 0;
1990 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceListEntries - %X, Result - %X\n",
1991 RebalanceListEntries
,
1994 for (ix
= 0; ix
< RebalanceListEntries
; ix
++)
1996 RebalanceTtEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
1998 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceTtEndpoint[%X] - %p, RebalanceTtEndpoint - %p, RebalanceLink - %p\n",
2000 RebalanceTtEndpoint
,
2001 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
2003 InsertTailList(&RebalanceList
,
2004 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
2008 ExFreePoolWithTag(Rebalance
, USB_PORT_TAG
);
2012 SMask
= USB2_GetSMASK(Endpoint
->TtEndpoint
);
2013 EndpointProperties
->InterruptScheduleMask
= SMask
;
2015 CMask
= USB2_GetCMASK(Endpoint
->TtEndpoint
);
2016 EndpointProperties
->SplitCompletionMask
= CMask
;
2018 AllocedBusTime
= TtEndpoint
->CalcBusTime
;
2020 EndpointBandwidth
= USB2_MICROFRAMES
* AllocedBusTime
;
2021 EndpointProperties
->UsbBandwidth
= EndpointBandwidth
;
2023 ActualPeriod
= Endpoint
->TtEndpoint
->ActualPeriod
;
2024 EndpointProperties
->Period
= ActualPeriod
;
2026 ScheduleOffset
= Endpoint
->TtEndpoint
->StartFrame
;
2027 EndpointProperties
->ScheduleOffset
= ScheduleOffset
;
2029 Factor
= USB2_FRAMES
/ ActualPeriod
;
2032 n
= ScheduleOffset
* Factor
;
2036 for (ix
= 0; ix
< Factor
; ix
++)
2038 TtExtension
->Bandwidth
[n
+ ix
] -= EndpointBandwidth
;
2043 for (ix
= 1; ix
< Factor
; ix
++)
2045 FdoExtension
->Bandwidth
[n
+ ix
] -= EndpointBandwidth
;
2049 USBPORT_DumpingEndpointProperties(EndpointProperties
);
2050 USBPORT_DumpingTtEndpoint(Endpoint
->TtEndpoint
);
2052 if (AllocedBusTime
>= (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
2054 DPRINT1("USBPORT_AllocateBandwidthUSB2: AllocedBusTime >= 0.5 * MAX_ALLOCATION \n");
2058 USB2_Rebalance(FdoDevice
, &RebalanceList
);
2062 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
2066 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2068 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
2071 USBPORT_UpdateAllocatedBwTt(TtExtension
);
2073 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2075 FdoExtension
->Bandwidth
[ix
] -= TtExtension
->MaxBandwidth
;
2078 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
2085 USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
2086 IN PUSBPORT_ENDPOINT Endpoint
)
2088 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
2090 ULONG ScheduleOffset
;
2091 ULONG EndpointBandwidth
;
2092 LIST_ENTRY RebalanceList
;
2094 PUSB2_REBALANCE Rebalance
;
2095 ULONG RebalanceListEntries
;
2099 PUSB2_TT_EXTENSION TtExtension
;
2100 PUSB2_TT_ENDPOINT RebalanceTtEndpoint
;
2102 DPRINT("USBPORT_FreeBandwidthUSB2: Endpoint - %p\n", Endpoint
);
2104 FdoExtension
= FdoDevice
->DeviceExtension
;
2106 Period
= Endpoint
->EndpointProperties
.Period
;
2107 ASSERT(Period
!= 0);
2109 ScheduleOffset
= Endpoint
->EndpointProperties
.ScheduleOffset
;
2110 EndpointBandwidth
= Endpoint
->EndpointProperties
.UsbBandwidth
;
2112 InitializeListHead(&RebalanceList
);
2114 TransferType
= Endpoint
->EndpointProperties
.TransferType
;
2116 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
2117 TransferType
== USBPORT_TRANSFER_TYPE_BULK
||
2118 (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
))
2123 Rebalance
= ExAllocatePoolWithTag(NonPagedPool
,
2124 sizeof(USB2_REBALANCE
),
2129 DPRINT1("USBPORT_FreeBandwidthUSB2: Rebalance == NULL!\n");
2133 RtlZeroMemory(Rebalance
, sizeof(USB2_REBALANCE
));
2135 Factor
= USB2_FRAMES
/ Period
;
2136 n
= ScheduleOffset
* Factor
;
2138 TtExtension
= Endpoint
->TtExtension
;
2142 for (ix
= 0; ix
< Factor
; ix
++)
2144 TtExtension
->Bandwidth
[n
+ ix
] += EndpointBandwidth
;
2149 for (ix
= 1; ix
< Factor
; ix
++)
2151 FdoExtension
->Bandwidth
[n
+ ix
] += EndpointBandwidth
;
2155 RebalanceListEntries
= USB2_FRAMES
- 2;
2157 USB2_DeallocateEndpointBudget(Endpoint
->TtEndpoint
,
2159 &RebalanceListEntries
,
2162 RebalanceListEntries
= 0;
2164 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
2166 RebalanceListEntries
= ix
+ 1;
2169 for (ix
= 0; ix
< RebalanceListEntries
; ix
++)
2171 RebalanceTtEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
2173 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceTtEndpoint[%X] - %p, RebalanceTtEndpoint - %p, RebalanceLink - %p\n",
2175 RebalanceTtEndpoint
,
2176 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
2178 InsertTailList(&RebalanceList
,
2179 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
2182 ExFreePoolWithTag(Rebalance
, USB_PORT_TAG
);
2184 USB2_Rebalance(FdoDevice
, &RebalanceList
);
2191 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2193 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
2196 USBPORT_UpdateAllocatedBwTt(TtExtension
);
2198 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2200 FdoExtension
->Bandwidth
[ix
] -= TtExtension
->MaxBandwidth
;
2203 DPRINT1("USBPORT_FreeBandwidthUSB2: exit\n");
2208 USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension
,
2214 DPRINT("USB2_InitTT: HcExtension - %p, Tt - %p\n", HcExtension
, Tt
);
2216 Tt
->HcExtension
= HcExtension
;
2218 Tt
->MaxTime
= USB2_FS_MAX_PERIODIC_ALLOCATION
;
2220 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2222 Tt
->FrameBudget
[ix
].TimeUsed
= USB2_MAX_MICROFRAMES
;
2223 Tt
->FrameBudget
[ix
].AltEndpoint
= NULL
;
2225 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
2227 Tt
->TimeCS
[ix
][jx
] = 0;
2228 Tt
->NumStartSplits
[ix
][jx
] = 0;
2231 Tt
->FrameBudget
[ix
].IsoEndpoint
= &Tt
->IsoEndpoint
[ix
];
2233 USB2_InitTtEndpoint(&Tt
->IsoEndpoint
[ix
],
2234 USBPORT_TRANSFER_TYPE_ISOCHRONOUS
,
2235 USBPORT_TRANSFER_DIRECTION_OUT
,
2241 Tt
->IsoEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
2242 Tt
->IsoEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
2243 Tt
->IsoEndpoint
[ix
].StartFrame
= ix
;
2244 Tt
->IsoEndpoint
[ix
].StartMicroframe
= 0xFF;
2246 Tt
->FrameBudget
[ix
].IntEndpoint
= &Tt
->IntEndpoint
[ix
];
2248 USB2_InitTtEndpoint(&Tt
->IntEndpoint
[ix
],
2249 USBPORT_TRANSFER_TYPE_INTERRUPT
,
2250 USBPORT_TRANSFER_DIRECTION_OUT
,
2256 Tt
->IntEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
2257 Tt
->IntEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
2258 Tt
->IntEndpoint
[ix
].StartFrame
= ix
;
2259 Tt
->IntEndpoint
[ix
].StartMicroframe
= 0xFF;
2265 USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension
)
2270 DPRINT("USB2_InitController: HcExtension - %p\n", HcExtension
);
2272 HcExtension
->MaxHsBusAllocation
= USB2_MAX_MICROFRAME_ALLOCATION
;
2274 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
2276 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
2278 HcExtension
->TimeUsed
[ix
][jx
] = 0;
2282 HcExtension
->HcDelayTime
= USB2_CONTROLLER_DELAY
;
2284 USB2_InitTT(HcExtension
, &HcExtension
->HcTt
);