Subversion Repositories Kolibri OS

Rev

Rev 3816 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3816 Rev 3826
Line 229... Line 229...
229
        ret
229
        ret
230
endp
230
endp
Line 231... Line 231...
231
 
231
 
232
; USB2 scheduler.
232
; USB2 scheduler.
233
; There are two parts: high-speed pipes and split-transaction pipes.
-
 
-
 
233
; There are two parts: high-speed pipes and split-transaction pipes.
234
; Split-transaction scheduler is currently a stub.
234
;
235
; High-speed scheduler uses the same algorithm as USB1 scheduler:
235
; High-speed scheduler uses the same algorithm as USB1 scheduler:
236
; when adding a pipe, optimize the following quantity:
236
; when adding a pipe, optimize the following quantity:
237
;  * for every microframe, take all bandwidth scheduled to periodic transfers,
237
;  * for every microframe, take all bandwidth scheduled to periodic transfers,
238
;  * calculate maximum over all microframe,
238
;  * calculate maximum over all microframes,
-
 
239
;  * select a variant which minimizes that maximum;
-
 
240
;  * if there are several such variants,
-
 
241
;    prefer those that are closer to end of frame
239
;  * select a variant which minimizes that maximum;
242
;    to minimize collisions with split transactions;
240
; when removing a pipe, do nothing (except for bookkeeping).
243
; when removing a pipe, do nothing (except for bookkeeping).
241
; in: esi -> usb_controller
244
; in: esi -> usb_controller
242
; out: edx -> usb_static_ep, eax = S-Mask
245
; out: edx -> usb_static_ep, eax = S-Mask
243
proc ehci_select_hs_interrupt_list
246
proc ehci_select_hs_interrupt_list
Line 343... Line 346...
343
        pop     edx
346
        pop     edx
344
; 4j. Loop #2: if the current variant is better (maybe not strictly)
347
; 4j. Loop #2: if the current variant is better (maybe not strictly)
345
; then the previous optimum, update the optimal bandwidth and the target.
348
; then the previous optimum, update the optimal bandwidth and the target.
346
        cmp     edi, [.bandwidth]
349
        cmp     edi, [.bandwidth]
347
        ja      @f
350
        ja      @f
-
 
351
        jb      .update
-
 
352
        cmp     ecx, [.targetsmask]
-
 
353
        jb      @f
-
 
354
.update:
348
        mov     [.bandwidth], edi
355
        mov     [.bandwidth], edi
349
        mov     [.target], edx
356
        mov     [.target], edx
350
        movi    eax, 1
-
 
351
        shl     eax, cl
-
 
352
        mov     [.targetsmask], eax
357
        mov     [.targetsmask], ecx
353
@@:
358
@@:
354
; 4k. Loop #2: continue 8 times for every microframe.
359
; 4k. Loop #2: continue 8 times for every microframe.
355
        inc     ecx
360
        inc     ecx
356
        cmp     ecx, 8
361
        cmp     ecx, 8
357
        jb      .varloop
362
        jb      .varloop
Line 449... Line 454...
449
        mov     dl, 0x55
454
        mov     dl, 0x55
450
        jz      @f
455
        jz      @f
451
        mov     dl, 0xFF
456
        mov     dl, 0xFF
452
@@:
457
@@:
453
; try all variants edx, edx shl 1, edx shl 2, ...
458
; try all variants edx, edx shl 1, edx shl 2, ...
454
; until they fit in the lower byte (8 microframes per frame)
459
; while they fit in the lower byte (8 microframes per frame)
455
.select_best_mframe:
460
.select_best_mframe:
456
        xor     edi, edi
461
        xor     edi, edi
457
        mov     ecx, edx
462
        mov     ecx, edx
458
        mov     eax, esp
463
        mov     eax, esp
459
.calc_mframe:
464
.calc_mframe:
Line 510... Line 515...
510
 
515
 
511
; Pipe is removing, update the corresponding lists.
516
; Pipe is removing, update the corresponding lists.
512
; We do not reorder anything, so just update book-keeping variable
517
; We do not reorder anything, so just update book-keeping variable
513
; in the list header.
518
; in the list header.
514
proc ehci_hs_interrupt_list_unlink
-
 
515
; get target list
-
 
516
        mov     edx, [ebx+ehci_pipe.BaseList-sizeof.ehci_pipe]
519
proc ehci_hs_interrupt_list_unlink
517
        movzx   eax, word [ebx+ehci_pipe.Token-sizeof.ehci_pipe+2]
520
        movzx   eax, word [ebx+ehci_pipe.Token-sizeof.ehci_pipe+2]
518
; calculate bandwidth
521
; calculate bandwidth
519
        call    calc_hs_bandwidth
522
        call    calc_hs_bandwidth
520
        mov     ecx, [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
523
        mov     ecx, [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
521
        shr     ecx, 30
524
        shr     ecx, 30
522
        imul    eax, ecx
525
        imul    eax, ecx
-
 
526
        movzx   ecx, byte [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
523
        movzx   ecx, byte [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
527
; get target list
524
        add     edx, ehci_static_ep.Bandwidths - ehci_static_ep.SoftwarePart
528
        mov     edx, [ebx+ehci_pipe.BaseList-sizeof.ehci_pipe]
525
; update bandwidth
529
; update bandwidth
526
.dec_bandwidth:
530
.dec_bandwidth:
527
        shr     ecx, 1
531
        shr     ecx, 1
528
        jnc     @f
532
        jnc     @f
529
        sub     [edx], ax
533
        sub     word [edx+ehci_static_ep.Bandwidths - ehci_static_ep.SoftwarePart], ax
530
@@:
534
@@:
531
        add     edx, 2
535
        add     edx, 2
532
        test    ecx, ecx
536
        test    ecx, ecx
533
        jnz     .dec_bandwidth
537
        jnz     .dec_bandwidth
Line 553... Line 557...
553
; 88 bits for another inter-packet delay.
557
; 88 bits for another inter-packet delay.
554
        lea     eax, [ecx+edx+989]
558
        lea     eax, [ecx+edx+989]
555
        ret
559
        ret
556
endp
560
endp
Line -... Line 561...
-
 
561
 
-
 
562
; Split-transaction scheduler (aka TT scheduler, TT stands for Transaction
-
 
563
; Translator, section 11.14 of the core spec) needs to schedule three event
-
 
564
; types on two buses: Start-Split and Complete-Split on HS bus and normal
-
 
565
; transaction on FS/LS bus.
-
 
566
; Assume that FS/LS bus is more restricted and more important to be scheduled
-
 
567
; uniformly, so select the variant which minimizes maximal used bandwidth
-
 
568
; on FS/LS bus and does not overflow HS bus.
-
 
569
; If there are several such variants, prefer variants which is closest to
-
 
570
; start of frame, and within the same microframe consider HS bandwidth
-
 
571
; utilization as a last criteria.
-
 
572
 
-
 
573
; The procedure ehci_select_tt_interrupt_list has been splitted into several
-
 
574
; macro, each representing a logical step of the procedure,
-
 
575
; to simplify understanding what is going on. Consider all the following macro
-
 
576
; as logical parts of one procedure, they are meaningless outside the context.
-
 
577
 
-
 
578
; Given a frame, calculate bandwidth occupied by already opened pipes
-
 
579
; in every microframe.
-
 
580
; Look for both HS and FS/LS buses: there are 16 words of information,
-
 
581
; 8 for HS bus, 8 for FS/LS bus, for every microframe.
-
 
582
; Since we count already opened pipes, the total bandwidth in every microframe
-
 
583
; is less than 60000 bits (and even 60000*80% bits), otherwise the scheduler
-
 
584
; would not allow to open those pipes.
-
 
585
; edi -> first list for the frame
-
 
586
macro tt_calc_bandwidth_in_frame
-
 
587
{
-
 
588
local .lists, .pipes, .pipes_done, .carry
-
 
589
; 1. Zero everything.
-
 
590
        xor     eax, eax
-
 
591
        mov     edx, edi
-
 
592
repeat 4
-
 
593
        mov     dword [.budget+(%-1)*4], eax
-
 
594
end repeat
-
 
595
repeat 4
-
 
596
        mov     dword [.hs_bandwidth+(%-1)*4], eax
-
 
597
end repeat
-
 
598
        mov     [.total_budget], ax
-
 
599
; Loop over all lists for the given frame.
-
 
600
.lists:
-
 
601
; 2. Total HS bandwidth for all pipes in one list is kept inside list header,
-
 
602
; add it. Note that overflow is impossible, so we may add entire dwords.
-
 
603
        mov     ebx, [edx+ehci_static_ep.SoftwarePart+usb_static_ep.NextVirt]
-
 
604
repeat 4
-
 
605
        mov     eax, dword [edx+ehci_static_ep.Bandwidths+(%-1)*4]
-
 
606
        add     dword [.hs_bandwidth+(%-1)*4], eax
-
 
607
end repeat
-
 
608
; Loop over all pipes in the given list.
-
 
609
        add     edx, ehci_static_ep.SoftwarePart
-
 
610
.pipes:
-
 
611
        cmp     ebx, edx
-
 
612
        jz      .pipes_done
-
 
613
; 3. For every pipe in every list for the given frame:
-
 
614
; 3a. Check whether the pipe resides on the same FS/LS bus as the new pipe.
-
 
615
; If not, skip this pipe.
-
 
616
        mov     eax, [ebx+usb_pipe.DeviceData]
-
 
617
        mov     eax, [eax+usb_device_data.TTHub]
-
 
618
        cmp     eax, [.tthub]
-
 
619
        jnz     @f
-
 
620
; 3b. Calculate FS/LS budget for the opened pipe.
-
 
621
; Note that eax = TTHub after 3a.
-
 
622
        call    tt_calc_budget
-
 
623
; 3c. Update total budget: add the value from 3b
-
 
624
; to the budget of the first microframe scheduled for this pipe.
-
 
625
        bsf     ecx, [ebx+ehci_pipe.Flags-sizeof.ehci_pipe]
-
 
626
        add     [.budget+ecx*2], ax
-
 
627
@@:
-
 
628
        mov     ebx, [ebx+usb_pipe.NextVirt]
-
 
629
        jmp     .pipes
-
 
630
.pipes_done:
-
 
631
        mov     edx, [edx+ehci_static_ep.NextList-ehci_static_ep.SoftwarePart]
-
 
632
        test    edx, edx
-
 
633
        jnz     .lists
-
 
634
; 4. If the budget for some microframe is exceeded, carry it to the following
-
 
635
; microframe(s). The actual size of one microframe is 187.5 raw bytes;
-
 
636
; the core spec says that 188 bytes should be scheduled in every microframe.
-
 
637
        xor     eax, eax
-
 
638
        xor     ecx, ecx
-
 
639
.carry:
-
 
640
        xor     edx, edx
-
 
641
        add     ax, [.budget+ecx*2]
-
 
642
        cmp     ax, 188
-
 
643
        jbe     @f
-
 
644
        mov     dx, ax
-
 
645
        mov     ax, 188
-
 
646
        sub     dx, ax
-
 
647
@@:
-
 
648
        mov     [.budget+ecx*2], ax
-
 
649
        add     [.total_budget], ax
-
 
650
        mov     ax, dx
-
 
651
        inc     ecx
-
 
652
        cmp     ecx, 8
-
 
653
        jb      .carry
-
 
654
}
-
 
655
 
-
 
656
; Checks whether the new pipe fits in the existing FS budget
-
 
657
; starting from the given microframe. If not, mark the microframe
-
 
658
; as impossible for scheduling.
-
 
659
; in: ecx = microframe
-
 
660
macro tt_exclude_microframe_if_no_budget
-
 
661
{
-
 
662
local .loop, .good, .bad
-
 
663
; 1. If the new budget plus the current budget does not exceed 188 bytes,
-
 
664
; the variant is possible.
-
 
665
        mov     ax, [.budget+ecx*2]
-
 
666
        mov     edx, ecx
-
 
667
        add     ax, [.new_budget]
-
 
668
        sub     ax, 188
-
 
669
        jbe     .good
-
 
670
; 2. Otherwise,
-
 
671
; a) nothing should be scheduled in some following microframes,
-
 
672
; b) after adding the new budget everything should fit in first 6 microframes,
-
 
673
;    this guarantees that even in the worst case 90% limit is satisfied.
-
 
674
.loop:
-
 
675
        cmp     edx, 5
-
 
676
        jae     .bad
-
 
677
        cmp     [.budget+(edx+1)*2], 0
-
 
678
        jnz     .bad
-
 
679
        inc     edx
-
 
680
        sub     ax, 188
-
 
681
        ja      .loop
-
 
682
.bad:
557
 
683
        btr     [.possible_microframes], ecx
-
 
684
.good:
-
 
685
}
-
 
686
 
-
 
687
; Calculate data corresponding to the particular scheduling variant for the new pipe.
-
 
688
; Data describe the current scheduling state collected over all frames touched
-
 
689
; by the given variant: maximal HS bandwidth, maximal FS/LS budget,
-
 
690
; which microframes fit in the current FS/LS budget for all frames.
-
 
691
macro tt_calc_statistics_for_one_variant
-
 
692
{
-
 
693
local .frames, .microframes
-
 
694
; 1. Initialize: zero maximal bandwidth,
-
 
695
; first 6 microframes are possible for scheduling.
-
 
696
        xor     eax, eax
-
 
697
repeat 4
-
 
698
        mov     dword [.max_hs_bandwidth+(%-1)*4], eax
-
 
699
end repeat
-
 
700
        mov     [.max_fs_bandwidth], ax
-
 
701
        mov     [.possible_microframes], 0x3F
-
 
702
; Loop over all frames starting with [.variant] advancing by [.variant_delta].
-
 
703
        mov     edi, [.variant]
-
 
704
.frames:
-
 
705
; 2. Calculate statistics for one frame.
-
 
706
        tt_calc_bandwidth_in_frame
-
 
707
; 3. Update maximal FS budget.
-
 
708
        mov     ax, [.total_budget]
-
 
709
        cmp     ax, [.max_fs_bandwidth]
-
 
710
        jb      @f
-
 
711
        mov     [.max_fs_bandwidth], ax
-
 
712
@@:
-
 
713
; 4. For every microframe, update maximal HS bandwidth
-
 
714
; and check whether the microframe is allowed for scheduling.
-
 
715
        xor     ecx, ecx
-
 
716
.microframes:
-
 
717
        mov     ax, [.hs_bandwidth+ecx*2]
-
 
718
        cmp     ax, [.max_hs_bandwidth+ecx*2]
-
 
719
        jb      @f
-
 
720
        mov     [.max_hs_bandwidth+ecx*2], ax
-
 
721
@@:
-
 
722
        tt_exclude_microframe_if_no_budget
-
 
723
        inc     ecx
-
 
724
        cmp     ecx, 8
-
 
725
        jb      .microframes
-
 
726
; Stop loop when outside of first descriptor group.
-
 
727
        lea     eax, [esi+ehci_controller.IntEDs+32*sizeof.ehci_static_ep-sizeof.ehci_controller]
-
 
728
        add     edi, [.variant_delta]
-
 
729
        cmp     edi, eax
-
 
730
        jb      .frames
-
 
731
}
-
 
732
 
-
 
733
struct usb_split_info
-
 
734
microframe_mask         dd      ?       ; lower byte is S-mask, second byte is C-mask
558
uglobal
735
ssplit_bandwidth        dd      ?
559
ehci_last_fs_alloc      dd      ?
736
csplit_bandwidth        dd      ?
560
endg
737
ends
-
 
738
 
-
 
739
; Check whether the current variant and the current microframe are allowed
-
 
740
; for scheduling. If so, check whether they are better than the previously
561
 
741
; selected variant+microframe, if any. If so, update the previously selected
-
 
742
; variant+microframe to current ones.
-
 
743
; ecx = microframe, [.variant] = variant
-
 
744
macro tt_check_variant_microframe
-
 
745
{
-
 
746
local .nothing, .update, .ssplit, .csplit, .csplit_done
-
 
747
; 1. If the current microframe does not fit in existing FS budget, do nothing.
-
 
748
        bt      [.possible_microframes], ecx
-
 
749
        jnc     .nothing
562
; This needs to be rewritten. Seriously.
750
; 2. Calculate maximal HS bandwidth over all affected microframes.
-
 
751
; 2a. Start-split phase: one or more microframes starting with ecx,
-
 
752
; coded in lower byte of .info.microframe_mask.
-
 
753
        xor     ebx, ebx
-
 
754
        xor     edx, edx
-
 
755
.ssplit:
-
 
756
        lea     eax, [ecx+edx]
-
 
757
        movzx   eax, [.max_hs_bandwidth+eax*2]
-
 
758
        add     eax, [.info.ssplit_bandwidth]
-
 
759
        cmp     ebx, eax
-
 
760
        ja      @f
-
 
761
        mov     ebx, eax
-
 
762
@@:
-
 
763
        inc     edx
-
 
764
        bt      [.info.microframe_mask], edx
-
 
765
        jc      .ssplit
-
 
766
; 2b. Complete-split phase: zero or more microframes starting with
563
; It schedules everything to the first microframe of some frame,
767
; ecx+(last start-split microframe)+2,
-
 
768
; coded in second byte of .info.microframe_mask.
-
 
769
        add     edx, 8
-
 
770
.csplit:
-
 
771
        inc     edx
-
 
772
        bt      [.info.microframe_mask], edx
-
 
773
        jnc     .csplit_done
-
 
774
        lea     eax, [ecx+edx]
-
 
775
        cmp     eax, 8
-
 
776
        jae     .csplit_done
-
 
777
        movzx   eax, [.max_hs_bandwidth+(eax-8)*2]
-
 
778
        add     eax, [.info.csplit_bandwidth]
-
 
779
        cmp     ebx, eax
-
 
780
        ja      .csplit
-
 
781
        mov     ebx, eax
-
 
782
        jmp     .csplit
-
 
783
.csplit_done:
-
 
784
; 3. Check that current HS bandwidth + new bandwidth <= limit;
-
 
785
; USB2 specification allows maximum 60000*80% bit times for periodic microframe.
-
 
786
        cmp     ebx, 48000
-
 
787
        ja      .nothing
564
; frame is spinned out of thin air.
788
; 4. This variant is possible for scheduling.
-
 
789
; Check whether it is better than the currently selected one.
-
 
790
; 4a. The primary criteria: FS/LS bandwidth.
-
 
791
        mov     ax, [.max_fs_bandwidth]
-
 
792
        cmp     ax, [.best_fs_bandwidth]
-
 
793
        ja      .nothing
565
; This works while you have one keyboard and one mouse...
794
        jb      .update
-
 
795
; 4b. The secondary criteria: prefer microframes which are closer to start of frame.
-
 
796
        cmp     ecx, [.targetsmask]
566
; maybe even ten keyboards and ten mice... but give any serious stress,
797
        ja      .nothing
-
 
798
        jb      .update
-
 
799
; 4c. The last criteria: HS bandwidth.
-
 
800
        cmp     ebx, [.bandwidth]
-
 
801
        ja      .nothing
-
 
802
.update:
-
 
803
; 5. This variant is better than the previously selected.
-
 
804
; Update the best variant with current data.
-
 
805
        mov     [.best_fs_bandwidth], ax
-
 
806
        mov     [.bandwidth], ebx
-
 
807
        mov     [.targetsmask], ecx
-
 
808
        mov     eax, [.variant]
-
 
809
        mov     [.target], eax
-
 
810
.nothing:
-
 
811
}
-
 
812
 
-
 
813
; TT scheduler: add new pipe.
-
 
814
; in: esi -> usb_controller, edi -> usb_pipe
567
; and this would break.
815
; out: edx -> usb_static_ep, eax = S-Mask
568
proc ehci_select_fs_interrupt_list
816
proc ehci_select_tt_interrupt_list
-
 
817
virtual at ebp-12-.local_vars_size
-
 
818
.local_vars_start:
-
 
819
.info                   usb_split_info
-
 
820
.new_budget             dw      ?
-
 
821
.total_budget           dw      ?
-
 
822
.possible_microframes   dd      ?
-
 
823
.tthub                  dd      ?
-
 
824
.budget                 rw      8
-
 
825
.hs_bandwidth           rw      8
-
 
826
.max_hs_bandwidth       rw      8
-
 
827
.max_fs_bandwidth       dw      ?
-
 
828
.best_fs_bandwidth      dw      ?
-
 
829
.variant                dd      ?
-
 
830
.variant_delta          dd      ?
-
 
831
.target_delta           dd      ?
-
 
832
.local_vars_size = $ - .local_vars_start
569
virtual at ebp-12
833
 
570
.targetsmask    dd      ?
834
.targetsmask    dd      ?
571
.bandwidth      dd      ?
835
.bandwidth      dd      ?
572
.target         dd      ?
836
.target         dd      ?
573
                dd      ?
837
                dd      ?
Line 576... Line 840...
576
.endpoint       dd      ?
840
.endpoint       dd      ?
577
.maxpacket      dd      ?
841
.maxpacket      dd      ?
578
.type           dd      ?
842
.type           dd      ?
579
.interval       dd      ?
843
.interval       dd      ?
580
end virtual
844
end virtual
-
 
845
        mov     eax, [edi+ehci_pipe.Token-sizeof.ehci_pipe]
-
 
846
        shr     eax, 16
-
 
847
        and     eax, (1 shl 11) - 1
-
 
848
        push    ebx edi
-
 
849
; 1. Compute the real interval. FS/LS devices encode the interval as
-
 
850
; number of milliseconds. Use the maximal power of two that is not greater than
-
 
851
; the given interval and EHCI scheduling area = 32 frames.
581
        cmp     [.interval], 1
852
        cmp     [.interval], 1
582
        adc     [.interval], 0
853
        adc     [.interval], 0
583
        mov     ecx, 64
854
        mov     ecx, 64
584
        mov     eax, ecx
855
        mov     eax, 64 * sizeof.ehci_static_ep
585
@@:
856
@@:
586
        shr     ecx, 1
857
        shr     ecx, 1
587
        cmp     [.interval], ecx
858
        cmp     [.interval], ecx
588
        jb      @b
859
        jb      @b
-
 
860
        mov     [.interval], ecx
-
 
861
; 2. Compute variables for further calculations.
-
 
862
; 2a. [.variant_delta] is delta between two lists from the first group
-
 
863
; that correspond to the same variant.
-
 
864
        imul    ecx, sizeof.ehci_static_ep
-
 
865
        mov     [.variant_delta], ecx
-
 
866
; 2b. [.target_delta] is delta between the final answer from the group
-
 
867
; corresponding to [.interval] and the item from the first group.
589
        sub     eax, ecx
868
        sub     eax, ecx
590
        sub     eax, ecx
869
        sub     eax, ecx
-
 
870
        mov     [.target_delta], eax
-
 
871
; 2c. [.variant] is the first list from the first group that corresponds
-
 
872
; to the current variant.
-
 
873
        lea     eax, [esi+ehci_controller.IntEDs-sizeof.ehci_controller]
-
 
874
        mov     [.variant], eax
-
 
875
; 2d. [.tthub] identifies TT hub for new pipe, [.new_budget] is FS budget
-
 
876
; for new pipe.
-
 
877
        mov     eax, [edi+usb_pipe.DeviceData]
-
 
878
        mov     eax, [eax+usb_device_data.TTHub]
-
 
879
        mov     ebx, edi
-
 
880
        mov     [.tthub], eax
-
 
881
        call    tt_calc_budget
-
 
882
        mov     [.new_budget], ax
-
 
883
; 2e. [.usb_split_info] describes bandwidth used by new pipe on HS bus.
-
 
884
        lea     edi, [.info]
-
 
885
        call    tt_fill_split_info
-
 
886
        test    eax, eax
-
 
887
        jz      .no_bandwidth
-
 
888
; 2f. There is no best variant yet, put maximal possible values,
-
 
889
; so any variant would be better than the "current".
-
 
890
        or      [.best_fs_bandwidth], -1
-
 
891
        or      [.target], -1
-
 
892
        or      [.bandwidth], -1
-
 
893
        or      [.targetsmask], -1
-
 
894
; 3. Loop over all variants, for every variant decide whether it is acceptable,
-
 
895
; select the best variant from all acceptable variants.
-
 
896
.check_variants:
-
 
897
        tt_calc_statistics_for_one_variant
-
 
898
        xor     ecx, ecx
-
 
899
.check_microframes:
-
 
900
        tt_check_variant_microframe
591
        dec     ecx
901
        inc     ecx
-
 
902
        cmp     ecx, 6
-
 
903
        jb      .check_microframes
-
 
904
        add     [.variant], sizeof.ehci_static_ep
-
 
905
        dec     [.interval]
-
 
906
        jnz     .check_variants
-
 
907
; 4. If there is no acceptable variants, return error.
592
        and     ecx, [ehci_last_fs_alloc]
908
        mov     ecx, [.targetsmask]
-
 
909
        mov     edx, [.target]
-
 
910
        cmp     ecx, -1
-
 
911
        jz      .no_bandwidth
-
 
912
; 5. Calculate the answer: edx -> selected list, eax = S-Mask and C-Mask.
-
 
913
        mov     eax, [.info.microframe_mask]
593
        inc     [ehci_last_fs_alloc]
914
        add     edx, [.target_delta]
-
 
915
        shl     eax, cl
-
 
916
        and     eax, 0xFFFF
-
 
917
; 6. Update HS bandwidths in the selected list.
-
 
918
        xor     ecx, ecx
-
 
919
        mov     ebx, [.info.ssplit_bandwidth]
-
 
920
.update_ssplit:
594
        add     eax, ecx
921
        bt      eax, ecx
-
 
922
        jnc     @f
-
 
923
        add     [edx+ehci_static_ep.Bandwidths+ecx*2], bx
-
 
924
@@:
-
 
925
        inc     ecx
-
 
926
        cmp     ecx, 8
-
 
927
        jb      .update_ssplit
595
        imul    eax, sizeof.ehci_static_ep
928
        mov     ebx, [.info.csplit_bandwidth]
-
 
929
.update_csplit:
-
 
930
        bt      eax, ecx
-
 
931
        jnc     @f
-
 
932
        add     [edx+ehci_static_ep.Bandwidths+(ecx-8)*2], bx
-
 
933
@@:
-
 
934
        inc     ecx
-
 
935
        cmp     ecx, 16
-
 
936
        jb      .update_csplit
-
 
937
; 7. Return.
596
        lea     edx, [esi+ehci_controller.IntEDs.SoftwarePart+eax-sizeof.ehci_controller]
938
        add     edx, ehci_static_ep.SoftwarePart
-
 
939
        pop     edi ebx
-
 
940
        ret
-
 
941
.no_bandwidth:
-
 
942
        dbgstr 'Periodic bandwidth limit reached'
597
        mov     ax, 1C01h
943
        xor     eax, eax
-
 
944
        xor     edx, edx
-
 
945
        pop     edi ebx
598
        ret
946
        ret
599
endp
947
endp
Line -... Line 948...
-
 
948
 
-
 
949
; Pipe is removing, update the corresponding lists.
-
 
950
; We do not reorder anything, so just update book-keeping variable
600
 
951
; in the list header.
-
 
952
proc ehci_fs_interrupt_list_unlink
-
 
953
; calculate bandwidth
-
 
954
        push    edi
-
 
955
        sub     esp, sizeof.usb_split_info
-
 
956
        mov     edi, esp
-
 
957
        call    tt_fill_split_info
-
 
958
; get target list
-
 
959
        mov     edx, [ebx+ehci_pipe.BaseList-sizeof.ehci_pipe]
-
 
960
; update bandwidth for Start-Split
-
 
961
        mov     eax, [edi+usb_split_info.ssplit_bandwidth]
-
 
962
        xor     ecx, ecx
-
 
963
.dec_bandwidth_1:
-
 
964
        bt      [ebx+ehci_pipe.Flags-sizeof.ehci_pipe], ecx
-
 
965
        jnc     @f
-
 
966
        sub     word [edx+ecx*2+ehci_static_ep.Bandwidths - ehci_static_ep.SoftwarePart], ax
-
 
967
@@:
-
 
968
        inc     ecx
-
 
969
        cmp     ecx, 8
-
 
970
        jb      .dec_bandwidth_1
-
 
971
; update bandwidth for Complete-Split
-
 
972
        mov     eax, [edi+usb_split_info.csplit_bandwidth]
-
 
973
.dec_bandwidth_2:
-
 
974
        bt      [ebx+ehci_pipe.Flags-sizeof.ehci_pipe], ecx
-
 
975
        jnc     @f
-
 
976
        sub     word [edx+(ecx-8)*2+ehci_static_ep.Bandwidths - ehci_static_ep.SoftwarePart], ax
-
 
977
@@:
-
 
978
        inc     ecx
-
 
979
        cmp     ecx, 16
-
 
980
        jb      .dec_bandwidth_2
-
 
981
        add     esp, sizeof.usb_split_info
-
 
982
        pop     edi
-
 
983
        ret
-
 
984
endp
-
 
985
 
-
 
986
; Helper procedure for ehci_select_tt_interrupt_list.
-
 
987
; Calculates "best-case budget" according to the core spec,
-
 
988
; that is, number of bytes (not bits) corresponding to "optimistic" transaction
-
 
989
; time, including inter-packet delays/bus turn-around time,
-
 
990
; but without bit stuffing and timers drift.
-
 
991
; One extra TT-specific delay is added: TT think time from the hub descriptor.
-
 
992
; Similar to calc_usb1_bandwidth with corresponding changes.
-
 
993
; eax -> usb_hub with TT, ebx -> usb_pipe
-
 
994
proc tt_calc_budget
-
 
995
        movzx   ecx, [eax+usb_hub.HubCharacteristics]
-
 
996
        shr     ecx, 5
-
 
997
        and     ecx, 3  ; 1+ecx = TT think time in FS-bytes
-
 
998
        mov     eax, [ebx+ehci_pipe.Token-sizeof.ehci_pipe]
-
 
999
        shr     eax, 16
-
 
1000
        and     eax, (1 shl 11) - 1     ; get data length
-
 
1001
        bt      [ebx+ehci_pipe.Token-sizeof.ehci_pipe], 12
-
 
1002
        jc      .low_speed
-
 
1003
; Full-speed interrupt IN/OUT:
-
 
1004
; 33 bits for Token packet (8 for SYNC, 24 for token+address, 3 for EOP),
-
 
1005
; 18 bits for bus turn-around, 11 bits for SYNC+EOP in Data packet,
-
 
1006
; 2 bits for inter-packet delay, 19 bits for Handshake packet,
-
 
1007
; 2 bits for another inter-packet delay. 85 bits total, pad to 11 bytes.
-
 
1008
        lea     eax, [eax+11+ecx+1]
-
 
1009
; 1 byte is minimal TT think time in addition to ecx.
-
 
1010
        ret
-
 
1011
.low_speed:
-
 
1012
; Low-speed interrupt IN/OUT:
-
 
1013
; multiply by 8 for LS -> FS,
-
 
1014
; add 85 bytes as in full-speed interrupt and extra 5 bytes for two PRE packets
-
 
1015
; and two hub delays.
-
 
1016
; 1 byte is minimal TT think time in addition to ecx.
-
 
1017
        lea     eax, [eax*8+90+ecx+1]
-
 
1018
        ret
-
 
1019
endp
-
 
1020
 
-
 
1021
; Helper procedure for TT scheduler.
-
 
1022
; Calculates Start-Split/Complete-Split masks and HS bandwidths.
-
 
1023
; ebx -> usb_pipe, edi -> usb_split_info
-
 
1024
proc tt_fill_split_info
-
 
1025
; Interrupt endpoints.
-
 
1026
; The core spec says in 5.7.3 "Interrupt Transfer Packet Size Constraints" that:
-
 
1027
; The maximum allowable interrupt data payload size is 64 bytes or less for full-speed.
-
 
1028
; Low-speed devices are limited to eight bytes or less maximum data payload size.
-
 
1029
; This is important for scheduling, it guarantees that in any case transaction fits
-
 
1030
; in two microframes (usually one, two if transaction has started too late in the first
-
 
1031
; microframe), so check it.
-
 
1032
        mov     eax, [ebx+ehci_pipe.Token-sizeof.ehci_pipe]
-
 
1033
        mov     ecx, 8
-
 
1034
        bt      eax, 12
-
 
1035
        jc      @f
-
 
1036
        mov     ecx, 64
-
 
1037
@@:
-
 
1038
        shr     eax, 16
-
 
1039
        and     eax, (1 shl 11) - 1     ; get data length
-
 
1040
        cmp     eax, ecx
-
 
1041
        ja      .error
-
 
1042
        add     eax, 3  ; add 3 bytes for other fields in data packet, PID+CRC16
-
 
1043
; Multiply by 8 for bytes -> bits and then by 7/6 to accomodate bit stuffing;
-
 
1044
; total 28/3 = 9+1/3
-
 
1045
        mov     edx, 55555556h
-
 
1046
        lea     ecx, [eax*9]
-
 
1047
        mul     edx
-
 
1048
; One start-split, three complete-splits (unless the last is too far,
-
 
1049
; but this is handled by the caller).
-
 
1050
        mov     eax, [ebx+usb_pipe.LastTD]
-
 
1051
        mov     [edi+usb_split_info.microframe_mask], 0x1C01
-
 
1052
; Structure and HS bandwidth of packets depends on the direction.
-
 
1053
        bt      [eax+ehci_gtd.Token-sizeof.ehci_gtd], 8
-
 
1054
        jc      .interrupt_in
-
 
1055
.interrupt_out:
-
 
1056
; Start-Split phase:
-
 
1057
; 77 bits for SPLIT packet (32 for SYNC, 8 for EOP, 32 for data, 5 for bit stuffing),
-
 
1058
; 88 bits for inter-packet delay, 68 bits for Token packet,
-
 
1059
; 88 bits for inter-packet delay, 40 bits for SYNC+EOP in Data packet,
-
 
1060
; 88 bits for last inter-packet delay, total 449 bits.
-
 
1061
        lea     eax, [edx+ecx+449]
-
 
1062
        mov     [edi+usb_split_info.ssplit_bandwidth], eax
-
 
1063
; Complete-Split phase:
-
 
1064
; 77 bits for SPLIT packet,
-
 
1065
; 88 bits for inter-packet delay, 68 bits for Token packet,
-
 
1066
; 736 bits for bus turn-around, 49 bits for Handshake packet,
-
 
1067
; 8 bits for inter-packet delay, total 1026 bits.
-
 
1068
        mov     [edi+usb_split_info.csplit_bandwidth], 1026
-
 
1069
        ret
-
 
1070
.interrupt_in:
-
 
1071
; Start-Split phase:
-
 
1072
; 77 bits for SPLIT packet, 88 bits for inter-packet delay,
-
 
1073
; 68 bits for Token packet, 88 bits for another inter-packet delay,
-
 
1074
; total 321 bits.
-
 
1075
        mov     [edi+usb_split_info.ssplit_bandwidth], 321
-
 
1076
; Complete-Split phase:
-
 
1077
; 77 bits for SPLIT packet, 88 bits for inter-packet delay,
-
 
1078
; 68 bits for Token packet, 736 bits for bus turn-around,
-
 
1079
; 40 bits for SYNC+EOP in Data packet, 8 bits for inter-packet delay,
-
 
1080
; total 1017 bits.
-
 
1081
        lea     eax, [edx+ecx+1017]
-
 
1082
        mov     [edi+usb_split_info.csplit_bandwidth], eax
-
 
1083
        ret
-
 
1084
.error:
601
proc ehci_fs_interrupt_list_unlink
1085
        xor     eax, eax
602
        ret
1086
        ret