Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/usb Handle abort paths gracefully on detach.



details:   https://anonhg.NetBSD.org/src/rev/5759cac2a8a2
branches:  trunk
changeset: 445804:5759cac2a8a2
user:      mlelstv <mlelstv%NetBSD.org@localhost>
date:      Tue Nov 13 10:30:57 2018 +0000

description:
Handle abort paths gracefully on detach.

diffstat:

 sys/dev/usb/umass.c        |  29 ++++++++++++++++++++++++-----
 sys/dev/usb/umass_scsipi.c |  21 +++++++++++++++++----
 sys/dev/usb/umassvar.h     |   3 ++-
 3 files changed, 43 insertions(+), 10 deletions(-)

diffs (155 lines):

diff -r 334a7510e511 -r 5759cac2a8a2 sys/dev/usb/umass.c
--- a/sys/dev/usb/umass.c       Tue Nov 13 10:30:35 2018 +0000
+++ b/sys/dev/usb/umass.c       Tue Nov 13 10:30:57 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: umass.c,v 1.165 2018/10/24 09:41:24 martin Exp $       */
+/*     $NetBSD: umass.c,v 1.166 2018/11/13 10:30:57 mlelstv Exp $      */
 
 /*
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -124,7 +124,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.165 2018/10/24 09:41:24 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.166 2018/11/13 10:30:57 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -801,7 +801,9 @@
 
        DPRINTFM(UDMASS_USB, "sc %#jx detached", (uintptr_t)sc, 0, 0, 0);
 
+       mutex_enter(&sc->sc_lock);
        sc->sc_dying = true;
+       mutex_exit(&sc->sc_lock);
 
        pmf_device_deregister(self);
 
@@ -1179,9 +1181,6 @@
                   "sc->sc_wire == 0x%02x wrong for umass_bbb_state\n",
                   sc->sc_wire);
 
-       if (sc->sc_dying)
-               return;
-
        /*
         * State handling for BBB transfers.
         *
@@ -1197,6 +1196,18 @@
            (uintptr_t)sc, (uintptr_t)xfer, sc->transfer_state,
            sc->transfer_dir);
 
+       if (err == USBD_CANCELLED) {
+               DPRINTFM(UDMASS_BBB, "sc %#jx xfer %#jx cancelled",
+                   (uintptr_t)sc, (uintptr_t)xfer, 0, 0);
+
+               sc->transfer_state = TSTATE_IDLE;
+               sc->transfer_cb(sc, sc->transfer_priv, 0, STATUS_TIMEOUT);
+               return;
+       }
+
+       if (sc->sc_dying)
+               return;
+
        switch (sc->transfer_state) {
 
        /***** Bulk Transfer *****/
@@ -1635,6 +1646,14 @@
                   "sc->sc_wire == 0x%02x wrong for umass_cbi_state\n",
                   sc->sc_wire);
 
+       if (err == USBD_CANCELLED) {
+               DPRINTFM(UDMASS_BBB, "sc %#jx xfer %#jx cancelled",
+                       (uintptr_t)sc, (uintptr_t)xfer, 0, 0);
+               sc->transfer_state = TSTATE_IDLE;
+               sc->transfer_cb(sc, sc->transfer_priv, 0, STATUS_TIMEOUT);
+               return;
+       }
+
        if (sc->sc_dying)
                return;
 
diff -r 334a7510e511 -r 5759cac2a8a2 sys/dev/usb/umass_scsipi.c
--- a/sys/dev/usb/umass_scsipi.c        Tue Nov 13 10:30:35 2018 +0000
+++ b/sys/dev/usb/umass_scsipi.c        Tue Nov 13 10:30:57 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: umass_scsipi.c,v 1.55 2017/10/28 00:37:12 pgoyette Exp $       */
+/*     $NetBSD: umass_scsipi.c,v 1.56 2018/11/13 10:30:57 mlelstv Exp $        */
 
 /*
  * Copyright (c) 2001, 2003, 2012 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: umass_scsipi.c,v 1.55 2017/10/28 00:37:12 pgoyette Exp $");
+__KERNEL_RCSID(0, "$NetBSD: umass_scsipi.c,v 1.56 2018/11/13 10:30:57 mlelstv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_usb.h"
@@ -136,12 +136,17 @@
        scbus->sc_channel.chan_id = scbus->sc_channel.chan_ntargets - 1;
        DPRINTFM(UDMASS_USB, "sc %#jx: SCSI", (uintptr_t)sc, 0, 0, 0);
 
+       mutex_enter(&sc->sc_lock);
        sc->sc_refcnt++;
+       mutex_exit(&sc->sc_lock);
        scbus->base.sc_child =
            config_found_ia(sc->sc_dev, "scsi", &scbus->sc_channel,
                scsiprint);
+       mutex_enter(&sc->sc_lock);
        if (--sc->sc_refcnt < 0)
-               usb_detach_wakeupold(sc->sc_dev);
+               usb_detach_broadcast(sc->sc_dev, &sc->sc_detach_cv);
+       mutex_exit(&sc->sc_lock);
+
 
        return 0;
 }
@@ -164,12 +169,16 @@
        scbus->sc_channel.chan_defquirks |= sc->sc_busquirks;
        DPRINTFM(UDMASS_USB, "sc %#jxp: ATAPI", (uintptr_t)sc, 0, 0, 0);
 
+       mutex_enter(&sc->sc_lock);
        sc->sc_refcnt++;
+       mutex_exit(&sc->sc_lock);
        scbus->base.sc_child =
            config_found_ia(sc->sc_dev, "atapi", &scbus->sc_channel,
                atapiprint);
+       mutex_enter(&sc->sc_lock);
        if (--sc->sc_refcnt < 0)
-               usb_detach_wakeupold(sc->sc_dev);
+               usb_detach_broadcast(sc->sc_dev, &sc->sc_detach_cv);
+       mutex_exit(&sc->sc_lock);
 
        return 0;
 }
@@ -445,6 +454,10 @@
                xs->error = XS_RESET;
                break;
 
+       case STATUS_TIMEOUT:
+               xs->error = XS_TIMEOUT;
+               break;
+
        default:
                panic("%s: Unknown status %d in umass_scsipi_cb",
                        device_xname(sc->sc_dev), status);
diff -r 334a7510e511 -r 5759cac2a8a2 sys/dev/usb/umassvar.h
--- a/sys/dev/usb/umassvar.h    Tue Nov 13 10:30:35 2018 +0000
+++ b/sys/dev/usb/umassvar.h    Tue Nov 13 10:30:57 2018 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: umassvar.h,v 1.38 2016/07/03 07:27:37 skrll Exp $      */
+/*     $NetBSD: umassvar.h,v 1.39 2018/11/13 10:30:57 mlelstv Exp $    */
 
 /*-
  * Copyright (c) 1999 MAEKAWA Masahide <bishop%rr.iij4u.or.jp@localhost>,
@@ -135,6 +135,7 @@
 #define STATUS_CMD_UNKNOWN     1       /* will have to fetch sense */
 #define STATUS_CMD_FAILED      2       /* transfer was ok, command failed */
 #define STATUS_WIRE_FAILED     3       /* couldn't even get command across */
+#define STATUS_TIMEOUT         4       /* transfer aborted */
 
 typedef void (*umass_wire_xfer)(struct umass_softc *, int, void *, int, void *,
                                int, int, u_int, int, umass_callback, void *);



Home | Main Index | Thread Index | Old Index