Module Name: src
Committed By: riastradh
Date: Sun Mar 20 00:41:01 UTC 2022
Modified Files:
src/sys/dev/usb: ualea.c
Log Message:
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
To generate a diff of this commit:
cvs rdiff -u -r1.16 -r1.17 src/sys/dev/usb/ualea.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/dev/usb/ualea.c
diff -u src/sys/dev/usb/ualea.c:1.16 src/sys/dev/usb/ualea.c:1.17
--- src/sys/dev/usb/ualea.c:1.16 Sat Mar 19 11:37:06 2022
+++ src/sys/dev/usb/ualea.c Sun Mar 20 00:41:01 2022
@@ -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 @@ ualea_detach(device_t self, int flags)
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 @@ ualea_xfer(struct ualea_softc *sc)
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 @@ ualea_xfer_done(struct usbd_xfer *xfer,
/* 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);