Module Name:    src
Committed By:   mlelstv
Date:           Tue Nov 13 10:30:57 UTC 2018

Modified Files:
        src/sys/dev/usb: umass.c umass_scsipi.c umassvar.h

Log Message:
Handle abort paths gracefully on detach.


To generate a diff of this commit:
cvs rdiff -u -r1.165 -r1.166 src/sys/dev/usb/umass.c
cvs rdiff -u -r1.55 -r1.56 src/sys/dev/usb/umass_scsipi.c
cvs rdiff -u -r1.38 -r1.39 src/sys/dev/usb/umassvar.h

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/umass.c
diff -u src/sys/dev/usb/umass.c:1.165 src/sys/dev/usb/umass.c:1.166
--- src/sys/dev/usb/umass.c:1.165	Wed Oct 24 09:41:24 2018
+++ src/sys/dev/usb/umass.c	Tue Nov 13 10:30:57 2018
@@ -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 @@ umass_detach(device_t self, int flags)
 
 	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 @@ umass_bbb_state(struct usbd_xfer *xfer, 
 		   "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 @@ umass_bbb_state(struct usbd_xfer *xfer, 
 	    (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 @@ umass_cbi_state(struct usbd_xfer *xfer, 
 		   "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;
 

Index: src/sys/dev/usb/umass_scsipi.c
diff -u src/sys/dev/usb/umass_scsipi.c:1.55 src/sys/dev/usb/umass_scsipi.c:1.56
--- src/sys/dev/usb/umass_scsipi.c:1.55	Sat Oct 28 00:37:12 2017
+++ src/sys/dev/usb/umass_scsipi.c	Tue Nov 13 10:30:57 2018
@@ -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 @@ umass_scsi_attach(struct umass_softc *sc
 	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 @@ umass_atapi_attach(struct umass_softc *s
 	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 @@ umass_scsipi_cb(struct umass_softc *sc, 
 		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);

Index: src/sys/dev/usb/umassvar.h
diff -u src/sys/dev/usb/umassvar.h:1.38 src/sys/dev/usb/umassvar.h:1.39
--- src/sys/dev/usb/umassvar.h:1.38	Sun Jul  3 07:27:37 2016
+++ src/sys/dev/usb/umassvar.h	Tue Nov 13 10:30:57 2018
@@ -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 <[email protected]>,
@@ -135,6 +135,7 @@ typedef void (*umass_callback)(struct um
 #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 *);

Reply via email to