Module Name:    src
Committed By:   snj
Date:           Wed Jun 21 18:18:55 UTC 2017

Modified Files:
        src/sys/dev/scsipi [netbsd-8]: atapiconf.c cd.c scsi_base.c scsiconf.c
            scsipi_base.c sd.c ss.c st.c

Log Message:
Pull up following revision(s) (requested by mlelstv in ticket #53):
        sys/dev/scsipi/atapiconf.c: revision 1.91
        sys/dev/scsipi/cd.c: revision 1.341
        sys/dev/scsipi/scsi_base.c: revision 1.92
        sys/dev/scsipi/scsiconf.c: revision 1.280
        sys/dev/scsipi/scsipi_base.c: revisions 1.176, 1.177
        sys/dev/scsipi/sd.c: revision 1.325
        sys/dev/scsipi/ss.c: revision 1.89
        sys/dev/scsipi/st.c: revision 1.231
The atapibus detach path did hold the channel mutex while calling into autoconf,
which would trigger a panic when unplugging a USB ATAPI CDROM.
Align detach code for scsibus and atapibus to fix this.
Also avoid races when detaching devices by replacing callout_stop with
callout_halt.
--
pass config_detach error to caller.


To generate a diff of this commit:
cvs rdiff -u -r1.90 -r1.90.8.1 src/sys/dev/scsipi/atapiconf.c
cvs rdiff -u -r1.340 -r1.340.6.1 src/sys/dev/scsipi/cd.c
cvs rdiff -u -r1.91 -r1.91.8.1 src/sys/dev/scsipi/scsi_base.c
cvs rdiff -u -r1.279 -r1.279.6.1 src/sys/dev/scsipi/scsiconf.c
cvs rdiff -u -r1.175 -r1.175.8.1 src/sys/dev/scsipi/scsipi_base.c
cvs rdiff -u -r1.324 -r1.324.6.1 src/sys/dev/scsipi/sd.c
cvs rdiff -u -r1.88 -r1.88.8.1 src/sys/dev/scsipi/ss.c
cvs rdiff -u -r1.230 -r1.230.8.1 src/sys/dev/scsipi/st.c

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/scsipi/atapiconf.c
diff -u src/sys/dev/scsipi/atapiconf.c:1.90 src/sys/dev/scsipi/atapiconf.c:1.90.8.1
--- src/sys/dev/scsipi/atapiconf.c:1.90	Tue Nov 29 03:23:00 2016
+++ src/sys/dev/scsipi/atapiconf.c	Wed Jun 21 18:18:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: atapiconf.c,v 1.90 2016/11/29 03:23:00 mlelstv Exp $	*/
+/*	$NetBSD: atapiconf.c,v 1.90.8.1 2017/06/21 18:18:55 snj Exp $	*/
 
 /*
  * Copyright (c) 1996, 2001 Manuel Bouyer.  All rights reserved.
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: atapiconf.c,v 1.90 2016/11/29 03:23:00 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: atapiconf.c,v 1.90.8.1 2017/06/21 18:18:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -147,6 +147,7 @@ atapibusattach(device_t parent, device_t
 	sc->sc_dev = self;
 
 	chan->chan_name = device_xname(sc->sc_dev);
+	chan->chan_id = -1;
 
 	/* ATAPI has no LUNs. */
 	chan->chan_nluns = 1;
@@ -192,38 +193,27 @@ atapibuschilddet(device_t self, device_t
 	mutex_exit(chan_mtx(chan));
 }
 
+/* same as scsibusdetach */
 static int
 atapibusdetach(device_t self, int flags)
 {
 	struct atapibus_softc *sc = device_private(self);
 	struct scsipi_channel *chan = sc->sc_channel;
-	struct scsipi_periph *periph;
-	int target, error = 0;
+	int error = 0;
 
 	/*
-	 * Shut down the channel.
+	 * Detach all of the periphs.
 	 */
-	scsipi_channel_shutdown(chan);
+	error = scsipi_target_detach(chan, -1, -1, flags);
+	if (error)
+		return error;
 
-	/* for config_detach() */
-	KERNEL_LOCK(1, curlwp);
+	pmf_device_deregister(self);
 
 	/*
-	 * Now detach all of the periphs.
+	 * Shut down the channel.
 	 */
-	mutex_enter(chan_mtx(chan));
-	for (target = 0; target < chan->chan_ntargets; target++) {
-		periph = scsipi_lookup_periph_locked(chan, target, 0);
-		if (periph == NULL)
-			continue;
-		error = config_detach(periph->periph_dev, flags);
-		if (error) {
-			mutex_exit(chan_mtx(chan));
-			goto out;
-		}
-		KASSERT(scsipi_lookup_periph(chan, target, 0) == NULL);
-	}
-	mutex_exit(chan_mtx(chan));
+	scsipi_channel_shutdown(chan);
 
 	cv_destroy(&chan->chan_cv_xs);
 	cv_destroy(&chan->chan_cv_comp);
@@ -232,10 +222,7 @@ atapibusdetach(device_t self, int flags)
 	if (atomic_dec_uint_nv(&chan_running(chan)) == 0)
 		mutex_destroy(chan_mtx(chan));
 
-out:
-	/* XXXSMP scsipi */
-	KERNEL_UNLOCK_ONE(curlwp);
-	return error;
+	return 0;
 }
 
 static int

Index: src/sys/dev/scsipi/cd.c
diff -u src/sys/dev/scsipi/cd.c:1.340 src/sys/dev/scsipi/cd.c:1.340.6.1
--- src/sys/dev/scsipi/cd.c:1.340	Sat Apr  8 13:50:23 2017
+++ src/sys/dev/scsipi/cd.c	Wed Jun 21 18:18:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: cd.c,v 1.340 2017/04/08 13:50:23 mlelstv Exp $	*/
+/*	$NetBSD: cd.c,v 1.340.6.1 2017/06/21 18:18:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2001, 2003, 2004, 2005, 2008 The NetBSD Foundation,
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.340 2017/04/08 13:50:23 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cd.c,v 1.340.6.1 2017/06/21 18:18:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -354,7 +354,7 @@ cddetach(device_t self, int flags)
 	}
 
 	/* kill any pending restart */
-	callout_stop(&cd->sc_callout);
+	callout_halt(&cd->sc_callout, NULL);
 
 	dk_drain(dksc);
 

Index: src/sys/dev/scsipi/scsi_base.c
diff -u src/sys/dev/scsipi/scsi_base.c:1.91 src/sys/dev/scsipi/scsi_base.c:1.91.8.1
--- src/sys/dev/scsipi/scsi_base.c:1.91	Sun Nov 20 15:37:19 2016
+++ src/sys/dev/scsipi/scsi_base.c	Wed Jun 21 18:18:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: scsi_base.c,v 1.91 2016/11/20 15:37:19 mlelstv Exp $	*/
+/*	$NetBSD: scsi_base.c,v 1.91.8.1 2017/06/21 18:18:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: scsi_base.c,v 1.91 2016/11/20 15:37:19 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scsi_base.c,v 1.91.8.1 2017/06/21 18:18:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -116,6 +116,16 @@ scsi_print_addr(struct scsipi_periph *pe
 void
 scsi_kill_pending(struct scsipi_periph *periph)
 {
+	struct scsipi_xfer *xs;
+
+	TAILQ_FOREACH(xs, &periph->periph_xferq, device_q) {
+		callout_stop(&xs->xs_callout);
+		scsi_print_addr(periph);
+		printf("killed ");
+		scsipi_print_cdb(xs->cmd);
+		xs->error = XS_DRIVER_STUFFUP;
+		scsipi_done(xs);
+	}
 }
 
 /*

Index: src/sys/dev/scsipi/scsiconf.c
diff -u src/sys/dev/scsipi/scsiconf.c:1.279 src/sys/dev/scsipi/scsiconf.c:1.279.6.1
--- src/sys/dev/scsipi/scsiconf.c:1.279	Sat Mar 18 08:05:40 2017
+++ src/sys/dev/scsipi/scsiconf.c	Wed Jun 21 18:18:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: scsiconf.c,v 1.279 2017/03/18 08:05:40 tsutsui Exp $	*/
+/*	$NetBSD: scsiconf.c,v 1.279.6.1 2017/06/21 18:18:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 1998, 1999, 2004 The NetBSD Foundation, Inc.
@@ -48,7 +48,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.279 2017/03/18 08:05:40 tsutsui Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.279.6.1 2017/06/21 18:18:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -333,43 +333,19 @@ scsibusdetach(device_t self, int flags)
 {
 	struct scsibus_softc *sc = device_private(self);
 	struct scsipi_channel *chan = sc->sc_channel;
-	struct scsipi_periph *periph;
-	int ctarget, clun;
-	struct scsipi_xfer *xs;
 	int error;
 
 	/*
 	 * Detach all of the periphs.
 	 */
-	if ((error = scsipi_target_detach(chan, -1, -1, flags)) != 0)
+	error = scsipi_target_detach(chan, -1, -1, flags);
+	if (error)
 		return error;
 
 	pmf_device_deregister(self);
 
 	/*
-	 * Process outstanding commands (which will never complete as the
-	 * controller is gone).
-	 *
-	 * XXX Surely this is redundant?  If we get this far, the
-	 * XXX peripherals have all been detached.
-	 */
-	for (ctarget = 0; ctarget < chan->chan_ntargets; ctarget++) {
-		if (ctarget == chan->chan_id)
-			continue;
-		for (clun = 0; clun < chan->chan_nluns; clun++) {
-			periph = scsipi_lookup_periph(chan, ctarget, clun);
-			if (periph == NULL)
-				continue;
-			TAILQ_FOREACH(xs, &periph->periph_xferq, device_q) {
-				callout_stop(&xs->xs_callout);
-				xs->error = XS_DRIVER_STUFFUP;
-				scsipi_done(xs);
-			}
-		}
-	}
-
-	/*
-	 * Now shut down the channel.
+	 * Shut down the channel.
 	 */
 	scsipi_channel_shutdown(chan);
 

Index: src/sys/dev/scsipi/scsipi_base.c
diff -u src/sys/dev/scsipi/scsipi_base.c:1.175 src/sys/dev/scsipi/scsipi_base.c:1.175.8.1
--- src/sys/dev/scsipi/scsipi_base.c:1.175	Thu Dec 22 11:19:21 2016
+++ src/sys/dev/scsipi/scsipi_base.c	Wed Jun 21 18:18:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: scsipi_base.c,v 1.175 2016/12/22 11:19:21 mlelstv Exp $	*/
+/*	$NetBSD: scsipi_base.c,v 1.175.8.1 2017/06/21 18:18:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 1998, 1999, 2000, 2002, 2003, 2004 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.175 2016/12/22 11:19:21 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: scsipi_base.c,v 1.175.8.1 2017/06/21 18:18:55 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_scsi.h"
@@ -2400,9 +2400,10 @@ scsipi_target_detach(struct scsipi_chann
     int flags)
 {
 	struct scsipi_periph *periph;
+	device_t tdev;
 	int ctarget, mintarget, maxtarget;
 	int clun, minlun, maxlun;
-	int error;
+	int error = 0;
 
 	if (target == -1) {
 		mintarget = 0;
@@ -2426,20 +2427,33 @@ scsipi_target_detach(struct scsipi_chann
 		maxlun = lun + 1;
 	}
 
+	/* for config_detach */
+	KERNEL_LOCK(1, curlwp);
+
+	mutex_enter(chan_mtx(chan));
 	for (ctarget = mintarget; ctarget < maxtarget; ctarget++) {
 		if (ctarget == chan->chan_id)
 			continue;
 
 		for (clun = minlun; clun < maxlun; clun++) {
-			periph = scsipi_lookup_periph(chan, ctarget, clun);
+			periph = scsipi_lookup_periph_locked(chan, ctarget, clun);
 			if (periph == NULL)
 				continue;
-			error = config_detach(periph->periph_dev, flags);
+			tdev = periph->periph_dev;
+			mutex_exit(chan_mtx(chan));
+			error = config_detach(tdev, flags);
 			if (error)
-				return error;
+				goto out;
+			mutex_enter(chan_mtx(chan));
+			KASSERT(scsipi_lookup_periph_locked(chan, ctarget, clun) == NULL);
 		}
 	}
-	return 0;
+	mutex_exit(chan_mtx(chan));
+
+out:
+	KERNEL_UNLOCK_ONE(curlwp);
+
+	return error;
 }
 
 /*

Index: src/sys/dev/scsipi/sd.c
diff -u src/sys/dev/scsipi/sd.c:1.324 src/sys/dev/scsipi/sd.c:1.324.6.1
--- src/sys/dev/scsipi/sd.c:1.324	Mon Apr 10 18:20:43 2017
+++ src/sys/dev/scsipi/sd.c	Wed Jun 21 18:18:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: sd.c,v 1.324 2017/04/10 18:20:43 jdolecek Exp $	*/
+/*	$NetBSD: sd.c,v 1.324.6.1 2017/06/21 18:18:55 snj Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc.
@@ -47,7 +47,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.324 2017/04/10 18:20:43 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.324.6.1 2017/06/21 18:18:55 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_scsi.h"
@@ -385,7 +385,7 @@ sddetach(device_t self, int flags)
 	}
 
 	/* kill any pending restart */
-	callout_stop(&sd->sc_callout);
+	callout_halt(&sd->sc_callout, NULL);
 
 	dk_drain(dksc);
 

Index: src/sys/dev/scsipi/ss.c
diff -u src/sys/dev/scsipi/ss.c:1.88 src/sys/dev/scsipi/ss.c:1.88.8.1
--- src/sys/dev/scsipi/ss.c:1.88	Sun Nov 20 15:37:19 2016
+++ src/sys/dev/scsipi/ss.c	Wed Jun 21 18:18:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: ss.c,v 1.88 2016/11/20 15:37:19 mlelstv Exp $	*/
+/*	$NetBSD: ss.c,v 1.88.8.1 2017/06/21 18:18:55 snj Exp $	*/
 
 /*
  * Copyright (c) 1995 Kenneth Stailey.  All rights reserved.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ss.c,v 1.88 2016/11/20 15:37:19 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ss.c,v 1.88.8.1 2017/06/21 18:18:55 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -207,7 +207,7 @@ ssdetach(device_t self, int flags)
 	cmaj = cdevsw_lookup_major(&ss_cdevsw);
 
 	/* kill any pending restart */
-	callout_stop(&ss->sc_callout);
+	callout_halt(&ss->sc_callout, NULL);
 
 	mutex_enter(chan_mtx(chan));
 

Index: src/sys/dev/scsipi/st.c
diff -u src/sys/dev/scsipi/st.c:1.230 src/sys/dev/scsipi/st.c:1.230.8.1
--- src/sys/dev/scsipi/st.c:1.230	Sun Nov 20 15:37:19 2016
+++ src/sys/dev/scsipi/st.c	Wed Jun 21 18:18:55 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: st.c,v 1.230 2016/11/20 15:37:19 mlelstv Exp $ */
+/*	$NetBSD: st.c,v 1.230.8.1 2017/06/21 18:18:55 snj Exp $ */
 
 /*-
  * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc.
@@ -50,7 +50,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: st.c,v 1.230 2016/11/20 15:37:19 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: st.c,v 1.230.8.1 2017/06/21 18:18:55 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_scsi.h"
@@ -440,7 +440,7 @@ stdetach(device_t self, int flags)
 	cmaj = cdevsw_lookup_major(&st_cdevsw);
 
 	/* kill any pending restart */
-	callout_stop(&st->sc_callout);
+	callout_halt(&st->sc_callout, NULL);
 
 	mutex_enter(chan_mtx(chan));
 

Reply via email to