Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
5201 serge 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: 5177 $
9
 
10
 
3555 Serge 11
; Implementation of the USB protocol for device enumeration.
12
; Manage a USB device when it becomes ready for USB commands:
13
; configure, enumerate, load the corresponding driver(s),
14
; pass device information to the driver.
15
 
16
; =============================================================================
17
; ================================= Constants =================================
18
; =============================================================================
19
; USB standard request codes
20
USB_GET_STATUS        = 0
21
USB_CLEAR_FEATURE     = 1
22
USB_SET_FEATURE       = 3
23
USB_SET_ADDRESS       = 5
24
USB_GET_DESCRIPTOR    = 6
25
USB_SET_DESCRIPTOR    = 7
26
USB_GET_CONFIGURATION = 8
27
USB_SET_CONFIGURATION = 9
28
USB_GET_INTERFACE     = 10
29
USB_SET_INTERFACE     = 11
30
USB_SYNCH_FRAME       = 12
31
 
32
; USB standard descriptor types
33
USB_DEVICE_DESCR             = 1
34
USB_CONFIG_DESCR             = 2
35
USB_STRING_DESCR             = 3
36
USB_INTERFACE_DESCR          = 4
37
USB_ENDPOINT_DESCR           = 5
38
USB_DEVICE_QUALIFIER_DESCR   = 6
39
USB_OTHER_SPEED_CONFIG_DESCR = 7
40
USB_INTERFACE_POWER_DESCR    = 8
41
 
42
; Compile-time setting. If set, the code will dump all descriptors as they are
43
; read to the debug board.
44
USB_DUMP_DESCRIPTORS = 1
45
 
5201 serge 46
; According to the USB specification (9.2.6.3),
47
; any device must response to SET_ADDRESS in 50 ms, or 5 timer ticks.
48
; Of course, our world is far from ideal.
49
; I have seen devices that just NAK everything when being reset from working
50
; state, but start to work after second reset.
51
; Our strategy is as follows: give 2 seconds for the first attempt,
52
; this should be enough for normal devices and not too long to detect buggy ones.
53
; If the device continues NAKing, reset it and retry several times,
54
; doubling the interval: 2s -> 4s -> 8s -> 16s. Give up after that.
55
; Numbers are quite arbitrary.
56
TIMEOUT_SET_ADDRESS_INITIAL = 200
57
TIMEOUT_SET_ADDRESS_LAST    = 1600
58
 
3555 Serge 59
; =============================================================================
60
; ================================ Structures =================================
61
; =============================================================================
62
; USB descriptors. See USB specification for detailed explanations.
63
; First two bytes of every descriptor have the same meaning.
64
struct usb_descr
65
bLength                 db      ?
66
; Size of this descriptor in bytes
67
bDescriptorType         db      ?
68
; One of USB_*_DESCR constants.
69
ends
70
 
71
; USB device descriptor
72
struct usb_device_descr usb_descr
73
bcdUSB                  dw      ?
74
; USB Specification Release number in BCD, e.g. 110h = USB 1.1
75
bDeviceClass            db      ?
76
; USB Device Class Code
77
bDeviceSubClass         db      ?
78
; USB Device Subclass Code
79
bDeviceProtocol         db      ?
80
; USB Device Protocol Code
81
bMaxPacketSize0         db      ?
82
; Maximum packet size for zero endpoint
83
idVendor                dw      ?
84
; Vendor ID
85
idProduct               dw      ?
86
; Product ID
87
bcdDevice               dw      ?
88
; Device release number in BCD
89
iManufacturer           db      ?
90
; Index of string descriptor describing manufacturer
91
iProduct                db      ?
92
; Index of string descriptor describing product
93
iSerialNumber           db      ?
94
; Index of string descriptor describing serial number
95
bNumConfigurations      db      ?
96
; Number of possible configurations
97
ends
98
 
99
; USB configuration descriptor
100
struct usb_config_descr usb_descr
101
wTotalLength            dw      ?
102
; Total length of data returned for this configuration
103
bNumInterfaces          db      ?
104
; Number of interfaces in this configuration
105
bConfigurationValue     db      ?
106
; Value for SET_CONFIGURATION control request
107
iConfiguration          db      ?
108
; Index of string descriptor describing this configuration
109
bmAttributes            db      ?
110
; Bit 6 is SelfPowered, bit 5 is RemoteWakeupSupported,
111
; bit 7 must be 1, other bits must be 0
112
bMaxPower               db      ?
113
; Maximum power consumption from the bus in 2mA units
114
ends
115
 
116
; USB interface descriptor
117
struct usb_interface_descr usb_descr
118
; The following two fields work in pair. Sometimes one interface can work
119
; in different modes; e.g. videostream from web-cameras requires different
120
; bandwidth depending on resolution/quality/compression settings.
121
; Each mode of each interface has its own descriptor with its own endpoints
122
; following; all descriptors for one interface have the same bInterfaceNumber,
123
; and different bAlternateSetting.
124
; By default, any interface operates in mode with bAlternateSetting = 0.
125
; Often this is the only mode. If there are another modes, the active mode
126
; is selected by SET_INTERFACE(bAlternateSetting) control request.
127
bInterfaceNumber        db      ?
128
bAlternateSetting       db      ?
129
bNumEndpoints           db      ?
130
; Number of endpoints used by this interface, excluding zero endpoint
131
bInterfaceClass         db      ?
132
; USB Interface Class Code
133
bInterfaceSubClass      db      ?
134
; USB Interface Subclass Code
135
bInterfaceProtocol      db      ?
136
; USB Interface Protocol Code
137
iInterface              db      ?
138
; Index of string descriptor describing this interface
139
ends
140
 
141
; USB endpoint descriptor
142
struct usb_endpoint_descr usb_descr
143
bEndpointAddress        db      ?
144
; Lower 4 bits form endpoint number,
145
; upper bit is 0 for OUT endpoints and 1 for IN endpoints,
146
; other bits must be zero
147
bmAttributes            db      ?
148
; Lower 2 bits form transfer type, one of *_PIPE,
149
; other bits must be zero for non-isochronous endpoints;
150
; refer to the USB specification for meaning in isochronous case
151
wMaxPacketSize          dw      ?
152
; Lower 11 bits form maximum packet size,
153
; next two bits specify the number of additional transactions per microframe
154
; for high-speed periodic endpoints, other bits must be zero.
155
bInterval               db      ?
156
; Interval for polling endpoint for data transfers.
157
; Isochronous and high-speed interrupt endpoints: poll every 2^(bInterval-1)
158
; (micro)frames
159
; Full/low-speed interrupt endpoints: poll every bInterval frames
160
; High-speed bulk/control OUT endpoints: maximum NAK rate
161
ends
162
 
163
; =============================================================================
164
; =================================== Code ====================================
165
; =============================================================================
166
 
167
; When a new device is ready to be configured, a controller-specific code
168
; calls usb_new_device.
169
; The sequence of further actions:
170
; * open pipe for the zero endpoint (usb_new_device);
171
;   maximum packet size is not known yet, but it must be at least 8 bytes,
172
;   so it is safe to send packets with <= 8 bytes
173
; * issue SET_ADDRESS control request (usb_new_device)
174
; * set the new device address in the pipe (usb_set_address_callback)
175
; * notify a controller-specific code that initialization of other ports
176
;   can be started (usb_set_address_callback)
177
; * issue GET_DESCRIPTOR control request for first 8 bytes of device descriptor
178
;   (usb_after_set_address)
179
; * first 8 bytes of device descriptor contain the true packet size for zero
180
;   endpoint, so set the true packet size (usb_get_descr8_callback)
181
; * first 8 bytes of a descriptor contain the full size of this descriptor,
182
;   issue GET_DESCRIPTOR control request for the full device descriptor
183
;   (usb_after_set_endpoint_size)
184
; * issue GET_DESCRIPTOR control request for first 8 bytes of configuration
185
;   descriptor (usb_get_descr_callback)
186
; * issue GET_DESCRIPTOR control request for full configuration descriptor
187
;   (usb_know_length_callback)
188
; * issue SET_CONFIGURATION control request (usb_set_config_callback)
189
; * parse configuration descriptor, load the corresponding driver(s),
190
;   pass the configuration descriptor to the driver and let the driver do
191
;   the further work (usb_got_config_callback)
192
 
193
; This function is called from controller-specific part
194
; when a new device is ready to be configured.
195
; in: ecx -> pseudo-pipe, part of usb_pipe
196
; in: esi -> usb_controller
197
; in: [esi+usb_controller.ResettingHub] is the pointer to usb_hub for device,
198
;     NULL if the device is connected to the root hub
199
; in: [esi+usb_controller.ResettingPort] is the port for the device, zero-based
200
; in: [esi+usb_controller.ResettingSpeed] is the speed of the device, one of
201
;     USB_SPEED_xx.
202
; out: eax = 0 <=> failed, the caller should disable the port.
203
proc usb_new_device
204
        push    ebx edi         ; save used registers to be stdcall
5201 serge 205
; 1. Check whether we're here because we were trying to reset
206
; already-registered device in hope to fix something serious.
207
; If so, skip allocation and go to 6.
208
        movzx   eax, [esi+usb_controller.ResettingPort]
209
        mov     edx, [esi+usb_controller.ResettingHub]
210
        test    edx, edx
211
        jz      .test_roothub
212
        mov     edx, [edx+usb_hub.ConnectedDevicesPtr]
213
        mov     ebx, [edx+eax*4]
214
        jmp     @f
215
.test_roothub:
216
        mov     ebx, [esi+usb_controller.DevicesByPort+eax*4]
217
@@:
218
        test    ebx, ebx
219
        jnz     .try_set_address
220
; 2. Allocate resources. Any device uses the following resources:
3555 Serge 221
; - device address in the bus
222
; - memory for device data
223
; - pipe for zero endpoint
224
; If some allocation fails, we must undo our actions. Closing the pipe
225
; is a hard task, so we avoid it and open the pipe as the last resource.
226
; The order for other two allocations is quite arbitrary.
5201 serge 227
; 2a. Allocate a bus address.
3555 Serge 228
        push    ecx
229
        call    usb_set_address_request
230
        pop     ecx
5201 serge 231
; 2b. If failed, just return zero.
3555 Serge 232
        test    eax, eax
233
        jz      .nothing
5201 serge 234
; 2c. Allocate memory for device data.
3555 Serge 235
; For now, we need sizeof.usb_device_data and extra 8 bytes for GET_DESCRIPTOR
236
; input and output, see usb_after_set_address. Later we will reallocate it
237
; to actual size needed for descriptors.
4265 Serge 238
        movi    eax, sizeof.usb_device_data + 8
3555 Serge 239
        push    ecx
240
        call    malloc
241
        pop     ecx
5201 serge 242
; 2d. If failed, free the bus address and return zero.
3555 Serge 243
        test    eax, eax
244
        jz      .nomemory
5201 serge 245
; 2e. Open pipe for endpoint zero.
3555 Serge 246
; For now, we do not know the actual maximum packet size;
247
; for full-speed devices it can be any of 8, 16, 32, 64 bytes,
248
; low-speed devices must have 8 bytes, high-speed devices must have 64 bytes.
249
; Thus, we must use some fake "maximum packet size" until the actual size
250
; will be known. However, the maximum packet size must be at least 8, and
251
; initial stages of the configuration process involves only packets of <= 8
252
; bytes, they will be transferred correctly as long as
253
; the fake "maximum packet size" is also at least 8.
254
; Thus, any number >= 8 is suitable for actual hardware.
255
; However, software emulation of EHCI in VirtualBox assumes that high-speed
256
; control transfers are those originating from pipes with max packet size = 64,
257
; even on early stages of the configuration process. This is incorrect,
258
; but we have no specific preferences, so let VirtualBox be happy and use 64
259
; as the fake "maximum packet size".
260
        push    eax
261
; We will need many zeroes.
262
; "push edi" is one byte, "push 0" is two bytes; save space, use edi.
263
        xor     edi, edi
264
        stdcall usb_open_pipe, ecx, edi, 64, edi, edi
265
; Put pointer to pipe into ebx. "xchg eax,reg" is one byte, mov is two bytes.
266
        xchg    eax, ebx
267
        pop     eax
5201 serge 268
; 2f. If failed, free the memory, the bus address and return zero.
3555 Serge 269
        test    ebx, ebx
270
        jz      .freememory
5201 serge 271
; 3. Store pointer to device data in the pipe structure.
3555 Serge 272
        mov     [ebx+usb_pipe.DeviceData], eax
5201 serge 273
; 4. Init device data, using usb_controller.Resetting* variables.
274
        mov     [eax+usb_device_data.Timer], edi
275
        mov     dword [eax+usb_device_data.DeviceDescriptor], TIMEOUT_SET_ADDRESS_INITIAL
3908 Serge 276
        mov     [eax+usb_device_data.TTHub], edi
277
        mov     [eax+usb_device_data.TTPort], 0
278
        mov     [eax+usb_device_data.NumInterfaces], edi
279
        mov     [eax+usb_device_data.DeviceDescrSize], 0
280
        mov     dl, [esi+usb_controller.ResettingSpeed]
281
        mov     [eax+usb_device_data.Speed], dl
3555 Serge 282
        mov     [eax+usb_device_data.NumPipes], 1
3908 Serge 283
        push    ebx
284
        cmp     dl, USB_SPEED_HS
285
        jz      .nott
286
        mov     ebx, [esi+usb_controller.ResettingHub]
287
        test    ebx, ebx
288
        jz      .nott
289
        mov     cl, [esi+usb_controller.ResettingPort]
290
        mov     edx, [ebx+usb_hub.ConfigPipe]
291
        mov     edx, [edx+usb_pipe.DeviceData]
292
        cmp     [edx+usb_device_data.TTHub], 0
293
        jz      @f
294
        mov     cl, [edx+usb_device_data.TTPort]
295
        mov     ebx, [edx+usb_device_data.TTHub]
296
        jmp     .has_tt
297
@@:
298
        cmp     [edx+usb_device_data.Speed], USB_SPEED_HS
299
        jnz     .nott
300
.has_tt:
301
        mov     [eax+usb_device_data.TTHub], ebx
302
        mov     [eax+usb_device_data.TTPort], cl
303
.nott:
304
        pop     ebx
3555 Serge 305
        mov     [eax+usb_device_data.ConfigDataSize], edi
306
        mov     [eax+usb_device_data.Interfaces], edi
307
        movzx   ecx, [esi+usb_controller.ResettingPort]
3908 Serge 308
        mov     [eax+usb_device_data.Port], cl
3555 Serge 309
        mov     edx, [esi+usb_controller.ResettingHub]
310
        mov     [eax+usb_device_data.Hub], edx
5201 serge 311
; 5. Store pointer to the config pipe in the hub data.
3555 Serge 312
; Config pipe serves as device identifier.
313
; Root hubs use the array inside usb_controller structure,
314
; non-root hubs use the array immediately after usb_hub structure.
315
        test    edx, edx
316
        jz      .roothub
317
        mov     edx, [edx+usb_hub.ConnectedDevicesPtr]
318
        mov     [edx+ecx*4], ebx
319
        jmp     @f
320
.roothub:
321
        mov     [esi+usb_controller.DevicesByPort+ecx*4], ebx
322
@@:
323
        call    usb_reinit_pipe_list
5201 serge 324
; 6. Issue SET_ADDRESS control request, using buffer filled in step 2a.
325
; 6a. Configure timer to force reset after timeout.
326
; Note: we can't use self-destructing timer, because we need to be able to cancel it,
327
; and for self-destructing timer we could have race condition in cancelling/destructing.
328
;        DEBUGF 1,'K : pipe %x\n',ebx
329
.try_set_address:
330
        xor     edi, edi
331
        mov     edx, [ebx+usb_pipe.DeviceData]
332
        stdcall timer_hs, [edx+usb_device_data.DeviceDescriptor], 7FFFFFFFh, usb_abort_pipe, ebx
333
        test    eax, eax
334
        jz      .nothing
335
        mov     edx, [ebx+usb_pipe.DeviceData]
336
        mov     [edx+usb_device_data.Timer], eax
337
; 6b. If it succeeded, setup timer to configure wait timeout.
338
        lea     eax, [esi+usb_controller.SetAddressBuffer]
339
        stdcall usb_control_async, ebx, eax, edi, edi, usb_set_address_callback, edi, edi
3555 Serge 340
; Use the return value from usb_control_async as our return value;
341
; if it is zero, then something has failed.
342
.nothing:
5201 serge 343
; 7. Return.
3555 Serge 344
        pop     edi ebx         ; restore used registers to be stdcall
345
        ret
5201 serge 346
; Handlers of failures in steps 2b, 2d, 2f.
3555 Serge 347
.freememory:
348
        call    free
349
        jmp     .freeaddr
350
.nomemory:
351
        dbgstr 'No memory for device data'
352
.freeaddr:
353
        mov     ecx, dword [esi+usb_controller.SetAddressBuffer+2]
354
        bts     [esi+usb_controller.ExistingAddresses], ecx
355
        xor     eax, eax
356
        jmp     .nothing
357
endp
358
 
359
; Helper procedure for usb_new_device.
360
; Allocates a new USB address and fills usb_controller.SetAddressBuffer
361
; with data for SET_ADDRESS(allocated_address) request.
362
; out: eax = 0 <=> failed
363
; Destroys edi.
364
proc usb_set_address_request
365
; There are 128 bits, one for each possible address.
366
; Note: only the USB thread works with usb_controller.ExistingAddresses,
367
; so there is no need for synchronization.
368
; We must find a bit set to 1 and clear it.
369
; 1. Find the first dword which has a nonzero bit = which is nonzero.
370
        mov     ecx, 128/32
371
        lea     edi, [esi+usb_controller.ExistingAddresses]
372
        xor     eax, eax
373
        repz scasd
374
; 2. If all dwords are zero, return an error.
375
        jz      .error
376
; 3. The dword at [edi-4] is nonzero. Find the lowest nonzero bit.
377
        bsf     eax, [edi-4]
378
; Now eax = bit number inside the dword at [edi-4].
379
; 4. Clear the bit.
380
        btr     [edi-4], eax
381
; 5. Generate the address by edi = memory address and eax = bit inside dword.
382
; Address = eax + 8 * (edi-4 - (esi+usb_controller.ExistingAddress)).
383
        sub     edi, esi
384
        lea     edi, [eax+(edi-4-usb_controller.ExistingAddresses)*8]
385
; 6. Store the allocated address in SetAddressBuffer and fill remaining fields.
386
; Note that usb_controller is zeroed at allocation, so only command byte needs
387
; to be filled.
388
        mov     byte [esi+usb_controller.SetAddressBuffer+1], USB_SET_ADDRESS
389
        mov     dword [esi+usb_controller.SetAddressBuffer+2], edi
390
; 7. Return non-zero value in eax.
391
        inc     eax
392
.nothing:
393
        ret
394
.error:
395
        dbgstr 'cannot allocate USB address'
396
        xor     eax, eax
397
        jmp     .nothing
398
endp
399
 
400
; This procedure is called by USB stack when SET_ADDRESS request initiated by
401
; usb_new_device is completed, either successfully or unsuccessfully.
402
; Note that USB stack uses esi = pointer to usb_controller.
403
proc usb_set_address_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword
404
        push    ebx     ; save ebx to be stdcall
5201 serge 405
        mov     ebx, [pipe]
406
; 1. In any case, cancel the timer.
407
        mov     eax, [ebx+usb_pipe.DeviceData]
408
        stdcall cancel_timer_hs, [eax+usb_device_data.Timer]
409
        mov     eax, [ebx+usb_pipe.DeviceData]
410
        mov     [eax+usb_device_data.Timer], 0
3555 Serge 411
; Load data to registers for further references.
412
        mov     ecx, dword [esi+usb_controller.SetAddressBuffer+2]
413
        mov     eax, [esi+usb_controller.HardwareFunc]
5201 serge 414
; 2. Check whether the device has accepted new address. If so, proceed to 3.
415
; Otherwise, go to 4 if killed by usb_set_address_timeout or to 5 otherwise.
416
        cmp     [status], USB_STATUS_CANCELLED
417
        jz      .timeout
3555 Serge 418
        cmp     [status], 0
419
        jnz     .error
5201 serge 420
; 3. Address accepted.
421
; 3a. The controller-specific structure for the control pipe still uses
3555 Serge 422
; zero address. Call the controller-specific function to change it to
423
; the actual address.
424
; Note that the hardware could cache the controller-specific structure,
425
; so setting the address could take some time until the cache is evicted.
426
; Thus, the call is asynchronous; meet us in usb_after_set_address when it will
427
; be safe to continue.
4423 Serge 428
;        dbgstr 'address set in device'
3555 Serge 429
        call    [eax+usb_hardware_func.SetDeviceAddress]
5201 serge 430
; 3b. If the port is in non-root hub, clear 'reset in progress' flag.
431
; In any case, proceed to 6.
3555 Serge 432
        mov     eax, [esi+usb_controller.ResettingHub]
433
        test    eax, eax
434
        jz      .return
435
        and     [eax+usb_hub.Actions], not HUB_RESET_IN_PROGRESS
436
.return:
5201 serge 437
; 6. Address configuration done, we can proceed with other ports.
3555 Serge 438
; Call the worker function for that.
439
        call    usb_test_pending_port
5201 serge 440
.wakeup:
441
        push    esi edi
442
        call    usb_wakeup
443
        pop     edi esi
3555 Serge 444
.nothing:
445
        pop     ebx     ; restore ebx to be stdcall
446
        ret
5201 serge 447
.timeout:
448
; 4. Device continues to NAK the request. Reset it and retry.
449
        mov     edx, [ebx+usb_pipe.DeviceData]
450
        mov     ecx, [edx+usb_device_data.DeviceDescriptor]
451
        add     ecx, ecx
452
        cmp     ecx, TIMEOUT_SET_ADDRESS_LAST
453
        ja      .error
454
        mov     [edx+usb_device_data.DeviceDescriptor], ecx
455
        dbgstr 'Timeout in USB device initialization, trying to reset...'
456
        cmp     [esi+usb_controller.ResettingHub], 0
457
        jz      .reset_roothub
458
        push    esi
459
        mov     esi, [esi+usb_controller.ResettingHub]
460
        call    usb_hub_initiate_reset
461
        pop     esi
462
        jmp     .nothing
463
.reset_roothub:
464
        movzx   ecx, [esi+usb_controller.ResettingPort]
465
        call    [eax+usb_hardware_func.InitiateReset]
466
        jmp     .wakeup
3555 Serge 467
.error:
5201 serge 468
; 5. Device error: device not responding, disconnect etc.
3555 Serge 469
        DEBUGF 1,'K : error %d in SET_ADDRESS, USB device disabled\n',[status]
5201 serge 470
; 5a. The address has not been accepted. Mark it as free.
3555 Serge 471
        bts     dword [esi+usb_controller.ExistingAddresses], ecx
5201 serge 472
; 5b. Disable the port with bad device.
3555 Serge 473
; For the root hub, call the controller-specific function and go to 6.
474
; For non-root hubs, let the hub code do its work and return (the request
475
; could take some time, the hub code is responsible for proceeding).
476
        cmp     [esi+usb_controller.ResettingHub], 0
477
        jz      .roothub
478
        mov     eax, [esi+usb_controller.ResettingHub]
479
        call    usb_hub_disable_resetting_port
480
        jmp     .nothing
481
.roothub:
482
        movzx   ecx, [esi+usb_controller.ResettingPort]
483
        call    [eax+usb_hardware_func.PortDisable]
484
        jmp     .return
485
endp
486
 
487
; This procedure is called from usb_subscription_done when the hardware cache
488
; is cleared after request from usb_set_address_callback.
489
; in: ebx -> usb_pipe
490
proc usb_after_set_address
4423 Serge 491
;        dbgstr 'address set for controller'
3555 Serge 492
; Issue control transfer GET_DESCRIPTOR(DEVICE_DESCR) for first 8 bytes.
493
; Remember, we still do not know the actual packet size;
494
; 8-bytes-request is safe.
495
; usb_new_device has allocated 8 extra bytes besides sizeof.usb_device_data;
496
; use them for both input and output.
497
        mov     eax, [ebx+usb_pipe.DeviceData]
498
        add     eax, usb_device_data.DeviceDescriptor
499
        mov     dword [eax], \
500
                80h + \         ; device-to-host, standard, device-wide
501
                (USB_GET_DESCRIPTOR shl 8) + \  ; request
502
                (0 shl 16) + \  ; descriptor index: there is only one
503
                (USB_DEVICE_DESCR shl 24)       ; descriptor type
504
        mov     dword [eax+4], 8 shl 16         ; data length
505
        stdcall usb_control_async, ebx, eax, eax, 8, usb_get_descr8_callback, eax, 0
506
        ret
507
endp
508
 
509
; This procedure is called by USB stack when GET_DESCRIPTOR(DEVICE_DESCR)
510
; request initiated by usb_after_set_address is completed, either successfully
511
; or unsuccessfully.
512
; Note that USB stack uses esi = pointer to usb_controller.
513
proc usb_get_descr8_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword
514
;       mov     eax, [buffer]
515
;       DEBUGF 1,'K : descr8: l=%x; %x %x %x %x %x %x %x %x\n',[length],\
516
;               [eax]:2,[eax+1]:2,[eax+2]:2,[eax+3]:2,[eax+4]:2,[eax+5]:2,[eax+6]:2,[eax+7]:2
517
        push    edi ebx         ; save used registers to be stdcall
518
        mov     ebx, [pipe]
519
; 1. Check whether the operation was successful.
520
; If not, say something to the debug board and stop the initialization.
521
        cmp     [status], 0
522
        jnz     .error
523
; 2. Length of descriptor must be at least sizeof.usb_device_descr bytes.
524
; If not, say something to the debug board and stop the initialization.
525
        mov     eax, [ebx+usb_pipe.DeviceData]
526
        cmp     [eax+usb_device_data.DeviceDescriptor+usb_device_descr.bLength], sizeof.usb_device_descr
527
        jb      .error
528
; 3. Now first 8 bytes of device descriptor are known;
529
; set DeviceDescrSize accordingly.
530
        mov     [eax+usb_device_data.DeviceDescrSize], 8
531
; 4. The controller-specific structure for the control pipe still uses
532
; the fake "maximum packet size". Call the controller-specific function to
533
; change it to the actual packet size from the device.
534
; Note that the hardware could cache the controller-specific structure,
535
; so changing it could take some time until the cache is evicted.
536
; Thus, the call is asynchronous; meet us in usb_after_set_endpoint_size
537
; when it will be safe to continue.
538
        movzx   ecx, [eax+usb_device_data.DeviceDescriptor+usb_device_descr.bMaxPacketSize0]
539
        mov     eax, [esi+usb_controller.HardwareFunc]
540
        call    [eax+usb_hardware_func.SetEndpointPacketSize]
541
.nothing:
542
; 5. Return.
543
        pop     ebx edi         ; restore used registers to be stdcall
544
        ret
545
.error:
546
        dbgstr 'error with USB device descriptor'
547
        jmp     .nothing
548
endp
549
 
550
; This procedure is called from usb_subscription_done when the hardware cache
551
; is cleared after request from usb_get_descr8_callback.
552
; in: ebx -> usb_pipe
553
proc usb_after_set_endpoint_size
554
; 1. Reallocate memory for device data:
555
; add memory for now-known size of device descriptor and extra 8 bytes
556
; for further actions.
557
; 1a. Allocate new memory.
558
        mov     eax, [ebx+usb_pipe.DeviceData]
559
        movzx   eax, [eax+usb_device_data.DeviceDescriptor+usb_device_descr.bLength]
560
; save length for step 2
561
        push    eax
562
        add     eax, sizeof.usb_device_data + 8
563
        call    malloc
564
; 1b. If failed, say something to the debug board and stop the initialization.
565
        test    eax, eax
566
        jz      .nomemory
567
; 1c. Copy data from old memory to new memory and switch the pointer in usb_pipe.
568
        push    eax
569
        push    esi edi
570
        mov     esi, [ebx+usb_pipe.DeviceData]
571
        mov     [ebx+usb_pipe.DeviceData], eax
572
        mov     edi, eax
573
        mov     eax, esi
3908 Serge 574
        mov     ecx, sizeof.usb_device_data / 4
575
        rep movsd
3555 Serge 576
        pop     edi esi
577
        call    usb_reinit_pipe_list
578
; 1d. Free the old memory.
579
        call    free
580
        pop     eax
581
; 2. Issue control transfer GET_DESCRIPTOR(DEVICE) for full descriptor.
582
; restore length saved in step 1a
583
        pop     edx
584
        add     eax, sizeof.usb_device_data
585
        mov     dword [eax], \
586
                80h + \         ; device-to-host, standard, device-wide
587
                (USB_GET_DESCRIPTOR shl 8) + \  ; request
588
                (0 shl 16) + \  ; descriptor index: there is only one
589
                (USB_DEVICE_DESCR shl 24)       ; descriptor type
590
        and     dword [eax+4], 0
591
        mov     [eax+6], dl     ; data length
592
        stdcall usb_control_async, ebx, eax, eax, edx, usb_get_descr_callback, eax, 0
593
; 3. Return.
594
        ret
595
.nomemory:
596
        dbgstr 'No memory for device data'
597
        ret
598
endp
599
 
600
; This procedure is called by USB stack when GET_DESCRIPTOR(DEVICE)
601
; request initiated by usb_after_set_endpoint_size is completed,
602
; either successfully or unsuccessfully.
603
proc usb_get_descr_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword
604
; Note: the prolog is the same as in usb_get_descr8_callback.
605
        push    edi ebx         ; save used registers to be stdcall
606
; 1. Check whether the operation was successful.
607
; If not, say something to the debug board and stop the initialization.
608
        cmp     [status], 0
609
        jnz     usb_get_descr8_callback.error
610
; The full descriptor is known, dump it if specified by compile-time option.
611
if USB_DUMP_DESCRIPTORS
612
        mov     eax, [buffer]
613
        mov     ecx, [length]
614
        sub     ecx, 8
615
        jbe     .skipdebug
616
        DEBUGF 1,'K : device descriptor:'
617
@@:
618
        DEBUGF 1,' %x',[eax]:2
619
        inc     eax
620
        dec     ecx
621
        jnz     @b
622
        DEBUGF 1,'\n'
623
.skipdebug:
624
end if
625
; 2. Check that bLength is the same as was in the previous request.
626
; If not, say something to the debug board and stop the initialization.
627
; It is important, because usb_after_set_endpoint_size has allocated memory
628
; according to the old bLength. Note that [length] for control transfers
629
; includes 8 bytes of setup packet, so data length = [length] - 8.
630
        mov     eax, [buffer]
631
        movzx   ecx, [eax+usb_device_descr.bLength]
632
        add     ecx, 8
633
        cmp     [length], ecx
634
        jnz     usb_get_descr8_callback.error
635
; Amuse the user if she is watching the debug board.
636
        mov     cl, [eax+usb_device_descr.bNumConfigurations]
637
        DEBUGF 1,'K : found USB device with ID %x:%x, %d configuration(s)\n',\
638
                [eax+usb_device_descr.idVendor]:4,\
639
                [eax+usb_device_descr.idProduct]:4,\
640
                cl
641
; 3. If there are no configurations, stop the initialization.
642
        cmp     [eax+usb_device_descr.bNumConfigurations], 0
643
        jz      .nothing
644
; 4. Copy length of device descriptor to device data structure.
645
        movzx   edx, [eax+usb_device_descr.bLength]
646
        mov     [eax+usb_device_data.DeviceDescrSize-usb_device_data.DeviceDescriptor], dl
647
; 5. Issue control transfer GET_DESCRIPTOR(CONFIGURATION). We do not know
648
; the full length of that descriptor, so start with first 8 bytes, they contain
649
; the full length.
650
; usb_after_set_endpoint_size has allocated 8 extra bytes after the
651
; device descriptor, use them for both input and output.
652
        add     eax, edx
653
        mov     dword [eax], \
654
                80h + \         ; device-to-host, standard, device-wide
655
                (USB_GET_DESCRIPTOR shl 8) + \  ; request
656
                (0 shl 16) + \  ; descriptor index: there is only one
657
                (USB_CONFIG_DESCR shl 24)       ; descriptor type
658
        mov     dword [eax+4], 8 shl 16         ; data length
659
        stdcall usb_control_async, [pipe], eax, eax, 8, usb_know_length_callback, eax, 0
660
.nothing:
661
; 6. Return.
662
        pop     ebx edi         ; restore used registers to be stdcall
663
        ret
664
endp
665
 
666
; This procedure is called by USB stack when GET_DESCRIPTOR(CONFIGURATION)
667
; request initiated by usb_get_descr_callback is completed,
668
; either successfully or unsuccessfully.
669
proc usb_know_length_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword
670
        push    ebx             ; save used registers to be stdcall
671
; 1. Check whether the operation was successful.
672
; If not, say something to the debug board and stop the initialization.
673
        cmp     [status], 0
674
        jnz     .error
675
; 2. Get the total length of data associated with config descriptor and store
676
; it in device data structure. The total length must be at least
677
; sizeof.usb_config_descr bytes; if not, say something to the debug board and
678
; stop the initialization.
679
        mov     eax, [buffer]
680
        mov     edx, [pipe]
681
        movzx   ecx, [eax+usb_config_descr.wTotalLength]
682
        mov     eax, [edx+usb_pipe.DeviceData]
683
        cmp     ecx, sizeof.usb_config_descr
684
        jb      .error
685
        mov     [eax+usb_device_data.ConfigDataSize], ecx
686
; 3. Reallocate memory for device data:
687
; include usb_device_data structure, device descriptor,
688
; config descriptor with all associated data, and extra bytes
689
; sufficient for 8 bytes control packet and for one usb_interface_data struc.
690
; Align extra bytes to dword boundary.
691
if sizeof.usb_interface_data > 8
692
.extra_size = sizeof.usb_interface_data
693
else
694
.extra_size = 8
695
end if
696
; 3a. Allocate new memory.
697
        movzx   edx, [eax+usb_device_data.DeviceDescrSize]
698
        lea     eax, [ecx+edx+sizeof.usb_device_data+.extra_size+3]
699
        and     eax, not 3
700
        push    eax
701
        call    malloc
702
        pop     edx
703
; 3b. If failed, say something to the debug board and stop the initialization.
704
        test    eax, eax
705
        jz      .nomemory
706
; 3c. Copy data from old memory to new memory and switch the pointer in usb_pipe.
707
        push    eax
708
        mov     ebx, [pipe]
709
        push    esi edi
710
        mov     esi, [ebx+usb_pipe.DeviceData]
711
        mov     edi, eax
712
        mov     [ebx+usb_pipe.DeviceData], eax
713
        mov     eax, esi
714
        movzx   ecx, [esi+usb_device_data.DeviceDescrSize]
715
        sub     edx, .extra_size
716
        mov     [esi+usb_device_data.Interfaces], edx
717
        add     ecx, sizeof.usb_device_data + 8
718
        mov     edx, ecx
719
        shr     ecx, 2
720
        and     edx, 3
721
        rep movsd
722
        mov     ecx, edx
723
        rep movsb
724
        pop     edi esi
725
        call    usb_reinit_pipe_list
726
; 3d. Free old memory.
727
        call    free
728
        pop     eax
5201 serge 729
; 4. Issue control transfer GET_DESCRIPTOR(CONFIGURATION) for full descriptor.
3555 Serge 730
        movzx   ecx, [eax+usb_device_data.DeviceDescrSize]
731
        mov     edx, [eax+usb_device_data.ConfigDataSize]
732
        lea     eax, [eax+ecx+sizeof.usb_device_data]
733
        mov     dword [eax], \
734
                80h + \         ; device-to-host, standard, device-wide
735
                (USB_GET_DESCRIPTOR shl 8) + \  ; request
736
                (0 shl 16) + \  ; descriptor index: there is only one
737
                (USB_CONFIG_DESCR shl 24)       ; descriptor type
738
        and     dword [eax+4], 0
739
        mov     word [eax+6], dx        ; data length
740
        stdcall usb_control_async, [pipe], eax, eax, edx, usb_set_config_callback, eax, 0
741
.nothing:
742
; 5. Return.
743
        pop     ebx             ; restore used registers to be stdcall
744
        ret
745
.error:
746
        dbgstr 'error with USB configuration descriptor'
747
        jmp     .nothing
748
.nomemory:
749
        dbgstr 'No memory for device data'
750
        jmp     .nothing
751
endp
752
 
753
; This procedure is called by USB stack when GET_DESCRIPTOR(CONFIGURATION)
754
; request initiated by usb_know_length_callback is completed,
755
; either successfully or unsuccessfully.
756
proc usb_set_config_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword
757
; Note that the prolog is the same as in usb_know_length_callback.
758
        push    ebx             ; save used registers to be stdcall
759
; 1. Check whether the operation was successful.
760
; If not, say something to the debug board and stop the initialization.
761
        xor     ecx, ecx
762
        mov     ebx, [pipe]
763
        cmp     [status], ecx
764
        jnz     usb_know_length_callback.error
765
; The full descriptor is known, dump it if specified by compile-time option.
766
if USB_DUMP_DESCRIPTORS
767
        mov     eax, [buffer]
768
        mov     ecx, [length]
769
        sub     ecx, 8
770
        jbe     .skip_debug
771
        DEBUGF 1,'K : config descriptor:'
772
@@:
773
        DEBUGF 1,' %x',[eax]:2
774
        inc     eax
775
        dec     ecx
776
        jnz     @b
777
        DEBUGF 1,'\n'
778
.skip_debug:
779
        xor     ecx, ecx
780
end if
781
; 2. Issue control transfer SET_CONFIGURATION to activate this configuration.
782
; Usually this is the only configuration.
783
; Use extra bytes allocated by usb_know_length_callback;
784
; offset from device data start is stored in Interfaces.
785
        mov     eax, [ebx+usb_pipe.DeviceData]
786
        mov     edx, [buffer]
787
        add     eax, [eax+usb_device_data.Interfaces]
788
        mov     dl, [edx+usb_config_descr.bConfigurationValue]
789
        mov     dword [eax], USB_SET_CONFIGURATION shl 8
790
        mov     dword [eax+4], ecx
791
        mov     byte [eax+2], dl
792
        stdcall usb_control_async, [pipe], eax, ecx, ecx, usb_got_config_callback, [buffer], ecx
793
        pop     ebx             ; restore used registers to be stdcall
794
        ret
795
endp
796
 
797
; This procedure is called by USB stack when SET_CONFIGURATION
798
; request initiated by usb_set_config_callback is completed,
799
; either successfully or unsuccessfully.
800
; If successfully, the device is configured and ready to work,
801
; pass the device to the corresponding driver(s).
802
proc usb_got_config_callback stdcall, pipe:dword, status:dword, buffer:dword, length:dword, calldata:dword
803
locals
804
InterfacesData  dd      ?
805
NumInterfaces   dd      ?
806
driver          dd      ?
807
endl
808
; 1. If there was an error, say something to the debug board and stop the
809
; initialization.
810
        cmp     [status], 0
811
        jz      @f
812
        dbgstr 'USB error in SET_CONFIGURATION'
813
        ret
814
@@:
815
        push    ebx edi         ; save used registers to be stdcall
816
; 2. Sanity checks: the total length must be the same as before (because we
817
; have allocated memory assuming the old value), length of config descriptor
818
; must be at least sizeof.usb_config_descr (we use fields from it),
819
; there must be at least one interface.
820
        mov     ebx, [pipe]
821
        mov     ebx, [ebx+usb_pipe.DeviceData]
822
        mov     eax, [calldata]
823
        mov     edx, [ebx+usb_device_data.ConfigDataSize]
824
        cmp     [eax+usb_config_descr.wTotalLength], dx
825
        jnz     .invalid
826
        cmp     [eax+usb_config_descr.bLength], 9
827
        jb      .invalid
828
        movzx   edx, [eax+usb_config_descr.bNumInterfaces]
829
        test    edx, edx
830
        jnz     @f
831
.invalid:
832
        dbgstr 'error: invalid configuration descriptor'
833
        jmp     .nothing
834
@@:
835
; 3. Store the number of interfaces in device data structure.
3908 Serge 836
        mov     [ebx+usb_device_data.NumInterfaces], edx
3555 Serge 837
; 4. If there is only one interface (which happens quite often),
838
; the memory allocated in usb_know_length_callback is sufficient.
839
; Otherwise (which also happens quite often), reallocate device data.
840
; 4a. Check whether there is only one interface. If so, skip this step.
841
        cmp     edx, 1
842
        jz      .has_memory
843
; 4b. Allocate new memory.
844
        mov     eax, [ebx+usb_device_data.Interfaces]
845
        lea     eax, [eax+edx*sizeof.usb_interface_data]
846
        call    malloc
847
; 4c. If failed, say something to the debug board and
848
; stop the initialization.
849
        test    eax, eax
850
        jnz     @f
851
        dbgstr 'No memory for device data'
852
        jmp     .nothing
853
@@:
854
; 4d. Copy data from old memory to new memory and switch the pointer in usb_pipe.
855
        push    eax
856
        push    esi
857
        mov     ebx, [pipe]
858
        mov     edi, eax
859
        mov     esi, [ebx+usb_pipe.DeviceData]
860
        mov     [ebx+usb_pipe.DeviceData], eax
861
        mov     eax, esi
862
        mov     ecx, [esi+usb_device_data.Interfaces]
863
        shr     ecx, 2
864
        rep movsd
865
        pop     esi
866
        call    usb_reinit_pipe_list
867
; 4e. Free old memory.
868
        call    free
869
        pop     ebx
870
.has_memory:
871
; 5. Initialize interfaces table: zero all contents.
872
        mov     edi, [ebx+usb_device_data.Interfaces]
873
        add     edi, ebx
874
        mov     [InterfacesData], edi
3908 Serge 875
        mov     ecx, [ebx+usb_device_data.NumInterfaces]
3555 Serge 876
if sizeof.usb_interface_data <> 8
877
You have changed sizeof.usb_interface_data? Modify this place too.
878
end if
879
        add     ecx, ecx
880
        xor     eax, eax
881
        rep stosd
882
; No interfaces are found yet.
883
        mov     [NumInterfaces], eax
884
; 6. Get the pointer to config descriptor data.
885
; Note: if there was reallocation, [buffer] is not valid anymore,
886
; so calculate value based on usb_device_data.
887
        movzx   eax, [ebx+usb_device_data.DeviceDescrSize]
888
        lea     eax, [eax+ebx+sizeof.usb_device_data]
889
        mov     [calldata], eax
890
        mov     ecx, [ebx+usb_device_data.ConfigDataSize]
891
; 7. Loop over all descriptors,
892
; scan for interface descriptors with bAlternateSetting = 0,
893
; load the corresponding driver, call its AddDevice function.
894
.descriptor_loop:
895
; While in loop: eax points to the current descriptor,
896
; ecx = number of bytes left, the iteration starts only if ecx is nonzero,
897
; edx = size of the current descriptor.
898
; 7a. The first byte is always accessible; it contains the length of
899
; the current descriptor. Validate that the length is at least 2 bytes,
900
; and the entire descriptor is readable (the length is at most number of
901
; bytes left).
902
        movzx   edx, [eax+usb_descr.bLength]
903
        cmp     edx, sizeof.usb_descr
904
        jb      .invalid
905
        cmp     ecx, edx
906
        jb      .invalid
907
; 7b. Check descriptor type. Ignore all non-INTERFACE descriptor.
908
        cmp     byte [eax+usb_descr.bDescriptorType], USB_INTERFACE_DESCR
909
        jz      .interface
910
.next_descriptor:
911
; 7c. Advance pointer, decrease length left, if there is still something left,
912
; continue the loop.
913
        add     eax, edx
914
        sub     ecx, edx
915
        jnz     .descriptor_loop
916
.done:
917
.nothing:
918
        pop     edi ebx         ; restore used registers to be stdcall
919
        ret
920
.interface:
921
; 7d. Validate the descriptor length.
922
        cmp     edx, sizeof.usb_interface_descr
923
        jb      .next_descriptor
924
; 7e. If bAlternateSetting is nonzero, this descriptor actually describes
925
; another mode of already known interface and belongs to the already loaded
926
; driver; amuse the user and continue to 7c.
927
        cmp     byte [eax+usb_interface_descr.bAlternateSetting], 0
928
        jz      @f
929
        DEBUGF 1,'K : note: alternate setting with %x/%x/%x\n',\
930
                [eax+usb_interface_descr.bInterfaceClass]:2,\
931
                [eax+usb_interface_descr.bInterfaceSubClass]:2,\
932
                [eax+usb_interface_descr.bInterfaceProtocol]:2
933
        jmp     .next_descriptor
934
@@:
935
; 7f. Check that the new interface does not overflow allocated table.
936
        mov     edx, [NumInterfaces]
3908 Serge 937
        inc     edx
938
        cmp     edx, [ebx+usb_device_data.NumInterfaces]
3555 Serge 939
        ja      .invalid
940
; 7g. We have found a new interface. Advance bookkeeping vars.
941
        mov     [NumInterfaces], edx
942
        add     [InterfacesData], sizeof.usb_interface_data
943
; 7h. Save length left and pointer to the current interface descriptor.
944
        push    ecx eax
945
; Amuse the user if she is watching the debug board.
946
        DEBUGF 1,'K : USB interface class/subclass/protocol = %x/%x/%x\n',\
947
                [eax+usb_interface_descr.bInterfaceClass]:2,\
948
                [eax+usb_interface_descr.bInterfaceSubClass]:2,\
949
                [eax+usb_interface_descr.bInterfaceProtocol]:2
950
; 7i. Select the correct driver based on interface class.
951
; For hubs, go to 7j. Otherwise, go to 7k.
952
; Note: this should be rewritten as table-based lookup when more drivers will
953
; be available.
954
        cmp     byte [eax+usb_interface_descr.bInterfaceClass], 9
955
        jz      .found_hub
956
        mov     edx, usb_hid_name
957
        cmp     byte [eax+usb_interface_descr.bInterfaceClass], 3
958
        jz      .load_driver
959
        mov     edx, usb_print_name
960
        cmp     byte [eax+usb_interface_descr.bInterfaceClass], 7
961
        jz      .load_driver
962
        mov     edx, usb_stor_name
963
        cmp     byte [eax+usb_interface_descr.bInterfaceClass], 8
964
        jz      .load_driver
965
        mov     edx, usb_other_name
966
        jmp     .load_driver
967
.found_hub:
968
; 7j. Hubs are a part of USB stack, thus, integrated into the kernel.
969
; Use the pointer to hub callbacks and go to 7m.
970
        mov     eax, usb_hub_pseudosrv - USBSRV.usb_func
971
        jmp     .driver_loaded
972
.load_driver:
973
; 7k. Load the corresponding driver.
974
        push    ebx esi edi
975
        stdcall get_service, edx
976
        pop     edi esi ebx
977
; 7l. If failed, say something to the debug board and go to 7p.
978
        test    eax, eax
979
        jnz     .driver_loaded
980
        dbgstr 'failed to load class driver'
981
        jmp     .next_descriptor2
982
.driver_loaded:
983
; 7m. Call AddDevice function of the driver.
984
; Note that top of stack contains a pointer to the current interface,
985
; saved by step 7h.
986
        mov     [driver], eax
987
        mov     eax, [eax+USBSRV.usb_func]
988
        pop     edx
989
        push    edx
990
; Note: usb_hub_init assumes that edx points to usb_interface_descr,
991
; ecx = length rest; if you change the code, modify usb_hub_init also.
992
        stdcall [eax+USBFUNC.add_device], [pipe], [calldata], edx
993
; 7n. If failed, say something to the debug board and go to 7p.
994
        test    eax, eax
995
        jnz     .store_data
996
        dbgstr 'USB device initialization failed'
997
        jmp     .next_descriptor2
998
.store_data:
999
; 7o. Store the returned value and the driver handle to InterfacesData.
1000
; Note that step 7g has already advanced InterfacesData.
1001
        mov     edx, [InterfacesData]
1002
        mov     [edx+usb_interface_data.DriverData-sizeof.usb_interface_data], eax
1003
        mov     eax, [driver]
1004
        mov     [edx+usb_interface_data.DriverFunc-sizeof.usb_interface_data], eax
1005
.next_descriptor2:
1006
; 7p. Restore registers saved in step 7h, get the descriptor length and
1007
; continue to 7c.
1008
        pop     eax ecx
1009
        movzx   edx, byte [eax+usb_descr.bLength]
1010
        jmp     .next_descriptor
1011
endp
1012
 
1013
; Driver names, see step 7i of usb_got_config_callback.
1014
iglobal
1015
usb_hid_name    db      'usbhid',0
1016
usb_stor_name   db      'usbstor',0
1017
usb_print_name  db      'usbprint',0
1018
usb_other_name  db      'usbother',0
1019
endg