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_GetLastIsoTime(IN PUSB2_TT_ENDPOINT TtEndpoint
,
140 PUSB2_TT_ENDPOINT nextTtEndpoint
;
143 DPRINT("USB2_GetLastIsoTime: TtEndpoint - %p, Frame - %X\n",
147 nextTtEndpoint
= TtEndpoint
->Tt
->FrameBudget
[Frame
].IsoEndpoint
->NextTtEndpoint
;
149 if (nextTtEndpoint
||
150 (nextTtEndpoint
= TtEndpoint
->Tt
->FrameBudget
[Frame
].AltEndpoint
) != NULL
)
152 Result
= nextTtEndpoint
->StartTime
+ nextTtEndpoint
->CalcBusTime
;
156 Result
= USB2_FS_SOF_TIME
;
164 USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
165 IN UCHAR TransferType
,
167 IN UCHAR DeviceSpeed
,
169 IN USHORT MaxPacketSize
,
172 RtlZeroMemory(TtEndpoint
, sizeof(USB2_TT_ENDPOINT
));
174 TtEndpoint
->TtEndpointParams
.TransferType
= TransferType
;
175 TtEndpoint
->TtEndpointParams
.Direction
= Direction
;
176 TtEndpoint
->TtEndpointParams
.DeviceSpeed
= DeviceSpeed
;
178 TtEndpoint
->Period
= Period
;
179 TtEndpoint
->MaxPacketSize
= MaxPacketSize
;
185 USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint
,
186 IN PUSB2_REBALANCE Rebalance
,
187 IN PULONG RebalanceListEntries
)
189 DPRINT("USB2_AllocateTimeForEndpoint: UNIMPLEMENTED. FIXME\n");
196 USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint
,
197 IN PUSB2_REBALANCE Rebalance
,
198 IN PULONG RebalanceListEntries
)
200 DPRINT1("USB2_PromotePeriods: UNIMPLEMENTED. FIXME\n");
207 USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension
)
210 ULONG NewBusBandwidth
;
211 ULONG MaxBusBandwidth
= 0;
212 ULONG MinBusBandwidth
;
215 DPRINT("USBPORT_UpdateAllocatedBwTt: TtExtension - %p\n", TtExtension
);
217 BusBandwidth
= TtExtension
->BusBandwidth
;
218 MinBusBandwidth
= BusBandwidth
;
220 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
222 NewBusBandwidth
= BusBandwidth
- TtExtension
->Bandwidth
[ix
];
224 if (NewBusBandwidth
> MaxBusBandwidth
)
225 MaxBusBandwidth
= NewBusBandwidth
;
227 if (NewBusBandwidth
< MinBusBandwidth
)
228 MinBusBandwidth
= NewBusBandwidth
;
231 TtExtension
->MaxBandwidth
= MaxBusBandwidth
;
233 if (MinBusBandwidth
== BusBandwidth
)
234 TtExtension
->MinBandwidth
= 0;
236 TtExtension
->MinBandwidth
= MinBusBandwidth
;
241 USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
242 IN PUSBPORT_ENDPOINT Endpoint
)
244 PUSBPORT_DEVICE_EXTENSION FdoExtension
;
245 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties
;
246 PUSB2_TT_EXTENSION TtExtension
;
248 PUSB2_REBALANCE Rebalance
;
249 LIST_ENTRY RebalanceList
;
250 ULONG RebalanceListEntries
;
251 PUSB2_TT_ENDPOINT TtEndpoint
;
252 PUSB2_TT_ENDPOINT RebalanceTtEndpoint
;
255 USB_DEVICE_SPEED DeviceSpeed
;
262 DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n",
266 EndpointProperties
= &Endpoint
->EndpointProperties
;
267 EndpointProperties
->ScheduleOffset
= 0;
269 if (Endpoint
->Flags
& ENDPOINT_FLAG_ROOTHUB_EP0
)
271 DPRINT("USBPORT_AllocateBandwidthUSB2: ENDPOINT_FLAG_ROOTHUB_EP0\n");
275 FdoExtension
= FdoDevice
->DeviceExtension
;
277 TransferType
= EndpointProperties
->TransferType
;
278 DPRINT("USBPORT_AllocateBandwidthUSB2: TransferType - %X\n", TransferType
);
280 if (TransferType
== USBPORT_TRANSFER_TYPE_CONTROL
||
281 TransferType
== USBPORT_TRANSFER_TYPE_BULK
)
286 if (Endpoint
->TtExtension
)
287 TtExtension
= Endpoint
->TtExtension
;
291 InitializeListHead(&RebalanceList
);
293 Rebalance
= ExAllocatePoolWithTag(NonPagedPool
,
294 sizeof(USB2_REBALANCE
),
297 DPRINT("USBPORT_AllocateBandwidthUSB2: Rebalance - %p, TtExtension - %p\n",
303 RtlZeroMemory(Rebalance
, sizeof(USB2_REBALANCE
));
305 TtEndpoint
= Endpoint
->TtEndpoint
;
306 TtEndpoint
->Endpoint
= Endpoint
;
308 Direction
= EndpointProperties
->Direction
== USBPORT_TRANSFER_DIRECTION_OUT
;
309 DeviceSpeed
= EndpointProperties
->DeviceSpeed
;
316 Tt
= &TtExtension
->Tt
;
317 Period
= USB2_FRAMES
;
319 while (Period
&& Period
> EndpointProperties
->Period
);
324 DPRINT("USBPORT_AllocateBandwidthUSB2: Period - %X\n", Period
);
330 Tt
= &FdoExtension
->Usb2Extension
->HcTt
;
331 Period
= EndpointProperties
->Period
;
333 if (EndpointProperties
->Period
> USB2_MAX_MICROFRAMES
)
334 Period
= USB2_MAX_MICROFRAMES
;
341 DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n", DeviceSpeed
);
343 Tt
= &TtExtension
->Tt
;
348 USB2_InitTtEndpoint(TtEndpoint
,
353 EndpointProperties
->MaxPacketSize
,
356 RebalanceListEntries
= USB2_FRAMES
- 2;
358 Result
= USB2_AllocateTimeForEndpoint(TtEndpoint
,
360 &RebalanceListEntries
);
364 Result
= USB2_PromotePeriods(TtEndpoint
,
366 &RebalanceListEntries
);
369 RebalanceListEntries
= 0;
371 for (ix
= 0; Rebalance
->RebalanceEndpoint
[ix
]; ix
++)
373 RebalanceListEntries
= ix
+ 1;
378 RebalanceListEntries
= 0;
382 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceListEntries - %X, Result - %X\n",
383 RebalanceListEntries
,
386 for (ix
= 0; ix
< RebalanceListEntries
; ix
++)
388 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceEndpoint[%X] - %X\n",
390 Rebalance
->RebalanceEndpoint
[ix
]);
392 RebalanceTtEndpoint
= Rebalance
->RebalanceEndpoint
[ix
];
394 InsertTailList(&RebalanceList
,
395 &RebalanceTtEndpoint
->Endpoint
->RebalanceLink
);
399 ExFreePool(Rebalance
);
403 DPRINT1("USBPORT_AllocateBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
407 //USB2_Rebalance(FdoDevice, &RebalanceList);
411 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
415 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
417 FdoExtension
->Bandwidth
[ix
] += TtExtension
->MaxBandwidth
;
420 USBPORT_UpdateAllocatedBwTt(TtExtension
);
422 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
424 FdoExtension
->Bandwidth
[ix
] -= TtExtension
->MaxBandwidth
;
427 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result
);
434 USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice
,
435 IN PUSBPORT_ENDPOINT Endpoint
)
437 DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
442 USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension
,
448 DPRINT("USB2_InitTT: HcExtension - %p, Tt - %p\n", HcExtension
, Tt
);
450 Tt
->HcExtension
= HcExtension
;
452 Tt
->MaxTime
= USB2_FS_MAX_PERIODIC_ALLOCATION
;
454 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
456 Tt
->FrameBudget
[ix
].TimeUsed
= USB2_MAX_MICROFRAMES
;
457 Tt
->FrameBudget
[ix
].AltEndpoint
= NULL
;
459 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
461 Tt
->TimeCS
[ix
][jx
] = 0;
462 Tt
->NumStartSplits
[ix
][jx
] = 0;
465 Tt
->FrameBudget
[ix
].IsoEndpoint
= &Tt
->IsoEndpoint
[ix
];
467 USB2_InitTtEndpoint(&Tt
->IsoEndpoint
[ix
],
468 USBPORT_TRANSFER_TYPE_ISOCHRONOUS
,
469 USBPORT_TRANSFER_DIRECTION_OUT
,
475 Tt
->IsoEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
476 Tt
->IsoEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
477 Tt
->IsoEndpoint
[ix
].StartFrame
= ix
;
478 Tt
->IsoEndpoint
[ix
].StartMicroframe
= 0xFF;
480 Tt
->FrameBudget
[ix
].IntEndpoint
= &Tt
->IntEndpoint
[ix
];
482 USB2_InitTtEndpoint(&Tt
->IntEndpoint
[ix
],
483 USBPORT_TRANSFER_TYPE_INTERRUPT
,
484 USBPORT_TRANSFER_DIRECTION_OUT
,
490 Tt
->IntEndpoint
[ix
].ActualPeriod
= USB2_FRAMES
;
491 Tt
->IntEndpoint
[ix
].CalcBusTime
= USB2_FS_SOF_TIME
+ USB2_HUB_DELAY
;
492 Tt
->IntEndpoint
[ix
].StartFrame
= ix
;
493 Tt
->IntEndpoint
[ix
].StartMicroframe
= 0xFF;
499 USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension
)
504 DPRINT("USB2_InitController: HcExtension - %p\n", HcExtension
);
506 HcExtension
->MaxHsBusAllocation
= USB2_MAX_MICROFRAME_ALLOCATION
;
508 for (ix
= 0; ix
< USB2_FRAMES
; ix
++)
510 for (jx
= 0; jx
< USB2_MICROFRAMES
; jx
++)
512 HcExtension
->TimeUsed
[ix
][jx
] = 0;
516 HcExtension
->HcDelayTime
= USB2_CONTROLLER_DELAY
;
518 USB2_InitTT(HcExtension
, &HcExtension
->HcTt
);