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 40... Line 40...
40
;   specification with some additional fields.
40
;   specification with some additional fields.
41
; * The hardware uses first two fields (8 bytes). Next two fields are used for
41
; * The hardware uses first two fields (8 bytes). Next two fields are used for
42
;   software book-keeping.
42
;   software book-keeping.
43
; * The hardware requires 16-bytes alignment of the hardware part.
43
; * The hardware requires 16-bytes alignment of the hardware part.
44
;   Since the allocator (usb_allocate_common) allocates memory sequentially
44
;   Since the allocator (usb_allocate_common) allocates memory sequentially
45
;   from page start (aligned on 0x1000 bytes), size of the structure must be
45
;   from page start (aligned on 0x1000 bytes), block size for the allocator
46
;   divisible by 16.
46
;   must be divisible by 16; usb1_allocate_endpoint ensures this.
47
struct uhci_pipe
47
struct uhci_pipe
48
NextQH          dd      ?
48
NextQH          dd      ?
49
; 1. First bit (bit 0) is Terminate bit. 1 = there is no next QH.
49
; 1. First bit (bit 0) is Terminate bit. 1 = there is no next QH.
50
; 2. Next bit (bit 1) is QH/TD select bit. 1 = NextQH points to QH.
50
; 2. Next bit (bit 1) is QH/TD select bit. 1 = NextQH points to QH.
51
; 3. Next two bits (bits 2-3) are reserved.
51
; 3. Next two bits (bits 2-3) are reserved.
Line 79... Line 79...
79
; the MaximumLength bitfield encodes maximum packet size,
79
; the MaximumLength bitfield encodes maximum packet size,
80
; the Reserved bit 20 is LowSpeedDevice bit.
80
; the Reserved bit 20 is LowSpeedDevice bit.
81
ErrorTD         dd      ?
81
ErrorTD         dd      ?
82
; Usually NULL. If nonzero, it is a pointer to descriptor which was error'd
82
; Usually NULL. If nonzero, it is a pointer to descriptor which was error'd
83
; and should be freed sometime in the future (the hardware could still use it).
83
; and should be freed sometime in the future (the hardware could still use it).
84
SoftwarePart    rd      sizeof.usb_pipe/4
-
 
85
; Common part for all controllers, described by usb_pipe structure.
-
 
86
ends
84
ends
Line 87... Line -...
87
 
-
 
88
if sizeof.uhci_pipe mod 16
-
 
89
.err uhci_pipe must be 16-bytes aligned
-
 
90
end if
-
 
91
 
85
 
92
; This structure describes the static head of every list of pipes.
86
; This structure describes the static head of every list of pipes.
93
; The hardware requires 16-bytes alignment of this structure.
87
; The hardware requires 16-bytes alignment of this structure.
94
; All instances of this structure are located sequentially in uhci_controller,
88
; All instances of this structure are located sequentially in uhci_controller,
95
; uhci_controller is page-aligned, so it is sufficient to make this structure
89
; uhci_controller is page-aligned, so it is sufficient to make this structure
Line 165... Line 159...
165
; * The hardware part consists of first 16 bytes and corresponds to the
159
; * The hardware part consists of first 16 bytes and corresponds to the
166
;   Transfer Descriptor aka TD from UHCI specification.
160
;   Transfer Descriptor aka TD from UHCI specification.
167
; * The hardware requires 16-bytes alignment of the hardware part, so
161
; * The hardware requires 16-bytes alignment of the hardware part, so
168
;   the entire descriptor must be 16-bytes aligned. Since the allocator
162
;   the entire descriptor must be 16-bytes aligned. Since the allocator
169
;   (uhci_allocate_common) allocates memory sequentially from page start
163
;   (uhci_allocate_common) allocates memory sequentially from page start
170
;   (aligned on 0x1000 bytes), size of the structure must be divisible by 16.
164
;   (aligned on 0x1000 bytes), block size for the allocator must be
-
 
165
;   divisible by 16; usb1_allocate_general_td ensures this.
171
struct uhci_gtd
166
struct uhci_gtd
172
NextTD          dd      ?
167
NextTD          dd      ?
173
; 1. First bit (bit 0) is Terminate bit. 1 = there is no next TD.
168
; 1. First bit (bit 0) is Terminate bit. 1 = there is no next TD.
174
; 2. Next bit (bit 1) is QH/TD select bit. 1 = NextTD points to QH.
169
; 2. Next bit (bit 1) is QH/TD select bit. 1 = NextTD points to QH.
175
;    This bit is always set to 0 in the implementation.
170
;    This bit is always set to 0 in the implementation.
Line 229... Line 224...
229
; Usually NULL. If the original buffer crosses a page boundary, this is a
224
; Usually NULL. If the original buffer crosses a page boundary, this is a
230
; pointer to the structure uhci_original_buffer for this request.
225
; pointer to the structure uhci_original_buffer for this request.
231
; bit 0: 1 = short packet is NOT allowed
226
; bit 0: 1 = short packet is NOT allowed
232
; (before the TD is processed, it is the copy of bit 29 of ControlStatus;
227
; (before the TD is processed, it is the copy of bit 29 of ControlStatus;
233
;  some controllers modify that bit, so we need a copy in a safe place)
228
;  some controllers modify that bit, so we need a copy in a safe place)
234
SoftwarePart    rd      sizeof.usb_gtd/4
-
 
235
; Software part, common for all controllers.
-
 
236
ends
229
ends
Line 237... Line -...
237
 
-
 
238
if sizeof.uhci_gtd mod 16
-
 
239
.err uhci_gtd must be 16-bytes aligned
-
 
240
end if
-
 
241
 
230
 
242
; UHCI requires that the entire transfer buffer should be on one page.
231
; UHCI requires that the entire transfer buffer should be on one page.
243
; If the actual buffer crosses page boundary, uhci_alloc_packet
232
; If the actual buffer crosses page boundary, uhci_alloc_packet
244
; allocates additional memory for buffer for hardware.
233
; allocates additional memory for buffer for hardware.
245
; This structure describes correspondence between two buffers.
234
; This structure describes correspondence between two buffers.
Line 851... Line 840...
851
.tdloop:
840
.tdloop:
852
; 3. For every descriptor, test active flag and check for end-of-queue;
841
; 3. For every descriptor, test active flag and check for end-of-queue;
853
; if either of conditions holds, exit from the internal loop.
842
; if either of conditions holds, exit from the internal loop.
854
        cmp     ebx, [esp]
843
        cmp     ebx, [esp]
855
        jz      .tddone
844
        jz      .tddone
856
        mov     eax, [ebx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart]
845
        mov     eax, [ebx+uhci_gtd.ControlStatus-sizeof.uhci_gtd]
857
        test    eax, 1 shl 23   ; active?
846
        test    eax, 1 shl 23   ; active?
858
        jnz     .tddone
847
        jnz     .tddone
859
; Release the queue lock while processing one descriptor:
848
; Release the queue lock while processing one descriptor:
860
; callback function could (and often would) schedule another transfer.
849
; callback function could (and often would) schedule another transfer.
861
        push    ecx
850
        push    ecx
Line 887... Line 876...
887
;       DEBUGF 1,'K : finalized TD:\n'
876
;       DEBUGF 1,'K : finalized TD:\n'
888
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-20],[ebx-16],[ebx-12],[ebx-8]
877
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-20],[ebx-16],[ebx-12],[ebx-8]
889
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-4],[ebx],[ebx+4],[ebx+8]
878
;       DEBUGF 1,'K : %x %x %x %x\n',[ebx-4],[ebx],[ebx+4],[ebx+8]
890
; 2. If this is IN transfer into special buffer, copy the data
879
; 2. If this is IN transfer into special buffer, copy the data
891
; to target location.
880
; to target location.
892
        mov     edx, [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
881
        mov     edx, [ebx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd]
893
        and     edx, not 1      ; clear lsb (used for another goal)
882
        and     edx, not 1      ; clear lsb (used for another goal)
894
        jz      .nocopy
883
        jz      .nocopy
895
        cmp     byte [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart], USB_PID_IN
884
        cmp     byte [ebx+uhci_gtd.Token-sizeof.uhci_gtd], USB_PID_IN
896
        jnz     .nocopy
885
        jnz     .nocopy
897
; Note: we assume that pointer to buffer is valid in the memory space of
886
; Note: we assume that pointer to buffer is valid in the memory space of
898
; the USB thread. This means that buffer must reside in kernel memory
887
; the USB thread. This means that buffer must reside in kernel memory
899
; (shared by all processes).
888
; (shared by all processes).
900
        push    esi edi
889
        push    esi edi
901
        mov     esi, [edx+uhci_original_buffer.UsedBuffer]
890
        mov     esi, [edx+uhci_original_buffer.UsedBuffer]
902
        mov     edi, [edx+uhci_original_buffer.OrigBuffer]
891
        mov     edi, [edx+uhci_original_buffer.OrigBuffer]
903
        mov     ecx, [ebx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart]
892
        mov     ecx, [ebx+uhci_gtd.ControlStatus-sizeof.uhci_gtd]
904
        inc     ecx
893
        inc     ecx
905
        and     ecx, 7FFh
894
        and     ecx, 7FFh
906
        mov     edx, ecx
895
        mov     edx, ecx
907
        shr     ecx, 2
896
        shr     ecx, 2
908
        and     edx, 3
897
        and     edx, 3
Line 911... Line 900...
911
        rep movsb
900
        rep movsb
912
        pop     edi esi
901
        pop     edi esi
913
.nocopy:
902
.nocopy:
914
; 3. Calculate actual number of bytes transferred.
903
; 3. Calculate actual number of bytes transferred.
915
; 3a. Read the state.
904
; 3a. Read the state.
916
        mov     eax, [ebx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart]
905
        mov     eax, [ebx+uhci_gtd.ControlStatus-sizeof.uhci_gtd]
917
        mov     ecx, [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart]
906
        mov     ecx, [ebx+uhci_gtd.Token-sizeof.uhci_gtd]
918
; 3b. Get number of bytes processed.
907
; 3b. Get number of bytes processed.
919
        lea     edx, [eax+1]
908
        lea     edx, [eax+1]
920
        and     edx, 7FFh
909
        and     edx, 7FFh
921
; 3c. Subtract number of bytes in this packet.
910
; 3c. Subtract number of bytes in this packet.
922
        add     ecx, 1 shl 21
911
        add     ecx, 1 shl 21
Line 936... Line 925...
936
; because the caller disallowed short packets or because the packet is not
925
; because the caller disallowed short packets or because the packet is not
937
; the last one in the corresponding transfer).
926
; the last one in the corresponding transfer).
938
        xor     ecx, ecx
927
        xor     ecx, ecx
939
        test    eax, 1 shl 22
928
        test    eax, 1 shl 22
940
        jnz     .error
929
        jnz     .error
941
        test    byte [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1
930
        test    byte [ebx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 1
942
        jz      .notify
931
        jz      .notify
943
        cmp     edx, [ebx+usb_gtd.Length]
932
        cmp     edx, [ebx+usb_gtd.Length]
944
        jz      .notify
933
        jz      .notify
945
.error:
934
.error:
946
; 5. There was an error while processing this packet.
935
; 5. There was an error while processing this packet.
947
; The hardware has stopped processing the queue.
936
; The hardware has stopped processing the queue.
948
        DEBUGF 1,'K : TD failed:\n'
937
        DEBUGF 1,'K : TD failed:\n'
949
if uhci_gtd.SoftwarePart <> 20
938
if sizeof.uhci_gtd <> 20
950
.err modify offsets for debug output
939
.err modify offsets for debug output
951
end if
940
end if
952
        DEBUGF 1,'K : %x %x %x %x\n',[ebx-20],[ebx-16],[ebx-12],[ebx-8]
941
        DEBUGF 1,'K : %x %x %x %x\n',[ebx-20],[ebx-16],[ebx-12],[ebx-8]
953
        DEBUGF 1,'K : %x %x %x %x\n',[ebx-4],[ebx],[ebx+4],[ebx+8]
942
        DEBUGF 1,'K : %x %x %x %x\n',[ebx-4],[ebx],[ebx+4],[ebx+8]
954
; 5a. Save the status and length.
943
; 5a. Save the status and length.
955
        push    edx
944
        push    edx
956
        push    eax
945
        push    eax
957
        mov     eax, [ebx+usb_gtd.Pipe]
946
        mov     eax, [ebx+usb_gtd.Pipe]
958
        DEBUGF 1,'K : pipe: %x %x\n',[eax+0-uhci_pipe.SoftwarePart],[eax+4-uhci_pipe.SoftwarePart]
947
        DEBUGF 1,'K : pipe: %x %x\n',[eax+0-sizeof.uhci_pipe],[eax+4-sizeof.uhci_pipe]
959
; 5b. Store the current TD as an error packet.
948
; 5b. Store the current TD as an error packet.
960
; If an error packet is already stored for this pipe,
949
; If an error packet is already stored for this pipe,
961
; it is definitely not used already, so free the old packet.
950
; it is definitely not used already, so free the old packet.
962
        mov     eax, [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
951
        mov     eax, [eax+uhci_pipe.ErrorTD-sizeof.uhci_pipe]
963
        test    eax, eax
952
        test    eax, eax
964
        jz      @f
953
        jz      @f
965
        stdcall uhci_free_td, eax
954
        stdcall uhci_free_td, eax
966
@@:
955
@@:
967
        mov     eax, [ebx+usb_gtd.Pipe]
956
        mov     eax, [ebx+usb_gtd.Pipe]
968
        mov     [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart], ebx
957
        mov     [eax+uhci_pipe.ErrorTD-sizeof.uhci_pipe], ebx
969
; 5c. Traverse the list of descriptors looking for the final packet
958
; 5c. Traverse the list of descriptors looking for the final packet
970
; for this transfer.
959
; for this transfer.
971
; Free and unlink non-final descriptors, except the current one.
960
; Free and unlink non-final descriptors, except the current one.
972
; Final descriptor will be freed in step 7.
961
; Final descriptor will be freed in step 7.
973
        call    usb_is_final_packet
962
        call    usb_is_final_packet
Line 1017... Line 1006...
1017
; as short-packet-is-error to stop controller from further processing
1006
; as short-packet-is-error to stop controller from further processing
1018
; of that stage; we need to restart processing from a TD following the last.
1007
; of that stage; we need to restart processing from a TD following the last.
1019
; After that, go to step 6 with ecx = 0 (no error).
1008
; After that, go to step 6 with ecx = 0 (no error).
1020
        cmp     ecx, USB_STATUS_UNDERRUN
1009
        cmp     ecx, USB_STATUS_UNDERRUN
1021
        jnz     @f
1010
        jnz     @f
1022
        test    byte [ebx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1
1011
        test    byte [ebx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 1
1023
        jnz     @f
1012
        jnz     @f
1024
; The controller has stopped this queue on the error packet.
1013
; The controller has stopped this queue on the error packet.
1025
; Update uhci_pipe.HeadTD to point to the next packet in the queue.
1014
; Update uhci_pipe.HeadTD to point to the next packet in the queue.
1026
        call    uhci_fix_toggle
1015
        call    uhci_fix_toggle
1027
        xor     ecx, ecx
1016
        xor     ecx, ecx
1028
.control:
1017
.control:
1029
        mov     eax, [ebx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart]
1018
        mov     eax, [ebx+uhci_gtd.NextTD-sizeof.uhci_gtd]
1030
        and     al, not 0xF
1019
        and     al, not 0xF
1031
        mov     edx, [ebx+usb_gtd.Pipe]
1020
        mov     edx, [ebx+usb_gtd.Pipe]
1032
        mov     [edx+uhci_pipe.HeadTD-uhci_pipe.SoftwarePart], eax
1021
        mov     [edx+uhci_pipe.HeadTD-sizeof.uhci_pipe], eax
1033
        pop     edx     ; length
1022
        pop     edx     ; length
1034
        jmp     .notify
1023
        jmp     .notify
1035
@@:
1024
@@:
1036
; 5f. Abort the entire transfer.
1025
; 5f. Abort the entire transfer.
1037
; There are two cases: either there is only one transfer stage
1026
; There are two cases: either there is only one transfer stage
Line 1045... Line 1034...
1045
        jnz     .normal
1034
        jnz     .normal
1046
; We cannot free ErrorTD yet, it could still be used by the hardware.
1035
; We cannot free ErrorTD yet, it could still be used by the hardware.
1047
        push    ecx
1036
        push    ecx
1048
        mov     eax, [ebx+usb_gtd.Pipe]
1037
        mov     eax, [ebx+usb_gtd.Pipe]
1049
        push    [ebx+usb_gtd.NextVirt]
1038
        push    [ebx+usb_gtd.NextVirt]
1050
        cmp     ebx, [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
1039
        cmp     ebx, [eax+uhci_pipe.ErrorTD-sizeof.uhci_pipe]
1051
        jz      @f
1040
        jz      @f
1052
        stdcall uhci_free_td, ebx
1041
        stdcall uhci_free_td, ebx
1053
@@:
1042
@@:
1054
        pop     ebx
1043
        pop     ebx
1055
        call    usb_unlink_td
1044
        call    usb_unlink_td
Line 1063... Line 1052...
1063
; support functional stall as well, but this is not recommended.").
1052
; support functional stall as well, but this is not recommended.").
1064
        mov     edx, [ebx+usb_gtd.Pipe]
1053
        mov     edx, [ebx+usb_gtd.Pipe]
1065
        cmp     [edx+usb_pipe.Type], CONTROL_PIPE
1054
        cmp     [edx+usb_pipe.Type], CONTROL_PIPE
1066
        jz      .control
1055
        jz      .control
1067
; Bulk/interrupt transfer; halt the queue.
1056
; Bulk/interrupt transfer; halt the queue.
1068
        mov     eax, [ebx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart]
1057
        mov     eax, [ebx+uhci_gtd.NextTD-sizeof.uhci_gtd]
1069
        and     al, not 0xF
1058
        and     al, not 0xF
1070
        inc     eax     ; set Halted bit
1059
        inc     eax     ; set Halted bit
1071
        mov     [edx+uhci_pipe.HeadTD-uhci_pipe.SoftwarePart], eax
1060
        mov     [edx+uhci_pipe.HeadTD-sizeof.uhci_pipe], eax
1072
        pop     edx     ; restore length saved in step 5a
1061
        pop     edx     ; restore length saved in step 5a
1073
.notify:
1062
.notify:
1074
; 6. Either the descriptor in ebx was processed without errors,
1063
; 6. Either the descriptor in ebx was processed without errors,
1075
; or all necessary error actions were taken and ebx points to the last
1064
; or all necessary error actions were taken and ebx points to the last
1076
; related descriptor.
1065
; related descriptor.
Line 1092... Line 1081...
1092
; 7. Free the current descriptor (if allowed) and return the next one.
1081
; 7. Free the current descriptor (if allowed) and return the next one.
1093
; 7a. Save pointer to the next descriptor.
1082
; 7a. Save pointer to the next descriptor.
1094
        push    [ebx+usb_gtd.NextVirt]
1083
        push    [ebx+usb_gtd.NextVirt]
1095
; 7b. Free the descriptor, unless it is saved as ErrorTD.
1084
; 7b. Free the descriptor, unless it is saved as ErrorTD.
1096
        mov     eax, [ebx+usb_gtd.Pipe]
1085
        mov     eax, [ebx+usb_gtd.Pipe]
1097
        cmp     [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart], ebx
1086
        cmp     [eax+uhci_pipe.ErrorTD-sizeof.uhci_pipe], ebx
1098
        jz      @f
1087
        jz      @f
1099
        stdcall uhci_free_td, ebx
1088
        stdcall uhci_free_td, ebx
1100
@@:
1089
@@:
1101
; 7c. Restore pointer to the next descriptor and return.
1090
; 7c. Restore pointer to the next descriptor and return.
1102
        pop     ebx
1091
        pop     ebx
Line 1116... Line 1105...
1116
        cmp     [ecx+usb_pipe.Type], CONTROL_PIPE
1105
        cmp     [ecx+usb_pipe.Type], CONTROL_PIPE
1117
        jz      .nothing
1106
        jz      .nothing
1118
; 2. The hardware expects next packet with toggle = (ErrorTD.toggle xor 1),
1107
; 2. The hardware expects next packet with toggle = (ErrorTD.toggle xor 1),
1119
; the current value in next packet is (ebx.toggle xor 1).
1108
; the current value in next packet is (ebx.toggle xor 1).
1120
; Nothing to do if ErrorTD.toggle == ebx.toggle.
1109
; Nothing to do if ErrorTD.toggle == ebx.toggle.
1121
        mov     eax, [ecx+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
1110
        mov     eax, [ecx+uhci_pipe.ErrorTD-sizeof.uhci_pipe]
1122
        mov     eax, [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart]
1111
        mov     eax, [eax+uhci_gtd.Token-sizeof.uhci_gtd]
1123
        xor     eax, [ebx+uhci_gtd.Token-uhci_gtd.SoftwarePart]
1112
        xor     eax, [ebx+uhci_gtd.Token-sizeof.uhci_gtd]
1124
        test    eax, 1 shl 19
1113
        test    eax, 1 shl 19
1125
        jz      .nothing
1114
        jz      .nothing
1126
; 3. Lock the transfer queue.
1115
; 3. Lock the transfer queue.
1127
        add     ecx, usb_pipe.Lock
1116
        add     ecx, usb_pipe.Lock
1128
        call    mutex_lock
1117
        call    mutex_lock
1129
; 4. Flip the toggle bit in all packets from ebx.NextVirt to ecx.LastTD
1118
; 4. Flip the toggle bit in all packets from ebx.NextVirt to ecx.LastTD
1130
; (inclusive).
1119
; (inclusive).
1131
        mov     eax, [ebx+usb_gtd.NextVirt]
1120
        mov     eax, [ebx+usb_gtd.NextVirt]
1132
.loop:
1121
.loop:
1133
        xor     byte [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart+2], 1 shl (19-16)
1122
        xor     byte [eax+uhci_gtd.Token-sizeof.uhci_gtd+2], 1 shl (19-16)
1134
        cmp     eax, [ecx+usb_pipe.LastTD-usb_pipe.Lock]
1123
        cmp     eax, [ecx+usb_pipe.LastTD-usb_pipe.Lock]
1135
        mov     eax, [eax+usb_gtd.NextVirt]
1124
        mov     eax, [eax+usb_gtd.NextVirt]
1136
        jnz     .loop
1125
        jnz     .loop
1137
; 5. Flip the toggle bit in uhci_pipe structure.
1126
; 5. Flip the toggle bit in uhci_pipe structure.
1138
        xor     byte [ecx+uhci_pipe.Token-uhci_pipe.SoftwarePart-usb_pipe.Lock+2], 1 shl (19-16)
1127
        xor     byte [ecx+uhci_pipe.Token-sizeof.uhci_pipe-usb_pipe.Lock+2], 1 shl (19-16)
1139
        or      dword [ecx+uhci_pipe.Token-uhci_pipe.SoftwarePart-usb_pipe.Lock], eax
1128
        or      dword [ecx+uhci_pipe.Token-sizeof.uhci_pipe-usb_pipe.Lock], eax
1140
; 6. Unlock the transfer queue.
1129
; 6. Unlock the transfer queue.
1141
        call    mutex_unlock
1130
        call    mutex_unlock
1142
.nothing:
1131
.nothing:
1143
        ret
1132
        ret
1144
endp
1133
endp
Line 1336... Line 1325...
1336
 
1325
 
1337
; This procedure is called from usb_set_address_callback
1326
; This procedure is called from usb_set_address_callback
1338
; and stores USB device address in the uhci_pipe structure.
1327
; and stores USB device address in the uhci_pipe structure.
1339
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
1328
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
1340
proc uhci_set_device_address
1329
proc uhci_set_device_address
1341
        mov     byte [ebx+uhci_pipe.Token+1-uhci_pipe.SoftwarePart], cl
1330
        mov     byte [ebx+uhci_pipe.Token+1-sizeof.uhci_pipe], cl
1342
        call    usb_subscription_done
1331
        call    usb_subscription_done
1343
        ret
1332
        ret
Line 1344... Line 1333...
1344
endp
1333
endp
1345
 
1334
 
1346
; This procedure returns USB device address from the uhci_pipe structure.
1335
; This procedure returns USB device address from the uhci_pipe structure.
1347
; in: esi -> usb_controller, ebx -> usb_pipe
1336
; in: esi -> usb_controller, ebx -> usb_pipe
1348
; out: eax = endpoint address
1337
; out: eax = endpoint address
1349
proc uhci_get_device_address
1338
proc uhci_get_device_address
1350
        mov     al, byte [ebx+uhci_pipe.Token+1-uhci_pipe.SoftwarePart]
1339
        mov     al, byte [ebx+uhci_pipe.Token+1-sizeof.uhci_pipe]
1351
        and     eax, 7Fh
1340
        and     eax, 7Fh
Line 1352... Line 1341...
1352
        ret
1341
        ret
Line 1370... Line 1359...
1370
; stores the packet size in uhci_pipe structure.
1359
; stores the packet size in uhci_pipe structure.
1371
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
1360
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
1372
proc uhci_set_endpoint_packet_size
1361
proc uhci_set_endpoint_packet_size
1373
        dec     ecx
1362
        dec     ecx
1374
        shl     ecx, 21
1363
        shl     ecx, 21
1375
        and     [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], (1 shl 21) - 1
1364
        and     [ebx+uhci_pipe.Token-sizeof.uhci_pipe], (1 shl 21) - 1
1376
        or      [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], ecx
1365
        or      [ebx+uhci_pipe.Token-sizeof.uhci_pipe], ecx
1377
; uhci_pipe.Token field is purely for software bookkeeping and does not affect
1366
; uhci_pipe.Token field is purely for software bookkeeping and does not affect
1378
; the hardware; thus, we can continue initialization immediately.
1367
; the hardware; thus, we can continue initialization immediately.
1379
        call    usb_subscription_done
1368
        call    usb_subscription_done
1380
        ret
1369
        ret
1381
endp
1370
endp
Line 1393... Line 1382...
1393
.maxpacket      dd      ?
1382
.maxpacket      dd      ?
1394
.type           dd      ?
1383
.type           dd      ?
1395
.interval       dd      ?
1384
.interval       dd      ?
1396
end virtual
1385
end virtual
1397
; 1. Initialize ErrorTD to zero.
1386
; 1. Initialize ErrorTD to zero.
1398
        and     [edi+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart], 0
1387
        and     [edi+uhci_pipe.ErrorTD-sizeof.uhci_pipe], 0
1399
; 2. Initialize HeadTD to the physical address of the first TD.
1388
; 2. Initialize HeadTD to the physical address of the first TD.
1400
        push    eax     ; store pointer to the first TD for step ?
1389
        push    eax     ; store pointer to the first TD for step ?
1401
        sub     eax, uhci_gtd.SoftwarePart
1390
        sub     eax, sizeof.uhci_gtd
1402
        call    get_phys_addr
1391
        call    get_phys_addr
1403
        mov     [edi+uhci_pipe.HeadTD-uhci_pipe.SoftwarePart], eax
1392
        mov     [edi+uhci_pipe.HeadTD-sizeof.uhci_pipe], eax
1404
; 3. Initialize Token field:
1393
; 3. Initialize Token field:
1405
; take DeviceAddress and LowSpeedDevice from the parent pipe,
1394
; take DeviceAddress and LowSpeedDevice from the parent pipe,
1406
; take Endpoint and MaximumLength fields from API arguments,
1395
; take Endpoint and MaximumLength fields from API arguments,
1407
; set PID depending on pipe type and provided pipe direction,
1396
; set PID depending on pipe type and provided pipe direction,
1408
; set DataToggle to zero.
1397
; set DataToggle to zero.
1409
        mov     eax, [ecx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
1398
        mov     eax, [ecx+uhci_pipe.Token-sizeof.uhci_pipe]
1410
        and     eax, 0x107F00   ; keep DeviceAddress and LowSpeedDevice
1399
        and     eax, 0x107F00   ; keep DeviceAddress and LowSpeedDevice
1411
        mov     edx, [.endpoint]
1400
        mov     edx, [.endpoint]
1412
        and     edx, 15
1401
        and     edx, 15
1413
        shl     edx, 15
1402
        shl     edx, 15
1414
        or      eax, edx
1403
        or      eax, edx
Line 1422... Line 1411...
1422
        mov     al, USB_PID_OUT
1411
        mov     al, USB_PID_OUT
1423
        test    byte [.endpoint], 80h
1412
        test    byte [.endpoint], 80h
1424
        jz      @f
1413
        jz      @f
1425
        mov     al, USB_PID_IN
1414
        mov     al, USB_PID_IN
1426
@@:
1415
@@:
1427
        mov     [edi+uhci_pipe.Token-uhci_pipe.SoftwarePart], eax
1416
        mov     [edi+uhci_pipe.Token-sizeof.uhci_pipe], eax
1428
; 4. Initialize the first TD:
1417
; 4. Initialize the first TD:
1429
; copy Token from uhci_pipe.Token zeroing reserved bit 20,
1418
; copy Token from uhci_pipe.Token zeroing reserved bit 20,
1430
; set ControlStatus for future transfers, bit make it inactive,
1419
; set ControlStatus for future transfers, bit make it inactive,
1431
; set bit 0 in NextTD = "no next TD".
1420
; set bit 0 in NextTD = "no next TD".
1432
        pop     edx     ; restore pointer saved in step 2
1421
        pop     edx     ; restore pointer saved in step 2
1433
        mov     [edx+uhci_gtd.Token-uhci_gtd.SoftwarePart], eax
1422
        mov     [edx+uhci_gtd.Token-sizeof.uhci_gtd], eax
1434
        and     byte [edx+uhci_gtd.Token+2-uhci_gtd.SoftwarePart], not (1 shl (20-16))
1423
        and     byte [edx+uhci_gtd.Token+2-sizeof.uhci_gtd], not (1 shl (20-16))
1435
        and     eax, 1 shl 20
1424
        and     eax, 1 shl 20
1436
        shl     eax, 6
1425
        shl     eax, 6
1437
        or      eax, UHCI_INVALID_LENGTH + (3 shl 27)
1426
        or      eax, UHCI_INVALID_LENGTH + (3 shl 27)
1438
                ; not processed, inactive, allow 3 errors
1427
                ; not processed, inactive, allow 3 errors
1439
        mov     [edx+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart], eax
1428
        mov     [edx+uhci_gtd.ControlStatus-sizeof.uhci_gtd], eax
1440
        mov     [edx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 1
1429
        mov     [edx+uhci_gtd.NextTD-sizeof.uhci_gtd], 1
1441
; 5. Select the corresponding list and insert to the list.
1430
; 5. Select the corresponding list and insert to the list.
1442
; 5a. Use Control list for control pipes, Bulk list for bulk pipes.
1431
; 5a. Use Control list for control pipes, Bulk list for bulk pipes.
1443
        lea     edx, [esi+uhci_controller.ControlED.SoftwarePart-sizeof.uhci_controller]
1432
        lea     edx, [esi+uhci_controller.ControlED.SoftwarePart-sizeof.uhci_controller]
1444
        cmp     [.type], BULK_PIPE
1433
        cmp     [.type], BULK_PIPE
1445
        jb      .insert ; control pipe
1434
        jb      .insert ; control pipe
Line 1469... Line 1458...
1469
        mov     [ecx+usb_pipe.PrevVirt], edi
1458
        mov     [ecx+usb_pipe.PrevVirt], edi
1470
        mov     [edx+usb_pipe.NextVirt], edi
1459
        mov     [edx+usb_pipe.NextVirt], edi
1471
; 5d. Insert in the hardware list: copy previous NextQH to the new pipe,
1460
; 5d. Insert in the hardware list: copy previous NextQH to the new pipe,
1472
; store the physical address of the new pipe to previous NextQH.
1461
; store the physical address of the new pipe to previous NextQH.
1473
        mov     ecx, [edx+uhci_static_ep.NextQH-uhci_static_ep.SoftwarePart]
1462
        mov     ecx, [edx+uhci_static_ep.NextQH-uhci_static_ep.SoftwarePart]
1474
        mov     [edi+uhci_pipe.NextQH-uhci_pipe.SoftwarePart], ecx
1463
        mov     [edi+uhci_pipe.NextQH-sizeof.uhci_pipe], ecx
1475
        lea     eax, [edi-uhci_pipe.SoftwarePart]
1464
        lea     eax, [edi-sizeof.uhci_pipe]
1476
        call    get_phys_addr
1465
        call    get_phys_addr
1477
        inc     eax
1466
        inc     eax
1478
        inc     eax
1467
        inc     eax
1479
        mov     [edx+uhci_static_ep.NextQH-uhci_static_ep.SoftwarePart], eax
1468
        mov     [edx+uhci_static_ep.NextQH-uhci_static_ep.SoftwarePart], eax
1480
; 6. Return with nonzero eax.
1469
; 6. Return with nonzero eax.
Line 1484... Line 1473...
1484
        ret
1473
        ret
1485
endp
1474
endp
Line 1486... Line 1475...
1486
 
1475
 
1487
; This procedure is called when a pipe is closing (either due to API call
1476
; This procedure is called when a pipe is closing (either due to API call
1488
; or due to disconnect); it unlinks a pipe from the corresponding list.
1477
; or due to disconnect); it unlinks a pipe from the corresponding list.
1489
if uhci_static_ep.SoftwarePart <> uhci_pipe.SoftwarePart
1478
if uhci_static_ep.SoftwarePart <> sizeof.uhci_pipe
1490
.err uhci_unlink_pipe assumes that uhci_static_ep.SoftwarePart == uhci_pipe.SoftwarePart
1479
.err uhci_unlink_pipe assumes that uhci_static_ep.SoftwarePart == sizeof.uhci_pipe
1491
end if
1480
end if
1492
proc uhci_unlink_pipe
1481
proc uhci_unlink_pipe
1493
        cmp     [ebx+usb_pipe.Type], INTERRUPT_PIPE
1482
        cmp     [ebx+usb_pipe.Type], INTERRUPT_PIPE
1494
        jnz     @f
1483
        jnz     @f
1495
        mov     eax, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
1484
        mov     eax, [ebx+uhci_pipe.Token-sizeof.uhci_pipe]
1496
        cmp     al, USB_PID_IN
1485
        cmp     al, USB_PID_IN
1497
        setz    ch
1486
        setz    ch
1498
        bt      eax, 20
1487
        bt      eax, 20
1499
        setc    cl
1488
        setc    cl
Line 1508... Line 1497...
1508
        mov     eax, [ebx+usb_pipe.PrevVirt]
1497
        mov     eax, [ebx+usb_pipe.PrevVirt]
1509
        mov     [edx+usb_pipe.PrevVirt], eax
1498
        mov     [edx+usb_pipe.PrevVirt], eax
1510
        mov     [eax+usb_pipe.NextVirt], edx
1499
        mov     [eax+usb_pipe.NextVirt], edx
1511
; Note: eax could be either usb_pipe or usb_static_ep;
1500
; Note: eax could be either usb_pipe or usb_static_ep;
1512
; fortunately, NextQH and SoftwarePart have same offsets in both.
1501
; fortunately, NextQH and SoftwarePart have same offsets in both.
1513
        mov     edx, [ebx+uhci_pipe.NextQH-uhci_pipe.SoftwarePart]
1502
        mov     edx, [ebx+uhci_pipe.NextQH-sizeof.uhci_pipe]
1514
        mov     [eax+uhci_pipe.NextQH-uhci_pipe.SoftwarePart], edx
1503
        mov     [eax+uhci_pipe.NextQH-sizeof.uhci_pipe], edx
1515
        ret
1504
        ret
1516
endp
1505
endp
Line 1517... Line 1506...
1517
 
1506
 
1518
; Free memory associated with pipe.
1507
; Free memory associated with pipe.
1519
; For UHCI, this includes usb_pipe structure and ErrorTD, if present.
1508
; For UHCI, this includes usb_pipe structure and ErrorTD, if present.
1520
proc uhci_free_pipe
1509
proc uhci_free_pipe
1521
        mov     eax, [esp+4]
1510
        mov     eax, [esp+4]
1522
        mov     eax, [eax+uhci_pipe.ErrorTD-uhci_pipe.SoftwarePart]
1511
        mov     eax, [eax+uhci_pipe.ErrorTD-sizeof.uhci_pipe]
1523
        test    eax, eax
1512
        test    eax, eax
1524
        jz      @f
1513
        jz      @f
1525
        stdcall uhci_free_td, eax
1514
        stdcall uhci_free_td, eax
1526
@@:
1515
@@:
Line 1542... Line 1531...
1542
        mov     [origTD], eax
1531
        mov     [origTD], eax
1543
; In UHCI one TD describes one packet, transfers should be split into parts
1532
; In UHCI one TD describes one packet, transfers should be split into parts
1544
; with size <= endpoint max packet size.
1533
; with size <= endpoint max packet size.
1545
; 2. Get the maximum packet size for endpoint from uhci_pipe.Token
1534
; 2. Get the maximum packet size for endpoint from uhci_pipe.Token
1546
; and generate Token field for TDs.
1535
; and generate Token field for TDs.
1547
        mov     edi, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
1536
        mov     edi, [ebx+uhci_pipe.Token-sizeof.uhci_pipe]
1548
        mov     eax, edi
1537
        mov     eax, edi
1549
        shr     edi, 21
1538
        shr     edi, 21
1550
        inc     edi
1539
        inc     edi
1551
; zero packet size (it will be set for every packet individually),
1540
; zero packet size (it will be set for every packet individually),
1552
; zero reserved bit 20,
1541
; zero reserved bit 20,
Line 1600... Line 1589...
1600
; if one of them will be short, the software intervention is needed
1589
; if one of them will be short, the software intervention is needed
1601
; to skip remaining packets; uhci_process_finalized_td will handle this
1590
; to skip remaining packets; uhci_process_finalized_td will handle this
1602
; transparently to the caller.
1591
; transparently to the caller.
1603
        test    [flags], 1
1592
        test    [flags], 1
1604
        jz      @f
1593
        jz      @f
1605
        and     byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], not (1 shl (29-24))
1594
        and     byte [ecx+uhci_gtd.ControlStatus+3-sizeof.uhci_gtd], not (1 shl (29-24))
1606
        and     byte [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], not 1
1595
        and     byte [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], not 1
1607
@@:
1596
@@:
1608
; 6. Update toggle bit in uhci_pipe structure from current value of [token].
1597
; 6. Update toggle bit in uhci_pipe structure from current value of [token].
1609
        mov     edx, [token]
1598
        mov     edx, [token]
1610
        xor     edx, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
1599
        xor     edx, [ebx+uhci_pipe.Token-sizeof.uhci_pipe]
1611
        and     edx, 1 shl 19
1600
        and     edx, 1 shl 19
1612
        xor     [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart], edx
1601
        xor     [ebx+uhci_pipe.Token-sizeof.uhci_pipe], edx
1613
.nothing:
1602
.nothing:
1614
        ret
1603
        ret
1615
.fail:
1604
.fail:
1616
        mov     edi, uhci_hardware_func
1605
        mov     edi, uhci_hardware_func
1617
        mov     eax, [td]
1606
        mov     eax, [td]
Line 1711... Line 1700...
1711
; 4. Initialize the next TD:
1700
; 4. Initialize the next TD:
1712
; mark it as last one (this will be changed when further packets will be
1701
; mark it as last one (this will be changed when further packets will be
1713
; allocated), copy Token field from uhci_pipe.Token zeroing bit 20,
1702
; allocated), copy Token field from uhci_pipe.Token zeroing bit 20,
1714
; generate ControlStatus field, mark as Active
1703
; generate ControlStatus field, mark as Active
1715
; (for last descriptor, this will be changed by uhci_insert_transfer).
1704
; (for last descriptor, this will be changed by uhci_insert_transfer).
1716
        mov     [eax+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 1  ; no next TD
1705
        mov     [eax+uhci_gtd.NextTD-sizeof.uhci_gtd], 1  ; no next TD
1717
        mov     edx, [ebx+uhci_pipe.Token-uhci_pipe.SoftwarePart]
1706
        mov     edx, [ebx+uhci_pipe.Token-sizeof.uhci_pipe]
1718
        mov     [eax+uhci_gtd.Token-uhci_gtd.SoftwarePart], edx
1707
        mov     [eax+uhci_gtd.Token-sizeof.uhci_gtd], edx
1719
        and     byte [eax+uhci_gtd.Token+2-uhci_gtd.SoftwarePart], not (1 shl (20-16))
1708
        and     byte [eax+uhci_gtd.Token+2-sizeof.uhci_gtd], not (1 shl (20-16))
1720
        and     edx, 1 shl 20
1709
        and     edx, 1 shl 20
1721
        shl     edx, 6
1710
        shl     edx, 6
1722
        or      edx, UHCI_INVALID_LENGTH + (1 shl 23) + (3 shl 27)
1711
        or      edx, UHCI_INVALID_LENGTH + (1 shl 23) + (3 shl 27)
1723
                ; not processed, active, allow 3 errors
1712
                ; not processed, active, allow 3 errors
1724
        mov     [eax+uhci_gtd.ControlStatus-uhci_gtd.SoftwarePart], edx
1713
        mov     [eax+uhci_gtd.ControlStatus-sizeof.uhci_gtd], edx
1725
; 5. Initialize remaining fields of the current TD.
1714
; 5. Initialize remaining fields of the current TD.
1726
; 5a. Store pointer to the buffer allocated in step 1 (or zero).
1715
; 5a. Store pointer to the buffer allocated in step 1 (or zero).
1727
        pop     [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
1716
        pop     [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd]
1728
; 5b. Store physical address of the next TD.
1717
; 5b. Store physical address of the next TD.
1729
        push    eax
1718
        push    eax
1730
        sub     eax, uhci_gtd.SoftwarePart
1719
        sub     eax, sizeof.uhci_gtd
1731
        call    get_phys_addr
1720
        call    get_phys_addr
1732
; use Depth traversal unless this is the first TD in the transfer stage;
1721
; use Depth traversal unless this is the first TD in the transfer stage;
1733
; uhci_insert_transfer will set Depth traversal for the first TD and clear
1722
; uhci_insert_transfer will set Depth traversal for the first TD and clear
1734
; it in the last TD
1723
; it in the last TD
1735
        cmp     ecx, [ebx+usb_pipe.LastTD]
1724
        cmp     ecx, [ebx+usb_pipe.LastTD]
1736
        jz      @f
1725
        jz      @f
1737
        or      eax, 4
1726
        or      eax, 4
1738
@@:
1727
@@:
1739
        mov     [ecx+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], eax
1728
        mov     [ecx+uhci_gtd.NextTD-sizeof.uhci_gtd], eax
1740
; 5c. Store physical address of the buffer: zero if no data present,
1729
; 5c. Store physical address of the buffer: zero if no data present,
1741
; the temporary buffer if it was allocated, the given buffer otherwise.
1730
; the temporary buffer if it was allocated, the given buffer otherwise.
1742
        xor     eax, eax
1731
        xor     eax, eax
1743
        cmp     [.packetSize], eax
1732
        cmp     [.packetSize], eax
1744
        jz      .hasphysbuf
1733
        jz      .hasphysbuf
1745
        mov     eax, [.buffer]
1734
        mov     eax, [.buffer]
1746
        mov     edx, [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
1735
        mov     edx, [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd]
1747
        test    edx, edx
1736
        test    edx, edx
1748
        jz      @f
1737
        jz      @f
1749
        mov     eax, [edx+uhci_original_buffer.UsedBuffer]
1738
        mov     eax, [edx+uhci_original_buffer.UsedBuffer]
1750
@@:
1739
@@:
1751
        call    get_phys_addr
1740
        call    get_phys_addr
1752
.hasphysbuf:
1741
.hasphysbuf:
1753
        mov     [ecx+uhci_gtd.Buffer-uhci_gtd.SoftwarePart], eax
1742
        mov     [ecx+uhci_gtd.Buffer-sizeof.uhci_gtd], eax
1754
; 5d. For IN transfers, disallow short packets.
1743
; 5d. For IN transfers, disallow short packets.
1755
; This will be overridden, if needed, by uhci_alloc_transfer.
1744
; This will be overridden, if needed, by uhci_alloc_transfer.
1756
        mov     eax, [.token]
1745
        mov     eax, [.token]
1757
        mov     edx, [.packetSize]
1746
        mov     edx, [.packetSize]
1758
        dec     edx
1747
        dec     edx
1759
        cmp     al, USB_PID_IN
1748
        cmp     al, USB_PID_IN
1760
        jnz     @f
1749
        jnz     @f
1761
        or      byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], 1 shl (29-24)        ; disallow short packets
1750
        or      byte [ecx+uhci_gtd.ControlStatus+3-sizeof.uhci_gtd], 1 shl (29-24)        ; disallow short packets
1762
        or      byte [ecx+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart], 1
1751
        or      byte [ecx+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd], 1
1763
@@:
1752
@@:
1764
; 5e. Get Token field: combine [.token] with [.packetSize].
1753
; 5e. Get Token field: combine [.token] with [.packetSize].
1765
        shl     edx, 21
1754
        shl     edx, 21
1766
        or      edx, eax
1755
        or      edx, eax
1767
        mov     [ecx+uhci_gtd.Token-uhci_gtd.SoftwarePart], edx
1756
        mov     [ecx+uhci_gtd.Token-sizeof.uhci_gtd], edx
1768
; 6. Flip toggle bit in [.token].
1757
; 6. Flip toggle bit in [.token].
1769
        xor     eax, 1 shl 19
1758
        xor     eax, 1 shl 19
1770
        mov     [.token], eax
1759
        mov     [.token], eax
1771
; 7. Return pointer to the next TD.
1760
; 7. Return pointer to the next TD.
1772
        pop     eax
1761
        pop     eax
Line 1783... Line 1772...
1783
; and activates the transfer which was previously allocated by
1772
; and activates the transfer which was previously allocated by
1784
; uhci_alloc_transfer.
1773
; uhci_alloc_transfer.
1785
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
1774
; ecx -> last descriptor for the transfer, ebx -> usb_pipe
1786
proc uhci_insert_transfer
1775
proc uhci_insert_transfer
1787
;       DEBUGF 1,'K : uhci_insert_transfer: eax=%x, ecx=%x, [esp+4]=%x\n',eax,ecx,[esp+4]
1776
;       DEBUGF 1,'K : uhci_insert_transfer: eax=%x, ecx=%x, [esp+4]=%x\n',eax,ecx,[esp+4]
1788
        and     byte [eax+uhci_gtd.ControlStatus+2-uhci_gtd.SoftwarePart], not (1 shl (23-16))  ; clear Active bit
1777
        and     byte [eax+uhci_gtd.ControlStatus+2-sizeof.uhci_gtd], not (1 shl (23-16))  ; clear Active bit
1789
        or      byte [ecx+uhci_gtd.ControlStatus+3-uhci_gtd.SoftwarePart], 1 shl (24-24)        ; set InterruptOnComplete bit
1778
        or      byte [ecx+uhci_gtd.ControlStatus+3-sizeof.uhci_gtd], 1 shl (24-24)        ; set InterruptOnComplete bit
1790
        mov     eax, [esp+4]
1779
        mov     eax, [esp+4]
1791
        or      byte [eax+uhci_gtd.ControlStatus+2-uhci_gtd.SoftwarePart], 1 shl (23-16)        ; set Active bit
1780
        or      byte [eax+uhci_gtd.ControlStatus+2-sizeof.uhci_gtd], 1 shl (23-16)        ; set Active bit
1792
        or      byte [eax+uhci_gtd.NextTD-uhci_gtd.SoftwarePart], 4     ; set Depth bit
1781
        or      byte [eax+uhci_gtd.NextTD-sizeof.uhci_gtd], 4     ; set Depth bit
1793
        ret
1782
        ret
1794
endp
1783
endp
Line 1795... Line 1784...
1795
 
1784
 
1796
; Free all memory associated with one TD.
1785
; Free all memory associated with one TD.
1797
; For UHCI, this includes memory for uhci_gtd itself
1786
; For UHCI, this includes memory for uhci_gtd itself
1798
; and the temporary buffer, if present.
1787
; and the temporary buffer, if present.
1799
proc uhci_free_td
1788
proc uhci_free_td
1800
        mov     eax, [esp+4]
1789
        mov     eax, [esp+4]
1801
        mov     eax, [eax+uhci_gtd.OrigBufferInfo-uhci_gtd.SoftwarePart]
1790
        mov     eax, [eax+uhci_gtd.OrigBufferInfo-sizeof.uhci_gtd]
1802
        and     eax, not 1
1791
        and     eax, not 1
1803
        jz      .nobuf
1792
        jz      .nobuf
1804
        push    ebx
1793
        push    ebx
1805
        call    free
1794
        call    free
1806
        pop     ebx
1795
        pop     ebx
1807
.nobuf:
1796
.nobuf:
1808
        sub     dword [esp+4], uhci_gtd.SoftwarePart
1797
        sub     dword [esp+4], sizeof.uhci_gtd
1809
        jmp     usb_free_common
1798
        jmp     usb_free_common