Subversion Repositories Kolibri OS

Rev

Rev 4227 | Rev 4305 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4227 Rev 4302
Line 217... Line 217...
217
                dd      ?       ; return address
217
                dd      ?       ; return address
218
.pipe           dd      ?       ; handle of the config pipe
218
.pipe           dd      ?       ; handle of the config pipe
219
.config         dd      ?       ; pointer to usb_config_descr
219
.config         dd      ?       ; pointer to usb_config_descr
220
.interface      dd      ?       ; pointer to usb_interface_descr
220
.interface      dd      ?       ; pointer to usb_interface_descr
221
end virtual
221
end virtual
-
 
222
; 1. Check that the maximal nesting is not exceeded:
-
 
223
; 5 non-root hubs is the maximum according to the spec.
-
 
224
        mov     ebx, [.pipe]
-
 
225
        movi    ecx, 5
-
 
226
        mov     eax, ebx
-
 
227
.count_parents:
-
 
228
        mov     eax, [eax+usb_pipe.DeviceData]
-
 
229
        mov     eax, [eax+usb_device_data.Hub]
-
 
230
        test    eax, eax
-
 
231
        jz      .depth_ok
-
 
232
        mov     eax, [eax+usb_hub.ConfigPipe]
-
 
233
        dec     ecx
-
 
234
        jnz     .count_parents
-
 
235
        dbgstr 'Hub chain is too long'
-
 
236
        jmp     .return0
-
 
237
.depth_ok:
222
; Hubs use one IN interrupt endpoint for polling the device
238
; Hubs use one IN interrupt endpoint for polling the device
223
; 1. Locate the descriptor of the interrupt endpoint.
239
; 2. Locate the descriptor of the interrupt endpoint.
224
; Loop over all descriptors owned by this interface.
240
; Loop over all descriptors owned by this interface.
225
.lookep:
241
.lookep:
226
; 1a. Skip the current descriptor.
242
; 2a. Skip the current descriptor.
227
        movzx   eax, [edx+usb_descr.bLength]
243
        movzx   eax, [edx+usb_descr.bLength]
228
        add     edx, eax
244
        add     edx, eax
229
        sub     ecx, eax
245
        sub     ecx, eax
230
        jb      .errorep
246
        jb      .errorep
231
; 1b. Length of data left must be at least sizeof.usb_endpoint_descr.
247
; 2b. Length of data left must be at least sizeof.usb_endpoint_descr.
232
        cmp     ecx, sizeof.usb_endpoint_descr
248
        cmp     ecx, sizeof.usb_endpoint_descr
233
        jb      .errorep
249
        jb      .errorep
234
; 1c. If we have found another interface descriptor but not found our endpoint,
250
; 2c. If we have found another interface descriptor but not found our endpoint,
235
; this is an error: all subsequent descriptors belong to that interface
251
; this is an error: all subsequent descriptors belong to that interface
236
; (or further interfaces).
252
; (or further interfaces).
237
        cmp     [edx+usb_endpoint_descr.bDescriptorType], USB_INTERFACE_DESCR
253
        cmp     [edx+usb_endpoint_descr.bDescriptorType], USB_INTERFACE_DESCR
238
        jz      .errorep
254
        jz      .errorep
239
; 1d. Ignore all interface-related descriptors except endpoint descriptor.
255
; 2d. Ignore all interface-related descriptors except endpoint descriptor.
240
        cmp     [edx+usb_endpoint_descr.bDescriptorType], USB_ENDPOINT_DESCR
256
        cmp     [edx+usb_endpoint_descr.bDescriptorType], USB_ENDPOINT_DESCR
241
        jnz     .lookep
257
        jnz     .lookep
242
; 1e. Length of endpoint descriptor must be at least sizeof.usb_endpoint_descr.
258
; 2e. Length of endpoint descriptor must be at least sizeof.usb_endpoint_descr.
243
        cmp     [edx+usb_endpoint_descr.bLength], sizeof.usb_endpoint_descr
259
        cmp     [edx+usb_endpoint_descr.bLength], sizeof.usb_endpoint_descr
244
        jb      .errorep
260
        jb      .errorep
245
; 1f. Ignore all endpoints except for INTERRUPT IN.
261
; 2f. Ignore all endpoints except for INTERRUPT IN.
246
        cmp     [edx+usb_endpoint_descr.bEndpointAddress], 0
262
        cmp     [edx+usb_endpoint_descr.bEndpointAddress], 0
247
        jge     .lookep
263
        jge     .lookep
248
        mov     al, [edx+usb_endpoint_descr.bmAttributes]
264
        mov     al, [edx+usb_endpoint_descr.bmAttributes]
249
        and     al, 3
265
        and     al, 3
250
        cmp     al, INTERRUPT_PIPE
266
        cmp     al, INTERRUPT_PIPE
251
        jnz     .lookep
267
        jnz     .lookep
252
; We have located the descriptor for INTERRUPT IN endpoint,
268
; We have located the descriptor for INTERRUPT IN endpoint,
253
; the pointer is in edx.
269
; the pointer is in edx.
254
; 2. Allocate memory for the hub descriptor.
270
; 3. Allocate memory for the hub descriptor.
255
; Maximum length (assuming 255 downstream ports) is 40 bytes.
271
; Maximum length (assuming 255 downstream ports) is 40 bytes.
256
; Allocate 4 extra bytes to keep wMaxPacketSize.
272
; Allocate 4 extra bytes to keep wMaxPacketSize.
257
; 2a. Save registers.
273
; 3a. Save registers.
258
        push    edx
274
        push    edx
259
; 2b. Call the allocator.
275
; 3b. Call the allocator.
260
        movi    eax, 44
276
        movi    eax, 44
261
        call    malloc
277
        call    malloc
262
; 2c. Restore registers.
278
; 3c. Restore registers.
263
        pop     ecx
279
        pop     ecx
264
; 2d. If failed, say something to the debug board and return error.
280
; 3d. If failed, say something to the debug board and return error.
265
        test    eax, eax
281
        test    eax, eax
266
        jz      .nomemory
282
        jz      .nomemory
267
; 2e. Store the pointer in esi. xchg eax,r32 is one byte shorter than mov.
283
; 3e. Store the pointer in esi. xchg eax,r32 is one byte shorter than mov.
268
        xchg    esi, eax
284
        xchg    esi, eax
269
; 3. Open a pipe for the status endpoint with descriptor found in step 1.
285
; 4. Open a pipe for the status endpoint with descriptor found in step 1.
270
        mov     ebx, [.pipe]
-
 
271
        movzx   eax, [ecx+usb_endpoint_descr.bEndpointAddress]
286
        movzx   eax, [ecx+usb_endpoint_descr.bEndpointAddress]
272
        movzx   edx, [ecx+usb_endpoint_descr.bInterval]
287
        movzx   edx, [ecx+usb_endpoint_descr.bInterval]
273
        movzx   ecx, [ecx+usb_endpoint_descr.wMaxPacketSize]
288
        movzx   ecx, [ecx+usb_endpoint_descr.wMaxPacketSize]
274
        test    ecx, (1 shl 11) - 1
289
        test    ecx, (1 shl 11) - 1
275
        jz      .free
290
        jz      .free
276
        push    ecx
291
        push    ecx
277
        stdcall usb_open_pipe, ebx, eax, ecx, INTERRUPT_PIPE, edx
292
        stdcall usb_open_pipe, ebx, eax, ecx, INTERRUPT_PIPE, edx
278
        pop     ecx
293
        pop     ecx
279
; If failed, free the memory allocated in step 2,
294
; If failed, free the memory allocated in step 3,
280
; say something to the debug board and return error.
295
; say something to the debug board and return error.
281
        test    eax, eax
296
        test    eax, eax
282
        jz      .free
297
        jz      .free
283
; 4. Send control query for the hub descriptor,
298
; 5. Send control query for the hub descriptor,
284
; pass status pipe as a callback parameter,
299
; pass status pipe as a callback parameter,
285
; allow short packets.
300
; allow short packets.
286
        and     ecx, (1 shl 11) - 1
301
        and     ecx, (1 shl 11) - 1
287
        mov     [esi+40], ecx
302
        mov     [esi+40], ecx
288
        mov     dword [esi], 0xA0 + \   ; class-specific request
303
        mov     dword [esi], 0xA0 + \   ; class-specific request
289
                (USB_GET_DESCRIPTOR shl 8) + \
304
                (USB_GET_DESCRIPTOR shl 8) + \
290
                (0 shl 16) + \          ; descriptor index 0
305
                (0 shl 16) + \          ; descriptor index 0
291
                (USB_HUB_DESCRIPTOR shl 24)
306
                (USB_HUB_DESCRIPTOR shl 24)
292
        mov     dword [esi+4], 40 shl 16
307
        mov     dword [esi+4], 40 shl 16
293
        stdcall usb_control_async, ebx, esi, esi, 40, usb_hub_got_config, eax, 1
308
        stdcall usb_control_async, ebx, esi, esi, 40, usb_hub_got_config, eax, 1
294
; 5. If failed, free the memory allocated in step 2,
309
; 6. If failed, free the memory allocated in step 3,
295
; say something to the debug board and return error.
310
; say something to the debug board and return error.
296
        test    eax, eax
311
        test    eax, eax
297
        jz      .free
312
        jz      .free
298
; Otherwise, return 1. usb_hub_got_config will overwrite it later.
313
; Otherwise, return 1. usb_hub_got_config will overwrite it later.
299
        xor     eax, eax
314
        xor     eax, eax