[USBPORT] Correcting USB2_AllocateHS().
[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 (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
255 {
256 if (nextTtEndpoint)
257 return nextTtEndpoint->StartTime + nextTtEndpoint->CalcBusTime;
258
259 ttEndpoint = TtEndpoint->Tt->FrameBudget[Frame].AltEndpoint;
260
261 if (ttEndpoint)
262 return ttEndpoint->StartTime + ttEndpoint->CalcBusTime;
263 else
264 return USB2_FS_SOF_TIME;
265 }
266 else
267 {
268 ttEndpoint = prevTtEndpoint;
269
270 if (ttEndpoint == TtEndpoint->Tt->FrameBudget[Frame].IntEndpoint)
271 return USB2_GetLastIsoTime(TtEndpoint, Frame);
272 else
273 return ttEndpoint->StartTime + ttEndpoint->CalcBusTime;
274 }
275 }
276
277 VOID
278 NTAPI
279 USB2_InitTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint,
280 IN UCHAR TransferType,
281 IN UCHAR Direction,
282 IN UCHAR DeviceSpeed,
283 IN USHORT Period,
284 IN USHORT MaxPacketSize,
285 IN PUSB2_TT Tt)
286 {
287 TtEndpoint->TtEndpointParams.TransferType = TransferType;
288 TtEndpoint->TtEndpointParams.Direction = Direction;
289 TtEndpoint->TtEndpointParams.DeviceSpeed = DeviceSpeed;
290
291 TtEndpoint->Period = Period;
292 TtEndpoint->MaxPacketSize = MaxPacketSize;
293 TtEndpoint->Tt = Tt;
294
295 TtEndpoint->CalcBusTime = 0;
296 TtEndpoint->StartTime = 0;
297 TtEndpoint->ActualPeriod = 0;
298 TtEndpoint->StartFrame = 0;
299 TtEndpoint->StartMicroframe = 0;
300
301 TtEndpoint->Nums.AsULONG = 0;
302 TtEndpoint->NextTtEndpoint = NULL;
303 TtEndpoint->Reserved2 = 0;
304 TtEndpoint->PreviosPeriod = 0;
305 TtEndpoint->IsPromoted = FALSE;
306 }
307
308 BOOLEAN
309 NTAPI
310 USB2_AllocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint,
311 IN LONG Frame)
312 {
313 PUSB2_HC_EXTENSION HcExtension;
314 PUSB2_TT Tt;
315 ULONG TransferType;
316 ULONG Direction;
317 ULONG DataTime;
318 ULONG DataSize;
319 ULONG RemainDataTime;
320 ULONG OverheadCS;
321 ULONG OverheadSS;
322 ULONG ix;
323 USHORT PktSize;
324 USHORT PktSizeBitStuff;
325 UCHAR frame;
326 UCHAR uframe;
327 BOOL Result = TRUE;
328
329 DPRINT("USB2_AllocateHS: TtEndpoint - %p, Frame - %X, StartFrame - %X\n",
330 TtEndpoint,
331 Frame,
332 TtEndpoint->StartFrame);
333
334 Tt = TtEndpoint->Tt;
335 HcExtension = Tt->HcExtension;
336
337 TransferType = TtEndpoint->TtEndpointParams.TransferType;
338 Direction = TtEndpoint->TtEndpointParams.Direction;
339
340 if (Frame == 0)
341 {
342 TtEndpoint->StartMicroframe =
343 TtEndpoint->StartTime / USB2_FS_RAW_BYTES_IN_MICROFRAME - 1;
344
345 DPRINT("USB2_AllocateHS: TtEndpoint->StartMicroframe - %X\n",
346 TtEndpoint->StartMicroframe);
347 }
348
349 USB2_GetHsOverhead(TtEndpoint, &OverheadSS, &OverheadCS);
350
351 if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
352 {
353 if (Frame == 0)
354 {
355 TtEndpoint->Nums.NumStarts = 1;
356
357 if ((CHAR)TtEndpoint->StartMicroframe < (USB2_MICROFRAMES - 3))
358 TtEndpoint->Nums.NumCompletes = 3;
359 else
360 TtEndpoint->Nums.NumCompletes = 2;
361 }
362 }
363 else
364 {
365 if (Direction == USBPORT_TRANSFER_DIRECTION_OUT)
366 {
367 DPRINT("USB2_AllocateHS: ISO UNIMPLEMENTED\n");
368 ASSERT(FALSE);
369 }
370 else
371 {
372 DPRINT("USB2_AllocateHS: ISO UNIMPLEMENTED\n");
373 ASSERT(FALSE);
374 }
375 }
376
377 frame = TtEndpoint->StartFrame + Frame;
378 uframe = TtEndpoint->StartMicroframe;
379
380 if (TtEndpoint->StartMicroframe == 0xFF)
381 USB2_GetPrevMicroFrame(&frame, &uframe);
382
383 for (ix = 0; ix < TtEndpoint->Nums.NumStarts; ix++)
384 {
385 if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe],
386 OverheadSS,
387 USB2_MAX_MICROFRAME_ALLOCATION))
388 {
389 Result = FALSE;
390 }
391
392 if (Tt->NumStartSplits[frame][uframe] >
393 (USB2_MAX_FS_LS_TRANSACTIONS_IN_UFRAME - 1))
394 {
395 DPRINT1("USB2_AllocateHS: Num Start Splits - %X\n",
396 Tt->NumStartSplits[frame][uframe] + 1);
397
398 ASSERT(FALSE);
399 Result = FALSE;
400 }
401
402 ++Tt->NumStartSplits[frame][uframe];
403 USB2_IncMicroFrame(&frame, &uframe);
404 }
405
406 frame = TtEndpoint->StartFrame + Frame;
407 uframe = TtEndpoint->StartMicroframe + TtEndpoint->Nums.NumStarts + 1;
408
409 for (ix = 0; ix < TtEndpoint->Nums.NumCompletes; ix++)
410 {
411 if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe],
412 OverheadCS,
413 USB2_MAX_MICROFRAME_ALLOCATION))
414 {
415 Result = FALSE;
416 }
417
418 USB2_IncMicroFrame(&frame, &uframe);
419 }
420
421 PktSize = TtEndpoint->MaxPacketSize;
422 PktSizeBitStuff = USB2_AddDataBitStuff(PktSize);
423
424 if (Direction == USBPORT_TRANSFER_DIRECTION_OUT)
425 {
426 frame = TtEndpoint->StartFrame + Frame;
427 uframe = TtEndpoint->StartMicroframe;
428
429 if (uframe == 0xFF)
430 USB2_GetPrevMicroFrame(&frame, &uframe);
431
432 DataTime = 0;
433
434 for (ix = 0; ix < TtEndpoint->Nums.NumStarts; ix++)
435 {
436 DataSize = PktSizeBitStuff - DataTime;
437
438 if (DataSize <= USB2_FS_RAW_BYTES_IN_MICROFRAME)
439 DataTime = DataSize;
440 else
441 DataTime = USB2_FS_RAW_BYTES_IN_MICROFRAME;
442
443 DPRINT("USB2_AllocateHS: ix - %X, frame - %X, uframe - %X, TimeUsed - %X\n",
444 ix,
445 frame,
446 uframe,
447 HcExtension->TimeUsed[frame][uframe]);
448
449 if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe],
450 DataTime,
451 USB2_MAX_MICROFRAME_ALLOCATION))
452 {
453 Result = FALSE;
454 }
455
456 USB2_IncMicroFrame(&frame, &uframe);
457 DataTime += USB2_FS_RAW_BYTES_IN_MICROFRAME;
458 }
459 }
460 else
461 {
462 frame = TtEndpoint->StartFrame + Frame;
463 uframe = TtEndpoint->StartMicroframe + TtEndpoint->Nums.NumStarts + 1;
464
465 for (ix = 0; ix < TtEndpoint->Nums.NumCompletes; ix++)
466 {
467 if (Tt->TimeCS[frame][uframe] < USB2_FS_RAW_BYTES_IN_MICROFRAME)
468 {
469 RemainDataTime = USB2_FS_RAW_BYTES_IN_MICROFRAME -
470 Tt->TimeCS[frame][uframe];
471
472 if (RemainDataTime >= PktSizeBitStuff)
473 {
474 DataTime = PktSizeBitStuff;
475 }
476 else if (RemainDataTime > 0)
477 {
478 DataTime = RemainDataTime;
479 }
480 else
481 {
482 DataTime = 0;
483 }
484
485 if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe],
486 DataTime,
487 USB2_MAX_MICROFRAME_ALLOCATION))
488 {
489 Result = FALSE;
490 }
491 }
492
493 if (PktSizeBitStuff < USB2_FS_RAW_BYTES_IN_MICROFRAME)
494 Tt->TimeCS[frame][uframe] += PktSizeBitStuff;
495 else
496 Tt->TimeCS[frame][uframe] += USB2_FS_RAW_BYTES_IN_MICROFRAME;
497
498 USB2_IncMicroFrame(&frame, &uframe);
499 }
500 }
501
502 DPRINT("USB2_AllocateHS: Result - %X\n", Result);
503 return Result;
504 }
505
506 VOID
507 NTAPI
508 USB2_DeallocateHS(IN PUSB2_TT_ENDPOINT TtEndpoint,
509 IN ULONG Frame)
510 {
511 DPRINT("USB2_DeallocateHS: UNIMPLEMENTED FIXME\n");
512 ASSERT(FALSE);
513 }
514
515 BOOLEAN
516 NTAPI
517 USB2_MoveTtEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint,
518 IN USHORT BusTime,
519 IN PUSB2_REBALANCE Rebalance,
520 IN ULONG RebalanceListEntries,
521 OUT BOOLEAN * OutResult)
522 {
523 DPRINT("USB2_MoveTtEndpoint: UNIMPLEMENTED FIXME\n");
524 ASSERT(FALSE);
525 return FALSE;
526 }
527
528 VOID
529 NTAPI
530 USB2_ConvertFrame(IN UCHAR Frame,
531 IN UCHAR Microframe,
532 OUT PUCHAR HcFrame,
533 OUT PUCHAR HcMicroframe)
534 {
535 DPRINT("USB2_ConvertFrame: Frame - %x, Microframe - %x\n",
536 Frame,
537 Microframe);
538
539 if (Microframe == 0xFF)
540 {
541 *HcFrame = Frame;
542 *HcMicroframe = 0;
543 }
544
545 if (Microframe >= 0 &&
546 Microframe <= (USB2_MICROFRAMES - 2))
547 {
548 *HcFrame = Frame;
549 *HcMicroframe = Microframe + 1;
550 }
551
552 if (Microframe == (USB2_MICROFRAMES - 1))
553 {
554 *HcFrame = Frame + 1;
555 *HcMicroframe = 0;
556 }
557 }
558
559 UCHAR
560 NTAPI
561 USB2_GetSMASK(IN PUSB2_TT_ENDPOINT TtEndpoint)
562 {
563 ULONG ix;
564 UCHAR SMask = 0;
565 UCHAR HcFrame;
566 UCHAR HcMicroFrame;
567
568 if (TtEndpoint->TtEndpointParams.DeviceSpeed == UsbHighSpeed)
569 {
570 SMask = (1 << TtEndpoint->StartMicroframe);
571 }
572 else
573 {
574 USB2_ConvertFrame(TtEndpoint->StartFrame,
575 TtEndpoint->StartMicroframe,
576 &HcFrame,
577 &HcMicroFrame);
578
579 for (ix = 0; ix < TtEndpoint->Nums.NumStarts; ix++)
580 {
581 SMask |= (1 << HcMicroFrame);
582 HcMicroFrame++;
583 }
584 }
585
586 return SMask;
587 }
588
589 UCHAR
590 NTAPI
591 USB2_GetCMASK(IN PUSB2_TT_ENDPOINT TtEndpoint)
592 {
593 ULONG NumCompletes;
594 ULONG TransferType;
595 ULONG DeviceSpeed;
596 ULONG Direction;
597 UCHAR Result;
598 UCHAR MicroFrameCS;
599 UCHAR HcFrame;
600 UCHAR HcMicroFrame;
601 UCHAR MaskCS = 0;
602 static const UCHAR CMASKS[USB2_MICROFRAMES] = {
603 0x1C, 0x38, 0x70, 0xE0, 0xC1, 0x83, 0x07, 0x0E
604 };
605
606 TransferType = TtEndpoint->TtEndpointParams.TransferType;
607 DeviceSpeed = TtEndpoint->TtEndpointParams.DeviceSpeed;
608 Direction = TtEndpoint->TtEndpointParams.Direction;
609
610 if (DeviceSpeed == UsbHighSpeed)
611 {
612 return 0;
613 }
614
615 if (TransferType == USBPORT_TRANSFER_TYPE_INTERRUPT)
616 {
617 USB2_ConvertFrame(TtEndpoint->StartFrame,
618 TtEndpoint->StartMicroframe,
619 &HcFrame,
620 &HcMicroFrame);
621
622 Result = CMASKS[HcMicroFrame];
623 }
624 else
625 {
626 if (Direction == USBPORT_TRANSFER_DIRECTION_OUT)
627 {
628 return 0;
629 }
630
631 USB2_ConvertFrame(TtEndpoint->StartFrame,
632 TtEndpoint->StartMicroframe,
633 &HcFrame,
634 &HcMicroFrame);
635
636 NumCompletes = TtEndpoint->Nums.NumCompletes;
637
638 for (MicroFrameCS = HcMicroFrame + 2;
639 MicroFrameCS < USB2_MICROFRAMES;
640 MicroFrameCS++)
641 {
642 MaskCS |= (1 << MicroFrameCS);
643 NumCompletes--;
644
645 if (!NumCompletes)
646 {
647 return MaskCS;
648 }
649 }
650
651 for (; NumCompletes; NumCompletes--)
652 {
653 MaskCS |= (1 << (MicroFrameCS - USB2_MICROFRAMES));
654 }
655
656 Result = MaskCS;
657 }
658
659 return Result;
660 }
661
662 BOOLEAN
663 NTAPI
664 USB2_DeallocateEndpointBudget(IN PUSB2_TT_ENDPOINT TtEndpoint,
665 IN PUSB2_REBALANCE Rebalance,
666 IN PULONG RebalanceListEntries,
667 IN ULONG MaxFrames)
668 {
669 DPRINT("USB2_DeallocateEndpointBudget: UNIMPLEMENTED FIXME\n");
670 ASSERT(FALSE);
671 return FALSE;
672 }
673
674 BOOLEAN
675 NTAPI
676 USB2_AllocateTimeForEndpoint(IN PUSB2_TT_ENDPOINT TtEndpoint,
677 IN PUSB2_REBALANCE Rebalance,
678 IN PULONG RebalanceListEntries)
679 {
680 PUSB2_TT Tt;
681 PUSB2_HC_EXTENSION HcExtension;
682 ULONG Speed;
683 ULONG TimeUsed;
684 ULONG MinTimeUsed;
685 ULONG ix;
686 ULONG frame;
687 ULONG uframe;
688 ULONG Microframe;
689 ULONG TransferType;
690 ULONG Overhead;
691 ULONG LatestStart;
692 PUSB2_TT_ENDPOINT prevTtEndpoint;
693 PUSB2_TT_ENDPOINT nextTtEndpoint;
694 PUSB2_TT_ENDPOINT IntEndpoint;
695 ULONG StartTime;
696 ULONG calcBusTime;
697 BOOLEAN Result = TRUE;
698
699 DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p\n", TtEndpoint);
700
701 Tt = TtEndpoint->Tt;
702 HcExtension = Tt->HcExtension;
703
704 TtEndpoint->Nums.NumStarts = 0;
705 TtEndpoint->Nums.NumCompletes = 0;
706
707 TtEndpoint->StartFrame = 0;
708 TtEndpoint->StartMicroframe = 0;
709
710 if (TtEndpoint->CalcBusTime)
711 {
712 DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint already allocated!\n");
713 return FALSE;
714 }
715
716 Speed = TtEndpoint->TtEndpointParams.DeviceSpeed;
717
718 if (Speed == UsbHighSpeed)
719 {
720 if (TtEndpoint->Period > USB2_MAX_MICROFRAMES)
721 TtEndpoint->ActualPeriod = USB2_MAX_MICROFRAMES;
722 else
723 TtEndpoint->ActualPeriod = TtEndpoint->Period;
724
725 MinTimeUsed = HcExtension->TimeUsed[0][0];
726
727 for (ix = 1; ix < TtEndpoint->ActualPeriod; ix++)
728 {
729 frame = ix / USB2_MICROFRAMES;
730 uframe = ix % (USB2_MICROFRAMES - 1);
731
732 TimeUsed = HcExtension->TimeUsed[frame][uframe];
733
734 if (TimeUsed < MinTimeUsed)
735 {
736 MinTimeUsed = TimeUsed;
737 TtEndpoint->StartFrame = frame;
738 TtEndpoint->StartMicroframe = uframe;
739 }
740 }
741
742 TtEndpoint->CalcBusTime = USB2_GetOverhead(TtEndpoint) +
743 USB2_AddDataBitStuff(TtEndpoint->MaxPacketSize);
744
745 DPRINT("USB2_AllocateTimeForEndpoint: StartFrame - %X, StartMicroframe - %X, CalcBusTime - %X\n",
746 TtEndpoint->StartFrame,
747 TtEndpoint->StartMicroframe,
748 TtEndpoint->CalcBusTime);
749
750 Microframe = TtEndpoint->StartFrame * USB2_MICROFRAMES +
751 TtEndpoint->StartMicroframe;
752
753 if (Microframe >= USB2_MAX_MICROFRAMES)
754 {
755 DPRINT("USB2_AllocateTimeForEndpoint: Microframe >= 256. Result - TRUE\n");
756 return TRUE;
757 }
758
759 for (ix = Microframe;
760 ix < USB2_MAX_MICROFRAMES;
761 ix += TtEndpoint->ActualPeriod)
762 {
763 frame = ix / USB2_MICROFRAMES;
764 uframe = ix % (USB2_MICROFRAMES - 1);
765
766 DPRINT("USB2_AllocateTimeForEndpoint: frame - %X, uframe - %X, TimeUsed[f][uf] - %X\n",
767 frame,
768 uframe,
769 HcExtension->TimeUsed[frame][uframe]);
770
771 if (!USB2_AllocateCheck(&HcExtension->TimeUsed[frame][uframe],
772 TtEndpoint->CalcBusTime,
773 USB2_MAX_MICROFRAME_ALLOCATION))
774 {
775 DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n");
776 Result = FALSE;
777 }
778 }
779
780 if (!Result)
781 {
782 for (ix = Microframe;
783 ix < USB2_MAX_MICROFRAMES;
784 ix += TtEndpoint->ActualPeriod)
785 {
786 frame = ix / USB2_MICROFRAMES;
787 uframe = ix % (USB2_MICROFRAMES - 1);
788
789 HcExtension->TimeUsed[frame][uframe] -= TtEndpoint->CalcBusTime;
790 }
791 }
792
793 DPRINT("USB2_AllocateTimeForEndpoint: Result - TRUE\n");
794 return TRUE;
795 }
796
797 /* Speed != UsbHighSpeed (FS/LS) */
798
799 if (TtEndpoint->Period > USB2_FRAMES)
800 TtEndpoint->ActualPeriod = USB2_FRAMES;
801 else
802 TtEndpoint->ActualPeriod = TtEndpoint->Period;
803
804 MinTimeUsed = Tt->FrameBudget[0].TimeUsed;
805
806 for (ix = 1; ix < TtEndpoint->ActualPeriod; ix++)
807 {
808 if ((Tt->FrameBudget[ix].TimeUsed) < MinTimeUsed)
809 {
810 MinTimeUsed = Tt->FrameBudget[ix].TimeUsed;
811 TtEndpoint->StartFrame = ix;
812 }
813 }
814
815 TransferType = TtEndpoint->TtEndpointParams.TransferType;
816
817 if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
818 {
819 if (Speed == UsbFullSpeed)
820 {
821 Overhead = USB2_FS_ISOCHRONOUS_OVERHEAD + Tt->DelayTime;
822 }
823 else
824 {
825 DPRINT("USB2_AllocateTimeForEndpoint: ISO can not be on a LS bus!\n");
826 return FALSE;
827 }
828 }
829 else
830 {
831 if (Speed == UsbFullSpeed)
832 Overhead = USB2_FS_INTERRUPT_OVERHEAD + Tt->DelayTime;
833 else
834 Overhead = USB2_LS_INTERRUPT_OVERHEAD + Tt->DelayTime;
835 }
836
837 if (Speed == UsbLowSpeed)
838 {
839 TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize * 8 + Overhead;
840 }
841 else
842 {
843 TtEndpoint->CalcBusTime = TtEndpoint->MaxPacketSize + Overhead;
844 }
845
846 LatestStart = USB2_HUB_DELAY + USB2_FS_SOF_TIME;
847
848 for (ix = 0;
849 (TtEndpoint->StartFrame + ix) < USB2_FRAMES;
850 ix += TtEndpoint->ActualPeriod)
851 {
852 frame = TtEndpoint->StartFrame + ix;
853
854 if (Tt->FrameBudget[frame].AltEndpoint &&
855 TtEndpoint->CalcBusTime >= (USB2_FS_MAX_PERIODIC_ALLOCATION / 2))
856 {
857 DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n");
858 return FALSE;
859 }
860
861 if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
862 prevTtEndpoint = Tt->FrameBudget[frame].IsoEndpoint;
863 else
864 prevTtEndpoint = Tt->FrameBudget[frame].IntEndpoint;
865
866 for (nextTtEndpoint = prevTtEndpoint->NextTtEndpoint;
867 nextTtEndpoint;
868 nextTtEndpoint = nextTtEndpoint->NextTtEndpoint)
869 {
870 if (USB2_CheckTtEndpointInsert(nextTtEndpoint, TtEndpoint))
871 {
872 break;
873 }
874
875 prevTtEndpoint = nextTtEndpoint;
876 }
877
878 StartTime = USB2_GetStartTime(nextTtEndpoint,
879 TtEndpoint,
880 prevTtEndpoint,
881 frame);
882
883 if (StartTime > LatestStart)
884 LatestStart = StartTime;
885 }
886
887 TtEndpoint->StartTime = LatestStart;
888
889 if ((LatestStart + TtEndpoint->CalcBusTime) > USB2_FS_MAX_PERIODIC_ALLOCATION)
890 {
891 TtEndpoint->CalcBusTime = 0;
892 DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n");
893 return FALSE;
894 }
895
896 for (ix = 0, frame = -TtEndpoint->StartFrame;
897 ix < USB2_FRAMES;
898 ix++, frame++)
899 {
900 DPRINT("USB2_AllocateTimeForEndpoint: ix - %X, frame - %X, StartFrame - %X\n",
901 ix,
902 frame,
903 TtEndpoint->StartFrame);
904
905 if (TransferType == USBPORT_TRANSFER_TYPE_ISOCHRONOUS)
906 {
907 DPRINT1("USB2_AllocateTimeForEndpoint: Iso Ep UNIMPLEMENTED. FIXME\n");
908 ASSERT(FALSE);
909 }
910 else
911 {
912 IntEndpoint = Tt->FrameBudget[ix].IntEndpoint;
913 nextTtEndpoint = IntEndpoint->NextTtEndpoint;
914
915 for (nextTtEndpoint = IntEndpoint->NextTtEndpoint;
916 nextTtEndpoint;
917 nextTtEndpoint = nextTtEndpoint->NextTtEndpoint)
918 {
919 if (USB2_CheckTtEndpointInsert(nextTtEndpoint, TtEndpoint))
920 break;
921 IntEndpoint = nextTtEndpoint;
922 }
923
924 if ((frame % TtEndpoint->ActualPeriod) == 0)
925 {
926 calcBusTime = 0;
927 }
928 else
929 {
930 if (nextTtEndpoint)
931 {
932 calcBusTime = LatestStart + TtEndpoint->CalcBusTime -
933 nextTtEndpoint->StartTime;
934 }
935 else
936 {
937 calcBusTime = TtEndpoint->CalcBusTime;
938 }
939
940 if (calcBusTime > 0)
941 {
942 TimeUsed = Tt->FrameBudget[ix].TimeUsed;
943
944 if (!USB2_AllocateCheck(&TimeUsed,
945 calcBusTime,
946 USB2_FS_MAX_PERIODIC_ALLOCATION))
947 {
948 DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n");
949 Result = FALSE;
950 }
951 }
952 }
953
954 if (nextTtEndpoint != TtEndpoint)
955 {
956 if ((frame % TtEndpoint->ActualPeriod) == 0)
957 {
958 if (frame == 0)
959 {
960 DPRINT("USB2_AllocateTimeForEndpoint: frame == 0\n");
961 TtEndpoint->NextTtEndpoint = nextTtEndpoint;
962 }
963
964 IntEndpoint->NextTtEndpoint = TtEndpoint;
965
966 DPRINT("USB2_AllocateTimeForEndpoint: TtEndpoint - %p, nextTtEndpoint - %p\n",
967 TtEndpoint,
968 nextTtEndpoint);
969 }
970
971 if (calcBusTime > 0)
972 {
973 BOOLEAN IsMoved;
974 BOOLEAN MoveResult;
975
976 DPRINT("USB2_AllocateTimeForEndpoint: nextTtEndpoint - %p, calcBusTime - %X\n",
977 nextTtEndpoint,
978 calcBusTime);
979
980 for (;
981 nextTtEndpoint;
982 nextTtEndpoint = nextTtEndpoint->NextTtEndpoint)
983 {
984 MoveResult = USB2_MoveTtEndpoint(nextTtEndpoint,
985 calcBusTime,
986 Rebalance,
987 *RebalanceListEntries,
988 &IsMoved);
989
990 if (!IsMoved)
991 {
992 DPRINT("USB2_AllocateTimeForEndpoint: Result = FALSE\n");
993 Result = FALSE;
994 }
995
996 if (!MoveResult)
997 break;
998 }
999 }
1000 }
1001 }
1002
1003 if ((frame % TtEndpoint->ActualPeriod) == 0)
1004 {
1005 if (!USB2_AllocateHS(TtEndpoint, frame))
1006 {
1007 DPRINT1("USB2_AllocateTimeForEndpoint: USB2_AllocateHS return FALSE\n");
1008 Result = FALSE;
1009 }
1010
1011 Tt->FrameBudget[ix].TimeUsed += TtEndpoint->CalcBusTime;
1012 }
1013
1014 if (Result == FALSE)
1015 {
1016 USB2_DeallocateEndpointBudget(TtEndpoint,
1017 Rebalance,
1018 RebalanceListEntries,
1019 ix + 1);
1020
1021 DPRINT("USB2_AllocateTimeForEndpoint: return FALSE\n");
1022 return FALSE;
1023 }
1024 }
1025
1026 DPRINT("USB2_AllocateTimeForEndpoint: Result - %X\n", Result);
1027 return Result;
1028 }
1029
1030 BOOLEAN
1031 NTAPI
1032 USB2_PromotePeriods(IN PUSB2_TT_ENDPOINT TtEndpoint,
1033 IN PUSB2_REBALANCE Rebalance,
1034 IN PULONG RebalanceListEntries)
1035 {
1036 DPRINT1("USB2_PromotePeriods: UNIMPLEMENTED. FIXME\n");
1037 ASSERT(FALSE);
1038 return FALSE;
1039 }
1040
1041 VOID
1042 NTAPI
1043 USBPORT_UpdateAllocatedBwTt(IN PUSB2_TT_EXTENSION TtExtension)
1044 {
1045 ULONG BusBandwidth;
1046 ULONG NewBusBandwidth;
1047 ULONG MaxBusBandwidth = 0;
1048 ULONG MinBusBandwidth;
1049 ULONG ix;
1050
1051 DPRINT("USBPORT_UpdateAllocatedBwTt: TtExtension - %p\n", TtExtension);
1052
1053 BusBandwidth = TtExtension->BusBandwidth;
1054 MinBusBandwidth = BusBandwidth;
1055
1056 for (ix = 0; ix < USB2_FRAMES; ix++)
1057 {
1058 NewBusBandwidth = BusBandwidth - TtExtension->Bandwidth[ix];
1059
1060 if (NewBusBandwidth > MaxBusBandwidth)
1061 MaxBusBandwidth = NewBusBandwidth;
1062
1063 if (NewBusBandwidth < MinBusBandwidth)
1064 MinBusBandwidth = NewBusBandwidth;
1065 }
1066
1067 TtExtension->MaxBandwidth = MaxBusBandwidth;
1068
1069 if (MinBusBandwidth == BusBandwidth)
1070 TtExtension->MinBandwidth = 0;
1071 else
1072 TtExtension->MinBandwidth = MinBusBandwidth;
1073 }
1074
1075 BOOLEAN
1076 NTAPI
1077 USBPORT_AllocateBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice,
1078 IN PUSBPORT_ENDPOINT Endpoint)
1079 {
1080 PUSBPORT_DEVICE_EXTENSION FdoExtension;
1081 PUSBPORT_ENDPOINT_PROPERTIES EndpointProperties;
1082 PUSB2_TT_EXTENSION TtExtension;
1083 ULONG TransferType;
1084 PUSB2_REBALANCE Rebalance;
1085 LIST_ENTRY RebalanceList;
1086 ULONG RebalanceListEntries;
1087 PUSB2_TT_ENDPOINT TtEndpoint;
1088 PUSB2_TT_ENDPOINT RebalanceTtEndpoint;
1089 PUSB2_TT Tt;
1090 USB_DEVICE_SPEED DeviceSpeed;
1091 ULONG Period;
1092 ULONG AllocedBusTime;
1093 ULONG EndpointBandwidth;
1094 ULONG ScheduleOffset;
1095 ULONG Factor;
1096 ULONG ix;
1097 ULONG n;
1098 BOOLEAN Direction;
1099 UCHAR SMask;
1100 UCHAR CMask;
1101 UCHAR ActualPeriod;
1102 BOOLEAN Result;
1103
1104 DPRINT("USBPORT_AllocateBandwidthUSB2: FdoDevice - %p, Endpoint - %p\n",
1105 FdoDevice,
1106 Endpoint);
1107
1108 EndpointProperties = &Endpoint->EndpointProperties;
1109 EndpointProperties->ScheduleOffset = 0;
1110
1111 if (Endpoint->Flags & ENDPOINT_FLAG_ROOTHUB_EP0)
1112 {
1113 DPRINT("USBPORT_AllocateBandwidthUSB2: ENDPOINT_FLAG_ROOTHUB_EP0\n");
1114 return TRUE;
1115 }
1116
1117 FdoExtension = FdoDevice->DeviceExtension;
1118
1119 TransferType = EndpointProperties->TransferType;
1120 DPRINT("USBPORT_AllocateBandwidthUSB2: TransferType - %X\n", TransferType);
1121
1122 if (TransferType == USBPORT_TRANSFER_TYPE_CONTROL ||
1123 TransferType == USBPORT_TRANSFER_TYPE_BULK)
1124 {
1125 return TRUE;
1126 }
1127
1128 if (Endpoint->TtExtension)
1129 TtExtension = Endpoint->TtExtension;
1130 else
1131 TtExtension = NULL;
1132
1133 InitializeListHead(&RebalanceList);
1134
1135 Rebalance = ExAllocatePoolWithTag(NonPagedPool,
1136 sizeof(USB2_REBALANCE),
1137 USB_PORT_TAG);
1138
1139 DPRINT("USBPORT_AllocateBandwidthUSB2: Rebalance - %p, TtExtension - %p\n",
1140 Rebalance,
1141 TtExtension);
1142
1143 if (Rebalance)
1144 {
1145 RtlZeroMemory(Rebalance, sizeof(USB2_REBALANCE));
1146
1147 TtEndpoint = Endpoint->TtEndpoint;
1148 TtEndpoint->Endpoint = Endpoint;
1149
1150 Direction = EndpointProperties->Direction == USBPORT_TRANSFER_DIRECTION_OUT;
1151 DeviceSpeed = EndpointProperties->DeviceSpeed;
1152
1153 switch (DeviceSpeed)
1154 {
1155 case UsbLowSpeed:
1156 case UsbFullSpeed:
1157 {
1158 Tt = &TtExtension->Tt;
1159
1160 Period = USB2_FRAMES;
1161
1162 while (Period > 0 && Period > EndpointProperties->Period)
1163 {
1164 Period >>= 1;
1165 }
1166
1167 DPRINT("USBPORT_AllocateBandwidthUSB2: Period - %X\n", Period);
1168 break;
1169 }
1170
1171 case UsbHighSpeed:
1172 {
1173 Tt = &FdoExtension->Usb2Extension->HcTt;
1174
1175 if (EndpointProperties->Period > USB2_MAX_MICROFRAMES)
1176 Period = USB2_MAX_MICROFRAMES;
1177 else
1178 Period = EndpointProperties->Period;
1179
1180 break;
1181 }
1182
1183 default:
1184 {
1185 DPRINT1("USBPORT_AllocateBandwidthUSB2: DeviceSpeed - %X!\n",
1186 DeviceSpeed);
1187
1188 DbgBreakPoint();
1189
1190 Tt = &TtExtension->Tt;
1191 break;
1192 }
1193 }
1194
1195 USB2_InitTtEndpoint(TtEndpoint,
1196 TransferType,
1197 Direction,
1198 DeviceSpeed,
1199 Period,
1200 EndpointProperties->MaxPacketSize,
1201 Tt);
1202
1203 RebalanceListEntries = USB2_FRAMES - 2;
1204
1205 Result = USB2_AllocateTimeForEndpoint(TtEndpoint,
1206 Rebalance,
1207 &RebalanceListEntries);
1208
1209 if (Result)
1210 {
1211 Result = USB2_PromotePeriods(TtEndpoint,
1212 Rebalance,
1213 &RebalanceListEntries);
1214 }
1215
1216 RebalanceListEntries = 0;
1217
1218 for (ix = 0; Rebalance->RebalanceEndpoint[ix]; ix++)
1219 {
1220 RebalanceListEntries = ix + 1;
1221 }
1222 }
1223 else
1224 {
1225 RebalanceListEntries = 0;
1226 Result = FALSE;
1227 }
1228
1229 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceListEntries - %X, Result - %X\n",
1230 RebalanceListEntries,
1231 Result);
1232
1233 for (ix = 0; ix < RebalanceListEntries; ix++)
1234 {
1235 RebalanceTtEndpoint = Rebalance->RebalanceEndpoint[ix];
1236
1237 DPRINT("USBPORT_AllocateBandwidthUSB2: RebalanceTtEndpoint[%X] - %p, RebalanceTtEndpoint - %p, RebalanceLink - %p\n",
1238 ix,
1239 RebalanceTtEndpoint,
1240 &RebalanceTtEndpoint->Endpoint->RebalanceLink);
1241
1242 InsertTailList(&RebalanceList,
1243 &RebalanceTtEndpoint->Endpoint->RebalanceLink);
1244 }
1245
1246 if (Rebalance)
1247 ExFreePoolWithTag(Rebalance, USB_PORT_TAG);
1248
1249 if (Result)
1250 {
1251 SMask = USB2_GetSMASK(Endpoint->TtEndpoint);
1252 EndpointProperties->InterruptScheduleMask = SMask;
1253
1254 CMask = USB2_GetCMASK(Endpoint->TtEndpoint);
1255 EndpointProperties->SplitCompletionMask = CMask;
1256
1257 AllocedBusTime = TtEndpoint->CalcBusTime;
1258
1259 EndpointBandwidth = USB2_MICROFRAMES * AllocedBusTime;
1260 EndpointProperties->UsbBandwidth = EndpointBandwidth;
1261
1262 ActualPeriod = Endpoint->TtEndpoint->ActualPeriod;
1263 EndpointProperties->Period = ActualPeriod;
1264
1265 ScheduleOffset = Endpoint->TtEndpoint->StartFrame;
1266 EndpointProperties->ScheduleOffset = ScheduleOffset;
1267
1268 Factor = USB2_FRAMES / ActualPeriod;
1269 ASSERT(Factor);
1270
1271 n = ScheduleOffset * Factor;
1272
1273 if (TtExtension)
1274 {
1275 for (ix = 0; ix < Factor; ix++)
1276 {
1277 TtExtension->Bandwidth[n + ix] -= EndpointBandwidth;
1278 }
1279 }
1280 else
1281 {
1282 for (ix = 1; ix < Factor; ix++)
1283 {
1284 FdoExtension->Bandwidth[n + ix] -= EndpointBandwidth;
1285 }
1286 }
1287
1288 USBPORT_DumpingEndpointProperties(EndpointProperties);
1289 USBPORT_DumpingTtEndpoint(Endpoint->TtEndpoint);
1290
1291 if (AllocedBusTime >= (USB2_FS_MAX_PERIODIC_ALLOCATION / 2))
1292 {
1293 DPRINT1("USBPORT_AllocateBandwidthUSB2: AllocedBusTime >= 0.5 * MAX_ALLOCATION \n");
1294 }
1295 }
1296
1297 //USB2_Rebalance(FdoDevice, &RebalanceList);
1298
1299 if (!TtExtension)
1300 {
1301 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result);
1302 return Result;
1303 }
1304
1305 for (ix = 0; ix < USB2_FRAMES; ix++)
1306 {
1307 FdoExtension->Bandwidth[ix] += TtExtension->MaxBandwidth;
1308 }
1309
1310 USBPORT_UpdateAllocatedBwTt(TtExtension);
1311
1312 for (ix = 0; ix < USB2_FRAMES; ix++)
1313 {
1314 FdoExtension->Bandwidth[ix] -= TtExtension->MaxBandwidth;
1315 }
1316
1317 DPRINT("USBPORT_AllocateBandwidthUSB2: Result - %X\n", Result);
1318
1319 return Result;
1320 }
1321
1322 VOID
1323 NTAPI
1324 USBPORT_FreeBandwidthUSB2(IN PDEVICE_OBJECT FdoDevice,
1325 IN PUSBPORT_ENDPOINT Endpoint)
1326 {
1327 DPRINT1("USBPORT_FreeBandwidthUSB2: UNIMPLEMENTED. FIXME. \n");
1328 }
1329
1330 VOID
1331 NTAPI
1332 USB2_InitTT(IN PUSB2_HC_EXTENSION HcExtension,
1333 IN PUSB2_TT Tt)
1334 {
1335 ULONG ix;
1336 ULONG jx;
1337
1338 DPRINT("USB2_InitTT: HcExtension - %p, Tt - %p\n", HcExtension, Tt);
1339
1340 Tt->HcExtension = HcExtension;
1341 Tt->DelayTime = 1;
1342 Tt->MaxTime = USB2_FS_MAX_PERIODIC_ALLOCATION;
1343
1344 for (ix = 0; ix < USB2_FRAMES; ix++)
1345 {
1346 Tt->FrameBudget[ix].TimeUsed = USB2_MAX_MICROFRAMES;
1347 Tt->FrameBudget[ix].AltEndpoint = NULL;
1348
1349 for (jx = 0; jx < USB2_MICROFRAMES; jx++)
1350 {
1351 Tt->TimeCS[ix][jx] = 0;
1352 Tt->NumStartSplits[ix][jx] = 0;
1353 }
1354
1355 Tt->FrameBudget[ix].IsoEndpoint = &Tt->IsoEndpoint[ix];
1356
1357 USB2_InitTtEndpoint(&Tt->IsoEndpoint[ix],
1358 USBPORT_TRANSFER_TYPE_ISOCHRONOUS,
1359 USBPORT_TRANSFER_DIRECTION_OUT,
1360 UsbFullSpeed,
1361 USB2_FRAMES,
1362 0,
1363 Tt);
1364
1365 Tt->IsoEndpoint[ix].ActualPeriod = USB2_FRAMES;
1366 Tt->IsoEndpoint[ix].CalcBusTime = USB2_FS_SOF_TIME + USB2_HUB_DELAY;
1367 Tt->IsoEndpoint[ix].StartFrame = ix;
1368 Tt->IsoEndpoint[ix].StartMicroframe = 0xFF;
1369
1370 Tt->FrameBudget[ix].IntEndpoint = &Tt->IntEndpoint[ix];
1371
1372 USB2_InitTtEndpoint(&Tt->IntEndpoint[ix],
1373 USBPORT_TRANSFER_TYPE_INTERRUPT,
1374 USBPORT_TRANSFER_DIRECTION_OUT,
1375 UsbFullSpeed,
1376 USB2_FRAMES,
1377 0,
1378 Tt);
1379
1380 Tt->IntEndpoint[ix].ActualPeriod = USB2_FRAMES;
1381 Tt->IntEndpoint[ix].CalcBusTime = USB2_FS_SOF_TIME + USB2_HUB_DELAY;
1382 Tt->IntEndpoint[ix].StartFrame = ix;
1383 Tt->IntEndpoint[ix].StartMicroframe = 0xFF;
1384 }
1385 }
1386
1387 VOID
1388 NTAPI
1389 USB2_InitController(IN PUSB2_HC_EXTENSION HcExtension)
1390 {
1391 ULONG ix;
1392 ULONG jx;
1393
1394 DPRINT("USB2_InitController: HcExtension - %p\n", HcExtension);
1395
1396 HcExtension->MaxHsBusAllocation = USB2_MAX_MICROFRAME_ALLOCATION;
1397
1398 for (ix = 0; ix < USB2_FRAMES; ix++)
1399 {
1400 for (jx = 0; jx < USB2_MICROFRAMES; jx++)
1401 {
1402 HcExtension->TimeUsed[ix][jx] = 0;
1403 }
1404 }
1405
1406 HcExtension->HcDelayTime = USB2_CONTROLLER_DELAY;
1407
1408 USB2_InitTT(HcExtension, &HcExtension->HcTt);
1409 }