Subversion Repositories Kolibri OS

Rev

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

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