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