mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-12-26 00:26:52 +03:00
r3711 continued, no binary changes
git-svn-id: svn://kolibrios.org@3726 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
38f0b2a169
commit
436a7c0974
@ -74,15 +74,15 @@ ends
|
||||
|
||||
; USB HID structures
|
||||
struct hid_descr
|
||||
bLength db ?
|
||||
bDescriptorType db ?
|
||||
bcdHID dw ?
|
||||
bCountryCode db ?
|
||||
bNumDescriptors db ?
|
||||
base_sizeof rb 0
|
||||
bLength db ?
|
||||
bDescriptorType db ?
|
||||
bcdHID dw ?
|
||||
bCountryCode db ?
|
||||
bNumDescriptors db ?
|
||||
base_sizeof rb 0
|
||||
; now two fields are repeated .bNumDescriptors times:
|
||||
subDescriptorType db ?
|
||||
subDescriptorLength dw ?
|
||||
subDescriptorType db ?
|
||||
subDescriptorLength dw ?
|
||||
ends
|
||||
|
||||
; Include macro for parsing report descriptors/data.
|
||||
@ -92,23 +92,23 @@ include 'report.inc'
|
||||
|
||||
; Driver data for all devices
|
||||
struct usb_device_data
|
||||
hid hid_data ; data of HID layer
|
||||
epdescr dd ? ; endpoint descriptor
|
||||
hiddescr dd ? ; HID descriptor
|
||||
interface_number dd ? ; copy of interface_descr.bInterfaceNumber
|
||||
configpipe dd ? ; config pipe handle
|
||||
intpipe dd ? ; interrupt pipe handle
|
||||
input_transfer_size dd ? ; input transfer size
|
||||
input_buffer dd ? ; buffer for input transfers
|
||||
control rb 8 ; control packet to device
|
||||
hid hid_data ; data of HID layer
|
||||
epdescr dd ? ; endpoint descriptor
|
||||
hiddescr dd ? ; HID descriptor
|
||||
interface_number dd ? ; copy of interface_descr.bInterfaceNumber
|
||||
configpipe dd ? ; config pipe handle
|
||||
intpipe dd ? ; interrupt pipe handle
|
||||
input_transfer_size dd ? ; input transfer size
|
||||
input_buffer dd ? ; buffer for input transfers
|
||||
control rb 8 ; control packet to device
|
||||
ends
|
||||
|
||||
section '.flat' code readable align 16
|
||||
; The start procedure.
|
||||
proc START
|
||||
virtual at esp
|
||||
dd ? ; return address
|
||||
.reason dd ?
|
||||
dd ? ; return address
|
||||
.reason dd ?
|
||||
end virtual
|
||||
; 1. Test whether the procedure is called with the argument DRV_ENTRY.
|
||||
; If not, return 0.
|
||||
@ -127,30 +127,30 @@ endp
|
||||
; This procedure is called when new HID device is detected.
|
||||
; It initializes the device.
|
||||
proc AddDevice
|
||||
push ebx esi edi ; save used registers to be stdcall
|
||||
push ebx esi edi ; save used registers to be stdcall
|
||||
virtual at esp
|
||||
rd 3 ; saved registers
|
||||
dd ? ; return address
|
||||
.config_pipe dd ?
|
||||
.config_descr dd ?
|
||||
.interface dd ?
|
||||
rd 3 ; saved registers
|
||||
dd ? ; return address
|
||||
.config_pipe dd ?
|
||||
.config_descr dd ?
|
||||
.interface dd ?
|
||||
end virtual
|
||||
DEBUGF 1,'K : USB HID device detected\n'
|
||||
; 1. Allocate memory for device data.
|
||||
movi eax, sizeof.usb_device_data
|
||||
movi eax, sizeof.usb_device_data
|
||||
call Kmalloc
|
||||
test eax, eax
|
||||
jnz @f
|
||||
mov esi, nomemory_msg
|
||||
call SysMsgBoardStr
|
||||
jmp .return0
|
||||
jnz @f
|
||||
mov esi, nomemory_msg
|
||||
call SysMsgBoardStr
|
||||
jmp .return0
|
||||
@@:
|
||||
; zero-initialize it
|
||||
mov edi, eax
|
||||
xchg eax, ebx
|
||||
xor eax, eax
|
||||
movi ecx, sizeof.usb_device_data / 4
|
||||
rep stosd
|
||||
mov edi, eax
|
||||
xchg eax, ebx
|
||||
xor eax, eax
|
||||
movi ecx, sizeof.usb_device_data / 4
|
||||
rep stosd
|
||||
mov edx, [.interface]
|
||||
; HID devices use one IN interrupt endpoint for polling the device
|
||||
; and an optional OUT interrupt endpoint. We do not use the later,
|
||||
@ -171,8 +171,8 @@ end virtual
|
||||
.lookep:
|
||||
; 3b. Get next descriptor.
|
||||
movzx ecx, byte [edx] ; the first byte of all descriptors is length
|
||||
test ecx, ecx
|
||||
jz .cfgerror
|
||||
test ecx, ecx
|
||||
jz .cfgerror
|
||||
add edx, ecx
|
||||
; 3c. Check that at least two bytes are readable. The opposite is an error.
|
||||
inc edx
|
||||
@ -188,34 +188,34 @@ end virtual
|
||||
; For other descriptors, continue the loop.
|
||||
; Note: bDescriptorType is in the same place in all descriptors.
|
||||
cmp [edx+endpoint_descr.bDescriptorType], ENDPOINT_DESCR_TYPE
|
||||
jz .foundep
|
||||
cmp [edx+endpoint_descr.bDescriptorType], HID_DESCR_TYPE
|
||||
jnz .lookep
|
||||
jz .foundep
|
||||
cmp [edx+endpoint_descr.bDescriptorType], HID_DESCR_TYPE
|
||||
jnz .lookep
|
||||
; 4a. Check that the descriptor contains all required data and all data are
|
||||
; readable. The opposite is an error.
|
||||
movzx ecx, [edx+hid_descr.bLength]
|
||||
cmp ecx, hid_descr.base_sizeof + 3
|
||||
jb .cfgerror
|
||||
add ecx, edx
|
||||
cmp ecx, eax
|
||||
ja .cfgerror
|
||||
movzx ecx, [edx+hid_descr.bLength]
|
||||
cmp ecx, hid_descr.base_sizeof + 3
|
||||
jb .cfgerror
|
||||
add ecx, edx
|
||||
cmp ecx, eax
|
||||
ja .cfgerror
|
||||
; 4b. Store the pointer in usb_device_data structure for further references.
|
||||
mov [ebx+usb_device_data.hiddescr], edx
|
||||
mov [ebx+usb_device_data.hiddescr], edx
|
||||
; 4c. Continue the loop.
|
||||
jmp .lookep
|
||||
jmp .lookep
|
||||
.foundep:
|
||||
; 5a. Check that the descriptor contains all required data and all data are
|
||||
; readable. The opposite is an error.
|
||||
cmp byte [edx+endpoint_descr.bLength], sizeof.endpoint_descr
|
||||
jb .cfgerror
|
||||
lea ecx, [edx+sizeof.endpoint_descr]
|
||||
cmp ecx, eax
|
||||
jbe @f
|
||||
lea ecx, [edx+sizeof.endpoint_descr]
|
||||
cmp ecx, eax
|
||||
jbe @f
|
||||
; 6. An error occured during processing endpoint descriptor.
|
||||
.cfgerror:
|
||||
; 6a. Print a message.
|
||||
mov esi, invalid_config_descr_msg
|
||||
call SysMsgBoardStr
|
||||
mov esi, invalid_config_descr_msg
|
||||
call SysMsgBoardStr
|
||||
; 6b. Free memory allocated for device data.
|
||||
.free:
|
||||
xchg eax, ebx
|
||||
@ -224,112 +224,112 @@ end virtual
|
||||
; 6c. Return an error.
|
||||
xor eax, eax
|
||||
.nothing:
|
||||
pop edi esi ebx ; restore used registers to be stdcall
|
||||
ret 12
|
||||
pop edi esi ebx ; restore used registers to be stdcall
|
||||
ret 12
|
||||
@@:
|
||||
; 5b. If this is not IN interrupt endpoint, ignore it and continue the loop.
|
||||
test [edx+endpoint_descr.bEndpointAddress], 80h
|
||||
jz .lookep
|
||||
mov cl, [edx+endpoint_descr.bmAttributes]
|
||||
and cl, 3
|
||||
cmp cl, INTERRUPT_PIPE
|
||||
jnz .lookep
|
||||
test [edx+endpoint_descr.bEndpointAddress], 80h
|
||||
jz .lookep
|
||||
mov cl, [edx+endpoint_descr.bmAttributes]
|
||||
and cl, 3
|
||||
cmp cl, INTERRUPT_PIPE
|
||||
jnz .lookep
|
||||
; 5c. Store the pointer in usb_device_data structure for futher references.
|
||||
mov [ebx+usb_device_data.epdescr], edx
|
||||
mov [ebx+usb_device_data.epdescr], edx
|
||||
; 5d. Check that HID descriptor was found. If not, go to 6.
|
||||
cmp [ebx+usb_device_data.hiddescr], 0
|
||||
jz .cfgerror
|
||||
cmp [ebx+usb_device_data.hiddescr], 0
|
||||
jz .cfgerror
|
||||
.descriptors_found:
|
||||
; 6. Configuration descriptor seems to be ok.
|
||||
; Send SET_IDLE command disabling auto-repeat feature (it is quite useless)
|
||||
; and continue configuring in SET_IDLE callback.
|
||||
lea edx, [ebx+usb_device_data.control]
|
||||
mov eax, [.interface]
|
||||
mov dword [edx], 21h + \ ; Class-specific request to Interface
|
||||
(0Ah shl 8) + \ ; SET_IDLE
|
||||
(0 shl 16) + \ ; apply to all input reports
|
||||
(0 shl 24) ; disable auto-repeat
|
||||
movzx eax, [eax+interface_descr.bInterfaceNumber]
|
||||
mov [ebx+usb_device_data.interface_number], eax
|
||||
mov [edx+4], eax ; set interface number, zero length
|
||||
mov eax, [.config_pipe]
|
||||
mov [ebx+usb_device_data.configpipe], eax
|
||||
xor ecx, ecx
|
||||
stdcall USBControlTransferAsync, eax, edx, ecx, ecx, idle_set, ebx, ecx
|
||||
lea edx, [ebx+usb_device_data.control]
|
||||
mov eax, [.interface]
|
||||
mov dword [edx], 21h + \ ; Class-specific request to Interface
|
||||
(0Ah shl 8) + \ ; SET_IDLE
|
||||
(0 shl 16) + \ ; apply to all input reports
|
||||
(0 shl 24) ; disable auto-repeat
|
||||
movzx eax, [eax+interface_descr.bInterfaceNumber]
|
||||
mov [ebx+usb_device_data.interface_number], eax
|
||||
mov [edx+4], eax ; set interface number, zero length
|
||||
mov eax, [.config_pipe]
|
||||
mov [ebx+usb_device_data.configpipe], eax
|
||||
xor ecx, ecx
|
||||
stdcall USBControlTransferAsync, eax, edx, ecx, ecx, idle_set, ebx, ecx
|
||||
; 7. Return pointer to usb_device_data.
|
||||
xchg eax, ebx
|
||||
jmp .nothing
|
||||
xchg eax, ebx
|
||||
jmp .nothing
|
||||
endp
|
||||
|
||||
; This procedure is called by USB stack when SET_IDLE request initiated by
|
||||
; AddDevice is completed, either successfully or unsuccessfully.
|
||||
proc idle_set
|
||||
push ebx esi ; save used registers to be stdcall
|
||||
push ebx esi ; save used registers to be stdcall
|
||||
virtual at esp
|
||||
rd 2 ; saved registers
|
||||
dd ? ; return address
|
||||
.pipe dd ?
|
||||
.status dd ?
|
||||
.buffer dd ?
|
||||
.length dd ?
|
||||
.calldata dd ?
|
||||
rd 2 ; saved registers
|
||||
dd ? ; return address
|
||||
.pipe dd ?
|
||||
.status dd ?
|
||||
.buffer dd ?
|
||||
.length dd ?
|
||||
.calldata dd ?
|
||||
end virtual
|
||||
; Ignore status. Support for SET_IDLE is optional, so the device is free to
|
||||
; STALL the request; config pipe should remain functional without explicit cleanup.
|
||||
mov ebx, [.calldata]
|
||||
mov ebx, [.calldata]
|
||||
; 1. HID descriptor contains length of Report descriptor. Parse it.
|
||||
mov esi, [ebx+usb_device_data.hiddescr]
|
||||
movzx ecx, [esi+hid_descr.bNumDescriptors]
|
||||
lea eax, [hid_descr.base_sizeof+ecx*3]
|
||||
cmp eax, 100h
|
||||
jae .cfgerror
|
||||
cmp al, [esi+hid_descr.bLength]
|
||||
jb .cfgerror
|
||||
mov esi, [ebx+usb_device_data.hiddescr]
|
||||
movzx ecx, [esi+hid_descr.bNumDescriptors]
|
||||
lea eax, [hid_descr.base_sizeof+ecx*3]
|
||||
cmp eax, 100h
|
||||
jae .cfgerror
|
||||
cmp al, [esi+hid_descr.bLength]
|
||||
jb .cfgerror
|
||||
.look_report:
|
||||
dec ecx
|
||||
js .cfgerror
|
||||
cmp [esi+hid_descr.subDescriptorType], REPORT_DESCR_TYPE
|
||||
jz .found_report
|
||||
add esi, 3
|
||||
jmp .look_report
|
||||
dec ecx
|
||||
js .cfgerror
|
||||
cmp [esi+hid_descr.subDescriptorType], REPORT_DESCR_TYPE
|
||||
jz .found_report
|
||||
add esi, 3
|
||||
jmp .look_report
|
||||
.cfgerror:
|
||||
mov esi, invalid_config_descr_msg
|
||||
mov esi, invalid_config_descr_msg
|
||||
.abort_with_msg:
|
||||
call SysMsgBoardStr
|
||||
jmp .nothing
|
||||
call SysMsgBoardStr
|
||||
jmp .nothing
|
||||
.found_report:
|
||||
; 2. Send request for the Report descriptor.
|
||||
; 2a. Allocate memory.
|
||||
movzx eax, [esi+hid_descr.subDescriptorLength]
|
||||
test eax, eax
|
||||
jz .cfgerror
|
||||
push eax
|
||||
call Kmalloc
|
||||
pop ecx
|
||||
movzx eax, [esi+hid_descr.subDescriptorLength]
|
||||
test eax, eax
|
||||
jz .cfgerror
|
||||
push eax
|
||||
call Kmalloc
|
||||
pop ecx
|
||||
; If failed, say a message and stop initialization.
|
||||
mov esi, nomemory_msg
|
||||
test eax, eax
|
||||
jz .abort_with_msg
|
||||
mov esi, nomemory_msg
|
||||
test eax, eax
|
||||
jz .abort_with_msg
|
||||
; 2b. Submit the request.
|
||||
xchg eax, esi
|
||||
lea edx, [ebx+usb_device_data.control]
|
||||
mov eax, [ebx+usb_device_data.interface_number]
|
||||
mov dword [edx], 81h + \ ; Standard request to Interface
|
||||
(6 shl 8) + \ ; GET_DESCRIPTOR
|
||||
(0 shl 16) + \ ; descriptor index: there is only one report descriptor
|
||||
(REPORT_DESCR_TYPE shl 24); descriptor type
|
||||
mov [edx+4], ax ; Interface number
|
||||
mov [edx+6], cx ; descriptor length
|
||||
stdcall USBControlTransferAsync, [ebx+usb_device_data.configpipe], \
|
||||
edx, esi, ecx, got_report, ebx, 0
|
||||
xchg eax, esi
|
||||
lea edx, [ebx+usb_device_data.control]
|
||||
mov eax, [ebx+usb_device_data.interface_number]
|
||||
mov dword [edx], 81h + \ ; Standard request to Interface
|
||||
(6 shl 8) + \ ; GET_DESCRIPTOR
|
||||
(0 shl 16) + \ ; descriptor index: there is only one report descriptor
|
||||
(REPORT_DESCR_TYPE shl 24); descriptor type
|
||||
mov [edx+4], ax ; Interface number
|
||||
mov [edx+6], cx ; descriptor length
|
||||
stdcall USBControlTransferAsync, [ebx+usb_device_data.configpipe], \
|
||||
edx, esi, ecx, got_report, ebx, 0
|
||||
; 2c. If failed, free the buffer and stop initialization.
|
||||
test eax, eax
|
||||
jnz .nothing
|
||||
xchg eax, esi
|
||||
call Kfree
|
||||
test eax, eax
|
||||
jnz .nothing
|
||||
xchg eax, esi
|
||||
call Kfree
|
||||
.nothing:
|
||||
pop esi ebx ; restore used registers to be stdcall
|
||||
ret 20
|
||||
pop esi ebx ; restore used registers to be stdcall
|
||||
ret 20
|
||||
endp
|
||||
|
||||
; This procedure is called by USB stack when the report descriptor queried
|
||||
@ -338,100 +338,100 @@ proc got_report stdcall uses ebx esi edi, pipe, status, buffer, length, calldata
|
||||
locals
|
||||
parse_descr_locals
|
||||
if ~HID_DUMP_UNCLAIMED
|
||||
has_driver db ?
|
||||
rb 3
|
||||
has_driver db ?
|
||||
rb 3
|
||||
end if
|
||||
endl
|
||||
; 1. Check the status; if the request has failed, say something to the debug board
|
||||
; and stop initialization.
|
||||
cmp [status], 0
|
||||
jnz .generic_fail
|
||||
cmp [status], 0
|
||||
jnz .generic_fail
|
||||
; 2. Subtract size of setup packet from the total length;
|
||||
; the rest is length of the descriptor, and it must be nonzero.
|
||||
sub [length], 8
|
||||
ja .has_something
|
||||
sub [length], 8
|
||||
ja .has_something
|
||||
.generic_fail:
|
||||
push esi
|
||||
mov esi, reportfail
|
||||
call SysMsgBoardStr
|
||||
pop esi
|
||||
jmp .exit
|
||||
push esi
|
||||
mov esi, reportfail
|
||||
call SysMsgBoardStr
|
||||
pop esi
|
||||
jmp .exit
|
||||
.has_something:
|
||||
; 3. Process descriptor.
|
||||
; 3a. Dump it to the debug board, if enabled in compile-time setting.
|
||||
if USB_DUMP_DESCRIPTORS
|
||||
mov eax, [buffer]
|
||||
mov ecx, [length]
|
||||
DEBUGF 1,'K : report descriptor:'
|
||||
mov eax, [buffer]
|
||||
mov ecx, [length]
|
||||
DEBUGF 1,'K : report descriptor:'
|
||||
@@:
|
||||
DEBUGF 1,' %x',[eax]:2
|
||||
inc eax
|
||||
dec ecx
|
||||
jnz @b
|
||||
DEBUGF 1,'\n'
|
||||
DEBUGF 1,' %x',[eax]:2
|
||||
inc eax
|
||||
dec ecx
|
||||
jnz @b
|
||||
DEBUGF 1,'\n'
|
||||
end if
|
||||
; 3b. Call the HID layer.
|
||||
parse_descr
|
||||
cmp [report_ok], 0
|
||||
jz got_report.exit
|
||||
mov ebx, [calldata]
|
||||
postprocess_descr
|
||||
parse_descr
|
||||
cmp [report_ok], 0
|
||||
jz got_report.exit
|
||||
mov ebx, [calldata]
|
||||
postprocess_descr
|
||||
; 4. Stop initialization if no driver is assigned.
|
||||
if ~HID_DUMP_UNCLAIMED
|
||||
cmp [has_driver], 0
|
||||
jz got_report.exit
|
||||
cmp [has_driver], 0
|
||||
jz got_report.exit
|
||||
end if
|
||||
; 5. Open interrupt IN pipe. If failed, stop initialization.
|
||||
mov edx, [ebx+usb_device_data.epdescr]
|
||||
mov edx, [ebx+usb_device_data.epdescr]
|
||||
movzx ecx, [edx+endpoint_descr.bEndpointAddress]
|
||||
movzx eax, [edx+endpoint_descr.bInterval]
|
||||
movzx edx, [edx+endpoint_descr.wMaxPacketSize]
|
||||
stdcall USBOpenPipe, [ebx+usb_device_data.configpipe], ecx, edx, INTERRUPT_PIPE, eax
|
||||
test eax, eax
|
||||
jz got_report.exit
|
||||
mov [ebx+usb_device_data.intpipe], eax
|
||||
stdcall USBOpenPipe, [ebx+usb_device_data.configpipe], ecx, edx, INTERRUPT_PIPE, eax
|
||||
test eax, eax
|
||||
jz got_report.exit
|
||||
mov [ebx+usb_device_data.intpipe], eax
|
||||
; 6. Initialize buffer for input packet.
|
||||
; 6a. Find the length of input packet.
|
||||
; This is the maximal length of all input reports.
|
||||
mov edx, [ebx+usb_device_data.hid.input.first_report]
|
||||
xor eax, eax
|
||||
mov edx, [ebx+usb_device_data.hid.input.first_report]
|
||||
xor eax, eax
|
||||
.find_input_size:
|
||||
test edx, edx
|
||||
jz .found_input_size
|
||||
cmp eax, [edx+report.size]
|
||||
jae @f
|
||||
mov eax, [edx+report.size]
|
||||
test edx, edx
|
||||
jz .found_input_size
|
||||
cmp eax, [edx+report.size]
|
||||
jae @f
|
||||
mov eax, [edx+report.size]
|
||||
@@:
|
||||
mov edx, [edx+report.next]
|
||||
jmp .find_input_size
|
||||
mov edx, [edx+report.next]
|
||||
jmp .find_input_size
|
||||
.found_input_size:
|
||||
; report.size is in bits, transform it to bytes
|
||||
add eax, 7
|
||||
shr eax, 3
|
||||
add eax, 7
|
||||
shr eax, 3
|
||||
; if reports are numbered, the first byte is report ID, include it
|
||||
cmp [ebx+usb_device_data.hid.input.numbered], 0
|
||||
jz @f
|
||||
inc eax
|
||||
cmp [ebx+usb_device_data.hid.input.numbered], 0
|
||||
jz @f
|
||||
inc eax
|
||||
@@:
|
||||
mov [ebx+usb_device_data.input_transfer_size], eax
|
||||
mov [ebx+usb_device_data.input_transfer_size], eax
|
||||
; 6b. Allocate memory for input packet: dword-align and add additional dword
|
||||
; for extract_field_value.
|
||||
add eax, 4+3
|
||||
and eax, not 3
|
||||
call Kmalloc
|
||||
test eax, eax
|
||||
jnz @f
|
||||
mov esi, nomemory_msg
|
||||
call SysMsgBoardStr
|
||||
jmp got_report.exit
|
||||
add eax, 4+3
|
||||
and eax, not 3
|
||||
call Kmalloc
|
||||
test eax, eax
|
||||
jnz @f
|
||||
mov esi, nomemory_msg
|
||||
call SysMsgBoardStr
|
||||
jmp got_report.exit
|
||||
@@:
|
||||
mov [ebx+usb_device_data.input_buffer], eax
|
||||
mov [ebx+usb_device_data.input_buffer], eax
|
||||
; 7. Submit a request for input packet and wait for input.
|
||||
call ask_for_input
|
||||
call ask_for_input
|
||||
got_report.exit:
|
||||
mov eax, [buffer]
|
||||
call Kfree
|
||||
ret
|
||||
mov eax, [buffer]
|
||||
call Kfree
|
||||
ret
|
||||
endp
|
||||
|
||||
; Helper procedure for got_report and got_input.
|
||||
@ -439,13 +439,13 @@ endp
|
||||
proc ask_for_input
|
||||
; just call USBNormalTransferAsync with correct parameters,
|
||||
; allow short packets
|
||||
stdcall USBNormalTransferAsync, \
|
||||
[ebx+usb_device_data.intpipe], \
|
||||
[ebx+usb_device_data.input_buffer], \
|
||||
[ebx+usb_device_data.input_transfer_size], \
|
||||
got_input, ebx, \
|
||||
1
|
||||
ret
|
||||
stdcall USBNormalTransferAsync, \
|
||||
[ebx+usb_device_data.intpipe], \
|
||||
[ebx+usb_device_data.input_buffer], \
|
||||
[ebx+usb_device_data.input_transfer_size], \
|
||||
got_input, ebx, \
|
||||
1
|
||||
ret
|
||||
endp
|
||||
|
||||
; This procedure is called by USB stack when a HID device responds with input
|
||||
@ -455,67 +455,67 @@ locals
|
||||
parse_input_locals
|
||||
endl
|
||||
; 1. Validate parameters: fail on error, ignore zero-length transfers.
|
||||
mov ebx, [calldata]
|
||||
cmp [status], 0
|
||||
jnz .fail
|
||||
cmp [length], 0
|
||||
jz .done
|
||||
mov ebx, [calldata]
|
||||
cmp [status], 0
|
||||
jnz .fail
|
||||
cmp [length], 0
|
||||
jz .done
|
||||
; 2. Get pointer to report in esi.
|
||||
; 2a. If there are no report IDs, use hid.input.data.
|
||||
mov eax, [buffer]
|
||||
mov esi, [ebx+usb_device_data.hid.input.data]
|
||||
cmp [ebx+usb_device_data.hid.input.numbered], 0
|
||||
jz .report_found
|
||||
mov eax, [buffer]
|
||||
mov esi, [ebx+usb_device_data.hid.input.data]
|
||||
cmp [ebx+usb_device_data.hid.input.numbered], 0
|
||||
jz .report_found
|
||||
; 2b. Otherwise, the first byte of report is report ID;
|
||||
; locate the report by its ID, advance buffer+length to one byte.
|
||||
movzx eax, byte [eax]
|
||||
mov esi, [esi+eax*4]
|
||||
inc [buffer]
|
||||
dec [length]
|
||||
movzx eax, byte [eax]
|
||||
mov esi, [esi+eax*4]
|
||||
inc [buffer]
|
||||
dec [length]
|
||||
.report_found:
|
||||
; 3. Validate: ignore transfers with unregistered report IDs
|
||||
; and transfers which are too short for the corresponding report.
|
||||
test esi, esi
|
||||
jz .done
|
||||
mov eax, [esi+report.size]
|
||||
add eax, 7
|
||||
shr eax, 3
|
||||
cmp eax, [length]
|
||||
ja .done
|
||||
test esi, esi
|
||||
jz .done
|
||||
mov eax, [esi+report.size]
|
||||
add eax, 7
|
||||
shr eax, 3
|
||||
cmp eax, [length]
|
||||
ja .done
|
||||
; 4. Pass everything to HID layer.
|
||||
parse_input
|
||||
parse_input
|
||||
.done:
|
||||
; 5. Query the next input.
|
||||
mov ebx, [calldata]
|
||||
call ask_for_input
|
||||
mov ebx, [calldata]
|
||||
call ask_for_input
|
||||
.nothing:
|
||||
ret
|
||||
ret
|
||||
.fail:
|
||||
mov esi, transfer_error_msg
|
||||
call SysMsgBoardStr
|
||||
jmp .nothing
|
||||
mov esi, transfer_error_msg
|
||||
call SysMsgBoardStr
|
||||
jmp .nothing
|
||||
endp
|
||||
|
||||
; This function is called by the USB subsystem when a device is disconnected.
|
||||
proc DeviceDisconnected
|
||||
push ebx esi edi ; save used registers to be stdcall
|
||||
push ebx esi edi ; save used registers to be stdcall
|
||||
virtual at esp
|
||||
rd 3 ; saved registers
|
||||
dd ? ; return address
|
||||
.device_data dd ?
|
||||
rd 3 ; saved registers
|
||||
dd ? ; return address
|
||||
.device_data dd ?
|
||||
end virtual
|
||||
; 1. Say a message.
|
||||
mov ebx, [.device_data]
|
||||
mov esi, disconnectmsg
|
||||
stdcall SysMsgBoardStr
|
||||
; 2. Ask HID layer to release all HID-related resources.
|
||||
hid_cleanup
|
||||
hid_cleanup
|
||||
; 3. Free the device data.
|
||||
xchg eax, ebx
|
||||
call Kfree
|
||||
; 4. Return.
|
||||
.nothing:
|
||||
pop edi esi ebx ; restore used registers to be stdcall
|
||||
pop edi esi ebx ; restore used registers to be stdcall
|
||||
ret 4 ; purge one dword argument to be stdcall
|
||||
endp
|
||||
|
||||
@ -526,13 +526,13 @@ include 'keyboard.inc'
|
||||
|
||||
; strings
|
||||
my_driver db 'usbhid',0
|
||||
nomemory_msg db 'K : no memory',13,10,0
|
||||
nomemory_msg db 'K : no memory',13,10,0
|
||||
invalid_config_descr_msg db 'K : invalid config descriptor',13,10,0
|
||||
reportfail db 'K : failed to read report descriptor',13,10,0
|
||||
transfer_error_msg db 'K : USB transfer error, disabling HID device',13,10,0
|
||||
disconnectmsg db 'K : USB HID device disconnected',13,10,0
|
||||
invalid_report_msg db 'K : report descriptor is invalid',13,10,0
|
||||
delimiter_note db 'K : note: alternate usage ignored',13,10,0
|
||||
reportfail db 'K : failed to read report descriptor',13,10,0
|
||||
transfer_error_msg db 'K : USB transfer error, disabling HID device',13,10,0
|
||||
disconnectmsg db 'K : USB HID device disconnected',13,10,0
|
||||
invalid_report_msg db 'K : report descriptor is invalid',13,10,0
|
||||
delimiter_note db 'K : note: alternate usage ignored',13,10,0
|
||||
|
||||
; Exported variable: kernel API version.
|
||||
align 4
|
||||
|
@ -358,40 +358,40 @@ high_code:
|
||||
call mutex_init
|
||||
|
||||
; SAVE REAL MODE VARIABLES
|
||||
xor eax,eax
|
||||
xor eax, eax
|
||||
mov ax, [BOOT_VAR + BOOT_IDE_PI_16]
|
||||
mov [IDEContrProgrammingInterface], ax
|
||||
mov ax, [BOOT_VAR + BOOT_IDE_BASE_ADDR]
|
||||
mov [IDEContrRegsBaseAddr], ax
|
||||
mov ax, [BOOT_VAR + BOOT_IDE_BAR0_16]
|
||||
mov [IDE_BAR0_val], ax
|
||||
|
||||
cmp ax,0
|
||||
je @f
|
||||
cmp ax,1
|
||||
je @f
|
||||
and ax,0xfff0
|
||||
mov [StandardATABases],ax
|
||||
mov [hd_address_table],eax
|
||||
mov [hd_address_table+8],eax
|
||||
|
||||
cmp ax, 0
|
||||
je @f
|
||||
cmp ax, 1
|
||||
je @f
|
||||
and ax, 0xfff0
|
||||
mov [StandardATABases], ax
|
||||
mov [hd_address_table], eax
|
||||
mov [hd_address_table+8], eax
|
||||
@@:
|
||||
mov ax, [BOOT_VAR + BOOT_IDE_BAR1_16]
|
||||
mov ax, [BOOT_VAR + BOOT_IDE_BAR1_16]
|
||||
mov [IDE_BAR1_val], ax
|
||||
mov ax, [BOOT_VAR + BOOT_IDE_BAR2_16]
|
||||
mov [IDE_BAR2_val], ax
|
||||
|
||||
cmp ax,0
|
||||
je @f
|
||||
cmp ax,1
|
||||
je @f
|
||||
and ax,0xfff0
|
||||
mov [StandardATABases+2],ax
|
||||
mov [hd_address_table+16],eax
|
||||
mov [hd_address_table+24],eax
|
||||
cmp ax, 0
|
||||
je @f
|
||||
cmp ax, 1
|
||||
je @f
|
||||
and ax, 0xfff0
|
||||
mov [StandardATABases+2], ax
|
||||
mov [hd_address_table+16], eax
|
||||
mov [hd_address_table+24], eax
|
||||
@@:
|
||||
mov ax, [BOOT_VAR + BOOT_IDE_BAR3_16]
|
||||
mov [IDE_BAR3_val], ax
|
||||
|
||||
|
||||
; --------------- APM ---------------------
|
||||
|
||||
; init selectors
|
||||
@ -1066,17 +1066,17 @@ end if
|
||||
|
||||
cmp [IDEContrRegsBaseAddr], 0
|
||||
setnz [dma_hdd]
|
||||
|
||||
cmp [dma_hdd],0
|
||||
|
||||
cmp [dma_hdd], 0
|
||||
je .print_pio
|
||||
.print_dma:
|
||||
DEBUGF 1, "K : IDE DMA mode\n"
|
||||
jmp .continue
|
||||
|
||||
|
||||
.print_pio:
|
||||
DEBUGF 1, "K : IDE PIO mode\n"
|
||||
.continue:
|
||||
|
||||
|
||||
mov [timer_ticks_enable], 1 ; for cd driver
|
||||
|
||||
sti
|
||||
@ -1634,27 +1634,27 @@ endg
|
||||
|
||||
dec ecx
|
||||
jnz noprma
|
||||
mov eax,[hd_address_table]
|
||||
mov [cdbase], eax ;0x1f0
|
||||
mov eax, [hd_address_table]
|
||||
mov [cdbase], eax ;0x1f0
|
||||
mov [cdid], 0xa0
|
||||
noprma:
|
||||
|
||||
dec ecx
|
||||
jnz noprsl
|
||||
mov eax,[hd_address_table]
|
||||
mov [cdbase], eax ;0x1f0
|
||||
mov eax, [hd_address_table]
|
||||
mov [cdbase], eax ;0x1f0
|
||||
mov [cdid], 0xb0
|
||||
noprsl:
|
||||
dec ecx
|
||||
jnz nosema
|
||||
mov eax,[hd_address_table+16]
|
||||
mov [cdbase], eax ;0x170
|
||||
mov eax, [hd_address_table+16]
|
||||
mov [cdbase], eax ;0x170
|
||||
mov [cdid], 0xa0
|
||||
nosema:
|
||||
dec ecx
|
||||
jnz nosesl
|
||||
mov eax,[hd_address_table+16]
|
||||
mov [cdbase], eax ;0x170
|
||||
mov eax, [hd_address_table+16]
|
||||
mov [cdbase], eax ;0x170
|
||||
mov [cdid], 0xb0
|
||||
nosesl:
|
||||
ret
|
||||
@ -1683,8 +1683,8 @@ endg
|
||||
|
||||
cmp ecx, 1
|
||||
jnz noprmahd
|
||||
mov eax,[hd_address_table]
|
||||
mov [hdbase], eax ;0x1f0
|
||||
mov eax, [hd_address_table]
|
||||
mov [hdbase], eax ;0x1f0
|
||||
and dword [hdid], 0x0
|
||||
mov dword [hdpos], ecx
|
||||
; call set_FAT32_variables
|
||||
@ -1692,8 +1692,8 @@ endg
|
||||
|
||||
cmp ecx, 2
|
||||
jnz noprslhd
|
||||
mov eax,[hd_address_table]
|
||||
mov [hdbase], eax ;0x1f0
|
||||
mov eax, [hd_address_table]
|
||||
mov [hdbase], eax ;0x1f0
|
||||
mov [hdid], 0x10
|
||||
mov dword [hdpos], ecx
|
||||
; call set_FAT32_variables
|
||||
@ -1701,8 +1701,8 @@ endg
|
||||
|
||||
cmp ecx, 3
|
||||
jnz nosemahd
|
||||
mov eax,[hd_address_table+16]
|
||||
mov [hdbase], eax ;0x170
|
||||
mov eax, [hd_address_table+16]
|
||||
mov [hdbase], eax ;0x170
|
||||
and dword [hdid], 0x0
|
||||
mov dword [hdpos], ecx
|
||||
; call set_FAT32_variables
|
||||
@ -1710,8 +1710,8 @@ endg
|
||||
|
||||
cmp ecx, 4
|
||||
jnz noseslhd
|
||||
mov eax,[hd_address_table+16]
|
||||
mov [hdbase], eax ;0x170
|
||||
mov eax, [hd_address_table+16]
|
||||
mov [hdbase], eax ;0x170
|
||||
mov [hdid], 0x10
|
||||
mov dword [hdpos], ecx
|
||||
; call set_FAT32_variables
|
||||
|
Loading…
Reference in New Issue
Block a user