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