On Wed, Jun 25, 2025 at 07:45:51AM +0200, Ronald Klop wrote: > Hi, Hi Ronald,
> nice work! > > Isn't the HARDWARE section in the man page used to generate a supported > hardware list in the release notes of a new FreeBSD version? ziaee will update the man page https://reviews.freebsd.org/D51036 Thanks. > Regards, > Ronald. > > > Van: Kevin Lo <ke...@freebsd.org> > Datum:woensdag, 25 juni 2025 03:36 > Aan:src-committ...@freebsd.org, dev-commits-src-all@FreeBSD.org, > dev-commits-src-m...@freebsd.org > Onderwerp:git: 1395712cab8e - main - uchcom: add support for CH9102 and CH343 > uarts > > > > The branch main has been updated by kevlo: > > > > URL: > > https://cgit.FreeBSD.org/src/commit/?id=1395712cab8e95808064ba68c5a792b7cd0fe35f > > > > commit 1395712cab8e95808064ba68c5a792b7cd0fe35f > > Author: Kevin Lo <ke...@freebsd.org> > > AuthorDate: 2025-06-25 01:33:35 +0000 > > Commit: Kevin Lo <ke...@freebsd.org> > > CommitDate: 2025-06-25 01:33:35 +0000 > > > > uchcom: add support for CH9102 and CH343 uarts > > The CH343 devices support any baud rate up to 6 Mbps. > > PR: 272803 > > Reviewed by: imp > > Tested by: joerg, Tomasz "CeDeROM" CEDRO <tomek_AT_cedro_DOT_info> > > Differential Revision: https://reviews.freebsd.org/D46290 > > --- > > share/man/man4/uchcom.4 | 27 +--- > > sys/dev/usb/serial/uchcom.c | 353 > > +++++++++++++++++++++++++------------------- > > sys/dev/usb/usbdevs | 4 +- > > 3 files changed, 208 insertions(+), 176 deletions(-) > > > > diff --git a/share/man/man4/uchcom.4 b/share/man/man4/uchcom.4 > > index d5efe83286ba..4d395573589f 100644 > > --- a/share/man/man4/uchcom.4 > > +++ b/share/man/man4/uchcom.4 > > @@ -27,12 +27,12 @@ > > .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > > THE > > .\" POSSIBILITY OF SUCH DAMAGE. > > .\" > > -.Dd April 26, 2017 > > +.Dd August 19, 2024 > > .Dt UCHCOM 4 > > .Os > > .Sh NAME > > .Nm uchcom > > -.Nd WinChipHead CH341/CH340 serial adapter driver > > +.Nd WinChipHead CH9102/CH343/CH341/CH340 serial adapter driver > > .Sh SYNOPSIS > > To compile this driver into the kernel, > > place the following lines in your > > @@ -52,22 +52,12 @@ uchcom_load="YES" > > .Sh DESCRIPTION > > The > > .Nm > > -driver provides support for the WinChipHead CH341/CH340 USB-to-RS-232 > > -Bridge chip. > > +driver provides support for the WinChipHead CH9102/CH343/CH341/CH340 > > +USB-to-RS-232 Bridge chip. > > .Pp > > -The device is accessed through the > > -.Xr ucom 4 > > -driver which makes it behave like a > > -.Xr tty 4 . > > -.Sh HARDWARE > > -The > > -.Nm > > -driver supports the following adapters: > > -.Pp > > -.Bl -bullet -compact > > -.It > > -HL USB-RS232 > > -.El > > +The datasheets for the CH340/CH341 list the maximum > > +supported baud rate as 2,000,000. > > +CH9102/CH343 devices support any baud rate up to 6 Mbps. > > .Sh FILES > > .Bl -tag -width "/dev/ttyU*.init" -compact > > .It Pa /dev/ttyU* > > @@ -95,6 +85,3 @@ The first > > .Fx > > release to include it was > > .Fx 8.0 . > > -.Sh BUGS > > -Actually, this chip seems unable to drive other than 8 data bits and > > -1 stop bit line. > > diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c > > index a886b25c89d7..fdc5515fa722 100644 > > --- a/sys/dev/usb/serial/uchcom.c > > +++ b/sys/dev/usb/serial/uchcom.c > > @@ -58,8 +58,7 @@ > > */ > > /* > > - * Driver for WinChipHead CH341/340, the worst USB-serial chip in the > > - * world. > > + * Driver for WinChipHead CH9102/343/341/340. > > */ > > #include <sys/stdint.h> > > @@ -101,17 +100,19 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, > > CTLFLAG_RWTUN, > > &uchcom_debug, 0, "uchcom debug level"); > > #endif > > -#define UCHCOM_IFACE_INDEX 0 > > -#define UCHCOM_CONFIG_INDEX 0 > > +#define UCHCOM_IFACE_INDEX 0 > > +#define UCHCOM_CONFIG_INDEX 0 > > +#define UCHCOM_SECOND_IFACE_INDEX 1 > > #define UCHCOM_REV_CH340 0x0250 > > #define UCHCOM_INPUT_BUF_SIZE 8 > > -#define UCHCOM_REQ_GET_VERSION 0x5F > > -#define UCHCOM_REQ_READ_REG 0x95 > > -#define UCHCOM_REQ_WRITE_REG 0x9A > > -#define UCHCOM_REQ_RESET 0xA1 > > -#define UCHCOM_REQ_SET_DTRRTS 0xA4 > > +#define UCHCOM_REQ_GET_VERSION 0x5F > > +#define UCHCOM_REQ_READ_REG 0x95 > > +#define UCHCOM_REQ_WRITE_REG 0x9A > > +#define UCHCOM_REQ_RESET 0xA1 > > +#define UCHCOM_REQ_SET_DTRRTS 0xA4 > > +#define UCHCOM_REQ_CH343_WRITE_REG 0xA8 > > #define UCHCOM_REG_STAT1 0x06 > > #define UCHCOM_REG_STAT2 0x07 > > @@ -134,13 +135,21 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, > > CTLFLAG_RWTUN, > > #define UCHCOM_RTS_MASK 0x40 > > #define UCHCOM_BRK_MASK 0x01 > > +#define UCHCOM_ABRK_MASK 0x10 > > +#define UCHCOM_CH343_BRK_MASK 0x80 > > #define UCHCOM_LCR1_MASK 0xAF > > #define UCHCOM_LCR2_MASK 0x07 > > #define UCHCOM_LCR1_RX 0x80 > > #define UCHCOM_LCR1_TX 0x40 > > #define UCHCOM_LCR1_PARENB 0x08 > > +#define UCHCOM_LCR1_CS5 0x00 > > +#define UCHCOM_LCR1_CS6 0x01 > > +#define UCHCOM_LCR1_CS7 0x02 > > #define UCHCOM_LCR1_CS8 0x03 > > +#define UCHCOM_LCR1_STOPB 0x04 > > +#define UCHCOM_LCR1_PARODD 0x00 > > +#define UCHCOM_LCR1_PAREVEN 0x10 > > #define UCHCOM_LCR2_PAREVEN 0x07 > > #define UCHCOM_LCR2_PARODD 0x06 > > #define UCHCOM_LCR2_PARMARK 0x05 > > @@ -150,12 +159,18 @@ SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, > > CTLFLAG_RWTUN, > > #define UCHCOM_INTR_STAT2 0x03 > > #define UCHCOM_INTR_LEAST 4 > > -#define UCHCOM_BULK_BUF_SIZE 1024 /* bytes */ > > +#define UCHCOM_T 0x08 > > +#define UCHCOM_CL 0x04 > > +#define UCHCOM_CH343_CT 0x80 > > +#define UCHCOM_CT 0x90 > > + > > +#define UCHCOM_BULK_BUF_SIZE 1024 /* bytes */ > > + > > +#define TYPE_CH343 1 > > enum { > > UCHCOM_BULK_DT_WR, > > UCHCOM_BULK_DT_RD, > > - UCHCOM_INTR_DT_RD, > > UCHCOM_N_TRANSFER, > > }; > > @@ -164,6 +179,7 @@ struct uchcom_softc { > > struct ucom_softc sc_ucom; > > struct usb_xfer *sc_xfer[UCHCOM_N_TRANSFER]; > > + struct usb_xfer *sc_intr_xfer; /* Interrupt endpoint */ > > struct usb_device *sc_udev; > > struct mtx sc_mtx; > > @@ -171,39 +187,19 @@ struct uchcom_softc { > > uint8_t sc_rts; /* local copy */ > > uint8_t sc_version; > > uint8_t sc_msr; > > - uint8_t sc_lsr; /* local status register */ > > -}; > > - > > -struct uchcom_divider { > > - uint8_t dv_prescaler; > > - uint8_t dv_div; > > - uint8_t dv_mod; > > -}; > > - > > -struct uchcom_divider_record { > > - uint32_t dvr_high; > > - uint32_t dvr_low; > > - uint32_t dvr_base_clock; > > - struct uchcom_divider dvr_divider; > > -}; > > - > > -static const struct uchcom_divider_record dividers[] = > > -{ > > - {307200, 307200, UCHCOM_BASE_UNKNOWN, {7, 0xD9, 0}}, > > - {921600, 921600, UCHCOM_BASE_UNKNOWN, {7, 0xF3, 0}}, > > - {2999999, 23530, 6000000, {3, 0, 0}}, > > - {23529, 2942, 750000, {2, 0, 0}}, > > - {2941, 368, 93750, {1, 0, 0}}, > > - {367, 1, 11719, {0, 0, 0}}, > > + uint8_t sc_lsr; /* local status register */ > > + uint8_t sc_chiptype; /* type of chip */ > > + uint8_t sc_ctrl_iface_no; > > + uint8_t sc_iface_index; > > }; > > -#define NUM_DIVIDERS nitems(dividers) > > - > > static const STRUCT_USB_HOST_ID uchcom_devs[] = { > > {USB_VPI(USB_VENDOR_WCH, USB_PRODUCT_WCH_CH341SER, 0)}, > > {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER, 0)}, > > {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER_2, 0)}, > > {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH341SER_3, 0)}, > > + {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH343SER, 0)}, > > + {USB_VPI(USB_VENDOR_WCH2, USB_PRODUCT_WCH2_CH9102SER, 0)}, > > }; > > /* protypes */ > > @@ -225,8 +221,9 @@ static void uchcom_update_version(struct uchcom_softc > > *); > > static void uchcom_convert_status(struct uchcom_softc *, uint8_t); > > static void uchcom_update_status(struct uchcom_softc *); > > static void uchcom_set_dtr_rts(struct uchcom_softc *); > > -static int uchcom_calc_divider_settings(struct uchcom_divider *, uint32_t); > > -static void uchcom_set_baudrate(struct uchcom_softc *, uint32_t); > > +static void uchcom_calc_baudrate(struct uchcom_softc *, uint32_t, > > uint8_t *, > > + uint8_t *); > > +static void uchcom_set_baudrate(struct uchcom_softc *, uint32_t, > > uint16_t); > > static void uchcom_poll(struct ucom_softc *ucom); > > static device_probe_t uchcom_probe; > > @@ -244,7 +241,7 @@ static const struct usb_config > > uchcom_config_data[UCHCOM_N_TRANSFER] = { > > .endpoint = UE_ADDR_ANY, > > .direction = UE_DIR_OUT, > > .bufsize = UCHCOM_BULK_BUF_SIZE, > > - .flags = {.pipe_bof = 1,.force_short_xfer = 1,}, > > + .flags = {.pipe_bof = 1,}, > > .callback = &uchcom_write_callback, > > }, > > @@ -256,8 +253,10 @@ static const struct usb_config > > uchcom_config_data[UCHCOM_N_TRANSFER] = { > > .flags = {.pipe_bof = 1,.short_xfer_ok = 1,}, > > .callback = &uchcom_read_callback, > > }, > > +}; > > - [UCHCOM_INTR_DT_RD] = { > > +static const struct usb_config uchcom_intr_config_data[1] = { > > + [0] = { > > .type = UE_INTERRUPT, > > .endpoint = UE_ADDR_ANY, > > .direction = UE_DIR_IN, > > @@ -311,8 +310,9 @@ uchcom_attach(device_t dev) > > { > > struct uchcom_softc *sc = device_get_softc(dev); > > struct usb_attach_arg *uaa = device_get_ivars(dev); > > + struct usb_interface *iface; > > + struct usb_interface_descriptor *id; > > int error; > > - uint8_t iface_index; > > DPRINTFN(11, "\n"); > > @@ -330,20 +330,49 @@ uchcom_attach(device_t dev) > > case USB_PRODUCT_WCH2_CH341SER_3: > > device_printf(dev, "CH341 detected\n"); > > break; > > + case USB_PRODUCT_WCH2_CH343SER: > > + device_printf(dev, "CH343 detected\n"); > > + break; > > + case USB_PRODUCT_WCH2_CH9102SER: > > + device_printf(dev, "CH9102 detected\n"); > > + break; > > default: > > - device_printf(dev, "New CH340/CH341 product 0x%04x detected\n", > > - uaa->info.idProduct); > > + device_printf(dev, "New CH340/CH341/CH343/CH9102 product " > > + "0x%04x detected\n", uaa->info.idProduct); > > break; > > } > > - iface_index = UCHCOM_IFACE_INDEX; > > - error = usbd_transfer_setup(uaa->device, > > - &iface_index, sc->sc_xfer, uchcom_config_data, > > - UCHCOM_N_TRANSFER, sc, &sc->sc_mtx); > > + /* CH343/CH9102 has two interfaces. */ > > + sc->sc_ctrl_iface_no = uaa->info.bIfaceNum; > > + iface = usbd_get_iface(uaa->device, UCHCOM_SECOND_IFACE_INDEX); > > + if (iface) { > > + id = usbd_get_interface_descriptor(iface); > > + if (id == NULL) { > > + device_printf(dev, "no interface descriptor\n"); > > + goto detach; > > + } > > + sc->sc_iface_index = UCHCOM_SECOND_IFACE_INDEX; > > + usbd_set_parent_iface(uaa->device, UCHCOM_SECOND_IFACE_INDEX, > > + uaa->info.bIfaceIndex); > > + sc->sc_chiptype = TYPE_CH343; > > + } else { > > + sc->sc_iface_index = UCHCOM_IFACE_INDEX; > > + } > > + > > + /* Setup all transfers. */ > > + error = usbd_transfer_setup(uaa->device, &sc->sc_iface_index, > > + sc->sc_xfer, uchcom_config_data, UCHCOM_N_TRANSFER, sc, > > + &sc->sc_mtx); > > + if (error) { > > + device_printf(dev, "could not allocate all pipes\n"); > > + goto detach; > > + } > > + error = usbd_transfer_setup(uaa->device, &sc->sc_ctrl_iface_no, > > + &sc->sc_intr_xfer, uchcom_intr_config_data, 1, sc, &sc->sc_mtx); > > if (error) { > > - DPRINTF("one or more missing USB endpoints, " > > - "error=%s\n", usbd_errstr(error)); > > + device_printf(dev, "allocating USB transfers failed for " > > + "interrupt\n"); > > goto detach; > > } > > @@ -449,7 +478,9 @@ uchcom_write_reg(struct uchcom_softc *sc, > > (unsigned)reg1, (unsigned)val1, > > (unsigned)reg2, (unsigned)val2); > > uchcom_ctrl_write( > > - sc, UCHCOM_REQ_WRITE_REG, > > + sc, > > + (sc->sc_chiptype != TYPE_CH343) ? > > + UCHCOM_REQ_WRITE_REG : UCHCOM_REQ_CH343_WRITE_REG, > > reg1 | ((uint16_t)reg2 << 8), val1 | ((uint16_t)val2 << 8)); > > } > > @@ -516,9 +547,6 @@ uchcom_update_version(struct uchcom_softc *sc) > > static void > > uchcom_convert_status(struct uchcom_softc *sc, uint8_t cur) > > { > > - sc->sc_dtr = !(cur & UCHCOM_DTR_MASK); > > - sc->sc_rts = !(cur & UCHCOM_RTS_MASK); > > - > > cur = ~cur & 0x0F; > > sc->sc_msr = (cur << 4) | ((sc->sc_msr >> 4) ^ cur); > > } > > @@ -555,78 +583,69 @@ uchcom_cfg_set_break(struct ucom_softc *ucom, uint8_t > > onoff) > > uint8_t brk1; > > uint8_t brk2; > > - uchcom_read_reg(sc, UCHCOM_REG_BREAK1, &brk1, UCHCOM_REG_LCR1, &brk2); > > - if (onoff) { > > - /* on - clear bits */ > > - brk1 &= ~UCHCOM_BRK_MASK; > > - brk2 &= ~UCHCOM_LCR1_TX; > > + if (sc->sc_chiptype == TYPE_CH343) { > > + brk1 = UCHCOM_CH343_BRK_MASK; > > + if (!onoff) > > + brk1 |= UCHCOM_ABRK_MASK; > > + uchcom_write_reg(sc, brk1, 0, 0, 0); > > } else { > > - /* off - set bits */ > > - brk1 |= UCHCOM_BRK_MASK; > > - brk2 |= UCHCOM_LCR1_TX; > > + uchcom_read_reg(sc, UCHCOM_REG_BREAK1, &brk1, UCHCOM_REG_LCR1, > > + &brk2); > > + if (onoff) { > > + /* on - clear bits */ > > + brk1 &= ~UCHCOM_BRK_MASK; > > + brk2 &= ~UCHCOM_LCR1_TX; > > + } else { > > + /* off - set bits */ > > + brk1 |= UCHCOM_BRK_MASK; > > + brk2 |= UCHCOM_LCR1_TX; > > + } > > + uchcom_write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_LCR1, > > + brk2); > > } > > - uchcom_write_reg(sc, UCHCOM_REG_BREAK1, brk1, UCHCOM_REG_LCR1, brk2); > > } > > -static int > > -uchcom_calc_divider_settings(struct uchcom_divider *dp, uint32_t rate) > > -{ > > - const struct uchcom_divider_record *rp; > > - uint32_t div; > > - uint32_t rem; > > - uint32_t mod; > > - uint8_t i; > > - > > - /* find record */ > > - for (i = 0; i != NUM_DIVIDERS; i++) { > > - if (dividers[i].dvr_high >= rate && > > - dividers[i].dvr_low <= rate) { > > - rp = ÷rs[i]; > > - goto found; > > - } > > - } > > - return (-1); > > - > > -found: > > - dp->dv_prescaler = rp->dvr_divider.dv_prescaler; > > - if (rp->dvr_base_clock == UCHCOM_BASE_UNKNOWN) > > - dp->dv_div = rp->dvr_divider.dv_div; > > - else { > > - div = rp->dvr_base_clock / rate; > > - rem = rp->dvr_base_clock % rate; > > - if (div == 0 || div >= 0xFF) > > - return (-1); > > - if ((rem << 1) >= rate) > > - div += 1; > > - dp->dv_div = (uint8_t)-div; > > +static void > > +uchcom_calc_baudrate(struct uchcom_softc *sc, uint32_t rate, uint8_t > > *divisor, > > + uint8_t *factor) > > +{ > > + uint32_t clk = 12000000; > > + > > + if (rate >= 256000 && sc->sc_chiptype == TYPE_CH343) > > + *divisor = 7; > > + else if (rate > 23529) { > > + clk /= 2; > > + *divisor = 3; > > + } else if (rate > 2941) { > > + clk /= 16; > > + *divisor = 2; > > + } else if (rate > 367) { > > + clk /= 128; > > + *divisor = 1; > > + } else { > > + clk = 11719; > > + *divisor = 0; > > } > > - mod = (UCHCOM_BPS_MOD_BASE / rate) + UCHCOM_BPS_MOD_BASE_OFS; > > - mod = mod + (mod / 2); > > + *factor = 256 - clk / rate; > > - dp->dv_mod = (mod + 0xFF) / 0x100; > > - > > - return (0); > > + if (rate == 921600 && sc->sc_chiptype != TYPE_CH343) { > > + *divisor = 7; > > + *factor = 243; > > + } > > } > > static void > > -uchcom_set_baudrate(struct uchcom_softc *sc, uint32_t rate) > > +uchcom_set_baudrate(struct uchcom_softc *sc, uint32_t rate, uint16_t lcr) > > { > > - struct uchcom_divider dv; > > + uint16_t idx; > > + uint8_t factor, div; > > - if (uchcom_calc_divider_settings(&dv, rate)) > > - return; > > + uchcom_calc_baudrate(sc, rate, &div, &factor); > > + div |= (sc->sc_chiptype != TYPE_CH343) ? 0x80 : 0x00; > > + idx = (factor << 8) | div; > > - /* > > - * According to linux code we need to set bit 7 of UCHCOM_REG_BPS_PRE, > > - * otherwise the chip will buffer data. > > - */ > > - uchcom_write_reg(sc, > > - UCHCOM_REG_BPS_PRE, dv.dv_prescaler | 0x80, > > - UCHCOM_REG_BPS_DIV, dv.dv_div); > > - uchcom_write_reg(sc, > > - UCHCOM_REG_BPS_MOD, dv.dv_mod, > > - UCHCOM_REG_BPS_PAD, 0); > > + uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, lcr, idx); > > } > > /* ---------------------------------------------------------------------- > > @@ -673,6 +692,14 @@ uchcom_cfg_open(struct ucom_softc *ucom) > > DPRINTF("\n"); > > + if (sc->sc_chiptype != TYPE_CH343) { > > + /* Set default configuration. */ > > + uchcom_get_version(sc, NULL); > > + uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0); > > + uchcom_write_reg(sc, UCHCOM_REG_BPS_PRE, 0x82, > > + UCHCOM_REG_BPS_DIV, 0xd9); > > + uchcom_write_reg(sc, 0x2c, 0x07, UCHCOM_REG_BPS_PAD, 0); > > + } > > uchcom_update_version(sc); > > uchcom_update_status(sc); > > } > > @@ -680,53 +707,69 @@ uchcom_cfg_open(struct ucom_softc *ucom) > > static int > > uchcom_pre_param(struct ucom_softc *ucom, struct termios *t) > > { > > - struct uchcom_divider dv; > > + struct uchcom_softc *sc = ucom->sc_parent; > > - switch (t->c_cflag & CSIZE) { > > - case CS8: > > + /* > > + * Check requested baud rate. > > + * The CH340/CH341 can set any baud rate up to 2Mb. > > + * The CH9102/CH343 can set any baud rate up to 6Mb. > > + */ > > + switch (sc->sc_chiptype) { > > + case TYPE_CH343: > > + if (t->c_ospeed <= 6000000) > > + return (0); > > break; > > default: > > - return (EIO); > > + if (t->c_ospeed <= 2000000) > > + return (0); > > + break; > > } > > - if ((t->c_cflag & CSTOPB) != 0) > > - return (EIO); > > - if ((t->c_cflag & PARENB) != 0) > > - return (EIO); > > - if (uchcom_calc_divider_settings(&dv, t->c_ospeed)) { > > - return (EIO); > > - } > > - return (0); /* success */ > > + return (EIO); > > } > > static void > > uchcom_cfg_param(struct ucom_softc *ucom, struct termios *t) > > { > > struct uchcom_softc *sc = ucom->sc_parent; > > + uint8_t lcr; > > - uchcom_get_version(sc, NULL); > > - uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0, 0); > > - uchcom_set_baudrate(sc, t->c_ospeed); > > - if (sc->sc_version < UCHCOM_VER_30) { > > - uchcom_read_reg(sc, UCHCOM_REG_LCR1, NULL, > > - UCHCOM_REG_LCR2, NULL); > > - uchcom_write_reg(sc, UCHCOM_REG_LCR1, 0x50, > > - UCHCOM_REG_LCR2, 0x00); > > - } else { > > - /* > > - * Set up line control: > > - * - enable transmit and receive > > - * - set 8n1 mode > > - * To do: support other sizes, parity, stop bits. > > - */ > > - uchcom_write_reg(sc, > > - UCHCOM_REG_LCR1, > > - UCHCOM_LCR1_RX | UCHCOM_LCR1_TX | UCHCOM_LCR1_CS8, > > - UCHCOM_REG_LCR2, 0x00); > > + lcr = UCHCOM_LCR1_RX | UCHCOM_LCR1_TX; > > + > > + if (t->c_cflag & CSTOPB) > > + lcr |= UCHCOM_LCR1_STOPB; > > + > > + if (t->c_cflag & PARENB) { > > + lcr |= UCHCOM_LCR1_PARENB; > > + if (t->c_cflag & PARODD) > > + lcr |= UCHCOM_LCR1_PARODD; > > + else > > + lcr |= UCHCOM_LCR1_PAREVEN; > > } > > - uchcom_update_status(sc); > > - uchcom_ctrl_write(sc, UCHCOM_REQ_RESET, 0x501f, 0xd90a); > > - uchcom_set_baudrate(sc, t->c_ospeed); > > + > > + switch (t->c_cflag & CSIZE) { > > + case CS5: > > + lcr |= UCHCOM_LCR1_CS5; > > + break; > > + case CS6: > > + lcr |= UCHCOM_LCR1_CS6; > > + break; > > + case CS7: > > + lcr |= UCHCOM_LCR1_CS7; > > + break; > > + case CS8: > > + default: > > + lcr |= UCHCOM_LCR1_CS8; > > + break; > > + } > > + > > + if (sc->sc_chiptype == TYPE_CH343) > > + uchcom_set_baudrate(sc, t->c_ospeed, > > + UCHCOM_T | UCHCOM_CL | UCHCOM_CH343_CT | lcr << 8); > > + else > > + uchcom_set_baudrate(sc, t->c_ospeed, > > + UCHCOM_T | UCHCOM_CL | UCHCOM_CT | lcr << 8); > > + > > uchcom_set_dtr_rts(sc); > > uchcom_update_status(sc); > > } > > @@ -737,7 +780,7 @@ uchcom_start_read(struct ucom_softc *ucom) > > struct uchcom_softc *sc = ucom->sc_parent; > > /* start interrupt endpoint */ > > - usbd_transfer_start(sc->sc_xfer[UCHCOM_INTR_DT_RD]); > > + usbd_transfer_start(sc->sc_intr_xfer); > > /* start read endpoint */ > > usbd_transfer_start(sc->sc_xfer[UCHCOM_BULK_DT_RD]); > > @@ -749,7 +792,7 @@ uchcom_stop_read(struct ucom_softc *ucom) > > struct uchcom_softc *sc = ucom->sc_parent; > > /* stop interrupt endpoint */ > > - usbd_transfer_stop(sc->sc_xfer[UCHCOM_INTR_DT_RD]); > > + usbd_transfer_stop(sc->sc_intr_xfer); > > /* stop read endpoint */ > > usbd_transfer_stop(sc->sc_xfer[UCHCOM_BULK_DT_RD]); > > @@ -779,7 +822,8 @@ uchcom_intr_callback(struct usb_xfer *xfer, usb_error_t > > error) > > { > > struct uchcom_softc *sc = usbd_xfer_softc(xfer); > > struct usb_page_cache *pc; > > - uint8_t buf[UCHCOM_INTR_LEAST]; > > + uint32_t intrstat; > > + uint8_t buf[16]; > > int actlen; > > usbd_xfer_status(xfer, &actlen, NULL, NULL, NULL); > > @@ -791,13 +835,12 @@ uchcom_intr_callback(struct usb_xfer *xfer, > > usb_error_t error) > > if (actlen >= UCHCOM_INTR_LEAST) { > > pc = usbd_xfer_get_frame(xfer, 0); > > - usbd_copy_out(pc, 0, buf, UCHCOM_INTR_LEAST); > > + usbd_copy_out(pc, 0, buf, sizeof(buf)); > > - DPRINTF("data = 0x%02X 0x%02X 0x%02X 0x%02X\n", > > - (unsigned)buf[0], (unsigned)buf[1], > > - (unsigned)buf[2], (unsigned)buf[3]); > > + intrstat = (sc->sc_chiptype == TYPE_CH343) ? > > + actlen - 1 : UCHCOM_INTR_STAT1; > > - uchcom_convert_status(sc, buf[UCHCOM_INTR_STAT1]); > > + uchcom_convert_status(sc, buf[intrstat]); > > ucom_status_change(&sc->sc_ucom); > > } > > case USB_ST_SETUP: > > diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs > > index f26edcebcb9c..2318e6bd0017 100644 > > --- a/sys/dev/usb/usbdevs > > +++ b/sys/dev/usb/usbdevs > > @@ -4972,9 +4972,11 @@ product WAVESENSE JAZZ 0xaaaa Jazz blood > > glucose meter > > /* WCH products */ > > product WCH CH341SER 0x5523 CH341/CH340 USB-Serial Bridge > > product WCH2 CH341SER_2 0x5523 CH341/CH340 USB-Serial Bridge > > +product WCH2 CH343SER 0x55d3 CH343 USB Serial > > +product WCH2 CH9102SER 0x55d4 CH9102 USB Serial > > product WCH2 CH341SER_3 0x7522 CH341/CH340 USB-Serial Bridge > > product WCH2 CH341SER 0x7523 CH341/CH340 USB-Serial Bridge > > -product WCH2 U2M 0X752d CH345 USB2.0-MIDI > > +product WCH2 U2M 0x752d CH345 USB2.0-MIDI > > /* West Mountain Radio products */ > > product WESTMOUNTAIN RIGBLASTER_ADVANTAGE 0x0003 RIGblaster Advantage > > > > > > > >