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