NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/53913: 4World USB to Serial adapter fails on connection
>Number: 53913
>Category: kern
>Synopsis: 4World USB to Serial adapter fails on connection
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jan 27 09:45:00 +0000 2019
>Originator: Andrius V
>Release: 8.99.30
>Organization:
>Environment:
NetBSD vertexpc 8.99.30 NetBSD 8.99.30 (GENERIC) #0: Tue Jan 15 14:23:56 UTC 2019 mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/i386/compile/GENERIC i386
>Description:
I've recently bought 4World USB to Serial adapter which is based on WinChipHead CH341/340 chip.
from dmesg:
uchcom0: QinHeng Electronics (0x1a86) USB2.0-Ser! (0x7523), rev 1.10/2.54, addr 3
ucom0 at uchcom0
uchcom0: WARNING: power management not supported
Unfortunately, when I am trying to use with minicom (or any alternative app), I am receiving this error message:
uchcom0: cannot reset: STALLED
I investigated it minimally and it returns error on the second call in reset_chip method:
err = read_reg(sc, UCHCOM_REG_BPS_PRE, &pre, UCHCOM_REG_BPS_DIV, &div);
So, I checked OpenBSD driver and it seams they simplified reset code with some hardcoded values. I actually tried it and OpenBSD code works for me (with default configuration at least). minicom successfully started, communication between PCs was successful too. OpenBSD commit can be seen here https://github.com/openbsd/src/commit/5165e579a145cd62a9fbbbd8c33e30b50d88b5d1#diff-e15f5490917f699be5d06d933f46a0b2.
However, I am not sure if it's desirable solution for NetBSD since I saw some recent development on the driver (issue is the same before or after those changes).
>How-To-Repeat:
Connect the cable to USB, try to start minicom with /dev/ttyU0 device. Check dmesg messages.
>Fix:
Workaround copied from OpenBSD:
Index: sys/dev/usb/uchcom.c
==================================================================
--- sys/dev/usb/uchcom.c
+++ sys/dev/usb/uchcom.c
@@ -116,10 +116,17 @@
#define UCHCOM_INTR_LEAST 4
#define UCHCOMIBUFSIZE 256
#define UCHCOMOBUFSIZE 256
+/*
+ * XXX - these magic numbers come from Linux (drivers/usb/serial/ch341.c).
+ * The manufacturer was unresponsive when asked for documentation.
+ */
+#define UCHCOM_RESET_VALUE 0x501F /* line mode? */
+#define UCHCOM_RESET_INDEX 0xD90A /* baud rate? */
+
struct uchcom_softc
{
device_t sc_dev;
struct usbd_device * sc_udev;
device_t sc_subdev;
@@ -761,31 +768,12 @@
static int
reset_chip(struct uchcom_softc *sc)
{
usbd_status err;
- uint8_t lcr, lcr2, pre, div;
- uint16_t val=0, idx=0;
-
- err = read_reg(sc, UCHCOM_REG_LCR, &lcr, UCHCOM_REG_LCR2, &lcr2);
- if (err)
- goto failed;
-
- err = read_reg(sc, UCHCOM_REG_BPS_PRE, &pre, UCHCOM_REG_BPS_DIV, &div);
- if (err)
- goto failed;
-
- val |= (uint16_t)lcr << 8;
- val |= 0x9c; /* magic from vendor Linux and Android drivers */
- idx |= pre & 0x07;
- idx |= (uint16_t)div << 8;
- idx |= UCHCOM_BPS_PRE_IMM;
-
- DPRINTF(("%s: reset v=0x%04X, i=0x%04X\n",
- device_xname(sc->sc_dev), val, idx));
-
- err = generic_control_out(sc, UCHCOM_REQ_RESET, val, idx);
+
+ err = generic_control_out(sc, UCHCOM_REQ_RESET, UCHCOM_RESET_VALUE, UCHCOM_RESET_INDEX);
if (err)
goto failed;
return 0;
Home |
Main Index |
Thread Index |
Old Index