summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorn_hibma <n_hibma@FreeBSD.org>2001-09-02 09:26:14 +0000
committern_hibma <n_hibma@FreeBSD.org>2001-09-02 09:26:14 +0000
commit8d3cf62e68b29b3aa2a0b90b438389799f660b83 (patch)
tree2b374499d95568b635e6846c65fe8d0cb12eacd6
parentd280926250c4f3a68af238c5ff83287cca0c36e2 (diff)
downloadFreeBSD-src-8d3cf62e68b29b3aa2a0b90b438389799f660b83.zip
FreeBSD-src-8d3cf62e68b29b3aa2a0b90b438389799f660b83.tar.gz
Only clear endpoint stall if status was USBD_STALLED.
This avoids panicing the system by unplugging a hub. The interrupt transfer would sometimes arrive after the driver had been removed.
-rw-r--r--sys/dev/usb/ugen.c3
-rw-r--r--sys/dev/usb/uhid.c3
-rw-r--r--sys/dev/usb/uhub.c6
-rw-r--r--sys/dev/usb/ukbd.c3
-rw-r--r--sys/dev/usb/umodem.c6
-rw-r--r--sys/dev/usb/ums.c3
6 files changed, 15 insertions, 9 deletions
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c
index 7a10e45..637c7a0 100644
--- a/sys/dev/usb/ugen.c
+++ b/sys/dev/usb/ugen.c
@@ -861,7 +861,8 @@ ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
if (status != USBD_NORMAL_COMPLETION) {
DPRINTF(("ugenintr: status=%d\n", status));
- usbd_clear_endpoint_stall_async(sce->pipeh);
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sce->pipeh);
return;
}
diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c
index f233e17..cffc5e5 100644
--- a/sys/dev/usb/uhid.c
+++ b/sys/dev/usb/uhid.c
@@ -351,7 +351,8 @@ uhid_intr(xfer, addr, status)
if (status != USBD_NORMAL_COMPLETION) {
DPRINTF(("uhid_intr: status=%d\n", status));
- sc->sc_state |= UHID_NEEDCLEAR;
+ if (status == USBD_STALLED)
+ sc->sc_state |= UHID_NEEDCLEAR;
return;
}
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c
index ab22fe9..f87879f 100644
--- a/sys/dev/usb/uhub.c
+++ b/sys/dev/usb/uhub.c
@@ -577,10 +577,10 @@ uhub_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
struct uhub_softc *sc = addr;
DPRINTFN(5,("uhub_intr: sc=%p\n", sc));
- if (status != USBD_NORMAL_COMPLETION)
+ if (status == USBD_STALLED)
usbd_clear_endpoint_stall_async(sc->sc_ipipe);
-
- usb_needs_explore(sc->sc_hub->bus);
+ else if (status == USBD_NORMAL_COMPLETION)
+ usb_needs_explore(sc->sc_hub->bus);
}
#if defined(__FreeBSD__)
diff --git a/sys/dev/usb/ukbd.c b/sys/dev/usb/ukbd.c
index ad2c8f1..6d3aa4e 100644
--- a/sys/dev/usb/ukbd.c
+++ b/sys/dev/usb/ukbd.c
@@ -700,7 +700,8 @@ ukbd_interrupt(keyboard_t *kbd, void *arg)
if (status != USBD_NORMAL_COMPLETION) {
DPRINTF(("ukbd_intr: status=%d\n", status));
- usbd_clear_endpoint_stall_async(state->ks_intrpipe);
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(state->ks_intrpipe);
return 0;
}
diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c
index 6d4aa16..05c9a47 100644
--- a/sys/dev/usb/umodem.c
+++ b/sys/dev/usb/umodem.c
@@ -479,7 +479,8 @@ umodemwritecb(xfer, priv, status)
if (status != USBD_NORMAL_COMPLETION) {
DPRINTF(("umodemwritecb: status=%d\n", status));
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
/* XXX we should restart after some delay. */
return;
}
@@ -753,7 +754,8 @@ umodemreadcb(xfer, p, status)
if (status != USBD_NORMAL_COMPLETION) {
DPRINTF(("umodemreadcb: status=%d\n", status));
- usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe);
/* XXX we should restart after some delay. */
return;
}
diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c
index c3ac612..ffabb7b 100644
--- a/sys/dev/usb/ums.c
+++ b/sys/dev/usb/ums.c
@@ -421,7 +421,8 @@ ums_intr(xfer, addr, status)
if (status != USBD_NORMAL_COMPLETION) {
DPRINTF(("ums_intr: status=%d\n", status));
- usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
+ if (status == USBD_STALLED)
+ usbd_clear_endpoint_stall_async(sc->sc_intrpipe);
return;
}
OpenPOWER on IntegriCloud