Two extra messages required after sending a baud rate update, as observed
authorjmatthew <jmatthew@openbsd.org>
Sun, 26 Apr 2015 06:38:04 +0000 (06:38 +0000)
committerjmatthew <jmatthew@openbsd.org>
Sun, 26 Apr 2015 06:38:04 +0000 (06:38 +0000)
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
sys/dev/usb/umct.h

index 64ae8a6..f50e5d0 100644 (file)
@@ -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);
index 0cc95e3..aac762d 100644 (file)
@@ -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.
 #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)
  */