Subversion Repositories Kolibri OS

Rev

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

Rev 3626 Rev 3725
Line 79... Line 79...
79
; * The hardware part consists of first 52 bytes and corresponds to
79
; * The hardware part consists of first 52 bytes and corresponds to
80
;   the Queue Element Transfer Descriptor from EHCI specification.
80
;   the Queue Element Transfer Descriptor from EHCI specification.
81
; * The hardware requires 32-bytes alignment of the hardware part, so
81
; * The hardware requires 32-bytes alignment of the hardware part, so
82
;   the entire descriptor must be 32-bytes aligned. Since the allocator
82
;   the entire descriptor must be 32-bytes aligned. Since the allocator
83
;   (usb_allocate_common) allocates memory sequentially from page start
83
;   (usb_allocate_common) allocates memory sequentially from page start
84
;   (aligned on 0x1000 bytes), size of the structure must be divisible by 32.
84
;   (aligned on 0x1000 bytes), block size for the allocator must be divisible
-
 
85
;   by 32; ehci_alloc_td ensures this.
85
; * The hardware also requires that the hardware part must not cross page
86
; * The hardware also requires that the hardware part must not cross page
86
;   boundary; the allocator satisfies this automatically.
87
;   boundary; the allocator satisfies this automatically.
87
struct ehci_gtd ehci_hardware_td
88
struct ehci_gtd ehci_hardware_td
88
Flags                   dd      ?
89
Flags                   dd      ?
89
; Copy of flags from the call to usb_*_transfer_async.
90
; Copy of flags from the call to usb_*_transfer_async.
90
SoftwarePart            rd      sizeof.usb_gtd/4
-
 
91
; Software part, common for all controllers.
-
 
92
                        rd      3       ; padding
-
 
93
ends
91
ends
Line 94... Line -...
94
 
-
 
95
if sizeof.ehci_gtd mod 32
-
 
96
.err ehci_gtd must be 32-bytes aligned
-
 
97
end if
-
 
98
 
92
 
99
; EHCI-specific part of a pipe descriptor.
93
; EHCI-specific part of a pipe descriptor.
100
; * This structure corresponds to the Queue Head from the EHCI specification.
94
; * This structure corresponds to the Queue Head from the EHCI specification.
101
; * The hardware requires 32-bytes alignment of the hardware part.
95
; * The hardware requires 32-bytes alignment of the hardware part.
102
;   Since the allocator (usb_allocate_common) allocates memory sequentially
96
;   Since the allocator (usb_allocate_common) allocates memory sequentially
103
;   from page start (aligned on 0x1000 bytes), size of the structure must be
97
;   from page start (aligned on 0x1000 bytes), block size for the allocator
104
;   divisible by 32.
98
;   must be divisible by 32; ehci_alloc_pipe ensures this.
105
; * The hardware requires also that the hardware part must not cross page
99
; * The hardware requires also that the hardware part must not cross page
106
;   boundary; the allocator satisfies this automatically.
100
;   boundary; the allocator satisfies this automatically.
107
struct ehci_pipe
101
struct ehci_pipe
108
NextQH                  dd      ?
102
NextQH                  dd      ?
Line 152... Line 146...
152
; Working area for the current TD, if there is any.
146
; Working area for the current TD, if there is any.
153
; When TD is retired, it is written to that TD and Overlay is loaded
147
; When TD is retired, it is written to that TD and Overlay is loaded
154
; from the new TD, if any.
148
; from the new TD, if any.
155
BaseList                dd      ?
149
BaseList                dd      ?
156
; Pointer to head of the corresponding pipe list.
150
; Pointer to head of the corresponding pipe list.
157
SoftwarePart            rd      sizeof.usb_pipe/4
-
 
158
; Software part, common for all controllers.
-
 
159
                        rd      2       ; padding
-
 
160
ends
151
ends
Line 161... Line -...
161
 
-
 
162
if sizeof.ehci_pipe mod 32
-
 
163
.err ehci_pipe must be 32-bytes aligned
-
 
164
end if
-
 
165
 
152
 
166
; This structure describes the static head of every list of pipes.
153
; This structure describes the static head of every list of pipes.
167
; The hardware requires 32-bytes alignment of this structure.
154
; The hardware requires 32-bytes alignment of this structure.
168
; All instances of this structure are located sequentially in ehci_controller,
155
; All instances of this structure are located sequentially in ehci_controller,
169
; ehci_controller is page-aligned, so it is sufficient to make this structure
156
; ehci_controller is page-aligned, so it is sufficient to make this structure
Line 762... Line 749...
762
 
749
 
763
; This procedure is called from usb_set_address_callback
750
; This procedure is called from usb_set_address_callback
764
; and stores USB device address in the ehci_pipe structure.
751
; and stores USB device address in the ehci_pipe structure.
765
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
752
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
766
proc ehci_set_device_address
753
proc ehci_set_device_address
767
        mov     byte [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart], cl
754
        mov     byte [ebx+ehci_pipe.Token-sizeof.ehci_pipe], cl
768
        call    usb_subscribe_control
755
        call    usb_subscribe_control
769
        ret
756
        ret
Line 770... Line 757...
770
endp
757
endp
771
 
758
 
772
; This procedure returns USB device address from the ehci_pipe structure.
759
; This procedure returns USB device address from the ehci_pipe structure.
773
; in: esi -> usb_controller, ebx -> usb_pipe
760
; in: esi -> usb_controller, ebx -> usb_pipe
774
; out: eax = endpoint address
761
; out: eax = endpoint address
775
proc ehci_get_device_address
762
proc ehci_get_device_address
776
        mov     eax, [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
763
        mov     eax, [ebx+ehci_pipe.Token-sizeof.ehci_pipe]
777
        and     eax, 7Fh
764
        and     eax, 7Fh
Line 778... Line 765...
778
        ret
765
        ret
Line 791... Line 778...
791
; This procedure is called from usb_get_descr8_callback when
778
; This procedure is called from usb_get_descr8_callback when
792
; the packet size for zero endpoint becomes known and
779
; the packet size for zero endpoint becomes known and
793
; stores the packet size in ehci_pipe structure.
780
; stores the packet size in ehci_pipe structure.
794
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
781
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
795
proc ehci_set_endpoint_packet_size
782
proc ehci_set_endpoint_packet_size
796
        mov     eax, [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
783
        mov     eax, [ebx+ehci_pipe.Token-sizeof.ehci_pipe]
797
        and     eax, not (0x7FF shl 16)
784
        and     eax, not (0x7FF shl 16)
798
        shl     ecx, 16
785
        shl     ecx, 16
799
        or      eax, ecx
786
        or      eax, ecx
800
        mov     [ebx+ehci_pipe.Token-ehci_pipe.SoftwarePart], eax
787
        mov     [ebx+ehci_pipe.Token-sizeof.ehci_pipe], eax
801
; Wait until hardware cache is evicted.
788
; Wait until hardware cache is evicted.
802
        call    usb_subscribe_control
789
        call    usb_subscribe_control
803
        ret
790
        ret
804
endp
791
endp
Line 816... Line 803...
816
; Both hardware+software parts must be allocated, returns pointer to usb_pipe
803
; Both hardware+software parts must be allocated, returns pointer to usb_pipe
817
; (software part).
804
; (software part).
818
proc ehci_alloc_pipe
805
proc ehci_alloc_pipe
819
        push    ebx
806
        push    ebx
820
        mov     ebx, ehci_ep_mutex
807
        mov     ebx, ehci_ep_mutex
821
        stdcall usb_allocate_common, sizeof.ehci_pipe
808
        stdcall usb_allocate_common, (sizeof.ehci_pipe + sizeof.usb_pipe + 1Fh) and not 1Fh
822
        test    eax, eax
809
        test    eax, eax
823
        jz      @f
810
        jz      @f
824
        add     eax, ehci_pipe.SoftwarePart
811
        add     eax, sizeof.ehci_pipe
825
@@:
812
@@:
826
        pop     ebx
813
        pop     ebx
827
        ret
814
        ret
828
endp
815
endp
Line 832... Line 819...
832
proc ehci_free_pipe
819
proc ehci_free_pipe
833
virtual at esp
820
virtual at esp
834
        dd      ?       ; return address
821
        dd      ?       ; return address
835
.ptr    dd      ?
822
.ptr    dd      ?
836
end virtual
823
end virtual
837
        sub     [.ptr], ehci_pipe.SoftwarePart
824
        sub     [.ptr], sizeof.ehci_pipe
838
        jmp     usb_free_common
825
        jmp     usb_free_common
839
endp
826
endp
Line 840... Line 827...
840
 
827
 
841
; This procedure is called from API usb_open_pipe and processes
828
; This procedure is called from API usb_open_pipe and processes
Line 851... Line 838...
851
.type           dd      ?
838
.type           dd      ?
852
.interval       dd      ?
839
.interval       dd      ?
853
end virtual
840
end virtual
854
; 1. Zero all fields in the hardware part.
841
; 1. Zero all fields in the hardware part.
855
        push    eax ecx
842
        push    eax ecx
856
        sub     edi, ehci_pipe.SoftwarePart
843
        sub     edi, sizeof.ehci_pipe
857
        xor     eax, eax
844
        xor     eax, eax
858
        movi    ecx, ehci_pipe.SoftwarePart/4
845
        movi    ecx, sizeof.ehci_pipe/4
859
        rep stosd
846
        rep stosd
860
        pop     ecx eax
847
        pop     ecx eax
861
; 2. Setup PID in the first TD and make sure that the it is not active.
848
; 2. Setup PID in the first TD and make sure that the it is not active.
862
        xor     edx, edx
849
        xor     edx, edx
863
        test    byte [.endpoint], 80h
850
        test    byte [.endpoint], 80h
864
        setnz   dh
851
        setnz   dh
865
        mov     [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], edx
852
        mov     [eax+ehci_gtd.Token-sizeof.ehci_gtd], edx
866
        mov     [eax+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], 1
853
        mov     [eax+ehci_gtd.NextTD-sizeof.ehci_gtd], 1
867
        mov     [eax+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], 1
854
        mov     [eax+ehci_gtd.AlternateNextTD-sizeof.ehci_gtd], 1
868
; 3. Store physical address of the first TD.
855
; 3. Store physical address of the first TD.
869
        sub     eax, ehci_gtd.SoftwarePart
856
        sub     eax, sizeof.ehci_gtd
870
        call    get_phys_addr
857
        call    get_phys_addr
871
        mov     [edi+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart], eax
858
        mov     [edi+ehci_pipe.Overlay.NextTD-sizeof.ehci_pipe], eax
872
; 4. Fill ehci_pipe.Flags except for S- and C-masks.
859
; 4. Fill ehci_pipe.Flags except for S- and C-masks.
873
; Copy location from the config pipe.
860
; Copy location from the config pipe.
874
        mov     eax, [ecx+ehci_pipe.Flags-ehci_pipe.SoftwarePart]
861
        mov     eax, [ecx+ehci_pipe.Flags-sizeof.ehci_pipe]
875
        and     eax, 3FFF0000h
862
        and     eax, 3FFF0000h
876
; Use 1 requests per microframe for control/bulk endpoints,
863
; Use 1 requests per microframe for control/bulk endpoints,
877
; use value from the endpoint descriptor for periodic endpoints
864
; use value from the endpoint descriptor for periodic endpoints
878
        movi    edx, 1
865
        movi    edx, 1
879
        test    [.type], 1
866
        test    [.type], 1
Line 882... Line 869...
882
        shr     edx, 11
869
        shr     edx, 11
883
        inc     edx
870
        inc     edx
884
@@:
871
@@:
885
        shl     edx, 30
872
        shl     edx, 30
886
        or      eax, edx
873
        or      eax, edx
887
        mov     [edi+ehci_pipe.Flags-ehci_pipe.SoftwarePart], eax
874
        mov     [edi+ehci_pipe.Flags-sizeof.ehci_pipe], eax
888
; 5. Fill ehci_pipe.Token.
875
; 5. Fill ehci_pipe.Token.
889
        mov     eax, [ecx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
876
        mov     eax, [ecx+ehci_pipe.Token-sizeof.ehci_pipe]
890
; copy following fields from the config pipe:
877
; copy following fields from the config pipe:
891
; DeviceAddress, EndpointSpeed, ControlEndpoint if new type is control
878
; DeviceAddress, EndpointSpeed, ControlEndpoint if new type is control
892
        mov     ecx, eax
879
        mov     ecx, eax
893
        and     eax, 307Fh
880
        and     eax, 307Fh
894
        and     ecx, 8000000h
881
        and     ecx, 8000000h
Line 913... Line 900...
913
        cmp     [.type], BULK_PIPE
900
        cmp     [.type], BULK_PIPE
914
        jnz     .nonak
901
        jnz     .nonak
915
@@:
902
@@:
916
        or      eax, 40000000h
903
        or      eax, 40000000h
917
.nonak:
904
.nonak:
918
        mov     [edi+ehci_pipe.Token-ehci_pipe.SoftwarePart], eax
905
        mov     [edi+ehci_pipe.Token-sizeof.ehci_pipe], eax
919
; 5. Select the corresponding list and insert to the list.
906
; 5. Select the corresponding list and insert to the list.
920
; 5a. Use Control list for control pipes, Bulk list for bulk pipes.
907
; 5a. Use Control list for control pipes, Bulk list for bulk pipes.
921
        lea     edx, [esi+ehci_controller.ControlED.SoftwarePart-sizeof.ehci_controller]
908
        lea     edx, [esi+ehci_controller.ControlED.SoftwarePart-sizeof.ehci_controller]
922
        cmp     [.type], BULK_PIPE
909
        cmp     [.type], BULK_PIPE
923
        jb      .insert ; control pipe
910
        jb      .insert ; control pipe
Line 929... Line 916...
929
; based on the current bandwidth distribution and the requested bandwidth.
916
; based on the current bandwidth distribution and the requested bandwidth.
930
; There are two schedulers, one for high-speed devices,
917
; There are two schedulers, one for high-speed devices,
931
; another for split transactions.
918
; another for split transactions.
932
; This could fail if the requested bandwidth is not available;
919
; This could fail if the requested bandwidth is not available;
933
; if so, return an error.
920
; if so, return an error.
934
        test    word [edi+ehci_pipe.Flags-ehci_pipe.SoftwarePart+2], 3FFFh
921
        test    word [edi+ehci_pipe.Flags-sizeof.ehci_pipe+2], 3FFFh
935
        jnz     .interrupt_fs
922
        jnz     .interrupt_fs
936
        call    ehci_select_hs_interrupt_list
923
        call    ehci_select_hs_interrupt_list
937
        jmp     .interrupt_common
924
        jmp     .interrupt_common
938
.interrupt_fs:
925
.interrupt_fs:
939
        call    ehci_select_fs_interrupt_list
926
        call    ehci_select_fs_interrupt_list
940
.interrupt_common:
927
.interrupt_common:
941
        test    edx, edx
928
        test    edx, edx
942
        jz      .return0
929
        jz      .return0
943
        mov     word [edi+ehci_pipe.Flags-ehci_pipe.SoftwarePart], ax
930
        mov     word [edi+ehci_pipe.Flags-sizeof.ehci_pipe], ax
944
.insert:
931
.insert:
945
        mov     [edi+ehci_pipe.BaseList-ehci_pipe.SoftwarePart], edx
932
        mov     [edi+ehci_pipe.BaseList-sizeof.ehci_pipe], edx
946
; Insert to the head of the corresponding list.
933
; Insert to the head of the corresponding list.
947
; Note: inserting to the head guarantees that the list traverse in
934
; Note: inserting to the head guarantees that the list traverse in
948
; ehci_process_updated_schedule, once started, will not interact with new pipes.
935
; ehci_process_updated_schedule, once started, will not interact with new pipes.
949
; However, we still need to ensure that links in the new pipe (edi.NextVirt)
936
; However, we still need to ensure that links in the new pipe (edi.NextVirt)
950
; are initialized before links to the new pipe (edx.NextVirt).
937
; are initialized before links to the new pipe (edx.NextVirt).
Line 955... Line 942...
955
        mov     [ecx+usb_pipe.PrevVirt], edi
942
        mov     [ecx+usb_pipe.PrevVirt], edi
956
        mov     [edx+usb_pipe.NextVirt], edi
943
        mov     [edx+usb_pipe.NextVirt], edi
957
; 5d. Insert in the hardware list: copy previous NextQH to the new pipe,
944
; 5d. Insert in the hardware list: copy previous NextQH to the new pipe,
958
; store the physical address of the new pipe to previous NextQH.
945
; store the physical address of the new pipe to previous NextQH.
959
        mov     ecx, [edx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart]
946
        mov     ecx, [edx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart]
960
        mov     [edi+ehci_pipe.NextQH-ehci_pipe.SoftwarePart], ecx
947
        mov     [edi+ehci_pipe.NextQH-sizeof.ehci_pipe], ecx
961
        lea     eax, [edi-ehci_pipe.SoftwarePart]
948
        lea     eax, [edi-sizeof.ehci_pipe]
962
        call    get_phys_addr
949
        call    get_phys_addr
963
        inc     eax
950
        inc     eax
964
        inc     eax
951
        inc     eax
965
        mov     [edx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], eax
952
        mov     [edx+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], eax
966
; 6. Return with nonzero eax.
953
; 6. Return with nonzero eax.
Line 1056... Line 1043...
1056
; One transfer descriptor can describe up to 5 pages.
1043
; One transfer descriptor can describe up to 5 pages.
1057
; In the worst case (when the buffer is something*1000h+0FFFh)
1044
; In the worst case (when the buffer is something*1000h+0FFFh)
1058
; this corresponds to 4001h bytes. If the requested size is
1045
; this corresponds to 4001h bytes. If the requested size is
1059
; greater, we should split the transfer into several descriptors.
1046
; greater, we should split the transfer into several descriptors.
1060
; Boundaries to split must be multiples of endpoint transfer size
1047
; Boundaries to split must be multiples of endpoint transfer size
1061
; to avoid short packets except in the end of the transfer,
1048
; to avoid short packets except in the end of the transfer.
-
 
1049
        cmp     [size], 4001h
1062
; 4000h is always a good value.
1050
        jbe     .lastpacket
1063
; 2. While the remaining data cannot fit in one descriptor,
1051
; 2. While the remaining data cannot fit in one descriptor,
1064
; allocate full descriptors (of maximal possible size).
1052
; allocate full descriptors (of maximal possible size).
-
 
1053
; 2a. Calculate size of one descriptor: must be a multiple of transfer size
-
 
1054
; and must be not greater than 4001h.
-
 
1055
        movzx   ecx, word [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe]
1065
        mov     edi, 4000h
1056
        mov     eax, 4001h
-
 
1057
        xor     edx, edx
-
 
1058
        mov     edi, eax
-
 
1059
        div     ecx
-
 
1060
        sub     edi, edx
1066
        mov     [packetSize], edi
1061
        mov     [packetSize], edi
1067
.fullpackets:
1062
.fullpackets:
1068
        cmp     [size], edi
-
 
1069
        jbe     .lastpacket
-
 
1070
        call    ehci_alloc_packet
1063
        call    ehci_alloc_packet
1071
        test    eax, eax
1064
        test    eax, eax
1072
        jz      .fail
1065
        jz      .fail
1073
        mov     [td], eax
1066
        mov     [td], eax
1074
        add     [buffer], edi
1067
        add     [buffer], edi
1075
        sub     [size], edi
1068
        sub     [size], edi
-
 
1069
        cmp     [size], 4001h
1076
        jmp     .fullpackets
1070
        ja      .fullpackets
1077
; 3. The remaining data can fit in one packet;
1071
; 3. The remaining data can fit in one packet;
1078
; allocate the last descriptor with size = size of remaining data.
1072
; allocate the last descriptor with size = size of remaining data.
1079
.lastpacket:
1073
.lastpacket:
1080
        mov     eax, [size]
1074
        mov     eax, [size]
1081
        mov     [packetSize], eax
1075
        mov     [packetSize], eax
1082
        call    ehci_alloc_packet
1076
        call    ehci_alloc_packet
1083
        test    eax, eax
1077
        test    eax, eax
1084
        jz      .fail
1078
        jz      .fail
1085
; 9. Update flags in the last packet.
1079
; 9. Update flags in the last packet.
1086
        mov     edx, [flags]
1080
        mov     edx, [flags]
1087
        mov     [ecx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], edx
1081
        mov     [ecx+ehci_gtd.Flags-sizeof.ehci_gtd], edx
1088
; 10. Fill AlternateNextTD field in all allocated TDs.
1082
; 10. Fill AlternateNextTD field in all allocated TDs.
1089
; If the caller says that short transfer is ok, the queue must advance to
1083
; If the caller says that short transfer is ok, the queue must advance to
1090
; the next descriptor, which is in eax.
1084
; the next descriptor, which is in eax.
1091
; Otherwise, the queue should stop, so make AlternateNextTD point to
1085
; Otherwise, the queue should stop, so make AlternateNextTD point to
1092
; always-inactive descriptor StopQueueTD.
1086
; always-inactive descriptor StopQueueTD.
1093
        push    eax
1087
        push    eax
1094
        test    dl, 1
1088
        test    dl, 1
1095
        jz      .disable_short
1089
        jz      .disable_short
1096
        sub     eax, ehci_gtd.SoftwarePart
1090
        sub     eax, sizeof.ehci_gtd
1097
        jmp     @f
1091
        jmp     @f
1098
.disable_short:
1092
.disable_short:
1099
        mov     eax, [ebx+usb_pipe.Controller]
1093
        mov     eax, [ebx+usb_pipe.Controller]
1100
        add     eax, ehci_controller.StopQueueTD - sizeof.ehci_controller
1094
        add     eax, ehci_controller.StopQueueTD - sizeof.ehci_controller
1101
@@:
1095
@@:
1102
        call    get_phys_addr
1096
        call    get_phys_addr
1103
        mov     edx, [origTD]
1097
        mov     edx, [origTD]
1104
@@:
1098
@@:
1105
        cmp     edx, [esp]
1099
        cmp     edx, [esp]
1106
        jz      @f
1100
        jz      @f
1107
        mov     [edx+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], eax
1101
        mov     [edx+ehci_gtd.AlternateNextTD-sizeof.ehci_gtd], eax
1108
        mov     edx, [edx+usb_gtd.NextVirt]
1102
        mov     edx, [edx+usb_gtd.NextVirt]
1109
        jmp     @b
1103
        jmp     @b
1110
@@:
1104
@@:
1111
        pop     eax
1105
        pop     eax
1112
        ret
1106
        ret
Line 1142... Line 1136...
1142
; 2. Initialize controller-independent parts of both TDs.
1136
; 2. Initialize controller-independent parts of both TDs.
1143
        push    eax
1137
        push    eax
1144
        call    usb_init_transfer
1138
        call    usb_init_transfer
1145
        pop     eax
1139
        pop     eax
1146
; 3. Copy PID to the new descriptor.
1140
; 3. Copy PID to the new descriptor.
1147
        mov     edx, [ecx+ehci_gtd.Token-ehci_gtd.SoftwarePart]
1141
        mov     edx, [ecx+ehci_gtd.Token-sizeof.ehci_gtd]
1148
        mov     [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], edx
1142
        mov     [eax+ehci_gtd.Token-sizeof.ehci_gtd], edx
1149
        mov     [eax+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], 1
1143
        mov     [eax+ehci_gtd.NextTD-sizeof.ehci_gtd], 1
1150
        mov     [eax+ehci_gtd.AlternateNextTD-ehci_gtd.SoftwarePart], 1
1144
        mov     [eax+ehci_gtd.AlternateNextTD-sizeof.ehci_gtd], 1
1151
; 4. Save the returned value (next descriptor).
1145
; 4. Save the returned value (next descriptor).
1152
        push    eax
1146
        push    eax
1153
; 5. Store the physical address of the next descriptor.
1147
; 5. Store the physical address of the next descriptor.
1154
        sub     eax, ehci_gtd.SoftwarePart
1148
        sub     eax, sizeof.ehci_gtd
1155
        call    get_phys_addr
1149
        call    get_phys_addr
1156
        mov     [ecx+ehci_gtd.NextTD-ehci_gtd.SoftwarePart], eax
1150
        mov     [ecx+ehci_gtd.NextTD-sizeof.ehci_gtd], eax
1157
; 6. For zero-length transfers, store zero in all fields for buffer addresses.
1151
; 6. For zero-length transfers, store zero in all fields for buffer addresses.
1158
; Otherwise, fill them with real values.
1152
; Otherwise, fill them with real values.
1159
        xor     eax, eax
1153
        xor     eax, eax
1160
        mov     [ecx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], eax
1154
        mov     [ecx+ehci_gtd.Flags-sizeof.ehci_gtd], eax
1161
repeat 10
1155
repeat 10
1162
        mov     [ecx+ehci_gtd.BufferPointers-ehci_gtd.SoftwarePart+(%-1)*4], eax
1156
        mov     [ecx+ehci_gtd.BufferPointers-sizeof.ehci_gtd+(%-1)*4], eax
1163
end repeat
1157
end repeat
1164
        cmp     [.packetSize], eax
1158
        cmp     [.packetSize], eax
1165
        jz      @f
1159
        jz      @f
1166
        mov     eax, [.buffer]
1160
        mov     eax, [.buffer]
1167
        call    get_phys_addr
1161
        call    get_phys_addr
1168
        mov     [ecx+ehci_gtd.BufferPointers-ehci_gtd.SoftwarePart], eax
1162
        mov     [ecx+ehci_gtd.BufferPointers-sizeof.ehci_gtd], eax
1169
        and     eax, 0xFFF
1163
        and     eax, 0xFFF
1170
        mov     edx, [.packetSize]
1164
        mov     edx, [.packetSize]
1171
        add     edx, eax
1165
        add     edx, eax
1172
        sub     edx, 0x1000
1166
        sub     edx, 0x1000
1173
        jbe     @f
1167
        jbe     @f
1174
        mov     eax, [.buffer]
1168
        mov     eax, [.buffer]
1175
        add     eax, 0x1000
1169
        add     eax, 0x1000
1176
        call    get_pg_addr
1170
        call    get_pg_addr
1177
        mov     [ecx+ehci_gtd.BufferPointers+4-ehci_gtd.SoftwarePart], eax
1171
        mov     [ecx+ehci_gtd.BufferPointers+4-sizeof.ehci_gtd], eax
1178
        sub     edx, 0x1000
1172
        sub     edx, 0x1000
1179
        jbe     @f
1173
        jbe     @f
1180
        mov     eax, [.buffer]
1174
        mov     eax, [.buffer]
1181
        add     eax, 0x2000
1175
        add     eax, 0x2000
1182
        call    get_pg_addr
1176
        call    get_pg_addr
1183
        mov     [ecx+ehci_gtd.BufferPointers+8-ehci_gtd.SoftwarePart], eax
1177
        mov     [ecx+ehci_gtd.BufferPointers+8-sizeof.ehci_gtd], eax
1184
        sub     edx, 0x1000
1178
        sub     edx, 0x1000
1185
        jbe     @f
1179
        jbe     @f
1186
        mov     eax, [.buffer]
1180
        mov     eax, [.buffer]
1187
        add     eax, 0x3000
1181
        add     eax, 0x3000
1188
        call    get_pg_addr
1182
        call    get_pg_addr
1189
        mov     [ecx+ehci_gtd.BufferPointers+12-ehci_gtd.SoftwarePart], eax
1183
        mov     [ecx+ehci_gtd.BufferPointers+12-sizeof.ehci_gtd], eax
1190
        sub     edx, 0x1000
1184
        sub     edx, 0x1000
1191
        jbe     @f
1185
        jbe     @f
1192
        mov     eax, [.buffer]
1186
        mov     eax, [.buffer]
1193
        add     eax, 0x4000
1187
        add     eax, 0x4000
1194
        call    get_pg_addr
1188
        call    get_pg_addr
1195
        mov     [ecx+ehci_gtd.BufferPointers+16-ehci_gtd.SoftwarePart], eax
1189
        mov     [ecx+ehci_gtd.BufferPointers+16-sizeof.ehci_gtd], eax
1196
@@:
1190
@@:
1197
; 7. Fill Token field:
1191
; 7. Fill Token field:
1198
; set Status = 0 (inactive, ehci_insert_transfer would mark everything active);
1192
; set Status = 0 (inactive, ehci_insert_transfer would mark everything active);
1199
; keep current PID if [.direction] is zero, use two lower bits of [.direction]
1193
; keep current PID if [.direction] is zero, use two lower bits of [.direction]
1200
; otherwise shifted as (0|1|2) -> (2|0|1);
1194
; otherwise shifted as (0|1|2) -> (2|0|1);
1201
; set error counter to 3;
1195
; set error counter to 3;
1202
; set current page to 0;
1196
; set current page to 0;
1203
; do not interrupt on complete (ehci_insert_transfer sets this bit where needed);
1197
; do not interrupt on complete (ehci_insert_transfer sets this bit where needed);
1204
; set DataToggle to bit 2 of [.direction].
1198
; set DataToggle to bit 2 of [.direction].
1205
        mov     eax, [ecx+ehci_gtd.Token-ehci_gtd.SoftwarePart]
1199
        mov     eax, [ecx+ehci_gtd.Token-sizeof.ehci_gtd]
1206
        and     eax, 300h       ; keep PID code
1200
        and     eax, 300h       ; keep PID code
1207
        mov     edx, [.direction]
1201
        mov     edx, [.direction]
1208
        test    edx, edx
1202
        test    edx, edx
1209
        jz      .haspid
1203
        jz      .haspid
1210
        and     edx, 3
1204
        and     edx, 3
Line 1220... Line 1214...
1220
.haspid:
1214
.haspid:
1221
        or      eax, 0C00h
1215
        or      eax, 0C00h
1222
        mov     edx, [.packetSize]
1216
        mov     edx, [.packetSize]
1223
        shl     edx, 16
1217
        shl     edx, 16
1224
        or      eax, edx
1218
        or      eax, edx
1225
        mov     [ecx+ehci_gtd.Token-ehci_gtd.SoftwarePart], eax
1219
        mov     [ecx+ehci_gtd.Token-sizeof.ehci_gtd], eax
1226
; 4. Restore the returned value saved in step 2.
1220
; 4. Restore the returned value saved in step 2.
1227
        pop     eax
1221
        pop     eax
1228
.nothing:
1222
.nothing:
1229
        ret
1223
        ret
1230
endp
1224
endp
Line 1232... Line 1226...
1232
; This procedure is called from several places in main USB code
1226
; This procedure is called from several places in main USB code
1233
; and activates the transfer which was previously allocated by
1227
; and activates the transfer which was previously allocated by
1234
; ehci_alloc_transfer.
1228
; ehci_alloc_transfer.
1235
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
1229
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
1236
proc ehci_insert_transfer
1230
proc ehci_insert_transfer
1237
        or      byte [ecx+ehci_gtd.Token+1-ehci_gtd.SoftwarePart], 80h  ; set IOC bit
1231
        or      byte [ecx+ehci_gtd.Token+1-sizeof.ehci_gtd], 80h  ; set IOC bit
1238
        mov     eax, [esp+4]
1232
        mov     eax, [esp+4]
1239
.activate:
1233
.activate:
1240
        or      byte [eax+ehci_gtd.Token-ehci_gtd.SoftwarePart], 80h    ; set Active bit
1234
        or      byte [eax+ehci_gtd.Token-sizeof.ehci_gtd], 80h    ; set Active bit
1241
        cmp     eax, ecx
1235
        cmp     eax, ecx
1242
        mov     eax, [eax+usb_gtd.NextVirt]
1236
        mov     eax, [eax+usb_gtd.NextVirt]
1243
        jnz     .activate
1237
        jnz     .activate
1244
        ret
1238
        ret
1245
endp
1239
endp
Line 1326... Line 1320...
1326
        mov     edx, [eax+usb_device_data.Hub]
1320
        mov     edx, [eax+usb_device_data.Hub]
1327
        jmp     .find_hs_hub
1321
        jmp     .find_hs_hub
1328
.found_hs_hub:
1322
.found_hs_hub:
1329
        mov     edx, [edx+usb_hub.ConfigPipe]
1323
        mov     edx, [edx+usb_hub.ConfigPipe]
1330
        inc     ecx
1324
        inc     ecx
1331
        mov     edx, [edx+ehci_pipe.Token-ehci_pipe.SoftwarePart]
1325
        mov     edx, [edx+ehci_pipe.Token-sizeof.ehci_pipe]
1332
        shl     ecx, 23
1326
        shl     ecx, 23
1333
        and     edx, 7Fh
1327
        and     edx, 7Fh
1334
        shl     edx, 16
1328
        shl     edx, 16
1335
        or      edx, ecx        ; ehci_pipe.Flags
1329
        or      edx, ecx        ; ehci_pipe.Flags
1336
        pop     eax
1330
        pop     eax
1337
        or      eax, 1 shl 27   ; ehci_pipe.Token
1331
        or      eax, 1 shl 27   ; ehci_pipe.Token
1338
.common:
1332
.common:
1339
; 5. Create pseudo-pipe in the stack.
1333
; 5. Create pseudo-pipe in the stack.
1340
; See ehci_init_pipe: only .Controller, .Token, .Flags fields are used.
1334
; See ehci_init_pipe: only .Controller, .Token, .Flags fields are used.
1341
        push    esi     ; ehci_pipe.SoftwarePart.Controller
1335
        push    esi     ; usb_pipe.Controller
1342
        mov     ecx, esp
1336
        mov     ecx, esp
1343
        sub     esp, ehci_pipe.SoftwarePart - ehci_pipe.Flags - 4
1337
        sub     esp, sizeof.ehci_pipe - ehci_pipe.Flags - 4
1344
        push    edx     ; ehci_pipe.Flags
1338
        push    edx     ; ehci_pipe.Flags
1345
        push    eax     ; ehci_pipe.Token
1339
        push    eax     ; ehci_pipe.Token
1346
; 6. Notify the protocol layer.
1340
; 6. Notify the protocol layer.
1347
        call    usb_new_device
1341
        call    usb_new_device
1348
; 7. Cleanup the stack after step 5 and return.
1342
; 7. Cleanup the stack after step 5 and return.
1349
        add     esp, ehci_pipe.SoftwarePart - ehci_pipe.Flags + 8
1343
        add     esp, sizeof.ehci_pipe - ehci_pipe.Flags + 8
1350
        pop     ecx ebx ; restore used registers
1344
        pop     ecx ebx ; restore used registers
1351
        ret
1345
        ret
1352
endp
1346
endp
Line 1353... Line 1347...
1353
 
1347
 
Line 1656... Line 1650...
1656
.tdloop:
1650
.tdloop:
1657
; 3. For every descriptor, test active flag and check for end-of-queue;
1651
; 3. For every descriptor, test active flag and check for end-of-queue;
1658
; if either of conditions holds, exit from the internal loop.
1652
; if either of conditions holds, exit from the internal loop.
1659
        cmp     ebx, [esp]
1653
        cmp     ebx, [esp]
1660
        jz      .tddone
1654
        jz      .tddone
1661
        cmp     byte [ebx+ehci_gtd.Token-ehci_gtd.SoftwarePart], 0
1655
        cmp     byte [ebx+ehci_gtd.Token-sizeof.ehci_gtd], 0
1662
        js      .tddone
1656
        js      .tddone
1663
; Release the queue lock while processing one descriptor:
1657
; Release the queue lock while processing one descriptor:
1664
; callback function could (and often would) schedule another transfer.
1658
; callback function could (and often would) schedule another transfer.
1665
        push    ecx
1659
        push    ecx
1666
        call    mutex_unlock
1660
        call    mutex_unlock
Line 1688... Line 1682...
1688
proc ehci_process_updated_td
1682
proc ehci_process_updated_td
1689
;       mov     eax, [ebx+usb_gtd.Pipe]
1683
;       mov     eax, [ebx+usb_gtd.Pipe]
1690
;       cmp     [eax+usb_pipe.Type], INTERRUPT_PIPE
1684
;       cmp     [eax+usb_pipe.Type], INTERRUPT_PIPE
1691
;       jnz     @f
1685
;       jnz     @f
1692
;       DEBUGF 1,'K : finalized TD for pipe %x:\n',eax
1686
;       DEBUGF 1,'K : finalized TD for pipe %x:\n',eax
1693
;       lea     eax, [ebx-ehci_gtd.SoftwarePart]
1687
;       lea     eax, [ebx-sizeof.ehci_gtd]
1694
;       DEBUGF 1,'K : %x %x %x %x\n',[eax],[eax+4],[eax+8],[eax+12]
1688
;       DEBUGF 1,'K : %x %x %x %x\n',[eax],[eax+4],[eax+8],[eax+12]
1695
;       DEBUGF 1,'K : %x %x %x %x\n',[eax+16],[eax+20],[eax+24],[eax+28]
1689
;       DEBUGF 1,'K : %x %x %x %x\n',[eax+16],[eax+20],[eax+24],[eax+28]
1696
;@@:
1690
;@@:
1697
; 1. Remove this descriptor from the list of descriptors for this pipe.
1691
; 1. Remove this descriptor from the list of descriptors for this pipe.
1698
        call    usb_unlink_td
1692
        call    usb_unlink_td
1699
; 2. Calculate actual number of bytes transferred.
1693
; 2. Calculate actual number of bytes transferred.
1700
        mov     eax, [ebx+ehci_gtd.Token-ehci_gtd.SoftwarePart]
1694
        mov     eax, [ebx+ehci_gtd.Token-sizeof.ehci_gtd]
1701
        lea     edx, [eax+eax]
1695
        lea     edx, [eax+eax]
1702
        shr     edx, 17
1696
        shr     edx, 17
1703
        sub     edx, [ebx+usb_gtd.Length]
1697
        sub     edx, [ebx+usb_gtd.Length]
1704
        neg     edx
1698
        neg     edx
1705
; 3. Check whether we need some special processing beyond notifying the driver.
1699
; 3. Check whether we need some special processing beyond notifying the driver.
Line 1713... Line 1707...
1713
; If special processing is not needed, advance to 4 with ecx = 0.
1707
; If special processing is not needed, advance to 4 with ecx = 0.
1714
; Otherwise, go to 6.
1708
; Otherwise, go to 6.
1715
        xor     ecx, ecx
1709
        xor     ecx, ecx
1716
        test    al, 40h
1710
        test    al, 40h
1717
        jnz     .error
1711
        jnz     .error
1718
        test    byte [ebx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], 1
1712
        test    byte [ebx+ehci_gtd.Flags-sizeof.ehci_gtd], 1
1719
        jnz     .notify
1713
        jnz     .notify
1720
        cmp     edx, [ebx+usb_gtd.Length]
1714
        cmp     edx, [ebx+usb_gtd.Length]
1721
        jnz     .special
1715
        jnz     .special
1722
.notify:
1716
.notify:
1723
; 4. Either the descriptor in ebx was processed without errors,
1717
; 4. Either the descriptor in ebx was processed without errors,
Line 1743... Line 1737...
1743
        stdcall ehci_free_td, ebx
1737
        stdcall ehci_free_td, ebx
1744
        pop     ebx
1738
        pop     ebx
1745
        ret
1739
        ret
1746
.error:
1740
.error:
1747
        push    ebx
1741
        push    ebx
1748
        sub     ebx, ehci_gtd.SoftwarePart
1742
        sub     ebx, sizeof.ehci_gtd
1749
        DEBUGF 1,'K : TD failed:\n'
1743
        DEBUGF 1,'K : TD failed:\n'
1750
        DEBUGF 1,'K : %x %x %x %x\n',[ebx],[ebx+4],[ebx+8],[ebx+12]
1744
        DEBUGF 1,'K : %x %x %x %x\n',[ebx],[ebx+4],[ebx+8],[ebx+12]
1751
        DEBUGF 1,'K : %x %x %x %x\n',[ebx+16],[ebx+20],[ebx+24],[ebx+28]
1745
        DEBUGF 1,'K : %x %x %x %x\n',[ebx+16],[ebx+20],[ebx+24],[ebx+28]
1752
        pop     ebx
1746
        pop     ebx
1753
        DEBUGF 1,'K : pipe now:\n'
1747
        DEBUGF 1,'K : pipe now:\n'
1754
        mov     ecx, [ebx+usb_gtd.Pipe]
1748
        mov     ecx, [ebx+usb_gtd.Pipe]
1755
        sub     ecx, ehci_pipe.SoftwarePart
1749
        sub     ecx, sizeof.ehci_pipe
1756
        DEBUGF 1,'K : %x %x %x %x\n',[ecx],[ecx+4],[ecx+8],[ecx+12]
1750
        DEBUGF 1,'K : %x %x %x %x\n',[ecx],[ecx+4],[ecx+8],[ecx+12]
1757
        DEBUGF 1,'K : %x %x %x %x\n',[ecx+16],[ecx+20],[ecx+24],[ecx+28]
1751
        DEBUGF 1,'K : %x %x %x %x\n',[ecx+16],[ecx+20],[ecx+24],[ecx+28]
1758
        DEBUGF 1,'K : %x %x %x %x\n',[ecx+32],[ecx+36],[ecx+40],[ecx+44]
1752
        DEBUGF 1,'K : %x %x %x %x\n',[ecx+32],[ecx+36],[ecx+40],[ecx+44]
1759
.special:
1753
.special:
1760
; 6. Special processing is needed.
1754
; 6. Special processing is needed.
Line 1800... Line 1794...
1800
.know_error:
1794
.know_error:
1801
; 6d. If error code is USB_STATUS_UNDERRUN and the last TD allows short packets,
1795
; 6d. If error code is USB_STATUS_UNDERRUN and the last TD allows short packets,
1802
; it is not an error; in this case, go to 4 with ecx = 0.
1796
; it is not an error; in this case, go to 4 with ecx = 0.
1803
        cmp     ecx, USB_STATUS_UNDERRUN
1797
        cmp     ecx, USB_STATUS_UNDERRUN
1804
        jnz     @f
1798
        jnz     @f
1805
        test    byte [ebx+ehci_gtd.Flags-ehci_gtd.SoftwarePart], 1
1799
        test    byte [ebx+ehci_gtd.Flags-sizeof.ehci_gtd], 1
1806
        jz      @f
1800
        jz      @f
1807
        xor     ecx, ecx
1801
        xor     ecx, ecx
1808
        pop     edx     ; length
1802
        pop     edx     ; length
1809
        jmp     .notify
1803
        jmp     .notify
1810
@@:
1804
@@:
Line 1830... Line 1824...
1830
; Control pipes normally recover at the next SETUP transaction (first stage
1824
; Control pipes normally recover at the next SETUP transaction (first stage
1831
; of any control transfer), so we hope on the best and just advance the queue
1825
; of any control transfer), so we hope on the best and just advance the queue
1832
; to the next transfer. (According to the standard, "A control pipe may also
1826
; to the next transfer. (According to the standard, "A control pipe may also
1833
; support functional stall as well, but this is not recommended.").
1827
; support functional stall as well, but this is not recommended.").
1834
        mov     edx, [ebx+usb_gtd.Pipe]
1828
        mov     edx, [ebx+usb_gtd.Pipe]
1835
        mov     eax, [ebx+ehci_gtd.NextTD-ehci_gtd.SoftwarePart]
1829
        mov     eax, [ebx+ehci_gtd.NextTD-sizeof.ehci_gtd]
1836
        or      al, 1
1830
        or      al, 1
1837
        mov     [edx+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart], eax
1831
        mov     [edx+ehci_pipe.Overlay.NextTD-sizeof.ehci_pipe], eax
1838
        mov     [edx+ehci_pipe.Overlay.AlternateNextTD-ehci_pipe.SoftwarePart], eax
1832
        mov     [edx+ehci_pipe.Overlay.AlternateNextTD-sizeof.ehci_pipe], eax
1839
        cmp     [edx+usb_pipe.Type], CONTROL_PIPE
1833
        cmp     [edx+usb_pipe.Type], CONTROL_PIPE
1840
        jz      .control
1834
        jz      .control
1841
; Bulk/interrupt transfer; halt the queue.
1835
; Bulk/interrupt transfer; halt the queue.
1842
        mov     [edx+ehci_pipe.Overlay.Token-ehci_pipe.SoftwarePart], 40h
1836
        mov     [edx+ehci_pipe.Overlay.Token-sizeof.ehci_pipe], 40h
1843
        pop     edx
1837
        pop     edx
1844
        jmp     .notify
1838
        jmp     .notify
1845
; Control transfer.
1839
; Control transfer.
1846
.control:
1840
.control:
1847
        and     [edx+ehci_pipe.Overlay.Token-ehci_pipe.SoftwarePart], 0
1841
        and     [edx+ehci_pipe.Overlay.Token-sizeof.ehci_pipe], 0
1848
        dec     [edx+ehci_pipe.Overlay.NextTD-ehci_pipe.SoftwarePart]
1842
        dec     [edx+ehci_pipe.Overlay.NextTD-sizeof.ehci_pipe]
1849
        pop     edx
1843
        pop     edx
1850
        jmp     .notify
1844
        jmp     .notify
1851
endp
1845
endp
Line 1852... Line 1846...
1852
 
1846
 
1853
; This procedure unlinks the pipe from the corresponding pipe list.
1847
; This procedure unlinks the pipe from the corresponding pipe list.
1854
; esi -> usb_controller, ebx -> usb_pipe
1848
; esi -> usb_controller, ebx -> usb_pipe
1855
proc ehci_unlink_pipe
1849
proc ehci_unlink_pipe
1856
        cmp     [ebx+usb_pipe.Type], INTERRUPT_PIPE
1850
        cmp     [ebx+usb_pipe.Type], INTERRUPT_PIPE
1857
        jnz     @f
1851
        jnz     @f
1858
        test    word [ebx+ehci_pipe.Flags-ehci_pipe.SoftwarePart+2], 3FFFh
1852
        test    word [ebx+ehci_pipe.Flags-sizeof.ehci_pipe+2], 3FFFh
1859
        jnz     .interrupt_fs
1853
        jnz     .interrupt_fs
1860
        call    ehci_hs_interrupt_list_unlink
1854
        call    ehci_hs_interrupt_list_unlink
1861
        jmp     .interrupt_common
1855
        jmp     .interrupt_common
1862
.interrupt_fs:
1856
.interrupt_fs:
Line 1868... Line 1862...
1868
        mov     [edx+usb_pipe.PrevVirt], eax
1862
        mov     [edx+usb_pipe.PrevVirt], eax
1869
        mov     [eax+usb_pipe.NextVirt], edx
1863
        mov     [eax+usb_pipe.NextVirt], edx
1870
        mov     edx, esi
1864
        mov     edx, esi
1871
        sub     edx, eax
1865
        sub     edx, eax
1872
        cmp     edx, sizeof.ehci_controller
1866
        cmp     edx, sizeof.ehci_controller
1873
        mov     edx, [ebx+ehci_pipe.NextQH-ehci_pipe.SoftwarePart]
1867
        mov     edx, [ebx+ehci_pipe.NextQH-sizeof.ehci_pipe]
1874
        jb      .prev_is_static
1868
        jb      .prev_is_static
1875
        mov     [eax+ehci_pipe.NextQH-ehci_pipe.SoftwarePart], edx
1869
        mov     [eax+ehci_pipe.NextQH-sizeof.ehci_pipe], edx
1876
        ret
1870
        ret
1877
.prev_is_static:
1871
.prev_is_static:
1878
        mov     [eax+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], edx
1872
        mov     [eax+ehci_static_ep.NextQH-ehci_static_ep.SoftwarePart], edx
1879
        ret
1873
        ret
1880
endp
1874
endp
Line 1881... Line 1875...
1881
 
1875
 
1882
proc ehci_alloc_td
1876
proc ehci_alloc_td
1883
        push    ebx
1877
        push    ebx
1884
        mov     ebx, ehci_gtd_mutex
1878
        mov     ebx, ehci_gtd_mutex
1885
        stdcall usb_allocate_common, sizeof.ehci_gtd
1879
        stdcall usb_allocate_common, (sizeof.ehci_gtd + sizeof.usb_gtd + 1Fh) and not 1Fh
1886
        test    eax, eax
1880
        test    eax, eax
1887
        jz      @f
1881
        jz      @f
1888
        add     eax, ehci_gtd.SoftwarePart
1882
        add     eax, sizeof.ehci_gtd
1889
@@:
1883
@@:
1890
        pop     ebx
1884
        pop     ebx
1891
        ret
1885
        ret
Line 1892... Line 1886...
1892
endp
1886
endp
1893
 
1887
 
1894
; This procedure is called from several places from main USB code and
1888
; This procedure is called from several places from main USB code and
1895
; frees all additional data associated with the transfer descriptor.
1889
; frees all additional data associated with the transfer descriptor.
1896
; EHCI has no additional data, so just free ehci_gtd structure.
1890
; EHCI has no additional data, so just free ehci_gtd structure.
1897
proc ehci_free_td
1891
proc ehci_free_td
1898
        sub     dword [esp+4], ehci_gtd.SoftwarePart
1892
        sub     dword [esp+4], sizeof.ehci_gtd