From daa923680cc0f4cc9a42d99b82ead36bcda45a5d Mon Sep 17 00:00:00 2001 From: Ian Dowse Date: Tue, 12 Apr 2005 23:45:34 +0000 Subject: MFC 1.57: fix the handling of the UCS_RXSTOP flag so that it always tracks whether or not the receive pipe is stopped. This ensures that we do not attempt to start the same transfer twice, and it allows ucomstop() to skip the restarting of the read pipe if it was not originally running, such as when called indirectly from ucomreadcb() PR: kern/79420 --- sys/dev/usb/ucom.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'sys/dev') diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c index f85619563cb2..44dd458ad236 100644 --- a/sys/dev/usb/ucom.c +++ b/sys/dev/usb/ucom.c @@ -381,6 +381,7 @@ ucomopen(struct cdev *dev, int flag, int mode, usb_proc_ptr p) (minor(dev) & UCOM_CALLOUT_MASK)) ttyld_modem(tp, 1); + sc->sc_state |= UCS_RXSTOP; ucomstartread(sc); } @@ -929,7 +930,7 @@ ucomstop(struct tty *tp, int flag) DPRINTF(("ucomstop: %d\n", flag)); - if (flag & FREAD) { + if ((flag & FREAD) && (sc->sc_state & UCS_RXSTOP) == 0) { DPRINTF(("ucomstop: read\n")); ucomstopread(sc); ucomstartread(sc); @@ -1009,10 +1010,9 @@ ucomstartread(struct ucom_softc *sc) DPRINTF(("ucomstartread: start\n")); - sc->sc_state &= ~UCS_RXSTOP; - - if (sc->sc_bulkin_pipe == NULL) + if (sc->sc_bulkin_pipe == NULL || (sc->sc_state & UCS_RXSTOP) == 0) return (USBD_NORMAL_COMPLETION); + sc->sc_state &= ~UCS_RXSTOP; usbd_setup_xfer(sc->sc_ixfer, sc->sc_bulkin_pipe, (usbd_private_handle)sc, @@ -1021,7 +1021,8 @@ ucomstartread(struct ucom_softc *sc) USBD_NO_TIMEOUT, ucomreadcb); err = usbd_transfer(sc->sc_ixfer); - if (err != USBD_IN_PROGRESS) { + if (err && err != USBD_IN_PROGRESS) { + sc->sc_state |= UCS_RXSTOP; DPRINTF(("ucomstartread: err = %s\n", usbd_errstr(err))); return (err); } @@ -1046,11 +1047,13 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) if (!(sc->sc_state & UCS_RXSTOP)) printf("%s: ucomreadcb: %s\n", USBDEVNAME(sc->sc_dev), usbd_errstr(status)); + sc->sc_state |= UCS_RXSTOP; if (status == USBD_STALLED) usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe); /* XXX we should restart after some delay. */ return; } + sc->sc_state |= UCS_RXSTOP; usbd_get_xfer_status(xfer, NULL, (void **)&cp, &cc, NULL); DPRINTF(("ucomreadcb: got %d chars, tp = %p\n", cc, tp)); -- cgit v1.3