Subversion Repositories Kolibri OS

Rev

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

Rev 4265 Rev 4423
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
        push    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     dword [esp]
-
 
234
        jnz     .count_parents
-
 
235
        pop     eax
-
 
236
        dbgstr 'Hub chain is too long'
-
 
237
        jmp     .return0
-
 
238
.depth_ok:
-
 
239
        pop     eax
222
; Hubs use one IN interrupt endpoint for polling the device
240
; Hubs use one IN interrupt endpoint for polling the device
223
; 1. Locate the descriptor of the interrupt endpoint.
241
; 2. Locate the descriptor of the interrupt endpoint.
224
; Loop over all descriptors owned by this interface.
242
; Loop over all descriptors owned by this interface.
225
.lookep:
243
.lookep:
226
; 1a. Skip the current descriptor.
244
; 2a. Skip the current descriptor.
227
        movzx   eax, [edx+usb_descr.bLength]
245
        movzx   eax, [edx+usb_descr.bLength]
228
        add     edx, eax
246
        add     edx, eax
229
        sub     ecx, eax
247
        sub     ecx, eax
230
        jb      .errorep
248
        jb      .errorep
231
; 1b. Length of data left must be at least sizeof.usb_endpoint_descr.
249
; 2b. Length of data left must be at least sizeof.usb_endpoint_descr.
232
        cmp     ecx, sizeof.usb_endpoint_descr
250
        cmp     ecx, sizeof.usb_endpoint_descr
233
        jb      .errorep
251
        jb      .errorep
234
; 1c. If we have found another interface descriptor but not found our endpoint,
252
; 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
253
; this is an error: all subsequent descriptors belong to that interface
236
; (or further interfaces).
254
; (or further interfaces).
237
        cmp     [edx+usb_endpoint_descr.bDescriptorType], USB_INTERFACE_DESCR
255
        cmp     [edx+usb_endpoint_descr.bDescriptorType], USB_INTERFACE_DESCR
238
        jz      .errorep
256
        jz      .errorep
239
; 1d. Ignore all interface-related descriptors except endpoint descriptor.
257
; 2d. Ignore all interface-related descriptors except endpoint descriptor.
240
        cmp     [edx+usb_endpoint_descr.bDescriptorType], USB_ENDPOINT_DESCR
258
        cmp     [edx+usb_endpoint_descr.bDescriptorType], USB_ENDPOINT_DESCR
241
        jnz     .lookep
259
        jnz     .lookep
242
; 1e. Length of endpoint descriptor must be at least sizeof.usb_endpoint_descr.
260
; 2e. Length of endpoint descriptor must be at least sizeof.usb_endpoint_descr.
243
        cmp     [edx+usb_endpoint_descr.bLength], sizeof.usb_endpoint_descr
261
        cmp     [edx+usb_endpoint_descr.bLength], sizeof.usb_endpoint_descr
244
        jb      .errorep
262
        jb      .errorep
245
; 1f. Ignore all endpoints except for INTERRUPT IN.
263
; 2f. Ignore all endpoints except for INTERRUPT IN.
246
        cmp     [edx+usb_endpoint_descr.bEndpointAddress], 0
264
        cmp     [edx+usb_endpoint_descr.bEndpointAddress], 0
247
        jge     .lookep
265
        jge     .lookep
248
        mov     al, [edx+usb_endpoint_descr.bmAttributes]
266
        mov     al, [edx+usb_endpoint_descr.bmAttributes]
249
        and     al, 3
267
        and     al, 3
250
        cmp     al, INTERRUPT_PIPE
268
        cmp     al, INTERRUPT_PIPE
251
        jnz     .lookep
269
        jnz     .lookep
252
; We have located the descriptor for INTERRUPT IN endpoint,
270
; We have located the descriptor for INTERRUPT IN endpoint,
253
; the pointer is in edx.
271
; the pointer is in edx.
254
; 2. Allocate memory for the hub descriptor.
272
; 3. Allocate memory for the hub descriptor.
255
; Maximum length (assuming 255 downstream ports) is 40 bytes.
273
; Maximum length (assuming 255 downstream ports) is 40 bytes.
256
; Allocate 4 extra bytes to keep wMaxPacketSize.
274
; Allocate 4 extra bytes to keep wMaxPacketSize.
257
; 2a. Save registers.
275
; 3a. Save registers.
258
        push    edx
276
        push    edx
259
; 2b. Call the allocator.
277
; 3b. Call the allocator.
260
        movi    eax, 44
278
        movi    eax, 44
261
        call    malloc
279
        call    malloc
262
; 2c. Restore registers.
280
; 3c. Restore registers.
263
        pop     ecx
281
        pop     ecx
264
; 2d. If failed, say something to the debug board and return error.
282
; 3d. If failed, say something to the debug board and return error.
265
        test    eax, eax
283
        test    eax, eax
266
        jz      .nomemory
284
        jz      .nomemory
267
; 2e. Store the pointer in esi. xchg eax,r32 is one byte shorter than mov.
285
; 3e. Store the pointer in esi. xchg eax,r32 is one byte shorter than mov.
268
        xchg    esi, eax
286
        xchg    esi, eax
269
; 3. Open a pipe for the status endpoint with descriptor found in step 1.
287
; 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]
288
        movzx   eax, [ecx+usb_endpoint_descr.bEndpointAddress]
272
        movzx   edx, [ecx+usb_endpoint_descr.bInterval]
289
        movzx   edx, [ecx+usb_endpoint_descr.bInterval]
273
        movzx   ecx, [ecx+usb_endpoint_descr.wMaxPacketSize]
290
        movzx   ecx, [ecx+usb_endpoint_descr.wMaxPacketSize]
274
        test    ecx, (1 shl 11) - 1
291
        test    ecx, (1 shl 11) - 1
275
        jz      .free
292
        jz      .free
276
        push    ecx
293
        push    ecx
277
        stdcall usb_open_pipe, ebx, eax, ecx, INTERRUPT_PIPE, edx
294
        stdcall usb_open_pipe, ebx, eax, ecx, INTERRUPT_PIPE, edx
278
        pop     ecx
295
        pop     ecx
279
; If failed, free the memory allocated in step 2,
296
; If failed, free the memory allocated in step 3,
280
; say something to the debug board and return error.
297
; say something to the debug board and return error.
281
        test    eax, eax
298
        test    eax, eax
282
        jz      .free
299
        jz      .free
283
; 4. Send control query for the hub descriptor,
300
; 5. Send control query for the hub descriptor,
284
; pass status pipe as a callback parameter,
301
; pass status pipe as a callback parameter,
285
; allow short packets.
302
; allow short packets.
286
        and     ecx, (1 shl 11) - 1
303
        and     ecx, (1 shl 11) - 1
287
        mov     [esi+40], ecx
304
        mov     [esi+40], ecx
288
        mov     dword [esi], 0xA0 + \   ; class-specific request
305
        mov     dword [esi], 0xA0 + \   ; class-specific request
289
                (USB_GET_DESCRIPTOR shl 8) + \
306
                (USB_GET_DESCRIPTOR shl 8) + \
290
                (0 shl 16) + \          ; descriptor index 0
307
                (0 shl 16) + \          ; descriptor index 0
291
                (USB_HUB_DESCRIPTOR shl 24)
308
                (USB_HUB_DESCRIPTOR shl 24)
292
        mov     dword [esi+4], 40 shl 16
309
        mov     dword [esi+4], 40 shl 16
293
        stdcall usb_control_async, ebx, esi, esi, 40, usb_hub_got_config, eax, 1
310
        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,
311
; 6. If failed, free the memory allocated in step 3,
295
; say something to the debug board and return error.
312
; say something to the debug board and return error.
296
        test    eax, eax
313
        test    eax, eax
297
        jz      .free
314
        jz      .free
298
; Otherwise, return 1. usb_hub_got_config will overwrite it later.
315
; Otherwise, return 1. usb_hub_got_config will overwrite it later.
299
        xor     eax, eax
316
        xor     eax, eax
Line 1243... Line 1260...
1243
        call    free
1260
        call    free
1244
        pop     ebx
1261
        pop     ebx
1245
.nothing:
1262
.nothing:
1246
        retn    4
1263
        retn    4
1247
endp
1264
endp
-
 
1265
 
-
 
1266
; Helper function for USB2 scheduler.
-
 
1267
; in: eax -> usb_hub
-
 
1268
; out: ecx = TT think time for the hub in FS-bytes
-
 
1269
proc usb_get_tt_think_time
-
 
1270
        movzx   ecx, [eax+usb_hub.HubCharacteristics]
-
 
1271
        shr     ecx, 5
-
 
1272
        and     ecx, 3
-
 
1273
        inc     ecx
-
 
1274
        ret
-
 
1275
endp