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_CheckTtEndpointInsert(IN PUSB2_TT_ENDPOINT nextTtEndpoint
,
44 IN PUSB2_TT_ENDPOINT TtEndpoint
)
48 DPRINT("USB2_CheckTtEndpointInsert: nextTtEndpoint - %p, TtEndpoint - %p\n",
54 if (TtEndpoint
->CalcBusTime
>= (USB2_FS_MAX_PERIODIC_ALLOCATION
/ 2))
56 DPRINT1("USB2_CheckTtEndpointInsert: Result - FALSE\n");
62 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
66 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
68 if (nextTtEndpoint
->ActualPeriod
< TtEndpoint
->ActualPeriod
&&
69 TransferType
== USBPORT_TRANSFER_TYPE_INTERRUPT
)
71 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
75 if ((nextTtEndpoint
->ActualPeriod
<= TtEndpoint
->ActualPeriod
&&
76 TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
) ||
77 nextTtEndpoint
== TtEndpoint
)
79 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
83 DPRINT("USB2_CheckTtEndpointInsert: Result - FALSE\n");
89 USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint
)
97 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
98 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
99 DeviceSpeed
= TtEndpoint
->TtEndpointParams
.Direction
;
101 HostDelay
= TtEndpoint
->Tt
->HcExtension
->HcDelayTime
;
103 if (DeviceSpeed
== UsbHighSpeed
)
105 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
107 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
108 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_OUT_OVERHEAD
;
110 Overhead
= HostDelay
+ USB2_HS_INTERRUPT_OUT_OVERHEAD
;
114 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
115 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_IN_OVERHEAD
;
117 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_OUT_OVERHEAD
;
120 else if (DeviceSpeed
== UsbFullSpeed
)
122 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
123 Overhead
= HostDelay
+ USB2_FS_ISOCHRONOUS_OVERHEAD
;
125 Overhead
= HostDelay
+ USB2_FS_INTERRUPT_OVERHEAD
;
129 Overhead
= HostDelay
+ USB2_LS_INTERRUPT_OVERHEAD
;
137 USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
138 IN UCHAR TransferType
,
140 IN UCHAR DeviceSpeed
,
142 IN USHORT MaxPacketSize
,
145 RtlZeroMemory(TtEndpoint
, sizeof(USB2_TT_ENDPOINT
));
147 TtEndpoint
->TtEndpointParams
.TransferType
= TransferType
;
148 TtEndpoint
->TtEndpointParams
.Direction
= Direction
;
149 TtEndpoint
->TtEndpointParams
.DeviceSpeed
= DeviceSpeed
;
151 TtEndpoint
->Period
= Period
;
152 TtEndpoint
->MaxPacketSize
= MaxPacketSize
;
158 USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
159 IN PUSB2_REBALANCE Rebalance
,
160 IN PULONG RebalanceListEntries
)
162 DPRINT("USB2_AllocateTimeForEndpoint: UNIMPLEMENTED. FIXME\n");
169 USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint
,
170 IN PUSB2_REBALANCE Rebalance
,
171 IN PULONG RebalanceListEntries
)
173 DPRINT1("USB2_PromotePeriods: UNIMPLEMENTED. FIXME\n");
180 USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension
)
183 ULONG NewBusBandwidth
;
184 ULONG MaxBusBandwidth
= 0;
185 ULONG MinBusBandwidth
;
188 DPRINT("USBPORT_UpdateAllocatedBwTt: TtExtension - %p\n", TtExtension
);
190 BusBandwidth
= TtExtension
->BusBandwidth
;
191 MinBusBandwidth
= BusBandwidth
;
193 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
195 NewBusBandwidth
= BusBandwidth
- TtExtension
->Bandwidth
[ix
];
197 if (NewBusBandwidth
> MaxBusBandwidth
)
198 MaxBusBandwidth
= NewBusBandwidth
;
200 if (NewBusBandwidth
< MinBusBandwidth
)
201 MinBusBandwidth
= NewBusBandwidth
;
204 TtExtension
->MaxBandwidth
= MaxBusBandwidth
;
206 if (MinBusBandwidth
== BusBandwidth
)
207 TtExtension
->MinBandwidth
= 0;
209 TtExtension
->MinBandwidth
= MinBusBandwidth
;
214 USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
215 IN PUSBPORT_ENDPOINT Endpoint
)
217 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
218 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
219 PUSB2_TT_EXTENSION TtExtension
;
221 PUSB2_REBALANCE Rebalance
;
222 LIST_ENTRY RebalanceList
;
223 ULONG RebalanceListEntries
;
224 PUSB2_TT_ENDPOINT TtEndpoint
;
225 PUSB2_TT_ENDPOINT RebalanceTtEndpoint
;
228 USB_DEVICE_SPEED DeviceSpeed
;
235 DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n",
239 EndpointProperties
= &Endpoint
->EndpointProperties
;
240 EndpointProperties
->ScheduleOffset
= 0;
242 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
244 DPRINT("USBPORT_AllocateBandwidthUSB2: ENDPOINT_FLAG_ROOTHUB_EP0\n");
248 FdoExtension
= FdoDevice
->DeviceExtension
;
250 TransferType
= EndpointProperties
->TransferType
;
251 DPRINT("USBPORT_AllocateBandwidthUSB2: TransferType - %X\n", TransferType
);
253 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
254 TransferType
== USBPORT_TRANSFER_TYPE_BULK
)
259 if (Endpoint
->TtExtension
)
260 TtExtension
= Endpoint
->TtExtension
;
264 InitializeListHead(&RebalanceList
);
266 Rebalance
= ExAllocatePoolWithTag(NonPagedPool
,
267 sizeof(USB2_REBALANCE
),
270 DPRINT("USBPORT_AllocateBandwidthUSB2: Rebalance - %p, TtExtension - %p\n",
276 RtlZeroMemory(Rebalance
, sizeof(USB2_REBALANCE
));
278 TtEndpoint
= Endpoint
->TtEndpoint
;
279 TtEndpoint
->Endpoint
= Endpoint
;
281 Direction
= EndpointProperties
->Direction
== USBPORT_TRANSFER_DIRECTION_OUT
;
282 DeviceSpeed
= EndpointProperties
->DeviceSpeed
;
289 Tt
= &TtExtension
->Tt
;
290 Period
= USB2_FRAMES
;
292 while (Period
&& Period
> EndpointProperties
->Period
);
297 DPRINT("USBPORT_AllocateBandwidthUSB2: Period - %X\n", Period
);
303 Tt
= &FdoExtension
->Usb2Extension
->HcTt
;
304 Period
= EndpointProperties
->Period
;
306 if (EndpointProperties
->Period
> USB2_MAX_MICROFRAMES
)
307 Period
= USB2_MAX_MICROFRAMES
;
314 DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n", DeviceSpeed
);
316 Tt
= &TtExtension
->Tt
;
321 USB2_InitTtEndpoint(TtEndpoint
,
326 EndpointProperties
->MaxPacketSize
,
329 RebalanceListEntries
= USB2_FRAMES
- 2;
331 Result
= USB2_AllocateTimeForEndpoint(TtEndpoint
,
333 &RebalanceListEntries
);
337 Result
= USB2_PromotePeriods(TtEndpoint
,
339 &RebalanceListEntries
);
342 RebalanceListEntries
= 0;
344 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
346 RebalanceListEntries
= ix
+ 1;
351 RebalanceListEntries
= 0;
355 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceListEntries - %X, Result - %X\n",
356 RebalanceListEntries
,
359 for (ix
= 0; ix
< RebalanceListEntries
; ix
++)
361 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceEndpoint[%X] - %X\n",
363 Rebalance
->RebalanceEndpoint
[ix
]);
365 RebalanceTtEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
367 InsertTailList(&RebalanceList
,
368 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
372 ExFreePool(Rebalance
);
376 DPRINT1("USBPORT_AllocateBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
380 //USB2_Rebalance(FdoDevice, &RebalanceList);
384 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
388 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
390 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
393 USBPORT_UpdateAllocatedBwTt(TtExtension
);
395 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
397 FdoExtension
->Bandwidth
[ix
] -= TtExtension
->MaxBandwidth
;
400 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
407 USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
408 IN PUSBPORT_ENDPOINT Endpoint
)
410 DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
415 USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension
,
421 DPRINT("USB2_InitTT: HcExtension - %p, Tt - %p\n", HcExtension
, Tt
);
423 Tt
->HcExtension
= HcExtension
;
425 Tt
->MaxTime
= USB2_FS_MAX_PERIODIC_ALLOCATION
;
427 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
429 Tt
->FrameBudget
[ix
].TimeUsed
= USB2_MAX_MICROFRAMES
;
430 Tt
->FrameBudget
[ix
].AltEndpoint
= NULL
;
432 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
434 Tt
->TimeCS
[ix
][jx
] = 0;
435 Tt
->NumStartSplits
[ix
][jx
] = 0;
438 Tt
->FrameBudget
[ix
].IsoEndpoint
= &Tt
->IsoEndpoint
[ix
];
440 USB2_InitTtEndpoint(&Tt
->IsoEndpoint
[ix
],
441 USBPORT_TRANSFER_TYPE_ISOCHRONOUS
,
442 USBPORT_TRANSFER_DIRECTION_OUT
,
448 Tt
->IsoEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
449 Tt
->IsoEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
450 Tt
->IsoEndpoint
[ix
].StartFrame
= ix
;
451 Tt
->IsoEndpoint
[ix
].StartMicroframe
= 0xFF;
453 Tt
->FrameBudget
[ix
].IntEndpoint
= &Tt
->IntEndpoint
[ix
];
455 USB2_InitTtEndpoint(&Tt
->IntEndpoint
[ix
],
456 USBPORT_TRANSFER_TYPE_INTERRUPT
,
457 USBPORT_TRANSFER_DIRECTION_OUT
,
463 Tt
->IntEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
464 Tt
->IntEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
465 Tt
->IntEndpoint
[ix
].StartFrame
= ix
;
466 Tt
->IntEndpoint
[ix
].StartMicroframe
= 0xFF;
472 USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension
)
477 DPRINT("USB2_InitController: HcExtension - %p\n", HcExtension
);
479 HcExtension
->MaxHsBusAllocation
= USB2_MAX_MICROFRAME_ALLOCATION
;
481 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
483 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
485 HcExtension
->TimeUsed
[ix
][jx
] = 0;
489 HcExtension
->HcDelayTime
= USB2_CONTROLLER_DELAY
;
491 USB2_InitTT(HcExtension
, &HcExtension
->HcTt
);