summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/kern/subr_disklabel.c301
-rw-r--r--sys/kern/subr_diskmbr.c529
-rw-r--r--sys/kern/subr_diskslice.c940
-rw-r--r--sys/pc98/pc98/diskslice_machdep.c404
4 files changed, 0 insertions, 2174 deletions
diff --git a/sys/kern/subr_disklabel.c b/sys/kern/subr_disklabel.c
deleted file mode 100644
index 32c0a5f..0000000
--- a/sys/kern/subr_disklabel.c
+++ /dev/null
@@ -1,301 +0,0 @@
-#ifdef NO_GEOM
-/*
- * 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.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * 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.
- *
- * @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/stdint.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/conf.h>
-#include <sys/kernel.h>
-#include <sys/disk.h>
-#include <sys/disklabel.h>
-#include <sys/syslog.h>
-
-dev_t
-dkmodpart(dev_t dev, int part)
-{
- return (makedev(major(dev), (minor(dev) & ~7) | part));
-}
-
-/*
- * Attempt to read a disk label from a device using the indicated strategy
- * routine. 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.
- */
-char *
-readdisklabel(dev, lp)
- dev_t dev;
- register struct disklabel *lp;
-{
- register struct buf *bp;
- struct disklabel *dlp;
- char *msg = NULL;
-
- bp = geteblk((int)lp->d_secsize);
- bp->b_dev = dev;
- bp->b_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE);
- bp->b_bcount = lp->d_secsize;
- bp->b_flags &= ~B_INVAL;
- bp->b_iocmd = BIO_READ;
- DEV_STRATEGY(bp);
- if (bufwait(bp))
- msg = "I/O error";
- else if (bp->b_resid != 0)
- msg = "disk too small for a label";
- else 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) {
- 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;
- }
- }
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
- return (msg);
-}
-
-/*
- * Check new disk label for sensibility before setting it.
- */
-int
-setdisklabel(olp, nlp, openmask)
- register struct disklabel *olp, *nlp;
- u_long openmask;
-{
- register int i;
- register struct partition *opp, *npp;
-
- /*
- * Check it is actually a disklabel we are looking at.
- */
- if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
- dkcksum(nlp) != 0)
- return (EINVAL);
- /*
- * For each partition that we think is open,
- */
- while ((i = ffs((long)openmask)) != 0) {
- i--;
- /*
- * Check it is not changing....
- */
- openmask &= ~(1 << i);
- if (nlp->d_npartitions <= i)
- return (EBUSY);
- opp = &olp->d_partitions[i];
- npp = &nlp->d_partitions[i];
- if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size)
- return (EBUSY);
- /*
- * Copy internally-set partition information
- * if new label doesn't include it. XXX
- * (If we are using it then we had better stay the same type)
- * This is possibly dubious, as someone else noted (XXX)
- */
- if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
- npp->p_fstype = opp->p_fstype;
- npp->p_fsize = opp->p_fsize;
- npp->p_frag = opp->p_frag;
- npp->p_cpg = opp->p_cpg;
- }
- }
- nlp->d_checksum = 0;
- nlp->d_checksum = dkcksum(nlp);
- *olp = *nlp;
- return (0);
-}
-
-/*
- * Write disk label back to device after modification.
- */
-int
-writedisklabel(dev, lp)
- dev_t dev;
- register struct disklabel *lp;
-{
- struct buf *bp;
- struct disklabel *dlp;
- int error = 0;
-
- if (lp->d_partitions[RAW_PART].p_offset != 0)
- return (EXDEV); /* not quite right */
- bp = geteblk((int)lp->d_secsize);
- bp->b_dev = dkmodpart(dev, RAW_PART);
- bp->b_blkno = LABELSECTOR * ((int)lp->d_secsize/DEV_BSIZE);
- bp->b_bcount = lp->d_secsize;
-#if 1
- /*
- * We read the label first to see if it's there,
- * in which case we will put ours at the same offset into the block..
- * (I think this is stupid [Julian])
- * Note that you can't write a label out over a corrupted label!
- * (also stupid.. how do you write the first one? by raw writes?)
- */
- bp->b_flags &= ~B_INVAL;
- bp->b_iocmd = BIO_READ;
- DEV_STRATEGY(bp);
- error = bufwait(bp);
- if (error)
- goto done;
- if (bp->b_resid != 0) {
- error = ENOSPC;
- 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_DONE;
- bp->b_iocmd = BIO_WRITE;
-#ifdef __alpha__
- alpha_fix_srm_checksum(bp);
-#endif
- DEV_STRATEGY(bp);
- error = bufwait(bp);
- goto done;
- }
- }
- error = ESRCH;
-done:
-#else
- bzero(bp->b_data, lp->d_secsize);
- dlp = (struct disklabel *)bp->b_data;
- *dlp = *lp;
- bp->b_flags &= ~B_INVAL;
- bp->b_iocmd = BIO_WRITE;
- DEV_STRATEGY(bp);
- error = bufwait(bp);
-#endif
- bp->b_flags |= B_INVAL | B_AGE;
- 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(struct bio *bp, struct disklabel *lp, int wlabel)
-{
- struct partition *p = lp->d_partitions + dkpart(bp->bio_dev);
- int labelsect = lp->d_partitions[0].p_offset;
- int maxsz = p->p_size,
- sz = (bp->bio_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
-
- /* overwriting disk label ? */
- /* XXX should also protect bootstrap in first 8K */
- if (bp->bio_blkno + p->p_offset <= LABELSECTOR + labelsect &&
-#if LABELSECTOR != 0
- bp->bio_blkno + p->p_offset + sz > LABELSECTOR + labelsect &&
-#endif
- (bp->bio_cmd == BIO_WRITE) && wlabel == 0) {
- bp->bio_error = EROFS;
- goto bad;
- }
-
-#if defined(DOSBBSECTOR) && defined(notyet)
- /* overwriting master boot record? */
- if (bp->bio_blkno + p->p_offset <= DOSBBSECTOR &&
- (bp->bio_cmd == BIO_WRITE) && wlabel == 0) {
- bp->bio_error = EROFS;
- goto bad;
- }
-#endif
-
- /* beyond partition? */
- if (bp->bio_blkno < 0 || bp->bio_blkno + sz > maxsz) {
- /* if exactly at end of disk, return an EOF */
- if (bp->bio_blkno == maxsz) {
- bp->bio_resid = bp->bio_bcount;
- return(0);
- }
- /* or truncate if part of it fits */
- sz = maxsz - bp->bio_blkno;
- if (sz <= 0) {
- bp->bio_error = EINVAL;
- goto bad;
- }
- bp->bio_bcount = sz << DEV_BSHIFT;
- }
-
- bp->bio_pblkno = bp->bio_blkno + p->p_offset;
- return(1);
-
-bad:
- bp->bio_flags |= BIO_ERROR;
- return(-1);
-}
-
-#ifdef __alpha__
-void
-alpha_fix_srm_checksum(bp)
- struct buf *bp;
-{
- u_int64_t *p;
- u_int64_t sum;
- int i;
-
- p = (u_int64_t *) bp->b_data;
- sum = 0;
- for (i = 0; i < 63; i++)
- sum += p[i];
- p[63] = sum;
-}
-#endif
-#endif
diff --git a/sys/kern/subr_diskmbr.c b/sys/kern/subr_diskmbr.c
deleted file mode 100644
index b457f44..0000000
--- a/sys/kern/subr_diskmbr.c
+++ /dev/null
@@ -1,529 +0,0 @@
-#ifdef NO_GEOM
-/*-
- * Copyright (c) 1994 Bruce D. Evans.
- * All rights reserved.
- *
- * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * 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.
- *
- * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
- * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/conf.h>
-#ifdef PC98
-#define PC98_ATCOMPAT
-#define dsinit atcompat_dsinit
-#endif
-#include <sys/disk.h>
-#include <sys/disklabel.h>
-#include <sys/diskmbr.h>
-#define DOSPTYP_EXTENDED 5
-#define DOSPTYP_EXTENDEDX 15
-#define DOSPTYP_ONTRACK 84
-#include <sys/diskslice.h>
-#include <sys/malloc.h>
-#include <sys/syslog.h>
-
-#define TRACE(str) do { if (dsi_debug) printf str; } while (0)
-
-static volatile u_char dsi_debug;
-
-/*
- * This is what we have embedded in every boot1 for supporting the bogus
- * "Dangerously Dedicated" mode. However, the old table is broken because
- * it has an illegal geometry in it - it specifies 256 heads (heads = end
- * head + 1) which causes nasty stuff when that wraps to zero in bios code.
- * eg: divide by zero etc. This caused the dead-thinkpad problem, numerous
- * SCSI bios crashes, EFI to crash, etc.
- *
- * We still have to recognize the old table though, even though we stopped
- * inflicting it apon the world.
- */
-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, },
-};
-static struct dos_partition historical_bogus_partition_table_fixed[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, 254, 255, 255, 0, 50000, },
-};
-
-static int check_part(char *sname, struct dos_partition *dp,
- u_long offset, int nsectors, int ntracks,
- u_long mbr_offset);
-static void mbr_extended(dev_t dev, struct disklabel *lp,
- struct diskslices *ssp, u_long ext_offset,
- u_long ext_size, u_long base_ext_offset,
- int nsectors, int ntracks, u_long mbr_offset,
- int level);
-static int mbr_setslice(char *sname, struct disklabel *lp,
- struct diskslice *sp, struct dos_partition *dp,
- u_long br_offset);
-
-static int
-check_part(sname, dp, offset, nsectors, ntracks, mbr_offset )
- char *sname;
- struct dos_partition *dp;
- u_long offset;
- int nsectors;
- int ntracks;
- u_long mbr_offset;
-{
- int chs_ecyl;
- int chs_esect;
- int chs_scyl;
- int chs_ssect;
- int error;
- u_long esector;
- u_long esector1;
- u_long secpercyl;
- u_long ssector;
- u_long ssector1;
-
- secpercyl = (u_long)nsectors * ntracks;
- chs_scyl = DPCYL(dp->dp_scyl, dp->dp_ssect);
- chs_ssect = DPSECT(dp->dp_ssect);
- ssector = chs_ssect - 1 + dp->dp_shd * nsectors + chs_scyl * secpercyl
- + mbr_offset;
- ssector1 = offset + dp->dp_start;
-
- /*
- * If ssector1 is on a cylinder >= 1024, then ssector can't be right.
- * Allow the C/H/S for it to be 1023/ntracks-1/nsectors, or correct
- * apart from the cylinder being reduced modulo 1024. Always allow
- * 1023/255/63, because this is the official way to represent
- * pure-LBA for the starting position.
- */
- if ((ssector < ssector1
- && ((chs_ssect == nsectors && dp->dp_shd == ntracks - 1
- && chs_scyl == 1023)
- || (secpercyl != 0
- && (ssector1 - ssector) % (1024 * secpercyl) == 0)))
- || (dp->dp_scyl == 255 && dp->dp_shd == 255
- && dp->dp_ssect == 255)) {
- TRACE(("%s: C/H/S start %d/%d/%d, start %lu: allow\n",
- sname, chs_scyl, dp->dp_shd, chs_ssect, ssector1));
- ssector = ssector1;
- }
-
- chs_ecyl = DPCYL(dp->dp_ecyl, dp->dp_esect);
- chs_esect = DPSECT(dp->dp_esect);
- esector = chs_esect - 1 + dp->dp_ehd * nsectors + chs_ecyl * secpercyl
- + mbr_offset;
- esector1 = ssector1 + dp->dp_size - 1;
-
- /*
- * Allow certain bogus C/H/S values for esector, as above. However,
- * heads == 255 isn't really legal and causes some BIOS crashes. The
- * correct value to indicate a pure-LBA end is 1023/heads-1/sectors -
- * usually 1023/254/63. "heads" is base 0, "sectors" is base 1.
- */
- if ((esector < esector1
- && ((chs_esect == nsectors && dp->dp_ehd == ntracks - 1
- && chs_ecyl == 1023)
- || (secpercyl != 0
- && (esector1 - esector) % (1024 * secpercyl) == 0)))
- || (dp->dp_ecyl == 255 && dp->dp_ehd == 255
- && dp->dp_esect == 255)) {
- TRACE(("%s: C/H/S end %d/%d/%d, end %lu: allow\n",
- sname, chs_ecyl, dp->dp_ehd, chs_esect, esector1));
- esector = esector1;
- }
-
- error = (ssector == ssector1 && esector == esector1) ? 0 : EINVAL;
- if (bootverbose)
- printf("%s: type 0x%x, start %lu, end = %lu, size %lu %s\n",
- sname, dp->dp_typ, ssector1, esector1,
- (u_long)dp->dp_size, error ? "" : ": OK");
- if (ssector != ssector1 && bootverbose)
- printf("%s: C/H/S start %d/%d/%d (%lu) != start %lu: invalid\n",
- sname, chs_scyl, dp->dp_shd, chs_ssect,
- ssector, ssector1);
- if (esector != esector1 && bootverbose)
- printf("%s: C/H/S end %d/%d/%d (%lu) != end %lu: invalid\n",
- sname, chs_ecyl, dp->dp_ehd, chs_esect,
- esector, esector1);
- return (error);
-}
-
-int
-dsinit(dev, lp, sspp)
- dev_t dev;
- struct disklabel *lp;
- struct diskslices **sspp;
-{
- struct buf *bp;
- u_char *cp;
- int dospart;
- struct dos_partition *dp;
- struct dos_partition *dp0;
- struct dos_partition dpcopy[NDOSPART];
- int error;
- int max_ncyls;
- int max_nsectors;
- int max_ntracks;
- u_long mbr_offset;
- char partname[2];
- u_long secpercyl;
- char *sname;
- struct diskslice *sp;
- struct diskslices *ssp;
-
- mbr_offset = DOSBBSECTOR;
-reread_mbr:
- /* Read master boot record. */
- bp = geteblk((int)lp->d_secsize);
- bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
- bp->b_blkno = mbr_offset;
- bp->b_bcount = lp->d_secsize;
- bp->b_iocmd = BIO_READ;
- DEV_STRATEGY(bp);
- if (bufwait(bp) != 0) {
- disk_err(&bp->b_io, "reading primary partition table: error",
- 0, 1);
- error = EIO;
- goto done;
- }
-
- /* Weakly verify it. */
- cp = bp->b_data;
- sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART, partname);
- if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
- if (bootverbose)
- printf("%s: invalid primary partition table: no magic\n",
- sname);
- error = EINVAL;
- goto done;
- }
-
- /* Make a copy of the partition table to avoid alignment problems. */
- memcpy(&dpcopy[0], cp + DOSPARTOFF, sizeof(dpcopy));
-
- dp0 = &dpcopy[0];
-
- /* Check for "Ontrack Diskmanager". */
- for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
- if (dp->dp_typ == DOSPTYP_ONTRACK) {
- if (bootverbose)
- printf(
- "%s: Found \"Ontrack Disk Manager\" on this disk.\n", sname);
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
- mbr_offset = 63;
- goto reread_mbr;
- }
- }
-
- if (bcmp(dp0, historical_bogus_partition_table,
- sizeof historical_bogus_partition_table) == 0 ||
- bcmp(dp0, historical_bogus_partition_table_fixed,
- sizeof historical_bogus_partition_table_fixed) == 0) {
- if (bootverbose)
- printf(
- "%s: invalid primary partition table: Dangerously Dedicated (ignored)\n",
- sname);
- error = EINVAL;
- goto done;
- }
-
- /* Guess the geometry. */
- /*
- * TODO:
- * Perhaps skip entries with 0 size.
- * Perhaps only look at entries of type DOSPTYP_386BSD.
- */
- max_ncyls = 0;
- max_nsectors = 0;
- max_ntracks = 0;
- for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
- int ncyls;
- int nsectors;
- int ntracks;
-
- ncyls = DPCYL(dp->dp_ecyl, dp->dp_esect) + 1;
- if (max_ncyls < ncyls)
- max_ncyls = ncyls;
- nsectors = DPSECT(dp->dp_esect);
- if (max_nsectors < nsectors)
- max_nsectors = nsectors;
- ntracks = dp->dp_ehd + 1;
- if (max_ntracks < ntracks)
- max_ntracks = ntracks;
- }
-
- /*
- * Check that we have guessed the geometry right by checking the
- * partition entries.
- */
- /*
- * TODO:
- * As above.
- * Check for overlaps.
- * Check against d_secperunit if the latter is reliable.
- */
- error = 0;
- for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
- if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0
- && dp->dp_start == 0 && dp->dp_size == 0)
- continue;
- sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
- RAW_PART, partname);
-
- /*
- * Temporarily ignore errors from this check. We could
- * simplify things by accepting the table eariler if we
- * always ignore errors here. Perhaps we should always
- * accept the table if the magic is right but not let
- * bad entries affect the geometry.
- */
- check_part(sname, dp, mbr_offset, max_nsectors, max_ntracks,
- mbr_offset);
- }
- if (error != 0)
- goto done;
-
- /*
- * Accept the DOS partition table.
- * First adjust the label (we have been careful not to change it
- * before we can guarantee success).
- */
- secpercyl = (u_long)max_nsectors * max_ntracks;
- if (secpercyl != 0) {
- lp->d_nsectors = max_nsectors;
- lp->d_ntracks = max_ntracks;
- lp->d_secpercyl = secpercyl;
- lp->d_ncylinders = lp->d_secperunit / secpercyl;
- }
-
- /*
- * We are passed a pointer to a suitably initialized minimal
- * slices "struct" with no dangling pointers in it. Replace it
- * by a maximal one. This usually oversizes the "struct", but
- * enlarging it while searching for logical drives would be
- * inconvenient.
- */
- free(*sspp, M_DEVBUF);
- ssp = dsmakeslicestruct(MAX_SLICES, lp);
- *sspp = ssp;
-
- /* Initialize normal slices. */
- sp = &ssp->dss_slices[BASE_SLICE];
- for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++, sp++) {
- sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
- RAW_PART, partname);
- (void)mbr_setslice(sname, lp, sp, dp, mbr_offset);
- }
- ssp->dss_nslices = BASE_SLICE + NDOSPART;
-
- /* Handle extended partitions. */
- sp -= NDOSPART;
- for (dospart = 0; dospart < NDOSPART; dospart++, sp++)
- if (sp->ds_type == DOSPTYP_EXTENDED ||
- sp->ds_type == DOSPTYP_EXTENDEDX)
- mbr_extended(bp->b_dev, lp, ssp,
- sp->ds_offset, sp->ds_size, sp->ds_offset,
- max_nsectors, max_ntracks, mbr_offset, 1);
-
- /*
- * mbr_extended() abuses ssp->dss_nslices for the number of slices
- * that would be found if there were no limit on the number of slices
- * in *ssp. Cut it back now.
- */
- if (ssp->dss_nslices > MAX_SLICES)
- ssp->dss_nslices = MAX_SLICES;
-
-done:
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
- if (error == EINVAL)
- error = 0;
- return (error);
-}
-
-static void
-mbr_extended(dev, lp, ssp, ext_offset, ext_size, base_ext_offset, nsectors,
- ntracks, mbr_offset, level)
- dev_t dev;
- struct disklabel *lp;
- struct diskslices *ssp;
- u_long ext_offset;
- u_long ext_size;
- u_long base_ext_offset;
- int nsectors;
- int ntracks;
- u_long mbr_offset;
- int level;
-{
- struct buf *bp;
- u_char *cp;
- int dospart;
- struct dos_partition *dp;
- struct dos_partition dpcopy[NDOSPART];
- u_long ext_offsets[NDOSPART];
- u_long ext_sizes[NDOSPART];
- char partname[2];
- int slice;
- char *sname;
- struct diskslice *sp;
-
- if (level >= 16) {
- printf(
- "%s: excessive recursion in search for slices; aborting search\n",
- devtoname(dev));
- return;
- }
-
- /* Read extended boot record. */
- bp = geteblk((int)lp->d_secsize);
- bp->b_dev = dev;
- bp->b_blkno = ext_offset;
- bp->b_bcount = lp->d_secsize;
- bp->b_iocmd = BIO_READ;
- DEV_STRATEGY(bp);
- if (bufwait(bp) != 0) {
- disk_err(&bp->b_io, "reading extended partition table: error",
- 0, 1);
- goto done;
- }
-
- /* Weakly verify it. */
- cp = bp->b_data;
- if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
- sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART,
- partname);
- if (bootverbose)
- printf("%s: invalid extended partition table: no magic\n",
- sname);
- goto done;
- }
-
- /* Make a copy of the partition table to avoid alignment problems. */
- memcpy(&dpcopy[0], cp + DOSPARTOFF, sizeof(dpcopy));
-
- slice = ssp->dss_nslices;
- for (dospart = 0, dp = &dpcopy[0]; dospart < NDOSPART;
- dospart++, dp++) {
- ext_sizes[dospart] = 0;
- if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0
- && dp->dp_start == 0 && dp->dp_size == 0)
- continue;
- if (dp->dp_typ == DOSPTYP_EXTENDED ||
- dp->dp_typ == DOSPTYP_EXTENDEDX) {
- static char buf[32];
-
- sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE,
- RAW_PART, partname);
- snprintf(buf, sizeof(buf), "%s", sname);
- if (strlen(buf) < sizeof buf - 11)
- strcat(buf, "<extended>");
- check_part(buf, dp, base_ext_offset, nsectors,
- ntracks, mbr_offset);
- ext_offsets[dospart] = base_ext_offset + dp->dp_start;
- ext_sizes[dospart] = dp->dp_size;
- } else {
- sname = dsname(dev, dkunit(dev), slice, RAW_PART,
- partname);
- check_part(sname, dp, ext_offset, nsectors, ntracks,
- mbr_offset);
- if (slice >= MAX_SLICES) {
- printf("%s: too many slices\n", sname);
- slice++;
- continue;
- }
- sp = &ssp->dss_slices[slice];
- if (mbr_setslice(sname, lp, sp, dp, ext_offset) != 0)
- continue;
- slice++;
- }
- }
- ssp->dss_nslices = slice;
-
- /* If we found any more slices, recursively find all the subslices. */
- for (dospart = 0; dospart < NDOSPART; dospart++)
- if (ext_sizes[dospart] != 0)
- mbr_extended(dev, lp, ssp, ext_offsets[dospart],
- ext_sizes[dospart], base_ext_offset,
- nsectors, ntracks, mbr_offset, ++level);
-
-done:
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
-}
-
-static int
-mbr_setslice(sname, lp, sp, dp, br_offset)
- char *sname;
- struct disklabel *lp;
- struct diskslice *sp;
- struct dos_partition *dp;
- u_long br_offset;
-{
- u_long offset;
- u_long size;
-
- offset = br_offset + dp->dp_start;
- if (offset > lp->d_secperunit || offset < br_offset) {
- printf(
- "%s: slice starts beyond end of the disk: rejecting it\n",
- sname);
- return (1);
- }
- size = lp->d_secperunit - offset;
- if (size >= dp->dp_size)
- size = dp->dp_size;
- else
- printf(
-"%s: slice extends beyond end of disk: truncating from %lu to %lu sectors\n",
- sname, (u_long)dp->dp_size, size);
- sp->ds_offset = offset;
- sp->ds_size = size;
- sp->ds_type = dp->dp_typ;
-#ifdef PC98_ATCOMPAT
- /* Fake FreeBSD(98). */
- if (sp->ds_type == DOSPTYP_386BSD)
- sp->ds_type = 0x94;
-#endif
-#if 0
- lp->d_subtype |= (lp->d_subtype & 3) | dospart | DSTYPE_INDOSPART;
-#endif
- return (0);
-}
-#endif
diff --git a/sys/kern/subr_diskslice.c b/sys/kern/subr_diskslice.c
deleted file mode 100644
index f674c37..0000000
--- a/sys/kern/subr_diskslice.c
+++ /dev/null
@@ -1,940 +0,0 @@
-#ifdef NO_GEOM
-/*-
- * Copyright (c) 1994 Bruce D. Evans.
- * All rights reserved.
- *
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * 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.
- *
- * from: @(#)wd.c 7.2 (Berkeley) 5/9/91
- * from: wd.c,v 1.55 1994/10/22 01:57:12 phk Exp $
- * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
- * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
- * $FreeBSD$
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bio.h>
-#include <sys/conf.h>
-#include <sys/disk.h>
-#include <sys/disklabel.h>
-#include <sys/diskslice.h>
-#if defined(PC98) && !defined(PC98_ATCOMPAT)
-#include <sys/diskpc98.h>
-#else
-#include <sys/diskmbr.h>
-#endif
-#include <sys/fcntl.h>
-#include <sys/malloc.h>
-#include <sys/stat.h>
-#include <sys/stdint.h>
-#include <sys/syslog.h>
-#include <sys/vnode.h>
-
-#define TRACE(str) do { if (ds_debug) printf str; } while (0)
-
-typedef u_char bool_t;
-
-static volatile bool_t ds_debug;
-
-static struct disklabel *clone_label(struct disklabel *lp);
-static void dsiodone(struct bio *bp);
-static char *fixlabel(char *sname, struct diskslice *sp,
- struct disklabel *lp, int writeflag);
-static void free_ds_label(struct diskslices *ssp, int slice);
-static void partition_info(char *sname, int part, struct partition *pp);
-static void slice_info(char *sname, struct diskslice *sp);
-static void set_ds_label(struct diskslices *ssp, int slice,
- struct disklabel *lp);
-static void set_ds_labeldevs(dev_t dev, struct diskslices *ssp);
-static void set_ds_wlabel(struct diskslices *ssp, int slice,
- int wlabel);
-
-/*
- * Duplicate a label for the whole disk, and initialize defaults in the
- * copy for fields that are not already initialized. The caller only
- * needs to initialize d_secsize and d_secperunit, and zero the fields
- * that are to be defaulted.
- */
-static struct disklabel *
-clone_label(lp)
- struct disklabel *lp;
-{
- struct disklabel *lp1;
-
- lp1 = malloc(sizeof *lp1, M_DEVBUF, 0);
- *lp1 = *lp;
- lp = NULL;
- if (lp1->d_typename[0] == '\0')
- strlcpy(lp1->d_typename, "amnesiac", sizeof(lp1->d_typename));
- if (lp1->d_packname[0] == '\0')
- strlcpy(lp1->d_packname, "fictitious", sizeof(lp1->d_packname));
- if (lp1->d_nsectors == 0)
- lp1->d_nsectors = 32;
- if (lp1->d_ntracks == 0)
- lp1->d_ntracks = 64;
- lp1->d_secpercyl = lp1->d_nsectors * lp1->d_ntracks;
- lp1->d_ncylinders = lp1->d_secperunit / lp1->d_secpercyl;
- if (lp1->d_rpm == 0)
- lp1->d_rpm = 3600;
- if (lp1->d_interleave == 0)
- lp1->d_interleave = 1;
- if (lp1->d_npartitions < RAW_PART + 1)
- lp1->d_npartitions = MAXPARTITIONS;
- if (lp1->d_bbsize == 0)
- lp1->d_bbsize = BBSIZE;
- lp1->d_partitions[RAW_PART].p_size = lp1->d_secperunit;
- lp1->d_magic = DISKMAGIC;
- lp1->d_magic2 = DISKMAGIC;
- lp1->d_checksum = dkcksum(lp1);
- return (lp1);
-}
-
-dev_t
-dkmodslice(dev_t dev, int slice)
-{
- return (makedev(major(dev), (minor(dev) & ~0x1f0000) | (slice << 16)));
-}
-
-u_int
-dkunit(dev_t dev)
-{
- return (((minor(dev) >> 16) & 0x1e0) | ((minor(dev) >> 3) & 0x1f));
-}
-
-/*
- * 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.
- *
- * XXX TODO:
- * o Split buffers that are too big for the device.
- * o Check for overflow.
- * o Finish cleaning this up.
- */
-int
-dscheck(bp, ssp)
- struct bio *bp;
- struct diskslices *ssp;
-{
- daddr_t blkno;
- daddr_t endsecno;
- daddr_t labelsect;
- struct disklabel *lp;
- char *msg;
- long nsec;
- struct partition *pp;
- daddr_t secno;
- daddr_t slicerel_secno;
- struct diskslice *sp;
-
- blkno = bp->bio_blkno;
- if (blkno < 0) {
- printf("dscheck(%s): negative bio_blkno %ld\n",
- devtoname(bp->bio_dev), (long)blkno);
- bp->bio_error = EINVAL;
- goto bad;
- }
- sp = &ssp->dss_slices[dkslice(bp->bio_dev)];
- lp = sp->ds_label;
- if (ssp->dss_secmult == 1) {
- if (bp->bio_bcount % (u_long)DEV_BSIZE)
- goto bad_bcount;
- secno = blkno;
- nsec = bp->bio_bcount >> DEV_BSHIFT;
- } else if (ssp->dss_secshift != -1) {
- if (bp->bio_bcount & (ssp->dss_secsize - 1))
- goto bad_bcount;
- if (blkno & (ssp->dss_secmult - 1))
- goto bad_blkno;
- secno = blkno >> ssp->dss_secshift;
- nsec = bp->bio_bcount >> (DEV_BSHIFT + ssp->dss_secshift);
- } else {
- if (bp->bio_bcount % ssp->dss_secsize)
- goto bad_bcount;
- if (blkno % ssp->dss_secmult)
- goto bad_blkno;
- secno = blkno / ssp->dss_secmult;
- nsec = bp->bio_bcount / ssp->dss_secsize;
- }
- if (lp == NULL) {
- labelsect = -LABELSECTOR - 1;
- endsecno = sp->ds_size;
- slicerel_secno = secno;
- } else {
- labelsect = lp->d_partitions[LABEL_PART].p_offset;
- if (labelsect != 0)
- Debugger("labelsect != 0 in dscheck()");
- pp = &lp->d_partitions[dkpart(bp->bio_dev)];
- endsecno = pp->p_size;
- slicerel_secno = pp->p_offset + secno;
- }
-
- /* overwriting disk label ? */
- /* XXX should also protect bootstrap in first 8K */
- if (slicerel_secno <= LABELSECTOR + labelsect &&
-#if LABELSECTOR != 0
- slicerel_secno + nsec > LABELSECTOR + labelsect &&
-#endif
- (bp->bio_cmd == BIO_WRITE) && sp->ds_wlabel == 0) {
- bp->bio_error = EROFS;
- goto bad;
- }
-
-#if defined(DOSBBSECTOR) && defined(notyet)
- /* overwriting master boot record? */
- if (slicerel_secno <= DOSBBSECTOR && (bp->bio_cmd == BIO_WRITE) &&
- sp->ds_wlabel == 0) {
- bp->bio_error = EROFS;
- goto bad;
- }
-#endif
-
- /* beyond partition? */
- if ((uintmax_t)secno + nsec > endsecno) {
- /* if exactly at end of disk, return an EOF */
- if (secno == endsecno) {
- bp->bio_resid = bp->bio_bcount;
- return (0);
- }
- /* or truncate if part of it fits */
- if (secno > endsecno) {
- bp->bio_error = EINVAL;
- goto bad;
- }
- bp->bio_bcount = (endsecno - secno) * ssp->dss_secsize;
- }
-
- bp->bio_pblkno = sp->ds_offset + slicerel_secno;
-
- /*
- * Snoop on label accesses if the slice offset is nonzero. Fudge
- * offsets in the label to keep the in-core label coherent with
- * the on-disk one.
- */
- if (slicerel_secno <= LABELSECTOR + labelsect
-#if LABELSECTOR != 0
- && slicerel_secno + nsec > LABELSECTOR + labelsect
-#endif
- && sp->ds_offset != 0) {
- struct iodone_chain *ic;
-
- ic = malloc(sizeof *ic , M_DEVBUF, 0);
- ic->ic_prev_flags = bp->bio_flags;
- ic->ic_prev_iodone = bp->bio_done;
- ic->ic_prev_iodone_chain = bp->bio_done_chain;
- ic->ic_args[0].ia_long = (LABELSECTOR + labelsect -
- slicerel_secno) * ssp->dss_secsize;
- ic->ic_args[1].ia_ptr = sp;
- bp->bio_done = dsiodone;
- bp->bio_done_chain = ic;
- if (!(bp->bio_cmd == BIO_READ)) {
- /*
- * XXX even disklabel(8) writes directly so we need
- * to adjust writes. Perhaps we should drop support
- * for DIOCWLABEL (always write protect labels) and
- * require the use of DIOCWDINFO.
- *
- * XXX probably need to copy the data to avoid even
- * temporarily corrupting the in-core copy.
- */
- /* XXX need name here. */
- msg = fixlabel((char *)NULL, sp,
- (struct disklabel *)
- (bp->bio_data + ic->ic_args[0].ia_long),
- TRUE);
- if (msg != NULL) {
- printf("dscheck(%s): %s\n",
- devtoname(bp->bio_dev), msg);
- bp->bio_error = EROFS;
- goto bad;
- }
- }
- }
- return (1);
-
-bad_bcount:
- printf(
- "dscheck(%s): bio_bcount %ld is not on a sector boundary (ssize %d)\n",
- devtoname(bp->bio_dev), bp->bio_bcount, ssp->dss_secsize);
- bp->bio_error = EINVAL;
- goto bad;
-
-bad_blkno:
- printf(
- "dscheck(%s): bio_blkno %ld is not on a sector boundary (ssize %d)\n",
- devtoname(bp->bio_dev), (long)blkno, ssp->dss_secsize);
- bp->bio_error = EINVAL;
- goto bad;
-
-bad:
- bp->bio_resid = bp->bio_bcount;
- bp->bio_flags |= BIO_ERROR;
- return (-1);
-}
-
-void
-dsclose(dev, mode, ssp)
- dev_t dev;
- int mode;
- struct diskslices *ssp;
-{
- u_char mask;
- struct diskslice *sp;
-
- sp = &ssp->dss_slices[dkslice(dev)];
- mask = 1 << dkpart(dev);
- sp->ds_openmask &= ~mask;
-}
-
-void
-dsgone(sspp)
- struct diskslices **sspp;
-{
- int slice;
- struct diskslice *sp;
- struct diskslices *ssp;
-
- for (slice = 0, ssp = *sspp; slice < ssp->dss_nslices; slice++) {
- sp = &ssp->dss_slices[slice];
- free_ds_label(ssp, slice);
- }
- free(ssp, M_DEVBUF);
- *sspp = NULL;
-}
-
-/*
- * For the "write" commands (DIOCSDINFO and DIOCWDINFO), this
- * is subject to the same restriction as dsopen().
- */
-int
-dsioctl(dev, cmd, data, flags, sspp)
- dev_t dev;
- u_long cmd;
- caddr_t data;
- int flags;
- struct diskslices **sspp;
-{
- int error;
- struct disklabel *lp;
- int old_wlabel;
- u_char openmask;
- int part;
- int slice;
- struct diskslice *sp;
- struct diskslices *ssp;
-
- slice = dkslice(dev);
- ssp = *sspp;
- sp = &ssp->dss_slices[slice];
- lp = sp->ds_label;
- switch (cmd) {
-
- case DIOCGDINFO:
- if (lp == NULL)
- return (EINVAL);
- *(struct disklabel *)data = *lp;
- return (0);
-
- case DIOCGMEDIASIZE:
- if (lp == NULL)
- *(off_t *)data = (off_t)sp->ds_size * ssp->dss_secsize;
- else
- *(off_t *)data =
- (off_t)lp->d_partitions[dkpart(dev)].p_size *
- lp->d_secsize;
- return (0);
-
- case DIOCGSECTORSIZE:
- *(u_int *)data = ssp->dss_secsize;
- return (0);
-
- case DIOCGSLICEINFO:
- bcopy(ssp, data, (char *)&ssp->dss_slices[ssp->dss_nslices] -
- (char *)ssp);
- return (0);
-
- case DIOCSDINFO:
- if (slice == WHOLE_DISK_SLICE)
- return (ENODEV);
- if (!(flags & FWRITE))
- return (EBADF);
- lp = malloc(sizeof *lp, M_DEVBUF, 0);
- if (sp->ds_label == NULL)
- bzero(lp, sizeof *lp);
- else
- bcopy(sp->ds_label, lp, sizeof *lp);
- if (sp->ds_label == NULL)
- openmask = 0;
- else {
- openmask = sp->ds_openmask;
- if (slice == COMPATIBILITY_SLICE)
- openmask |= ssp->dss_slices[
- ssp->dss_first_bsd_slice].ds_openmask;
- else if (slice == ssp->dss_first_bsd_slice)
- openmask |= ssp->dss_slices[
- COMPATIBILITY_SLICE].ds_openmask;
- }
- error = setdisklabel(lp, (struct disklabel *)data,
- (u_long)openmask);
- /* XXX why doesn't setdisklabel() check this? */
- if (error == 0 && lp->d_partitions[RAW_PART].p_offset != 0)
- error = EXDEV;
- if (error == 0) {
- if (lp->d_secperunit > sp->ds_size)
- error = ENOSPC;
- for (part = 0; part < lp->d_npartitions; part++)
- if (lp->d_partitions[part].p_size > sp->ds_size)
- error = ENOSPC;
- }
- if (error != 0) {
- free(lp, M_DEVBUF);
- return (error);
- }
- free_ds_label(ssp, slice);
- set_ds_label(ssp, slice, lp);
- set_ds_labeldevs(dev, ssp);
- return (0);
-
- case DIOCSYNCSLICEINFO:
- if (slice != WHOLE_DISK_SLICE || dkpart(dev) != RAW_PART)
- return (EINVAL);
- if (!*(int *)data)
- for (slice = 0; slice < ssp->dss_nslices; slice++) {
- openmask = ssp->dss_slices[slice].ds_openmask;
- if (openmask
- && (slice != WHOLE_DISK_SLICE
- || openmask & ~(1 << RAW_PART)))
- return (EBUSY);
- }
-
- /*
- * Temporarily forget the current slices struct and read
- * the current one.
- * XXX should wait for current accesses on this disk to
- * complete, then lock out future accesses and opens.
- */
- *sspp = NULL;
- lp = malloc(sizeof *lp, M_DEVBUF, 0);
- *lp = *ssp->dss_slices[WHOLE_DISK_SLICE].ds_label;
- error = dsopen(dev, S_IFCHR, ssp->dss_oflags, sspp, lp);
- if (error != 0) {
- free(lp, M_DEVBUF);
- *sspp = ssp;
- return (error);
- }
-
- /*
- * Reopen everything. This is a no-op except in the "force"
- * case and when the raw bdev and cdev are both open. Abort
- * if anything fails.
- */
- for (slice = 0; slice < ssp->dss_nslices; slice++) {
- for (openmask = ssp->dss_slices[slice].ds_openmask,
- part = 0; openmask; openmask >>= 1, part++) {
- if (!(openmask & 1))
- continue;
- error = dsopen(dkmodslice(dkmodpart(dev, part),
- slice),
- S_IFCHR, ssp->dss_oflags, sspp,
- lp);
- if (error != 0) {
- free(lp, M_DEVBUF);
- *sspp = ssp;
- return (EBUSY);
- }
- }
- }
-
- free(lp, M_DEVBUF);
- dsgone(&ssp);
- return (0);
-
- case DIOCWDINFO:
- error = dsioctl(dev, DIOCSDINFO, data, flags, &ssp);
- if (error != 0)
- return (error);
- /*
- * XXX this used to hack on dk_openpart to fake opening
- * partition 0 in case that is used instead of dkpart(dev).
- */
- old_wlabel = sp->ds_wlabel;
- set_ds_wlabel(ssp, slice, TRUE);
- error = writedisklabel(dev, sp->ds_label);
- /* XXX should invalidate in-core label if write failed. */
- set_ds_wlabel(ssp, slice, old_wlabel);
- return (error);
-
- case DIOCWLABEL:
-#ifndef __alpha__
- if (slice == WHOLE_DISK_SLICE)
- return (ENODEV);
-#endif
- if (!(flags & FWRITE))
- return (EBADF);
- set_ds_wlabel(ssp, slice, *(int *)data != 0);
- return (0);
-
- default:
- return (ENOIOCTL);
- }
-}
-
-static void
-dsiodone(bp)
- struct bio *bp;
-{
- struct iodone_chain *ic;
- char *msg;
-
- ic = bp->bio_done_chain;
- bp->bio_done = ic->ic_prev_iodone;
- bp->bio_done_chain = ic->ic_prev_iodone_chain;
- if (!(bp->bio_cmd == BIO_READ)
- || (!(bp->bio_flags & BIO_ERROR) && bp->bio_error == 0)) {
- msg = fixlabel((char *)NULL, ic->ic_args[1].ia_ptr,
- (struct disklabel *)
- (bp->bio_data + ic->ic_args[0].ia_long),
- FALSE);
- if (msg != NULL)
- printf("%s\n", msg);
- }
- free(ic, M_DEVBUF);
- biodone(bp);
-}
-
-int
-dsisopen(ssp)
- struct diskslices *ssp;
-{
- int slice;
-
- if (ssp == NULL)
- return (0);
- for (slice = 0; slice < ssp->dss_nslices; slice++)
- if (ssp->dss_slices[slice].ds_openmask)
- return (1);
- return (0);
-}
-
-/*
- * Allocate a slices "struct" and initialize it to contain only an empty
- * compatibility slice (pointing to itself), a whole disk slice (covering
- * the disk as described by the label), and (nslices - BASE_SLICES) empty
- * slices beginning at BASE_SLICE.
- */
-struct diskslices *
-dsmakeslicestruct(nslices, lp)
- int nslices;
- struct disklabel *lp;
-{
- struct diskslice *sp;
- struct diskslices *ssp;
-
- ssp = malloc(offsetof(struct diskslices, dss_slices) +
- nslices * sizeof *sp, M_DEVBUF, 0);
- ssp->dss_first_bsd_slice = COMPATIBILITY_SLICE;
- ssp->dss_nslices = nslices;
- ssp->dss_oflags = 0;
- ssp->dss_secmult = lp->d_secsize / DEV_BSIZE;
- if (ssp->dss_secmult & (ssp->dss_secmult - 1))
- ssp->dss_secshift = -1;
- else
- ssp->dss_secshift = ffs(ssp->dss_secmult) - 1;
- ssp->dss_secsize = lp->d_secsize;
- sp = &ssp->dss_slices[0];
- bzero(sp, nslices * sizeof *sp);
- sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
- return (ssp);
-}
-
-char *
-dsname(dev, unit, slice, part, partname)
- dev_t dev;
- int unit;
- int slice;
- int part;
- char *partname;
-{
- static char name[32];
- const char *dname;
-
- dname = devsw(dev)->d_name;
- if (strlen(dname) > 16)
- dname = "nametoolong";
- snprintf(name, sizeof(name), "%s%d", dname, unit);
- partname[0] = '\0';
- if (slice != WHOLE_DISK_SLICE || part != RAW_PART) {
- partname[0] = 'a' + part;
- partname[1] = '\0';
- if (slice != COMPATIBILITY_SLICE)
- snprintf(name + strlen(name),
- sizeof(name) - strlen(name), "s%d", slice - 1);
- }
- return (name);
-}
-
-/*
- * This should only be called when the unit is inactive and the strategy
- * routine should not allow it to become active unless we call it. Our
- * strategy routine must be special to allow activity.
- */
-int
-dsopen(dev, mode, flags, sspp, lp)
- dev_t dev;
- int mode;
- u_int flags;
- struct diskslices **sspp;
- struct disklabel *lp;
-{
- dev_t dev1;
- int error;
- struct disklabel *lp1;
- char *msg;
- u_char mask;
- int part;
- char partname[2];
- int slice;
- char *sname;
- struct diskslice *sp;
- struct diskslices *ssp;
- int unit;
-
- dev->si_bsize_phys = lp->d_secsize;
-
- unit = dkunit(dev);
- if (lp->d_secsize % DEV_BSIZE) {
- printf("%s: invalid sector size %lu\n", devtoname(dev),
- (u_long)lp->d_secsize);
- return (EINVAL);
- }
-
- /*
- * XXX reinitialize the slice table unless there is an open device
- * on the unit. This should only be done if the media has changed.
- */
- ssp = *sspp;
- if (!dsisopen(ssp)) {
- if (ssp != NULL)
- dsgone(sspp);
- /*
- * Allocate a minimal slices "struct". This will become
- * the final slices "struct" if we don't want real slices
- * or if we can't find any real slices.
- */
- *sspp = dsmakeslicestruct(BASE_SLICE, lp);
-
- TRACE(("dsinit\n"));
- error = dsinit(dev, lp, sspp);
- if (error != 0) {
- dsgone(sspp);
- return (error);
- }
- ssp = *sspp;
- ssp->dss_oflags = flags;
-
- /*
- * If there are no real slices, then make the compatiblity
- * slice cover the whole disk.
- */
- if (ssp->dss_nslices == BASE_SLICE)
- ssp->dss_slices[COMPATIBILITY_SLICE].ds_size
- = lp->d_secperunit;
-
- /* Point the compatibility slice at the BSD slice, if any. */
- for (slice = BASE_SLICE; slice < ssp->dss_nslices; slice++) {
- sp = &ssp->dss_slices[slice];
- if (sp->ds_type == DOSPTYP_386BSD /* XXX */) {
- ssp->dss_first_bsd_slice = slice;
- ssp->dss_slices[COMPATIBILITY_SLICE].ds_offset
- = sp->ds_offset;
- ssp->dss_slices[COMPATIBILITY_SLICE].ds_size
- = sp->ds_size;
- ssp->dss_slices[COMPATIBILITY_SLICE].ds_type
- = sp->ds_type;
- break;
- }
- }
-
- ssp->dss_slices[WHOLE_DISK_SLICE].ds_label = clone_label(lp);
- ssp->dss_slices[WHOLE_DISK_SLICE].ds_wlabel = TRUE;
- }
-
- /* Initialize secondary info for all slices. */
- for (slice = 0; slice < ssp->dss_nslices; slice++) {
- sp = &ssp->dss_slices[slice];
- if (sp->ds_label != NULL
-#ifdef __alpha__
- && slice != WHOLE_DISK_SLICE
-#endif
- )
- continue;
- dev1 = dkmodslice(dkmodpart(dev, RAW_PART), slice);
-#if 0
- sname = dsname(dev, unit, slice, RAW_PART, partname);
-#else
- *partname='\0';
- sname = dev1->si_name;
-#endif
- /*
- * XXX this should probably only be done for the need_init
- * case, but there may be a problem with DIOCSYNCSLICEINFO.
- */
- set_ds_wlabel(ssp, slice, TRUE); /* XXX invert */
- lp1 = clone_label(lp);
- TRACE(("readdisklabel\n"));
- msg = readdisklabel(dev1, lp1);
- if (msg == NULL)
- msg = fixlabel(sname, sp, lp1, FALSE);
- if (msg == NULL && lp1->d_secsize != ssp->dss_secsize)
- msg = "inconsistent sector size";
- if (msg != NULL) {
- if (sp->ds_type == DOSPTYP_386BSD /* XXX */)
- log(LOG_WARNING, "%s: cannot find label (%s)\n",
- sname, msg);
- free(lp1, M_DEVBUF);
- continue;
- }
- if (lp1->d_flags & D_BADSECT) {
- log(LOG_ERR, "%s: bad sector table not supported\n",
- sname);
- free(lp1, M_DEVBUF);
- continue;
- }
- set_ds_label(ssp, slice, lp1);
- set_ds_labeldevs(dev1, ssp);
- set_ds_wlabel(ssp, slice, FALSE);
- }
-
- slice = dkslice(dev);
- if (slice >= ssp->dss_nslices)
- return (ENXIO);
- sp = &ssp->dss_slices[slice];
- part = dkpart(dev);
- if (part != RAW_PART
- && (sp->ds_label == NULL || part >= sp->ds_label->d_npartitions))
- return (EINVAL); /* XXX needs translation */
- mask = 1 << part;
- sp->ds_openmask |= mask;
- return (0);
-}
-
-int
-dssize(dev, sspp)
- dev_t dev;
- struct diskslices **sspp;
-{
- struct disklabel *lp;
- int part;
- int slice;
- struct diskslices *ssp;
-
- slice = dkslice(dev);
- part = dkpart(dev);
- ssp = *sspp;
- if (ssp == NULL || slice >= ssp->dss_nslices
- || !(ssp->dss_slices[slice].ds_openmask & (1 << part))) {
- if (devsw(dev)->d_open(dev, FREAD, S_IFCHR,
- (struct thread *)NULL) != 0)
- return (-1);
- devsw(dev)->d_close(dev, FREAD, S_IFCHR, (struct thread *)NULL);
- ssp = *sspp;
- }
- lp = ssp->dss_slices[slice].ds_label;
- if (lp == NULL)
- return (-1);
- return ((int)lp->d_partitions[part].p_size);
-}
-
-static void
-free_ds_label(ssp, slice)
- struct diskslices *ssp;
- int slice;
-{
- struct disklabel *lp;
- struct diskslice *sp;
-
- sp = &ssp->dss_slices[slice];
- lp = sp->ds_label;
- if (lp == NULL)
- return;
- free(lp, M_DEVBUF);
- set_ds_label(ssp, slice, (struct disklabel *)NULL);
-}
-
-
-static char *
-fixlabel(sname, sp, lp, writeflag)
- char *sname;
- struct diskslice *sp;
- struct disklabel *lp;
- int writeflag;
-{
- u_long end;
- u_long offset;
- int part;
- struct partition *pp;
- u_long start;
- bool_t warned;
-
- /* These errors "can't happen" so don't bother reporting details. */
- if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC)
- return ("fixlabel: invalid magic");
- if (dkcksum(lp) != 0)
- return ("fixlabel: invalid checksum");
-
- pp = &lp->d_partitions[RAW_PART];
- if (writeflag) {
- start = 0;
- offset = sp->ds_offset;
- } else {
- start = sp->ds_offset;
- offset = -sp->ds_offset;
- }
- if (pp->p_offset != start) {
- if (sname != NULL) {
- printf(
-"%s: rejecting BSD label: raw partition offset != slice offset\n",
- sname);
- slice_info(sname, sp);
- partition_info(sname, RAW_PART, pp);
- }
- return ("fixlabel: raw partition offset != slice offset");
- }
- if (pp->p_size != sp->ds_size) {
- if (sname != NULL) {
- printf("%s: raw partition size != slice size\n", sname);
- slice_info(sname, sp);
- partition_info(sname, RAW_PART, pp);
- }
- if (pp->p_size > sp->ds_size) {
- if (sname == NULL)
- return ("fixlabel: raw partition size > slice size");
- printf("%s: truncating raw partition\n", sname);
- pp->p_size = sp->ds_size;
- }
- }
- end = start + sp->ds_size;
- if (start > end)
- return ("fixlabel: slice wraps");
- if (lp->d_secpercyl <= 0)
- return ("fixlabel: d_secpercyl <= 0");
- pp -= RAW_PART;
- warned = FALSE;
- for (part = 0; part < lp->d_npartitions; part++, pp++) {
- if (pp->p_offset != 0 || pp->p_size != 0) {
- if (pp->p_offset < start
- || pp->p_offset + pp->p_size > end
- || pp->p_offset + pp->p_size < pp->p_offset) {
- if (sname != NULL) {
- printf(
-"%s: rejecting partition in BSD label: it isn't entirely within the slice\n",
- sname);
- if (!warned) {
- slice_info(sname, sp);
- warned = TRUE;
- }
- partition_info(sname, part, pp);
- }
- /* XXX else silently discard junk. */
- bzero(pp, sizeof *pp);
- } else
- pp->p_offset += offset;
- }
- }
- lp->d_ncylinders = sp->ds_size / lp->d_secpercyl;
- lp->d_secperunit = sp->ds_size;
- lp->d_checksum = 0;
- lp->d_checksum = dkcksum(lp);
- return (NULL);
-}
-
-static void
-partition_info(sname, part, pp)
- char *sname;
- int part;
- struct partition *pp;
-{
- printf("%s%c: start %lu, end %lu, size %lu\n", sname, 'a' + part,
- (u_long)pp->p_offset, (u_long)(pp->p_offset + pp->p_size - 1),
- (u_long)pp->p_size);
-}
-
-static void
-slice_info(sname, sp)
- char *sname;
- struct diskslice *sp;
-{
- printf("%s: start %lu, end %lu, size %lu\n", sname,
- sp->ds_offset, sp->ds_offset + sp->ds_size - 1, sp->ds_size);
-}
-
-static void
-set_ds_label(ssp, slice, lp)
- struct diskslices *ssp;
- int slice;
- struct disklabel *lp;
-{
- ssp->dss_slices[slice].ds_label = lp;
- if (slice == COMPATIBILITY_SLICE)
- ssp->dss_slices[ssp->dss_first_bsd_slice].ds_label = lp;
- else if (slice == ssp->dss_first_bsd_slice)
- ssp->dss_slices[COMPATIBILITY_SLICE].ds_label = lp;
-}
-
-static void
-set_ds_labeldevs(dev, ssp)
- dev_t dev;
- struct diskslices *ssp;
-{
-}
-
-
-static void
-set_ds_wlabel(ssp, slice, wlabel)
- struct diskslices *ssp;
- int slice;
- int wlabel;
-{
- ssp->dss_slices[slice].ds_wlabel = wlabel;
- if (slice == COMPATIBILITY_SLICE)
- ssp->dss_slices[ssp->dss_first_bsd_slice].ds_wlabel = wlabel;
- else if (slice == ssp->dss_first_bsd_slice)
- ssp->dss_slices[COMPATIBILITY_SLICE].ds_wlabel = wlabel;
-}
-#endif
diff --git a/sys/pc98/pc98/diskslice_machdep.c b/sys/pc98/pc98/diskslice_machdep.c
deleted file mode 100644
index af8f206..0000000
--- a/sys/pc98/pc98/diskslice_machdep.c
+++ /dev/null
@@ -1,404 +0,0 @@
-#ifdef NO_GEOM
-/*-
- * Copyright (c) 1994 Bruce D. Evans.
- * All rights reserved.
- *
- * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * 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.
- *
- * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
- * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
- * $FreeBSD$
- */
-
-/*
- * PC9801 port by KATO Takenor <kato@eclogite.eps.nagoya-u.ac.jp>
- */
-
-#include "compat_atdisk.h"
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/conf.h>
-#include <sys/disk.h>
-#include <sys/disklabel.h>
-#if defined(PC98) && !defined(PC98_ATCOMPAT)
-#include <sys/diskpc98.h>
-#else
-#include <sys/diskmbr.h>
-#endif
-#include <sys/diskslice.h>
-#include <sys/malloc.h>
-#include <sys/syslog.h>
-
-#define TRACE(str) do { if (dsi_debug) printf str; } while (0)
-
-static volatile u_char dsi_debug;
-
-
-static int check_part(char *sname, struct pc98_partition *dp,
- u_long offset, int nsectors, int ntracks,
- u_long mbr_offset);
-static int mbr_setslice(char *sname, struct disklabel *lp,
- struct diskslice *sp, struct pc98_partition *dp,
- u_long br_offset);
-
-#define DPBLKNO(cyl,hd,sect) ((cyl)*(lp->d_secpercyl))
-#if NCOMPAT_ATDISK > 0
-int atcompat_dsinit(dev_t dev,
- struct disklabel *lp, struct diskslices **sspp);
-#endif
-
-static int
-check_part(sname, dp, offset, nsectors, ntracks, mbr_offset )
- char *sname;
- struct pc98_partition *dp;
- u_long offset;
- int nsectors;
- int ntracks;
- u_long mbr_offset;
-{
- int chs_ecyl;
- int chs_esect;
- int chs_scyl;
- int chs_ssect;
- int error;
- u_long esector;
- u_long esector1;
- u_long secpercyl;
- u_long ssector;
- u_long ssector1;
- u_long pc98_start;
- u_long pc98_size;
-
- secpercyl = (u_long)nsectors * ntracks;
- chs_scyl = dp->dp_scyl;
- chs_ssect = dp->dp_ssect;
- ssector = chs_ssect + dp->dp_shd * nsectors +
- chs_scyl * secpercyl + mbr_offset;
- pc98_start = dp->dp_scyl * secpercyl;
- pc98_size = dp->dp_ecyl ?
- (dp->dp_ecyl + 1) * secpercyl - pc98_start : 0;
- ssector1 = offset + pc98_start;
-
- /*
- * If ssector1 is on a cylinder >= 1024, then ssector can't be right.
- * Allow the C/H/S for it to be 1023/ntracks-1/nsectors, or correct
- * apart from the cylinder being reduced modulo 1024. Always allow
- * 1023/255/63.
- */
- if ((ssector < ssector1
- && ((chs_ssect == nsectors && dp->dp_shd == ntracks - 1
- && chs_scyl == 1023)
- || (secpercyl != 0
- && (ssector1 - ssector) % (1024 * secpercyl) == 0)))
- || (dp->dp_scyl == 255 && dp->dp_shd == 255
- && dp->dp_ssect == 255)) {
- TRACE(("%s: C/H/S start %d/%d/%d, start %lu: allow\n",
- sname, chs_scyl, dp->dp_shd, chs_ssect, ssector1));
- ssector = ssector1;
- }
-
- chs_ecyl = dp->dp_ecyl;
- chs_esect = nsectors - 1;
- esector = chs_esect + (ntracks - 1) * nsectors +
- chs_ecyl * secpercyl + mbr_offset;
- esector1 = ssector1 + pc98_size - 1;
-
- /* Allow certain bogus C/H/S values for esector, as above. */
- if ((esector < esector1
- && ((chs_esect == nsectors && dp->dp_ehd == ntracks - 1
- && chs_ecyl == 1023)
- || (secpercyl != 0
- && (esector1 - esector) % (1024 * secpercyl) == 0)))
- || (dp->dp_ecyl == 255 && dp->dp_ehd == 255
- && dp->dp_esect == 255)) {
- TRACE(("%s: C/H/S end %d/%d/%d, end %lu: allow\n",
- sname, chs_ecyl, dp->dp_ehd, chs_esect, esector1));
- esector = esector1;
- }
-
- error = (ssector == ssector1 && esector == esector1) ? 0 : EINVAL;
- if (bootverbose)
- printf("%s: mid 0x%x, start %lu, end = %lu, size %lu%s\n",
- sname, dp->dp_mid, ssector1, esector1, pc98_size,
- error ? "" : ": OK");
- if (ssector != ssector1 && bootverbose)
- printf("%s: C/H/S start %d/%d/%d (%lu) != start %lu: invalid\n",
- sname, chs_scyl, dp->dp_shd, chs_ssect,
- ssector, ssector1);
- if (esector != esector1 && bootverbose)
- printf("%s: C/H/S end %d/%d/%d (%lu) != end %lu: invalid\n",
- sname, chs_ecyl, dp->dp_ehd, chs_esect,
- esector, esector1);
- return (error);
-}
-
-int
-dsinit(dev, lp, sspp)
- dev_t dev;
- struct disklabel *lp;
- struct diskslices **sspp;
-{
- struct buf *bp;
- u_char *cp;
- int dospart;
- struct pc98_partition *dp;
- struct pc98_partition *dp0;
- int error;
- int max_ncyls;
- int max_nsectors;
- int max_ntracks;
- u_long mbr_offset;
- char partname[2];
- u_long secpercyl;
- char *sname;
- struct diskslice *sp;
- struct diskslices *ssp;
-
- mbr_offset = DOSBBSECTOR;
- /* Read master boot record. */
- if ((int)lp->d_secsize < 1024)
- bp = geteblk((int)1024);
- else
- bp = geteblk((int)lp->d_secsize);
- bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART);
- bp->b_blkno = mbr_offset;
- bp->b_bcount = lp->d_secsize;
- bp->b_iocmd = BIO_READ;
- if (bp->b_bcount < 1024)
- bp->b_bcount = 1024;
- DEV_STRATEGY(bp);
- if (bufwait(bp) != 0) {
- disk_err(&bp->b_io, "reading primary partition table: error",
- 0, 1);
- error = EIO;
- goto done;
- }
-
- /* Weakly verify it. */
- cp = bp->b_data;
- sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART, partname);
- if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) {
- if (bootverbose)
- printf("%s: invalid primary partition table: no magic\n",
- sname);
- error = EINVAL;
- goto done;
- }
- /*
- * entire disk for FreeBSD
- */
- if ((*(cp + 512) == 0x57) && (*(cp + 513) == 0x45) &&
- (*(cp + 514) == 0x56) && (*(cp + 515) == 0x82)) {
- sname = dsname(dev, dkunit(dev), BASE_SLICE,
- RAW_PART, partname);
- free(*sspp, M_DEVBUF);
- ssp = dsmakeslicestruct(MAX_SLICES, lp);
- *sspp = ssp;
-
- /* Initialize normal slices. */
- sp = &ssp->dss_slices[BASE_SLICE];
- sp->ds_offset = 0;
- sp->ds_size = lp->d_secperunit;
- sp->ds_type = DOSPTYP_386BSD;
- sp->ds_subtype = 0xc4;
- error = 0;
- ssp->dss_nslices = BASE_SLICE + 1;
- goto done;
- }
-
- /*
- * XXX --- MS-DOG MO
- */
- if ((*(cp + 0x0e) == 1) && (*(cp + 0x15) == 0xf0) &&
- (*(cp + 0x1c) == 0x0) &&
- ((*(cp + 512) == 0xf0) || (*(cp + 512) == 0xf8)) &&
- (*(cp + 513) == 0xff) && (*(cp + 514) == 0xff)) {
- sname = dsname(dev, dkunit(dev), BASE_SLICE,
- RAW_PART, partname);
- free(*sspp, M_DEVBUF);
- ssp = dsmakeslicestruct(MAX_SLICES, lp);
- *sspp = ssp;
-
- /* Initialize normal slices. */
- sp = &ssp->dss_slices[BASE_SLICE];
- sp->ds_offset = 0;
- sp->ds_size = lp->d_secperunit;
- sp->ds_type = 0xa0; /* XXX */
- sp->ds_subtype = 0x81; /* XXX */
- error = 0;
- ssp->dss_nslices = BASE_SLICE + 1;
- goto done;
- }
-#if NCOMPAT_ATDISK > 0
- /*
- * Check magic number of 'extended format' for PC-9801.
- * If no magic, it may be formatted on IBM-PC.
- */
- if (((cp[4] != 'I') || (cp[5] != 'P') || (cp[6] != 'L') ||
- (cp[7] != '1')) &&
- ((strncmp(devtoname(bp->b_dev), "da", 2) == 0) ||
- (strncmp(devtoname(bp->b_dev), "wd", 2) == 0) ||
- (strncmp(devtoname(bp->b_dev), "ad", 2) == 0))) {
- /* IBM-PC HDD */
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
- return atcompat_dsinit(dev, lp, sspp);
- }
-#endif
- dp0 = (struct pc98_partition *)(cp + 512);
-
- /* Guess the geometry. */
- /*
- * TODO:
- * Perhaps skip entries with 0 size.
- * Perhaps only look at entries of type DOSPTYP_386BSD.
- */
- max_ncyls = 0;
- max_nsectors = 0;
- max_ntracks = 0;
- for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
- int ncyls;
- int nsectors;
- int ntracks;
-
-
- ncyls = lp->d_ncylinders;
- if (max_ncyls < ncyls)
- max_ncyls = ncyls;
- nsectors = lp->d_nsectors;
- if (max_nsectors < nsectors)
- max_nsectors = nsectors;
- ntracks = lp->d_ntracks;
- if (max_ntracks < ntracks)
- max_ntracks = ntracks;
- }
-
- /*
- * Check that we have guessed the geometry right by checking the
- * partition entries.
- */
- /*
- * TODO:
- * As above.
- * Check for overlaps.
- * Check against d_secperunit if the latter is reliable.
- */
- error = 0;
- for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) {
- if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0)
- continue;
- sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
- RAW_PART, partname);
- /*
- * Temporarily ignore errors from this check. We could
- * simplify things by accepting the table eariler if we
- * always ignore errors here. Perhaps we should always
- * accept the table if the magic is right but not let
- * bad entries affect the geometry.
- */
- check_part(sname, dp, mbr_offset, max_nsectors, max_ntracks,
- mbr_offset);
- }
- if (error != 0)
- goto done;
-
- /*
- * Accept the DOS partition table.
- * First adjust the label (we have been careful not to change it
- * before we can guarantee success).
- */
- secpercyl = (u_long)max_nsectors * max_ntracks;
- if (secpercyl != 0) {
- lp->d_nsectors = max_nsectors;
- lp->d_ntracks = max_ntracks;
- lp->d_secpercyl = secpercyl;
- lp->d_ncylinders = lp->d_secperunit / secpercyl;
- }
-
- /*
- * We are passed a pointer to a suitably initialized minimal
- * slices "struct" with no dangling pointers in it. Replace it
- * by a maximal one. This usually oversizes the "struct", but
- * enlarging it while searching for logical drives would be
- * inconvenient.
- */
- free(*sspp, M_DEVBUF);
- ssp = dsmakeslicestruct(MAX_SLICES, lp);
- *sspp = ssp;
-
- /* Initialize normal slices. */
- sp = &ssp->dss_slices[BASE_SLICE];
- for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++, sp++) {
- sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart,
- RAW_PART, partname);
- (void)mbr_setslice(sname, lp, sp, dp, mbr_offset);
- }
- ssp->dss_nslices = BASE_SLICE + NDOSPART;
-
-
-done:
- bp->b_flags |= B_INVAL | B_AGE;
- brelse(bp);
- if (error == EINVAL)
- error = 0;
- return (error);
-}
-
-
-static int
-mbr_setslice(sname, lp, sp, dp, br_offset)
- char *sname;
- struct disklabel *lp;
- struct diskslice *sp;
- struct pc98_partition *dp;
- u_long br_offset;
-{
- u_long offset;
- u_long size;
-
- offset = DPBLKNO(dp->dp_scyl, dp->dp_shd, dp->dp_ssect);
- size = dp->dp_ecyl ?
- DPBLKNO(dp->dp_ecyl + 1, dp->dp_ehd, dp->dp_esect) - offset : 0;
- sp->ds_offset = offset;
- sp->ds_size = size;
- sp->ds_type = dp->dp_mid;
- sp->ds_subtype = dp->dp_sid;
- strncpy(sp->ds_name, dp->dp_name, sizeof(sp->ds_name));
-#if 0
- lp->d_subtype |= (lp->d_subtype & 3) | dospart | DSTYPE_INDOSPART;
-#endif
- return (0);
-}
-#endif
OpenPOWER on IntegriCloud