summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2003-11-13 23:00:56 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2003-11-13 23:00:56 +0000
commit6d8deb389f7695a1c95535fabce300526917a09e (patch)
tree7ef53570331d9ef75dbcc79a2c073664bf393968 /sys/arch
parentcce13257a58fd519aea05b988b4b650299939ae1 (diff)
Add support for RDB partitioned disks. Not bootable yet.
This also reorganizes the code into <fs>disksubr.c done to prevent copyright pollution and possibly allow for additional reuseable code.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/pegasos/include/disklabel.h8
-rw-r--r--sys/arch/pegasos/include/rdb.h229
-rw-r--r--sys/arch/pegasos/pegasos/disksubr.c299
-rw-r--r--sys/arch/pegasos/pegasos/hfsdisksubr.c121
-rw-r--r--sys/arch/pegasos/pegasos/mbrdisksubr.c209
-rw-r--r--sys/arch/pegasos/pegasos/rdbdisksubr.c361
6 files changed, 979 insertions, 248 deletions
diff --git a/sys/arch/pegasos/include/disklabel.h b/sys/arch/pegasos/include/disklabel.h
index 098812c3aa4..6357be2124a 100644
--- a/sys/arch/pegasos/include/disklabel.h
+++ b/sys/arch/pegasos/include/disklabel.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: disklabel.h,v 1.1 2003/10/31 03:54:33 drahn Exp $ */
+/* $OpenBSD: disklabel.h,v 1.2 2003/11/13 23:00:54 drahn Exp $ */
/*
* Copyright (c) 1994 Christopher G. Demetriou
@@ -33,6 +33,8 @@
#ifndef _MACHINE_DISKLABEL_H_
#define _MACHINE_DISKLABEL_H_
+#include <machine/rdb.h>
+
#define LABELSECTOR 1 /* sector containing label */
#define LABELOFFSET 0 /* offset of label in sector */
#define MAXPARTITIONS 16 /* number of partitions */
@@ -159,6 +161,10 @@ struct cpu_disklabel {
/* only store first entry and openbsd partition */
struct part_map_entry macparts[2];
struct dkbad bad;
+ int rdblock;
+ int rd_bsdlbl;
+ int pbindex[MAXPARTITIONS];
+ int pblist[MAXPARTITIONS];
};
#define DKBAD(x) ((x)->bad)
diff --git a/sys/arch/pegasos/include/rdb.h b/sys/arch/pegasos/include/rdb.h
new file mode 100644
index 00000000000..214387f7825
--- /dev/null
+++ b/sys/arch/pegasos/include/rdb.h
@@ -0,0 +1,229 @@
+/* $OpenBSD: rdb.h,v 1.1 2003/11/13 23:00:54 drahn Exp $ */
+/* $NetBSD: disklabel.h,v 1.6 1996/04/21 21:13:19 veego Exp $ */
+
+/*
+ * Copyright (c) 1994 Christian E. Hopps
+ * 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 Christian E. Hopps.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * 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.
+ */
+#ifndef _ADOS_RDB_H
+#define _ADOS_RDB_H
+
+/*
+ * describes ados Rigid Disk Blocks
+ * which are used to partition a drive
+ */
+#define RDBNULL ((u_long)0xffffffff)
+#define RDB_MAXBLOCKS 16
+
+/*
+ * Dos types for identifying file systems
+ * bsd file systems will be 'N','B',x,y where y is the fstype found in
+ * disklabel.h (for DOST_DOS it will be the version number)
+ */
+#define DOST_XXXBSD 0x42534400 /* Old type back compat*/
+#define DOST_NBR 0x4e425200 /* 'NBRx' Netbsd root partition */
+#define DOST_NBS 0x4e425300 /* 'NBS0' Netbsd swap partition */
+#define DOST_NBU 0x4e425500 /* 'NBUx' Netbsd user partition */
+#define DOST_DOS 0x444f5300 /* 'DOSx' AmigaDos partition */
+#define DOST_AMIX 0x554e4900 /* 'UNIx' AmigaDos partition */
+#define DOST_MUFS 0x6d754600 /* 'muFx' AmigaDos partition (muFS) */
+#define DOST_EXT2 0x4c4e5800 /* 'LNX0' Linux fs partition (ext2fs) */
+#define DOST_LNXSWP 0x53575000 /* 'LNX0' Linux swap partition */
+#define DOST_OBSD 0x4f425344 /* 'OBSD' OpenBSD partition table */
+
+struct adostype {
+ u_char archtype; /* see ADT_xxx below */
+ u_char fstype; /* byte 3 from amiga dostype */
+};
+
+/* archtypes */
+#define ADT_UNKNOWN 0
+#define ADT_AMIGADOS 1
+#define ADT_NETBSDROOT 2
+#define ADT_NETBSDSWAP 3
+#define ADT_NETBSDUSER 4
+#define ADT_AMIX 5
+#define ADT_EXT2 6
+
+#define ISFSARCH_NETBSD(adt) \
+ ((adt).archtype >= ADT_NETBSDROOT && (adt).archtype <= ADT_NETBSDUSER)
+
+
+/*
+ * you will find rdblock somewhere in [0, RDBMAXBLOCKS)
+ */
+#define RDB_MAXBLOCKS 16
+
+struct rdblock {
+ u_long id; /* 'RDSK' */
+ u_long nsumlong; /* number of longs in check sum */
+ u_long chksum; /* simple additive with wrap checksum */
+ u_long hostid; /* scsi target of host */
+ u_long nbytes; /* size of disk blocks */
+ u_long flags;
+ u_long badbhead; /* linked list of badblocks */
+ u_long partbhead; /* linked list of partblocks */
+ u_long fsbhead; /* " " of fsblocks */
+ u_long driveinit;
+ u_long resv1[6]; /* RDBNULL */
+ u_long ncylinders; /* number of cylinders on drive */
+ u_long nsectors; /* number of sectors per track */
+ u_long nheads; /* number of tracks per cylinder */
+ u_long interleave;
+ u_long park; /* only used with st506 i.e. not */
+ u_long resv2[3];
+ u_long wprecomp; /* start cyl for write precomp */
+ u_long reducedwrite; /* start cyl for reduced write current */
+ u_long steprate; /* driver step rate in ?s */
+ u_long resv3[5];
+ u_long rdblowb; /* lowblock of range for rdb's */
+ u_long rdbhighb; /* high block of range for rdb's */
+ u_long lowcyl; /* low cylinder of partition area */
+ u_long highcyl; /* upper cylinder of partition area */
+ u_long secpercyl; /* number of sectors per cylinder */
+ u_long parkseconds; /* zero if no park needed */
+ u_long resv4[2];
+ char diskvendor[8]; /* inquiry stuff */
+ char diskproduct[16]; /* inquiry stuff */
+ char diskrevision[4]; /* inquiry stuff */
+ char contvendor[8]; /* inquiry stuff */
+ char contproduct[16]; /* inquiry stuff */
+ char contrevision[4]; /* inquiry stuff */
+#if never_use_secsize
+ u_long resv5[0];
+#endif
+};
+
+
+#define RDBF_LAST 0x1 /* last drive available */
+#define RDBF_LASTLUN 0x2 /* last LUN available */
+#define RDBF_LASTUNIT 0x4 /* last target available */
+#define RDBF_NORESELECT 0x8 /* do not use reselect */
+#define RDBF_DISKID 0x10 /* disk id is valid ?? */
+#define RDBF_CTRLID 0x20 /* ctrl id is valid ?? */
+#define RDBF_SYNC 0x40 /* drive supports SCSI synchronous mode */
+
+struct ados_environ {
+ u_long tabsize; /* 0: environ table size */
+ u_long sizeblock; /* 1: n long words in a block */
+ u_long secorg; /* 2: not used must be zero */
+ u_long numheads; /* 3: number of surfaces */
+ u_long secperblk; /* 4: must be 1 */
+ u_long secpertrk; /* 5: blocks per track */
+ u_long resvblocks; /* 6: reserved blocks at start */
+ u_long prefac; /* 7: must be 0 */
+ u_long interleave; /* 8: normally 1 */
+ u_long lowcyl; /* 9: low cylinder of partition */
+ u_long highcyl; /* 10: upper cylinder of partition */
+ u_long numbufs; /* 11: ados: number of buffers */
+ u_long membuftype; /* 12: ados: type of bufmem */
+ u_long maxtrans; /* 13: maxtrans the ctrlr supports */
+ u_long mask; /* 14: mask for valid address */
+ u_long bootpri; /* 15: boot priority for autoboot */
+ u_long dostype; /* 16: filesystem type */
+ u_long baud; /* 17: serial handler baud rate */
+ u_long control; /* 18: control word for fs */
+ u_long bootblocks; /* 19: blocks containing boot code */
+ u_long fsize; /* 20: file system block size */
+ u_long frag; /* 21: allowable frags per block */
+ u_long cpg; /* 22: cylinders per group */
+};
+
+struct partblock {
+ u_long id; /* 'PART' */
+ u_long nsumlong; /* number of longs in check sum */
+ u_long chksum; /* simple additive with wrap checksum */
+ u_long hostid; /* scsi target of host */
+ u_long next; /* next in chain */
+ u_long flags; /* see below */
+ u_long resv1[3];
+ u_char partname[32]; /* (BCPL) part name (may not be unique) */
+ u_long resv2[15];
+ struct ados_environ e;
+#if never_use_secsize
+ u_long extra[9]; /* 8 for extra added to environ */
+#endif
+};
+
+#define PBF_BOOTABLE 0x1 /* partition is bootable */
+#define PBF_NOMOUNT 0x2 /* partition should be mounted */
+
+struct badblock {
+ u_long id; /* 'BADB' */
+ u_long nsumlong; /* number of longs in check sum */
+ u_long chksum; /* simple additive with wrap checksum */
+ u_long hostid; /* scsi target of host */
+ u_long next; /* next in chain */
+ u_long resv;
+ struct badblockent {
+ u_long badblock;
+ u_long goodblock;
+ } badtab[0]; /* 61 for secsize == 512 */
+};
+
+struct fsblock {
+ u_long id; /* 'FSHD' */
+ u_long nsumlong; /* number of longs in check sum */
+ u_long chksum; /* simple additive with wrap checksum */
+ u_long hostid; /* scsi target of host */
+ u_long next; /* next in chain */
+ u_long flags;
+ u_long resv1[2];
+ u_long dostype; /* this is a file system for this type */
+ u_long version; /* version of this fs */
+ u_long patchflags; /* describes which functions to replace */
+ u_long type; /* zero */
+ u_long task; /* zero */
+ u_long lock; /* zero */
+ u_long handler; /* zero */
+ u_long stacksize; /* to use when loading handler */
+ u_long priority; /* to run the fs at. */
+ u_long startup; /* zero */
+ u_long lsegblocks; /* linked list of lsegblocks of fs code */
+ u_long globalvec; /* bcpl vector not used mostly */
+#if never_use_secsize
+ u_long resv2[44];
+#endif
+};
+
+struct lsegblock {
+ u_long id; /* 'LSEG' */
+ u_long nsumlong; /* number of longs in check sum */
+ u_long chksum; /* simple additive with wrap checksum */
+ u_long hostid; /* scsi target of host */
+ u_long next; /* next in chain */
+ u_long loaddata[0]; /* load segment data, 123 for secsize == 512 */
+};
+
+#define RDBLOCK_ID 0x5244534b /* 'RDSK' */
+#define PARTBLOCK_ID 0x50415254 /* 'PART' */
+#define BADBLOCK_ID 0x42414442 /* 'BADB' */
+#define FSBLOCK_ID 0x46534844 /* 'FSHD' */
+#define LSEGBLOCK_ID 0x4c534547 /* 'LSEG' */
+
+#endif /* _ADOS_RDB_H */
diff --git a/sys/arch/pegasos/pegasos/disksubr.c b/sys/arch/pegasos/pegasos/disksubr.c
index 5754dad6e1c..27b4e1484c7 100644
--- a/sys/arch/pegasos/pegasos/disksubr.c
+++ b/sys/arch/pegasos/pegasos/disksubr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: disksubr.c,v 1.1 2003/10/31 03:54:33 drahn Exp $ */
+/* $OpenBSD: disksubr.c,v 1.2 2003/11/13 23:00:55 drahn Exp $ */
/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
/*
@@ -43,14 +43,25 @@
#define b_cylin b_resid
-#define BOOT_MAGIC 0xAA55
-#define BOOT_MAGIC_OFF (DOSPARTOFF+NDOSPART*sizeof(struct dos_partition))
-
void
dk_establish(struct disk *dk, struct device *dev)
{
}
+int
+try_rdb_label(dev_t dev, void (*strat)(struct buf *), struct buf *bp,
+ struct disklabel *lp, struct cpu_disklabel *osdep, char **pmsg,
+ int *bsdpartoff);
+int
+try_hfs_label(dev_t dev, void (*strat)(struct buf *), struct buf *bp,
+ struct disklabel *lp, struct cpu_disklabel *osdep, char **pmsg,
+ int *bsdpartoff);
+int
+try_mbr_label(dev_t dev, void (*strat)(struct buf *), struct buf *bp,
+ struct disklabel *lp, struct cpu_disklabel *osdep, char **pmsg,
+ int *bsdpartoff);
+
+
/*
* Attempt to read a disk label from a device
* using the indicated strategy routine.
@@ -59,32 +70,17 @@ dk_establish(struct disk *dk, struct device *dev)
* operation in the driver's strategy/start routines
* must be filled in before calling us.
*
- * If dos partition table requested, attempt to load it and
- * find disklabel inside a DOS partition. Also, if bad block
- * table needed, attempt to extract it as well. Return buffer
- * for use in signalling errors if requested.
- *
- * We would like to check if each MBR has a valid BOOT_MAGIC, but
- * we cannot because it doesn't always exist. So.. we assume the
- * MBR is valid.
- *
* Returns null on success and an error string on failure.
*/
char *
readdisklabel(dev_t dev, void (*strat)(struct buf *),
struct disklabel *lp, struct cpu_disklabel *osdep, int spoofonly)
{
- struct dos_partition *dp = osdep->dosparts, *dp2;
struct dkbad *bdp = &DKBAD(osdep);
struct buf *bp;
struct disklabel *dlp;
- char *msg = NULL, *cp;
- char *s;
- int dospartoff, cyl, i, ourpart = -1;
- /* HFS variables */
- int part_cnt, n, hfspartoff;
- struct part_map_entry *part;
-
+ char *msg = NULL;
+ int partoff, i, found;
/* minimal requirements for archtypal disk label */
if (lp->d_secsize == 0)
@@ -104,69 +100,31 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
bp = geteblk((int)lp->d_secsize);
bp->b_dev = dev;
- /* DPME (HFS) disklabel */
-
- bp->b_blkno = 1;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylin = 1 / lp->d_secpercyl;
- (*strat)(bp);
-
- /* if successful, wander through DPME partition table */
- if (biowait(bp)) {
- msg = "DPME partition I/O error";
- goto hfs_done;
- }
-
- part = (struct part_map_entry *)bp->b_data;
- /* if first partition is not valid, assume not HFS/DPME partitioned */
- if (part->pmSig != PART_ENTRY_MAGIC) {
- osdep->macparts[0].pmSig = 0; /* make invalid */
- goto hfs_done;
- }
- osdep->macparts[0] = *part;
- part_cnt = part->pmMapBlkCnt;
- n = 0;
- for (i = 0; i < part_cnt; i++) {
- struct partition *pp = &lp->d_partitions[8+n];
-
- bp->b_blkno = 1+i;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylin = 1+i / lp->d_secpercyl;
- (*strat)(bp);
-
- if (biowait(bp)) {
- msg = "DPME partition I/O error";
- goto hfs_done;
- }
- part = (struct part_map_entry *)bp->b_data;
- /* toupper the string, in case caps are different... */
- for (s = part->pmPartType; *s; s++)
- if ((*s >= 'a') && (*s <= 'z'))
- *s = (*s - 'a' + 'A');
-
- if (strcmp(part->pmPartType, PART_TYPE_OPENBSD) == 0) {
- hfspartoff = part->pmPyPartStart;
- osdep->macparts[1] = *part;
- }
- /* currently we ignore all but HFS partitions */
- if (strcmp(part->pmPartType, PART_TYPE_MAC) == 0) {
- pp->p_offset = part->pmPyPartStart;
- pp->p_size = part->pmPartBlkCnt;
- pp->p_fstype = FS_HFS;
- n++;
- }
+ partoff = -1;
+
+ /* try hfs */
+ found = try_hfs_label(dev, strat, bp, lp, osdep, &msg, &partoff);
+ /* if no hfs or mbr, try rdb */
+ if (found == 0)
+ found = try_rdb_label(dev, strat, bp, lp, osdep, &msg,
+ &partoff);
+ /* if no hfs, try mbr */
+ if (found == 0)
+ found = try_mbr_label(dev, strat, bp, lp, osdep, &msg,
+ &partoff);
+ /* if no partition found, return */
+ if (found == 0 || partoff == -1) {
+ /* no special partition table found try raw labeled disk. */
+ partoff = LABELSECTOR;
}
- lp->d_npartitions = MAXPARTITIONS;
/* don't read the on-disk label if we are in spoofed-only mode */
if (spoofonly)
goto done;
/* next, dig out disk label */
- bp->b_blkno = hfspartoff;
- bp->b_cylin = hfspartoff/lp->d_secpercyl; /* XXX */
+ bp->b_blkno = partoff;
+ bp->b_cylin = partoff/lp->d_secpercyl; /* XXX */
bp->b_bcount = lp->d_secsize;
bp->b_flags = B_BUSY | B_READ;
(*strat)(bp);
@@ -177,178 +135,10 @@ readdisklabel(dev_t dev, void (*strat)(struct buf *),
msg = "disk label I/O error";
goto done;
}
- goto found_disklabel;
-
-
-hfs_done:
- /* MBR type disklabel */
- /* do dos partitions in the process of getting disklabel? */
- dospartoff = 0;
- cyl = LABELSECTOR / lp->d_secpercyl;
- if (dp) {
- daddr_t part_blkno = DOSBBSECTOR;
- unsigned long extoff = 0;
- int wander = 1, loop = 0;
- n = 0;
-
- /*
- * Read dos partition table, follow extended partitions.
- * Map the partitions to disklabel entries i-p
- */
- while (wander && n < 8 && loop < 8) {
- loop++;
- wander = 0;
- if (part_blkno < extoff)
- part_blkno = extoff;
-
- /* read boot record */
- bp->b_blkno = part_blkno;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- bp->b_cylin = part_blkno / lp->d_secpercyl;
- (*strat)(bp);
- /* if successful, wander through dos partition table */
- if (biowait(bp)) {
- msg = "dos partition I/O error";
- goto done;
- }
- bcopy(bp->b_data + DOSPARTOFF, dp,
- NDOSPART * sizeof(*dp));
-
- if (ourpart == -1) {
- /* Search for our MBR partition */
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (get_le(&dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_OPENBSD)
- ourpart = i;
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (get_le(&dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_FREEBSD)
- ourpart = i;
- for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
- i++, dp2++)
- if (get_le(&dp2->dp_size) &&
- dp2->dp_typ == DOSPTYP_NETBSD)
- ourpart = i;
- if (ourpart == -1)
- goto donot;
- /*
- * This is our MBR partition.
- * need sector address * for SCSI/IDE,
- * cylinder for ESDI/ST506/RLL
- */
- dp2 = &dp[ourpart];
- dospartoff = get_le(&dp2->dp_start) +
- part_blkno;
- cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
-
- /* XXX build a temporary disklabel */
- lp->d_partitions[0].p_size =
- get_le(&dp2->dp_size);
- lp->d_partitions[0].p_offset =
- get_le(&dp2->dp_start) + part_blkno;
- if (lp->d_ntracks == 0)
- lp->d_ntracks = dp2->dp_ehd + 1;
- if (lp->d_nsectors == 0)
- lp->d_nsectors = DPSECT(dp2->dp_esect);
- if (lp->d_secpercyl == 0)
- lp->d_secpercyl = lp->d_ntracks *
- lp->d_nsectors;
- }
-donot:
- /*
- * In case the disklabel read below fails, we want to
- * provide a fake label in i-p.
- */
- for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
- struct partition *pp = &lp->d_partitions[8+n];
-
- if (dp2->dp_typ == DOSPTYP_OPENBSD)
- continue;
- if (get_le(&dp2->dp_size) > lp->d_secperunit)
- continue;
- if (get_le(&dp2->dp_size))
- pp->p_size = get_le(&dp2->dp_size);
- if (get_le(&dp2->dp_start))
- pp->p_offset =
- get_le(&dp2->dp_start) + part_blkno;
-
- switch (dp2->dp_typ) {
- case DOSPTYP_UNUSED:
- for (cp = (char *)dp2;
- cp < (char *)(dp2 + 1); cp++)
- if (*cp)
- break;
- /*
- * Was it all zeroes? If so, it is
- * an unused entry that we don't
- * want to show.
- */
- if (cp == (char *)(dp2 + 1))
- continue;
- lp->d_partitions[8 + n++].p_fstype =
- FS_UNUSED;
- break;
-
- case DOSPTYP_LINUX:
- pp->p_fstype = FS_EXT2FS;
- n++;
- break;
-
- case DOSPTYP_FAT12:
- case DOSPTYP_FAT16S:
- case DOSPTYP_FAT16B:
- case DOSPTYP_FAT16C:
- case DOSPTYP_FAT32:
- pp->p_fstype = FS_MSDOS;
- n++;
- break;
- case DOSPTYP_EXTEND:
- case DOSPTYP_EXTENDL:
- part_blkno = get_le(&dp2->dp_start) + extoff;
- if (!extoff) {
- extoff = get_le(&dp2->dp_start);
- part_blkno = 0;
- }
- wander = 1;
- break;
- default:
- pp->p_fstype = FS_OTHER;
- n++;
- break;
- }
- }
- }
- lp->d_bbsize = 8192;
- lp->d_sbsize = 64*1024; /* XXX ? */
- lp->d_npartitions = MAXPARTITIONS;
- }
-
- /* don't read the on-disk label if we are in spoofed-only mode */
- if (spoofonly)
- goto done;
-
- /* next, dig out disk label */
- bp->b_blkno = dospartoff + LABELSECTOR;
- bp->b_cylin = cyl;
- bp->b_bcount = lp->d_secsize;
- bp->b_flags = B_BUSY | B_READ;
- (*strat)(bp);
-
- /* if successful, locate disk label within block and validate */
- if (biowait(bp)) {
- /* XXX we return the faked label built so far */
- msg = "disk label I/O error";
- goto done;
- }
-
-found_disklabel:
for (dlp = (struct disklabel *)bp->b_data;
- dlp <= (struct disklabel *)(bp->b_data +
- lp->d_secsize - sizeof(*dlp));
+ dlp <= (struct disklabel *)(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)
@@ -506,6 +296,21 @@ writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp,
goto done;
}
+ /* label RDB disk */
+ if (osdep->rd_bsdlbl != 0) {
+ /* we have a location for the BSD label */
+ /* Really need to add some validation code here */
+ bp->b_blkno = osdep->rd_bsdlbl;
+ bp->b_cylin = bp->b_blkno/lp->d_secpercyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_WRITE;
+ *(struct disklabel *)bp->b_data = *lp;
+ (*strat)(bp);
+ error = biowait(bp);
+ goto done;
+ }
+
+
/* do dos partitions in the process of getting disklabel? */
dospartoff = 0;
cyl = LABELSECTOR / lp->d_secpercyl;
diff --git a/sys/arch/pegasos/pegasos/hfsdisksubr.c b/sys/arch/pegasos/pegasos/hfsdisksubr.c
new file mode 100644
index 00000000000..39e26d85588
--- /dev/null
+++ b/sys/arch/pegasos/pegasos/hfsdisksubr.c
@@ -0,0 +1,121 @@
+/* $OpenBSD: hfsdisksubr.c,v 1.1 2003/11/13 23:00:55 drahn Exp $ */
+/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
+
+/*
+ * Copyright (c) 1996 Theo de Raadt
+ * 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. 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 7.16 (Berkeley) 5/4/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <sys/syslog.h>
+#include <sys/disk.h>
+
+#define b_cylin b_resid
+
+int
+try_hfs_label(dev_t dev, void (*strat)(struct buf *), struct buf *bp,
+ struct disklabel *lp, struct cpu_disklabel *osdep, char **pmsg,
+ int *bsdpartoff);
+
+int
+try_hfs_label(dev_t dev, void (*strat)(struct buf *), struct buf *bp,
+ struct disklabel *lp, struct cpu_disklabel *osdep, char **pmsg,
+ int *bsdpartoff)
+{
+ int part_cnt, n, i;
+ struct part_map_entry *part;
+ int hfspartoff = -1;
+ char *s;
+
+ bp->b_blkno = 1;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = 1 / lp->d_secpercyl;
+ (*strat)(bp);
+
+ /* if successful, wander through DPME partition table */
+ if (biowait(bp)) {
+ *pmsg = "DPME partition I/O error";
+ return 0;
+ }
+
+ part = (struct part_map_entry *)bp->b_data;
+ /* if first partition is not valid, assume not HFS/DPME partitioned */
+ if (part->pmSig != PART_ENTRY_MAGIC) {
+ osdep->macparts[0].pmSig = 0; /* make invalid */
+ return 0;
+ }
+ osdep->macparts[0] = *part;
+ part_cnt = part->pmMapBlkCnt;
+ n = 0;
+ for (i = 0; i < part_cnt; i++) {
+ struct partition *pp = &lp->d_partitions[8+n];
+
+ bp->b_blkno = 1+i;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = 1+i / lp->d_secpercyl;
+ (*strat)(bp);
+
+ if (biowait(bp)) {
+ *pmsg = "DPME partition I/O error";
+ return 0;
+ }
+ part = (struct part_map_entry *)bp->b_data;
+ /* toupper the string, in case caps are different... */
+ for (s = part->pmPartType; *s; s++)
+ if ((*s >= 'a') && (*s <= 'z'))
+ *s = (*s - 'a' + 'A');
+
+ if (0 == strcmp(part->pmPartType, PART_TYPE_OPENBSD)) {
+ hfspartoff = part->pmPyPartStart;
+ osdep->macparts[1] = *part;
+ }
+ /* currently we ignore all but HFS partitions */
+ if (0 == strcmp(part->pmPartType, PART_TYPE_MAC)) {
+ pp->p_offset = part->pmPyPartStart;
+ pp->p_size = part->pmPartBlkCnt;
+ pp->p_fstype = FS_HFS;
+ n++;
+#if 0
+ printf("found DPME HFS partition [%s], adding to fake\n",
+ part->pmPartName);
+#endif
+ }
+ }
+ lp->d_npartitions = MAXPARTITIONS;
+
+ *bsdpartoff = hfspartoff;
+ return 1;
+}
diff --git a/sys/arch/pegasos/pegasos/mbrdisksubr.c b/sys/arch/pegasos/pegasos/mbrdisksubr.c
new file mode 100644
index 00000000000..1c2bd65052f
--- /dev/null
+++ b/sys/arch/pegasos/pegasos/mbrdisksubr.c
@@ -0,0 +1,209 @@
+/* $OpenBSD: mbrdisksubr.c,v 1.1 2003/11/13 23:00:55 drahn Exp $ */
+/* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
+
+/*
+ * Copyright (c) 1996 Theo de Raadt
+ * 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. 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 7.16 (Berkeley) 5/4/91
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <sys/syslog.h>
+#include <sys/disk.h>
+
+#define b_cylin b_resid
+
+#define BOOT_MAGIC 0xAA55
+#define BOOT_MAGIC_OFF (DOSPARTOFF+NDOSPART*sizeof(struct dos_partition))
+
+int
+try_mbr_label(dev_t dev, void (*strat)(struct buf *), struct buf *bp,
+ struct disklabel *lp, struct cpu_disklabel *osdep, char **pmsg,
+ int *bsdpartoff);
+int
+try_mbr_label(dev_t dev, void (*strat)(struct buf *), struct buf *bp,
+ struct disklabel *lp, struct cpu_disklabel *osdep, char **pmsg,
+ int *bsdpartoff)
+{
+ struct dos_partition *dp = osdep->dosparts, *dp2;
+ char *cp;
+ int cyl, n, i, ourpart = -1;
+ int dospartoff = -1;
+
+ /* MBR type disklabel */
+ /* do dos partitions in the process of getting disklabel? */
+ cyl = LABELSECTOR / lp->d_secpercyl;
+ if (dp) {
+ daddr_t part_blkno = DOSBBSECTOR;
+ unsigned long extoff = 0;
+ int wander = 1, loop = 0;
+ n = 0;
+
+ /*
+ * Read dos partition table, follow extended partitions.
+ * Map the partitions to disklabel entries i-p
+ */
+ while (wander && n < 8 && loop < 8) {
+ loop++;
+ wander = 0;
+ if (part_blkno < extoff)
+ part_blkno = extoff;
+
+ /* read boot record */
+ bp->b_blkno = part_blkno;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ bp->b_cylin = part_blkno / lp->d_secpercyl;
+ (*strat)(bp);
+
+ /* if successful, wander through dos partition table */
+ if (biowait(bp)) {
+ *pmsg = "dos partition I/O error";
+ return 0;
+ }
+ bcopy(bp->b_data + DOSPARTOFF, dp, NDOSPART * sizeof(*dp));
+
+ if (ourpart == -1) {
+ /* Search for our MBR partition */
+ for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
+ i++, dp2++)
+ if (get_le(&dp2->dp_size) &&
+ dp2->dp_typ == DOSPTYP_OPENBSD)
+ ourpart = i;
+ for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
+ i++, dp2++)
+ if (get_le(&dp2->dp_size) &&
+ dp2->dp_typ == DOSPTYP_FREEBSD)
+ ourpart = i;
+ for (dp2=dp, i=0; i < NDOSPART && ourpart == -1;
+ i++, dp2++)
+ if (get_le(&dp2->dp_size) &&
+ dp2->dp_typ == DOSPTYP_NETBSD)
+ ourpart = i;
+ if (ourpart == -1)
+ goto donot;
+ /*
+ * This is our MBR partition. need sector address
+ * for SCSI/IDE, cylinder for ESDI/ST506/RLL
+ */
+ dp2 = &dp[ourpart];
+ dospartoff = get_le(&dp2->dp_start) + part_blkno;
+ cyl = DPCYL(dp2->dp_scyl, dp2->dp_ssect);
+
+ /* XXX build a temporary disklabel */
+ lp->d_partitions[0].p_size = get_le(&dp2->dp_size);
+ lp->d_partitions[0].p_offset =
+ get_le(&dp2->dp_start) + part_blkno;
+ if (lp->d_ntracks == 0)
+ lp->d_ntracks = dp2->dp_ehd + 1;
+ if (lp->d_nsectors == 0)
+ lp->d_nsectors = DPSECT(dp2->dp_esect);
+ if (lp->d_secpercyl == 0)
+ lp->d_secpercyl = lp->d_ntracks *
+ lp->d_nsectors;
+ }
+donot:
+ /*
+ * In case the disklabel read below fails, we want to
+ * provide a fake label in i-p.
+ */
+ for (dp2=dp, i=0; i < NDOSPART && n < 8; i++, dp2++) {
+ struct partition *pp = &lp->d_partitions[8+n];
+
+ if (dp2->dp_typ == DOSPTYP_OPENBSD)
+ continue;
+ if (get_le(&dp2->dp_size) > lp->d_secperunit)
+ continue;
+ if (get_le(&dp2->dp_size))
+ pp->p_size = get_le(&dp2->dp_size);
+ if (get_le(&dp2->dp_start))
+ pp->p_offset =
+ get_le(&dp2->dp_start) + part_blkno;
+
+ switch (dp2->dp_typ) {
+ case DOSPTYP_UNUSED:
+ for (cp = (char *)dp2;
+ cp < (char *)(dp2 + 1); cp++)
+ if (*cp)
+ break;
+ /*
+ * Was it all zeroes? If so, it is
+ * an unused entry that we don't
+ * want to show.
+ */
+ if (cp == (char *)(dp2 + 1))
+ continue;
+ lp->d_partitions[8 + n++].p_fstype =
+ FS_UNUSED;
+ break;
+
+ case DOSPTYP_LINUX:
+ pp->p_fstype = FS_EXT2FS;
+ n++;
+ break;
+
+ case DOSPTYP_FAT12:
+ case DOSPTYP_FAT16S:
+ case DOSPTYP_FAT16B:
+ case DOSPTYP_FAT16C:
+ case DOSPTYP_FAT32:
+ pp->p_fstype = FS_MSDOS;
+ n++;
+ break;
+ case DOSPTYP_EXTEND:
+ case DOSPTYP_EXTENDL:
+ part_blkno = get_le(&dp2->dp_start) + extoff;
+ if (!extoff) {
+ extoff = get_le(&dp2->dp_start);
+ part_blkno = 0;
+ }
+ wander = 1;
+ break;
+ default:
+ pp->p_fstype = FS_OTHER;
+ n++;
+ break;
+ }
+ }
+ }
+ lp->d_bbsize = 8192;
+ lp->d_sbsize = 64*1024; /* XXX ? */
+ lp->d_npartitions = MAXPARTITIONS;
+ }
+
+ /* if not partitions found return failure */
+ if (n == 0 && dospartoff == -1)
+ return 0;
+ *bsdpartoff = dospartoff + LABELSECTOR;
+ return 1;
+}
diff --git a/sys/arch/pegasos/pegasos/rdbdisksubr.c b/sys/arch/pegasos/pegasos/rdbdisksubr.c
new file mode 100644
index 00000000000..3a9f4680fba
--- /dev/null
+++ b/sys/arch/pegasos/pegasos/rdbdisksubr.c
@@ -0,0 +1,361 @@
+/* $OpenBSD: rdbdisksubr.c,v 1.1 2003/11/13 23:00:55 drahn Exp $ */
+/* $NetBSD: disksubr.c,v 1.27 1996/10/13 03:06:34 christos Exp $ */
+
+/*
+ * Copyright (c) 1994 Christian E. Hopps
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <sys/disklabel.h>
+#include <sys/syslog.h>
+#include <sys/disk.h>
+
+struct adostype getadostype(u_long dostype);
+
+u_long rdbchksum(void *bdata);
+
+#define b_cylin b_resid
+int
+try_rdb_label(dev_t dev, void (*strat)(struct buf *), struct buf *bp,
+ struct disklabel *lp, struct cpu_disklabel *osdep, char **pmsg,
+ int *bsdpartoff);
+int
+try_rdb_label(dev_t dev, void (*strat)(struct buf *), struct buf *bp,
+ struct disklabel *lp, struct cpu_disklabel *clp, char **pmsg,
+ int *bsdpartoff)
+{
+ int nextb, i;
+ int rdbpartoff = -1;
+ struct rdblock *rbp;
+ struct partblock *pbp;
+ struct partition *pp = NULL;
+ struct adostype adt;
+ int cindex;
+
+ clp->rdblock = RDBNULL;
+
+ /* initialize */
+ for (i = 0; i < MAXPARTITIONS; i++) {
+ clp->pbindex[i] = -1;
+ clp->pblist[i] = RDBNULL;
+ }
+ if (lp->d_partitions[RAW_PART].p_size == 0)
+ lp->d_partitions[RAW_PART].p_size = 0x1fffffff;
+ lp->d_partitions[RAW_PART].p_offset = 0;
+
+ lp->d_npartitions = 'i' - 'a';
+
+ bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), RAW_PART);
+
+ /* Find RDB block */
+
+ for (nextb = 0; nextb < RDB_MAXBLOCKS; nextb++) {
+ bp->b_blkno = nextb;
+ bp->b_cylin = nextb / lp->d_secpercyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ strat(bp);
+
+ if (biowait(bp)) {
+ *pmsg = "RDB search I/O error";
+ goto done;
+ }
+ rbp = (void *)(bp->b_data);
+
+ if (rbp->id == RDBLOCK_ID) {
+ if (rdbchksum(rbp) == 0)
+ break;
+ else
+ *pmsg = "bad rdb checksum";
+ }
+ }
+ if (nextb == RDB_MAXBLOCKS)
+ goto done; /* no RDB found */
+
+ clp->rdblock = nextb;
+
+ lp->d_secsize = rbp->nbytes;
+ lp->d_nsectors = rbp->nsectors;
+ lp->d_ntracks = rbp->nheads;
+ /*
+ * should be rdb->ncylinders however this is a bogus value
+ * sometimes it seems
+ */
+ if (rbp->highcyl == 0)
+ lp->d_ncylinders = rbp->ncylinders;
+ else
+ lp->d_ncylinders = rbp->highcyl + 1;
+ /*
+ * I also don't trust rdb->secpercyl
+ */
+ lp->d_secpercyl = min(rbp->secpercyl, lp->d_nsectors * lp->d_ntracks);
+ if (lp->d_secpercyl == 0)
+ lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
+
+ cindex = 0;
+ for (nextb = rbp->partbhead; nextb != RDBNULL; nextb = pbp->next) {
+ bp->b_blkno = nextb;
+ bp->b_cylin = nextb / lp->d_secpercyl;
+ bp->b_bcount = lp->d_secsize;
+ bp->b_flags = B_BUSY | B_READ;
+ strat(bp);
+
+ if (biowait(bp)) {
+ *pmsg = "RDB partition scan I/O error";
+ goto done;
+ }
+ pbp = (void *)(bp->b_data);
+
+ if (pbp->id != PARTBLOCK_ID) {
+ *pmsg = "RDB partition block bad id";
+ goto done;
+ }
+ if (rdbchksum(pbp)) {
+ *pmsg = "RDB partition block bad cksum";
+ goto done;
+ }
+ if (pbp->e.tabsize < 11)
+ *pmsg = "RDB bad partition info (environ < 11)";
+
+ if (pbp->e.dostype == DOST_OBSD) {
+ rdbpartoff = pbp->e.lowcyl * pbp->e.secpertrk
+ * pbp->e.numheads;
+ clp->rd_bsdlbl = rdbpartoff;
+ continue;
+ }
+
+ if (pbp->e.tabsize >= 16)
+ adt = getadostype(pbp->e.dostype);
+ else {
+ adt.archtype = ADT_UNKNOWN;
+ adt.fstype = FS_UNUSED;
+ }
+
+ switch (adt.archtype) {
+ case ADT_NETBSDROOT:
+ pp = &lp->d_partitions[0];
+ if (pp->p_size) {
+ printf("WARN: more than one root, ignoring\n");
+ clp->rdblock = RDBNULL; /* invlidate cpulab */
+ continue;
+ }
+ break;
+ case ADT_NETBSDSWAP:
+ pp = &lp->d_partitions[1];
+ if (pp->p_size) {
+ printf("WARN: more than one swap, ignoring\n");
+ clp->rdblock = RDBNULL; /* invlidate cpulab */
+ continue;
+ }
+ break;
+ case ADT_NETBSDUSER:
+ case ADT_AMIGADOS:
+ case ADT_AMIX:
+ case ADT_EXT2:
+ case ADT_UNKNOWN:
+ pp = &lp->d_partitions[lp->d_npartitions];
+ break;
+ }
+
+ if (lp->d_npartitions <= (pp - lp->d_partitions))
+ lp->d_npartitions = (pp - lp->d_partitions) + 1;
+
+#if 0
+ if (lp->d_secpercyl != (pbp->e.secpertrk * pbp->e.numheads)) {
+ if (pbp->partname[0] < sizeof(pbp->partname))
+ pbp->partname[pbp->partname[0] + 1] = 0;
+ else
+ pbp->partname[sizeof(pbp->partname) - 1] = 0;
+ printf("Partition '%s' geometry %ld/%ld differs",
+ pbp->partname + 1, pbp->e.numheads,
+ pbp->e.secpertrk);
+ printf(" from RDB %d/%d\n", lp->d_ntracks,
+ lp->d_nsectors);
+ }
+#endif
+#if 0
+ /*
+ * insert sort in increasing offset order
+ */
+ while ((pp - lp->d_partitions) > RAW_PART + 1) {
+ daddr_t boff;
+
+ boff = pbp->e.lowcyl * pbp->e.secpertrk
+ * pbp->e.numheads;
+ if (boff > (pp - 1)->p_offset)
+ break;
+ *pp = *(pp - 1); /* struct copy */
+ pp--;
+ }
+#endif
+ i = (pp - lp->d_partitions);
+
+ pp->p_size = (pbp->e.highcyl - pbp->e.lowcyl + 1)
+ * pbp->e.secpertrk * pbp->e.numheads;
+ pp->p_offset = pbp->e.lowcyl * pbp->e.secpertrk
+ * pbp->e.numheads;
+ pp->p_fstype = adt.fstype;
+ if (adt.archtype == ADT_AMIGADOS) {
+ /*
+ * Save reserved blocks at begin in cpg and
+ * adjust size by reserved blocks at end
+ */
+ pp->p_fsize = 512;
+ pp->p_frag = pbp->e.secperblk;
+ pp->p_cpg = pbp->e.resvblocks;
+ pp->p_size -= pbp->e.prefac;
+ } else if (pbp->e.tabsize > 22 && ISFSARCH_NETBSD(adt)) {
+ pp->p_fsize = pbp->e.fsize;
+ pp->p_frag = pbp->e.frag;
+ pp->p_cpg = pbp->e.cpg;
+ } else {
+ pp->p_fsize = 1024;
+ pp->p_frag = 8;
+ pp->p_cpg = 0;
+ }
+
+ /*
+ * store this partitions block number
+ */
+ clp->pbindex[i] = cindex;
+ clp->pblist[cindex] = nextb;
+ cindex++;
+ }
+done:
+ if (clp->rdblock != RDBNULL && rdbpartoff != -1)
+ *bsdpartoff = rdbpartoff;
+ bp->b_dev = dev;
+ return (clp->rdblock != RDBNULL);
+}
+
+struct adostype
+getadostype(u_long dostype)
+{
+ struct adostype adt;
+ u_long t3, b1;
+
+ t3 = dostype & 0xffffff00;
+ b1 = dostype & 0x000000ff;
+
+ adt.fstype = b1;
+
+ switch (t3) {
+ case DOST_NBR:
+ adt.archtype = ADT_NETBSDROOT;
+ return (adt);
+ case DOST_NBS:
+ adt.archtype = ADT_NETBSDSWAP;
+ return (adt);
+ case DOST_NBU:
+ adt.archtype = ADT_NETBSDUSER;
+ return (adt);
+ case DOST_MUFS:
+ /* check for 'muFS'? */
+ adt.archtype = ADT_AMIGADOS;
+ adt.fstype = FS_ADOS;
+ return (adt);
+ case DOST_DOS:
+ adt.archtype = ADT_AMIGADOS;
+ if (b1 > 5)
+#if 0
+ /*
+ * XXX at least I, <niklas@appli.se>, have a partition
+ * that looks like "DOS\023", wherever that came from,
+ * but ADOS accepts it, so should we.
+ */
+ goto unknown;
+ else
+#else
+ printf("found dostype: 0x%x, assuming an ADOS FS "
+ "although it's unknown\n", dostype);
+#endif
+ adt.fstype = FS_ADOS;
+ return (adt);
+ case DOST_AMIX:
+ adt.archtype = ADT_AMIX;
+ if (b1 == 2)
+ adt.fstype = FS_BSDFFS;
+ else
+ goto unknown;
+ return (adt);
+ case DOST_XXXBSD:
+#ifdef DIAGNOSTIC
+ printf("found dostype: 0x%x which is deprecated", dostype);
+#endif
+ if (b1 == 'S') {
+ dostype = DOST_NBS;
+ dostype |= FS_SWAP;
+ } else {
+ if (b1 == 'R')
+ dostype = DOST_NBR;
+ else
+ dostype = DOST_NBU;
+ dostype |= FS_BSDFFS;
+ }
+#ifdef DIAGNOSTIC
+ printf(" using: 0x%x instead\n", dostype);
+#endif
+ return (getadostype(dostype));
+ case DOST_EXT2:
+ adt.archtype = ADT_EXT2;
+ adt.fstype = FS_EXT2FS;
+ return(adt);
+ default:
+ unknown:
+#ifdef DIAGNOSTIC
+ printf("warning unknown dostype: 0x%x marking unused\n",
+ dostype);
+#endif
+ adt.archtype = ADT_UNKNOWN;
+ adt.fstype = FS_UNUSED;
+ return (adt);
+ }
+}
+
+u_long
+rdbchksum(bdata)
+ void *bdata;
+{
+ u_long *blp, cnt, val;
+
+ blp = bdata;
+ cnt = blp[1];
+ val = 0;
+
+ while (cnt--)
+ val += *blp++;
+ return (val);
+}