Subversion Repositories Kolibri OS

Rev

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

Rev 3598 Rev 3653
Line 42... Line 42...
42
; OHCI-specific part of a pipe descriptor.
42
; OHCI-specific part of a pipe descriptor.
43
; * This structure corresponds to the Endpoint Descriptor aka ED from the OHCI
43
; * This structure corresponds to the Endpoint Descriptor aka ED from the OHCI
44
;   specification.
44
;   specification.
45
; * The hardware requires 16-bytes alignment of the hardware part.
45
; * The hardware requires 16-bytes alignment of the hardware part.
46
;   Since the allocator (usb_allocate_common) allocates memory sequentially
46
;   Since the allocator (usb_allocate_common) allocates memory sequentially
47
;   from page start (aligned on 0x1000 bytes), size of the structure must be
47
;   from page start (aligned on 0x1000 bytes), block size for the allocator
48
;   divisible by 16.
48
;   must be divisible by 16; usb1_allocate_endpoint ensures this.
49
struct ohci_pipe
49
struct ohci_pipe
50
; All addresses are physical.
50
; All addresses are physical.
51
Flags           dd      ?
51
Flags           dd      ?
52
; 1. Lower 7 bits (bits 0-6) are FunctionAddress. This is the USB address of
52
; 1. Lower 7 bits (bits 0-6) are FunctionAddress. This is the USB address of
53
;    the function containing the endpoint that this ED controls.
53
;    the function containing the endpoint that this ED controls.
Line 93... Line 93...
93
; * The 1ms periodic list also serves Isochronous endpoints, which should be
93
; * The 1ms periodic list also serves Isochronous endpoints, which should be
94
;   in the end of the list.
94
;   in the end of the list.
95
; * There is no "next" list for Bulk and Control lists, they are processed
95
; * There is no "next" list for Bulk and Control lists, they are processed
96
;   separately from others.
96
;   separately from others.
97
; * There is no "next" list for Periodic list for 1ms interval.
97
; * There is no "next" list for Periodic list for 1ms interval.
98
SoftwarePart    rd      sizeof.usb_pipe/4
-
 
99
; Software part, common for all controllers.
-
 
100
ends
98
ends
Line 101... Line -...
101
 
-
 
102
if sizeof.ohci_pipe mod 16
-
 
103
.err ohci_pipe must be 16-bytes aligned
-
 
104
end if
-
 
105
 
99
 
106
; This structure describes the static head of every list of pipes.
100
; This structure describes the static head of every list of pipes.
107
; The hardware requires 16-bytes alignment of this structure.
101
; The hardware requires 16-bytes alignment of this structure.
108
; All instances of this structure are located sequentially in uhci_controller,
102
; All instances of this structure are located sequentially in uhci_controller,
109
; uhci_controller is page-aligned, so it is sufficient to make this structure
103
; uhci_controller is page-aligned, so it is sufficient to make this structure
Line 202... Line 196...
202
; * The hardware part consists of first 16 bytes and corresponds to
196
; * The hardware part consists of first 16 bytes and corresponds to
203
;   the General Transfer Descriptor aka general TD from OHCI specification.
197
;   the General Transfer Descriptor aka general TD from OHCI specification.
204
; * The hardware requires 16-bytes alignment of the hardware part, so
198
; * The hardware requires 16-bytes alignment of the hardware part, so
205
;   the entire descriptor must be 16-bytes aligned. Since the allocator
199
;   the entire descriptor must be 16-bytes aligned. Since the allocator
206
;   (usb_allocate_common) allocates memory sequentially from page start
200
;   (usb_allocate_common) allocates memory sequentially from page start
207
;   (aligned on 0x1000 bytes), size of the structure must be divisible by 16.
201
;   (aligned on 0x1000 bytes), block size for the allocator must be
-
 
202
;   divisible by 16; usb1_allocate_generic_td ensures this.
208
struct ohci_gtd
203
struct ohci_gtd
209
; ------------------------------ hardware fields ------------------------------
204
; ------------------------------ hardware fields ------------------------------
210
; All addresses in this part are physical.
205
; All addresses in this part are physical.
211
Flags           dd      ?
206
Flags           dd      ?
212
; 1. Lower 18 bits (bits 0-17) are ignored and not modified by the hardware.
207
; 1. Lower 18 bits (bits 0-17) are ignored and not modified by the hardware.
Line 246... Line 241...
246
;   Physical address of the previous processed TD.
241
;   Physical address of the previous processed TD.
247
; When the descriptor is processed by the IRQ handler, but not yet completed:
242
; When the descriptor is processed by the IRQ handler, but not yet completed:
248
;   Virtual pointer to the next processed TD.
243
;   Virtual pointer to the next processed TD.
249
BufEnd          dd      ?
244
BufEnd          dd      ?
250
; Physical address of the last byte in the buffer for this TD.
245
; Physical address of the last byte in the buffer for this TD.
251
                dd      ?       ; padding for 16-bytes alignment
-
 
252
SoftwarePart    rd      sizeof.usb_gtd/4
246
		dd	?	; padding to align with uhci_gtd
253
; Common part for all controllers.
-
 
254
ends
247
ends
Line 255... Line -...
255
 
-
 
256
if sizeof.ohci_gtd mod 16
-
 
257
.err ohci_gtd must be 16-bytes aligned
-
 
258
end if
-
 
259
 
248
 
260
; OHCI isochronous transfer descriptor.
249
; OHCI isochronous transfer descriptor.
261
; * The structure describes transfers to be performed on Isochronous endpoints.
250
; * The structure describes transfers to be performed on Isochronous endpoints.
262
; * The structure includes two parts, the hardware part and the software part.
251
; * The structure includes two parts, the hardware part and the software part.
263
; * The hardware part consists of first 32 bytes and corresponds to
252
; * The hardware part consists of first 32 bytes and corresponds to
Line 724... Line 713...
724
; edx = virtual pointer to the last item.NextTD (first in the reverse list)
713
; edx = virtual pointer to the last item.NextTD (first in the reverse list)
725
; ebx = virtual pointer to the next item (previous in the reverse list)
714
; ebx = virtual pointer to the next item (previous in the reverse list)
726
.tdloop:
715
.tdloop:
727
        mov     ecx, [eax+ohci_gtd.NextTD]
716
        mov     ecx, [eax+ohci_gtd.NextTD]
728
        mov     [eax+ohci_gtd.NextTD], ebx
717
        mov     [eax+ohci_gtd.NextTD], ebx
729
        lea     ebx, [eax+ohci_gtd.SoftwarePart]
718
        lea     ebx, [eax+sizeof.ohci_gtd]
730
        test    ecx, ecx
719
        test    ecx, ecx
731
        jz      .tddone
720
        jz      .tddone
732
        call    usb_td_to_virt
721
        call    usb_td_to_virt
733
        test    eax, eax
722
        test    eax, eax
734
        jnz     .tdloop
723
        jnz     .tdloop
Line 891... Line 880...
891
 
880
 
892
; This procedure is called from usb_set_address_callback
881
; This procedure is called from usb_set_address_callback
893
; and stores USB device address in the ohci_pipe structure.
882
; and stores USB device address in the ohci_pipe structure.
894
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
883
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
895
proc ohci_set_device_address
884
proc ohci_set_device_address
896
        mov     byte [ebx+ohci_pipe.Flags-ohci_pipe.SoftwarePart], cl
885
        mov     byte [ebx+ohci_pipe.Flags-sizeof.ohci_pipe], cl
897
; Wait until the hardware will forget the old value.
886
; Wait until the hardware will forget the old value.
898
        call    usb_subscribe_control
887
        call    usb_subscribe_control
899
        ret
888
        ret
Line 900... Line 889...
900
endp
889
endp
901
 
890
 
902
; This procedure returns USB device address from the usb_pipe structure.
891
; This procedure returns USB device address from the usb_pipe structure.
903
; in: esi -> usb_controller, ebx -> usb_pipe
892
; in: esi -> usb_controller, ebx -> usb_pipe
904
; out: eax = endpoint address
893
; out: eax = endpoint address
905
proc ohci_get_device_address
894
proc ohci_get_device_address
906
        mov     eax, [ebx+ohci_pipe.Flags-ohci_pipe.SoftwarePart]
895
        mov     eax, [ebx+ohci_pipe.Flags-sizeof.ohci_pipe]
907
        and     eax, 7Fh
896
        and     eax, 7Fh
Line 908... Line 897...
908
        ret
897
        ret
Line 921... Line 910...
921
; This procedure is called from usb_get_descr8_callback when
910
; This procedure is called from usb_get_descr8_callback when
922
; the packet size for zero endpoint becomes known and
911
; the packet size for zero endpoint becomes known and
923
; stores the packet size in ohci_pipe structure.
912
; stores the packet size in ohci_pipe structure.
924
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
913
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
925
proc ohci_set_endpoint_packet_size
914
proc ohci_set_endpoint_packet_size
926
        mov     byte [ebx+ohci_pipe.Flags+2-ohci_pipe.SoftwarePart], cl
915
        mov     byte [ebx+ohci_pipe.Flags+2-sizeof.ohci_pipe], cl
927
; Wait until the hardware will forget the old value.
916
; Wait until the hardware will forget the old value.
928
        call    usb_subscribe_control
917
        call    usb_subscribe_control
929
        ret
918
        ret
930
endp
919
endp
Line 941... Line 930...
941
.maxpacket      dd      ?
930
.maxpacket      dd      ?
942
.type           dd      ?
931
.type           dd      ?
943
.interval       dd      ?
932
.interval       dd      ?
944
end virtual
933
end virtual
945
; 1. Initialize the queue of transfer descriptors: empty.
934
; 1. Initialize the queue of transfer descriptors: empty.
946
        sub     eax, ohci_gtd.SoftwarePart
935
        sub     eax, sizeof.ohci_gtd
947
        call    get_phys_addr
936
        call    get_phys_addr
948
        mov     [edi+ohci_pipe.TailP-ohci_pipe.SoftwarePart], eax
937
        mov     [edi+ohci_pipe.TailP-sizeof.ohci_pipe], eax
949
        mov     [edi+ohci_pipe.HeadP-ohci_pipe.SoftwarePart], eax
938
        mov     [edi+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
950
; 2. Generate ohci_pipe.Flags, see the description in ohci_pipe.
939
; 2. Generate ohci_pipe.Flags, see the description in ohci_pipe.
951
        mov     eax, [ecx+ohci_pipe.Flags-ohci_pipe.SoftwarePart]
940
        mov     eax, [ecx+ohci_pipe.Flags-sizeof.ohci_pipe]
952
        and     eax, 0x207F     ; keep Speed bit and FunctionAddress
941
        and     eax, 0x207F     ; keep Speed bit and FunctionAddress
953
        mov     edx, [.endpoint]
942
        mov     edx, [.endpoint]
954
        and     edx, 15
943
        and     edx, 15
955
        shl     edx, 7
944
        shl     edx, 7
956
        or      eax, edx
945
        or      eax, edx
957
        mov     [edi+ohci_pipe.Flags-ohci_pipe.SoftwarePart], eax
946
        mov     [edi+ohci_pipe.Flags-sizeof.ohci_pipe], eax
958
        mov     eax, [.maxpacket]
947
        mov     eax, [.maxpacket]
959
        mov     word [edi+ohci_pipe.Flags+2-ohci_pipe.SoftwarePart], ax
948
        mov     word [edi+ohci_pipe.Flags+2-sizeof.ohci_pipe], ax
960
        cmp     [.type], CONTROL_PIPE
949
        cmp     [.type], CONTROL_PIPE
961
        jz      @f
950
        jz      @f
962
        test    byte [.endpoint], 80h
951
        test    byte [.endpoint], 80h
963
        setnz   al
952
        setnz   al
964
        inc     eax
953
        inc     eax
965
        shl     al, 3
954
        shl     al, 3
966
        or      byte [edi+ohci_pipe.Flags+1-ohci_pipe.SoftwarePart], al
955
        or      byte [edi+ohci_pipe.Flags+1-sizeof.ohci_pipe], al
967
@@:
956
@@:
968
; 3. Insert the new pipe to the corresponding list of endpoints.
957
; 3. Insert the new pipe to the corresponding list of endpoints.
969
; 3a. Use Control list for control pipes, Bulk list for bulk pipes.
958
; 3a. Use Control list for control pipes, Bulk list for bulk pipes.
970
        lea     edx, [esi+ohci_controller.ControlED.SoftwarePart-sizeof.ohci_controller]
959
        lea     edx, [esi+ohci_controller.ControlED.SoftwarePart-sizeof.ohci_controller]
971
        cmp     [.type], BULK_PIPE
960
        cmp     [.type], BULK_PIPE
Line 990... Line 979...
990
        mov     ecx, [edx+usb_pipe.NextVirt]
979
        mov     ecx, [edx+usb_pipe.NextVirt]
991
        mov     [edi+usb_pipe.NextVirt], ecx
980
        mov     [edi+usb_pipe.NextVirt], ecx
992
        mov     [edi+usb_pipe.PrevVirt], edx
981
        mov     [edi+usb_pipe.PrevVirt], edx
993
        mov     [ecx+usb_pipe.PrevVirt], edi
982
        mov     [ecx+usb_pipe.PrevVirt], edi
994
        mov     [edx+usb_pipe.NextVirt], edi
983
        mov     [edx+usb_pipe.NextVirt], edi
995
        mov     ecx, [edx+ohci_pipe.NextED-ohci_pipe.SoftwarePart]
984
        mov     ecx, [edx+ohci_pipe.NextED-sizeof.ohci_pipe]
996
        mov     [edi+ohci_pipe.NextED-ohci_pipe.SoftwarePart], ecx
985
        mov     [edi+ohci_pipe.NextED-sizeof.ohci_pipe], ecx
997
        lea     eax, [edi-ohci_pipe.SoftwarePart]
986
        lea     eax, [edi-sizeof.ohci_pipe]
998
        call    get_phys_addr
987
        call    get_phys_addr
999
        mov     [edx+ohci_pipe.NextED-ohci_pipe.SoftwarePart], eax
988
        mov     [edx+ohci_pipe.NextED-sizeof.ohci_pipe], eax
1000
; 4. Return something non-zero.
989
; 4. Return something non-zero.
1001
        ret
990
        ret
1002
.return0:
991
.return0:
1003
        xor     eax, eax
992
        xor     eax, eax
1004
        ret
993
        ret
Line 1092... Line 1081...
1092
        mov     [packetSize], eax
1081
        mov     [packetSize], eax
1093
        call    ohci_alloc_packet
1082
        call    ohci_alloc_packet
1094
        test    eax, eax
1083
        test    eax, eax
1095
        jz      .fail
1084
        jz      .fail
1096
; 4. Enable an immediate interrupt on completion of the last packet.
1085
; 4. Enable an immediate interrupt on completion of the last packet.
1097
        and     byte [ecx+ohci_gtd.Flags+2-ohci_gtd.SoftwarePart], not (7 shl (21-16))
1086
        and     byte [ecx+ohci_gtd.Flags+2-sizeof.ohci_gtd], not (7 shl (21-16))
1098
; 5. If a short transfer is ok for a caller, set the corresponding bit in
1087
; 5. If a short transfer is ok for a caller, set the corresponding bit in
1099
; the last descriptor, but not in others.
1088
; the last descriptor, but not in others.
1100
; Note: even if the caller says that short transfers are ok,
1089
; Note: even if the caller says that short transfers are ok,
1101
; all packets except the last one are marked as 'must be complete':
1090
; all packets except the last one are marked as 'must be complete':
1102
; if one of them will be short, the software intervention is needed
1091
; if one of them will be short, the software intervention is needed
1103
; to skip remaining packets; ohci_process_finalized_td will handle this
1092
; to skip remaining packets; ohci_process_finalized_td will handle this
1104
; transparently to the caller.
1093
; transparently to the caller.
1105
        test    [flags], 1
1094
        test    [flags], 1
1106
        jz      @f
1095
        jz      @f
1107
        or      byte [ecx+ohci_gtd.Flags+2-ohci_gtd.SoftwarePart], 1 shl (18-16)
1096
        or      byte [ecx+ohci_gtd.Flags+2-sizeof.ohci_gtd], 1 shl (18-16)
1108
@@:
1097
@@:
1109
        ret
1098
        ret
1110
.fail:
1099
.fail:
1111
        mov     edi, ohci_hardware_func
1100
        mov     edi, ohci_hardware_func
1112
        mov     eax, [td]
1101
        mov     eax, [td]
Line 1141... Line 1130...
1141
        call    usb_init_transfer
1130
        call    usb_init_transfer
1142
        pop     eax
1131
        pop     eax
1143
; 3. Save the returned value (next descriptor).
1132
; 3. Save the returned value (next descriptor).
1144
        push    eax
1133
        push    eax
1145
; 4. Store the physical address of the next descriptor.
1134
; 4. Store the physical address of the next descriptor.
1146
        sub     eax, ohci_gtd.SoftwarePart
1135
        sub     eax, sizeof.ohci_gtd
1147
        call    get_phys_addr
1136
        call    get_phys_addr
1148
        mov     [ecx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart], eax
1137
        mov     [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd], eax
1149
; 5. For zero-length transfers, store zero in both fields for buffer addresses.
1138
; 5. For zero-length transfers, store zero in both fields for buffer addresses.
1150
; Otherwise, fill them with real values.
1139
; Otherwise, fill them with real values.
1151
        xor     eax, eax
1140
        xor     eax, eax
1152
        mov     [ecx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart], eax
1141
        mov     [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
1153
        mov     [ecx+ohci_gtd.BufEnd-ohci_gtd.SoftwarePart], eax
1142
        mov     [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
1154
        cmp     [.packetSize], eax
1143
        cmp     [.packetSize], eax
1155
        jz      @f
1144
        jz      @f
1156
        mov     eax, [.buffer]
1145
        mov     eax, [.buffer]
1157
        call    get_phys_addr
1146
        call    get_phys_addr
1158
        mov     [ecx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart], eax
1147
        mov     [ecx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], eax
1159
        mov     eax, [.buffer]
1148
        mov     eax, [.buffer]
1160
        add     eax, [.packetSize]
1149
        add     eax, [.packetSize]
1161
        dec     eax
1150
        dec     eax
1162
        call    get_phys_addr
1151
        call    get_phys_addr
1163
        mov     [ecx+ohci_gtd.BufEnd-ohci_gtd.SoftwarePart], eax
1152
        mov     [ecx+ohci_gtd.BufEnd-sizeof.ohci_gtd], eax
1164
@@:
1153
@@:
1165
; 6. Generate Flags field:
1154
; 6. Generate Flags field:
1166
; - set bufferRounding (bit 18) to zero = disallow short transfers;
1155
; - set bufferRounding (bit 18) to zero = disallow short transfers;
1167
;   for the last transfer in a row, ohci_alloc_transfer would set the real value;
1156
;   for the last transfer in a row, ohci_alloc_transfer would set the real value;
1168
; - set Direction (bits 19-20) to lower 2 bits of [.direction];
1157
; - set Direction (bits 19-20) to lower 2 bits of [.direction];
Line 1177... Line 1166...
1177
        and     eax, 3
1166
        and     eax, 3
1178
        shl     eax, 19
1167
        shl     eax, 19
1179
        and     edx, (3 shl 2)
1168
        and     edx, (3 shl 2)
1180
        shl     edx, 24 - 2
1169
        shl     edx, 24 - 2
1181
        lea     eax, [eax + edx + (7 shl 21) + (15 shl 28)]
1170
        lea     eax, [eax + edx + (7 shl 21) + (15 shl 28)]
1182
        mov     [ecx+ohci_gtd.Flags-ohci_gtd.SoftwarePart], eax
1171
        mov     [ecx+ohci_gtd.Flags-sizeof.ohci_gtd], eax
1183
; 7. Restore the returned value saved in step 3.
1172
; 7. Restore the returned value saved in step 3.
1184
        pop     eax
1173
        pop     eax
1185
.nothing:
1174
.nothing:
1186
        ret
1175
        ret
1187
endp
1176
endp
Line 1190... Line 1179...
1190
; and activates the transfer which was previously allocated by
1179
; and activates the transfer which was previously allocated by
1191
; ohci_alloc_transfer.
1180
; ohci_alloc_transfer.
1192
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
1181
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
1193
proc ohci_insert_transfer
1182
proc ohci_insert_transfer
1194
; 1. Advance the queue of transfer descriptors.
1183
; 1. Advance the queue of transfer descriptors.
1195
        mov     eax, [ecx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart]
1184
        mov     eax, [ecx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1196
        mov     [ebx+ohci_pipe.TailP-ohci_pipe.SoftwarePart], eax
1185
        mov     [ebx+ohci_pipe.TailP-sizeof.ohci_pipe], eax
1197
; 2. For control and bulk pipes, notify the controller that
1186
; 2. For control and bulk pipes, notify the controller that
1198
; there is new work in control/bulk queue respectively.
1187
; there is new work in control/bulk queue respectively.
1199
ohci_notify_new_work:
1188
ohci_notify_new_work:
1200
        mov     edx, [ebx+usb_pipe.Controller]
1189
        mov     edx, [ebx+usb_pipe.Controller]
1201
        mov     edx, [edx+ohci_controller.MMIOBase-sizeof.ohci_controller]
1190
        mov     edx, [edx+ohci_controller.MMIOBase-sizeof.ohci_controller]
Line 1391... Line 1380...
1391
; disconnect; if so, the callback will be called by usb_pipe_closed with
1380
; disconnect; if so, the callback will be called by usb_pipe_closed with
1392
; correct status, so go to step 6 with ebx = 0 (do not free the TD).
1381
; correct status, so go to step 6 with ebx = 0 (do not free the TD).
1393
        mov     edx, [ebx+usb_gtd.Pipe]
1382
        mov     edx, [ebx+usb_gtd.Pipe]
1394
        test    [edx+usb_pipe.Flags], USB_FLAG_CLOSED
1383
        test    [edx+usb_pipe.Flags], USB_FLAG_CLOSED
1395
        jz      @f
1384
        jz      @f
1396
        lea     eax, [ebx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart]
1385
        lea     eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1397
        xor     ebx, ebx
1386
        xor     ebx, ebx
1398
        jmp     .next_td2
1387
        jmp     .next_td2
1399
@@:
1388
@@:
1400
; 2. Remove the descriptor from the descriptors queue.
1389
; 2. Remove the descriptor from the descriptors queue.
1401
        call    usb_unlink_td
1390
        call    usb_unlink_td
1402
; 3. Get number of bytes that remain to be transferred.
1391
; 3. Get number of bytes that remain to be transferred.
1403
; If CurBufPtr is zero, everything was transferred.
1392
; If CurBufPtr is zero, everything was transferred.
1404
        xor     edx, edx
1393
        xor     edx, edx
1405
        cmp     [ebx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart], edx
1394
        cmp     [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd], edx
1406
        jz      .gotlen
1395
        jz      .gotlen
1407
; Otherwise, the remaining length is
1396
; Otherwise, the remaining length is
1408
; (BufEnd and 0xFFF) - (CurBufPtr and 0xFFF) + 1,
1397
; (BufEnd and 0xFFF) - (CurBufPtr and 0xFFF) + 1,
1409
; plus 0x1000 if BufEnd and CurBufPtr are in different pages.
1398
; plus 0x1000 if BufEnd and CurBufPtr are in different pages.
1410
        mov     edx, [ebx+ohci_gtd.BufEnd-ohci_gtd.SoftwarePart]
1399
        mov     edx, [ebx+ohci_gtd.BufEnd-sizeof.ohci_gtd]
1411
        mov     eax, [ebx+ohci_gtd.CurBufPtr-ohci_gtd.SoftwarePart]
1400
        mov     eax, [ebx+ohci_gtd.CurBufPtr-sizeof.ohci_gtd]
1412
        mov     ecx, edx
1401
        mov     ecx, edx
1413
        and     edx, 0xFFF
1402
        and     edx, 0xFFF
1414
        inc     edx
1403
        inc     edx
1415
        xor     ecx, eax
1404
        xor     ecx, eax
1416
        and     ecx, -0x1000
1405
        and     ecx, -0x1000
Line 1423... Line 1412...
1423
; The actual length is Length - (remaining length).
1412
; The actual length is Length - (remaining length).
1424
        sub     edx, [ebx+usb_gtd.Length]
1413
        sub     edx, [ebx+usb_gtd.Length]
1425
        neg     edx
1414
        neg     edx
1426
; 4. Check for error. If so, go to 7.
1415
; 4. Check for error. If so, go to 7.
1427
        push    ebx
1416
        push    ebx
1428
        mov     eax, [ebx+ohci_gtd.Flags-ohci_gtd.SoftwarePart]
1417
        mov     eax, [ebx+ohci_gtd.Flags-sizeof.ohci_gtd]
1429
        shr     eax, 28
1418
        shr     eax, 28
1430
        jnz     .error
1419
        jnz     .error
1431
.notify:
1420
.notify:
1432
; 5. Successful completion.
1421
; 5. Successful completion.
1433
; 5a. Check whether this descriptor has an associated callback.
1422
; 5a. Check whether this descriptor has an associated callback.
Line 1449... Line 1438...
1449
        cmp     ebx, [esp]
1438
        cmp     ebx, [esp]
1450
        jz      @f
1439
        jz      @f
1451
        stdcall usb1_free_general_td, ebx
1440
        stdcall usb1_free_general_td, ebx
1452
@@:
1441
@@:
1453
        pop     ebx
1442
        pop     ebx
1454
        lea     eax, [ebx+ohci_gtd.NextTD-ohci_gtd.SoftwarePart]
1443
        lea     eax, [ebx+ohci_gtd.NextTD-sizeof.ohci_gtd]
1455
.next_td2:
1444
.next_td2:
1456
        push    ebx
1445
        push    ebx
1457
        mov     ebx, eax
1446
        mov     ebx, eax
1458
        lea     edx, [esi+ohci_controller.DoneList-sizeof.ohci_controller]
1447
        lea     edx, [esi+ohci_controller.DoneList-sizeof.ohci_controller]
1459
        xor     ecx, ecx        ; no next item
1448
        xor     ecx, ecx        ; no next item
Line 1482... Line 1471...
1482
; The hardware has stopped processing the queue.
1471
; The hardware has stopped processing the queue.
1483
; 7a. Save status and length.
1472
; 7a. Save status and length.
1484
        push    eax
1473
        push    eax
1485
        push    edx
1474
        push    edx
1486
;       DEBUGF 1,'K : TD failed:\n'
1475
;       DEBUGF 1,'K : TD failed:\n'
1487
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-ohci_gtd.SoftwarePart],[ebx-ohci_gtd.SoftwarePart+4],[ebx-ohci_gtd.SoftwarePart+8],[ebx-ohci_gtd.SoftwarePart+12]
1476
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd],[ebx-sizeof.ohci_gtd+4],[ebx-sizeof.ohci_gtd+8],[ebx-sizeof.ohci_gtd+12]
1488
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-ohci_gtd.SoftwarePart+16],[ebx-ohci_gtd.SoftwarePart+20],[ebx-ohci_gtd.SoftwarePart+24],[ebx-ohci_gtd.SoftwarePart+28]
1477
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-sizeof.ohci_gtd+16],[ebx-sizeof.ohci_gtd+20],[ebx-sizeof.ohci_gtd+24],[ebx-sizeof.ohci_gtd+28]
1489
;       mov     eax, [ebx+usb_gtd.Pipe]
1478
;       mov     eax, [ebx+usb_gtd.Pipe]
1490
;       DEBUGF 1,'K : pipe: %x %x %x %x\n',[eax-ohci_pipe.SoftwarePart],[eax-ohci_pipe.SoftwarePart+4],[eax-ohci_pipe.SoftwarePart+8],[eax-ohci_pipe.SoftwarePart+12]
1479
;       DEBUGF 1,'K : pipe: %x %x %x %x\n',[eax-sizeof.ohci_pipe],[eax-sizeof.ohci_pipe+4],[eax-sizeof.ohci_pipe+8],[eax-sizeof.ohci_pipe+12]
1491
; 7b. Traverse the list of descriptors looking for the final packet
1480
; 7b. Traverse the list of descriptors looking for the final packet
1492
; for this transfer.
1481
; for this transfer.
1493
; Free and unlink non-final descriptors, except the current one.
1482
; Free and unlink non-final descriptors, except the current one.
1494
; Final descriptor will be freed in step 6.
1483
; Final descriptor will be freed in step 6.
1495
        call    usb_is_final_packet
1484
        call    usb_is_final_packet
Line 1515... Line 1504...
1515
; as short-packet-is-error to stop controller from further processing
1504
; as short-packet-is-error to stop controller from further processing
1516
; of that stage; we need to restart processing from a TD following the last.
1505
; of that stage; we need to restart processing from a TD following the last.
1517
; After that, go to step 5 with eax = 0 (no error).
1506
; After that, go to step 5 with eax = 0 (no error).
1518
        cmp     dword [.error_code], USB_STATUS_UNDERRUN
1507
        cmp     dword [.error_code], USB_STATUS_UNDERRUN
1519
        jnz     .no_underrun
1508
        jnz     .no_underrun
1520
        test    byte [ebx+ohci_gtd.Flags+2-ohci_gtd.SoftwarePart], 1 shl (18-16)
1509
        test    byte [ebx+ohci_gtd.Flags+2-sizeof.ohci_gtd], 1 shl (18-16)
1521
        jz      .no_underrun
1510
        jz      .no_underrun
1522
        and     dword [.error_code], 0
1511
        and     dword [.error_code], 0
1523
        mov     ecx, [ebx+usb_gtd.Pipe]
1512
        mov     ecx, [ebx+usb_gtd.Pipe]
1524
        mov     edx, [ecx+ohci_pipe.HeadP-ohci_pipe.SoftwarePart]
1513
        mov     edx, [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe]
1525
        and     edx, 2
1514
        and     edx, 2
1526
.advance_queue:
1515
.advance_queue:
1527
        mov     eax, [ebx+usb_gtd.NextVirt]
1516
        mov     eax, [ebx+usb_gtd.NextVirt]
1528
        sub     eax, ohci_gtd.SoftwarePart
1517
        sub     eax, sizeof.ohci_gtd
1529
        call    get_phys_addr
1518
        call    get_phys_addr
1530
        or      eax, edx
1519
        or      eax, edx
1531
        mov     [ecx+ohci_pipe.HeadP-ohci_pipe.SoftwarePart], eax
1520
        mov     [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe], eax
1532
        push    ebx
1521
        push    ebx
1533
        mov     ebx, ecx
1522
        mov     ebx, ecx
1534
        call    ohci_notify_new_work
1523
        call    ohci_notify_new_work
1535
        pop     ebx
1524
        pop     ebx
1536
        pop     edx eax
1525
        pop     edx eax
Line 1560... Line 1549...
1560
; of any control transfer), so we hope on the best and just advance the queue
1549
; of any control transfer), so we hope on the best and just advance the queue
1561
; to the next transfer. (According to the standard, "A control pipe may also
1550
; to the next transfer. (According to the standard, "A control pipe may also
1562
; support functional stall as well, but this is not recommended.").
1551
; support functional stall as well, but this is not recommended.").
1563
; Advance the transfer queue to the next descriptor.
1552
; Advance the transfer queue to the next descriptor.
1564
        mov     ecx, [ebx+usb_gtd.Pipe]
1553
        mov     ecx, [ebx+usb_gtd.Pipe]
1565
        mov     edx, [ecx+ohci_pipe.HeadP-ohci_pipe.SoftwarePart]
1554
        mov     edx, [ecx+ohci_pipe.HeadP-sizeof.ohci_pipe]
1566
        and     edx, 2  ; keep toggleCarry bit
1555
        and     edx, 2  ; keep toggleCarry bit
1567
        cmp     [ecx+usb_pipe.Type], CONTROL_PIPE
1556
        cmp     [ecx+usb_pipe.Type], CONTROL_PIPE
1568
        jnz     @f
1557
        jnz     @f
1569
        inc     edx     ; set Halted bit
1558
        inc     edx     ; set Halted bit
1570
@@:
1559
@@:
Line 1575... Line 1564...
1575
; or due to disconnect); it unlinks the pipe from the corresponding list.
1564
; or due to disconnect); it unlinks the pipe from the corresponding list.
1576
; esi -> usb_controller, ebx -> usb_pipe
1565
; esi -> usb_controller, ebx -> usb_pipe
1577
proc ohci_unlink_pipe
1566
proc ohci_unlink_pipe
1578
        cmp     [ebx+usb_pipe.Type], INTERRUPT_PIPE
1567
        cmp     [ebx+usb_pipe.Type], INTERRUPT_PIPE
1579
        jnz     @f
1568
        jnz     @f
1580
        mov     eax, [ebx+ohci_pipe.Flags-ohci_pipe.SoftwarePart]
1569
        mov     eax, [ebx+ohci_pipe.Flags-sizeof.ohci_pipe]
1581
        bt      eax, 13
1570
        bt      eax, 13
1582
        setc    cl
1571
        setc    cl
1583
        bt      eax, 11
1572
        bt      eax, 11
1584
        setc    ch
1573
        setc    ch
1585
        shr     eax, 16
1574
        shr     eax, 16
Line 1587... Line 1576...
1587
@@:
1576
@@:
1588
        mov     edx, [ebx+usb_pipe.NextVirt]
1577
        mov     edx, [ebx+usb_pipe.NextVirt]
1589
        mov     eax, [ebx+usb_pipe.PrevVirt]
1578
        mov     eax, [ebx+usb_pipe.PrevVirt]
1590
        mov     [edx+usb_pipe.PrevVirt], eax
1579
        mov     [edx+usb_pipe.PrevVirt], eax
1591
        mov     [eax+usb_pipe.NextVirt], edx
1580
        mov     [eax+usb_pipe.NextVirt], edx
1592
        mov     edx, [ebx+ohci_pipe.NextED-ohci_pipe.SoftwarePart]
1581
        mov     edx, [ebx+ohci_pipe.NextED-sizeof.ohci_pipe]
1593
        mov     [eax+ohci_pipe.NextED-ohci_pipe.SoftwarePart], edx
1582
        mov     [eax+ohci_pipe.NextED-sizeof.ohci_pipe], edx
1594
        ret
1583
        ret
1595
endp
1584
endp