diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-11-19 16:03:52 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-11-19 16:03:52 +0000 |
commit | d89bd8d4ccb843dc6c19b55e6e8b6c455a0eb705 (patch) | |
tree | 097f626eb6c7cbf12bc67fa6170e97df333eb13e /sys/arch/mvme68k | |
parent | c7b5934b74afaa45a0e07b9b516834569d903d35 (diff) |
typo glitch repair
Diffstat (limited to 'sys/arch/mvme68k')
-rw-r--r-- | sys/arch/mvme68k/mvme68k/disksubr.c | 514 |
1 files changed, 379 insertions, 135 deletions
diff --git a/sys/arch/mvme68k/mvme68k/disksubr.c b/sys/arch/mvme68k/mvme68k/disksubr.c index 81a995068b2..5fc48e7a92f 100644 --- a/sys/arch/mvme68k/mvme68k/disksubr.c +++ b/sys/arch/mvme68k/mvme68k/disksubr.c @@ -1,14 +1,7 @@ -/* $NetBSD: disksubr.c,v 1.2 1995/08/10 19:36:41 chuck Exp $ */ - /* - * Copyright (c) 1982, 1986, 1988, 1993 - * The Regents of the University of California. All rights reserved. - * (c) UNIX System Laboratories, Inc. - * All or some portions of this file are derived from material licensed - * to the University of California by American Telephone and Telegraph - * Co. or Unix System Laboratories, Inc. and are reproduced herein with - * the permission of UNIX System Laboratories, Inc. - * + * Copyright (c) 1995 Dale Rahn. + * All rights reserved. + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: @@ -19,105 +12,138 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * This product includes software developed by Dale Rahn. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include <sys/param.h> -#include <sys/systm.h> #include <sys/buf.h> +#define DKTYPENAMES #include <sys/disklabel.h> -#include <sys/syslog.h> -#define b_cylinder b_resid +#define b_cylin b_resid + +#ifdef DEBUG +int disksubr_debug = 0; +#endif + +static void bsdtocpulabel __P((struct disklabel *lp, + struct cpu_disklabel *clp)); +static void cputobsdlabel __P((struct disklabel *lp, + struct cpu_disklabel *clp)); + +#ifdef DEBUG +static void printlp __P((struct disklabel *lp, char *str)); +static void printclp __P((struct cpu_disklabel *clp, char *str)); +#endif + +int +dk_establish() +{ + return(-1); +} /* - * Attempt to read a disk label from a device using the indicated stategy - * routine. The label must be partly set up before this: secpercyl and - * anything required in the strategy routine (e.g., sector size) must be - * filled in before calling us. Returns null on success and an error - * string on failure. + * Attempt to read a disk label from a device + * using the indicated stategy routine. + * The label must be partly set up before this: + * secpercyl and anything required in the strategy routine + * (e.g., sector size) must be filled in before calling us. + * Returns null on success and an error string on failure. */ char * -readdisklabel(dev, strat, lp, osdep) +readdisklabel(dev, strat, lp, clp) dev_t dev; void (*strat)(); - register struct disklabel *lp; - struct cpu_disklabel *osdep; + struct disklabel *lp; + struct cpu_disklabel *clp; { - register struct buf *bp; - struct disklabel *dlp; + struct buf *bp; char *msg = NULL; - if (lp->d_secperunit == 0) - lp->d_secperunit = 0x1fffffff; - lp->d_npartitions = 1; - if (lp->d_partitions[0].p_size == 0) - lp->d_partitions[0].p_size = 0x1fffffff; - lp->d_partitions[0].p_offset = 0; - + /* obtain buffer to probe drive with */ bp = geteblk((int)lp->d_secsize); + + /* request no partition relocation by driver on I/O operations */ bp->b_dev = dev; - bp->b_blkno = LABELSECTOR; + bp->b_blkno = 0; /* contained in block 0 */ bp->b_bcount = lp->d_secsize; bp->b_flags = B_BUSY | B_READ; - bp->b_cylinder = LABELSECTOR / lp->d_secpercyl; + bp->b_cylin = 0; /* contained in block 0 */ (*strat)(bp); - if (biowait(bp)) - msg = "I/O error"; - else for (dlp = (struct disklabel *)bp->b_data; - dlp <= (struct disklabel *)((char *)bp->b_data + - DEV_BSIZE - sizeof(*dlp)); - dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { - if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { - if (msg == NULL) - msg = "no disk label"; - } else if (dlp->d_npartitions > MAXPARTITIONS || - dkcksum(dlp) != 0) - msg = "disk label corrupted"; - else { - *lp = *dlp; - msg = NULL; - break; - } + + if (biowait(bp)) { + msg = "cpu_disklabel read error\n"; + } else { + bcopy(bp->b_data, clp, sizeof (struct cpu_disklabel)); } - bp->b_flags = B_INVAL | B_AGE; + + bp->b_flags = B_INVAL | B_AGE | B_READ; brelse(bp); + + if (msg || clp->magic1 != DISKMAGIC || clp->magic2 != DISKMAGIC) { + return (msg); + } + + cputobsdlabel(lp, clp); +#ifdef DEBUG + if(disksubr_debug > 0) { + printlp(lp, "readdisklabel:bsd label"); + printclp(clp, "readdisklabel:cpu label"); + } +#endif return (msg); } /* - * Check new disk label for sensibility before setting it. + * Check new disk label for sensibility + * before setting it. */ int -setdisklabel(olp, nlp, openmask, osdep) +setdisklabel(olp, nlp, openmask, clp) register struct disklabel *olp, *nlp; u_long openmask; - struct cpu_disklabel *osdep; + struct cpu_disklabel *clp; { register i; register struct partition *opp, *npp; +#ifdef DEBUG + if(disksubr_debug > 0) { + printlp(nlp, "setdisklabel:new disklabel"); + printlp(olp, "setdisklabel:old disklabel"); + printclp(clp, "setdisklabel:cpu disklabel"); + } +#endif + + + /* sanity clause */ + if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0 || + (nlp->d_secsize % DEV_BSIZE) != 0) + return (EINVAL); + + /* special case to allow disklabel to be invalidated */ + if (nlp->d_magic == 0xffffffff) { + *olp = *nlp; + return (0); + } + if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC || dkcksum(nlp) != 0) return (EINVAL); + while ((i = ffs((long)openmask)) != 0) { i--; openmask &= ~(1 << i); @@ -138,109 +164,327 @@ setdisklabel(olp, nlp, openmask, osdep) npp->p_cpg = opp->p_cpg; } } + nlp->d_checksum = 0; nlp->d_checksum = dkcksum(nlp); *olp = *nlp; +#ifdef DEBUG + if(disksubr_debug > 0) { + printlp(olp, "setdisklabel:old->new disklabel"); + } +#endif return (0); } -/* encoding of disk minor numbers, should be elsewhere... */ -#define dkunit(dev) (minor(dev) >> 3) -#define dkpart(dev) (minor(dev) & 07) -#define dkminor(unit, part) (((unit) << 3) | (part)) - /* * Write disk label back to device after modification. */ -int -writedisklabel(dev, strat, lp, osdep) +writedisklabel(dev, strat, lp, clp) dev_t dev; void (*strat)(); register struct disklabel *lp; - struct cpu_disklabel *osdep; + struct cpu_disklabel *clp; { struct buf *bp; - struct disklabel *dlp; - int labelpart; - int error = 0; + int error; - labelpart = dkpart(dev); - if (lp->d_partitions[labelpart].p_offset != 0) { - if (lp->d_partitions[0].p_offset != 0) - return (EXDEV); /* not quite right */ - labelpart = 0; +#ifdef DEBUG + if(disksubr_debug > 0) { + printlp(lp, "writedisklabel: bsd label"); } +#endif + + /* obtain buffer to read initial cpu_disklabel, for bootloader size :-) */ bp = geteblk((int)lp->d_secsize); - bp->b_dev = makedev(major(dev), dkminor(dkunit(dev), labelpart)); - bp->b_blkno = LABELSECTOR; + + /* request no partition relocation by driver on I/O operations */ + bp->b_dev = dev; + bp->b_blkno = 0; /* contained in block 0 */ bp->b_bcount = lp->d_secsize; - bp->b_flags = B_READ; + bp->b_flags = B_BUSY | B_READ; + bp->b_cylin = 0; /* contained in block 0 */ (*strat)(bp); - if (error = biowait(bp)) - goto done; - for (dlp = (struct disklabel *)bp->b_data; - dlp <= (struct disklabel *) - ((char *)bp->b_data + lp->d_secsize - sizeof(*dlp)); - dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { - if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC && - dkcksum(dlp) == 0) { - *dlp = *lp; - bp->b_flags = B_WRITE; - (*strat)(bp); - error = biowait(bp); - goto done; - } + + if (error = biowait(bp)) { + /* nothing */ + } else { + bcopy(bp->b_data, clp, sizeof(struct cpu_disklabel)); } - error = ESRCH; -done: + + bp->b_flags = B_INVAL | B_AGE | B_READ; brelse(bp); - return (error); + + if (error) { + return (error); + } + + bsdtocpulabel(lp, clp); + +#ifdef DEBUG + if (disksubr_debug > 0) { + printclp(clp, "writedisklabel: cpu label"); + } +#endif + + if (lp->d_magic == DISKMAGIC && lp->d_magic2 == DISKMAGIC && + dkcksum(lp) == 0) { + /* obtain buffer to scrozz drive with */ + bp = geteblk((int)lp->d_secsize); + + bcopy(clp, bp->b_data, sizeof(struct cpu_disklabel)); + + /* request no partition relocation by driver on I/O operations */ + bp->b_dev = dev; + bp->b_blkno = 0; /* contained in block 0 */ + bp->b_bcount = lp->d_secsize; + bp->b_flags = B_WRITE; + bp->b_cylin = 0; /* contained in block 0 */ + (*strat)(bp); + + error = biowait(bp); + + bp->b_flags = B_INVAL | B_AGE | B_READ; + brelse(bp); + } + return (error); } -/* - * Determine the size of the transfer, and make sure it is - * within the boundaries of the partition. Adjust transfer - * if needed, and signal errors or early completion. - */ + int bounds_check_with_label(bp, lp, wlabel) struct buf *bp; struct disklabel *lp; int wlabel; { - struct partition *p = &lp->d_partitions[dkpart(bp->b_dev)]; + struct partition *p = lp->d_partitions + DISKPART(bp->b_dev); int labelsect = lp->d_partitions[0].p_offset; int maxsz = p->p_size; int sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT; - /* Overwriting disk label? */ - if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect && - (bp->b_flags & B_READ) == 0 && !wlabel) { - bp->b_error = EROFS; - goto bad; - } + /* overwriting disk label ? */ + /* XXX should also protect bootstrap in first 8K */ + if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect && +#if LABELSECTOR != 0 + bp->b_blkno + p->p_offset + sz > LABELSECTOR + labelsect && +#endif + (bp->b_flags & B_READ) == 0 && wlabel == 0) { + bp->b_error = EROFS; + goto bad; + } /* beyond partition? */ - if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) { - if (bp->b_blkno == maxsz) { - /* If exactly at end of disk, return EOF. */ - bp->b_resid = bp->b_bcount; - return (0); - } - /* ...or truncate if part of it fits */ - sz = maxsz - bp->b_blkno; - if (sz <= 0) { + if (bp->b_blkno < 0 || bp->b_blkno + sz > maxsz) { + /* if exactly at end of disk, return an EOF */ + if (bp->b_blkno == maxsz) { + bp->b_resid = bp->b_bcount; + return(0); + } + /* or truncate if part of it fits */ + sz = maxsz - bp->b_blkno; + if (sz <= 0) { bp->b_error = EINVAL; - goto bad; + goto bad; } - bp->b_bcount = sz << DEV_BSHIFT; - } + bp->b_bcount = sz << DEV_BSHIFT; + } /* calculate cylinder for disksort to order transfers with */ - bp->b_resid = (bp->b_blkno + p->p_offset) / lp->d_secpercyl; - return (1); + bp->b_cylin = (bp->b_blkno + p->p_offset) / lp->d_secpercyl; + return(1); - bad: +bad: bp->b_flags |= B_ERROR; - return (-1); + return(-1); +} + + +static void +bsdtocpulabel(lp, clp) + struct disklabel *lp; + struct cpu_disklabel *clp; +{ + int i; + + clp->magic1 = lp->d_magic; + clp->type = lp->d_type; + clp->subtype = lp->d_subtype; + strncpy(clp->vid_vd, lp->d_typename, 16); + strncpy(clp->packname, lp->d_packname, 16); + clp->cfg_psm = lp->d_secsize; + clp->cfg_spt = lp->d_nsectors; + clp->cfg_trk = lp->d_ncylinders; /* trk is really num of cyl! */ + clp->cfg_hds = lp->d_ntracks; + + clp->secpercyl = lp->d_secpercyl; + clp->secperunit = lp->d_secperunit; + clp->sparespertrack = lp->d_sparespertrack; + clp->sparespercyl = lp->d_sparespercyl; + clp->acylinders = lp->d_acylinders; + clp->rpm = lp->d_rpm; + + clp->cfg_ilv = lp->d_interleave; + clp->cfg_sof = lp->d_trackskew; + clp->cylskew = lp->d_cylskew; + clp->headswitch = lp->d_headswitch; + + /* this silly table is for winchester drives */ + if (lp->d_trkseek < 6) { + clp->cfg_ssr = 0; + } else if (lp->d_trkseek < 10) { + clp->cfg_ssr = 1; + } else if (lp->d_trkseek < 15) { + clp->cfg_ssr = 2; + } else if (lp->d_trkseek < 20) { + clp->cfg_ssr = 3; + } else { + clp->cfg_ssr = 4; + } + + clp->flags = lp->d_flags; + for (i = 0; i < NDDATA; i++) + clp->drivedata[i] = lp->d_drivedata[i]; + for (i = 0; i < NSPARE; i++) + clp->spare[i] = lp->d_spare[i]; + + clp->magic2 = lp->d_magic2; + clp->checksum = lp->d_checksum; + clp->partitions = lp->d_npartitions; + clp->bbsize = lp->d_bbsize; + clp->sbsize = lp->d_sbsize; + clp->checksum = lp->d_checksum; + bcopy(&lp->d_partitions[0], clp->vid_4, sizeof(struct partition) * 4); + bcopy(&lp->d_partitions[4], clp->cfg_4, sizeof(struct partition) * 12); +} + +static void +cputobsdlabel(lp, clp) + struct disklabel *lp; + struct cpu_disklabel *clp; +{ + int i; + + lp->d_magic = clp->magic1; + lp->d_type = clp->type; + lp->d_subtype = clp->subtype; + strncpy(lp->d_typename, clp->vid_vd, 16); + strncpy(lp->d_packname, clp->packname, 16); + lp->d_secsize = clp->cfg_psm; + lp->d_nsectors = clp->cfg_spt; + lp->d_ncylinders = clp->cfg_trk; /* trk is really num of cyl! */ + lp->d_ntracks = clp->cfg_hds; + + lp->d_secpercyl = clp->secpercyl; + lp->d_secperunit = clp->secperunit; + lp->d_secpercyl = clp->secpercyl; + lp->d_secperunit = clp->secperunit; + lp->d_sparespertrack = clp->sparespertrack; + lp->d_sparespercyl = clp->sparespercyl; + lp->d_acylinders = clp->acylinders; + lp->d_rpm = clp->rpm; + lp->d_interleave = clp->cfg_ilv; + lp->d_trackskew = clp->cfg_sof; + lp->d_cylskew = clp->cylskew; + lp->d_headswitch = clp->headswitch; + + /* this silly table is for winchester drives */ + switch (clp->cfg_ssr) { + case 0: + lp->d_trkseek = 0; + break; + case 1: + lp->d_trkseek = 6; + break; + case 2: + lp->d_trkseek = 10; + break; + case 3: + lp->d_trkseek = 15; + break; + case 4: + lp->d_trkseek = 20; + break; + default: + lp->d_trkseek = 0; + } + lp->d_flags = clp->flags; + for (i = 0; i < NDDATA; i++) + lp->d_drivedata[i] = clp->drivedata[i]; + for (i = 0; i < NSPARE; i++) + lp->d_spare[i] = clp->spare[i]; + + lp->d_magic2 = clp->magic2; + lp->d_checksum = clp->checksum; + lp->d_npartitions = clp->partitions; + lp->d_bbsize = clp->bbsize; + lp->d_sbsize = clp->sbsize; + bcopy(clp->vid_4, &lp->d_partitions[0], sizeof(struct partition) * 4); + bcopy(clp->cfg_4, &lp->d_partitions[4], sizeof(struct partition) * 12); + lp->d_checksum = 0; + lp->d_checksum = dkcksum(lp); +#if DEBUG + if (disksubr_debug > 0) { + printlp(lp, "translated label read from disk\n"); + } +#endif +} + +#ifdef DEBUG +static void +printlp(lp, str) + struct disklabel *lp; + char *str; +{ + int i; + + printf("%s\n", str); + printf("magic1 %x\n", lp->d_magic); + printf("magic2 %x\n", lp->d_magic2); + printf("typename %s\n", lp->d_typename); + printf("secsize %x nsect %x ntrack %x ncylinders %x\n", + lp->d_secsize, lp->d_nsectors, lp->d_ntracks, lp->d_ncylinders); + printf("Num partitions %x\n", lp->d_npartitions); + for (i = 0; i < lp->d_npartitions; i++) { + struct partition *part = &lp->d_partitions[i]; + char *fstyp = fstypenames[part->p_fstype]; + + printf("%c: size %10x offset %10x type %7s frag %5x cpg %3x\n", + 'a' + i, part->p_size, part->p_offset, fstyp, + part->p_frag, part->p_cpg); + } +} + +static void +printclp(clp, str) + struct cpu_disklabel *clp; + char *str; +{ + int max, i; + + printf("%s\n", str); + printf("magic1 %x\n", clp->magic1); + printf("magic2 %x\n", clp->magic2); + printf("typename %s\n", clp->vid_vd); + printf("secsize %x nsect %x ntrack %x ncylinders %x\n", + clp->cfg_psm, clp->cfg_spt, clp->cfg_hds, clp->cfg_trk); + printf("Num partitions %x\n", clp->partitions); + max = clp->partitions < 16 ? clp->partitions : 16; + for (i = 0; i < max; i++) { + struct partition *part; + char *fstyp; + + if (i < 4) { + part = (void *)&clp->vid_4[0]; + part = &part[i]; + } else { + part = (void *)&clp->cfg_4[0]; + part = &part[i-4]; + } + + fstyp = fstypenames[part->p_fstype]; + + printf("%c: size %10x offset %10x type %7s frag %5x cpg %3x\n", + 'a' + i, part->p_size, part->p_offset, fstyp, + part->p_frag, part->p_cpg); + } } +#endif |