From c5cd80abbcd215ffa698449c6b0f8df0e6cd73f7 Mon Sep 17 00:00:00 2001 From: Alexey Ryabov Date: Sun, 18 May 2025 15:25:53 +0500 Subject: [PATCH] Fix serial port reconfigure --- usbcdc.asm | 105 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 63 insertions(+), 42 deletions(-) diff --git a/usbcdc.asm b/usbcdc.asm index 060ab7a..2979b8a 100644 --- a/usbcdc.asm +++ b/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