Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/usb ualea(4): Fix detach and error paths.



details:   https://anonhg.NetBSD.org/src/rev/8c96023f95a2
branches:  trunk
changeset: 364382:8c96023f95a2
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Mar 20 00:41:01 2022 +0000

description:
ualea(4): Fix detach and error paths.

- Set sc_needed before aborting the pipe to prevent the xfer callback
  from rescheduling itself.

- Make sure all paths out of the xfer callback clear sc_inflight.

While here, use device_printf instead of aprint_* after attach.

Now my system survives repeated insertion and yanking of ualea(4)
during:

sysctl -w kern.entropy.depletion=1
cat </dev/random >/dev/null

diffstat:

 sys/dev/usb/ualea.c |  21 ++++++++++++++-------
 1 files changed, 14 insertions(+), 7 deletions(-)

diffs (61 lines):

diff -r b9e9b89bff6b -r 8c96023f95a2 sys/dev/usb/ualea.c
--- a/sys/dev/usb/ualea.c       Sun Mar 20 00:40:52 2022 +0000
+++ b/sys/dev/usb/ualea.c       Sun Mar 20 00:41:01 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ualea.c,v 1.16 2022/03/19 11:37:06 riastradh Exp $     */
+/*     $NetBSD: ualea.c,v 1.17 2022/03/20 00:41:01 riastradh Exp $     */
 
 /*-
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ualea.c,v 1.16 2022/03/19 11:37:06 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ualea.c,v 1.17 2022/03/20 00:41:01 riastradh Exp $");
 
 #include <sys/types.h>
 #include <sys/atomic.h>
@@ -159,6 +159,11 @@
        if (sc->sc_attached)
                rnd_detach_source(&sc->sc_rnd);
 
+       /* Prevent xfer from rescheduling itself, if still pending.  */
+       mutex_enter(&sc->sc_lock);
+       sc->sc_needed = 0;
+       mutex_exit(&sc->sc_lock);
+
        /* Cancel pending xfer.  */
        if (sc->sc_pipe)
                usbd_abort_pipe(sc->sc_pipe);
@@ -196,8 +201,8 @@
        status = usbd_transfer(sc->sc_xfer);
        KASSERT(status != USBD_NORMAL_COMPLETION); /* asynchronous xfer */
        if (status != USBD_IN_PROGRESS) {
-               aprint_error_dev(sc->sc_dev, "failed to issue xfer: %d\n",
-                   status);
+               device_printf(sc->sc_dev, "failed to issue xfer: %s\n",
+                   usbd_errstr(status));
                /* We failed -- let someone else have a go.  */
                return;
        }
@@ -227,14 +232,16 @@
 
        /* Check the transfer status.  */
        if (status) {
-               aprint_error_dev(sc->sc_dev, "xfer failed: %d\n", status);
-               return;
+               device_printf(sc->sc_dev, "xfer failed: %s\n",
+                   usbd_errstr(status));
+               pktsize = 0;
+               goto out;
        }
 
        /* Get and sanity-check the transferred size.  */
        usbd_get_xfer_status(xfer, NULL, &pkt, &pktsize, NULL);
        if (pktsize > sc->sc_maxpktsize) {
-               aprint_error_dev(sc->sc_dev,
+               device_printf(sc->sc_dev,
                    "bogus packet size: %"PRIu32" > %"PRIu16" (max), ignoring"
                    "\n",
                    pktsize, sc->sc_maxpktsize);



Home | Main Index | Thread Index | Old Index