From 16cb7d6f69f328ad172ec0bf81ab8be7a12ada1d Mon Sep 17 00:00:00 2001 From: martin Date: Thu, 20 May 2004 09:23:33 +0000 Subject: [PATCH] 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. --- sys/dev/usb/uplcom.c | 45 +++++++++++++++++++++++++++++++------------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/sys/dev/usb/uplcom.c b/sys/dev/usb/uplcom.c index 1a7765747948..7ad69e31b0a9 100644 --- a/sys/dev/usb/uplcom.c +++ b/sys/dev/usb/uplcom.c @@ -1,4 +1,4 @@ -/* $NetBSD: uplcom.c,v 1.36 2004/04/23 17:25:26 itojun Exp $ */ +/* $NetBSD: uplcom.c,v 1.37 2004/05/20 09:23:33 martin Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. @@ -41,7 +41,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uplcom.c,v 1.36 2004/04/23 17:25:26 itojun Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uplcom.c,v 1.37 2004/05/20 09:23:33 martin Exp $"); #include #include @@ -84,6 +84,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 */ @@ -97,9 +106,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 */ @@ -337,7 +345,7 @@ USB_ATTACH(uplcom) USB_ATTACH_ERROR_RETURN; } - sc->sc_dtr = sc->sc_rts = 0; + sc->sc_dtr = sc->sc_rts = -1; uca.portno = UCOM_UNK_PORTNO; /* bulkin, bulkout set above */ uca.ibufsize = UPLCOMIBUFSIZE; @@ -439,8 +447,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); @@ -477,9 +492,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); } @@ -489,9 +505,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_rts == !onoff) return; - sc->sc_rts = onoff; + + sc->sc_rts = !!onoff; uplcom_set_line_state(sc); } @@ -614,6 +631,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); @@ -634,7 +654,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,