Subversion Repositories Kolibri OS

Rev

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

  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.  
  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.
  19. USBHC_VERSION = 2
  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
  59. USB_STATUS_CANCELLED    = 17    ; transfer cancelled with USBAbortPipe
  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
  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.
  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).
  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
  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.
  332. BaseList                dd      ?
  333. ; Pointer to head of the processing list.
  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_*.
  454. Timer           dd      ?
  455. ; Handle of timer that handles request timeout.
  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
  473.