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