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 *);