Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4429 Serge 1
; Constants and structures that are shared between different parts of
2
; USB subsystem and *HCI drivers.
3
 
4
; =============================================================================
5
; ================================= Constants =================================
6
; =============================================================================
7
; Version of all structures related to host controllers.
8
; Must be the same in kernel and *hci-drivers.
9
USBHC_VERSION = 1
10
 
11
; USB device must have at least 100ms of stable power before initializing can
12
; proceed; one timer tick is 10ms, so enforce delay in 10 ticks
13
USB_CONNECT_DELAY = 10
14
; USB requires at least 10 ms for reset signalling. Normally, this is one timer
15
; tick. However, it is possible that we start reset signalling in the end of
16
; interval between timer ticks and then we test time in the start of the next
17
; interval; in this case, the delta between [timer_ticks] is 1, but the real
18
; time passed is significantly less than 10 ms. To avoid this, we add an extra
19
; tick; this guarantees that at least 10 ms have passed.
20
USB_RESET_TIME = 2
21
; USB requires at least 10 ms of reset recovery, a delay between reset
22
; signalling and any commands to device. Add an extra tick for the same reasons
23
; as with the previous constant.
24
USB_RESET_RECOVERY_TIME = 2
25
 
26
; USB pipe types
27
CONTROL_PIPE = 0
28
ISOCHRONOUS_PIPE = 1
29
BULK_PIPE = 2
30
INTERRUPT_PIPE = 3
31
 
32
; Status codes for transfer callbacks.
33
; Taken from OHCI as most verbose controller in this sense.
34
USB_STATUS_OK           = 0     ; no error
35
USB_STATUS_CRC          = 1     ; CRC error
36
USB_STATUS_BITSTUFF     = 2     ; bit stuffing violation
37
USB_STATUS_TOGGLE       = 3     ; data toggle mismatch
38
USB_STATUS_STALL        = 4     ; device returned STALL
39
USB_STATUS_NORESPONSE   = 5     ; device not responding
40
USB_STATUS_PIDCHECK     = 6     ; invalid PID check bits
41
USB_STATUS_WRONGPID     = 7     ; unexpected PID value
42
USB_STATUS_OVERRUN      = 8     ; too many data from endpoint
43
USB_STATUS_UNDERRUN     = 9     ; too few data from endpoint
44
USB_STATUS_BUFOVERRUN   = 12    ; overflow of internal controller buffer
45
USB_STATUS_BUFUNDERRUN  = 13    ; underflow of internal controller buffer
46
USB_STATUS_CLOSED       = 16    ; pipe closed
47
                                ; either explicitly with USBClosePipe
48
                                ; or implicitly due to device disconnect
49
 
50
; Possible speeds of USB devices
51
USB_SPEED_FS = 0 ; full-speed
52
USB_SPEED_LS = 1 ; low-speed
53
USB_SPEED_HS = 2 ; high-speed
54
 
55
; flags for usb_pipe.Flags
56
USB_FLAG_CLOSED     = 1         ; pipe is closed, no new transfers
57
; pipe is closed, return error instead of submitting any new transfer
58
USB_FLAG_CAN_FREE   = 2
59
; pipe is closed via explicit call to USBClosePipe, so it can be freed without
60
; any driver notification; if this flag is not set, then the pipe is closed due
61
; to device disconnect, so it must remain valid until return from disconnect
62
; callback provided by the driver
63
USB_FLAG_EXTRA_WAIT = 4
64
; The pipe was in wait list, while another event occured;
65
; when the first wait will be done, reinsert the pipe to wait list
66
USB_FLAG_CLOSED_BIT = 0 ; USB_FLAG_CLOSED = 1 shl USB_FLAG_CLOSED_BIT
67
 
68
; =============================================================================
69
; ================================ Structures =================================
70
; =============================================================================
71
 
72
; Description of controller-specific data and functions.
73
struct usb_hardware_func
74
Version         dd      ?       ; must be USBHC_VERSION
75
ID              dd      ?       ; '*HCI'
76
DataSize        dd      ?       ; sizeof(*hci_controller)
77
BeforeInit      dd      ?
78
; Early initialization: take ownership from BIOS.
79
; in: [ebp-4] = (bus shl 8) + devfn
80
Init            dd      ?
81
; Initialize controller-specific part of controller data.
82
; in: eax -> *hci_controller to initialize, [ebp-4] = (bus shl 8) + devfn
83
; out: eax = 0 <=> failed, otherwise eax -> usb_controller
84
ProcessDeferred dd      ?
85
; Called regularly from the main loop of USB thread
86
; (either due to timeout from a previous call, or due to explicit wakeup).
87
; in: esi -> usb_controller
88
; out: eax = maximum timeout for next call (-1 = infinity)
89
SetDeviceAddress        dd      ?
90
; in: esi -> usb_controller, ebx -> usb_pipe, cl = address
91
GetDeviceAddress        dd      ?
92
; in: esi -> usb_controller, ebx -> usb_pipe
93
; out: eax = address
94
PortDisable             dd      ?
95
; Disable the given port in the root hub.
96
; in: esi -> usb_controller, ecx = port (zero-based)
97
InitiateReset           dd      ?
98
; Start reset signalling on the given port.
99
; in: esi -> usb_controller, ecx = port (zero-based)
100
SetEndpointPacketSize   dd      ?
101
; in: esi -> usb_controller, ebx -> usb_pipe, ecx = packet size
102
AllocPipe               dd      ?
103
; out: eax = pointer to allocated usb_pipe
104
FreePipe                dd      ?
105
; void stdcall with one argument = pointer to previously allocated usb_pipe
106
InitPipe                dd      ?
107
; in: edi -> usb_pipe for target, ecx -> usb_pipe for config pipe,
108
; esi -> usb_controller, eax -> usb_gtd for the first TD,
109
; [ebp+12] = endpoint, [ebp+16] = maxpacket, [ebp+20] = type
110
UnlinkPipe              dd      ?
111
; esi -> usb_controller, ebx -> usb_pipe
112
AllocTD                 dd      ?
113
; out: eax = pointer to allocated usb_gtd
114
FreeTD                  dd      ?
115
; void stdcall with one argument = pointer to previously allocated usb_gtd
116
AllocTransfer           dd      ?
117
; Allocate and initialize one stage of a transfer.
118
; ebx -> usb_pipe, other parameters are passed through the stack:
119
; buffer,size = data to transfer
120
; flags = same as in usb_open_pipe:
121
;   bit 0 = allow short transfer, other bits reserved
122
; td = pointer to the current end-of-queue descriptor
123
; direction =
124
;   0000b for normal transfers,
125
;   1000b for control SETUP transfer,
126
;   1101b for control OUT transfer,
127
;   1110b for control IN transfer
128
; returns eax = pointer to the new end-of-queue descriptor
129
; (not included in the queue itself) or 0 on error
130
InsertTransfer          dd      ?
131
; Activate previously initialized transfer (maybe with multiple stages).
132
; esi -> usb_controller, ebx -> usb_pipe,
133
; [esp+4] -> first usb_gtd for the transfer,
134
; ecx -> last descriptor for the transfer
135
NewDevice               dd      ?
136
; Initiate configuration of a new device (create pseudo-pipe describing that
137
; device and call usb_new_device).
138
; esi -> usb_controller, eax = speed (one of USB_SPEED_* constants).
139
ends
140
 
141
; pointers to kernel API functions that are called from *HCI-drivers
142
struct usbhc_func
143
usb_process_gtd                 dd      ?
144
usb_init_static_endpoint        dd      ?
145
usb_wakeup_if_needed            dd      ?
146
usb_subscribe_control           dd      ?
147
usb_subscription_done           dd      ?
148
usb_allocate_common             dd      ?
149
usb_free_common                 dd      ?
150
usb_td_to_virt                  dd      ?
151
usb_init_transfer               dd      ?
152
usb_undo_tds                    dd      ?
153
usb_test_pending_port           dd      ?
154
usb_get_tt                      dd      ?
155
usb_get_tt_think_time           dd      ?
156
usb_new_device                  dd      ?
157
usb_disconnect_stage2           dd      ?
158
usb_process_wait_lists          dd      ?
159
usb_unlink_td                   dd      ?
160
usb_is_final_packet             dd      ?
161
usb_find_ehci_companion         dd      ?
162
ends
163
 
164
; Controller descriptor.
165
; This structure represents the common (controller-independent) part
166
; of a controller for the USB code. The corresponding controller-dependent
167
; part *hci_controller is located immediately before usb_controller.
168
struct usb_controller
169
; Two following fields organize all controllers in the global linked list.
170
Next            dd      ?
171
Prev            dd      ?
172
HardwareFunc    dd      ?
173
; Pointer to usb_hardware_func structure with controller-specific functions.
174
NumPorts        dd      ?
175
; Number of ports in the root hub.
176
PCICoordinates  dd      ?
177
; Device:function and bus number from PCI.
178
;
179
; The hardware is allowed to cache some data from hardware structures.
180
; Regular operations are designed considering this,
181
; but sometimes it is required to wait for synchronization of hardware cache
182
; with modified structures in memory.
183
; The code keeps two queues of pipes waiting for synchronization,
184
; one for asynchronous (bulk/control) pipes, one for periodic pipes, hardware
185
; cache is invalidated under different conditions for those types.
186
; Both queues are organized in the same way, as single-linked lists.
187
; There are three special positions: the head of list (new pipes are added
188
; here), the first pipe to be synchronized at the current iteration,
189
; the tail of list (all pipes starting from here are synchronized).
190
WaitPipeListAsync       dd      ?
191
WaitPipeListPeriodic    dd      ?
192
; List heads.
193
WaitPipeRequestAsync    dd      ?
194
WaitPipeRequestPeriodic dd      ?
195
; Pending request to hardware to refresh cache for items from WaitPipeList*.
196
; (Pointers to some items in WaitPipeList* or NULLs).
197
ReadyPipeHeadAsync      dd      ?
198
ReadyPipeHeadPeriodic   dd      ?
199
; Items of RemovingList* which were released by hardware and are ready
200
; for further processing.
201
; (Pointers to some items in WaitPipeList* or NULLs).
202
NewConnected    dd      ?
203
; bit mask of recently connected ports of the root hub,
204
; bit set = a device was recently connected to the corresponding port;
205
; after USB_CONNECT_DELAY ticks of stable status these ports are moved to
206
; PendingPorts
207
NewDisconnected dd      ?
208
; bit mask of disconnected ports of the root hub,
209
; bit set = a device in the corresponding port was disconnected,
210
; disconnect processing is required.
211
PendingPorts    dd      ?
212
; bit mask of ports which are ready to be initialized
213
ControlLock     MUTEX   ?
214
; mutex which guards all operations with control queue
215
BulkLock        MUTEX   ?
216
; mutex which guards all operations with bulk queue
217
PeriodicLock    MUTEX   ?
218
; mutex which guards all operations with periodic queues
219
WaitSpinlock:
220
; spinlock guarding WaitPipeRequest/ReadyPipeHead (but not WaitPipeList)
221
StartWaitFrame  dd      ?
222
; USB frame number when WaitPipeRequest* was registered.
223
ResettingHub    dd      ?
224
; Pointer to usb_hub responsible for the currently resetting port, if any.
225
; NULL for the root hub.
226
ResettingPort   db      ?
227
; Port that is currently resetting, 0-based.
228
ResettingSpeed  db      ?
229
; Speed of currently resetting device.
230
ResettingStatus db      ?
231
; Status of port reset. 0 = no port is resetting, -1 = reset failed,
232
; 1 = reset in progress, 2 = reset recovery in progress.
233
                rb      1       ; alignment
234
ResetTime       dd      ?
235
; Time when reset signalling or reset recovery has been started.
236
SetAddressBuffer        rb      8
237
; Buffer for USB control command SET_ADDRESS.
238
ExistingAddresses       rd      128/32
239
; Bitmask for 128 bits; bit i is cleared <=> address i is free for allocating
240
; for new devices. Bit 0 is always set.
241
ConnectedTime   rd      16
242
; Time, in timer ticks, when the port i has signalled the connect event.
243
; Valid only if bit i in NewConnected is set.
244
DevicesByPort   rd      16
245
; Pointer to usb_pipe for zero endpoint (which serves as device handle)
246
; for each port.
247
ends
248
 
249
; Pipe descriptor.
250
; * An USB pipe is described by two structures, for hardware and for software.
251
; * This is the software part. The hardware part is defined in a driver
252
;   of the corresponding controller.
253
; * The hardware part is located immediately before usb_pipe,
254
;   both are allocated at once by controller-specific code
255
;   (it knows the total length, which depends on the hardware part).
256
struct usb_pipe
257
Controller      dd      ?
258
; Pointer to usb_controller structure corresponding to this pipe.
259
; Must be the first dword after hardware part, see *hci_new_device.
260
;
261
; Every endpoint is included into one of processing lists:
262
; * Bulk list contains all Bulk endpoints.
263
; * Control list contains all Control endpoints.
264
; * Several Periodic lists serve Interrupt endpoints with different interval.
265
;   - There are N=2^n "leaf" periodic lists for N ms interval, one is processed
266
;     in the frames 0,N,2N,..., another is processed in the frames
267
;     1,1+N,1+2N,... and so on. The hardware starts processing of periodic
268
;     endpoints in every frame from the list identified by lower n bits of the
269
;     frame number; the addresses of these N lists are written to the
270
;     controller data area during the initialization.
271
;   - We assume that n=5, N=32 to simplify the code and compact the data.
272
;     OHCI works in this way. UHCI and EHCI actually have n=10, N=1024,
273
;     but this is an overkill for interrupt endpoints; the large value of N is
274
;     useful only for isochronous transfers in UHCI and EHCI. UHCI/EHCI code
275
;     initializes "leaf" lists k,k+32,k+64,...,k+(1024-32) to the same value,
276
;     giving essentially N=32.
277
;     This restriction means that the actual maximum interval of polling any
278
;     interrupt endpoint is 32ms, which seems to be a reasonable value.
279
;   - Similarly, there are 16 lists for 16-ms interval, 8 lists for 8-ms
280
;     interval and so on. Finally, there is one list for 1ms interval. Their
281
;     addresses are not directly known to the controller.
282
;   - The hardware serves endpoints following a physical link from the hardware
283
;     part.
284
;   - The hardware links are organized as follows. If the list item is not the
285
;     last, it's hardware link points to the next item. The hardware link of
286
;     the last item points to the first item of the "next" list.
287
;   - The "next" list for k-th and (k+M)-th periodic lists for interval 2M ms
288
;     is the k-th periodic list for interval M ms, M >= 1. In this scheme,
289
;     if two "previous" lists are served in the frames k,k+2M,k+4M,...
290
;     and k+M,k+3M,k+5M,... correspondingly, the "next" list is served in
291
;     the frames k,k+M,k+2M,k+3M,k+4M,k+5M,..., which is exactly what we want.
292
;   - The links between Periodic, Control, Bulk lists and the processing of
293
;     Isochronous endpoints are controller-specific.
294
; * The head of every processing list is a static entry which does not
295
;   correspond to any real pipe. It is described by usb_static_ep
296
;   structure, not usb_pipe. For OHCI and UHCI, sizeof.usb_static_ep plus
297
;   sizeof hardware part is 20h, the total number of lists is
298
;   32+16+8+4+2+1+1+1 = 65, so all these structures fit in one page,
299
;   leaving space for other data. This is another reason for 32ms limit.
300
; * Static endpoint descriptors are kept in *hci_controller structure.
301
; * All items in every processing list, including the static head, are
302
;   organized in a double-linked list using .NextVirt and .PrevVirt fields.
303
; * [[item.NextVirt].PrevVirt] = [[item.PrevVirt].NextVirt] for all items.
304
NextVirt        dd      ?
305
; Next endpoint in the processing list.
306
; See also PrevVirt field and the description before NextVirt field.
307
PrevVirt        dd      ?
308
; Previous endpoint in the processing list.
309
; See also NextVirt field and the description before NextVirt field.
310
;
311
; Every pipe has the associated transfer queue, that is, the double-linked
312
; list of Transfer Descriptors aka TD. For Control, Bulk and Interrupt
313
; endpoints this list consists of usb_gtd structures
314
; (GTD = General Transfer Descriptors), for Isochronous endpoints
315
; this list consists of usb_itd structures, which are not developed yet.
316
; The pipe needs to know only the last TD; the first TD can be
317
; obtained as [[pipe.LastTD].NextVirt].
318
LastTD          dd      ?
319
; Last TD in the transfer queue.
320
;
321
; All opened pipes corresponding to the same physical device are organized in
322
; the double-linked list using .NextSibling and .PrevSibling fields.
323
; The head of this list is kept in usb_device_data structure (OpenedPipeList).
324
; This list is used when the device is disconnected and all pipes for the
325
; device should be closed.
326
; Also, all pipes closed due to disconnect must remain valid at least until
327
; driver-provided disconnect function returns; all should-be-freed-but-not-now
328
; pipes for one device are organized in another double-linked list with
329
; the head in usb_device_data.ClosedPipeList; this list uses the same link
330
; fields, one pipe can never be in both lists.
331
NextSibling     dd      ?
332
; Next pipe for the physical device.
333
PrevSibling     dd      ?
334
; Previous pipe for the physical device.
335
;
336
; When hardware part of pipe is changed, some time is needed before further
337
; actions so that hardware reacts on this change. During that time,
338
; all changed pipes are organized in single-linked list with the head
339
; usb_controller.WaitPipeList* and link field NextWait.
340
; Currently there are two possible reasons to change:
341
; change of address/packet size in initial configuration,
342
; close of the pipe. They are distinguished by USB_FLAG_CLOSED.
343
NextWait        dd      ?
344
Lock            MUTEX
345
; Mutex that guards operations with transfer queue for this pipe.
346
Type            db      ?
347
; Type of pipe, one of {CONTROL,ISOCHRONOUS,BULK,INTERRUPT}_PIPE.
348
Flags           db      ?
349
; Combination of flags, USB_FLAG_*.
350
                rb      2       ; dword alignment
351
DeviceData      dd      ?
352
; Pointer to usb_device_data, common for all pipes for one device.
353
ends
354
 
355
; This structure describes the static head of every list of pipes.
356
struct usb_static_ep
357
; software fields
358
Bandwidth       dd      ?
359
; valid only for interrupt/isochronous USB1 lists
360
; The offsets of the following two fields must be the same in this structure
361
; and in usb_pipe.
362
NextVirt        dd      ?
363
PrevVirt        dd      ?
364
ends
365
 
366
; This structure represents one transfer descriptor
367
; ('g' stands for "general" as opposed to isochronous usb_itd).
368
; Note that one transfer can have several descriptors:
369
; a control transfer has three stages.
370
; Additionally, every controller has a limit on transfer length with
371
; one descriptor (packet size for UHCI, 1K for OHCI, 4K for EHCI),
372
; large transfers must be split into individual packets according to that limit.
373
struct usb_gtd
374
Callback        dd      ?
375
; Zero for intermediate descriptors, pointer to callback function
376
; for final descriptor. See the docs for description of the callback.
377
UserData        dd      ?
378
; Dword which is passed to Callback as is, not used by USB code itself.
379
; Two following fields organize all descriptors for one pipe in
380
; the linked list.
381
NextVirt        dd      ?
382
PrevVirt        dd      ?
383
Pipe            dd      ?
384
; Pointer to the parent usb_pipe.
385
Buffer          dd      ?
386
; Pointer to data for this descriptor.
387
Length          dd      ?
388
; Length of data for this descriptor.
389
ends
390
 
391
; Interface-specific data. Several interfaces of one device can operate
392
; independently, each is controlled by some driver and is identified by
393
; some driver-specific data passed as is to the driver.
394
struct usb_interface_data
395
DriverData      dd      ?
396
; Passed as is to the driver.
397
DriverFunc      dd      ?
398
; Pointer to USBSRV structure for the driver.
399
ends
400
 
401
; Device-specific data.
402
struct usb_device_data
403
PipeListLock    MUTEX
404
; Lock guarding OpenedPipeList. Must be the first item of the structure,
405
; the code passes pointer to usb_device_data as is to mutex_lock/unlock.
406
OpenedPipeList  rd      2
407
; List of all opened pipes for the device.
408
; Used when the device is disconnected, so all pipes should be closed.
409
ClosedPipeList  rd      2
410
; List of all closed, but still valid pipes for the device.
411
; A pipe closed with USBClosePipe is just deallocated,
412
; but a pipe closed due to disconnect must remain valid until driver-provided
413
; disconnect handler returns; this list links all such pipes to deallocate them
414
; after disconnect processing.
415
NumPipes        dd      ?
416
; Number of not-yet-closed pipes.
417
Hub             dd      ?
418
; NULL if connected to the root hub, pointer to usb_hub otherwise.
419
TTHub           dd      ?
420
; Pointer to usb_hub for (the) hub with Transaction Translator for the device,
421
; NULL if the device operates in the same speed as the controller.
422
Port            db      ?
423
; Port on the hub, zero-based.
424
TTPort          db      ?
425
; Port on the TTHub, zero-based.
426
DeviceDescrSize db      ?
427
; Size of device descriptor.
428
Speed           db      ?
429
; Device speed, one of USB_SPEED_*.
430
NumInterfaces   dd      ?
431
; Number of interfaces.
432
ConfigDataSize  dd      ?
433
; Total size of data associated with the configuration descriptor
434
; (including the configuration descriptor itself).
435
Interfaces      dd      ?
436
; Offset from the beginning of this structure to Interfaces field.
437
; Variable-length fields:
438
; DeviceDescriptor:
439
;  device descriptor starts here
440
; ConfigDescriptor = DeviceDescriptor + DeviceDescrSize
441
;  configuration descriptor with all associated data
442
; Interfaces = ALIGN_UP(ConfigDescriptor + ConfigDataSize, 4)
443
;  array of NumInterfaces elements of type usb_interface_data
444
ends
445
 
446
usb_device_data.DeviceDescriptor = sizeof.usb_device_data