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_AddDataBitStuff(IN USHORT DataTime
)
17 return (DataTime
+ (DataTime
/ 16));
22 USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint
)
30 TransferType
= TtEndpoint
->TtEndpointParams
.TransferType
;
31 Direction
= TtEndpoint
->TtEndpointParams
.Direction
;
32 DeviceSpeed
= TtEndpoint
->TtEndpointParams
.Direction
;
34 HostDelay
= TtEndpoint
->Tt
->HcExtension
->HcDelayTime
;
36 if (DeviceSpeed
== UsbHighSpeed
)
38 if (Direction
== USBPORT_TRANSFER_DIRECTION_OUT
)
40 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
41 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_OUT_OVERHEAD
;
43 Overhead
= HostDelay
+ USB2_HS_INTERRUPT_OUT_OVERHEAD
;
47 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
48 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_IN_OVERHEAD
;
50 Overhead
= HostDelay
+ USB2_HS_ISOCHRONOUS_OUT_OVERHEAD
;
53 else if (DeviceSpeed
== UsbFullSpeed
)
55 if (TransferType
== USBPORT_TRANSFER_TYPE_ISOCHRONOUS
)
56 Overhead
= HostDelay
+ USB2_FS_ISOCHRONOUS_OVERHEAD
;
58 Overhead
= HostDelay
+ USB2_FS_INTERRUPT_OVERHEAD
;
62 Overhead
= HostDelay
+ USB2_LS_INTERRUPT_OVERHEAD
;
70 USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
71 IN UCHAR TransferType
,
75 IN USHORT MaxPacketSize
,
78 RtlZeroMemory(TtEndpoint
, sizeof(USB2_TT_ENDPOINT
));
80 TtEndpoint
->TtEndpointParams
.TransferType
= TransferType
;
81 TtEndpoint
->TtEndpointParams
.Direction
= Direction
;
82 TtEndpoint
->TtEndpointParams
.DeviceSpeed
= DeviceSpeed
;
84 TtEndpoint
->Period
= Period
;
85 TtEndpoint
->MaxPacketSize
= MaxPacketSize
;
91 USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
92 IN PUSB2_REBALANCE Rebalance
,
93 IN PULONG RebalanceListEntries
)
95 DPRINT("USB2_AllocateTimeForEndpoint: UNIMPLEMENTED. FIXME\n");
102 USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint
,
103 IN PUSB2_REBALANCE Rebalance
,
104 IN PULONG RebalanceListEntries
)
106 DPRINT1("USB2_PromotePeriods: UNIMPLEMENTED. FIXME\n");
113 USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension
)
116 ULONG NewBusBandwidth
;
117 ULONG MaxBusBandwidth
= 0;
118 ULONG MinBusBandwidth
;
121 DPRINT("USBPORT_UpdateAllocatedBwTt: TtExtension - %p\n", TtExtension
);
123 BusBandwidth
= TtExtension
->BusBandwidth
;
124 MinBusBandwidth
= BusBandwidth
;
126 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
128 NewBusBandwidth
= BusBandwidth
- TtExtension
->Bandwidth
[ix
];
130 if (NewBusBandwidth
> MaxBusBandwidth
)
131 MaxBusBandwidth
= NewBusBandwidth
;
133 if (NewBusBandwidth
< MinBusBandwidth
)
134 MinBusBandwidth
= NewBusBandwidth
;
137 TtExtension
->MaxBandwidth
= MaxBusBandwidth
;
139 if (MinBusBandwidth
== BusBandwidth
)
140 TtExtension
->MinBandwidth
= 0;
142 TtExtension
->MinBandwidth
= MinBusBandwidth
;
147 USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
148 IN PUSBPORT_ENDPOINT Endpoint
)
150 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
151 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
152 PUSB2_TT_EXTENSION TtExtension
;
154 PUSB2_REBALANCE Rebalance
;
155 LIST_ENTRY RebalanceList
;
156 ULONG RebalanceListEntries
;
157 PUSB2_TT_ENDPOINT TtEndpoint
;
158 PUSB2_TT_ENDPOINT RebalanceTtEndpoint
;
161 USB_DEVICE_SPEED DeviceSpeed
;
168 DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n",
172 EndpointProperties
= &Endpoint
->EndpointProperties
;
173 EndpointProperties
->ScheduleOffset
= 0;
175 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
177 DPRINT("USBPORT_AllocateBandwidthUSB2: ENDPOINT_FLAG_ROOTHUB_EP0\n");
181 FdoExtension
= FdoDevice
->DeviceExtension
;
183 TransferType
= EndpointProperties
->TransferType
;
184 DPRINT("USBPORT_AllocateBandwidthUSB2: TransferType - %X\n", TransferType
);
186 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
187 TransferType
== USBPORT_TRANSFER_TYPE_BULK
)
192 if (Endpoint
->TtExtension
)
193 TtExtension
= Endpoint
->TtExtension
;
197 InitializeListHead(&RebalanceList
);
199 Rebalance
= ExAllocatePoolWithTag(NonPagedPool
,
200 sizeof(USB2_REBALANCE
),
203 DPRINT("USBPORT_AllocateBandwidthUSB2: Rebalance - %p, TtExtension - %p\n",
209 RtlZeroMemory(Rebalance
, sizeof(USB2_REBALANCE
));
211 TtEndpoint
= Endpoint
->TtEndpoint
;
212 TtEndpoint
->Endpoint
= Endpoint
;
214 Direction
= EndpointProperties
->Direction
== USBPORT_TRANSFER_DIRECTION_OUT
;
215 DeviceSpeed
= EndpointProperties
->DeviceSpeed
;
222 Tt
= &TtExtension
->Tt
;
223 Period
= USB2_FRAMES
;
225 while (Period
&& Period
> EndpointProperties
->Period
);
230 DPRINT("USBPORT_AllocateBandwidthUSB2: Period - %X\n", Period
);
236 Tt
= &FdoExtension
->Usb2Extension
->HcTt
;
237 Period
= EndpointProperties
->Period
;
239 if (EndpointProperties
->Period
> USB2_MAX_MICROFRAMES
)
240 Period
= USB2_MAX_MICROFRAMES
;
247 DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n", DeviceSpeed
);
249 Tt
= &TtExtension
->Tt
;
254 USB2_InitTtEndpoint(TtEndpoint
,
259 EndpointProperties
->MaxPacketSize
,
262 RebalanceListEntries
= USB2_FRAMES
- 2;
264 Result
= USB2_AllocateTimeForEndpoint(TtEndpoint
,
266 &RebalanceListEntries
);
270 Result
= USB2_PromotePeriods(TtEndpoint
,
272 &RebalanceListEntries
);
275 RebalanceListEntries
= 0;
277 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
279 RebalanceListEntries
= ix
+ 1;
284 RebalanceListEntries
= 0;
288 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceListEntries - %X, Result - %X\n",
289 RebalanceListEntries
,
292 for (ix
= 0; ix
< RebalanceListEntries
; ix
++)
294 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceEndpoint[%X] - %X\n",
296 Rebalance
->RebalanceEndpoint
[ix
]);
298 RebalanceTtEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
300 InsertTailList(&RebalanceList
,
301 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
305 ExFreePool(Rebalance
);
309 DPRINT1("USBPORT_AllocateBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
313 //USB2_Rebalance(FdoDevice, &RebalanceList);
317 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
321 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
323 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
326 USBPORT_UpdateAllocatedBwTt(TtExtension
);
328 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
330 FdoExtension
->Bandwidth
[ix
] -= TtExtension
->MaxBandwidth
;
333 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
340 USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
341 IN PUSBPORT_ENDPOINT Endpoint
)
343 DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
348 USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension
,
354 DPRINT("USB2_InitTT: HcExtension - %p, Tt - %p\n", HcExtension
, Tt
);
356 Tt
->HcExtension
= HcExtension
;
358 Tt
->MaxTime
= USB2_FS_MAX_PERIODIC_ALLOCATION
;
360 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
362 Tt
->FrameBudget
[ix
].TimeUsed
= USB2_MAX_MICROFRAMES
;
363 Tt
->FrameBudget
[ix
].AltEndpoint
= NULL
;
365 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
367 Tt
->TimeCS
[ix
][jx
] = 0;
368 Tt
->NumStartSplits
[ix
][jx
] = 0;
371 Tt
->FrameBudget
[ix
].IsoEndpoint
= &Tt
->IsoEndpoint
[ix
];
373 USB2_InitTtEndpoint(&Tt
->IsoEndpoint
[ix
],
374 USBPORT_TRANSFER_TYPE_ISOCHRONOUS
,
375 USBPORT_TRANSFER_DIRECTION_OUT
,
381 Tt
->IsoEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
382 Tt
->IsoEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
383 Tt
->IsoEndpoint
[ix
].StartFrame
= ix
;
384 Tt
->IsoEndpoint
[ix
].StartMicroframe
= 0xFF;
386 Tt
->FrameBudget
[ix
].IntEndpoint
= &Tt
->IntEndpoint
[ix
];
388 USB2_InitTtEndpoint(&Tt
->IntEndpoint
[ix
],
389 USBPORT_TRANSFER_TYPE_INTERRUPT
,
390 USBPORT_TRANSFER_DIRECTION_OUT
,
396 Tt
->IntEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
397 Tt
->IntEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
398 Tt
->IntEndpoint
[ix
].StartFrame
= ix
;
399 Tt
->IntEndpoint
[ix
].StartMicroframe
= 0xFF;
405 USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension
)
410 DPRINT("USB2_InitController: HcExtension - %p\n", HcExtension
);
412 HcExtension
->MaxHsBusAllocation
= USB2_MAX_MICROFRAME_ALLOCATION
;
414 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
416 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
418 HcExtension
->TimeUsed
[ix
][jx
] = 0;
422 HcExtension
->HcDelayTime
= USB2_CONTROLLER_DELAY
;
424 USB2_InitTT(HcExtension
, &HcExtension
->HcTt
);