Tue May 19 19:56:11 2009 UTC ()
Delete wdactivate() and sdactivate().  They were no-ops, but as a
side-effect of registering them, config_detach(9) cleared DVF_ACTIVE
before it called wddetach() or sddetach().  Even though sd(4)'s
detachment may have subsequently failed with EBUSY, we could not
begin new disk I/O on sd(4) because the device had been deactivated.

By analogy to sdstrategy(), test device_is_active() in wdstrategy()
and if it is false set b_errno to EIO instead of initiating new
disk I/O.

XXX We should decline more politely to start new I/O, since
XXX !device_is_active() may mean simply that the device is suspended.
XXX I suppose that EIO is safe as long as system suspension is
XXX all-or-nothing.


(dyoung)
diff -r1.374 -r1.375 src/sys/dev/ata/wd.c
diff -r1.283 -r1.284 src/sys/dev/scsipi/sd.c

cvs diff -r1.374 -r1.375 src/sys/dev/ata/wd.c (expand / switch to unified diff)

--- src/sys/dev/ata/wd.c 2009/05/15 23:49:28 1.374
+++ src/sys/dev/ata/wd.c 2009/05/19 19:56:10 1.375
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: wd.c,v 1.374 2009/05/15 23:49:28 dyoung Exp $ */ 1/* $NetBSD: wd.c,v 1.375 2009/05/19 19:56:10 dyoung Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. 4 * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software 14 * 3. All advertising materials mentioning features or use of this software
@@ -49,27 +49,27 @@ @@ -49,27 +49,27 @@
49 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 49 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
50 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 50 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
52 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
56 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 56 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
58 * POSSIBILITY OF SUCH DAMAGE. 58 * POSSIBILITY OF SUCH DAMAGE.
59 */ 59 */
60 60
61#include <sys/cdefs.h> 61#include <sys/cdefs.h>
62__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.374 2009/05/15 23:49:28 dyoung Exp $"); 62__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.375 2009/05/19 19:56:10 dyoung Exp $");
63 63
64#include "opt_ata.h" 64#include "opt_ata.h"
65 65
66#include "rnd.h" 66#include "rnd.h"
67 67
68#include <sys/param.h> 68#include <sys/param.h>
69#include <sys/systm.h> 69#include <sys/systm.h>
70#include <sys/kernel.h> 70#include <sys/kernel.h>
71#include <sys/conf.h> 71#include <sys/conf.h>
72#include <sys/file.h> 72#include <sys/file.h>
73#include <sys/stat.h> 73#include <sys/stat.h>
74#include <sys/ioctl.h> 74#include <sys/ioctl.h>
75#include <sys/buf.h> 75#include <sys/buf.h>
@@ -119,36 +119,35 @@ __KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.374 @@ -119,36 +119,35 @@ __KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.374
119#define DEBUG_PROBE 0x10 119#define DEBUG_PROBE 0x10
120#ifdef ATADEBUG 120#ifdef ATADEBUG
121int wdcdebug_wd_mask = 0x0; 121int wdcdebug_wd_mask = 0x0;
122#define ATADEBUG_PRINT(args, level) \ 122#define ATADEBUG_PRINT(args, level) \
123 if (wdcdebug_wd_mask & (level)) \ 123 if (wdcdebug_wd_mask & (level)) \
124 printf args 124 printf args
125#else 125#else
126#define ATADEBUG_PRINT(args, level) 126#define ATADEBUG_PRINT(args, level)
127#endif 127#endif
128 128
129int wdprobe(device_t, cfdata_t, void *); 129int wdprobe(device_t, cfdata_t, void *);
130void wdattach(device_t, device_t, void *); 130void wdattach(device_t, device_t, void *);
131int wddetach(device_t, int); 131int wddetach(device_t, int);
132int wdactivate(device_t, enum devact); 
133int wdprint(void *, char *); 132int wdprint(void *, char *);
134void wdperror(const struct wd_softc *); 133void wdperror(const struct wd_softc *);
135 134
136static void wdlastclose(struct wd_softc *); 135static void wdlastclose(struct wd_softc *);
137static bool wd_suspend(device_t PMF_FN_PROTO); 136static bool wd_suspend(device_t PMF_FN_PROTO);
138static int wd_standby(struct wd_softc *, int); 137static int wd_standby(struct wd_softc *, int);
139 138
140CFATTACH_DECL3_NEW(wd, sizeof(struct wd_softc), 139CFATTACH_DECL3_NEW(wd, sizeof(struct wd_softc),
141 wdprobe, wdattach, wddetach, wdactivate, NULL, NULL, DVF_DETACH_SHUTDOWN); 140 wdprobe, wdattach, wddetach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
142 141
143extern struct cfdriver wd_cd; 142extern struct cfdriver wd_cd;
144 143
145dev_type_open(wdopen); 144dev_type_open(wdopen);
146dev_type_close(wdclose); 145dev_type_close(wdclose);
147dev_type_read(wdread); 146dev_type_read(wdread);
148dev_type_write(wdwrite); 147dev_type_write(wdwrite);
149dev_type_ioctl(wdioctl); 148dev_type_ioctl(wdioctl);
150dev_type_strategy(wdstrategy); 149dev_type_strategy(wdstrategy);
151dev_type_dump(wddump); 150dev_type_dump(wddump);
152dev_type_size(wdsize); 151dev_type_size(wdsize);
153 152
154const struct bdevsw wd_bdevsw = { 153const struct bdevsw wd_bdevsw = {
@@ -425,45 +424,26 @@ wdattach(device_t parent, device_t self, @@ -425,45 +424,26 @@ wdattach(device_t parent, device_t self,
425} 424}
426 425
427static bool 426static bool
428wd_suspend(device_t dv PMF_FN_ARGS) 427wd_suspend(device_t dv PMF_FN_ARGS)
429{ 428{
430 struct wd_softc *sc = device_private(dv); 429 struct wd_softc *sc = device_private(dv);
431 430
432 wd_flushcache(sc, AT_WAIT); 431 wd_flushcache(sc, AT_WAIT);
433 wd_standby(sc, AT_WAIT); 432 wd_standby(sc, AT_WAIT);
434 return true; 433 return true;
435} 434}
436 435
437int 436int
438wdactivate(device_t self, enum devact act) 
439{ 
440 int rv = 0; 
441 
442 switch (act) { 
443 case DVACT_ACTIVATE: 
444 rv = EOPNOTSUPP; 
445 break; 
446 
447 case DVACT_DEACTIVATE: 
448 /* 
449 * Nothing to do; we key off the device's DVF_ACTIVATE. 
450 */ 
451 break; 
452 } 
453 return (rv); 
454} 
455 
456int 
457wddetach(device_t self, int flags) 437wddetach(device_t self, int flags)
458{ 438{
459 struct wd_softc *sc = device_private(self); 439 struct wd_softc *sc = device_private(self);
460 int bmaj, cmaj, i, mn, rc, s; 440 int bmaj, cmaj, i, mn, rc, s;
461 441
462 rc = 0; 442 rc = 0;
463 mutex_enter(&sc->sc_dk.dk_openlock); 443 mutex_enter(&sc->sc_dk.dk_openlock);
464 if (sc->sc_dk.dk_openmask == 0) 444 if (sc->sc_dk.dk_openmask == 0)
465 ; /* nothing to do */ 445 ; /* nothing to do */
466 else if ((flags & DETACH_FORCE) == 0) 446 else if ((flags & DETACH_FORCE) == 0)
467 rc = EBUSY; 447 rc = EBUSY;
468 else 448 else
469 wdlastclose(sc); 449 wdlastclose(sc);
@@ -538,28 +518,30 @@ wdstrategy(struct buf *bp) @@ -538,28 +518,30 @@ wdstrategy(struct buf *bp)
538 int s; 518 int s;
539 519
540 ATADEBUG_PRINT(("wdstrategy (%s)\n", device_xname(wd->sc_dev)), 520 ATADEBUG_PRINT(("wdstrategy (%s)\n", device_xname(wd->sc_dev)),
541 DEBUG_XFERS); 521 DEBUG_XFERS);
542 522
543 /* Valid request? */ 523 /* Valid request? */
544 if (bp->b_blkno < 0 || 524 if (bp->b_blkno < 0 ||
545 (bp->b_bcount % lp->d_secsize) != 0 || 525 (bp->b_bcount % lp->d_secsize) != 0 ||
546 (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) { 526 (bp->b_bcount / lp->d_secsize) >= (1 << NBBY)) {
547 bp->b_error = EINVAL; 527 bp->b_error = EINVAL;
548 goto done; 528 goto done;
549 } 529 }
550 530
551 /* If device invalidated (e.g. media change, door open), error. */ 531 /* If device invalidated (e.g. media change, door open,
552 if ((wd->sc_flags & WDF_LOADED) == 0) { 532 * device suspension), then error.
 533 */
 534 if ((wd->sc_flags & WDF_LOADED) == 0 || !device_is_active(wd->sc_dev)) {
553 bp->b_error = EIO; 535 bp->b_error = EIO;
554 goto done; 536 goto done;
555 } 537 }
556 538
557 /* If it's a null transfer, return immediately. */ 539 /* If it's a null transfer, return immediately. */
558 if (bp->b_bcount == 0) 540 if (bp->b_bcount == 0)
559 goto done; 541 goto done;
560 542
561 /* 543 /*
562 * Do bounds checking, adjust transfer. if error, process. 544 * Do bounds checking, adjust transfer. if error, process.
563 * If end of partition, just return. 545 * If end of partition, just return.
564 */ 546 */
565 if (WDPART(bp->b_dev) == RAW_PART) { 547 if (WDPART(bp->b_dev) == RAW_PART) {

cvs diff -r1.283 -r1.284 src/sys/dev/scsipi/sd.c (expand / switch to unified diff)

--- src/sys/dev/scsipi/sd.c 2009/05/17 18:11:34 1.283
+++ src/sys/dev/scsipi/sd.c 2009/05/19 19:56:11 1.284
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sd.c,v 1.283 2009/05/17 18:11:34 dyoung Exp $ */ 1/* $NetBSD: sd.c,v 1.284 2009/05/19 19:56:11 dyoung Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998, 2003, 2004 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2003, 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. 8 * by Charles M. Hannum.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -37,27 +37,27 @@ @@ -37,27 +37,27 @@
37 * Mellon University, makes this software available to CMU to distribute 37 * Mellon University, makes this software available to CMU to distribute
38 * or use in any manner that they see fit as long as this message is kept with 38 * or use in any manner that they see fit as long as this message is kept with
39 * the software. For this reason TFS also grants any other persons or 39 * the software. For this reason TFS also grants any other persons or
40 * organisations permission to use or modify this software. 40 * organisations permission to use or modify this software.
41 * 41 *
42 * TFS supplies this software to be publicly redistributed 42 * TFS supplies this software to be publicly redistributed
43 * on the understanding that TFS is not responsible for the correct 43 * on the understanding that TFS is not responsible for the correct
44 * functioning of this software in any circumstances. 44 * functioning of this software in any circumstances.
45 * 45 *
46 * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992 46 * Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
47 */ 47 */
48 48
49#include <sys/cdefs.h> 49#include <sys/cdefs.h>
50__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.283 2009/05/17 18:11:34 dyoung Exp $"); 50__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.284 2009/05/19 19:56:11 dyoung Exp $");
51 51
52#include "opt_scsi.h" 52#include "opt_scsi.h"
53#include "rnd.h" 53#include "rnd.h"
54 54
55#include <sys/param.h> 55#include <sys/param.h>
56#include <sys/systm.h> 56#include <sys/systm.h>
57#include <sys/kernel.h> 57#include <sys/kernel.h>
58#include <sys/file.h> 58#include <sys/file.h>
59#include <sys/stat.h> 59#include <sys/stat.h>
60#include <sys/ioctl.h> 60#include <sys/ioctl.h>
61#include <sys/scsiio.h> 61#include <sys/scsiio.h>
62#include <sys/buf.h> 62#include <sys/buf.h>
63#include <sys/bufq.h> 63#include <sys/bufq.h>
@@ -116,32 +116,31 @@ static int sd_get_simplifiedparms(struct @@ -116,32 +116,31 @@ static int sd_get_simplifiedparms(struct
116static int sd_get_capacity(struct sd_softc *, struct disk_parms *, int); 116static int sd_get_capacity(struct sd_softc *, struct disk_parms *, int);
117static int sd_get_parms(struct sd_softc *, struct disk_parms *, int); 117static int sd_get_parms(struct sd_softc *, struct disk_parms *, int);
118static int sd_get_parms_page4(struct sd_softc *, struct disk_parms *, 118static int sd_get_parms_page4(struct sd_softc *, struct disk_parms *,
119 int); 119 int);
120static int sd_get_parms_page5(struct sd_softc *, struct disk_parms *, 120static int sd_get_parms_page5(struct sd_softc *, struct disk_parms *,
121 int); 121 int);
122 122
123static int sd_flush(struct sd_softc *, int); 123static int sd_flush(struct sd_softc *, int);
124static int sd_getcache(struct sd_softc *, int *); 124static int sd_getcache(struct sd_softc *, int *);
125static int sd_setcache(struct sd_softc *, int); 125static int sd_setcache(struct sd_softc *, int);
126 126
127static int sdmatch(device_t, cfdata_t, void *); 127static int sdmatch(device_t, cfdata_t, void *);
128static void sdattach(device_t, device_t, void *); 128static void sdattach(device_t, device_t, void *);
129static int sdactivate(device_t, enum devact); 
130static int sddetach(device_t, int); 129static int sddetach(device_t, int);
131static void sd_set_properties(struct sd_softc *); 130static void sd_set_properties(struct sd_softc *);
132 131
133CFATTACH_DECL3_NEW(sd, sizeof(struct sd_softc), sdmatch, sdattach, sddetach, 132CFATTACH_DECL3_NEW(sd, sizeof(struct sd_softc), sdmatch, sdattach, sddetach,
134 sdactivate, NULL, NULL, DVF_DETACH_SHUTDOWN); 133 NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
135 134
136extern struct cfdriver sd_cd; 135extern struct cfdriver sd_cd;
137 136
138static const struct scsipi_inquiry_pattern sd_patterns[] = { 137static const struct scsipi_inquiry_pattern sd_patterns[] = {
139 {T_DIRECT, T_FIXED, 138 {T_DIRECT, T_FIXED,
140 "", "", ""}, 139 "", "", ""},
141 {T_DIRECT, T_REMOV, 140 {T_DIRECT, T_REMOV,
142 "", "", ""}, 141 "", "", ""},
143 {T_OPTICAL, T_FIXED, 142 {T_OPTICAL, T_FIXED,
144 "", "", ""}, 143 "", "", ""},
145 {T_OPTICAL, T_REMOV, 144 {T_OPTICAL, T_REMOV,
146 "", "", ""}, 145 "", "", ""},
147 {T_SIMPLE_DIRECT, T_FIXED, 146 {T_SIMPLE_DIRECT, T_FIXED,
@@ -318,45 +317,26 @@ sdattach(device_t parent, device_t self, @@ -318,45 +317,26 @@ sdattach(device_t parent, device_t self,
318 * attach the device into the random source list 317 * attach the device into the random source list
319 */ 318 */
320 rnd_attach_source(&sd->rnd_source, device_xname(sd->sc_dev), 319 rnd_attach_source(&sd->rnd_source, device_xname(sd->sc_dev),
321 RND_TYPE_DISK, 0); 320 RND_TYPE_DISK, 0);
322#endif 321#endif
323 322
324 /* Discover wedges on this disk. */ 323 /* Discover wedges on this disk. */
325 dkwedge_discover(&sd->sc_dk); 324 dkwedge_discover(&sd->sc_dk);
326 325
327 sd_set_properties(sd); 326 sd_set_properties(sd);
328} 327}
329 328
330static int 329static int
331sdactivate(device_t self, enum devact act) 
332{ 
333 int rv = 0; 
334 
335 switch (act) { 
336 case DVACT_ACTIVATE: 
337 rv = EOPNOTSUPP; 
338 break; 
339 
340 case DVACT_DEACTIVATE: 
341 /* 
342 * Nothing to do; we key off the device's DVF_ACTIVE. 
343 */ 
344 break; 
345 } 
346 return (rv); 
347} 
348 
349static int 
350sddetach(device_t self, int flags) 330sddetach(device_t self, int flags)
351{ 331{
352 struct sd_softc *sd = device_private(self); 332 struct sd_softc *sd = device_private(self);
353 int s, bmaj, cmaj, i, mn, rc; 333 int s, bmaj, cmaj, i, mn, rc;
354 334
355 rc = 0; 335 rc = 0;
356 mutex_enter(&sd->sc_dk.dk_openlock); 336 mutex_enter(&sd->sc_dk.dk_openlock);
357 if (sd->sc_dk.dk_openmask == 0) 337 if (sd->sc_dk.dk_openmask == 0)
358 ; /* nothing to do */ 338 ; /* nothing to do */
359 else if ((flags & DETACH_FORCE) == 0) 339 else if ((flags & DETACH_FORCE) == 0)
360 rc = EBUSY; 340 rc = EBUSY;
361 else 341 else
362 sdlastclose(sd); 342 sdlastclose(sd);