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.
This commit is contained in:
dyoung 2009-05-19 19:56:10 +00:00
parent 42b74af385
commit a94204e132
2 changed files with 10 additions and 48 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: wd.c,v 1.374 2009/05/15 23:49:28 dyoung Exp $ */
/* $NetBSD: wd.c,v 1.375 2009/05/19 19:56:10 dyoung Exp $ */
/*
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
@ -59,7 +59,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.374 2009/05/15 23:49:28 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.375 2009/05/19 19:56:10 dyoung Exp $");
#include "opt_ata.h"
@ -129,7 +129,6 @@ int wdcdebug_wd_mask = 0x0;
int wdprobe(device_t, cfdata_t, void *);
void wdattach(device_t, device_t, void *);
int wddetach(device_t, int);
int wdactivate(device_t, enum devact);
int wdprint(void *, char *);
void wdperror(const struct wd_softc *);
@ -138,7 +137,7 @@ static bool wd_suspend(device_t PMF_FN_PROTO);
static int wd_standby(struct wd_softc *, int);
CFATTACH_DECL3_NEW(wd, sizeof(struct wd_softc),
wdprobe, wdattach, wddetach, wdactivate, NULL, NULL, DVF_DETACH_SHUTDOWN);
wdprobe, wdattach, wddetach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
extern struct cfdriver wd_cd;
@ -434,25 +433,6 @@ wd_suspend(device_t dv PMF_FN_ARGS)
return true;
}
int
wdactivate(device_t self, enum devact act)
{
int rv = 0;
switch (act) {
case DVACT_ACTIVATE:
rv = EOPNOTSUPP;
break;
case DVACT_DEACTIVATE:
/*
* Nothing to do; we key off the device's DVF_ACTIVATE.
*/
break;
}
return (rv);
}
int
wddetach(device_t self, int flags)
{
@ -548,8 +528,10 @@ wdstrategy(struct buf *bp)
goto done;
}
/* If device invalidated (e.g. media change, door open), error. */
if ((wd->sc_flags & WDF_LOADED) == 0) {
/* If device invalidated (e.g. media change, door open,
* device suspension), then error.
*/
if ((wd->sc_flags & WDF_LOADED) == 0 || !device_is_active(wd->sc_dev)) {
bp->b_error = EIO;
goto done;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: sd.c,v 1.283 2009/05/17 18:11:34 dyoung Exp $ */
/* $NetBSD: sd.c,v 1.284 2009/05/19 19:56:11 dyoung 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.283 2009/05/17 18:11:34 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: sd.c,v 1.284 2009/05/19 19:56:11 dyoung Exp $");
#include "opt_scsi.h"
#include "rnd.h"
@ -126,12 +126,11 @@ static int sd_setcache(struct sd_softc *, int);
static int sdmatch(device_t, cfdata_t, void *);
static void sdattach(device_t, device_t, void *);
static int sdactivate(device_t, enum devact);
static int sddetach(device_t, int);
static void sd_set_properties(struct sd_softc *);
CFATTACH_DECL3_NEW(sd, sizeof(struct sd_softc), sdmatch, sdattach, sddetach,
sdactivate, NULL, NULL, DVF_DETACH_SHUTDOWN);
NULL, NULL, NULL, DVF_DETACH_SHUTDOWN);
extern struct cfdriver sd_cd;
@ -327,25 +326,6 @@ sdattach(device_t parent, device_t self, void *aux)
sd_set_properties(sd);
}
static int
sdactivate(device_t self, enum devact act)
{
int rv = 0;
switch (act) {
case DVACT_ACTIVATE:
rv = EOPNOTSUPP;
break;
case DVACT_DEACTIVATE:
/*
* Nothing to do; we key off the device's DVF_ACTIVE.
*/
break;
}
return (rv);
}
static int
sddetach(device_t self, int flags)
{