Subversion Repositories Kolibri OS

Rev

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

Rev 3908 Rev 4423
Line 1... Line 1...
1
; Functions for USB pipe manipulation: opening/closing, sending data etc.
1
; Functions for USB pipe manipulation: opening/closing, sending data etc.
2
;
2
;
3
; =============================================================================
-
 
4
; ================================= Constants =================================
-
 
5
; =============================================================================
-
 
6
; USB pipe types
-
 
7
CONTROL_PIPE = 0
-
 
8
ISOCHRONOUS_PIPE = 1
-
 
9
BULK_PIPE = 2
-
 
10
INTERRUPT_PIPE = 3
-
 
11
 
-
 
12
; Status codes for transfer callbacks.
-
 
13
; Taken from OHCI as most verbose controller in this sense.
-
 
14
USB_STATUS_OK           = 0     ; no error
-
 
15
USB_STATUS_CRC          = 1     ; CRC error
-
 
16
USB_STATUS_BITSTUFF     = 2     ; bit stuffing violation
-
 
17
USB_STATUS_TOGGLE       = 3     ; data toggle mismatch
-
 
18
USB_STATUS_STALL        = 4     ; device returned STALL
-
 
19
USB_STATUS_NORESPONSE   = 5     ; device not responding
-
 
20
USB_STATUS_PIDCHECK     = 6     ; invalid PID check bits
-
 
21
USB_STATUS_WRONGPID     = 7     ; unexpected PID value
-
 
22
USB_STATUS_OVERRUN      = 8     ; too many data from endpoint
-
 
23
USB_STATUS_UNDERRUN     = 9     ; too few data from endpoint
-
 
24
USB_STATUS_BUFOVERRUN   = 12    ; overflow of internal controller buffer
-
 
25
USB_STATUS_BUFUNDERRUN  = 13    ; underflow of internal controller buffer
-
 
26
USB_STATUS_CLOSED       = 16    ; pipe closed
-
 
27
                                ; either explicitly with USBClosePipe
-
 
28
                                ; or implicitly due to device disconnect
-
 
29
 
-
 
30
; flags for usb_pipe.Flags
-
 
31
USB_FLAG_CLOSED     = 1         ; pipe is closed, no new transfers
-
 
32
; pipe is closed, return error instead of submitting any new transfer
-
 
33
USB_FLAG_CAN_FREE   = 2
-
 
34
; pipe is closed via explicit call to USBClosePipe, so it can be freed without
-
 
35
; any driver notification; if this flag is not set, then the pipe is closed due
-
 
36
; to device disconnect, so it must remain valid until return from disconnect
-
 
37
; callback provided by the driver
-
 
38
USB_FLAG_EXTRA_WAIT = 4
-
 
39
; The pipe was in wait list, while another event occured;
-
 
40
; when the first wait will be done, reinsert the pipe to wait list
-
 
41
USB_FLAG_CLOSED_BIT = 0 ; USB_FLAG_CLOSED = 1 shl USB_FLAG_CLOSED_BIT
-
 
42
 
-
 
43
; =============================================================================
-
 
44
; ================================ Structures =================================
-
 
45
; =============================================================================
-
 
46
 
-
 
47
; Pipe descriptor.
-
 
48
; * An USB pipe is described by two structures, for hardware and for software.
-
 
49
; * This is the software part. The hardware part is defined in a driver
-
 
50
;   of the corresponding controller.
-
 
51
; * The hardware part is located immediately before usb_pipe,
-
 
52
;   both are allocated at once by controller-specific code
-
 
53
;   (it knows the total length, which depends on the hardware part).
-
 
54
struct usb_pipe
-
 
55
Controller      dd      ?
-
 
56
; Pointer to usb_controller structure corresponding to this pipe.
-
 
57
; Must be the first dword after hardware part, see *hci_new_device.
-
 
58
;
-
 
59
; Every endpoint is included into one of processing lists:
-
 
60
; * Bulk list contains all Bulk endpoints.
-
 
61
; * Control list contains all Control endpoints.
-
 
62
; * Several Periodic lists serve Interrupt endpoints with different interval.
-
 
63
;   - There are N=2^n "leaf" periodic lists for N ms interval, one is processed
-
 
64
;     in the frames 0,N,2N,..., another is processed in the frames
-
 
65
;     1,1+N,1+2N,... and so on. The hardware starts processing of periodic
-
 
66
;     endpoints in every frame from the list identified by lower n bits of the
-
 
67
;     frame number; the addresses of these N lists are written to the
-
 
68
;     controller data area during the initialization.
-
 
69
;   - We assume that n=5, N=32 to simplify the code and compact the data.
-
 
70
;     OHCI works in this way. UHCI and EHCI actually have n=10, N=1024,
-
 
71
;     but this is an overkill for interrupt endpoints; the large value of N is
-
 
72
;     useful only for isochronous transfers in UHCI and EHCI. UHCI/EHCI code
-
 
73
;     initializes "leaf" lists k,k+32,k+64,...,k+(1024-32) to the same value,
-
 
74
;     giving essentially N=32.
-
 
75
;     This restriction means that the actual maximum interval of polling any
-
 
76
;     interrupt endpoint is 32ms, which seems to be a reasonable value.
-
 
77
;   - Similarly, there are 16 lists for 16-ms interval, 8 lists for 8-ms
-
 
78
;     interval and so on. Finally, there is one list for 1ms interval. Their
-
 
79
;     addresses are not directly known to the controller.
-
 
80
;   - The hardware serves endpoints following a physical link from the hardware
-
 
81
;     part.
-
 
82
;   - The hardware links are organized as follows. If the list item is not the
-
 
83
;     last, it's hardware link points to the next item. The hardware link of
-
 
84
;     the last item points to the first item of the "next" list.
-
 
85
;   - The "next" list for k-th and (k+M)-th periodic lists for interval 2M ms
-
 
86
;     is the k-th periodic list for interval M ms, M >= 1. In this scheme,
-
 
87
;     if two "previous" lists are served in the frames k,k+2M,k+4M,...
-
 
88
;     and k+M,k+3M,k+5M,... correspondingly, the "next" list is served in
-
 
89
;     the frames k,k+M,k+2M,k+3M,k+4M,k+5M,..., which is exactly what we want.
-
 
90
;   - The links between Periodic, Control, Bulk lists and the processing of
-
 
91
;     Isochronous endpoints are controller-specific.
-
 
92
; * The head of every processing list is a static entry which does not
-
 
93
;   correspond to any real pipe. It is described by usb_static_ep
-
 
94
;   structure, not usb_pipe. For OHCI and UHCI, sizeof.usb_static_ep plus
-
 
95
;   sizeof hardware part is 20h, the total number of lists is
-
 
96
;   32+16+8+4+2+1+1+1 = 65, so all these structures fit in one page,
-
 
97
;   leaving space for other data. This is another reason for 32ms limit.
-
 
98
; * Static endpoint descriptors are kept in *hci_controller structure.
-
 
99
; * All items in every processing list, including the static head, are
-
 
100
;   organized in a double-linked list using .NextVirt and .PrevVirt fields.
-
 
101
; * [[item.NextVirt].PrevVirt] = [[item.PrevVirt].NextVirt] for all items.
-
 
102
NextVirt        dd      ?
-
 
103
; Next endpoint in the processing list.
-
 
104
; See also PrevVirt field and the description before NextVirt field.
-
 
105
PrevVirt        dd      ?
-
 
106
; Previous endpoint in the processing list.
-
 
107
; See also NextVirt field and the description before NextVirt field.
-
 
108
;
-
 
109
; Every pipe has the associated transfer queue, that is, the double-linked
-
 
110
; list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt
-
 
111
; endpoints this list consists of usb_gtd structures
-
 
112
; (GTD = General Transfer Descriptors), for Isochronous endpoints
-
 
113
; this list consists of usb_itd structures, which are not developed yet.
-
 
114
; The pipe needs to know only the last TD; the first TD can be
-
 
115
; obtained as [[pipe.LastTD].NextVirt].
-
 
116
LastTD          dd      ?
-
 
117
; Last TD in the transfer queue.
-
 
118
;
-
 
119
; All opened pipes corresponding to the same physical device are organized in
-
 
120
; the double-linked list using .NextSibling and .PrevSibling fields.
-
 
121
; The head of this list is kept in usb_device_data structure (OpenedPipeList).
-
 
122
; This list is used when the device is disconnected and all pipes for the
-
 
123
; device should be closed.
-
 
124
; Also, all pipes closed due to disconnect must remain valid at least until
-
 
125
; driver-provided disconnect function returns; all should-be-freed-but-not-now
-
 
126
; pipes for one device are organized in another double-linked list with
-
 
127
; the head in usb_device_data.ClosedPipeList; this list uses the same link
-
 
128
; fields, one pipe can never be in both lists.
-
 
129
NextSibling     dd      ?
-
 
130
; Next pipe for the physical device.
-
 
131
PrevSibling     dd      ?
-
 
132
; Previous pipe for the physical device.
-
 
133
;
-
 
134
; When hardware part of pipe is changed, some time is needed before further
-
 
135
; actions so that hardware reacts on this change. During that time,
-
 
136
; all changed pipes are organized in single-linked list with the head
-
 
137
; usb_controller.WaitPipeList* and link field NextWait.
-
 
138
; Currently there are two possible reasons to change:
-
 
139
; change of address/packet size in initial configuration,
-
 
140
; close of the pipe. They are distinguished by USB_FLAG_CLOSED.
-
 
141
NextWait        dd      ?
-
 
142
Lock            MUTEX
-
 
143
; Mutex that guards operations with transfer queue for this pipe.
-
 
144
Type            db      ?
-
 
145
; Type of pipe, one of {CONTROL,ISOCHRONOUS,BULK,INTERRUPT}_PIPE.
-
 
146
Flags           db      ?
-
 
147
; Combination of flags, USB_FLAG_*.
-
 
148
                rb      2       ; dword alignment
-
 
149
DeviceData      dd      ?
-
 
150
; Pointer to usb_device_data, common for all pipes for one device.
-
 
151
ends
-
 
152
 
-
 
153
; This structure describes the static head of every list of pipes.
-
 
154
struct usb_static_ep
-
 
155
; software fields
-
 
156
Bandwidth       dd      ?
-
 
157
; valid only for interrupt/isochronous USB1 lists
-
 
158
; The offsets of the following two fields must be the same in this structure
-
 
159
; and in usb_pipe.
-
 
160
NextVirt        dd      ?
-
 
161
PrevVirt        dd      ?
-
 
162
ends
-
 
163
 
-
 
164
; This structure represents one transfer descriptor
-
 
165
; ('g' stands for "general" as opposed to isochronous usb_itd).
-
 
166
; Note that one transfer can have several descriptors:
-
 
167
; a control transfer has three stages.
-
 
168
; Additionally, every controller has a limit on transfer length with
-
 
169
; one descriptor (packet size for UHCI, 1K for OHCI, 4K for EHCI),
-
 
170
; large transfers must be split into individual packets according to that limit.
-
 
171
struct usb_gtd
-
 
172
Callback        dd      ?
-
 
173
; Zero for intermediate descriptors, pointer to callback function
-
 
174
; for final descriptor. See the docs for description of the callback.
-
 
175
UserData        dd      ?
-
 
176
; Dword which is passed to Callback as is, not used by USB code itself.
-
 
177
; Two following fields organize all descriptors for one pipe in
-
 
178
; the linked list.
-
 
179
NextVirt        dd      ?
-
 
180
PrevVirt        dd      ?
-
 
181
Pipe            dd      ?
-
 
182
; Pointer to the parent usb_pipe.
-
 
183
Buffer          dd      ?
-
 
184
; Pointer to data for this descriptor.
-
 
185
Length          dd      ?
-
 
186
; Length of data for this descriptor.
-
 
187
ends
-
 
188
 
-
 
189
; =============================================================================
-
 
190
; =================================== Code ====================================
-
 
191
; =============================================================================
-
 
192
 
-
 
193
USB_STDCALL_VERIFY = 1
3
USB_STDCALL_VERIFY = 1
194
macro stdcall_verify [arg]
4
macro stdcall_verify [arg]
195
{
5
{
196
common
6
common
197
if USB_STDCALL_VERIFY
7
if USB_STDCALL_VERIFY
Line 214... Line 24...
214
 
24
 
215
; Part of API for drivers, see documentation for USBOpenPipe.
25
; Part of API for drivers, see documentation for USBOpenPipe.
216
proc usb_open_pipe stdcall uses ebx esi edi,\
26
proc usb_open_pipe stdcall uses ebx esi edi,\
217
 config_pipe:dword, endpoint:dword, maxpacket:dword, type:dword, interval:dword
27
 config_pipe:dword, endpoint:dword, maxpacket:dword, type:dword, interval:dword
218
locals
28
locals
219
tt_vars         rd      (ehci_select_tt_interrupt_list.local_vars_size + 3) / 4
29
tt_vars         rd      24      ; should be enough for ehci_select_tt_interrupt_list
220
targetsmask     dd      ?       ; S-Mask for USB2
30
targetsmask     dd      ?       ; S-Mask for USB2
221
bandwidth       dd      ?
31
bandwidth       dd      ?
222
target          dd      ?
32
target          dd      ?
223
endl
33
endl
Line 808... Line 618...
808
        mov     [eax+usb_gtd.NextVirt], edx
618
        mov     [eax+usb_gtd.NextVirt], edx
809
        call    mutex_unlock
619
        call    mutex_unlock
810
        ret
620
        ret
811
endp
621
endp
Line -... Line 622...
-
 
622
 
-
 
623
; One part of transfer is completed, run the associated callback
-
 
624
; or update total length in the next part of transfer.
-
 
625
; in: ebx -> usb_gtd, ecx = status, edx = length
-
 
626
proc usb_process_gtd
-
 
627
; 1. Test whether it is the last descriptor in the transfer
-
 
628
; <=> it has an associated callback.
-
 
629
        mov     eax, [ebx+usb_gtd.Callback]
-
 
630
        test    eax, eax
-
 
631
        jz      .nocallback
-
 
632
; 2. It has an associated callback; call it with corresponding parameters.
-
 
633
        stdcall_verify eax, [ebx+usb_gtd.Pipe], ecx, \
-
 
634
                [ebx+usb_gtd.Buffer], edx, [ebx+usb_gtd.UserData]
-
 
635
        ret
-
 
636
.nocallback:
-
 
637
; 3. It is an intermediate descriptor. Add its length to the length
-
 
638
; in the following descriptor.
-
 
639
        mov     eax, [ebx+usb_gtd.NextVirt]
-
 
640
        add     [eax+usb_gtd.Length], edx
-
 
641
        ret
-
 
642
endp
812
 
643
 
813
if USB_STDCALL_VERIFY
644
if USB_STDCALL_VERIFY
814
proc verify_regs
645
proc verify_regs
815
virtual at esp
646
virtual at esp
816
        dd      ?       ; return address
647
        dd      ?       ; return address