diff options
-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, |