From d19a5360efa3c70d37fb9011fa8f8bc25680f90c Mon Sep 17 00:00:00 2001 From: jmatthew Date: Sun, 26 Apr 2015 06:38:04 +0000 Subject: [PATCH] Two extra messages required after sending a baud rate update, as observed in the linux mct_u232 driver, which apparently got them by sniffing usb traffic from the vendor's windows 98 driver. Makes this device work at 115200: umct0 at uhub0 port 2 "Belkin Components F5U109 Serial" rev 1.10/1.02 addr 2 ok dlg@ --- sys/dev/usb/umct.c | 28 +++++++++++++++++++++++----- sys/dev/usb/umct.h | 8 +++++++- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/sys/dev/usb/umct.c b/sys/dev/usb/umct.c index 64ae8a65969..f50e5d0dfb3 100644 --- a/sys/dev/usb/umct.c +++ b/sys/dev/usb/umct.c @@ -1,4 +1,4 @@ -/* $OpenBSD: umct.c,v 1.43 2015/03/14 03:38:50 jsg Exp $ */ +/* $OpenBSD: umct.c,v 1.44 2015/04/26 06:38:04 jmatthew Exp $ */ /* $NetBSD: umct.c,v 1.10 2003/02/23 04:20:07 simonb Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -104,7 +104,7 @@ struct umct_softc { #define UMCTOBUFSIZE 256 void umct_init(struct umct_softc *); -void umct_set_baudrate(struct umct_softc *, u_int); +void umct_set_baudrate(struct umct_softc *, u_int, int); void umct_set_lcr(struct umct_softc *, u_int); void umct_intr(struct usbd_xfer *, void *, usbd_status); @@ -413,7 +413,7 @@ umct_set_lcr(struct umct_softc *sc, u_int data) } void -umct_set_baudrate(struct umct_softc *sc, u_int rate) +umct_set_baudrate(struct umct_softc *sc, u_int rate, int cts) { usb_device_request_t req; uDWord arate; @@ -447,12 +447,30 @@ umct_set_baudrate(struct umct_softc *sc, u_int rate) /* XXX should check */ (void)usbd_do_request(sc->sc_udev, &req, arate); + + /* unknown request, required after setting baud rate */ + USETDW(arate, 0); + req.bmRequestType = UMCT_SET_REQUEST; + req.bRequest = REQ_UNKNOWN1; + USETW(req.wValue, 0); + USETW(req.wIndex, sc->sc_iface_number); + USETW(req.wLength, LENGTH_UNKNOWN1); + (void)usbd_do_request(sc->sc_udev, &req, arate); + + /* update CTS, also required after setting baud rate */ + USETDW(arate, cts); + req.bmRequestType = UMCT_SET_REQUEST; + req.bRequest = REQ_SET_CTS; + USETW(req.wValue, 0); + USETW(req.wIndex, sc->sc_iface_number); + USETW(req.wLength, LENGTH_SET_CTS); + (void)usbd_do_request(sc->sc_udev, &req, arate); } void umct_init(struct umct_softc *sc) { - umct_set_baudrate(sc, 9600); + umct_set_baudrate(sc, 9600, 0); umct_set_lcr(sc, LCR_DATA_BITS_8 | LCR_PARITY_NONE | LCR_STOP_BITS_1); } @@ -492,7 +510,7 @@ umct_param(void *addr, int portno, struct termios *t) break; } - umct_set_baudrate(sc, t->c_ospeed); + umct_set_baudrate(sc, t->c_ospeed, ISSET(t->c_cflag, CRTSCTS)); sc->last_lcr = data; umct_set_lcr(sc, data); diff --git a/sys/dev/usb/umct.h b/sys/dev/usb/umct.h index 0cc95e3628c..aac762d3ce7 100644 --- a/sys/dev/usb/umct.h +++ b/sys/dev/usb/umct.h @@ -1,4 +1,4 @@ -/* $OpenBSD: umct.h,v 1.4 2008/06/26 05:42:19 ray Exp $ */ +/* $OpenBSD: umct.h,v 1.5 2015/04/26 06:38:04 jmatthew Exp $ */ /* $NetBSD: umct.h,v 1.1 2001/03/28 18:42:13 ichiro Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -50,6 +50,12 @@ #define REQ_SET_MCR 10 /* Set Modem Control Register (MCR) */ #define LENGTH_SET_MCR 1 +#define REQ_UNKNOWN1 11 /* Unknown functionality */ +#define LENGTH_UNKNOWN1 1 + +#define REQ_SET_CTS 12 /* Apparently controls CTS */ +#define LENGTH_SET_CTS 1 + /* * Baud rate (divisor) */ -- 2.20.1