diff options
| author | thorpej <thorpej@NetBSD.org> | 2004-09-25 04:47:02 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 2004-09-25 04:47:02 +0000 |
| commit | 2a671cfd0e920efa12cb4ffbe78e2bc55d8dc6df (patch) | |
| tree | 6bb3c9a8bf231723b91a5f036a2a435e976896ae /sys | |
| parent | 46cfcf0eb86917bafc33cbc2635b43dbbf1ae57f (diff) | |
Add support for wedges to the MCA ESDI disk driver.
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/dev/mca/ed_mca.c | 123 | ||||
| -rw-r--r-- | sys/dev/mca/edvar.h | 3 |
2 files changed, 65 insertions, 61 deletions
diff --git a/sys/dev/mca/ed_mca.c b/sys/dev/mca/ed_mca.c index 00b9b54f867..6cbf24e3bf8 100644 --- a/sys/dev/mca/ed_mca.c +++ b/sys/dev/mca/ed_mca.c @@ -1,4 +1,4 @@ -/* $NetBSD: ed_mca.c,v 1.24 2004/09/01 20:57:58 drochner Exp $ */ +/* $NetBSD: ed_mca.c,v 1.25 2004/09/25 04:47:02 thorpej Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ed_mca.c,v 1.24 2004/09/01 20:57:58 drochner Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ed_mca.c,v 1.25 2004/09/25 04:47:02 thorpej Exp $"); #include "rnd.h" @@ -90,8 +90,6 @@ CFATTACH_DECL(ed_mca, sizeof(struct ed_softc), extern struct cfdriver ed_cd; static int ed_get_params __P((struct ed_softc *, int *)); -static int ed_lock __P((struct ed_softc *)); -static void ed_unlock __P((struct ed_softc *)); static void edgetdisklabel __P((dev_t, struct ed_softc *)); static void edgetdefaultlabel __P((struct ed_softc *, struct disklabel *)); @@ -114,7 +112,7 @@ const struct cdevsw ed_cdevsw = { nostop, notty, nopoll, nommap, nokqfilter, D_DISK }; -static struct dkdriver eddkdriver = { edmcastrategy }; +static struct dkdriver eddkdriver = { edmcastrategy, minphys }; /* * Just check if it's possible to identify the disk. @@ -149,7 +147,7 @@ ed_mca_attach(parent, self, aux) struct ed_softc *ed = (void *) self; struct edc_mca_softc *sc = (void *) parent; struct ed_attach_args *eda = (struct ed_attach_args *) aux; - char pbuf[8], lckname[10]; + char pbuf[8]; int drv_flags; ed->edc_softc = sc; @@ -158,8 +156,6 @@ ed_mca_attach(parent, self, aux) bufq_alloc(&ed->sc_q, BUFQ_DISKSORT|BUFQ_SORT_RAWBLOCK); simple_lock_init(&ed->sc_q_lock); - snprintf(lckname, sizeof(lckname), "%slck", ed->sc_dev.dv_xname); - lockinit(&ed->sc_lock, PRIBIO | PCATCH, lckname, 0, 0); if (ed_get_params(ed, &drv_flags)) { printf(": IDENTIFY failed, no disk found\n"); @@ -194,6 +190,9 @@ ed_mca_attach(parent, self, aux) #endif ed->sc_flags |= EDF_INIT; + + /* Discover wedges on this disk. */ + dkwedge_discover(&ed->sc_dk); } /* @@ -289,37 +288,6 @@ edmcawrite(dev, uio, flags) return (physio(edmcastrategy, NULL, dev, B_WRITE, minphys, uio)); } -/* - * Wait interruptibly for an exclusive lock. - */ -static int -ed_lock(ed) - struct ed_softc *ed; -{ - int error; - int s; - - ATADEBUG_PRINT(("ed_lock\n"), DEBUG_FUNCS); - - s = splbio(); - error = lockmgr(&ed->sc_lock, LK_EXCLUSIVE, NULL); - splx(s); - - return (error); -} - -/* - * Unlock and wake up any waiters. - */ -static void -ed_unlock(ed) - struct ed_softc *ed; -{ - ATADEBUG_PRINT(("ed_unlock\n"), DEBUG_FUNCS); - - (void) lockmgr(&ed->sc_lock, LK_RELEASE, NULL); -} - int edmcaopen(dev, flag, fmt, p) dev_t dev; @@ -334,8 +302,19 @@ edmcaopen(dev, flag, fmt, p) if (wd == NULL || (wd->sc_flags & EDF_INIT) == 0) return (ENXIO); - if ((error = ed_lock(wd)) != 0) - goto bad4; + part = DISKPART(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 (wd->sc_dk.dk_openmask != 0) { /* @@ -344,7 +323,7 @@ edmcaopen(dev, flag, fmt, p) */ if ((wd->sc_flags & WDF_LOADED) == 0) { error = EIO; - goto bad3; + goto bad1; } } else { if ((wd->sc_flags & WDF_LOADED) == 0) { @@ -362,14 +341,12 @@ edmcaopen(dev, flag, fmt, p) } } - part = DISKPART(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 bad1; } /* Insure only one open at a time. */ @@ -384,16 +361,11 @@ edmcaopen(dev, flag, fmt, p) wd->sc_dk.dk_openmask = wd->sc_dk.dk_copenmask | wd->sc_dk.dk_bopenmask; - ed_unlock(wd); + (void) lockmgr(&wd->sc_dk.dk_openlock, LK_RELEASE, NULL); return 0; -bad: - if (wd->sc_dk.dk_openmask == 0) { - } - -bad3: - ed_unlock(wd); -bad4: + bad1: + (void) lockmgr(&wd->sc_dk.dk_openlock, LK_RELEASE, NULL); return (error); } @@ -408,8 +380,9 @@ edmcaclose(dev, flag, fmt, p) int error; ATADEBUG_PRINT(("edmcaclose\n"), DEBUG_FUNCS); - if ((error = ed_lock(wd)) != 0) - return error; + + if ((error = lockmgr(&wd->sc_dk.dk_openlock, LK_EXCLUSIVE, NULL)) != 0) + return (error); switch (fmt) { case S_IFCHR: @@ -432,7 +405,7 @@ edmcaclose(dev, flag, fmt, p) wd->sc_flags &= ~WDF_LOADED; } - ed_unlock(wd); + (void) lockmgr(&wd->sc_dk.dk_openlock, LK_RELEASE, NULL); return 0; } @@ -547,8 +520,9 @@ edmcaioctl(dev, xfer, addr, flag, p) if ((flag & FWRITE) == 0) return EBADF; - if ((error = ed_lock(ed)) != 0) - return error; + if ((error = lockmgr(&ed->sc_dk.dk_openlock, LK_EXCLUSIVE, + NULL)) != 0) + return (error); ed->sc_flags |= WDF_LABELLING; error = setdisklabel(ed->sc_dk.dk_label, @@ -566,7 +540,7 @@ edmcaioctl(dev, xfer, addr, flag, p) } ed->sc_flags &= ~WDF_LABELLING; - ed_unlock(ed); + (void) lockmgr(&ed->sc_dk.dk_openlock, LK_RELEASE, NULL); return (error); } @@ -618,6 +592,37 @@ edmcaioctl(dev, xfer, addr, flag, p) } #endif + 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, ed->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, ed->sc_dev.dv_xname); + return (dkwedge_del(dkw)); + } + + case DIOCLWEDGES: + { + struct dkwedge_list *dkwl = (void *) addr; + + return (dkwedge_list(&ed->sc_dk, dkwl, p)); + } + default: return ENOTTY; } diff --git a/sys/dev/mca/edvar.h b/sys/dev/mca/edvar.h index 4ffb747b592..c323d310fc2 100644 --- a/sys/dev/mca/edvar.h +++ b/sys/dev/mca/edvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: edvar.h,v 1.7 2002/07/20 16:30:19 hannken Exp $ */ +/* $NetBSD: edvar.h,v 1.8 2004/09/25 04:47:02 thorpej Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -51,7 +51,6 @@ struct ed_softc { #define WDF_LOADED 0x004 /* parameters loaded */ #define WDF_KLABEL 0x008 /* retain label after 'full' close */ #define EDF_INIT 0x100 /* disk initialized */ - struct lock sc_lock; /* drive lock */ /* actual drive parameters */ int sc_capacity; |
