Fix serial port reconfigure
This commit is contained in:
105
usbcdc.asm
105
usbcdc.asm
@@ -7,11 +7,14 @@ L_DBG = 1
|
||||
L_ERR = 2
|
||||
|
||||
__DEBUG__ = 1
|
||||
__DEBUG_LEVEL__ = L_DBG
|
||||
__DEBUG_LEVEL__ = L_ERR
|
||||
|
||||
USB_IFACE_CDCACM = 0x0202
|
||||
USB_IFACE_CDCDATA = 0x000A
|
||||
|
||||
; bmRequestType: OUT, Class, Interface
|
||||
BM_REQ_TYPE = 0x21
|
||||
|
||||
; USBPSTN1.2 Table 19
|
||||
SET_COMM_FEATURE = 02h
|
||||
GET_COMM_FEATURE = 03h
|
||||
@@ -70,8 +73,6 @@ struct CDC_DEVICE
|
||||
tx_buf_lock dd ?
|
||||
rx_buf dd ?
|
||||
rx_buf_lock dd ?
|
||||
conf_buf dd ?, ?, ?, ?
|
||||
inp_buf dd ?, ?, ?
|
||||
ends
|
||||
|
||||
section '.flat' readable writable executable
|
||||
@@ -90,7 +91,7 @@ proc START c, .reason:dword, .cmdline:dword
|
||||
invoke GetService, drv_serial_name
|
||||
test eax, eax
|
||||
jnz @f
|
||||
DEBUGF L_ERR, "usbcdc: couldn't load serial driver"
|
||||
DEBUGF L_ERR, "usbcdc: couldn't load serial.sys driver"
|
||||
jmp .fail
|
||||
@@:
|
||||
mov [serial_drv_entry], eax
|
||||
@@ -196,27 +197,16 @@ proc usb_add_device stdcall uses ebx edi, .config_pipe:dword, \
|
||||
ret
|
||||
endp
|
||||
|
||||
proc usb_device_disconnected stdcall, .port:dword
|
||||
mov edx, [.port]
|
||||
stdcall serial_remove_port, [edx + CDC_DEVICE.port_handle]
|
||||
mov eax, edx
|
||||
invoke Kfree
|
||||
proc usb_device_disconnected stdcall uses ebx, .port:dword
|
||||
DEBUGF L_DBG, "usbcdc: disconnected\n"
|
||||
mov ebx, [.port]
|
||||
stdcall serial_remove_port, [ebx + CDC_DEVICE.port_handle]
|
||||
mov eax, ebx
|
||||
invoke Kfree
|
||||
xor eax, eax
|
||||
ret
|
||||
endp
|
||||
|
||||
proc got_input stdcall, .pipe:dword, .status:dword, .buffer:dword, \
|
||||
.length:dword, .calldata:dword
|
||||
DEBUGF L_DBG, "usbcdc: got_input status 0x%x length 0x%x\n", [.status], [.length]
|
||||
cmp [.length], 2
|
||||
jb @f
|
||||
mov eax, [.buffer]
|
||||
DEBUGF L_DBG, "usbcdc: got_input: %x %x\n", [eax]:2, [eax + 1]:2
|
||||
@@:
|
||||
ret
|
||||
endp
|
||||
|
||||
proc serial_startup stdcall uses ebx, .port:dword, .conf:dword
|
||||
DEBUGF L_DBG, "usbcdc: startup %x %x\n", [.port], [.conf]
|
||||
stdcall serial_reconf, [.port], [.conf]
|
||||
@@ -259,22 +249,40 @@ proc serial_shutdown stdcall uses ebx, .port:dword
|
||||
ret
|
||||
endp
|
||||
|
||||
proc control_complete stdcall, .pipe:dword, .status:dword, .buffer:dword, \
|
||||
.length:dword, .calldata:dword
|
||||
mov eax, [.status]
|
||||
test eax, eax
|
||||
jz @f
|
||||
DEBUGF L_ERR, "usbcdc: control_complete err %x\n", eax
|
||||
@@:
|
||||
proc control_complete stdcall uses ebx esi edi, .pipe:dword, .status:dword, \
|
||||
.buffer:dword, .length:dword, .calldata:dword
|
||||
mov ecx, [.calldata]
|
||||
mov eax, [ecx]
|
||||
mov ebx, [ecx + 4]
|
||||
mov edx, [.status]
|
||||
mov [ecx + 8], edx
|
||||
xor esi, esi
|
||||
xor edx, edx
|
||||
invoke RaiseEvent
|
||||
ret
|
||||
endp
|
||||
|
||||
proc serial_reconf stdcall uses ebx edi esi, .port:dword, .conf:dword
|
||||
locals
|
||||
.conf_buf rd 4
|
||||
.event rd 3
|
||||
endl
|
||||
xor esi, esi
|
||||
xor ecx, ecx
|
||||
invoke CreateEvent
|
||||
test eax, eax
|
||||
jnz .event_ok
|
||||
or eax, -1
|
||||
jmp .exit
|
||||
.event_ok:
|
||||
mov [.event], eax
|
||||
mov [.event + 4], edx
|
||||
|
||||
mov ebx, [.port]
|
||||
lea edi, [ebx + CDC_DEVICE.conf_buf]
|
||||
mov dword [edi], 0x21 or (SET_LINE_CODING shl 8)
|
||||
mov dword [edi + 4], 7 shl 16
|
||||
mov esi, edi
|
||||
lea edx, [.conf_buf]
|
||||
mov dword [edx], BM_REQ_TYPE or (SET_LINE_CODING shl 8)
|
||||
mov dword [edx + 4], sizeof.LINE_CODING shl 16
|
||||
mov esi, edx
|
||||
add esi, 8
|
||||
|
||||
mov ecx, [.conf]
|
||||
@@ -288,11 +296,24 @@ proc serial_reconf stdcall uses ebx edi esi, .port:dword, .conf:dword
|
||||
mov al, [ecx + SP_CONF.word_size]
|
||||
mov [esi + LINE_CODING.bDataBits], al
|
||||
|
||||
invoke USBControlTransferAsync, [ebx + CDC_DEVICE.conf_pipe], edi, esi, \
|
||||
sizeof.LINE_CODING, control_complete, ebx, 0
|
||||
test eax, eax
|
||||
jz .exit
|
||||
xor eax, eax
|
||||
lea edi, [.event]
|
||||
invoke USBControlTransferAsync, [ebx + CDC_DEVICE.conf_pipe], edx, esi, \
|
||||
sizeof.LINE_CODING, control_complete, edi, 0
|
||||
mov eax, [.event]
|
||||
mov ebx, [.event + 4]
|
||||
invoke WaitEvent ; TODO WaitEventTimeout?
|
||||
mov eax, [.event + 8]
|
||||
; check the status from control_complete callback
|
||||
cmp eax, USB_STATUS_OK
|
||||
je .status_ok
|
||||
DEBUGF L_ERR, "usbcdc: control transfer error %d\n", eax
|
||||
mov eax, -2
|
||||
.status_ok:
|
||||
push eax
|
||||
mov eax, [.event]
|
||||
mov ebx, [.event + 4]
|
||||
invoke DestroyEvent
|
||||
pop eax
|
||||
.exit:
|
||||
ret
|
||||
endp
|
||||
@@ -305,7 +326,7 @@ proc bulk_out_complete stdcall uses ebx edi esi, .pipe:dword, .status:dword, \
|
||||
DEBUGF L_ERR, "usbcdc: bulk out error %x\n", eax
|
||||
@@:
|
||||
mov ebx, [.calldata]
|
||||
btr dword [ebx + CDC_DEVICE.tx_buf_lock], 0
|
||||
btr [ebx + CDC_DEVICE.tx_buf_lock], 0
|
||||
stdcall serial_tx, ebx
|
||||
ret
|
||||
endp
|
||||
@@ -313,7 +334,7 @@ endp
|
||||
proc serial_tx stdcall uses ebx esi, .port:dword
|
||||
xor eax, eax
|
||||
mov ebx, [.port]
|
||||
bts dword [ebx + CDC_DEVICE.tx_buf_lock], 0
|
||||
bts [ebx + CDC_DEVICE.tx_buf_lock], 0
|
||||
jc .exit
|
||||
|
||||
mov esi, [ebx + CDC_DEVICE.tx_buf]
|
||||
@@ -343,7 +364,7 @@ proc serial_tx stdcall uses ebx esi, .port:dword
|
||||
.error:
|
||||
or eax, -1
|
||||
.unlock:
|
||||
btr dword [ebx + CDC_DEVICE.tx_buf_lock], 0
|
||||
btr [ebx + CDC_DEVICE.tx_buf_lock], 0
|
||||
.exit:
|
||||
ret
|
||||
endp
|
||||
@@ -364,14 +385,14 @@ proc bulk_in_complete stdcall uses ebx edi esi, .pipe:dword, .status:dword, \
|
||||
stdcall serial_handle_event, [ebx + CDC_DEVICE.port_handle], \
|
||||
SERIAL_EVT_RXNE, ecx, esi
|
||||
.exit:
|
||||
btr dword [ebx + CDC_DEVICE.rx_buf_lock], 0
|
||||
btr [ebx + CDC_DEVICE.rx_buf_lock], 0
|
||||
ret
|
||||
endp
|
||||
|
||||
proc serial_rx stdcall uses ebx esi, .port:dword
|
||||
xor eax, eax
|
||||
mov ebx, [.port]
|
||||
bts dword [ebx + CDC_DEVICE.rx_buf_lock], 0
|
||||
bts [ebx + CDC_DEVICE.rx_buf_lock], 0
|
||||
jc .exit
|
||||
|
||||
mov esi, [ebx + CDC_DEVICE.rx_buf]
|
||||
@@ -394,7 +415,7 @@ proc serial_rx stdcall uses ebx esi, .port:dword
|
||||
xor eax, eax
|
||||
jmp .exit
|
||||
.error:
|
||||
btr dword [ebx + CDC_DEVICE.rx_buf_lock], 0
|
||||
btr [ebx + CDC_DEVICE.rx_buf_lock], 0
|
||||
or eax, -1
|
||||
.exit:
|
||||
ret
|
||||
|
||||
Reference in New Issue
Block a user