[USBPORT] Continue implementation USBPORT_AllocateBandwidthUSB2().
[reactos.git] / drivers / usb / usbport / usb2.c
1 /*
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>
6 */
7
8 #include "usbport.h"
9
10 //#define NDEBUG
11 #include <debug.h>
12
13 BOOLEAN
14 NTAPI
15 USB2_AllocateCheck(IN OUT PULONG OutTimeUsed,
16 IN ULONG CalcBusTime,
17 IN ULONG LimitAllocation)
18 {
19 ULONG BusTime;
20 BOOLEAN Result = TRUE;
21
22 BusTime = *OutTimeUsed + CalcBusTime;
23 *OutTimeUsed += CalcBusTime;
24
25 if (BusTime > LimitAllocation)
26 {
27 DPRINT("USB2_AllocateCheck: BusTime > LimitAllocation\n");
28 Result = FALSE;
29 }
30
31 return Result;
32 }
33
34 USHORT
35 NTAPI
36 USB2_AddDataBitStuff(IN USHORT DataTime)
37 {
38 return (DataTime + (DataTime / 16));
39 }
40
41 VOID
42 NTAPI
43 USB2_IncMicroFrame(OUT PUCHAR frame,
44 OUT PUCHAR uframe)
45 {
46 ++*uframe;
47
48 if (*uframe > (USB2_MICROFRAMES - 1))
49 {
50 *uframe = 0;
51 *frame = (*frame + 1) & (USB2_FRAMES - 1);
52 }
53 }
54
55 VOID
56 NTAPI
57 USB2_GetPrevMicroFrame(OUT PUCHAR frame,
58 OUT PUCHAR uframe)
59 {
60 *uframe = USB2_MICROFRAMES - 1;
61
62 if (*frame)
63 --*frame;
64 else
65 *frame = USB2_FRAMES - 1;
66 }
67
68 BOOLEAN
69 NTAPI
70 USB2_CheckTtEndpointInsert(IN PUSB2_TT_ENDPOINT nextTtEndpoint,
71 IN PUSB2_TT_ENDPOINT TtEndpoint)
72 {
73 ULONG TransferType;
74
75 DPRINT("USB2_CheckTtEndpointInsert: nextTtEndpoint - %p, TtEndpoint - %p\n",
76 nextTtEndpoint,
77 TtEndpoint);
78
79 ASSERT(TtEndpoint);
80
81 if (TtEndpoint->CalcBusTime >= (USB2_FS_MAX_PERIODIC_ALLOCATION / 2))
82 {
83 DPRINT1("USB2_CheckTtEndpointInsert: Result - FALSE\n");
84 return FALSE;
85 }
86
87 if (!nextTtEndpoint)
88 {
89 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
90 return TRUE;
91 }
92
93 TransferType = TtEndpoint->TtEndpointParams.TransferType;
94
95 if (nextTtEndpoint->ActualPeriod < TtEndpoint->ActualPeriod &&
96 TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
97 {
98 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
99 return TRUE;
100 }
101
102 if ((nextTtEndpoint->ActualPeriod <= TtEndpoint->ActualPeriod &&
103 TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS) ||
104 nextTtEndpoint == TtEndpoint)
105 {
106 DPRINT("USB2_CheckTtEndpointInsert: Result - TRUE\n");
107 return TRUE;
108 }
109
110 DPRINT("USB2_CheckTtEndpointInsert: Result - FALSE\n");
111 return FALSE;
112 }
113
114 ULONG
115 NTAPI
116 USB2_GetOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint)
117 {
118 ULONG TransferType;
119 ULONG Direction;
120 ULONG DeviceSpeed;
121 ULONG Overhead;
122 ULONG HostDelay;
123
124 TransferType = TtEndpoint->TtEndpointParams.TransferType;
125 Direction = TtEndpoint->TtEndpointParams.Direction;
126 DeviceSpeed = TtEndpoint->TtEndpointParams.Direction;
127
128 HostDelay = TtEndpoint->Tt->HcExtension->HcDelayTime;
129
130 if (DeviceSpeed == UsbHighSpeed)
131 {
132 if (Direction == USBPORT_TRANSFER_DIRECTION_OUT)
133 {
134 if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
135 Overhead = HostDelay + USB2_HS_ISOCHRONOUS_OUT_OVERHEAD;
136 else
137 Overhead = HostDelay + USB2_HS_INTERRUPT_OUT_OVERHEAD;
138 }
139 else
140 {
141 if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
142 Overhead = HostDelay + USB2_HS_ISOCHRONOUS_IN_OVERHEAD;
143 else
144 Overhead = HostDelay + USB2_HS_ISOCHRONOUS_OUT_OVERHEAD;
145 }
146 }
147 else if (DeviceSpeed == UsbFullSpeed)
148 {
149 if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
150 Overhead = HostDelay + USB2_FS_ISOCHRONOUS_OVERHEAD;
151 else
152 Overhead = HostDelay + USB2_FS_INTERRUPT_OVERHEAD;
153 }
154 else
155 {
156 Overhead = HostDelay + USB2_LS_INTERRUPT_OVERHEAD;
157 }
158
159 return Overhead;
160 }
161
162 VOID
163 NTAPI
164 USB2_GetHsOverhead(IN PUSB2_TT_ENDPOINT TtEndpoint,
165 IN PULONG OverheadSS,
166 IN PULONG OverheadCS)
167 {
168 ULONG TransferType;
169 ULONG Direction;
170 ULONG HostDelay;
171
172 TransferType = TtEndpoint->TtEndpointParams.TransferType;
173 Direction = TtEndpoint->TtEndpointParams.Direction;
174
175 HostDelay = TtEndpoint->Tt->HcExtension->HcDelayTime;
176
177 if (Direction == USBPORT_TRANSFER_DIRECTION_OUT)
178 {
179 if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
180 {
181 *OverheadSS = HostDelay + USB2_HS_SS_ISOCHRONOUS_OUT_OVERHEAD;
182 *OverheadCS = 0;
183 }
184 else
185 {
186 *OverheadSS = HostDelay + USB2_HS_SS_INTERRUPT_OUT_OVERHEAD;
187 *OverheadCS = HostDelay + USB2_HS_CS_INTERRUPT_OUT_OVERHEAD;
188 }
189 }
190 else
191 {
192 if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
193 {
194 *OverheadSS = HostDelay + USB2_HS_SS_ISOCHRONOUS_IN_OVERHEAD;
195 *OverheadCS = HostDelay + USB2_HS_CS_ISOCHRONOUS_IN_OVERHEAD;
196 }
197 else
198 {
199 *OverheadSS = HostDelay + USB2_HS_SS_INTERRUPT_IN_OVERHEAD;
200 *OverheadCS = HostDelay + USB2_HS_CS_INTERRUPT_IN_OVERHEAD;
201 }
202
203 DPRINT("USB2_GetHsOverhead: *OverheadSS - %X, *OverheadCS - %X\n",
204 *OverheadSS,
205 *OverheadCS);
206 }
207 }
208
209 ULONG
210 NTAPI
211 USB2_GetLastIsoTime(IN PUSB2_TT_ENDPOINT TtEndpoint,
212 IN ULONG Frame)
213 {
214 PUSB2_TT_ENDPOINT nextTtEndpoint;
215 ULONG Result;
216
217 DPRINT("USB2_GetLastIsoTime: TtEndpoint - %p, Frame - %X\n",
218 TtEndpoint,
219 Frame);
220
221 nextTtEndpoint = TtEndpoint->Tt->FrameBudget[Frame].IsoEndpoint->NextTtEndpoint;
222
223 if (nextTtEndpoint ||
224 (nextTtEndpoint = TtEndpoint->Tt->FrameBudget[Frame].AltEndpoint) != NULL)
225 {
226 Result = nextTtEndpoint->StartTime + nextTtEndpoint->CalcBusTime;
227 }
228 else
229 {
230 Result = USB2_FS_SOF_TIME;
231 }
232
233 return Result;
234 }
235
236 ULONG
237 NTAPI
238 USB2_GetStartTime(IN PUSB2_TT_ENDPOINT nextTtEndpoint,
239 IN PUSB2_TT_ENDPOINT TtEndpoint,
240 IN PUSB2_TT_ENDPOINT prevTtEndpoint,
241 IN ULONG Frame)
242 {
243 PUSB2_TT_ENDPOINT ttEndpoint;
244 ULONG TransferType;
245
246 DPRINT("USB2_GetStartTime: nextTtEndpoint - %p, TtEndpoint - %p, prevTtEndpoint - %p, Frame - %X\n",
247 nextTtEndpoint,
248 TtEndpoint,
249 prevTtEndpoint,
250 Frame);
251
252 TransferType = TtEndpoint->TtEndpointParams.TransferType;
253
254 if (nextTtEndpoint && TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
255 {
256 return nextTtEndpoint->StartTime + nextTtEndpoint->CalcBusTime;
257 }
258
259 if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
260 {
261 ttEndpoint = TtEndpoint->Tt->FrameBudget[Frame].AltEndpoint;
262
263 if (ttEndpoint)
264 return ttEndpoint->StartTime + ttEndpoint->CalcBusTime;
265 else
266 return USB2_FS_SOF_TIME;
267 }
268 else
269 {
270 ttEndpoint = prevTtEndpoint;
271
272 if (ttEndpoint == TtEndpoint->Tt->FrameBudget[Frame].IntEndpoint)
273 return USB2_GetLastIsoTime(TtEndpoint, Frame);
274 else
275 return ttEndpoint->StartTime + ttEndpoint->CalcBusTime;
276 }
277 }
278
279 VOID
280 NTAPI
281 USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint,
282 IN UCHAR TransferType,
283 IN UCHAR Direction,
284 IN UCHAR DeviceSpeed,
285 IN USHORT Period,
286 IN USHORT MaxPacketSize,
287 IN PUSB2_TT Tt)
288 {
289 RtlZeroMemory(TtEndpoint, sizeof(USB2_TT_ENDPOINT));
290
291 TtEndpoint->TtEndpointParams.TransferType = TransferType;
292 TtEndpoint->TtEndpointParams.Direction = Direction;
293 TtEndpoint->TtEndpointParams.DeviceSpeed = DeviceSpeed;
294
295 TtEndpoint->Period = Period;
296 TtEndpoint->MaxPacketSize = MaxPacketSize;
297 TtEndpoint->Tt = Tt;
298 }
299
300 BOOLEAN
301 NTAPI
302 USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint,
303 IN LONG Frame)
304 {
305 PUSB2_HC_EXTENSION HcExtension;
306 PUSB2_TT Tt;
307 ULONG TransferType;
308 ULONG Direction;
309 ULONG DataTime;
310 ULONG RemainDataTime;
311 ULONG OverheadCS;
312 ULONG OverheadSS;
313 ULONG ix;
314 USHORT PktSize;
315 UCHAR frame;
316 UCHAR uframe;
317 BOOL Result = TRUE;
318
319 DPRINT("USB2_AllocateHS: TtEndpoint - %p, Frame - %X, TtEndpoint->StartFrame - %X\n",
320 TtEndpoint,
321 Frame,
322 TtEndpoint->StartFrame);
323
324 Tt = TtEndpoint->Tt;
325 HcExtension = Tt->HcExtension;
326
327 TransferType = TtEndpoint->TtEndpointParams.TransferType;
328 Direction = TtEndpoint->TtEndpointParams.Direction;
329
330 if (Frame == 0)
331 {
332 TtEndpoint->StartMicroframe =
333 TtEndpoint->StartTime / USB2_FS_RAW_BYTES_IN_MICROFRAME - 1;
334
335 DPRINT("USB2_AllocateHS: TtEndpoint->StartMicroframe - %X\n",
336 TtEndpoint->StartMicroframe);
337 }
338
339 USB2_GetHsOverhead(TtEndpoint, &OverheadSS, &OverheadCS);
340
341 if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
342 {
343 if (Frame == 0)
344 {
345 TtEndpoint->Nums.NumStarts = 1;
346
347 if ((CHAR)TtEndpoint->StartMicroframe < 5)
348 {
349 TtEndpoint->Nums.NumCompletes = 3;
350 }
351 else
352 {
353 TtEndpoint->Nums.NumCompletes = 2;
354 }
355 }
356 }
357 else
358 {
359 if (Direction == USBPORT_TRANSFER_DIRECTION_OUT)
360 {
361 DPRINT("USB2_AllocateHS: ISO UNIMPLEMENTED\n");
362 ASSERT(FALSE);
363 }
364 else
365 {
366 DPRINT("USB2_AllocateHS: ISO UNIMPLEMENTED\n");
367 ASSERT(FALSE);
368 }
369 }
370
371 frame = TtEndpoint->StartFrame + Frame;
372 uframe = TtEndpoint->StartMicroframe;
373
374 if (TtEndpoint->StartMicroframe == 0xFF)
375 USB2_GetPrevMicroFrame(&frame, &uframe);
376
377 for (ix = 0; ix < TtEndpoint->Nums.NumStarts; ix++)
378 {
379 if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe],
380 OverheadSS,
381 USB2_MAX_MICROFRAME_ALLOCATION))
382 {
383 Result = FALSE;
384 }
385
386 if (Tt->NumStartSplits[frame][uframe] > (USB2_MAX_FS_LS_TRANSACTIONS_IN_UFRAME - 1))
387 {
388 DPRINT1("USB2_AllocateHS: Num Start Splits - %X\n",
389 Tt->NumStartSplits[frame][uframe] + 1);
390
391 ASSERT(FALSE);
392 Result = FALSE;
393 }
394
395 ++Tt->NumStartSplits[frame][uframe];
396 USB2_IncMicroFrame(&frame, &uframe);
397 }
398
399 frame = TtEndpoint->StartFrame + Frame;
400 uframe = TtEndpoint->StartMicroframe + TtEndpoint->Nums.NumStarts + 1;
401
402 for (ix = 0; ix < TtEndpoint->Nums.NumCompletes; ix++)
403 {
404 if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe],
405 OverheadCS,
406 USB2_MAX_MICROFRAME_ALLOCATION))
407 {
408 Result = FALSE;
409 }
410
411 USB2_IncMicroFrame(&frame, &uframe);
412 }
413
414 if (Direction == USBPORT_TRANSFER_DIRECTION_OUT)
415 {
416 DPRINT("USB2_AllocateHS: DIRECTION OUT UNIMPLEMENTED\n");
417 ASSERT(FALSE);
418 }
419 else
420 {
421 frame = TtEndpoint->StartFrame + Frame;
422 uframe = TtEndpoint->StartMicroframe + TtEndpoint->Nums.NumStarts + 1;
423
424 for (ix = 0; ix < TtEndpoint->Nums.NumCompletes; ix++)
425 {
426 if (Tt->TimeCS[frame][uframe] < USB2_FS_RAW_BYTES_IN_MICROFRAME)
427 {
428 if (Tt->TimeCS[frame][uframe] < USB2_FS_RAW_BYTES_IN_MICROFRAME)
429 {
430 RemainDataTime = USB2_FS_RAW_BYTES_IN_MICROFRAME -
431 Tt->TimeCS[frame][uframe];
432 }
433 else
434 {
435 RemainDataTime = 0;
436 }
437
438 PktSize = TtEndpoint->MaxPacketSize;
439
440 if (RemainDataTime >= USB2_AddDataBitStuff(PktSize))
441 {
442 DataTime = USB2_AddDataBitStuff(PktSize);
443 }
444 else
445 {
446 DataTime = RemainDataTime;
447 }
448
449 if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe],
450 DataTime,
451 USB2_MAX_MICROFRAME_ALLOCATION))
452 {
453 Result = FALSE;
454 }
455 }
456
457 PktSize = TtEndpoint->MaxPacketSize;
458
459 if (USB2_AddDataBitStuff(PktSize) < USB2_FS_RAW_BYTES_IN_MICROFRAME)
460 {
461 Tt->TimeCS[frame][uframe] += USB2_AddDataBitStuff(PktSize);
462 }
463 else
464 {
465 Tt->TimeCS[frame][uframe] += USB2_FS_RAW_BYTES_IN_MICROFRAME;
466 }
467
468 USB2_IncMicroFrame(&frame, &uframe);
469 }
470 }
471
472 DPRINT("USB2_AllocateHS: Result - %X\n", Result);
473 return Result;
474 }
475
476 BOOLEAN
477 NTAPI
478 USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint,
479 IN PUSB2_REBALANCE Rebalance,
480 IN PULONG RebalanceListEntries,
481 IN ULONG MaxFrames)
482 {
483 DPRINT("USB2_DeallocateEndpointBudget: UNIMPLEMENTED FIXME\n");
484 ASSERT(FALSE);
485 return FALSE;
486 }
487
488 BOOLEAN
489 NTAPI
490 USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint,
491 IN PUSB2_REBALANCE Rebalance,
492 IN PULONG RebalanceListEntries)
493 {
494 DPRINT("USB2_AllocateTimeForEndpoint: UNIMPLEMENTED. FIXME\n");
495 ASSERT(FALSE);
496 return FALSE;
497 }
498
499 BOOLEAN
500 NTAPI
501 USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint,
502 IN PUSB2_REBALANCE Rebalance,
503 IN PULONG RebalanceListEntries)
504 {
505 DPRINT1("USB2_PromotePeriods: UNIMPLEMENTED. FIXME\n");
506 ASSERT(FALSE);
507 return FALSE;
508 }
509
510 VOID
511 NTAPI
512 USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension)
513 {
514 ULONG BusBandwidth;
515 ULONG NewBusBandwidth;
516 ULONG MaxBusBandwidth = 0;
517 ULONG MinBusBandwidth;
518 ULONG ix;
519
520 DPRINT("USBPORT_UpdateAllocatedBwTt: TtExtension - %p\n", TtExtension);
521
522 BusBandwidth = TtExtension->BusBandwidth;
523 MinBusBandwidth = BusBandwidth;
524
525 for (ix = 0; ix < USB2_FRAMES; ix++)
526 {
527 NewBusBandwidth = BusBandwidth - TtExtension->Bandwidth[ix];
528
529 if (NewBusBandwidth > MaxBusBandwidth)
530 MaxBusBandwidth = NewBusBandwidth;
531
532 if (NewBusBandwidth < MinBusBandwidth)
533 MinBusBandwidth = NewBusBandwidth;
534 }
535
536 TtExtension->MaxBandwidth = MaxBusBandwidth;
537
538 if (MinBusBandwidth == BusBandwidth)
539 TtExtension->MinBandwidth = 0;
540 else
541 TtExtension->MinBandwidth = MinBusBandwidth;
542 }
543
544 BOOLEAN
545 NTAPI
546 USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice,
547 IN PUSBPORT_ENDPOINT Endpoint)
548 {
549 PUSBPORT_DEVICE_EXTENSION FdoExtension;
550 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties;
551 PUSB2_TT_EXTENSION TtExtension;
552 ULONG TransferType;
553 PUSB2_REBALANCE Rebalance;
554 LIST_ENTRY RebalanceList;
555 ULONG RebalanceListEntries;
556 PUSB2_TT_ENDPOINT TtEndpoint;
557 PUSB2_TT_ENDPOINT RebalanceTtEndpoint;
558 PUSB2_TT Tt;
559 USB_DEVICE_SPEED DeviceSpeed;
560 ULONG Period;
561 ULONG AllocedBusTime;
562 ULONG EndpointBandwidth;
563 ULONG ScheduleOffset;
564 ULONG Factor;
565 ULONG ix;
566 ULONG n;
567 BOOLEAN Direction;
568 UCHAR SMask;
569 UCHAR CMask;
570 UCHAR ActualPeriod;
571 BOOLEAN Result;
572
573 DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n",
574 FdoDevice,
575 Endpoint);
576
577 EndpointProperties = &Endpoint->EndpointProperties;
578 EndpointProperties->ScheduleOffset = 0;
579
580 if (Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0)
581 {
582 DPRINT("USBPORT_AllocateBandwidthUSB2: ENDPOINT_FLAG_ROOTHUB_EP0\n");
583 return TRUE;
584 }
585
586 FdoExtension = FdoDevice->DeviceExtension;
587
588 TransferType = EndpointProperties->TransferType;
589 DPRINT("USBPORT_AllocateBandwidthUSB2: TransferType - %X\n", TransferType);
590
591 if (TransferType == USBPORT_TRANSFER_TYPE_CONTROL ||
592 TransferType == USBPORT_TRANSFER_TYPE_BULK)
593 {
594 return TRUE;
595 }
596
597 if (Endpoint->TtExtension)
598 TtExtension = Endpoint->TtExtension;
599 else
600 TtExtension = NULL;
601
602 InitializeListHead(&RebalanceList);
603
604 Rebalance = ExAllocatePoolWithTag(NonPagedPool,
605 sizeof(USB2_REBALANCE),
606 USB_PORT_TAG);
607
608 DPRINT("USBPORT_AllocateBandwidthUSB2: Rebalance - %p, TtExtension - %p\n",
609 Rebalance,
610 TtExtension);
611
612 if (Rebalance)
613 {
614 RtlZeroMemory(Rebalance, sizeof(USB2_REBALANCE));
615
616 TtEndpoint = Endpoint->TtEndpoint;
617 TtEndpoint->Endpoint = Endpoint;
618
619 Direction = EndpointProperties->Direction == USBPORT_TRANSFER_DIRECTION_OUT;
620 DeviceSpeed = EndpointProperties->DeviceSpeed;
621
622 switch (DeviceSpeed)
623 {
624 case UsbLowSpeed:
625 case UsbFullSpeed:
626 {
627 Tt = &TtExtension->Tt;
628
629 Period = USB2_FRAMES;
630
631 while (Period > 0 && Period > EndpointProperties->Period)
632 {
633 Period >>= 1;
634 }
635
636 DPRINT("USBPORT_AllocateBandwidthUSB2: Period - %X\n", Period);
637 break;
638 }
639
640 case UsbHighSpeed:
641 {
642 Tt = &FdoExtension->Usb2Extension->HcTt;
643
644 if (EndpointProperties->Period > USB2_MAX_MICROFRAMES)
645 Period = USB2_MAX_MICROFRAMES;
646 else
647 Period = EndpointProperties->Period;
648
649 break;
650 }
651
652 default:
653 {
654 DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n",
655 DeviceSpeed);
656
657 DbgBreakPoint();
658
659 Tt = &TtExtension->Tt;
660 break;
661 }
662 }
663
664 USB2_InitTtEndpoint(TtEndpoint,
665 TransferType,
666 Direction,
667 DeviceSpeed,
668 Period,
669 EndpointProperties->MaxPacketSize,
670 Tt);
671
672 RebalanceListEntries = USB2_FRAMES - 2;
673
674 Result = USB2_AllocateTimeForEndpoint(TtEndpoint,
675 Rebalance,
676 &RebalanceListEntries);
677
678 if (Result)
679 {
680 Result = USB2_PromotePeriods(TtEndpoint,
681 Rebalance,
682 &RebalanceListEntries);
683 }
684
685 RebalanceListEntries = 0;
686
687 for (ix = 0; Rebalance->RebalanceEndpoint[ix]; ix++)
688 {
689 RebalanceListEntries = ix + 1;
690 }
691 }
692 else
693 {
694 RebalanceListEntries = 0;
695 Result = FALSE;
696 }
697
698 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceListEntries - %X, Result - %X\n",
699 RebalanceListEntries,
700 Result);
701
702 for (ix = 0; ix < RebalanceListEntries; ix++)
703 {
704 RebalanceTtEndpoint = Rebalance->RebalanceEndpoint[ix];
705
706 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceTtEndpoint[%X] - %p, RebalanceTtEndpoint - %p, RebalanceLink - %p\n",
707 ix,
708 RebalanceTtEndpoint,
709 &RebalanceTtEndpoint->Endpoint->RebalanceLink);
710
711 InsertTailList(&RebalanceList,
712 &RebalanceTtEndpoint->Endpoint->RebalanceLink);
713 }
714
715 if (Rebalance)
716 ExFreePoolWithTag(Rebalance, USB_PORT_TAG);
717
718 if (Result)
719 {
720 SMask = USB2_GetSMASK(Endpoint->TtEndpoint);
721 EndpointProperties->InterruptScheduleMask = SMask;
722
723 CMask = USB2_GetCMASK(Endpoint->TtEndpoint);
724 EndpointProperties->SplitCompletionMask = CMask;
725
726 AllocedBusTime = TtEndpoint->CalcBusTime;
727
728 EndpointBandwidth = USB2_MICROFRAMES * AllocedBusTime;
729 EndpointProperties->UsbBandwidth = EndpointBandwidth;
730
731 ActualPeriod = Endpoint->TtEndpoint->ActualPeriod;
732 EndpointProperties->Period = ActualPeriod;
733
734 ScheduleOffset = Endpoint->TtEndpoint->StartFrame;
735 EndpointProperties->ScheduleOffset = ScheduleOffset;
736
737 Factor = USB2_FRAMES / ActualPeriod;
738 ASSERT(Factor);
739
740 n = ScheduleOffset * Factor;
741
742 if (TtExtension)
743 {
744 for (ix = 0; ix < Factor; ix++)
745 {
746 TtExtension->Bandwidth[n + ix] -= EndpointBandwidth;
747 }
748 }
749 else
750 {
751 for (ix = 1; ix < Factor; ix++)
752 {
753 FdoExtension->Bandwidth[n + ix] -= EndpointBandwidth;
754 }
755 }
756
757 USBPORT_DumpingEndpointProperties(EndpointProperties);
758 USBPORT_DumpingTtEndpoint(Endpoint->TtEndpoint);
759
760 if (AllocedBusTime >= (USB2_FS_MAX_PERIODIC_ALLOCATION / 2))
761 {
762 DPRINT1("USBPORT_AllocateBandwidthUSB2: AllocedBusTime >= 0.5 * MAX_ALLOCATION \n");
763 }
764 }
765
766 //USB2_Rebalance(FdoDevice, &RebalanceList);
767
768 if (!TtExtension)
769 {
770 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result);
771 return Result;
772 }
773
774 for (ix = 0; ix < USB2_FRAMES; ix++)
775 {
776 FdoExtension->Bandwidth[ix] += TtExtension->MaxBandwidth;
777 }
778
779 USBPORT_UpdateAllocatedBwTt(TtExtension);
780
781 for (ix = 0; ix < USB2_FRAMES; ix++)
782 {
783 FdoExtension->Bandwidth[ix] -= TtExtension->MaxBandwidth;
784 }
785
786 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result);
787
788 return Result;
789 }
790
791 VOID
792 NTAPI
793 USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice,
794 IN PUSBPORT_ENDPOINT Endpoint)
795 {
796 DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
797 }
798
799 VOID
800 NTAPI
801 USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension,
802 IN PUSB2_TT Tt)
803 {
804 ULONG ix;
805 ULONG jx;
806
807 DPRINT("USB2_InitTT: HcExtension - %p, Tt - %p\n", HcExtension, Tt);
808
809 Tt->HcExtension = HcExtension;
810 Tt->DelayTime = 1;
811 Tt->MaxTime = USB2_FS_MAX_PERIODIC_ALLOCATION;
812
813 for (ix = 0; ix < USB2_FRAMES; ix++)
814 {
815 Tt->FrameBudget[ix].TimeUsed = USB2_MAX_MICROFRAMES;
816 Tt->FrameBudget[ix].AltEndpoint = NULL;
817
818 for (jx = 0; jx < USB2_MICROFRAMES; jx++)
819 {
820 Tt->TimeCS[ix][jx] = 0;
821 Tt->NumStartSplits[ix][jx] = 0;
822 }
823
824 Tt->FrameBudget[ix].IsoEndpoint = &Tt->IsoEndpoint[ix];
825
826 USB2_InitTtEndpoint(&Tt->IsoEndpoint[ix],
827 USBPORT_TRANSFER_TYPE_ISOCHRONOUS,
828 USBPORT_TRANSFER_DIRECTION_OUT,
829 UsbFullSpeed,
830 USB2_FRAMES,
831 0,
832 Tt);
833
834 Tt->IsoEndpoint[ix].ActualPeriod = USB2_FRAMES;
835 Tt->IsoEndpoint[ix].CalcBusTime = USB2_FS_SOF_TIME + USB2_HUB_DELAY;
836 Tt->IsoEndpoint[ix].StartFrame = ix;
837 Tt->IsoEndpoint[ix].StartMicroframe = 0xFF;
838
839 Tt->FrameBudget[ix].IntEndpoint = &Tt->IntEndpoint[ix];
840
841 USB2_InitTtEndpoint(&Tt->IntEndpoint[ix],
842 USBPORT_TRANSFER_TYPE_INTERRUPT,
843 USBPORT_TRANSFER_DIRECTION_OUT,
844 UsbFullSpeed,
845 USB2_FRAMES,
846 0,
847 Tt);
848
849 Tt->IntEndpoint[ix].ActualPeriod = USB2_FRAMES;
850 Tt->IntEndpoint[ix].CalcBusTime = USB2_FS_SOF_TIME + USB2_HUB_DELAY;
851 Tt->IntEndpoint[ix].StartFrame = ix;
852 Tt->IntEndpoint[ix].StartMicroframe = 0xFF;
853 }
854 }
855
856 VOID
857 NTAPI
858 USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension)
859 {
860 ULONG ix;
861 ULONG jx;
862
863 DPRINT("USB2_InitController: HcExtension - %p\n", HcExtension);
864
865 HcExtension->MaxHsBusAllocation = USB2_MAX_MICROFRAME_ALLOCATION;
866
867 for (ix = 0; ix < USB2_FRAMES; ix++)
868 {
869 for (jx = 0; jx < USB2_MICROFRAMES; jx++)
870 {
871 HcExtension->TimeUsed[ix][jx] = 0;
872 }
873 }
874
875 HcExtension->HcDelayTime = USB2_CONTROLLER_DELAY;
876
877 USB2_InitTT(HcExtension, &HcExtension->HcTt);
878 }