mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
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..
This commit is contained in:
parent
9f14a215f4
commit
ad27f8d9a5
10 changed files with 831 additions and 1062 deletions
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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,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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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 ;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue