Make it possible to detach ld devices.

This commit is contained in:
ad 2000-12-03 13:03:30 +00:00
parent c9305d1df0
commit a5248b66cf
2 changed files with 64 additions and 3 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ld.c,v 1.1 2000/11/26 17:44:04 ad Exp $ */
/* $NetBSD: ld.c,v 1.2 2000/12/03 13:03:30 ad Exp $ */
/*-
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
@ -57,6 +57,7 @@
#include <sys/lock.h>
#include <sys/conf.h>
#include <sys/fcntl.h>
#include <sys/vnode.h>
#include <sys/syslog.h>
#if NRND > 0
#include <sys/rnd.h>
@ -112,6 +113,55 @@ ldattach(struct ld_softc *sc)
BUFQ_INIT(&sc->sc_bufq);
}
void
lddetach(struct ld_softc *sc)
{
struct buf *bp;
int s, bmaj, cmaj, mn;
/* Wait for commands queued with the hardware to complete. */
if (sc->sc_queuecnt != 0)
tsleep(&sc->sc_queuecnt, PRIBIO, "lddrn", 0);
/* Locate the major numbers. */
for (bmaj = 0; bmaj <= nblkdev; bmaj++)
if (bdevsw[bmaj].d_open == sdopen)
break;
for (cmaj = 0; cmaj <= nchrdev; cmaj++)
if (cdevsw[cmaj].d_open == sdopen)
break;
/* Kill off any queued buffers. */
s = splbio();
while ((bp = BUFQ_FIRST(&sc->sc_bufq)) != NULL) {
BUFQ_REMOVE(&sc->sc_bufq, bp);
bp->b_error = EIO;
bp->b_flags |= B_ERROR;
bp->b_resid = bp->b_bcount;
biodone(bp);
}
splx(s);
/* Nuke the vnodes for any open instances. */
mn = DISKUNIT(sc->sc_dv.dv_unit);
vdevgone(bmaj, mn, mn + (MAXPARTITIONS - 1), VBLK);
vdevgone(cmaj, mn, mn + (MAXPARTITIONS - 1), VCHR);
/* Detach from the disk list. */
disk_detach(&sc->sc_dk);
#if NRND > 0
/* Unhook the entropy source. */
rnd_detach_source(&sc->sc_rnd_source);
#endif
/* Flush the device's cache. */
if (sc->sc_flush != NULL)
if ((*sc->sc_flush)(sc) != 0)
printf("%s: unable to flush cache\n",
sc->sc_dv.dv_xname);
}
static void
ldshutdown(void *cookie)
{
@ -301,6 +351,14 @@ ldstart(struct ld_softc *sc, struct buf *bp)
struct disklabel *lp;
int part, s, rv;
if ((sc->sc_flags & LDF_DRAIN) != 0) {
bp->b_error = EIO;
bp->b_flags |= B_ERROR;
bp->b_resid = bp->b_bcount;
biodone(bp);
return (-1);
}
part = DISKPART(bp->b_dev);
lp = sc->sc_dk.dk_label;
@ -378,7 +436,8 @@ lddone(struct ld_softc *sc, struct buf *bp)
rnd_add_uint32(&sc->sc_rnd_source, bp->b_rawblkno);
#endif
biodone(bp);
sc->sc_queuecnt--;
if (--sc->sc_queuecnt == 0 && (sc->sc_flags & LDF_DRAIN) != 0)
wakeup(&sc->sc_queuecnt);
while ((bp = BUFQ_FIRST(&sc->sc_bufq)) != NULL) {
BUFQ_REMOVE(&sc->sc_bufq, bp);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ldvar.h,v 1.1 2000/11/26 17:44:04 ad Exp $ */
/* $NetBSD: ldvar.h,v 1.2 2000/12/03 13:03:30 ad Exp $ */
/*-
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@ -70,8 +70,10 @@ struct ld_softc {
#define LDF_LKWANTED 0x04 /* lock wanted */
#define LDF_WLABEL 0x08 /* label is writable */
#define LDF_LABELLING 0x10 /* writing label */
#define LDF_DRAIN 0x20 /* detach pending */
void ldattach(struct ld_softc *);
void lddetach(struct ld_softc *);
void lddone(struct ld_softc *, struct buf *);
#endif /* !_DEV_LD_LDVAR_H_ */