Add support for wedges to the ATA disk driver.
This commit is contained in:
parent
ef92b0de59
commit
cc79c7aeb0
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wd.c,v 1.293 2004/09/16 20:52:43 bouyer Exp $ */
|
||||
/* $NetBSD: wd.c,v 1.294 2004/09/25 03:34:02 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved.
|
||||
|
@ -66,7 +66,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.293 2004/09/16 20:52:43 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: wd.c,v 1.294 2004/09/25 03:34:02 thorpej Exp $");
|
||||
|
||||
#ifndef ATADEBUG
|
||||
#define ATADEBUG
|
||||
|
@ -195,7 +195,7 @@ void wd_shutdown(void *);
|
|||
int wd_getcache(struct wd_softc *, int *);
|
||||
int wd_setcache(struct wd_softc *, int);
|
||||
|
||||
struct dkdriver wddkdriver = { wdstrategy };
|
||||
struct dkdriver wddkdriver = { wdstrategy, minphys };
|
||||
|
||||
#ifdef HAS_BAD144_HANDLING
|
||||
static void bad144intern(struct wd_softc *);
|
||||
|
@ -275,8 +275,6 @@ wdattach(struct device *parent, struct device *self, void *aux)
|
|||
const struct wd_quirk *wdq;
|
||||
ATADEBUG_PRINT(("wdattach\n"), DEBUG_FUNCS | DEBUG_PROBE);
|
||||
|
||||
lockinit(&wd->sc_lock, PRIBIO | PCATCH, "wdlock", 0, 0);
|
||||
|
||||
callout_init(&wd->sc_restart_ch);
|
||||
bufq_alloc(&wd->sc_q, BUFQ_DISK_DEFAULT_STRAT()|BUFQ_SORT_RAWBLOCK);
|
||||
#ifdef WD_SOFTBADSECT
|
||||
|
@ -389,6 +387,9 @@ wdattach(struct device *parent, struct device *self, void *aux)
|
|||
rnd_attach_source(&wd->rnd_source, wd->sc_dev.dv_xname,
|
||||
RND_TYPE_DISK, 0);
|
||||
#endif
|
||||
|
||||
/* Discover wedges on this disk. */
|
||||
dkwedge_discover(&wd->sc_dk);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -428,6 +429,9 @@ wddetach(struct device *self, int flags)
|
|||
vdevgone(cmaj, mn, mn, VCHR);
|
||||
}
|
||||
|
||||
/* Delete all of our wedges. */
|
||||
dkwedge_delall(&sc->sc_dk);
|
||||
|
||||
s = splbio();
|
||||
|
||||
/* Kill off any queued buffers. */
|
||||
|
@ -465,7 +469,6 @@ wddetach(struct device *self, int flags)
|
|||
rnd_detach_source(&sc->rnd_source);
|
||||
#endif
|
||||
|
||||
lockmgr(&sc->sc_lock, LK_DRAIN, NULL);
|
||||
sc->drvp->drive_flags = 0; /* no drive any more here */
|
||||
|
||||
return (0);
|
||||
|
@ -870,16 +873,27 @@ wdopen(dev_t dev, int flag, int fmt, struct proc *p)
|
|||
if ((wd->sc_dev.dv_flags & DVF_ACTIVE) == 0)
|
||||
return (ENODEV);
|
||||
|
||||
part = WDPART(dev);
|
||||
|
||||
if ((error = lockmgr(&wd->sc_dk.dk_openlock, LK_EXCLUSIVE, NULL)) != 0)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* If there are wedges, and this is not RAW_PART, then we
|
||||
* need to fail.
|
||||
*/
|
||||
if (wd->sc_dk.dk_nwedges != 0 && part != RAW_PART) {
|
||||
error = EBUSY;
|
||||
goto bad1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is the first open of this device, add a reference
|
||||
* to the adapter.
|
||||
*/
|
||||
if (wd->sc_dk.dk_openmask == 0 &&
|
||||
(error = wd->atabus->ata_addref(wd->drvp)) != 0)
|
||||
return (error);
|
||||
|
||||
if ((error = lockmgr(&wd->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
|
||||
goto bad4;
|
||||
goto bad1;
|
||||
|
||||
if (wd->sc_dk.dk_openmask != 0) {
|
||||
/*
|
||||
|
@ -888,7 +902,7 @@ wdopen(dev_t dev, int flag, int fmt, struct proc *p)
|
|||
*/
|
||||
if ((wd->sc_flags & WDF_LOADED) == 0) {
|
||||
error = EIO;
|
||||
goto bad3;
|
||||
goto bad2;
|
||||
}
|
||||
} else {
|
||||
if ((wd->sc_flags & WDF_LOADED) == 0) {
|
||||
|
@ -902,14 +916,12 @@ wdopen(dev_t dev, int flag, int fmt, struct proc *p)
|
|||
}
|
||||
}
|
||||
|
||||
part = WDPART(dev);
|
||||
|
||||
/* Check that the partition exists. */
|
||||
if (part != RAW_PART &&
|
||||
(part >= wd->sc_dk.dk_label->d_npartitions ||
|
||||
wd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) {
|
||||
error = ENXIO;
|
||||
goto bad;
|
||||
goto bad2;
|
||||
}
|
||||
|
||||
/* Insure only one open at a time. */
|
||||
|
@ -924,18 +936,14 @@ wdopen(dev_t dev, int flag, int fmt, struct proc *p)
|
|||
wd->sc_dk.dk_openmask =
|
||||
wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask;
|
||||
|
||||
lockmgr(&wd->sc_lock, LK_RELEASE, NULL);
|
||||
(void) lockmgr(&wd->sc_dk.dk_openlock, LK_RELEASE, NULL);
|
||||
return 0;
|
||||
|
||||
bad:
|
||||
if (wd->sc_dk.dk_openmask == 0) {
|
||||
}
|
||||
|
||||
bad3:
|
||||
lockmgr(&wd->sc_lock, LK_RELEASE, NULL);
|
||||
bad4:
|
||||
bad2:
|
||||
if (wd->sc_dk.dk_openmask == 0)
|
||||
wd->atabus->ata_delref(wd->drvp);
|
||||
bad1:
|
||||
(void) lockmgr(&wd->sc_dk.dk_openlock, LK_RELEASE, NULL);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -947,7 +955,8 @@ wdclose(dev_t dev, int flag, int fmt, struct proc *p)
|
|||
int error;
|
||||
|
||||
ATADEBUG_PRINT(("wdclose\n"), DEBUG_FUNCS);
|
||||
if ((error = lockmgr(&wd->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
|
||||
|
||||
if ((error = lockmgr(&wd->sc_dk.dk_openlock, LK_EXCLUSIVE, NULL)) != 0)
|
||||
return error;
|
||||
|
||||
switch (fmt) {
|
||||
|
@ -970,7 +979,7 @@ wdclose(dev_t dev, int flag, int fmt, struct proc *p)
|
|||
wd->atabus->ata_delref(wd->drvp);
|
||||
}
|
||||
|
||||
lockmgr(&wd->sc_lock, LK_RELEASE, NULL);
|
||||
(void) lockmgr(&wd->sc_dk.dk_openlock, LK_RELEASE, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1236,7 +1245,8 @@ wdioctl(dev_t dev, u_long xfer, caddr_t addr, int flag, struct proc *p)
|
|||
#endif
|
||||
lp = (struct disklabel *)addr;
|
||||
|
||||
if ((error = lockmgr(&wd->sc_lock, LK_EXCLUSIVE, NULL)) != 0)
|
||||
if ((error = lockmgr(&wd->sc_dk.dk_openlock, LK_EXCLUSIVE,
|
||||
NULL)) != 0)
|
||||
goto bad;
|
||||
wd->sc_flags |= WDF_LABELLING;
|
||||
|
||||
|
@ -1260,7 +1270,7 @@ wdioctl(dev_t dev, u_long xfer, caddr_t addr, int flag, struct proc *p)
|
|||
}
|
||||
|
||||
wd->sc_flags &= ~WDF_LABELLING;
|
||||
lockmgr(&wd->sc_lock, LK_RELEASE, NULL);
|
||||
(void) lockmgr(&wd->sc_dk.dk_openlock, LK_RELEASE, NULL);
|
||||
bad:
|
||||
#ifdef __HAVE_OLD_DISKLABEL
|
||||
if (newlabel != NULL)
|
||||
|
@ -1385,6 +1395,37 @@ bad:
|
|||
return(error);
|
||||
}
|
||||
|
||||
case DIOCAWEDGE:
|
||||
{
|
||||
struct dkwedge_info *dkw = (void *) addr;
|
||||
|
||||
if ((flag & FWRITE) == 0)
|
||||
return (EBADF);
|
||||
|
||||
/* If the ioctl happens here, the parent is us. */
|
||||
strcpy(dkw->dkw_parent, wd->sc_dev.dv_xname);
|
||||
return (dkwedge_add(dkw));
|
||||
}
|
||||
|
||||
case DIOCDWEDGE:
|
||||
{
|
||||
struct dkwedge_info *dkw = (void *) addr;
|
||||
|
||||
if ((flag & FWRITE) == 0)
|
||||
return (EBADF);
|
||||
|
||||
/* If the ioctl happens here, the parent is us. */
|
||||
strcpy(dkw->dkw_parent, wd->sc_dev.dv_xname);
|
||||
return (dkwedge_del(dkw));
|
||||
}
|
||||
|
||||
case DIOCLWEDGES:
|
||||
{
|
||||
struct dkwedge_list *dkwl = (void *) addr;
|
||||
|
||||
return (dkwedge_list(&wd->sc_dk, dkwl, p));
|
||||
}
|
||||
|
||||
default:
|
||||
return ENOTTY;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wdvar.h,v 1.27 2004/08/30 09:34:42 drochner Exp $ */
|
||||
/* $NetBSD: wdvar.h,v 1.28 2004/09/25 03:34:02 thorpej Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998, 2001 Manuel Bouyer.
|
||||
|
@ -40,7 +40,6 @@ struct wd_softc {
|
|||
/* General disk infos */
|
||||
struct device sc_dev;
|
||||
struct disk sc_dk;
|
||||
struct lock sc_lock;
|
||||
struct bufq_state sc_q;
|
||||
struct callout sc_restart_ch;
|
||||
int sc_quirks; /* any quirks drive might have */
|
||||
|
|
Loading…
Reference in New Issue