diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index 91973cc66c0..c26370bf859 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 57d3c2a04d3..197510d87d2 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 #include @@ -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,146 +102,387 @@ 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); +} + +static int +dkl_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 = dklallocprivate(slice))) { + return (error); + } + } + slice->flags |= SLF_PROBING; + if ((error = slice_request_block(slice, LABELSECTOR))) { + slice->flags &= ~SLF_PROBING; + dkl_revoke(slice->private_up); + } + return (error); +} + +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); +} + +/* + * called with an argument of a bp when it is completed + */ +static int +dkl_done(sl_p slice, struct buf *bp) +{ + register struct private_data *pd; + struct disklabel label; + struct disklabel *lp, *dlp, *dl; + struct partition *dp0, *dp, *dp2; + int part; + 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 */ - bzero(lp, sizeof(*lp)); - 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, 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; - 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; + 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; } - break; + } + if (! found) { + goto nope; } -done: + /* copy the table out of the buf and release it. */ + bcopy(dlp, &label, sizeof(label)); bp->b_flags |= B_INVAL | B_AGE; brelse(bp); - return (error); -} -/* - * given a table, write it to disk. - */ -static int -dkl_insert_table(sl_p slice, struct disklabel * lp) -{ - int error = EINVAL; - struct buf *bp; - struct disklabel *dlp; - struct partition *dp; - int part; - int slice_offset; /* XXX */ - 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. - */ - 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; - } - 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; - } - /* - * 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; + if ( dp->p_offset < slice_offset ) { + printf("slice before 'c'\n"); + 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); + + + /*- + * 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. + */ + 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); + } + } + } + /*- 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)); + +#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); + return (error); + } + } +#endif +#endif + dp0 = dl->d_partitions; + + /*- + * Handle each of the partitions. + * We should check that each makes sence 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 overlap other slices. + * It can include sector 0 (unfortunatly) + */ + dp = dp0; + for (part = 0; part < MAXPARTITIONS; part++, dp++) { + int i; + if ( part == 2 ) + continue; /* XXX skip the 'c' partition */ + /* + * We could be reloading, in which case skip + * entries already set up. + */ + if (pd->subdevs[part].slice != NULL) +breakout: continue; + /* + * also skip partitions not present + */ + if (dp->p_size == 0) + continue; +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)) { + printf("dkl: slice %d too big ", part); + printf("(%x > %x:%x )\n", + (dp->p_offset + dp->p_size), + (slice->limits.slicesize / slice->limits.blksize) ); + continue; + } + /* check for overlaps with existing slices */ + for (i = 0; i < MAXPARTITIONS; i++) { + /* 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)) + { + printf("dkl: slice %d overlaps slice %d\n", + part, i); + goto breakout; + } + } + /*- + * the slice seems to make sense. Use it. + */ + pd->subdevs[part].part = part; + pd->subdevs[part].pd = pd; + pd->subdevs[part].offset = dp->p_offset; + pd->subdevs[part].limit.blksize + = slice->limits.blksize; + pd->subdevs[part].limit.slicesize + = (slice->limits.blksize * (u_int64_t)dp->p_size); + + sprintf(name, "%s%c", slice->name, (char )('a' + part)); + sl_make_slice(&slicetype, + &pd->subdevs[part], + &pd->subdevs[part].limit, + &pd->subdevs[part].slice, + name); + pd->subdevs[part].slice->probeinfo.typespecific = &dp->p_fstype; + switch (dp->p_fstype) { + case FS_UNUSED: + /* allow unuseed to be further split */ + pd->subdevs[part].slice->probeinfo.type = NULL; + break; + case FS_V6: + case FS_V7: + case FS_SYSV: + case FS_V71K: + case FS_V8: + case FS_MSDOS: + case FS_BSDLFS: + case FS_OTHER: + case FS_HPFS: + case FS_ISO9660: + case FS_BOOT : +#if 0 + printf("%s: type %d. Leaving\n", + pd->subdevs[part].slice->name, + (u_int)dp->p_fstype); +#endif + case FS_SWAP: + case FS_BSDFFS: + pd->subdevs[part].slice->probeinfo.type = NO_SUBPART; + break; + default: + pd->subdevs[part].slice->probeinfo.type = NULL; + } + /* + * Dont allow further breakup of slices that + * cover our disklabel (that would recurse forever) + */ + if (dp->p_offset < 16) { +#if 0 + printf("%s: covers disklabel. Leaving\n", + pd->subdevs[part].slice->name); +#endif + pd->subdevs[part].slice->probeinfo.type = NO_SUBPART; + } + slice_start_probe(pd->subdevs[part].slice); + } + slice->flags &= ~SLF_PROBING; + return (0); +nope: +printf(" .. nope\n"); + dkl_revoke(pd); return (error); } +#if 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))) + 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, &disklabel)) != 0) { + 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. + */ +static int +dkl_revoke(void *private) +{ + register struct private_data *pd; + register struct slice *slice; + int part; + + RR; + pd = private; + slice = pd->slice_down; + for (part = 0; part < MAXPARTITIONS; part++) { + if (pd->subdevs[part].slice) { + sl_rmslice(pd->subdevs[part].slice); + } + } + /*- + * remove ourself as a handler + */ + slice->handler_up = NULL; + slice->private_up = NULL; + slicetype.refs--; #ifdef BAD144 + if (pd->bad) + free(pd->bad, M_DEVBUF); +#endif + free(pd, M_DEVBUF); + sl_unref(slice); + 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) { @@ -275,6 +517,11 @@ dkl_internbad144(struct private_data *pd, struct dkbad *btp, int flag) 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) { @@ -313,349 +560,6 @@ dkl_transbad144(struct private_data *pd, daddr_t 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. - */ - if ((error = dkl_extract_table(slice, &disklabel)) != 0) { - return (error); - } - /*- - * 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. - */ - 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; - - 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 (pd->disklabel.d_flags & D_BADSECT) { - if ((error = dkl_readbad144(pd))) { - free(pd, M_DEVBUF); - return (error); - } - } -#endif - slice->refs++; - slice->handler_up = &slicetype; - slice->private_up = pd; - slicetype.refs++; - } - dl = &pd->disklabel; - dp0 = dl->d_partitions; - - /*- - * Handle each of the partitions. - * We should check that each makes sence 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 overlap other slices. - * It can include sector 0 (unfortunatly) - */ - dp = dp0; - for (part = 0; part < MAXPARTITIONS; part++, dp++) { - int i; - if ( part == 2 ) - continue; /* XXX skip the 'c' partition */ - /* - * We could be reloading, in which case skip - * entries already set up. - */ - if (pd->subdevs[part].slice != NULL) - 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); - - if ((dp->p_offset + dp->p_size) > - (slice->limits.slicesize / slice->limits.blksize)) { - printf("dkl: slice %d too big ", part); - printf("(%x > %x:%x )\n", - (dp->p_offset + dp->p_size), - (slice->limits.slicesize / slice->limits.blksize) ); - continue; - } - /* 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. - */ - 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)) { - printf("dkl: slice %d overlaps slice %d\n", - part, i); - goto breakout; - } - } - /*- - * the slice seems to make sense. Use it. - */ - pd->subdevs[part].part = part; - pd->subdevs[part].pd = pd; - pd->subdevs[part].offset = dp->p_offset; - pd->subdevs[part].limit.blksize - = slice->limits.blksize; - pd->subdevs[part].limit.slicesize - = (slice->limits.blksize * (u_int64_t)dp->p_size); - - sprintf(name, "%s%c", slice->name, (char )('a' + part)); - sl_make_slice(&slicetype, - &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) { - case FS_UNUSED: - /* allow unuseed to be further split */ - pd->subdevs[part].slice->probeinfo.type = NULL; - break; - case FS_V6: - case FS_V7: - case FS_SYSV: - case FS_V71K: - case FS_V8: - case FS_MSDOS: - case FS_BSDLFS: - case FS_OTHER: - case FS_HPFS: - case FS_ISO9660: - case FS_BOOT : -#if 0 - printf("%s: type %d. Leaving\n", - pd->subdevs[part].slice->name, - (u_int)dp->p_fstype); -#endif - case FS_SWAP: - case FS_BSDFFS: - pd->subdevs[part].slice->probeinfo.type = NO_SUBPART; - break; - default: - pd->subdevs[part].slice->probeinfo.type = NULL; - } - /* - * Dont allow further breakup of slices that - * cover our disklabel - */ - if (dp->p_offset < 16) { -#if 0 - printf("%s: covers disklabel. Leaving\n", - pd->subdevs[part].slice->name); -#endif - pd->subdevs[part].slice->probeinfo.type = NO_SUBPART; - } - if ((tp = slice_probeall(pd->subdevs[part].slice)) != NULL) { - (*tp->constructor)(pd->subdevs[part].slice); - } - } - 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. - */ -static int -dkl_verify(sl_p slice) -{ - register struct private_data *pd; - struct disklabel label; - struct partition *dp, *dp2; - struct disklabel *dl; - int part; - int error; - /* register struct slice *slice; */ - - 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. - */ - 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); - } - } - } - /*- 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); -} - -/*- - * Invalidate all subslices, and free resources for this handler instance. - */ -static int -dkl_revoke(void *private) -{ - register struct private_data *pd; - register struct slice *slice; - int part; - - RR; - pd = private; - slice = pd->slice_down; - for (part = 0; part < MAXPARTITIONS; part++) { - if (pd->subdevs[part].slice) { - sl_rmslice(pd->subdevs[part].slice); - } - } - /*- - * remove ourself as a handler - */ - slice->handler_up = NULL; - slice->private_up = NULL; - slicetype.refs--; -#ifdef BAD144 - if (pd->bad) - free(pd->bad, M_DEVBUF); -#endif - free(pd, M_DEVBUF); - sl_unref(slice); - return (0); -} - /*- * 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 f462887d299..f3eff945ccc 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 @@ -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 -mbr_find_table(sl_p slice, struct buf **bpp, int *blknum) +mbrallocprivate(sl_p slice) { - int ontrack_offset = 0; - int error; + 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_done(sl_p slice, struct buf *bp) +{ + 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,153 +226,199 @@ 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); + goto nope; + } + /*- + * 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. + */ + 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); + } + } } /* - * 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. + * Having got rid of changing slices, replace + * the old table with the new one. */ - if (bcmp(dp0, historical_bogus_partition_table, - sizeof historical_bogus_partition_table) == 0) { - printf("rejecting disklabel table "); - return (EINVAL); - } + bcopy( table, pd->dos_table, sizeof(table)); + /* - * well, it looks like one of ours. + * Handle each of the partitions. + * 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. */ - return (0); + dp = dp0; + for (part = 0; part < NDOSPART; part++, dp++) { + int i; + if (pd->subdevs[part].slice != NULL) +breakout: continue; + if (dp->dp_size == 0) + 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)) { + 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 ) + continue; + if ((dp0[i].dp_start < (dp->dp_start + dp->dp_size)) + && ((dp0[i].dp_start + dp0[i].dp_size) > dp->dp_start)) + { + printf("mbr: new slice %d overlaps slice %d\n", + part, i); + goto breakout; + } + } + /* + * the slice seems to make sense. Use it. + */ + pd->subdevs[part].part = part; + pd->subdevs[part].pd = pd; + pd->subdevs[part].offset = dp->dp_start; + pd->subdevs[part].limit.blksize + = slice->limits.blksize; + pd->subdevs[part].limit.slicesize + = (slice->limits.blksize * (u_int64_t)dp->dp_size); + + sprintf(name, "%ss%d", slice->name, part + 1); + sl_make_slice(&slicetype, + &pd->subdevs[part], + &pd->subdevs[part].limit, + &pd->subdevs[part].slice, + name); + pd->subdevs[part].slice->probeinfo.typespecific = &dp->dp_typ; + switch (dp->dp_typ) { /* list stolen from fdisk */ + case 0x00: /* "unused" */ + case 0x01: /* "Primary DOS with 12 bit FAT" */ + case 0x02: /* "XENIX / filesystem" */ + case 0x03: /* "XENIX /usr filesystem" */ + case 0x04: /* "Primary DOS with 16 bit FAT" */ + case 0x05: /* "Extended DOS" */ + case 0x06: /* "Primary 'big' DOS (> 32MB)" */ + case 0x07: /* "OS/2 HPFS, QNX or Advanced UNIX" */ + case 0x08: /* "AIX filesystem" */ + case 0x09: /* "AIX boot partition or Coherent" */ + case 0x0A: /* "OS/2 Boot Manager or OPUS" */ + case 0x10: /* "OPUS" */ + case 0x40: /* "VENIX 286" */ + case 0x50: /* "DM" */ + case 0x51: /* "DM" */ + case 0x52: /* "CP/M or Microport SysV/AT" */ + case 0x56: /* "GB" */ + case 0x61: /* "Speed" */ + case 0x63: /* "ISC UNIX, System V/386, GNU HURD or Mach" */ + case 0x64: /* "Novell Netware 2.xx" */ + case 0x65: /* "Novell Netware 3.xx" */ + case 0x75: /* "PCIX" */ + case 0x80: /* "Minix 1.1 ... 1.4a" */ + case 0x81: /* "Minix 1.4b ... 1.5.10" */ + case 0x82: /* "Linux swap" */ + case 0x83: /* "Linux filesystem" */ + case 0x93: /* "Amoeba filesystem" */ + case 0x94: /* "Amoeba bad block table" */ + case 0xA6: /* "OpenBSD" */ + case 0xA7: /* "NEXTSTEP" */ + case 0xB7: /* "BSDI BSD/386 filesystem" */ + case 0xB8: /* "BSDI BSD/386 swap" */ + case 0xDB: /* "Concurrent CPM or C.DOS or CTOS" */ + case 0xE1: /* "Speed" */ + case 0xE3: /* "Speed" */ + case 0xE4: /* "Speed" */ + case 0xF1: /* "Speed" */ + case 0xF2: /* "DOS 3.3+ Secondary" */ + case 0xF4: /* "Speed" */ + case 0xFF: /* "BBT (Bad Blocks Table)" */ + printf("%s: type %d. Leaving\n", + pd->subdevs[part].slice->name, + (u_int)dp->dp_typ); + pd->subdevs[part].slice->probeinfo.type = NO_SUBPART; + break; + case DOSPTYP_386BSD: /* 0xA5 "FreeBSD/NetBSD/386BSD" */ + pd->subdevs[part].slice->probeinfo.type = "disklabel"; + break; + default: + pd->subdevs[part].slice->probeinfo.type = NULL; + } + slice_start_probe(pd->subdevs[part].slice); + } + slice->flags &= ~SLF_PROBING; + return (0); +nope: + mbr_revoke(pd); + return (error); } /* @@ -310,12 +427,19 @@ RR; * 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. */ int mbr_geom_hack(struct slice * slice, struct ide_geom *geom) { struct dos_partition table[NDOSPART]; struct dos_partition *dp, *dp0; + struct private_data *pd; int part; int error; int max_ncyls; @@ -324,18 +448,12 @@ mbr_geom_hack(struct slice * slice, struct ide_geom *geom) 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; + if (slice->handler_up != &slicetype) + return (ENXIO); + pd = slice->private_up; /* XXX */ + if (pd == NULL) + return (ENXIO); + dp0 = pd->dos_table; /* * Guess the geometry. For some old drives (ESDI, st506) the * driver below us may not yet know the geometry, but needs @@ -416,252 +534,6 @@ RR; 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; - - /* - * Handle each of the partitions. - * We should check that each makes sence 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. - */ - dp = dp0; - for (part = 0; part < NDOSPART; part++, dp++) { - int i; - if (pd->subdevs[part].slice != NULL) -breakout: continue; - if (dp->dp_size == 0) - continue; - if (dp->dp_start < 1) - continue; - if ((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 ) - continue; - if ((dp0[i].dp_start < (dp->dp_start + dp->dp_size)) - && ((dp0[i].dp_start + dp0[i].dp_size) > dp->dp_start)) - { - printf("mbr: new slice %d overlaps slice %d\n", - part, i); - goto breakout; - } - } - /* - * the slice seems to make sense. Use it. - */ - pd->subdevs[part].part = part; - pd->subdevs[part].pd = pd; - pd->subdevs[part].offset = dp->dp_start; - pd->subdevs[part].limit.blksize - = slice->limits.blksize; - pd->subdevs[part].limit.slicesize - = (slice->limits.blksize * (u_int64_t)dp->dp_size); - - sprintf(name, "%ss%d", slice->name, part + 1); - sl_make_slice(&slicetype, - &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 */ - case 0x00: /* "unused" */ - case 0x01: /* "Primary DOS with 12 bit FAT" */ - case 0x02: /* "XENIX / filesystem" */ - case 0x03: /* "XENIX /usr filesystem" */ - case 0x04: /* "Primary DOS with 16 bit FAT" */ - case 0x05: /* "Extended DOS" */ - case 0x06: /* "Primary 'big' DOS (> 32MB)" */ - case 0x07: /* "OS/2 HPFS, QNX or Advanced UNIX" */ - case 0x08: /* "AIX filesystem" */ - case 0x09: /* "AIX boot partition or Coherent" */ - case 0x0A: /* "OS/2 Boot Manager or OPUS" */ - case 0x10: /* "OPUS" */ - case 0x40: /* "VENIX 286" */ - case 0x50: /* "DM" */ - case 0x51: /* "DM" */ - case 0x52: /* "CP/M or Microport SysV/AT" */ - case 0x56: /* "GB" */ - case 0x61: /* "Speed" */ - case 0x63: /* "ISC UNIX, System V/386, GNU HURD or Mach" */ - case 0x64: /* "Novell Netware 2.xx" */ - case 0x65: /* "Novell Netware 3.xx" */ - case 0x75: /* "PCIX" */ - case 0x80: /* "Minix 1.1 ... 1.4a" */ - case 0x81: /* "Minix 1.4b ... 1.5.10" */ - case 0x82: /* "Linux swap" */ - case 0x83: /* "Linux filesystem" */ - case 0x93: /* "Amoeba filesystem" */ - case 0x94: /* "Amoeba bad block table" */ - case 0xA6: /* "OpenBSD" */ - case 0xA7: /* "NEXTSTEP" */ - case 0xB7: /* "BSDI BSD/386 filesystem" */ - case 0xB8: /* "BSDI BSD/386 swap" */ - case 0xDB: /* "Concurrent CPM or C.DOS or CTOS" */ - case 0xE1: /* "Speed" */ - case 0xE3: /* "Speed" */ - case 0xE4: /* "Speed" */ - case 0xF1: /* "Speed" */ - case 0xF2: /* "DOS 3.3+ Secondary" */ - case 0xF4: /* "Speed" */ - case 0xFF: /* "BBT (Bad Blocks Table)" */ - printf("%s: type %d. Leaving\n", - pd->subdevs[part].slice->name, - (u_int)dp->dp_typ); - pd->subdevs[part].slice->probeinfo.type = NO_SUBPART; - break; - case DOSPTYP_386BSD: /* 0xA5 "FreeBSD/NetBSD/386BSD" */ - pd->subdevs[part].slice->probeinfo.type = "disklabel"; - break; - default: - pd->subdevs[part].slice->probeinfo.type = NULL; - } - if ((tp = slice_probeall(pd->subdevs[part].slice)) != NULL) { - (*tp->constructor)(pd->subdevs[part].slice); - } - } - 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 - */ -static int -mbr_verify(sl_p slice) -{ - register struct private_data *pd; - struct dos_partition table[NDOSPART]; - struct dos_partition *dp, *dp0; - int part; - int error; - /* register struct slice *slice; */ - -RR; - pd = slice->private_up; - /* slice = pd->slice_down; */ - bzero(table, sizeof(table)); - /* - * Try load a valid MBR table. This is 90% of what we need to check. - */ - 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)); - } - /* - * 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. - */ - dp = dp0 = pd->dos_table; - 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); - } - } - } - /* - * 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....) - */ - bcopy( table, dp0, sizeof(table)); - error = mbr_constructor(slice); - return (error); -} - /* * Invalidate all subslices, and free resources for this handler instance. */ @@ -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 3d7eabd679e..ca6dfe049aa 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 60256edcd5c..27521244f2b 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 @@ -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 160b57e12b2..8a586d2232d 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 91973cc66c0..c26370bf859 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 839092d3c4b..636ea0302c3 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 91973cc66c0..c26370bf859 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 697fe4a148a..f9e7b688b87 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 */