diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2005-01-10 12:05:09 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2005-01-10 12:05:09 +0000 |
commit | 4f1b83eb275a9bc760466bc4acf3d006a464cff7 (patch) | |
tree | 694d953e45810f113d20361bc2dda9ae1b41c046 | |
parent | 2ba2e9c431f5064e237b2e54f6f2a6b86b2ac07c (diff) |
from netbsd uplcom.c revision 1.37:
Make sure that we call uplcom_set_line_state() to get consistent state
between our idea of flow controll settings and the chips one.
In uplcom_set_line_state use the same value as the manufacturer suggests,
since the previously used (umodem based) values do not seem to work.
It is not completely clear what happened here - either the "not calling
uplcom_set_line_state" due to luck prevented the non working state to
be discovered or there are variants of the chip that need the old values.
During testing none such chips have been found - if they ever apear we
might have to make this function more intelligent, depending on the chip
in use.
-rw-r--r-- | sys/dev/usb/uplcom.c | 41 |
1 files changed, 30 insertions, 11 deletions
diff --git a/sys/dev/usb/uplcom.c b/sys/dev/usb/uplcom.c index 0b8eb134e0d..edc8b213ffb 100644 --- a/sys/dev/usb/uplcom.c +++ b/sys/dev/usb/uplcom.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uplcom.c,v 1.17 2005/01/10 11:58:52 dlg Exp $ */ +/* $OpenBSD: uplcom.c,v 1.18 2005/01/10 12:05:08 dlg Exp $ */ /* $NetBSD: uplcom.c,v 1.29 2002/09/23 05:51:23 simonb Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -87,6 +87,15 @@ int uplcomdebug = 0; #define RSAQ_STATUS_DSR 0x02 #define RSAQ_STATUS_DCD 0x01 +#define UPLCOM_FLOW_OUT_CTS 0x0001 +#define UPLCOM_FLOW_OUT_DSR 0x0002 +#define UPLCOM_FLOW_IN_DSR 0x0004 +#define UPLCOM_FLOW_IN_DTR 0x0008 +#define UPLCOM_FLOW_IN_RTS 0x0010 +#define UPLCOM_FLOW_OUT_RTS 0x0020 +#define UPLCOM_FLOW_OUT_XON 0x0080 +#define UPLCOM_FLOW_IN_XON 0x0100 + struct uplcom_softc { USBBASEDEVICE sc_dev; /* base device */ usbd_device_handle sc_udev; /* USB device */ @@ -100,9 +109,8 @@ struct uplcom_softc { int sc_isize; usb_cdc_line_state_t sc_line_state; /* current line state */ - u_char sc_dtr; /* current DTR state */ - u_char sc_rts; /* current RTS state */ - u_char sc_status; + int sc_dtr; /* current DTR state */ + int sc_rts; /* current RTS state */ device_ptr_t sc_subdev; /* ucom device */ @@ -446,8 +454,15 @@ uplcom_set_line_state(struct uplcom_softc *sc) usb_device_request_t req; int ls; - ls = (sc->sc_dtr ? UCDC_LINE_DTR : 0) | - (sc->sc_rts ? UCDC_LINE_RTS : 0); + /* Make sure we have initialized state for sc_dtr and sc_rts */ + if (sc->sc_dtr == -1) + sc->sc_dtr = 0; + if (sc->sc_rts == -1) + sc->sc_rts = 0; + + ls = (sc->sc_dtr ? UPLCOM_FLOW_OUT_DSR : 0) | + (sc->sc_rts ? UPLCOM_FLOW_OUT_CTS : 0); + req.bmRequestType = UT_WRITE_CLASS_INTERFACE; req.bRequest = UCDC_SET_CONTROL_LINE_STATE; USETW(req.wValue, ls); @@ -484,9 +499,10 @@ uplcom_dtr(struct uplcom_softc *sc, int onoff) DPRINTF(("uplcom_dtr: onoff=%d\n", onoff)); - if (sc->sc_dtr == onoff) + if (sc->sc_dtr != -1 && !sc->sc_dtr == !onoff) return; - sc->sc_dtr = onoff; + + sc->sc_dtr = !onoff; uplcom_set_line_state(sc); } @@ -496,9 +512,10 @@ uplcom_rts(struct uplcom_softc *sc, int onoff) { DPRINTF(("uplcom_rts: onoff=%d\n", onoff)); - if (sc->sc_rts == onoff) + if (sc->sc_rts == -1 && !sc->sc_dtr == !onoff) return; - sc->sc_rts = onoff; + + sc->sc_rts = !onoff; uplcom_set_line_state(sc); } @@ -621,6 +638,9 @@ uplcom_param(void *addr, int portno, struct termios *t) if (ISSET(t->c_cflag, CRTSCTS)) uplcom_set_crtscts(sc); + if (sc->sc_rts == -1 || sc->sc_dtr == -1) + uplcom_set_line_state(sc); + if (err) { DPRINTF(("uplcom_param: err=%s\n", usbd_errstr(err))); return (EIO); @@ -641,7 +661,6 @@ uplcom_open(void *addr, int portno) DPRINTF(("uplcom_open: sc=%p\n", sc)); if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) { - sc->sc_status = 0; /* clear status bit */ sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); err = usbd_open_pipe_intr(sc->sc_intr_iface, sc->sc_intr_number, USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, |