Subversion Repositories Kolibri OS

Rev

Rev 3745 | Rev 4418 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3520 clevermous 1
; Functions for USB pipe manipulation: opening/closing, sending data etc.
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
194
macro stdcall_verify [arg]
195
{
196
common
197
if USB_STDCALL_VERIFY
198
        pushad
199
        stdcall arg
200
        call    verify_regs
201
        popad
202
else
203
        stdcall arg
204
end if
205
}
206
 
207
; Initialization of usb_static_ep structure,
208
; called from controller-specific initialization; edi -> usb_static_ep
209
proc usb_init_static_endpoint
210
        mov     [edi+usb_static_ep.NextVirt], edi
211
        mov     [edi+usb_static_ep.PrevVirt], edi
212
        ret
213
endp
214
 
215
; Part of API for drivers, see documentation for USBOpenPipe.
216
proc usb_open_pipe stdcall uses ebx esi edi,\
217
 config_pipe:dword, endpoint:dword, maxpacket:dword, type:dword, interval:dword
218
locals
3826 clevermous 219
tt_vars         rd      (ehci_select_tt_interrupt_list.local_vars_size + 3) / 4
3520 clevermous 220
targetsmask     dd      ?       ; S-Mask for USB2
221
bandwidth       dd      ?
222
target          dd      ?
223
endl
224
; 1. Verify type of pipe: it must be one of *_PIPE constants.
225
; Isochronous pipes are not supported yet.
226
        mov     eax, [type]
227
        cmp     eax, INTERRUPT_PIPE
228
        ja      .badtype
229
        cmp     al, ISOCHRONOUS_PIPE
230
        jnz     .goodtype
231
.badtype:
232
        dbgstr 'unsupported type of USB pipe'
233
        jmp     .return0
234
.goodtype:
235
; 2. Allocate memory for pipe and transfer queue.
236
; Empty transfer queue consists of one inactive TD.
237
        mov     ebx, [config_pipe]
238
        mov     esi, [ebx+usb_pipe.Controller]
239
        mov     edx, [esi+usb_controller.HardwareFunc]
240
        call    [edx+usb_hardware_func.AllocPipe]
241
        test    eax, eax
242
        jz      .nothing
243
        mov     edi, eax
244
        mov     edx, [esi+usb_controller.HardwareFunc]
245
        call    [edx+usb_hardware_func.AllocTD]
246