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_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint
,
258 DPRINT("USB2_AllocateHS: UNIMPLEMENTED FIXME\n");
264 USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint
,
265 IN PUSB2_REBALANCE Rebalance
,
266 IN PULONG RebalanceListEntries
,
269 DPRINT("USB2_DeallocateEndpointBudget: UNIMPLEMENTED FIXME\n");
276 USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
277 IN PUSB2_REBALANCE Rebalance
,
278 IN PULONG RebalanceListEntries
)
280 DPRINT("USB2_AllocateTimeForEndpoint: UNIMPLEMENTED. FIXME\n");
287 USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint
,
288 IN PUSB2_REBALANCE Rebalance
,
289 IN PULONG RebalanceListEntries
)
291 DPRINT1("USB2_PromotePeriods: UNIMPLEMENTED. FIXME\n");
298 USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension
)
301 ULONG NewBusBandwidth
;
302 ULONG MaxBusBandwidth
= 0;
303 ULONG MinBusBandwidth
;
306 DPRINT("USBPORT_UpdateAllocatedBwTt: TtExtension - %p\n", TtExtension
);
308 BusBandwidth
= TtExtension
->BusBandwidth
;
309 MinBusBandwidth
= BusBandwidth
;
311 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
313 NewBusBandwidth
= BusBandwidth
- TtExtension
->Bandwidth
[ix
];
315 if (NewBusBandwidth
> MaxBusBandwidth
)
316 MaxBusBandwidth
= NewBusBandwidth
;
318 if (NewBusBandwidth
< MinBusBandwidth
)
319 MinBusBandwidth
= NewBusBandwidth
;
322 TtExtension
->MaxBandwidth
= MaxBusBandwidth
;
324 if (MinBusBandwidth
== BusBandwidth
)
325 TtExtension
->MinBandwidth
= 0;
327 TtExtension
->MinBandwidth
= MinBusBandwidth
;
332 USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
333 IN PUSBPORT_ENDPOINT Endpoint
)
335 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
336 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
337 PUSB2_TT_EXTENSION TtExtension
;
339 PUSB2_REBALANCE Rebalance
;
340 LIST_ENTRY RebalanceList
;
341 ULONG RebalanceListEntries
;
342 PUSB2_TT_ENDPOINT TtEndpoint
;
343 PUSB2_TT_ENDPOINT RebalanceTtEndpoint
;
346 USB_DEVICE_SPEED DeviceSpeed
;
353 DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n",
357 EndpointProperties
= &Endpoint
->EndpointProperties
;
358 EndpointProperties
->ScheduleOffset
= 0;
360 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
362 DPRINT("USBPORT_AllocateBandwidthUSB2: ENDPOINT_FLAG_ROOTHUB_EP0\n");
366 FdoExtension
= FdoDevice
->DeviceExtension
;
368 TransferType
= EndpointProperties
->TransferType
;
369 DPRINT("USBPORT_AllocateBandwidthUSB2: TransferType - %X\n", TransferType
);
371 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
372 TransferType
== USBPORT_TRANSFER_TYPE_BULK
)
377 if (Endpoint
->TtExtension
)
378 TtExtension
= Endpoint
->TtExtension
;
382 InitializeListHead(&RebalanceList
);
384 Rebalance
= ExAllocatePoolWithTag(NonPagedPool
,
385 sizeof(USB2_REBALANCE
),
388 DPRINT("USBPORT_AllocateBandwidthUSB2: Rebalance - %p, TtExtension - %p\n",
394 RtlZeroMemory(Rebalance
, sizeof(USB2_REBALANCE
));
396 TtEndpoint
= Endpoint
->TtEndpoint
;
397 TtEndpoint
->Endpoint
= Endpoint
;
399 Direction
= EndpointProperties
->Direction
== USBPORT_TRANSFER_DIRECTION_OUT
;
400 DeviceSpeed
= EndpointProperties
->DeviceSpeed
;
407 Tt
= &TtExtension
->Tt
;
408 Period
= USB2_FRAMES
;
410 while (Period
&& Period
> EndpointProperties
->Period
);
415 DPRINT("USBPORT_AllocateBandwidthUSB2: Period - %X\n", Period
);
421 Tt
= &FdoExtension
->Usb2Extension
->HcTt
;
422 Period
= EndpointProperties
->Period
;
424 if (EndpointProperties
->Period
> USB2_MAX_MICROFRAMES
)
425 Period
= USB2_MAX_MICROFRAMES
;
432 DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n", DeviceSpeed
);
434 Tt
= &TtExtension
->Tt
;
439 USB2_InitTtEndpoint(TtEndpoint
,
444 EndpointProperties
->MaxPacketSize
,
447 RebalanceListEntries
= USB2_FRAMES
- 2;
449 Result
= USB2_AllocateTimeForEndpoint(TtEndpoint
,
451 &RebalanceListEntries
);
455 Result
= USB2_PromotePeriods(TtEndpoint
,
457 &RebalanceListEntries
);
460 RebalanceListEntries
= 0;
462 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
464 RebalanceListEntries
= ix
+ 1;
469 RebalanceListEntries
= 0;
473 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceListEntries - %X, Result - %X\n",
474 RebalanceListEntries
,
477 for (ix
= 0; ix
< RebalanceListEntries
; ix
++)
479 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceEndpoint[%X] - %X\n",
481 Rebalance
->RebalanceEndpoint
[ix
]);
483 RebalanceTtEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
485 InsertTailList(&RebalanceList
,
486 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
490 ExFreePool(Rebalance
);
494 DPRINT1("USBPORT_AllocateBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
498 //USB2_Rebalance(FdoDevice, &RebalanceList);
502 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
506 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
508 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
511 USBPORT_UpdateAllocatedBwTt(TtExtension
);
513 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
515 FdoExtension
->Bandwidth
[ix
] -= TtExtension
->MaxBandwidth
;
518 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
525 USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
526 IN PUSBPORT_ENDPOINT Endpoint
)
528 DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
533 USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension
,
539 DPRINT("USB2_InitTT: HcExtension - %p, Tt - %p\n", HcExtension
, Tt
);
541 Tt
->HcExtension
= HcExtension
;
543 Tt
->MaxTime
= USB2_FS_MAX_PERIODIC_ALLOCATION
;
545 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
547 Tt
->FrameBudget
[ix
].TimeUsed
= USB2_MAX_MICROFRAMES
;
548 Tt
->FrameBudget
[ix
].AltEndpoint
= NULL
;
550 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
552 Tt
->TimeCS
[ix
][jx
] = 0;
553 Tt
->NumStartSplits
[ix
][jx
] = 0;
556 Tt
->FrameBudget
[ix
].IsoEndpoint
= &Tt
->IsoEndpoint
[ix
];
558 USB2_InitTtEndpoint(&Tt
->IsoEndpoint
[ix
],
559 USBPORT_TRANSFER_TYPE_ISOCHRONOUS
,
560 USBPORT_TRANSFER_DIRECTION_OUT
,
566 Tt
->IsoEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
567 Tt
->IsoEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
568 Tt
->IsoEndpoint
[ix
].StartFrame
= ix
;
569 Tt
->IsoEndpoint
[ix
].StartMicroframe
= 0xFF;
571 Tt
->FrameBudget
[ix
].IntEndpoint
= &Tt
->IntEndpoint
[ix
];
573 USB2_InitTtEndpoint(&Tt
->IntEndpoint
[ix
],
574 USBPORT_TRANSFER_TYPE_INTERRUPT
,
575 USBPORT_TRANSFER_DIRECTION_OUT
,
581 Tt
->IntEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
582 Tt
->IntEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
583 Tt
->IntEndpoint
[ix
].StartFrame
= ix
;
584 Tt
->IntEndpoint
[ix
].StartMicroframe
= 0xFF;
590 USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension
)
595 DPRINT("USB2_InitController: HcExtension - %p\n", HcExtension
);
597 HcExtension
->MaxHsBusAllocation
= USB2_MAX_MICROFRAME_ALLOCATION
;
599 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
601 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
603 HcExtension
->TimeUsed
[ix
][jx
] = 0;
607 HcExtension
->HcDelayTime
= USB2_CONTROLLER_DELAY
;
609 USB2_InitTT(HcExtension
, &HcExtension
->HcTt
);