forked from KolibriOS/kolibrios
sanity check: avoid infinitely nested hubs
git-svn-id: svn://kolibrios.org@4302 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
ea362458cb
commit
10242c9784
@ -219,30 +219,46 @@ virtual at esp
|
||||
.config dd ? ; pointer to usb_config_descr
|
||||
.interface dd ? ; pointer to usb_interface_descr
|
||||
end virtual
|
||||
; 1. Check that the maximal nesting is not exceeded:
|
||||
; 5 non-root hubs is the maximum according to the spec.
|
||||
mov ebx, [.pipe]
|
||||
movi ecx, 5
|
||||
mov eax, ebx
|
||||
.count_parents:
|
||||
mov eax, [eax+usb_pipe.DeviceData]
|
||||
mov eax, [eax+usb_device_data.Hub]
|
||||
test eax, eax
|
||||
jz .depth_ok
|
||||
mov eax, [eax+usb_hub.ConfigPipe]
|
||||
dec ecx
|
||||
jnz .count_parents
|
||||
dbgstr 'Hub chain is too long'
|
||||
jmp .return0
|
||||
.depth_ok:
|
||||
; Hubs use one IN interrupt endpoint for polling the device
|
||||
; 1. Locate the descriptor of the interrupt endpoint.
|
||||
; 2. Locate the descriptor of the interrupt endpoint.
|
||||
; Loop over all descriptors owned by this interface.
|
||||
.lookep:
|
||||
; 1a. Skip the current descriptor.
|
||||
; 2a. Skip the current descriptor.
|
||||
movzx eax, [edx+usb_descr.bLength]
|
||||
add edx, eax
|
||||
sub ecx, eax
|
||||
jb .errorep
|
||||
; 1b. Length of data left must be at least sizeof.usb_endpoint_descr.
|
||||
; 2b. Length of data left must be at least sizeof.usb_endpoint_descr.
|
||||
cmp ecx, sizeof.usb_endpoint_descr
|
||||
jb .errorep
|
||||
; 1c. If we have found another interface descriptor but not found our endpoint,
|
||||
; 2c. If we have found another interface descriptor but not found our endpoint,
|
||||
; this is an error: all subsequent descriptors belong to that interface
|
||||
; (or further interfaces).
|
||||
cmp [edx+usb_endpoint_descr.bDescriptorType], USB_INTERFACE_DESCR
|
||||
jz .errorep
|
||||
; 1d. Ignore all interface-related descriptors except endpoint descriptor.
|
||||
; 2d. Ignore all interface-related descriptors except endpoint descriptor.
|
||||
cmp [edx+usb_endpoint_descr.bDescriptorType], USB_ENDPOINT_DESCR
|
||||
jnz .lookep
|
||||
; 1e. Length of endpoint descriptor must be at least sizeof.usb_endpoint_descr.
|
||||
; 2e. Length of endpoint descriptor must be at least sizeof.usb_endpoint_descr.
|
||||
cmp [edx+usb_endpoint_descr.bLength], sizeof.usb_endpoint_descr
|
||||
jb .errorep
|
||||
; 1f. Ignore all endpoints except for INTERRUPT IN.
|
||||
; 2f. Ignore all endpoints except for INTERRUPT IN.
|
||||
cmp [edx+usb_endpoint_descr.bEndpointAddress], 0
|
||||
jge .lookep
|
||||
mov al, [edx+usb_endpoint_descr.bmAttributes]
|
||||
@ -251,23 +267,22 @@ end virtual
|
||||
jnz .lookep
|
||||
; We have located the descriptor for INTERRUPT IN endpoint,
|
||||
; the pointer is in edx.
|
||||
; 2. Allocate memory for the hub descriptor.
|
||||
; 3. Allocate memory for the hub descriptor.
|
||||
; Maximum length (assuming 255 downstream ports) is 40 bytes.
|
||||
; Allocate 4 extra bytes to keep wMaxPacketSize.
|
||||
; 2a. Save registers.
|
||||
; 3a. Save registers.
|
||||
push edx
|
||||
; 2b. Call the allocator.
|
||||
; 3b. Call the allocator.
|
||||
movi eax, 44
|
||||
call malloc
|
||||
; 2c. Restore registers.
|
||||
; 3c. Restore registers.
|
||||
pop ecx
|
||||
; 2d. If failed, say something to the debug board and return error.
|
||||
; 3d. If failed, say something to the debug board and return error.
|
||||
test eax, eax
|
||||
jz .nomemory
|
||||
; 2e. Store the pointer in esi. xchg eax,r32 is one byte shorter than mov.
|
||||
; 3e. Store the pointer in esi. xchg eax,r32 is one byte shorter than mov.
|
||||
xchg esi, eax
|
||||
; 3. Open a pipe for the status endpoint with descriptor found in step 1.
|
||||
mov ebx, [.pipe]
|
||||
; 4. Open a pipe for the status endpoint with descriptor found in step 1.
|
||||
movzx eax, [ecx+usb_endpoint_descr.bEndpointAddress]
|
||||
movzx edx, [ecx+usb_endpoint_descr.bInterval]
|
||||
movzx ecx, [ecx+usb_endpoint_descr.wMaxPacketSize]
|
||||
@ -276,11 +291,11 @@ end virtual
|
||||
push ecx
|
||||
stdcall usb_open_pipe, ebx, eax, ecx, INTERRUPT_PIPE, edx
|
||||
pop ecx
|
||||
; If failed, free the memory allocated in step 2,
|
||||
; If failed, free the memory allocated in step 3,
|
||||
; say something to the debug board and return error.
|
||||
test eax, eax
|
||||
jz .free
|
||||
; 4. Send control query for the hub descriptor,
|
||||
; 5. Send control query for the hub descriptor,
|
||||
; pass status pipe as a callback parameter,
|
||||
; allow short packets.
|
||||
and ecx, (1 shl 11) - 1
|
||||
@ -291,7 +306,7 @@ end virtual
|
||||
(USB_HUB_DESCRIPTOR shl 24)
|
||||
mov dword [esi+4], 40 shl 16
|
||||
stdcall usb_control_async, ebx, esi, esi, 40, usb_hub_got_config, eax, 1
|
||||
; 5. If failed, free the memory allocated in step 2,
|
||||
; 6. If failed, free the memory allocated in step 3,
|
||||
; say something to the debug board and return error.
|
||||
test eax, eax
|
||||
jz .free
|
||||
|
Loading…
Reference in New Issue
Block a user