summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>1998-07-13 08:23:05 +0000
committerjulian <julian@FreeBSD.org>1998-07-13 08:23:05 +0000
commit1dc298263b8472c42f06ae8d53d88b88d443c895 (patch)
treef7b039cefef35b7038646d2a611116206a1c3f50
parent1805fa7aa872b21ea42eaf5c8226a0739bc9f86f (diff)
downloadFreeBSD-src-1dc298263b8472c42f06ae8d53d88b88d443c895.zip
FreeBSD-src-1dc298263b8472c42f06ae8d53d88b88d443c895.tar.gz
SLICE probing becomes asynchronous. It can now be triggered by
interupt level events. This needs a lot of cleanup, but has been working here for a month or two.. originally needed for CAM integration but that hasn't happenned yet. The probing state machines for each handler should be replaced by a more generic state-service. It's still quite messy in there..
-rw-r--r--sys/dev/fdc/fdc.c9
-rw-r--r--sys/dev/slice/disklabel.c676
-rw-r--r--sys/dev/slice/mbr.c657
-rw-r--r--sys/dev/slice/slice.h32
-rw-r--r--sys/dev/slice/slice_base.c242
-rw-r--r--sys/dev/vn/vn.c7
-rw-r--r--sys/i386/isa/fd.c9
-rw-r--r--sys/i386/isa/wd.c8
-rw-r--r--sys/isa/fd.c9
-rw-r--r--sys/scsi/sd.c8
10 files changed, 713 insertions, 944 deletions
diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c
index 91973cc..c26370b 100644
--- a/sys/dev/fdc/fdc.c
+++ b/sys/dev/fdc/fdc.c
@@ -44,7 +44,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.115 1998/07/04 22:30:16 julian Exp $
+ * $Id: fd.c,v 1.116 1998/07/11 06:35:37 bde Exp $
*
*/
@@ -794,7 +794,6 @@ fdattach(struct isa_device *dev)
&fd->subdevs[0],
&fd->subdevs[0].limit,
&fd->subdevs[0].slice,
- NULL,
namebuf);
/* Allow full probing */
fd->subdevs[0].slice->probeinfo.typespecific = NULL;
@@ -861,7 +860,6 @@ fdattach(struct isa_device *dev)
&fd->subdevs[i],
&fd->subdevs[i].limit,
&fd->subdevs[i].slice,
- NULL,
namebuf);
/* Allow full probing */
fd->subdevs[i].slice->probeinfo.typespecific = NULL;
@@ -914,10 +912,9 @@ fdsinit(void *arg)
struct subdev *sd = arg;
sh_p tp;
- if ((tp = slice_probeall(sd->slice)) != NULL) {
- (*tp->constructor)(sd->slice);
- }
+ slice_start_probe(sd->slice);
config_intrhook_disestablish(&sd->drive->ich);
+ DELAY(2000000); /* XXX */
}
#endif /* SLICE */
diff --git a/sys/dev/slice/disklabel.c b/sys/dev/slice/disklabel.c
index 57d3c2a..197510d 100644
--- a/sys/dev/slice/disklabel.c
+++ b/sys/dev/slice/disklabel.c
@@ -23,9 +23,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: disklabel.c,v 1.5 1998/05/06 23:32:47 julian Exp $
+ * $Id: disklabel.c,v 1.6 1998/06/07 19:40:31 dfr Exp $
*/
#define BAD144
+#undef BAD144
#include <sys/param.h>
#include <sys/kernel.h>
@@ -65,7 +66,6 @@ struct private_data {
#endif
};
-static sl_h_constructor_t dkl_constructor; /* constructor (from device) */
static sl_h_IO_req_t dkl_IOreq; /* IO req downward (to device) */
static sl_h_ioctl_t dkl_ioctl; /* ioctl req downward (to device) */
static sl_h_open_t dkl_open; /* downwards travelling open */
@@ -75,13 +75,14 @@ static sl_h_revoke_t dkl_revoke;/* upwards travelling revokation */
static sl_h_verify_t dkl_verify;/* things changed, are we stil valid? */
static sl_h_upconfig_t dkl_upconfig;/* config requests from below */
static sl_h_dump_t dkl_dump; /* core dump req downward */
+static sl_h_done_t dkl_done; /* callback after async request */
static struct slice_handler slicetype = {
"disklabel",
0,
NULL,
0,
- &dkl_constructor, /* constructor */
+ &dkl_done,
&dkl_IOreq,
&dkl_ioctl,
&dkl_open,
@@ -101,342 +102,183 @@ sd_drvinit(void *unused)
SYSINIT(sddev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sd_drvinit, NULL);
-/*-
- * Given a slice, extract out our table of information
- */
-/*-
- * Attempt to read a disk label from a slice.
- * The label must be partly set up before this: secpercyl, secsize
- * and anything required in the strategy routine (e.g., dummy bounds for the
- * partition containing the label) must be filled in before calling us.
- * Returns NULL on success and an error string on failure.
+/*
+ * Allocate and the private data.
*/
static int
-dkl_extract_table(sl_p slice, struct disklabel * lp)
+dklallocprivate(sl_p slice)
{
- int error = EINVAL;
- struct buf *bp;
- struct disklabel *dlp;
- struct partition *dp;
- int part;
- int slice_offset; /* XXX */
+ register struct private_data *pd;
+
+ pd = malloc(sizeof(*pd), M_DEVBUF, M_NOWAIT);
+ if (pd == NULL) {
+ printf("dkl: failed malloc\n");
+ return (ENOMEM);
+ }
+ bzero(pd, sizeof(*pd));
+ pd->slice_down = slice;
+ slice->refs++;
+ slice->handler_up = &slicetype;
+ slice->private_up = pd;
+ slicetype.refs++;
+ return (0);
+}
- RR;
- /* start off with a known result */
- bzero(lp, sizeof(*lp));
- if (error = slice_readblock(slice, LABELSECTOR, &bp))
- return (error);
+static int
+dkl_claim(sl_p slice)
+{
+ int error = 0;
/*
- * Step through the block looking for the label.
- * It may not be at the front (Though I have never seen this).
- * When found, copy it to the destination supplied.
+ * Don't even BOTHER if it's not 512 byte sectors
*/
- error = EINVAL;
- for (dlp = (struct disklabel *) bp->b_data;
- dlp <= (struct disklabel *) ((char *) bp->b_data
- + slice->limits.blksize
- - sizeof(*dlp));
- dlp = (struct disklabel *) ((char *) dlp + sizeof(long))) {
- if ((dlp->d_magic != DISKMAGIC) ||
- (dlp->d_magic2 != DISKMAGIC) ||
- (dlp->d_npartitions > MAXPARTITIONS) ||
- dkcksum(dlp))
- continue;
- error = 0;
- bcopy(dlp, lp, sizeof(*lp));
- /*
- * disklabels are done relative to the base of the disk,
- * rather than the local partition, (DUH!)
- * so use partition 2 (c) to get the base,
- * and subtract it from all non-0 offsets.
- */
- dp = lp->d_partitions;
- slice_offset = dp[2].p_offset;
- for (part = 0; part < MAXPARTITIONS; part++, dp++) {
- /*
- * We could be reloading, in which case skip
- * entries already set up.
- */
- if (dp->p_size == 0)
- continue;
- if( dp->p_offset < slice_offset ) {
- printf("slice before 'c'\n");
- dp->p_size = 0;
- continue;
- }
- dp->p_offset -= slice_offset;
+ if (slice->limits.blksize != 512)
+ return (EINVAL);
+ if (slice->private_up == NULL) {
+ if ((error = dklallocprivate(slice))) {
+ return (error);
}
- break;
}
+ slice->flags |= SLF_PROBING;
+ if ((error = slice_request_block(slice, LABELSECTOR))) {
+ slice->flags &= ~SLF_PROBING;
+ dkl_revoke(slice->private_up);
+ }
+ return (error);
+}
-done:
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
+static int
+dkl_verify(sl_p slice)
+{
+ int error = 0;
+ /*
+ * Don't even BOTHER if it's not 512 byte sectors
+ */
+ if (slice->limits.blksize != 512)
+ return (EINVAL);
+ if ((error = slice_request_block(slice, LABELSECTOR))) {
+ dkl_revoke(slice->private_up);
+ }
return (error);
}
-/*
- * given a table, write it to disk.
+
+/*
+ * called with an argument of a bp when it is completed
*/
static int
-dkl_insert_table(sl_p slice, struct disklabel * lp)
+dkl_done(sl_p slice, struct buf *bp)
{
- int error = EINVAL;
- struct buf *bp;
- struct disklabel *dlp;
- struct partition *dp;
+ register struct private_data *pd;
+ struct disklabel label;
+ struct disklabel *lp, *dlp, *dl;
+ struct partition *dp0, *dp, *dp2;
int part;
- int slice_offset; /* XXX */
+ int found = 0;
+ int i;
+ char name[64];
+ int slice_offset;
+ int error = 0;
+
+
+RR;
+ /*
+ * Discover whether the IO was successful.
+ */
+ pd = slice->private_up;
+ if ( bp->b_flags & B_ERROR ) {
+ error = bp->b_error;
+ goto nope;
+
+ }
- RR;
- /* start off with a known result */
- if (error = slice_readblock(slice, LABELSECTOR, &bp))
- return (error);
/*
* Step through the block looking for the label.
* It may not be at the front (Though I have never seen this).
- * When found, replace it witht he new one.
+ * When found, copy it to the destination supplied.
*/
- error = EINVAL;
for (dlp = (struct disklabel *) bp->b_data;
dlp <= (struct disklabel *) ((char *) bp->b_data
+ slice->limits.blksize
- sizeof(*dlp));
- dlp = (struct disklabel *) ((char *) dlp + sizeof(long))) {
- if ((dlp->d_magic != DISKMAGIC) ||
- (dlp->d_magic2 != DISKMAGIC) ||
- (dlp->d_npartitions > MAXPARTITIONS) ||
- dkcksum(dlp))
- continue;
- error = 0;
+ dlp = (struct disklabel *) (((char *) dlp) + sizeof(long))) {
+ if ((dlp->d_magic == DISKMAGIC) &&
+ (dlp->d_magic2 == DISKMAGIC) &&
+ (dlp->d_npartitions <= MAXPARTITIONS) &&
+ (dkcksum(dlp) == 0)) {
+ found = 1;
+ break;
+ }
}
- if (error) {
- /*
- * We didn't find one..
- * so clear the block and place the new disklabel
- * at the start.
- */
- bzero(bp->b_data, slice->limits.blksize);
- dlp = (struct disklabel *) bp->b_data;
+ if (! found) {
+ goto nope;
}
+
+ /* copy the table out of the buf and release it. */
+ bcopy(dlp, &label, sizeof(label));
+ bp->b_flags |= B_INVAL | B_AGE;
+ brelse(bp);
+
/*
- * old disklabels are done relative to the base of the disk,
+ * Disklabels are done relative to the base of the disk,
* rather than the local partition, (DUH!)
* so use partition 2 (c) to get the base,
* and subtract it from all non-0 offsets.
*/
- dp = dlp->d_partitions;
+ dp = label.d_partitions;
slice_offset = dp[2].p_offset;
- bcopy(lp, dlp, sizeof(*lp));
- slice_offset -= dp[2].p_offset; /* size we adjust by? */
for (part = 0; part < MAXPARTITIONS; part++, dp++) {
+ /*
+ * We could be reloading, in which case skip
+ * entries already set up.
+ */
if (dp->p_size == 0)
continue;
- dp->p_offset += slice_offset;
- }
- error = slice_writeblock(slice, LABELSECTOR, bp);
-quit:
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
- return (error);
-}
-
-#ifdef BAD144
-static int
-dkl_internbad144(struct private_data *pd, struct dkbad *btp, int flag)
-{
- struct disklabel *lp = &pd->disklabel;
- struct dkbad_intern *bip = pd->bad;
- int i;
-
- if (bip == NULL) {
- bip = malloc(sizeof *bip, M_DEVBUF, flag);
- if (bip == NULL)
- return (ENOMEM);
- pd->bad = bip;
- }
- /*
- * Spare sectors are allocated beginning with the last sector of
- * the second last track of the disk (the last track is used for
- * the bad sector list).
- */
- bip->bi_maxspare = lp->d_secperunit - lp->d_nsectors - 1;
- bip->bi_nbad = DKBAD_MAXBAD;
- for (i=0; i < DKBAD_MAXBAD && btp->bt_bad[i].bt_cyl != DKBAD_NOCYL; i++)
- bip->bi_bad[i] = btp->bt_bad[i].bt_cyl * lp->d_secpercyl
- + (btp->bt_bad[i].bt_trksec >> 8)
- * lp->d_nsectors
- + (btp->bt_bad[i].bt_trksec & 0x00ff);
- bip->bi_bad[i] = -1;
-#if 1
- for (i = 0; i < DKBAD_MAXBAD && bip->bi_bad[i] != -1; i++)
- printf(" %8d => %8d\n", bip->bi_bad[i],
- bip->bi_maxspare - i);
-#endif
- return (0);
-}
-
-static int
-dkl_readbad144(struct private_data *pd)
-{
- sl_p slice = pd->slice_down;
- struct disklabel *lp = &pd->disklabel;
- struct dkbad *db;
- struct buf *bp;
- int blkno, i, error;
-
- for (i = 0; i < min(10, lp->d_nsectors); i += 2) {
- blkno = lp->d_secperunit - lp->d_nsectors + i;
- if (lp->d_secsize > slice->limits.blksize)
- blkno *= lp->d_secsize / slice->limits.blksize;
- else
- blkno /= slice->limits.blksize / lp->d_secsize;
- error = slice_readblock(slice, blkno, &bp);
- if (error)
- return (error);
- bp->b_flags |= B_INVAL | B_AGE;
- db = (struct dkbad *)bp->b_data;
- if (db->bt_mbz == 0 && db->bt_flag == DKBAD_MAGIC) {
- printf(" bad144 table found at block %d\n", blkno);
- error = dkl_internbad144(pd, db, M_NOWAIT);
- brelse(bp);
- return (error);
+ if ( dp->p_offset < slice_offset ) {
+ printf("slice before 'c'\n");
+ dp->p_size = 0;
+ continue;
}
- brelse(bp);
+ dp->p_offset -= slice_offset;
}
- return (EINVAL);
-}
-static __inline daddr_t
-dkl_transbad144(struct private_data *pd, daddr_t blkno)
-{
- return transbad144(pd->bad, blkno);
-}
-#endif
-
-/*-
- * look at a slice and figure out if we should be interested in it. (Is it
- * ours?)
- */
-static int
-dkl_claim(struct slice * slice, struct slice * lower, void *ID)
-{
- struct disklabel disklabel;
- struct disklabel *dl, *dl0;
- int error;
- RR;
/*-
- * Try load a valid disklabel table.
- * This is 90% of what we need to check.
+ * Handle the case when we are being asked to reevaluate
+ * an already loaded disklabel.
+ * We've already handled the case when it's completely vanished.
+ *
+ * Look at a slice that USED to be ours.
+ * Decide if any sub-slices need to be revoked.
+ * For each existing subslice, check that the basic size
+ * and position has not changed. Also check the TYPE.
+ * If not then at least ask them to verify themselves.
+ * It is possible we should allow a slice to grow.
*/
- if ((error = dkl_extract_table(slice, &disklabel)) != 0) {
- return (error);
+ dl = &(pd->disklabel);
+ dp = dl->d_partitions;
+ dp2 = label.d_partitions;
+ for (part = 0; part < MAXPARTITIONS; part++, dp++, dp2++) {
+ if (pd->subdevs[part].slice) {
+ if ((dp2->p_offset != dp->p_offset)
+ || (dp2->p_size != dp->p_size)) {
+ sl_rmslice(pd->subdevs[part].slice);
+ pd->subdevs[part].slice = NULL;
+ } else if (pd->subdevs[part].slice->handler_up) {
+ (*pd->subdevs[part].slice->handler_up->verify)
+ (pd->subdevs[part].slice);
+ }
+ }
}
- /*-
- * If there is no geometry info, extract it from the label
- * as some drivers need this.
- */
- /* XXX */
-
- /*-
- * well, it looks like one of ours.
- */
- return (0);
-}
-
-/*-
- * This is a special HACK function for the IDE driver.
- * It is here because everything it need is in scope here,
- * but it is not really part of the SLICE code.
- * Because old ESDI drives could not tell their geometry, They need
- * to get it from the MBR or the disklabel. This is the disklabel bit.
- */
-int
-dkl_geom_hack(struct slice * slice, struct ide_geom *geom)
-{
- struct disklabel disklabel;
- struct disklabel *dl, *dl0;
- int error;
- RR;
-
- /* first check it's a disklabel*/
- if ((error = dkl_claim (slice, NULL, 0)))
- return (error);
- /*-
- * Try load a valid disklabel table.
- * This is wasteful but never called on new (< 5 YO ) drives.
+ /*- having got rid of changing slices, replace
+ * the old table with the new one, and
+ * handle any new slices by calling the constructor.
*/
- if ((error = dkl_extract_table(slice, &disklabel)) != 0) {
- return (error);
- }
- geom->secpertrack = disklabel. d_nsectors;
- geom->trackpercyl = disklabel.d_ntracks;
- geom->cyls = disklabel.d_ncylinders;
- return (0);
-}
-
-/*-
- * look at a slice we know to be ours and decide what the #$%^ to do with it.
- */
-static int
-dkl_constructor(sl_p slice)
-{
- int i;
- u_int64_t disksize = slice->limits.slicesize;
- struct private_data *pd;
- struct partition *dp, *dp0;
- struct disklabel *dl;
- sh_p tp;
- char name[64];
-
- int part;
- int error = 0;
- u_long dkl_offset;
+ bcopy(&label, dl, sizeof(label));
- RR;
- /*-
- * If we are being called to re-load a slice,
- * then don't reallocate resources.
- */
- if ((pd = slice->private_up) == NULL) {
- if (slice->name == NULL) {
- printf("name is NULL\n");
- return (EINVAL);
- }
- if (strlen(slice->name) > 58) {
- printf("slice: name %s too long\n", slice->name);
- return (ENAMETOOLONG);
- }
- pd = malloc(sizeof(*pd), M_DEVBUF, M_NOWAIT);
- if (pd == NULL) {
- printf("fdisk: failed malloc\n");
- return (ENOMEM);
- }
- bzero(pd, sizeof(*pd));
- pd->slice_down = slice;
- if ((error = dkl_extract_table(slice, &pd->disklabel)) != 0) {
- struct partinfo data;
- /*
- * If it's just that there is no disklabel there,
- * Then we fake one up and write it. if this were
- * not ok, then we would have not been called.
- * (as probe will have failed). If it's
- * a physical error, then that's reason to fail.
- */
- if (error != EINVAL) {
- free(pd, M_DEVBUF);
- return (error);
- }
- dkl_dummy_ioctl(slice, DIOCGPART,
- (caddr_t) &data, 0, NULL);
- bcopy(data.disklab, &pd->disklabel,
- sizeof(pd->disklabel));
- if ((error = dkl_insert_table(slice, &pd->disklabel))) {
- free(pd, M_DEVBUF);
- return (error);
- }
- }
#ifdef BAD144
+#if 0
+ /* place holder:
+ remember to add some state machine to handle bad144 loading */
+
if (pd->disklabel.d_flags & D_BADSECT) {
if ((error = dkl_readbad144(pd))) {
free(pd, M_DEVBUF);
@@ -444,12 +286,7 @@ dkl_constructor(sl_p slice)
}
}
#endif
- slice->refs++;
- slice->handler_up = &slicetype;
- slice->private_up = pd;
- slicetype.refs++;
- }
- dl = &pd->disklabel;
+#endif
dp0 = dl->d_partitions;
/*-
@@ -471,13 +308,13 @@ dkl_constructor(sl_p slice)
* entries already set up.
*/
if (pd->subdevs[part].slice != NULL)
- breakout: continue;
+breakout: continue;
/*
* also skip partitions not present
*/
if (dp->p_size == 0)
continue;
-printf(" part %d, start=%d, size=%d\n", part, dp->p_offset, dp->p_size);
+printf(" part %c, start=%d, size=%d\n", part + 'a', dp->p_offset, dp->p_size);
if ((dp->p_offset + dp->p_size) >
(slice->limits.slicesize / slice->limits.blksize)) {
@@ -489,14 +326,12 @@ printf(" part %d, start=%d, size=%d\n", part, dp->p_offset, dp->p_size);
}
/* check for overlaps with existing slices */
for (i = 0; i < MAXPARTITIONS; i++) {
- /*
- * Don't bother if that slice was not made.
- * This handles the (i == part) case.
- */
+ /* skip empty slots (including this one) */
if (pd->subdevs[i].slice == NULL)
continue;
if ((dp0[i].p_offset < (dp->p_offset + dp->p_size))
- && ((dp0[i].p_offset + dp0[i].p_size) > dp->p_offset)) {
+ && ((dp0[i].p_offset + dp0[i].p_size) > dp->p_offset))
+ {
printf("dkl: slice %d overlaps slice %d\n",
part, i);
goto breakout;
@@ -518,7 +353,6 @@ printf(" part %d, start=%d, size=%d\n", part, dp->p_offset, dp->p_size);
&pd->subdevs[part],
&pd->subdevs[part].limit,
&pd->subdevs[part].slice,
- NULL,
name);
pd->subdevs[part].slice->probeinfo.typespecific = &dp->p_fstype;
switch (dp->p_fstype) {
@@ -551,7 +385,7 @@ printf(" part %d, start=%d, size=%d\n", part, dp->p_offset, dp->p_size);
}
/*
* Dont allow further breakup of slices that
- * cover our disklabel
+ * cover our disklabel (that would recurse forever)
*/
if (dp->p_offset < 16) {
#if 0
@@ -560,68 +394,48 @@ printf(" part %d, start=%d, size=%d\n", part, dp->p_offset, dp->p_size);
#endif
pd->subdevs[part].slice->probeinfo.type = NO_SUBPART;
}
- if ((tp = slice_probeall(pd->subdevs[part].slice)) != NULL) {
- (*tp->constructor)(pd->subdevs[part].slice);
- }
+ slice_start_probe(pd->subdevs[part].slice);
}
+ slice->flags &= ~SLF_PROBING;
+ return (0);
+nope:
+printf(" .. nope\n");
+ dkl_revoke(pd);
return (error);
}
+#if 0
/*-
- * look at a slice that USED to be ours.
- * decide if any sub-slices need to be revoked.
- * If not then at least ask them to verify themselves.
+ * This is a special HACK function for the IDE driver.
+ * It is here because everything it need is in scope here,
+ * but it is not really part of the SLICE code.
+ * Because old ESDI drives could not tell their geometry, They need
+ * to get it from the MBR or the disklabel. This is the disklabel bit.
*/
-static int
-dkl_verify(sl_p slice)
+int
+dkl_geom_hack(struct slice * slice, struct ide_geom *geom)
{
- register struct private_data *pd;
- struct disklabel label;
- struct partition *dp, *dp2;
- struct disklabel *dl;
- int part;
- int error;
- /* register struct slice *slice; */
-
+ struct disklabel disklabel;
+ struct disklabel *dl, *dl0;
+ int error;
RR;
- pd = slice->private_up;
- /* slice = pd->slice_down; */
- bzero(&label, sizeof(label));
- /*
- * Try load a valid disklabel. This is 90% of what we need to check.
+
+ /* first check it's a disklabel*/
+ if ((error = dkl_claim (slice)))
+ return (error);
+ /*-
+ * Try load a valid disklabel table.
+ * This is wasteful but never called on new (< 5 YO ) drives.
*/
- if (((error = dkl_extract_table(slice, &label)) != 0)
- || (slice->limits.blksize != 512)) {
- /*-
- * Oh oh, we need to invalidate all the subslices.
- * and relinquish this slice.
- */
- return (dkl_revoke(pd));
- }
- dl = &(pd->disklabel);
- dp = dl->d_partitions;
- dp2 = label.d_partitions;
- for (part = 0; part < MAXPARTITIONS; part++, dp++, dp2++) {
- if (pd->subdevs[part].slice) {
- if ((dp2->p_offset != dp->p_offset)
- || (dp2->p_size != dp->p_size)) {
- sl_rmslice(pd->subdevs[part].slice);
- pd->subdevs[part].slice = NULL;
- } else if (pd->subdevs[part].slice->handler_up) {
- (*pd->subdevs[part].slice->handler_up->verify)
- (pd->subdevs[part].slice);
- }
- }
+ if ((error = dkl_extract_table(slice, &disklabel)) != 0) {
+ return (error);
}
- /*- having got rid of changing slices, replace
- * the old table with the new one, and
- * handle any new slices by calling the constructor.
- */
- bcopy(&label, dl, sizeof(label));
- error = dkl_constructor(slice);
-done:
- return (error);
+ geom->secpertrack = disklabel. d_nsectors;
+ geom->trackpercyl = disklabel.d_ntracks;
+ geom->cyls = disklabel.d_ncylinders;
+ return (0);
}
+#endif
/*-
* Invalidate all subslices, and free resources for this handler instance.
@@ -656,6 +470,96 @@ dkl_revoke(void *private)
return (0);
}
+#ifdef BAD144
+#if 0
+ bucket= blknum >> 4; /* set 16 blocks to the same bucket */
+ bucket ^= (bucket>>16); /* combine bytes 1+3, 2+4 */
+ bucket ^= (bucket>>8); /* combine bytes 1+3+2+4 */
+ bucket &= 0x7F; /* AND 128 entries */
+#endif
+/*
+ * Given a bad144 table, load the values into ram.
+ * eventually we should hash them so we can do forwards lookups.
+ * Probably should hash on (blknum >> 4) to minimise
+ * lookups for a clustered IO. (see above)
+ */
+static int
+dkl_internbad144(struct private_data *pd, struct dkbad *btp, int flag)
+{
+ struct disklabel *lp = &pd->disklabel;
+ struct dkbad_intern *bip = pd->bad;
+ int i;
+
+ if (bip == NULL) {
+ bip = malloc(sizeof *bip, M_DEVBUF, flag);
+ if (bip == NULL)
+ return (ENOMEM);
+ pd->bad = bip;
+ }
+ /*
+ * Spare sectors are allocated beginning with the last sector of
+ * the second last track of the disk (the last track is used for
+ * the bad sector list).
+ */
+ bip->bi_maxspare = lp->d_secperunit - lp->d_nsectors - 1;
+ bip->bi_nbad = DKBAD_MAXBAD;
+ for (i=0; i < DKBAD_MAXBAD && btp->bt_bad[i].bt_cyl != DKBAD_NOCYL; i++)
+ bip->bi_bad[i] = btp->bt_bad[i].bt_cyl * lp->d_secpercyl
+ + (btp->bt_bad[i].bt_trksec >> 8)
+ * lp->d_nsectors
+ + (btp->bt_bad[i].bt_trksec & 0x00ff);
+ bip->bi_bad[i] = -1;
+#if 1
+ for (i = 0; i < DKBAD_MAXBAD && bip->bi_bad[i] != -1; i++)
+ printf(" %8d => %8d\n", bip->bi_bad[i],
+ bip->bi_maxspare - i);
+#endif
+ return (0);
+}
+
+/*
+ * Hunt in the last cylinder for the bad144 table
+ * this needs to be turned around to be made into a state operation
+ * driven by IO completion of the read.
+ */
+static int
+dkl_readbad144(struct private_data *pd)
+{
+ sl_p slice = pd->slice_down;
+ struct disklabel *lp = &pd->disklabel;
+ struct dkbad *db;
+ struct buf *bp;
+ int blkno, i, error;
+
+ for (i = 0; i < min(10, lp->d_nsectors); i += 2) {
+ blkno = lp->d_secperunit - lp->d_nsectors + i;
+ if (lp->d_secsize > slice->limits.blksize)
+ blkno *= lp->d_secsize / slice->limits.blksize;
+ else
+ blkno /= slice->limits.blksize / lp->d_secsize;
+ error = slice_readblock(slice, blkno, &bp);
+ if (error)
+ return (error);
+ bp->b_flags |= B_INVAL | B_AGE;
+ db = (struct dkbad *)bp->b_data;
+ if (db->bt_mbz == 0 && db->bt_flag == DKBAD_MAGIC) {
+ printf(" bad144 table found at block %d\n", blkno);
+ error = dkl_internbad144(pd, db, M_NOWAIT);
+ brelse(bp);
+ return (error);
+ }
+ brelse(bp);
+ }
+ return (EINVAL);
+}
+
+static __inline daddr_t
+dkl_transbad144(struct private_data *pd, daddr_t blkno)
+{
+ return transbad144(pd->bad, blkno);
+}
+#endif
+
/*-
* shift the appropriate IO by the offset for that slice.
*/
@@ -731,52 +635,6 @@ RR;
return (0);
}
-#if 0
-static void
-dkl_close(void *private, int flags, int mode, struct proc * p)
-{
- register struct private_data *pd;
- struct subdev *sdp;
- register struct slice *slice;
- u_int8_t newrflags = 0;
- u_int8_t newwflags = 0;
- int newoflags;
- int part;
- u_int8_t partbit;
-
-RR;
- sdp = private;
- part = sdp->part;
- partbit = (1 << part);
- pd = sdp->pd;
- slice = pd->slice_down;
-
- if ((pd->rflags == 0) && (pd->wflags == 0))
- return;
-
- /* work out what our stored flags will be if this succeeds */
- newwflags &= ~ (partbit);
- newrflags &= ~ (partbit);
- newwflags |= (flags & FWRITE) ? (partbit) : 0;
- newrflags |= (flags & FREAD) ? (partbit) : 0;
-
- /* work out what we want to pass down this time */
- newoflags = newwflags ? FWRITE : 0;
- newoflags |= newrflags ? FREAD : 0;
-
- /*
- * If this was the last open slice above, then release our own open
- */
- if ((pd->rflags == 0) && (pd->wflags == 0)) {
- sliceclose(slice, newoflags, mode, p, SLW_ABOVE);
- }
- pd->rflags = newrflags;
- pd->wflags = newwflags;
- pd->savedoflags = newoflags;
- return ;
-}
-#endif /* 0 */
-
static int
dkl_ioctl(void *private, u_long cmd, caddr_t addr, int flag, struct proc * p)
{
@@ -920,6 +778,10 @@ dkcksum(lp)
}
#endif /* 0 */
+/*
+ * pass down a dump request.
+ * make sure it's offset by the right amount.
+ */
static int
dkl_dump(void *private, int32_t blkoff, int32_t blkcnt)
{
@@ -932,7 +794,7 @@ RR;
pd = sdp->pd;
slice = pd->slice_down;
blkoff += sdp->offset;
- if(slice->handler_down->dump) {
+ if (slice->handler_down->dump) {
return (*slice->handler_down->dump)(slice->private_down,
blkoff, blkcnt);
}
diff --git a/sys/dev/slice/mbr.c b/sys/dev/slice/mbr.c
index f462887..f3eff94 100644
--- a/sys/dev/slice/mbr.c
+++ b/sys/dev/slice/mbr.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: mbr.c,v 1.5 1998/05/06 23:32:48 julian Exp $
+ * $Id: mbr.c,v 1.6 1998/06/07 19:40:31 dfr Exp $
*/
#include <sys/param.h>
@@ -42,6 +42,8 @@ struct private_data {
u_int32_t flags;
struct slice *slice_down;
int savedoflags;
+/* struct buf *bp; */
+ u_int32_t table_offset;
struct dos_partition dos_table[NDOSPART];
struct subdev {
int part;
@@ -68,15 +70,8 @@ struct private_data {
#define MBRF_MSK_WR 0xF0
#define MBRF_MSK_OPEN 0xFF
-static struct dos_partition historical_bogus_partition_table[NDOSPART] = {
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,},
- {0x80, 0, 1, 0, DOSPTYP_386BSD, 255, 255, 255, 0, 50000,},
-};
#define DOSPTYP_ONTRACK 84
-static sl_h_constructor_t mbr_constructor; /* constructor (from device) */
static sl_h_IO_req_t mbr_IOreq; /* IO req downward (to device) */
static sl_h_ioctl_t mbr_ioctl; /* ioctl req downward (to device) */
static sl_h_open_t mbr_open; /* downwards travelling open */
@@ -86,13 +81,14 @@ static sl_h_revoke_t mbr_revoke;/* upwards travelling revokation */
static sl_h_verify_t mbr_verify;/* things changed, are we stil valid? */
static sl_h_upconfig_t mbr_upconfig;/* config request from below */
static sl_h_dump_t mbr_dump; /* core dump req downward */
+static sl_h_done_t mbr_done; /* callback after async request */
static struct slice_handler slicetype = {
"MBR",
0,
NULL,
0,
- &mbr_constructor, /* constructor */
+ &mbr_done,
&mbr_IOreq,
&mbr_ioctl,
&mbr_open,
@@ -113,40 +109,115 @@ sd_drvinit(void *unused)
SYSINIT(sddev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, sd_drvinit, NULL);
/*
- * Given a slice, extract out our table of information
+ * Allocate and the private data.
+ */
+static int
+mbrallocprivate(sl_p slice)
+{
+ register struct private_data *pd;
+
+ pd = malloc(sizeof(*pd), M_DEVBUF, M_NOWAIT);
+ if (pd == NULL) {
+ printf("mbr: failed malloc\n");
+ return (ENOMEM);
+ }
+ bzero(pd, sizeof(*pd));
+ pd->slice_down = slice;
+ slice->refs++;
+ slice->handler_up = &slicetype;
+ slice->private_up = pd;
+ slicetype.refs++;
+ return (0);
+}
+
+static int
+mbr_claim(sl_p slice)
+{
+ int error = 0;
+ /*
+ * Don't even BOTHER if it's not 512 byte sectors
+ */
+ if (slice->limits.blksize != 512)
+ return (EINVAL);
+ if (slice->private_up == NULL) {
+ if ((error = mbrallocprivate(slice))) {
+ return (error);
+ }
+ }
+ slice->flags |= SLF_PROBING;
+ if ((error = slice_request_block(slice, 0))) {
+ slice->flags &= ~SLF_PROBING;
+ mbr_revoke(slice->private_up);
+ }
+ return (error);
+}
+
+static int
+mbr_verify(sl_p slice)
+{
+ int error = 0;
+ /*
+ * Don't even BOTHER if it's not 512 byte sectors
+ */
+ if (slice->limits.blksize != 512)
+ return (EINVAL);
+ if ((error = slice_request_block(slice, 0))) {
+ mbr_revoke(slice->private_up);
+ }
+ return (error);
+}
+
+/*
+ * called with an argument of a bp when it is completed
*/
static int
-mbr_find_table(sl_p slice, struct buf **bpp, int *blknum)
+mbr_done(sl_p slice, struct buf *bp)
{
- int ontrack_offset = 0;
- int error;
+ struct private_data *pd;
+ struct dos_partition table[NDOSPART];
+ struct dos_partition *dp0, *dp, *dp2;
u_int8_t *cp;
- struct dos_partition *dp0, *dp;
int part;
- int redone = 0;
- struct buf *bp;
+ int numactive = 0;
+ int i;
+ char name[64];
+ int error = 0;
RR;
- *bpp = NULL;
-reread:
- if (error = slice_readblock(slice, ontrack_offset, &bp))
- return (error);
+ /*
+ * Discover whether the IO was successful.
+ */
+ pd = slice->private_up;
+ if ( bp->b_flags & B_ERROR ) {
+ error = bp->b_error;
+ bp->b_flags |= B_INVAL | B_AGE;
+ brelse(bp);
+ goto nope;
+ }
cp = bp->b_data;
if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
+ bp->b_flags |= B_INVAL | B_AGE;
+ brelse(bp);
error = EINVAL;
- goto done;
+ goto nope;
}
dp0 = (struct dos_partition *) (cp + DOSPARTOFF);
+ /* copy the table out of the buf and release it. */
+ bcopy(dp0, table, sizeof(table));
+ bp->b_flags |= B_INVAL | B_AGE;
+ brelse(bp);
+
/*
* Check for "Ontrack Diskmanager". Note that if the geometry is
* still needed then we probably won't be able to read a DiskManager
* MBR because we will fail to read sector 63. The very act of
* finding a Disk Manager might however have given us the info we
* need if the disk manager set's its partition up correctly.
+ * XXX not true with interrupt driven probes.
*/
- if (!redone) {
- for (part = 0, dp = dp0;
+ if (pd->table_offset == 0) {
+ for (part = 0, dp = table;
part < NDOSPART; part++, dp++) {
if (dp->dp_typ == DOSPTYP_ONTRACK) {
#ifdef MAYBE
@@ -155,342 +226,89 @@ reread:
* if this is just the start of the 2nd
* track.
*/
- ontrack_offset = dp->dp_start;
+ pd->table_offset = dp->dp_start;
#else
- ontrack_offset = 63;
+ pd->table_offset = 63;
#endif
if (bootverbose)
printf("Found \"Ontrack Disk Manager\"\n");
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
- redone++;
- goto reread;
+ slice_request_block(slice, pd->table_offset);
+ return (0);
}
}
}
-done:
- if (blknum)
- *blknum = ontrack_offset;
- *bpp = bp;
- return (error);
-}
-
-/*
- * Given a slice, extract out our table of information
- */
-static int
-mbr_extract_table(sl_p slice, struct dos_partition *table)
-{
- int error;
- struct buf *bp;
-RR;
- /* start off with a known result */
- bzero(table, sizeof(*table) * NDOSPART);
- error = mbr_find_table(slice, &bp, NULL);
- if (!error)
- bcopy((bp->b_data + DOSPARTOFF), table,
- sizeof(*table) * NDOSPART);
-done:
- if (bp) {
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
- }
- return (error);
-}
-/*
- * read the block and replace the mbr table with that given.
- * If there isn't one, clear the rest of the block.
- */
-static int
-mbr_insert_table(sl_p slice, struct dos_partition *table)
-{
- int blknum = 0;
- int error;
- struct buf *bp;
-
-RR;
- error = mbr_find_table(slice, &bp, &blknum);
- if ( error == EINVAL) {
- /*
- * The block was read, but there was no table there.
- * just clear out the cruft for now.
- */
- bzero(bp->b_data, slice->limits.blksize);
- } else if (error == 0) {
- bcopy( table, (bp->b_data + DOSPARTOFF),
- sizeof(*table) * NDOSPART);
- bp->b_data[0x1FE] = 0x55;
- bp->b_data[0x1FF] = 0xAA;
- /* XXX Somehow we should get boot code in there too. */
- /* for now leave it to the tool */
- error = slice_writeblock(slice, blknum, bp);
- }
-done:
- if (bp) {
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
- }
- return (error);
-}
-
-/*
- * look at a slice and figure out if we should be interested in it. (Is it
- * ours?)
- */
-static int
-mbr_claim(struct slice * slice, struct slice * lower, void *ID)
-{
- struct dos_partition table[NDOSPART];
- struct dos_partition *dp, *dp0;
- int part;
- int error;
- int max_ncyls;
- int max_nsectors;
- int max_ntracks;
- u_int32_t secpercyl;
- int numactive = 0;
-RR;
/*
- * Don't even BOTHER if it's not 512 byte sectors
- */
- if (slice->limits.blksize != 512)
- return (EINVAL);
- /*
- * Try load a valid MBR table. This is 90% of what we need to check.
- */
- if ((error = mbr_extract_table(slice, table)) != 0) {
- return (error);
- }
- dp0 = table;
- /*
* The first block of the dos code is marked like a valid MBR.
- * Try to distinguish this case byt doing a sanity check on the table.
+ * Try to distinguish this case by doing a sanity check on the table.
* Check:
* Flag byte can only be 0 or 0x80.
* At most one active partition.
* -Other tests to be added here-
*/
- for (part = 0, dp = dp0; part < NDOSPART; part++, dp++) {
+ for (part = 0, dp = table; part < NDOSPART; part++, dp++) {
if (dp->dp_flag & 0x7f) {
printf ("rejected.. bad flag ");
- return(EINVAL); /* must be either 0 or 0x80 */
+ goto nope;
}
if ((dp->dp_typ) && (dp->dp_size) && (dp->dp_start == 0)) {
printf("rejected.. Slice includes MBR ");
- return (EINVAL);
+ goto nope;
}
if (dp->dp_flag == 0x80)
numactive++;
}
if (numactive > 1) {
printf ("rejected.. multiple active ");
- return (EINVAL);
- }
- /*
- * If it's the MBR that comes with the disklabel then we should just
- * give up and let the disklabel handler take control of this slice.
- */
- if (bcmp(dp0, historical_bogus_partition_table,
- sizeof historical_bogus_partition_table) == 0) {
- printf("rejecting disklabel table ");
- return (EINVAL);
- }
- /*
- * well, it looks like one of ours.
- */
- return (0);
-}
-
-/*
- * This routine tries to guess the geometry for
- * old disk drivers that need the MBR code to set it. Bits taken from
- * diskslice_machdep.c which itself evolved from earlier code.
- * This is not part of the SLICE code per-se, but just a convenient place to
- * put this HACK because everything is in scope. Only called by the IDE driver.
- */
-int
-mbr_geom_hack(struct slice * slice, struct ide_geom *geom)
-{
- struct dos_partition table[NDOSPART];
- struct dos_partition *dp, *dp0;
- int part;
- int error;
- int max_ncyls;
- int max_nsectors;
- int max_ntracks;
- u_int32_t secpercyl;
-RR;
-
- /*
- * Don't even BOTHER if it's not claimable by us.
- */
- if ((error = mbr_claim(slice,NULL,0)))
- return (error);
- /*
- * Load the mbr.
- */
- if ((error = mbr_extract_table(slice, table)) != 0) {
- return (error);
- }
- dp0 = table;
- /*
- * Guess the geometry. For some old drives (ESDI, st506) the
- * driver below us may not yet know the geometry, but needs
- * to before it can access blocks out of the first track.
- * This hack is to use information in the MBR to "deduce"
- * this information and pass it back.
- */
- max_ncyls = 0;
- max_nsectors = 0;
- max_ntracks = 0;
- for (part = 0, dp = dp0; part < NDOSPART; part++, dp++) {
- int ncyls;
- int nsectors;
- int ntracks;
-
- if (dp->dp_size == 0)
- continue;
- ncyls = DPCYL(dp->dp_ecyl, dp->dp_esect) + 1;
- if (max_ncyls < ncyls)
- max_ncyls = ncyls;
- nsectors = DPSECT(dp->dp_esect);
- if (max_nsectors < nsectors)
- max_nsectors = nsectors;
- ntracks = dp->dp_ehd + 1;
- if (max_ntracks < ntracks)
- max_ntracks = ntracks;
+ goto nope;
}
- if ((max_ncyls == 0)
- && (max_nsectors == 0)
- && (max_ntracks == 0)) {
- /* we've gained nought, so just return */
- return (EINVAL);
- }
- secpercyl = (u_long) max_nsectors *max_ntracks;
- printf("s=%d, h=%d, c=%d\n", max_nsectors, max_ntracks, max_ncyls);
- /*
- * Check that we have guessed the geometry right by checking
- * the partition entries.
+ /*-
+ * Handle the case when we are being asked to reevaluate
+ * an already loaded mbr table.
+ * We've already handled the case when it's completely vanished.
+ *
+ * Look at a slice that USED to be ours.
+ * Decide if any sub-slices need to be revoked.
+ * For each existing subslice, check that the basic size
+ * and position has not changed. Also check the TYPE.
+ * If not then at least ask them to verify themselves.
+ * It is possible we should allow a slice to grow.
*/
- error = 0;
- for (part = 0, dp = dp0; part < NDOSPART; part++, dp++) {
- int cyl;
- int sector;
- int track;
- int secpercyl;
-
- if (dp->dp_size == 0)
- continue;
- cyl = DPCYL(dp->dp_scyl, dp->dp_ssect);
- track = dp->dp_shd;
- sector = DPSECT(dp->dp_ssect) - 1;
- secpercyl = max_nsectors * max_ntracks;
- /*
- * If the geometry doesn't work for any partition
- * start then don't accept it.
- */
- if (((((dp->dp_start / secpercyl) % 1024) != cyl)
- && (cyl != 1023))
- || (((dp->dp_start % secpercyl)
- / max_nsectors) != track)
- || (((dp->dp_start % secpercyl)
- % max_nsectors) != sector)) {
- printf("Can't get disk geometry from MBR\n");
- return (EINVAL);
- }
- if ((dp->dp_start / secpercyl) > 1023) {
- printf("part %d above BIOS reach\n", part);
+ dp = pd->dos_table;
+ dp0 = pd->dos_table;
+ dp2 = table;
+ for (part = 0; part < NDOSPART; part++, dp++, dp2++) {
+ if (pd->subdevs[part].slice) {
+ if ((dp2->dp_start != dp->dp_start)
+ || (dp2->dp_size != dp->dp_size)
+ || (dp2->dp_typ != dp->dp_typ) ) {
+ sl_rmslice(pd->subdevs[part].slice);
+ pd->subdevs[part].slice = NULL;
+ } else if (pd->subdevs[part].slice->handler_up) {
+ (*pd->subdevs[part].slice->handler_up->verify)
+ (pd->subdevs[part].slice);
+ }
}
}
-
/*
- * Set our newely hypothesised numbers into the geometry
- * slots in the supplied SLICE.
+ * Having got rid of changing slices, replace
+ * the old table with the new one.
*/
- geom->secpertrack = max_nsectors;
- geom->trackpercyl = max_ntracks;
- geom->cyls = max_ncyls;
- return (0);
-}
-
-/*
- * look at a slice we know to be ours and decide what the #$%^ to do with it.
- * We presume the driver already did the geometry hack if needed.
- */
-static int
-mbr_constructor(sl_p slice)
-{
- int i;
- u_int64_t disksize = slice->limits.slicesize;
- struct private_data *pd;
- struct dos_partition *dp, *dp0;
- int redone = 0;
- int ontrack_offset = 0;
- char name[64];
- sh_p tp;
-
- int part;
- int error = 0;
-
-RR;
- /*
- * If we are being called to re-load a slice,
- * then don't reallocate resources.
- */
- if ( (pd = slice->private_up) == NULL) {
- if (slice->name == NULL) {
- printf("name is NULL\n");
- return (EINVAL);
- }
- if (strlen(slice->name) > 58) {
- printf("slice: name %s too long\n", slice->name);
- return (ENAMETOOLONG);
- }
- pd = malloc(sizeof(*pd), M_DEVBUF, M_NOWAIT);
- if (pd == NULL) {
- printf("fdisk: failed malloc\n");
- return (ENOMEM);
- }
- bzero(pd, sizeof(*pd));
- pd->slice_down = slice;
- if ((error = mbr_extract_table(slice, pd->dos_table)) != 0) {
- /*
- * If it's just that there is no table there,
- * Then we fake an empty one up and write it. if
- * this were not ok, then we would have not been
- * called. (as probe will have failed). If it's
- * a physical error, then that's reason to fail.
- */
- if (error != EINVAL) {
- free(pd, M_DEVBUF);
- return (error);
- }
- bzero(pd->dos_table, sizeof(pd->dos_table));
- if ((error = mbr_insert_table(slice, pd->dos_table))) {
- free(pd, M_DEVBUF);
- return (error);
- }
-
- }
- slice->refs++;
- slice->handler_up = &slicetype;
- slice->private_up = pd;
- slicetype.refs++;
- }
-
- dp0 = pd->dos_table;
+ bcopy( table, pd->dos_table, sizeof(table));
/*
* Handle each of the partitions.
- * We should check that each makes sence and is legal.
+ * We should check that each makes sense and is legal.
* 1/ it should not already have a slice.
* 2/ should not be 0 length.
* 3/ should not go past end of our slice.
* 4/ should not include sector 0.
* 5/ should not overlap other slices.
+ *
+ * Be aware that this may queue up one (or more) IO requests
+ * for each subslice created.
*/
dp = dp0;
for (part = 0; part < NDOSPART; part++, dp++) {
@@ -501,13 +319,20 @@ breakout: continue;
continue;
if (dp->dp_start < 1)
continue;
+printf(" part %d, start=%d, size=%d\n", part + 1, dp->dp_start, dp->dp_size);
+
if ((dp->dp_start + dp->dp_size) >
- (slice->limits.slicesize/slice->limits.blksize))
+ (slice->limits.slicesize/slice->limits.blksize)) {
+ printf("mbr: slice %d too big ", part);
+ printf("(%x > %x:%x )\n",
+ (dp->dp_start + dp->dp_size),
+ (slice->limits.slicesize / slice->limits.blksize) );
continue;
+ }
/* check for overlaps with existing slices */
for (i = 0; i < NDOSPART; i++) {
/* skip empty slots (including this one) */
- if(pd->subdevs[i].slice == NULL )
+ if (pd->subdevs[i].slice == NULL )
continue;
if ((dp0[i].dp_start < (dp->dp_start + dp->dp_size))
&& ((dp0[i].dp_start + dp0[i].dp_size) > dp->dp_start))
@@ -533,7 +358,6 @@ breakout: continue;
&pd->subdevs[part],
&pd->subdevs[part].limit,
&pd->subdevs[part].slice,
- NULL,
name);
pd->subdevs[part].slice->probeinfo.typespecific = &dp->dp_typ;
switch (dp->dp_typ) { /* list stolen from fdisk */
@@ -588,78 +412,126 @@ breakout: continue;
default:
pd->subdevs[part].slice->probeinfo.type = NULL;
}
- if ((tp = slice_probeall(pd->subdevs[part].slice)) != NULL) {
- (*tp->constructor)(pd->subdevs[part].slice);
- }
+ slice_start_probe(pd->subdevs[part].slice);
}
+ slice->flags &= ~SLF_PROBING;
+ return (0);
+nope:
+ mbr_revoke(pd);
return (error);
}
/*
- * look at a slice that USED to be ours.
- * decide if any sub-slices need to be revoked.
- * If not then at least ask them to verify themselves.
- * Note, arg 'slice' is not strictly needed
+ * This routine tries to guess the geometry for
+ * old disk drivers that need the MBR code to set it. Bits taken from
+ * diskslice_machdep.c which itself evolved from earlier code.
+ * This is not part of the SLICE code per-se, but just a convenient place to
+ * put this HACK because everything is in scope. Only called by the IDE driver.
+ * At the moment I don't know when it could be called from wd.c
+ * Possibly it might call the claim function itself so it may be called instead of
+ * the claim. It would have to inhibit the claim from calling the disklabel
+ * claim till after the correct values were assigned. possibbly this
+ * might be broken into two parts, the first of which hangs a struct off the
+ * private data, and the second of which fills it in after the mbr has been loaded.
*/
-static int
-mbr_verify(sl_p slice)
+int
+mbr_geom_hack(struct slice * slice, struct ide_geom *geom)
{
- register struct private_data *pd;
struct dos_partition table[NDOSPART];
struct dos_partition *dp, *dp0;
+ struct private_data *pd;
int part;
int error;
- /* register struct slice *slice; */
-
+ int max_ncyls;
+ int max_nsectors;
+ int max_ntracks;
+ u_int32_t secpercyl;
RR;
- pd = slice->private_up;
- /* slice = pd->slice_down; */
- bzero(table, sizeof(table));
+
+ if (slice->handler_up != &slicetype)
+ return (ENXIO);
+ pd = slice->private_up; /* XXX */
+ if (pd == NULL)
+ return (ENXIO);
+ dp0 = pd->dos_table;
/*
- * Try load a valid MBR table. This is 90% of what we need to check.
+ * Guess the geometry. For some old drives (ESDI, st506) the
+ * driver below us may not yet know the geometry, but needs
+ * to before it can access blocks out of the first track.
+ * This hack is to use information in the MBR to "deduce"
+ * this information and pass it back.
*/
- if ((slice->limits.blksize != 512)
- || ((error = mbr_extract_table(slice, table)) != 0)) {
- /*
- * Oh oh, we need to invalidate all the subslices.
- * and relinquish this slice.
- */
- return(mbr_revoke(pd));
+ max_ncyls = 0;
+ max_nsectors = 0;
+ max_ntracks = 0;
+ for (part = 0, dp = dp0; part < NDOSPART; part++, dp++) {
+ int ncyls;
+ int nsectors;
+ int ntracks;
+
+ if (dp->dp_size == 0)
+ continue;
+ ncyls = DPCYL(dp->dp_ecyl, dp->dp_esect) + 1;
+ if (max_ncyls < ncyls)
+ max_ncyls = ncyls;
+ nsectors = DPSECT(dp->dp_esect);
+ if (max_nsectors < nsectors)
+ max_nsectors = nsectors;
+ ntracks = dp->dp_ehd + 1;
+ if (max_ntracks < ntracks)
+ max_ntracks = ntracks;
+ }
+ if ((max_ncyls == 0)
+ && (max_nsectors == 0)
+ && (max_ntracks == 0)) {
+ /* we've gained nought, so just return */
+ return (EINVAL);
}
+ secpercyl = (u_long) max_nsectors *max_ntracks;
+ printf("s=%d, h=%d, c=%d\n", max_nsectors, max_ntracks, max_ncyls);
/*
- * For each existing subslice, check that the basic size
- * and position has not changed. Also check the TYPE.
- * It is possible we should allow a slice to grow.
+ * Check that we have guessed the geometry right by checking
+ * the partition entries.
*/
- dp = dp0 = pd->dos_table;
+ error = 0;
for (part = 0, dp = dp0; part < NDOSPART; part++, dp++) {
- if (pd->subdevs[part].slice) {
- if ((table[part].dp_start != dp->dp_start)
- || (table[part].dp_size != dp->dp_size)
- || (table[part].dp_typ != dp->dp_typ) ) {
- sl_rmslice(pd->subdevs[part].slice);
- pd->subdevs[part].slice = NULL;
- } else if ( pd->subdevs[part].slice->handler_up) {
- (*pd->subdevs[part].slice->handler_up->verify)
- (pd->subdevs[part].slice);
- }
+ int cyl;
+ int sector;
+ int track;
+ int secpercyl;
+
+ if (dp->dp_size == 0)
+ continue;
+ cyl = DPCYL(dp->dp_scyl, dp->dp_ssect);
+ track = dp->dp_shd;
+ sector = DPSECT(dp->dp_ssect) - 1;
+ secpercyl = max_nsectors * max_ntracks;
+ /*
+ * If the geometry doesn't work for any partition
+ * start then don't accept it.
+ */
+ if (((((dp->dp_start / secpercyl) % 1024) != cyl)
+ && (cyl != 1023))
+ || (((dp->dp_start % secpercyl)
+ / max_nsectors) != track)
+ || (((dp->dp_start % secpercyl)
+ % max_nsectors) != sector)) {
+ printf("Can't get disk geometry from MBR\n");
+ return (EINVAL);
+ }
+ if ((dp->dp_start / secpercyl) > 1023) {
+ printf("part %d above BIOS reach\n", part);
}
}
+
/*
- * Having got rid of changing slices, replace
- * the old table with the new one, and
- * Handle any new slices by calling the constructor.
- * This way, if we are in 'promiscuous' mode,
- * (e.g. repartitionning a disk we are running on from
- * Single user mode, the unchanged slices can remain open and active
- * through the process. If you change an open slice,
- * the vnodes will be changed to deadfs so a crash is probably
- * nearby. XXX too late. It's written to disk.. (we COULD reverse it,
- * but....)
+ * Set our newely hypothesised numbers into the geometry
+ * slots in the supplied SLICE.
*/
- bcopy( table, dp0, sizeof(table));
- error = mbr_constructor(slice);
- return (error);
+ geom->secpertrack = max_nsectors;
+ geom->trackpercyl = max_ntracks;
+ geom->cyls = max_ncyls;
+ return (0);
}
/*
@@ -763,49 +635,6 @@ RR;
return (0);
}
-#if 0
-static void
-mbr_close(void *private, int flags, int mode, struct proc * p)
-{
- register struct private_data *pd;
- struct subdev *sdp;
- register struct slice *slice;
- int newflags;
- int newoflags;
- int part;
-
-RR;
- sdp = private;
- part = sdp->part;
- pd = sdp->pd;
- slice = pd->slice_down;
-
- if ((pd->flags & MBRF_MSK_OPEN) == 0)
- return;
-
- /* work out what our stored flags will be if this succeeds */
- newflags = pd->flags & ~((MBRF_OPEN_WBIT|MBRF_OPEN_RBIT) << part);
- newflags |= (flags & FWRITE) ? (MBRF_OPEN_WBIT << part) : 0;
- newflags |= (flags & FREAD) ? (MBRF_OPEN_RBIT << part) : 0;
-
- /* work out what we want to pass down this time */
- newoflags = (newflags & MBRF_MSK_WR) ? FWRITE : 0;
- newoflags |= (newflags & MBRF_MSK_RD) ? FREAD : 0;
-
- /*
- * If this was the last open slice above, then release our own open
- */
- pd->flags &= ~((MBRF_OPEN_RBIT|MBRF_OPEN_WBIT) << part);
- if (pd->flags & MBRF_MSK_OPEN) {
- sliceclose(slice, newoflags, mode, p, SLW_ABOVE);
- }
- pd->flags &= ~MBRF_MSK_OPEN;
- pd->flags |= newflags;
- pd->savedoflags = newoflags;
- return ;
-}
-#endif /* 0 */
-
static int
mbr_ioctl(void *private, u_long cmd, caddr_t addr, int flag, struct proc * p)
{
@@ -884,7 +713,7 @@ RR;
pd = sdp->pd;
slice = pd->slice_down;
blkoff += sdp->offset;
- if(slice->handler_down->dump) {
+ if (slice->handler_down->dump) {
return (*slice->handler_down->dump)(slice->private_down,
blkoff, blkcnt);
}
diff --git a/sys/dev/slice/slice.h b/sys/dev/slice/slice.h
index 3d7eabd..ca6dfe0 100644
--- a/sys/dev/slice/slice.h
+++ b/sys/dev/slice/slice.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: slice.h,v 1.2 1998/05/06 22:14:33 julian Exp $
+ * $Id: slice.h,v 1.3 1998/06/07 19:40:32 dfr Exp $
*/
typedef struct slice_handler *sh_p;
@@ -62,6 +62,7 @@ struct ide_geom {
* needed.
*/
struct probehints {
+ sh_p trial_handler; /* methods of handler being probed */
char *type; /* don't probe, just use this type */
void *typespecific; /* the lower layer specifies this */
};
@@ -109,6 +110,13 @@ struct slice {
#define SLF_INVALID 0x00000100 /* Everything aborts */
#define SLF_LOCKED 0x00000200 /* Hold off, It's busy */
#define SLF_WANTED 0x00000400 /* I held off, wake me up */
+#define SLF_PROBING 0x00000800 /* Probe state machine active */
+#define SLF_PROBE_SEL 0x00001000 /* Probe selecting */
+#define SLF_DONT_ARGUE 0x00002000 /* an assign, not a probe */
+
+#define SLF_WAIT_READ 0x00008000 /* waiting for a probe read */
+#define SLF_WAIT_WRITE 0x0000C000 /* waiting for a probe read */
+#define SLF_PROBE_STATE 0x0000C000 /* Present probe state */
/*
* prototypes for slice methods
@@ -116,12 +124,11 @@ struct slice {
typedef void sl_h_IO_req_t(void *private, struct buf * buf);
typedef int sl_h_ioctl_t(void *private, u_long cmd, caddr_t data,
int fflag, struct proc * p);
-typedef int sl_h_constructor_t(sl_p slice);
+typedef int sl_h_done_t(sl_p slice, struct buf *bp);
typedef int sl_h_open_t(void *private, int flags, int mode, struct proc * p);
typedef void sl_h_close_t(void *private, int flags, int mode, struct proc * p);
typedef int sl_h_revoke_t(void *private);
-typedef int sl_h_claim_t(struct slice * slice, struct slice * lower,
- void *ID); /* eg ID=165 for BSD */
+typedef int sl_h_claim_t(struct slice * slice);
typedef int sl_h_verify_t(struct slice *slice);
typedef int sl_h_upconfig_t(struct slice *slice, int cmd, caddr_t data,
int fflag, struct proc *p);
@@ -132,7 +139,7 @@ struct slice_handler {
int version;/* the version of this handler */
struct slice_handler *next; /* next registered type */
int refs; /* references to this type */
- sl_h_constructor_t *constructor; /* make new instantiation */
+ sl_h_done_t *done; /* return after async request */
sl_h_IO_req_t *IOreq; /* IO req downward (to device) */
sl_h_ioctl_t *ioctl; /* ioctl downward (to device) */
sl_h_open_t *open; /* downwards travelling open */
@@ -149,15 +156,18 @@ struct slice_handler {
*/
int sl_make_slice(sh_p handler_down, void *private_down,
struct slicelimits *limits,
- sl_p *slicepp, char *type, char *name);
+ sl_p *slicepp, char *name);
void sl_rmslice(sl_p slice);
int sl_newtype(sh_p tp);
sh_p sl_findtype(char *type);
-sh_p slice_probeall(sl_p slice);
-int lockslice(sl_p slice);
-int unlockslice(sl_p slice);
-int slice_readblock(struct slice *slice, int blkno, struct buf **bpp);
-int slice_writeblock(struct slice *slice, int blkno, struct buf *bp);
+void slice_start_probe(sl_p slice);
+int slice_lock(sl_p slice);
+int slice_unlock(sl_p slice);
+int slice_request_block(struct slice *slice, int blkno);
+int slice_writeblock(struct slice * slice, int blkno,
+ void (*iodone )(struct buf *),
+ caddr_t data, int len);
+void slice_probe_next(sl_p slice);
/*
* Definitions for "SLICE" utilities. (handler or device acting on a slice).
diff --git a/sys/dev/slice/slice_base.c b/sys/dev/slice/slice_base.c
index 60256ed..2752124 100644
--- a/sys/dev/slice/slice_base.c
+++ b/sys/dev/slice/slice_base.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: slice_base.c,v 1.3 1998/04/22 10:25:10 julian Exp $
+ * $Id: slice_base.c,v 1.4 1998/06/14 19:00:12 julian Exp $
*/
#include <sys/param.h>
@@ -41,6 +41,8 @@
#define SLICESPL() splbio()
+static void sl_async_done(struct buf *bp);
+
static int slicexclusive = 0; /* default value == "foot shootable" */
@@ -83,47 +85,68 @@ sl_findtype(char *type)
* Ask all known handler types if a given slice is handled by them.
* If the slice specifies a type, then just find that.
*/
-sh_p
-slice_probeall(sl_p slice)
+void
+slice_start_probe(sl_p slice)
{
sh_p tp = types;
+
if (slice->probeinfo.type == NULL) {
- while (tp) {
- printf("%s: probing for %s.. ",slice->name, tp->name);
- if ((*tp->claim) (slice, NULL, NULL) == 0) {
- printf("yep\n");
- return (tp);
- }
- printf("nope\n");
- tp = tp->next;
+ if(slice->handler_up == NULL) {
+ slice->probeinfo.trial_handler = tp;
+ printf("%s: probing for %s.. ",slice->name, tp->name);
+ (*tp->claim) (slice);
}
+ return;
+ }
+
/*
- * Null string ("") means "don't even try". Caller probably should
- * pre-trap such cases but we'll check here too.
+ * Null string ("") means "don't even try". Caller probably
+ * should pre-trap such cases but we'll check here too.
*/
- } else if (slice->probeinfo.type[0]) {
+ if (slice->probeinfo.type[0]) {
tp = sl_findtype(slice->probeinfo.type);
- if ((tp) && ((*tp->claim) (slice, NULL, NULL) == 0)) {
- printf("%s: attaching %s..\n",slice->name, tp->name);
- return (tp);
+ if (tp) {
+ printf("%s: attaching %s..\n", slice->name, tp->name);
+ (*tp->claim) (slice);
}
}
- /*printf("%s: Leaving as raw device\n", slice->name); */
- return (NULL);
}
+/*
+ * Move the slice probe type, on to the next type
+ * and call that. Called from failed probes.
+ */
+void
+slice_probe_next(sl_p slice)
+{
+ sh_p tp = slice->probeinfo.trial_handler;
+
+ if ((slice->flags & SLF_PROBING) == 0)
+ panic("slice_probe_next: bad call");
+ if (tp != NULL) {
+ tp = tp->next;
+ slice->probeinfo.trial_handler = tp;
+ if (tp) {
+ printf("%s: probing for %s.. ",slice->name, tp->name);
+ (*tp->claim) (slice);
+ return;
+ }
+ }
+ slice->flags &= ~SLF_PROBING;
+}
/*
* Make a handler instantiation of the requested type.
+ * don't take no for an answer.
+ * force it to mark it's new territory.
+ * Must be called from a with a user context.
*
*/
static int
-sl_make_handler(char *type, sl_p slice)
+sl_make_handler(sl_p slice, char *type)
{
sh_p handler_up;
- void *private_up;
- int errval;
/*
* check that the type makes sense.
@@ -135,17 +158,12 @@ sl_make_handler(char *type, sl_p slice)
if (handler_up == NULL) {
return (ENXIO);
}
+
/*
* and call the constructor
*/
- if (handler_up->constructor != NULL) {
- errval = (*handler_up->constructor) (slice);
- return (errval);
- } else {
- printf("slice handler %s has no constructor\n",
- handler_up->name);
- return (EINVAL);
- }
+ slice->flags |= SLF_DONT_ARGUE;
+ return( (*handler_up->claim) (slice));
}
/*
@@ -154,7 +172,7 @@ sl_make_handler(char *type, sl_p slice)
* XXX This doesn't work for SMP.
*/
int
-lockslice(struct slice *slice)
+slice_lock(struct slice *slice)
{
int s = SLICESPL();
slice->refs++;
@@ -165,7 +183,7 @@ lockslice(struct slice *slice)
return (ENXIO);
}
slice->flags |= SLF_WANTED;
- tsleep(slice, PRIBIO, "lockslice", 0);
+ tsleep(slice, PRIBIO, "slice_lock", 0);
}
slice->flags |= SLF_LOCKED;
splx(s);
@@ -178,7 +196,7 @@ lockslice(struct slice *slice)
* We can still hold a reference on it.
*/
int
-unlockslice(struct slice *slice)
+slice_unlock(struct slice *slice)
{
int s = SLICESPL();
slice->flags &= ~SLF_LOCKED;
@@ -191,13 +209,13 @@ unlockslice(struct slice *slice)
}
/*
- * create a new slice. Link it into the structures. don't yet find and call
- * it's type handler. That's done later
+ * create a new slice. Link it into the structures.
+ * As of yet it has no upper handler.
*/
int
sl_make_slice(sh_p handler_down, void *private_down,
struct slicelimits * limits,
- sl_p * slicepp, char *type, char *name)
+ sl_p * slicepp, char *name)
{
sl_p slice;
@@ -226,11 +244,6 @@ sl_make_slice(sh_p handler_down, void *private_down,
slice_add_device(slice);
slice->refs = 1; /* one for our downward creator */
*slicepp = slice;
- if (type) {
- slice->refs++; /* don't go away *//* probably not needed */
- sl_make_handler(type, slice);
- sl_unref(slice);
- }
return (0);
}
@@ -238,6 +251,7 @@ sl_make_slice(sh_p handler_down, void *private_down,
* Forceably start a shutdown process on a slice. Either call it's shutdown
* method, or do the default shutdown if there is no type-specific method.
* XXX Really should say who called us.
+ * Should be called at SLICESPL (splbio)
*/
void
sl_rmslice(sl_p slice)
@@ -293,67 +307,139 @@ sl_unref(sl_p slice)
}
}
+
/*
- * Read a block on behalf of a handler.
+ * Given a slice, launch an IOrequest for information
* This is not a bulk IO routine but meant for probes etc.
- * I think that perhaps it should attempt to do sliceopen()
- * calls on the slice first. (XXX?)
*/
int
-slice_readblock(struct slice * slice, int blkno, struct buf ** bpp)
+slice_request_block(sl_p slice, int blknum)
{
struct buf *bp;
- int error = 0;
+ int s;
- /*
- * posibly attempt to open device?
- */
- /* --not yet-- */
- /*
- * Now that it is open, get the buffer and set in the parameters.
- */
+RR;
+ s = splbio();
+#ifdef PARANOID
+ if ( slice->private_up == NULL) {
+ panic("slice_request_block: no pd");
+ }
+ if (slice->flags & SLF_PROBE_STATE) {
+ panic("slice_request_block: 2nd IO");
+ }
+#endif /* PARANOID */
bp = geteblk((int) slice->limits.blksize);
if (bp == NULL) {
return (ENOMEM);
}
- bp->b_pblkno = bp->b_blkno = blkno;
+ slice->flags |= SLF_WAIT_READ;
+ bp->b_iodone = &sl_async_done;
+ bp->b_flags |= B_CALL;
+ bp->b_dev = (dev_t)slice; /* XXX HACK ALERT! */
+ bp->b_pblkno = bp->b_blkno = blknum;
bp->b_bcount = slice->limits.blksize;
bp->b_flags |= B_BUSY | B_READ;
sliceio(slice, bp, SLW_ABOVE);
- if (biowait(bp) != 0) {
- printf("failure reading device block\n");
- error = EIO;
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
- bp = NULL;
- }
- *bpp = bp;
- return (error);
+ splx(s);
+ return (0);
}
/*
- * Read a block on behalf of a handler.
+ * Write a block on behalf of a handler.
* This is not a bulk IO routine but meant for probes etc.
* I think that perhaps it should attempt to do sliceopen()
- * calls on the slice first. (XXX?)
+ * calls on the slice first. (XXX?) no, they may block?
*/
int
-slice_writeblock(struct slice * slice, int blkno, struct buf * bp)
+slice_writeblock(struct slice * slice, int blkno,
+ void (*iodone )(struct buf *),
+ caddr_t data, int len)
{
+ struct buf *bp;
int error = 0;
+#ifdef PARANOID
+ if ( slice->handler_up == NULL) {
+ panic("slice_writeblock: no handler");
+ }
+ if (slice->flags & SLF_PROBE_STATE) {
+ panic("slice_writeblock: 2nd IO");
+ }
+#endif /* PARANOID */
+ if (len > slice->limits.blksize)
+ return (EINVAL);
+ bp = geteblk((int) slice->limits.blksize);
if (bp == NULL) {
return (ENOMEM);
}
+ slice->flags |= SLF_WAIT_WRITE;
+ bcopy(data, bp->b_data, len);
+ bp->b_iodone = sl_async_done;
+ bp->b_flags |= B_CALL;
+ bp->b_dev = (dev_t)slice; /* XXX HACK ALERT! */
bp->b_pblkno = bp->b_blkno = blkno;
bp->b_bcount = slice->limits.blksize;
bp->b_flags |= B_BUSY | B_WRITE;
sliceio(slice, bp, SLW_ABOVE);
- if (biowait(bp) != 0) {
- printf("failure reading device block\n");
- error = EIO;
+ return (0);
+}
+
+/*
+ * called with an argument of a bp when it is completed
+ */
+static void
+sl_async_done(struct buf *bp)
+{
+ sl_p slice;
+ int error;
+
+RR;
+ if (bp->b_dev < 0xf0000000)
+ panic ("b_dev used in SLICE code");
+ slice = (struct slice *)bp->b_dev; /* XXX HACK! */
+
+#ifdef PARANOID
+ if ( slice->handler_up == NULL) {
+ panic("sl_async_done: no pd");
}
- return (error);
+ if (bp->b_flags & B_READ) {
+ if ((slice->flags & SLF_PROBE_STATE) != SLF_WAIT_READ)
+ panic("sl_async_done: unexpected read completion");
+ } else {
+ if ((slice->flags & SLF_PROBE_STATE) != SLF_WAIT_WRITE)
+ panic("sl_async_done: unexpected write completion");
+ }
+#endif /* PARANOID */
+ /*
+ * if the IO failed, then abandon the probes and
+ * return. Possibly ask the lower layer to try again later?
+ */
+ if (bp->b_flags & B_ERROR) {
+ (* slice->handler_up->revoke)(slice->private_up);
+
+ /* (* slice->handler_down->SOMETHING) (slice->private_down); */
+
+ bp->b_flags |= B_INVAL | B_AGE;
+ brelse(bp);
+ return;
+ }
+
+ error = (* slice->handler_up->done)(slice, bp);
+ /*
+ * If the handler has left itself there, or cleared
+ * the PROBING bit, then consider
+ * probing to have come to a close. So just return.
+ * an IO error would be a great hint to abandon probing as well.
+ * we could catch that on the way up but we might want to give
+ * the handler a chance to clean up state?
+ */
+ if (slice->handler_up)
+ return;
+ if (error) {
+ slice->flags &= ~SLF_PROBING;
+ return;
+ }
+ slice_probe_next(slice);
}
/*
@@ -500,7 +586,7 @@ sliceopen(struct slice *slice, int flags, int mode,
/*
* Firstly, don't allow re-opens of what is already open
*/
- if (error = lockslice(slice))
+ if (error = slice_lock(slice))
return (error);
error = EBUSY; /* default answer */
switch (who) {
@@ -597,17 +683,15 @@ sliceopen(struct slice *slice, int flags, int mode,
* Maybe we should ask the lower one to re-issue the request?
*/
if (slice->handler_up == NULL) {
- if ((tp = slice_probeall(slice)) != NULL) {
- (*tp->constructor)(slice);
- }
+ slice_start_probe(slice);
}
}
#endif
reject:
- unlockslice(slice);
+ slice_unlock(slice);
if ((slice->flags & SLF_INVALID) == SLF_INVALID)
error = ENODEV; /* we've been zapped while down there! */
- sl_unref(slice); /* lockslice gave us a ref.*/
+ sl_unref(slice); /* slice_lock gave us a ref.*/
return (error);
}
@@ -620,7 +704,7 @@ sliceclose(struct slice *slice, int flags, int mode,
if (slice->flags & SLF_INVALID)
return ;
- if (lockslice(slice))
+ if (slice_lock(slice))
return ;
switch (who) {
case SLW_ABOVE:
@@ -652,7 +736,7 @@ sliceclose(struct slice *slice, int flags, int mode,
* Maybe we should ask the lower one to re-issue the request?
*/
if (slice->handler_up == NULL) {
- if ((tp = slice_probeall(slice)) != NULL) {
+ if ((tp = slice_start_probe(slice)) != NULL) {
(*tp->constructor)(slice);
}
}
@@ -668,7 +752,7 @@ sliceclose(struct slice *slice, int flags, int mode,
if ( (slice->flags & SLF_OPEN_STATE) == 0)
(*slice->handler_down->close) (slice->private_down,
flags, mode, p);
- unlockslice(slice);
+ slice_unlock(slice);
sl_unref(slice);
return ;
}
diff --git a/sys/dev/vn/vn.c b/sys/dev/vn/vn.c
index 160b57e..8a586d2 100644
--- a/sys/dev/vn/vn.c
+++ b/sys/dev/vn/vn.c
@@ -38,7 +38,7 @@
* from: Utah Hdr: vn.c 1.13 94/04/02
*
* from: @(#)vn.c 8.6 (Berkeley) 4/1/94
- * $Id: vn.c,v 1.64 1998/07/04 22:30:14 julian Exp $
+ * $Id: vn.c,v 1.65 1998/07/11 07:45:22 bde Exp $
*/
/*
@@ -729,9 +729,7 @@ vnioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
* We have a media to read/write.
* Try identify it.
*/
- if ((tp = slice_probeall(vn->slice)) != NULL) {
- (*tp->constructor)(vn->slice);
- }
+ slice_start_probe(vn->slice); /* this happens asynchronously */
#else
IFOPT(vn, VN_LABELS) {
/*
@@ -921,7 +919,6 @@ vn_drvinit(void *unused)
vn,
&vn->limit,
&vn->slice,
- NULL,
namebuf);
/* Allow full probing */
vn->slice->probeinfo.typespecific = NULL;
diff --git a/sys/i386/isa/fd.c b/sys/i386/isa/fd.c
index 91973cc..c26370b 100644
--- a/sys/i386/isa/fd.c
+++ b/sys/i386/isa/fd.c
@@ -44,7 +44,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.115 1998/07/04 22:30:16 julian Exp $
+ * $Id: fd.c,v 1.116 1998/07/11 06:35:37 bde Exp $
*
*/
@@ -794,7 +794,6 @@ fdattach(struct isa_device *dev)
&fd->subdevs[0],
&fd->subdevs[0].limit,
&fd->subdevs[0].slice,
- NULL,
namebuf);
/* Allow full probing */
fd->subdevs[0].slice->probeinfo.typespecific = NULL;
@@ -861,7 +860,6 @@ fdattach(struct isa_device *dev)
&fd->subdevs[i],
&fd->subdevs[i].limit,
&fd->subdevs[i].slice,
- NULL,
namebuf);
/* Allow full probing */
fd->subdevs[i].slice->probeinfo.typespecific = NULL;
@@ -914,10 +912,9 @@ fdsinit(void *arg)
struct subdev *sd = arg;
sh_p tp;
- if ((tp = slice_probeall(sd->slice)) != NULL) {
- (*tp->constructor)(sd->slice);
- }
+ slice_start_probe(sd->slice);
config_intrhook_disestablish(&sd->drive->ich);
+ DELAY(2000000); /* XXX */
}
#endif /* SLICE */
diff --git a/sys/i386/isa/wd.c b/sys/i386/isa/wd.c
index 839092d..636ea03 100644
--- a/sys/i386/isa/wd.c
+++ b/sys/i386/isa/wd.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)wd.c 7.2 (Berkeley) 5/9/91
- * $Id: wd.c,v 1.170 1998/07/04 22:30:18 julian Exp $
+ * $Id: wd.c,v 1.171 1998/07/11 07:45:35 bde Exp $
*/
/* TODO:
@@ -598,7 +598,6 @@ wdattach(struct isa_device *dvp)
du,
&du->limit,
&du->slice,
- NULL,
namebuf);
/* Allow full probing */
du->slice->probeinfo.typespecific = NULL;
@@ -706,10 +705,9 @@ wds_init(void *arg)
}
}
#endif
- if ((tp = slice_probeall(du->slice)) != NULL) {
- (*tp->constructor)(du->slice);
- }
+ slice_start_probe(du->slice);
config_intrhook_disestablish(&du->ich);
+ DELAY(2000000); /* XXX */
#if 0
wdsclose(du, 0, 0, curproc);
#else
diff --git a/sys/isa/fd.c b/sys/isa/fd.c
index 91973cc..c26370b 100644
--- a/sys/isa/fd.c
+++ b/sys/isa/fd.c
@@ -44,7 +44,7 @@
* SUCH DAMAGE.
*
* from: @(#)fd.c 7.4 (Berkeley) 5/25/91
- * $Id: fd.c,v 1.115 1998/07/04 22:30:16 julian Exp $
+ * $Id: fd.c,v 1.116 1998/07/11 06:35:37 bde Exp $
*
*/
@@ -794,7 +794,6 @@ fdattach(struct isa_device *dev)
&fd->subdevs[0],
&fd->subdevs[0].limit,
&fd->subdevs[0].slice,
- NULL,
namebuf);
/* Allow full probing */
fd->subdevs[0].slice->probeinfo.typespecific = NULL;
@@ -861,7 +860,6 @@ fdattach(struct isa_device *dev)
&fd->subdevs[i],
&fd->subdevs[i].limit,
&fd->subdevs[i].slice,
- NULL,
namebuf);
/* Allow full probing */
fd->subdevs[i].slice->probeinfo.typespecific = NULL;
@@ -914,10 +912,9 @@ fdsinit(void *arg)
struct subdev *sd = arg;
sh_p tp;
- if ((tp = slice_probeall(sd->slice)) != NULL) {
- (*tp->constructor)(sd->slice);
- }
+ slice_start_probe(sd->slice);
config_intrhook_disestablish(&sd->drive->ich);
+ DELAY(2000000); /* XXX */
}
#endif /* SLICE */
diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c
index 697fe4a..f9e7b68 100644
--- a/sys/scsi/sd.c
+++ b/sys/scsi/sd.c
@@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
*
- * $Id: sd.c,v 1.132 1998/07/04 22:30:24 julian Exp $
+ * $Id: sd.c,v 1.133 1998/07/11 07:45:59 bde Exp $
*/
#include "opt_bounce.h"
@@ -323,7 +323,6 @@ sdattach(struct scsi_link *sc_link)
sd,
&sd->limit,
&sd->slice,
- NULL,
namebuf);
/* Allow full probing */
sd->slice->probeinfo.typespecific = NULL;
@@ -359,10 +358,9 @@ sds_init(void *arg)
struct scsi_data *sd = arg;
sh_p tp;
- if ((tp = slice_probeall(sd->slice)) != NULL) {
- (*tp->constructor)(sd->slice);
- }
+ slice_start_probe(sd->slice);
config_intrhook_disestablish(&sd->ich);
+ DELAY(2000000); /* XXX */
}
#endif /* SLICE */
OpenPOWER on IntegriCloud