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_GetLastIsoTime(IN PUSB2_TT_ENDPOINT TtEndpoint
,
167 PUSB2_TT_ENDPOINT nextTtEndpoint
;
170 DPRINT("USB2_GetLastIsoTime: TtEndpoint - %p, Frame - %X\n",
174 nextTtEndpoint
= TtEndpoint
->Tt
->FrameBudget
[Frame
].IsoEndpoint
->NextTtEndpoint
;
176 if (nextTtEndpoint
||
177 (nextTtEndpoint
= TtEndpoint
->Tt
->FrameBudget
[Frame
].AltEndpoint
) != NULL
)
179 Result
= nextTtEndpoint
->StartTime
+ nextTtEndpoint
->CalcBusTime
;
183 Result
= USB2_FS_SOF_TIME
;
191 USB2_GetStartTime(IN PUSB2_TT_ENDPOINT nextTtEndpoint
,
192 IN PUSB2_TT_ENDPOINT TtEndpoint
,
193 IN PUSB2_TT_ENDPOINT prevTtEndpoint
,
196 PUSB2_TT_ENDPOINT ttEndpoint
;
199 DPRINT("USB2_GetStartTime: nextTtEndpoint - %p, TtEndpoint - %p, prevTtEndpoint - %p, Frame - %X\n",
205 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
207 if (nextTtEndpoint
&& TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
209 return nextTtEndpoint
->StartTime
+ nextTtEndpoint
->CalcBusTime
;
212 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
214 ttEndpoint
= TtEndpoint
->Tt
->FrameBudget
[Frame
].AltEndpoint
;
217 return ttEndpoint
->StartTime
+ ttEndpoint
->CalcBusTime
;
219 return USB2_FS_SOF_TIME
;
223 ttEndpoint
= prevTtEndpoint
;
225 if (ttEndpoint
== TtEndpoint
->Tt
->FrameBudget
[Frame
].IntEndpoint
)
226 return USB2_GetLastIsoTime(TtEndpoint
, Frame
);
228 return ttEndpoint
->StartTime
+ ttEndpoint
->CalcBusTime
;
234 USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
235 IN UCHAR TransferType
,
237 IN UCHAR DeviceSpeed
,
239 IN USHORT MaxPacketSize
,
242 RtlZeroMemory(TtEndpoint
, sizeof(USB2_TT_ENDPOINT
));
244 TtEndpoint
->TtEndpointParams
.TransferType
= TransferType
;
245 TtEndpoint
->TtEndpointParams
.Direction
= Direction
;
246 TtEndpoint
->TtEndpointParams
.DeviceSpeed
= DeviceSpeed
;
248 TtEndpoint
->Period
= Period
;
249 TtEndpoint
->MaxPacketSize
= MaxPacketSize
;
255 USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
256 IN PUSB2_REBALANCE Rebalance
,
257 IN PULONG RebalanceListEntries
)
259 DPRINT("USB2_AllocateTimeForEndpoint: UNIMPLEMENTED. FIXME\n");
266 USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint
,
267 IN PUSB2_REBALANCE Rebalance
,
268 IN PULONG RebalanceListEntries
)
270 DPRINT1("USB2_PromotePeriods: UNIMPLEMENTED. FIXME\n");
277 USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension
)
280 ULONG NewBusBandwidth
;
281 ULONG MaxBusBandwidth
= 0;
282 ULONG MinBusBandwidth
;
285 DPRINT("USBPORT_UpdateAllocatedBwTt: TtExtension - %p\n", TtExtension
);
287 BusBandwidth
= TtExtension
->BusBandwidth
;
288 MinBusBandwidth
= BusBandwidth
;
290 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
292 NewBusBandwidth
= BusBandwidth
- TtExtension
->Bandwidth
[ix
];
294 if (NewBusBandwidth
> MaxBusBandwidth
)
295 MaxBusBandwidth
= NewBusBandwidth
;
297 if (NewBusBandwidth
< MinBusBandwidth
)
298 MinBusBandwidth
= NewBusBandwidth
;
301 TtExtension
->MaxBandwidth
= MaxBusBandwidth
;
303 if (MinBusBandwidth
== BusBandwidth
)
304 TtExtension
->MinBandwidth
= 0;
306 TtExtension
->MinBandwidth
= MinBusBandwidth
;
311 USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
312 IN PUSBPORT_ENDPOINT Endpoint
)
314 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
315 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
316 PUSB2_TT_EXTENSION TtExtension
;
318 PUSB2_REBALANCE Rebalance
;
319 LIST_ENTRY RebalanceList
;
320 ULONG RebalanceListEntries
;
321 PUSB2_TT_ENDPOINT TtEndpoint
;
322 PUSB2_TT_ENDPOINT RebalanceTtEndpoint
;
325 USB_DEVICE_SPEED DeviceSpeed
;
332 DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n",
336 EndpointProperties
= &Endpoint
->EndpointProperties
;
337 EndpointProperties
->ScheduleOffset
= 0;
339 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
341 DPRINT("USBPORT_AllocateBandwidthUSB2: ENDPOINT_FLAG_ROOTHUB_EP0\n");
345 FdoExtension
= FdoDevice
->DeviceExtension
;
347 TransferType
= EndpointProperties
->TransferType
;
348 DPRINT("USBPORT_AllocateBandwidthUSB2: TransferType - %X\n", TransferType
);
350 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
351 TransferType
== USBPORT_TRANSFER_TYPE_BULK
)
356 if (Endpoint
->TtExtension
)
357 TtExtension
= Endpoint
->TtExtension
;
361 InitializeListHead(&RebalanceList
);
363 Rebalance
= ExAllocatePoolWithTag(NonPagedPool
,
364 sizeof(USB2_REBALANCE
),
367 DPRINT("USBPORT_AllocateBandwidthUSB2: Rebalance - %p, TtExtension - %p\n",
373 RtlZeroMemory(Rebalance
, sizeof(USB2_REBALANCE
));
375 TtEndpoint
= Endpoint
->TtEndpoint
;
376 TtEndpoint
->Endpoint
= Endpoint
;
378 Direction
= EndpointProperties
->Direction
== USBPORT_TRANSFER_DIRECTION_OUT
;
379 DeviceSpeed
= EndpointProperties
->DeviceSpeed
;
386 Tt
= &TtExtension
->Tt
;
387 Period
= USB2_FRAMES
;
389 while (Period
&& Period
> EndpointProperties
->Period
);
394 DPRINT("USBPORT_AllocateBandwidthUSB2: Period - %X\n", Period
);
400 Tt
= &FdoExtension
->Usb2Extension
->HcTt
;
401 Period
= EndpointProperties
->Period
;
403 if (EndpointProperties
->Period
> USB2_MAX_MICROFRAMES
)
404 Period
= USB2_MAX_MICROFRAMES
;
411 DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n", DeviceSpeed
);
413 Tt
= &TtExtension
->Tt
;
418 USB2_InitTtEndpoint(TtEndpoint
,
423 EndpointProperties
->MaxPacketSize
,
426 RebalanceListEntries
= USB2_FRAMES
- 2;
428 Result
= USB2_AllocateTimeForEndpoint(TtEndpoint
,
430 &RebalanceListEntries
);
434 Result
= USB2_PromotePeriods(TtEndpoint
,
436 &RebalanceListEntries
);
439 RebalanceListEntries
= 0;
441 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
443 RebalanceListEntries
= ix
+ 1;
448 RebalanceListEntries
= 0;
452 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceListEntries - %X, Result - %X\n",
453 RebalanceListEntries
,
456 for (ix
= 0; ix
< RebalanceListEntries
; ix
++)
458 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceEndpoint[%X] - %X\n",
460 Rebalance
->RebalanceEndpoint
[ix
]);
462 RebalanceTtEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
464 InsertTailList(&RebalanceList
,
465 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
469 ExFreePool(Rebalance
);
473 DPRINT1("USBPORT_AllocateBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
477 //USB2_Rebalance(FdoDevice, &RebalanceList);
481 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
485 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
487 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
490 USBPORT_UpdateAllocatedBwTt(TtExtension
);
492 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
494 FdoExtension
->Bandwidth
[ix
] -= TtExtension
->MaxBandwidth
;
497 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
504 USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
505 IN PUSBPORT_ENDPOINT Endpoint
)
507 DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
512 USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension
,
518 DPRINT("USB2_InitTT: HcExtension - %p, Tt - %p\n", HcExtension
, Tt
);
520 Tt
->HcExtension
= HcExtension
;
522 Tt
->MaxTime
= USB2_FS_MAX_PERIODIC_ALLOCATION
;
524 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
526 Tt
->FrameBudget
[ix
].TimeUsed
= USB2_MAX_MICROFRAMES
;
527 Tt
->FrameBudget
[ix
].AltEndpoint
= NULL
;
529 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
531 Tt
->TimeCS
[ix
][jx
] = 0;
532 Tt
->NumStartSplits
[ix
][jx
] = 0;
535 Tt
->FrameBudget
[ix
].IsoEndpoint
= &Tt
->IsoEndpoint
[ix
];
537 USB2_InitTtEndpoint(&Tt
->IsoEndpoint
[ix
],
538 USBPORT_TRANSFER_TYPE_ISOCHRONOUS
,
539 USBPORT_TRANSFER_DIRECTION_OUT
,
545 Tt
->IsoEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
546 Tt
->IsoEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
547 Tt
->IsoEndpoint
[ix
].StartFrame
= ix
;
548 Tt
->IsoEndpoint
[ix
].StartMicroframe
= 0xFF;
550 Tt
->FrameBudget
[ix
].IntEndpoint
= &Tt
->IntEndpoint
[ix
];
552 USB2_InitTtEndpoint(&Tt
->IntEndpoint
[ix
],
553 USBPORT_TRANSFER_TYPE_INTERRUPT
,
554 USBPORT_TRANSFER_DIRECTION_OUT
,
560 Tt
->IntEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
561 Tt
->IntEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
562 Tt
->IntEndpoint
[ix
].StartFrame
= ix
;
563 Tt
->IntEndpoint
[ix
].StartMicroframe
= 0xFF;
569 USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension
)
574 DPRINT("USB2_InitController: HcExtension - %p\n", HcExtension
);
576 HcExtension
->MaxHsBusAllocation
= USB2_MAX_MICROFRAME_ALLOCATION
;
578 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
580 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
582 HcExtension
->TimeUsed
[ix
][jx
] = 0;
586 HcExtension
->HcDelayTime
= USB2_CONTROLLER_DELAY
;
588 USB2_InitTT(HcExtension
, &HcExtension
->HcTt
);