Remember the error of ucomreadcb() for the next ucomread() call and returns an
authorjan <jan@openbsd.org>
Mon, 27 Jun 2022 13:14:49 +0000 (13:14 +0000)
committerjan <jan@openbsd.org>
Mon, 27 Jun 2022 13:14:49 +0000 (13:14 +0000)
EIO.  Thus the userland notices the error and closes the device.  We forget the
error on reopen and the device works again.

Ok mbuhl

sys/dev/usb/ucom.c

index ed3a2a4..e2e41ce 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ucom.c,v 1.72 2022/04/09 20:07:44 naddy Exp $ */
+/*     $OpenBSD: ucom.c,v 1.73 2022/06/27 13:14:49 jan Exp $ */
 /*     $NetBSD: ucom.c,v 1.49 2003/01/01 00:10:25 thorpej Exp $        */
 
 /*
@@ -114,6 +114,7 @@ struct ucom_softc {
        int                     sc_swflags;
 
        u_char                  sc_cua;
+       int                     sc_error;
 
        struct rwlock           sc_lock;        /* lock during open */
        int                     sc_open;
@@ -307,6 +308,8 @@ ucomopen(dev_t dev, int flag, int mode, struct proc *p)
        if (sc == NULL)
                return (ENXIO);
 
+       sc->sc_error = 0;
+
        if (usbd_is_dying(sc->sc_uparent))
                return (EIO);
 
@@ -606,6 +609,9 @@ ucomread(dev_t dev, struct uio *uio, int flag)
        if (sc == NULL || usbd_is_dying(sc->sc_uparent))
                return (EIO);
 
+       if (sc->sc_error)
+               return (sc->sc_error);
+
        sc->sc_refcnt++;
        tp = sc->sc_tty;
        error = (*LINESW(tp, l_read))(tp, uio, flag);
@@ -1144,6 +1150,7 @@ ucomreadcb(struct usbd_xfer *xfer, void *p, usbd_status status)
            usbd_is_dying(sc->sc_uparent)) {
                DPRINTF(("ucomreadcb: dying\n"));
                /* Send something to wake upper layer */
+               sc->sc_error = EIO;
                s = spltty();
                (*rint)('\n', tp);
                ttwakeup(tp);