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 MFC after: 1 day
This commit is contained in:
parent
308f942ec9
commit
f04d2ba47f
@ -297,6 +297,7 @@ ucomopen(struct tty *tp, struct cdev *dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sc->sc_state |= UCS_RXSTOP;
|
||||
ucomstartread(sc);
|
||||
|
||||
sc->sc_poll = 1;
|
||||
@ -621,7 +622,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);
|
||||
@ -701,10 +702,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,
|
||||
@ -713,7 +713,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);
|
||||
}
|
||||
@ -738,11 +739,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));
|
||||
|
Loading…
x
Reference in New Issue
Block a user