Tue Apr 26 07:41:18 2011 UTC ()
Fixup previous.

The bug was in scsibusdetach(), which is not doing things in the proper
order: it has to detach its children and check for error.  If no error,
then it can release the resources that the children were using.

From David Young via source-changes-d.


(hannken)
diff -r1.261 -r1.262 src/sys/dev/scsipi/scsiconf.c

cvs diff -r1.261 -r1.262 src/sys/dev/scsipi/scsiconf.c (expand / switch to unified diff)

--- src/sys/dev/scsipi/scsiconf.c 2011/04/25 14:14:22 1.261
+++ src/sys/dev/scsipi/scsiconf.c 2011/04/26 07:41:18 1.262
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: scsiconf.c,v 1.261 2011/04/25 14:14:22 hannken Exp $ */ 1/* $NetBSD: scsiconf.c,v 1.262 2011/04/26 07:41:18 hannken Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998, 1999, 2004 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 1999, 2004 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace 8 * by Charles M. Hannum; Jason R. Thorpe of the Numerical Aerospace
9 * Simulation Facility, NASA Ames Research Center. 9 * Simulation Facility, NASA Ames Research Center.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -38,27 +38,27 @@ @@ -38,27 +38,27 @@
38 * Mellon University, makes this software available to CMU to distribute 38 * Mellon University, makes this software available to CMU to distribute
39 * or use in any manner that they see fit as long as this message is kept with 39 * or use in any manner that they see fit as long as this message is kept with
40 * the software. For this reason TFS also grants any other persons or 40 * the software. For this reason TFS also grants any other persons or
41 * organisations permission to use or modify this software. 41 * organisations permission to use or modify this software.
42 * 42 *
43 * TFS supplies this software to be publicly redistributed 43 * TFS supplies this software to be publicly redistributed
44 * on the understanding that TFS is not responsible for the correct 44 * on the understanding that TFS is not responsible for the correct
45 * functioning of this software in any circumstances. 45 * functioning of this software in any circumstances.
46 * 46 *
47 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992 47 * Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
48 */ 48 */
49 49
50#include <sys/cdefs.h> 50#include <sys/cdefs.h>
51__KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.261 2011/04/25 14:14:22 hannken Exp $"); 51__KERNEL_RCSID(0, "$NetBSD: scsiconf.c,v 1.262 2011/04/26 07:41:18 hannken Exp $");
52 52
53#include <sys/param.h> 53#include <sys/param.h>
54#include <sys/systm.h> 54#include <sys/systm.h>
55#include <sys/kernel.h> 55#include <sys/kernel.h>
56#include <sys/proc.h> 56#include <sys/proc.h>
57#include <sys/kthread.h> 57#include <sys/kthread.h>
58#include <sys/malloc.h> 58#include <sys/malloc.h>
59#include <sys/mutex.h> 59#include <sys/mutex.h>
60#include <sys/once.h> 60#include <sys/once.h>
61#include <sys/device.h> 61#include <sys/device.h>
62#include <sys/conf.h> 62#include <sys/conf.h>
63#include <sys/fcntl.h> 63#include <sys/fcntl.h>
64#include <sys/scsiio.h> 64#include <sys/scsiio.h>
@@ -246,60 +246,61 @@ scsibus_config(struct scsipi_channel *ch @@ -246,60 +246,61 @@ scsibus_config(struct scsipi_channel *ch
246 config_pending_decr(); 246 config_pending_decr();
247} 247}
248 248
249static int 249static int
250scsibusdetach(device_t self, int flags) 250scsibusdetach(device_t self, int flags)
251{ 251{
252 struct scsibus_softc *sc = device_private(self); 252 struct scsibus_softc *sc = device_private(self);
253 struct scsipi_channel *chan = sc->sc_channel; 253 struct scsipi_channel *chan = sc->sc_channel;
254 struct scsipi_periph *periph; 254 struct scsipi_periph *periph;
255 int ctarget, clun; 255 int ctarget, clun;
256 struct scsipi_xfer *xs; 256 struct scsipi_xfer *xs;
257 int error; 257 int error;
258 258
 259 /*
 260 * Detach all of the periphs.
 261 */
 262 if ((error = scsipi_target_detach(chan, -1, -1, flags)) != 0)
 263 return error;
 264
259 pmf_device_deregister(self); 265 pmf_device_deregister(self);
260 266
261 /* 267 /*
262 * Process outstanding commands (which will never complete as the 268 * Process outstanding commands (which will never complete as the
263 * controller is gone). 269 * controller is gone).
 270 *
 271 * XXX Surely this is redundant? If we get this far, the
 272 * XXX peripherals have all been detached.
264 */ 273 */
265 for (ctarget = 0; ctarget < chan->chan_ntargets; ctarget++) { 274 for (ctarget = 0; ctarget < chan->chan_ntargets; ctarget++) {
266 if (ctarget == chan->chan_id) 275 if (ctarget == chan->chan_id)
267 continue; 276 continue;
268 for (clun = 0; clun < chan->chan_nluns; clun++) { 277 for (clun = 0; clun < chan->chan_nluns; clun++) {
269 periph = scsipi_lookup_periph(chan, ctarget, clun); 278 periph = scsipi_lookup_periph(chan, ctarget, clun);
270 if (periph == NULL) 279 if (periph == NULL)
271 continue; 280 continue;
272 if ((flags & DETACH_SHUTDOWN) != 0) 
273 return EBUSY; 
274 TAILQ_FOREACH(xs, &periph->periph_xferq, device_q) { 281 TAILQ_FOREACH(xs, &periph->periph_xferq, device_q) {
275 callout_stop(&xs->xs_callout); 282 callout_stop(&xs->xs_callout);
276 xs->error = XS_DRIVER_STUFFUP; 283 xs->error = XS_DRIVER_STUFFUP;
277 scsipi_done(xs); 284 scsipi_done(xs);
278 } 285 }
279 } 286 }
280 } 287 }
281 288
282 /* 289 /*
283 * Detach all of the periphs. 
284 */ 
285 error = scsipi_target_detach(chan, -1, -1, flags); 
286 
287 /* 
288 * Now shut down the channel. 290 * Now shut down the channel.
289 * XXX only if no errors ? 
290 */ 291 */
291 scsipi_channel_shutdown(chan); 292 scsipi_channel_shutdown(chan);
292 return (error); 293 return 0;
293} 294}
294 295
295/* 296/*
296 * Probe the requested scsi bus. It must be already set up. 297 * Probe the requested scsi bus. It must be already set up.
297 * target and lun optionally narrow the search if not -1 298 * target and lun optionally narrow the search if not -1
298 */ 299 */
299int 300int
300scsi_probe_bus(struct scsibus_softc *sc, int target, int lun) 301scsi_probe_bus(struct scsibus_softc *sc, int target, int lun)
301{ 302{
302 struct scsipi_channel *chan = sc->sc_channel; 303 struct scsipi_channel *chan = sc->sc_channel;
303 int maxtarget, mintarget, maxlun, minlun; 304 int maxtarget, mintarget, maxlun, minlun;
304 int error; 305 int error;
305 306