Module Name:    src
Committed By:   phx
Date:           Fri Sep 11 12:00:13 UTC 2009

Modified Files:
        src/sys/arch/ofppc/stand/ofwboot: Makefile ofdev.c ofdev.h version
Added Files:
        src/sys/arch/ofppc/stand/ofwboot: mbr.c mbr.h rdb.c rdb.h

Log Message:
Added support for RDB partitions.
Moved MBR parition code out of ofdev.c into mbr.c.
Tested on Pegasos2 (RDB and MBR) and RS6000.


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/arch/ofppc/stand/ofwboot/Makefile
cvs rdiff -u -r0 -r1.1 src/sys/arch/ofppc/stand/ofwboot/mbr.c \
    src/sys/arch/ofppc/stand/ofwboot/mbr.h \
    src/sys/arch/ofppc/stand/ofwboot/rdb.c \
    src/sys/arch/ofppc/stand/ofwboot/rdb.h
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/ofppc/stand/ofwboot/ofdev.c
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/ofppc/stand/ofwboot/ofdev.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/ofppc/stand/ofwboot/version

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/ofppc/stand/ofwboot/Makefile
diff -u src/sys/arch/ofppc/stand/ofwboot/Makefile:1.24 src/sys/arch/ofppc/stand/ofwboot/Makefile:1.25
--- src/sys/arch/ofppc/stand/ofwboot/Makefile:1.24	Mon Jan 12 07:49:57 2009
+++ src/sys/arch/ofppc/stand/ofwboot/Makefile	Fri Sep 11 12:00:12 2009
@@ -1,9 +1,10 @@
-#	$NetBSD: Makefile,v 1.24 2009/01/12 07:49:57 tsutsui Exp $
+#	$NetBSD: Makefile,v 1.25 2009/09/11 12:00:12 phx Exp $
 
 S!=	cd ${.CURDIR}/../../../.. ; pwd
 
 PROG=		ofwboot
-SRCS=		ofwstart.S Locore.c boot.c ofdev.c net.c netif_of.c vers.c
+SRCS=		ofwstart.S Locore.c boot.c ofdev.c net.c netif_of.c
+SRCS+=		mbr.c rdb.c vers.c
 CFLAGS+=	-msoft-float -Wno-main -ffreestanding
 CFLAGS+=	-Wall -Wmissing-prototypes -Wstrict-prototypes -Wpointer-arith
 #CPPFLAGS+=	-g -DALLOC_TRACE -DDEBUG #-DOFW_DEBUG -DNETIF_DEBUG

Index: src/sys/arch/ofppc/stand/ofwboot/ofdev.c
diff -u src/sys/arch/ofppc/stand/ofwboot/ofdev.c:1.16 src/sys/arch/ofppc/stand/ofwboot/ofdev.c:1.17
--- src/sys/arch/ofppc/stand/ofwboot/ofdev.c:1.16	Mon Jan 12 07:49:57 2009
+++ src/sys/arch/ofppc/stand/ofwboot/ofdev.c	Fri Sep 11 12:00:12 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ofdev.c,v 1.16 2009/01/12 07:49:57 tsutsui Exp $	*/
+/*	$NetBSD: ofdev.c,v 1.17 2009/09/11 12:00:12 phx Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -37,8 +37,6 @@
 #include "ofdev.h"
 
 #include <sys/param.h>
-#include <sys/disklabel.h>
-#include <sys/bootblock.h>
 
 #include <netinet/in.h>
 
@@ -52,6 +50,8 @@
 
 #include "net.h"
 #include "openfirm.h"
+#include "mbr.h"
+#include "rdb.h"
 
 extern char bootdev[];
 
@@ -120,7 +120,7 @@
 	return 0;
 }
 
-static int
+int
 strategy(void *devdata, int rw, daddr_t blk, size_t size, void *buf,
 	 size_t *rsize)
 {
@@ -186,76 +186,6 @@
 char opened_name[256];
 int floppyboot;
 
-static u_long
-get_long(const void *p)
-{
-	const unsigned char *cp = p;
-
-	return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
-}
-
-/*
- * Find a valid disklabel.
- */
-static int
-search_label(struct of_dev *devp, u_long off, char *buf, struct disklabel *lp,
-								u_long off0)
-{
-	size_t read;
-	struct mbr_partition *p;
-	int i;
-	u_long poff;
-	static int recursion;
-
-	if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
-	    || read != DEV_BSIZE)
-		return ERDLAB;
-
-	if (*(u_int16_t *)&buf[MBR_MAGIC_OFFSET] != sa_htole16(MBR_MAGIC))
-		return ERDLAB;
-
-	if (recursion++ <= 1)
-		off0 += off;
-	for (p = (struct mbr_partition *)(buf + MBR_PART_OFFSET), i = 0;
-	     i < MBR_PART_COUNT; i++, p++) {
-		if (p->mbrp_type == MBR_PTYPE_NETBSD
-#ifdef COMPAT_386BSD_MBRPART
-		    || (p->mbrp_type == MBR_PTYPE_386BSD &&
-			(printf("WARNING: old BSD partition ID!\n"), 1)
-			/* XXX XXX - libsa printf() is void */ )
-#endif
-		    ) {
-			poff = get_long(&p->mbrp_start) + off0;
-			if (strategy(devp, F_READ, poff + LABELSECTOR,
-				     DEV_BSIZE, buf, &read) == 0
-			    && read == DEV_BSIZE) {
-				if (!getdisklabel(buf, lp)) {
-					recursion--;
-					return 0;
-				}
-			}
-			if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
-			    || read != DEV_BSIZE) {
-				recursion--;
-				return ERDLAB;
-			}
-		} else if (p->mbrp_type == MBR_PTYPE_EXT) {
-			poff = get_long(&p->mbrp_start);
-			if (!search_label(devp, poff, buf, lp, off0)) {
-				recursion--;
-				return 0;
-			}
-			if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
-			    || read != DEV_BSIZE) {
-				recursion--;
-				return ERDLAB;
-			}
-		}
-	}
-
-	recursion--;
-	return ERDLAB;
-}
 
 int
 devopen(struct open_file *of, const char *name, char **file)
@@ -263,11 +193,12 @@
 	char *cp;
 	char partition;
 	char fname[256];
-	char buf[DEV_BSIZE];
 	struct disklabel label;
 	int handle, part;
 	size_t read;
 	int error = 0;
+	/* allow disk blocks up to 65536 bytes */
+	char buf[DEV_BSIZE<<7];
 
 	if (ofdev.handle != -1)
 		panic("devopen");
@@ -326,14 +257,19 @@
 		ofdev.type = OFDEV_DISK;
 		ofdev.bsize = DEV_BSIZE;
 
-		/* First try to find a disklabel without MBR partitions */
+		/* First try to find a disklabel without MBR/RDB partitions */
 		if (strategy(&ofdev, F_READ,
 			     LABELSECTOR, DEV_BSIZE, buf, &read) != 0
 		    || read != DEV_BSIZE
 		    || getdisklabel(buf, &label)) {
 
 			/* Else try MBR partitions */
-			error = search_label(&ofdev, 0, buf, &label, 0);
+			error = search_mbr_label(&ofdev, 0, buf, &label, 0);
+			if (error && error != ERDLAB)
+				goto bad;
+
+			/* and finally try RDB partitions */
+			error = search_rdb_label(&ofdev, buf, &label);
 			if (error && error != ERDLAB)
 				goto bad;
 		}

Index: src/sys/arch/ofppc/stand/ofwboot/ofdev.h
diff -u src/sys/arch/ofppc/stand/ofwboot/ofdev.h:1.2 src/sys/arch/ofppc/stand/ofwboot/ofdev.h:1.3
--- src/sys/arch/ofppc/stand/ofwboot/ofdev.h:1.2	Thu Jun 26 20:47:51 2003
+++ src/sys/arch/ofppc/stand/ofwboot/ofdev.h	Fri Sep 11 12:00:12 2009
@@ -1,4 +1,4 @@
-/*	$NetBSD: ofdev.h,v 1.2 2003/06/26 20:47:51 aymeric Exp $	*/
+/*	$NetBSD: ofdev.h,v 1.3 2009/09/11 12:00:12 phx Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -51,4 +51,6 @@
 extern char opened_name[];
 extern int floppyboot;
 
+int strategy(void *, int, daddr_t, size_t, void *, size_t *);
+
 #endif

Index: src/sys/arch/ofppc/stand/ofwboot/version
diff -u src/sys/arch/ofppc/stand/ofwboot/version:1.10 src/sys/arch/ofppc/stand/ofwboot/version:1.11
--- src/sys/arch/ofppc/stand/ofwboot/version:1.10	Wed Feb 13 20:11:38 2008
+++ src/sys/arch/ofppc/stand/ofwboot/version	Fri Sep 11 12:00:12 2009
@@ -1,4 +1,4 @@
-$NetBSD: version,v 1.10 2008/02/13 20:11:38 garbled Exp $
+$NetBSD: version,v 1.11 2009/09/11 12:00:12 phx Exp $
 
 1.1:		Boot program for OpenFirmware; initial revision
 1.2:		Boot program rearrangement
@@ -10,3 +10,4 @@
 1.8:		Support IBM RS/6000, switch to stock libsa alloc
 1.9:		Add support for auto-detection of 64bit CPUs
 1.10:		Change note to indicate real mode, add ldscript to support 7046
+1.11:		Support for RDB partitions.

Added files:

Index: src/sys/arch/ofppc/stand/ofwboot/mbr.c
diff -u /dev/null src/sys/arch/ofppc/stand/ofwboot/mbr.c:1.1
--- /dev/null	Fri Sep 11 12:00:13 2009
+++ src/sys/arch/ofppc/stand/ofwboot/mbr.c	Fri Sep 11 12:00:12 2009
@@ -0,0 +1,113 @@
+/*	$NetBSD: mbr.c,v 1.1 2009/09/11 12:00:12 phx Exp $	*/
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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/bootblock.h>
+
+#include <lib/libsa/byteorder.h>
+#include <lib/libsa/stand.h>
+
+#include "mbr.h"
+
+
+static u_long
+get_long(const void *p)
+{
+	const unsigned char *cp = p;
+
+	return cp[0] | (cp[1] << 8) | (cp[2] << 16) | (cp[3] << 24);
+}
+
+
+/*
+ * Find a valid MBR disklabel.
+ */
+int
+search_mbr_label(struct of_dev *devp, u_long off, char *buf,
+    struct disklabel *lp, u_long off0)
+{
+	size_t read;
+	struct mbr_partition *p;
+	int i;
+	u_long poff;
+	static int recursion;
+
+	if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+	    || read != DEV_BSIZE)
+		return ERDLAB;
+
+	if (*(u_int16_t *)&buf[MBR_MAGIC_OFFSET] != sa_htole16(MBR_MAGIC))
+		return ERDLAB;
+
+	if (recursion++ <= 1)
+		off0 += off;
+	for (p = (struct mbr_partition *)(buf + MBR_PART_OFFSET), i = 0;
+	     i < MBR_PART_COUNT; i++, p++) {
+		if (p->mbrp_type == MBR_PTYPE_NETBSD
+#ifdef COMPAT_386BSD_MBRPART
+		    || (p->mbrp_type == MBR_PTYPE_386BSD &&
+			(printf("WARNING: old BSD partition ID!\n"), 1)
+			/* XXX XXX - libsa printf() is void */ )
+#endif
+		    ) {
+			poff = get_long(&p->mbrp_start) + off0;
+			if (strategy(devp, F_READ, poff + LABELSECTOR,
+				     DEV_BSIZE, buf, &read) == 0
+			    && read == DEV_BSIZE) {
+				if (!getdisklabel(buf, lp)) {
+					recursion--;
+					return 0;
+				}
+			}
+			if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+			    || read != DEV_BSIZE) {
+				recursion--;
+				return ERDLAB;
+			}
+		} else if (p->mbrp_type == MBR_PTYPE_EXT) {
+			poff = get_long(&p->mbrp_start);
+			if (!search_mbr_label(devp, poff, buf, lp, off0)) {
+				recursion--;
+				return 0;
+			}
+			if (strategy(devp, F_READ, off, DEV_BSIZE, buf, &read)
+			    || read != DEV_BSIZE) {
+				recursion--;
+				return ERDLAB;
+			}
+		}
+	}
+
+	recursion--;
+	return ERDLAB;
+}
Index: src/sys/arch/ofppc/stand/ofwboot/mbr.h
diff -u /dev/null src/sys/arch/ofppc/stand/ofwboot/mbr.h:1.1
--- /dev/null	Fri Sep 11 12:00:13 2009
+++ src/sys/arch/ofppc/stand/ofwboot/mbr.h	Fri Sep 11 12:00:12 2009
@@ -0,0 +1,43 @@
+/* $NetBSD: mbr.h,v 1.1 2009/09/11 12:00:12 phx Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996 Wolfgang Solfrank.
+ * Copyright (C) 1995, 1996 TooLs GmbH.
+ * 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 TooLs GmbH.
+ * 4. The name of TooLs GmbH may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``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 TOOLS GMBH 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 MBR_H_
+#define MBR_H_
+
+#include <sys/disklabel.h>
+#include "ofdev.h"
+
+int search_mbr_label(struct of_dev *, u_long, char *, struct disklabel *,
+    u_long);
+
+#endif /* MBR_H_ */
Index: src/sys/arch/ofppc/stand/ofwboot/rdb.c
diff -u /dev/null src/sys/arch/ofppc/stand/ofwboot/rdb.c:1.1
--- /dev/null	Fri Sep 11 12:00:13 2009
+++ src/sys/arch/ofppc/stand/ofwboot/rdb.c	Fri Sep 11 12:00:12 2009
@@ -0,0 +1,253 @@
+/*	$NetBSD: rdb.c,v 1.1 2009/09/11 12:00:12 phx Exp $	*/
+
+/*-
+ * Copyright (c) 2009 Frank Wille.
+ * All rights reserved.
+ *
+ * Written by Frank Wille for The NetBSD Project.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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/disklabel_rdb.h>
+
+#include <lib/libsa/stand.h>
+
+#include "rdb.h"
+
+
+static u_long
+rdbchksum(void *bdata)
+{
+	u_long *blp, cnt, val;
+
+	blp = bdata;
+	cnt = blp[1];
+	val = 0;
+
+	while (cnt--)
+		val += *blp++;
+	return val;
+}
+
+
+static 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_AMIX:
+		adt.archtype = ADT_AMIX;
+		if (b1 == 2)
+			adt.fstype = FS_BSDFFS;
+		else
+			adt.fstype = FS_UNUSED;
+		return adt;
+	case DOST_XXXBSD:
+		if (b1 == 'S') {
+			dostype = DOST_NBS;
+			dostype |= FS_SWAP;
+		} else {
+			if (b1 == 'R')
+				dostype = DOST_NBR;
+			else
+				dostype = DOST_NBU;
+			dostype |= FS_BSDFFS;
+		}
+		return getadostype(dostype);
+	case DOST_EXT2:
+		adt.archtype = ADT_EXT2;
+		adt.fstype = FS_EX2FS;
+		return adt;
+	case DOST_RAID:
+		adt.archtype = ADT_RAID;
+		adt.fstype = FS_RAID;
+		return adt;
+	default:
+		adt.archtype = ADT_UNKNOWN;
+		adt.fstype = FS_UNUSED;
+		return adt;
+	}
+}
+
+
+/*
+ * Find a valid RDB disklabel.
+ */
+int
+search_rdb_label(struct of_dev *devp, char *buf, struct disklabel *lp)
+{
+	struct adostype adt;
+	struct rdblock *rbp;
+	struct partblock *pbp;
+	struct disklabel *dlp;
+	struct partition *pp;
+	u_long blk;
+	size_t read;
+	int i;
+
+	/*
+	 * Scan the first RDB_MAXBLOCKS of a disk for an RDB block.
+	 */
+	rbp = (struct rdblock *)buf;
+	for (blk = 0; blk < RDB_MAXBLOCKS; blk++) {
+		if (strategy(devp, F_READ, blk, DEV_BSIZE, buf, &read)
+		    || read != DEV_BSIZE)
+			return ERDLAB;
+
+		/* check for valid RDB */
+		if (rbp->id == RDBLOCK_ID && rdbchksum(rbp) == 0)
+			break;
+
+		/* check for native NetBSD label */
+		dlp = (struct disklabel *)(buf + LABELOFFSET);
+		if (dlp->d_magic == DISKMAGIC && dkcksum(dlp) == 0) {
+			*lp = *dlp;
+			return 0;
+		}
+	}
+	if (blk == RDB_MAXBLOCKS)
+		return ERDLAB;
+
+	/* Found RDB, clear disklabel partitions before reading PART blocks. */
+	lp->d_npartitions = RAW_PART + 1;
+	for (i = 0; i < MAXPARTITIONS; i++) {
+		lp->d_partitions[i].p_size = 0;
+		lp->d_partitions[i].p_offset = 0;
+		lp->d_partitions[i].p_fstype = 0;
+	}
+
+	/*
+	 * Construct a disklabel from RDB.
+	 */
+	lp->d_secsize = rbp->nbytes;
+	lp->d_nsectors = rbp->nsectors;
+	lp->d_ntracks = rbp->nheads;
+	/* be prepared that rbp->ncylinders may be a bogus value */
+	if (rbp->highcyl == 0)
+		lp->d_ncylinders = rbp->ncylinders;
+	else
+		lp->d_ncylinders = rbp->highcyl + 1;
+	/* also don't trust rbp->secpercyl */
+	lp->d_secpercyl = (rbp->secpercyl <= lp->d_nsectors * lp->d_ntracks) ?
+	    rbp->secpercyl : lp->d_nsectors * lp->d_ntracks;
+	if (lp->d_secpercyl == 0)
+		lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
+
+	lp->d_secperunit = lp->d_secpercyl * lp->d_ncylinders;
+	lp->d_acylinders = rbp->ncylinders - (rbp->highcyl - rbp->lowcyl + 1);
+	lp->d_rpm = 3600;
+	lp->d_interleave = rbp->interleave;
+	lp->d_headswitch = lp->d_flags = lp->d_trackskew = lp->d_cylskew = 0;
+	lp->d_trkseek = 0;
+
+	/* raw partition gets the entire disk */
+	lp->d_partitions[RAW_PART].p_size = rbp->ncylinders * lp->d_secpercyl;
+
+	/*
+	 * Now scan for partition blocks.
+	 */
+	pbp = (struct partblock *)buf;
+	for (blk = rbp->partbhead; blk != RDBNULL; blk = pbp->next) {
+		if (strategy(devp, F_READ, blk * (lp->d_secsize / DEV_BSIZE),
+		    lp->d_secsize, buf, &read)
+		    || read != lp->d_secsize)
+			return ERDLAB;
+
+		/* verify ID and checksum of PART block */
+		if (pbp->id != PARTBLOCK_ID || rdbchksum(pbp))
+			return ERDLAB;
+
+		/* environment table in PART block needs at least 11 entries */
+		if (pbp->e.tabsize < 11)
+			return ERDLAB;
+
+		/* need a table size of 16 for a valid dostype */
+		if (pbp->e.tabsize < 16)
+			pbp->e.dostype = 0;
+		adt = getadostype(pbp->e.dostype);
+
+		/* determine partition index */
+		switch (adt.archtype) {
+		case ADT_NETBSDROOT:
+			pp = &lp->d_partitions[0];
+			if (pp->p_size)
+				continue;
+			break;
+		case ADT_NETBSDSWAP:
+			pp = &lp->d_partitions[1];
+			if (pp->p_size)
+				continue;
+			break;
+		default:
+			pp = &lp->d_partitions[lp->d_npartitions++];
+			break;
+		}
+
+		/* sort partitions after RAW_PART by offset */
+		while ((pp - lp->d_partitions) > RAW_PART + 1) {
+			daddr_t boff;
+
+			boff = pbp->e.lowcyl * pbp->e.secpertrk
+			    * pbp->e.numheads
+			    * ((pbp->e.sizeblock << 2) / lp->d_secsize);
+			if (boff > (pp - 1)->p_offset)
+				break;
+			*pp = *(pp - 1);	/* struct copy */
+			pp--;
+		}
+
+		/* get partition size, offset, fstype */
+		pp->p_size = (pbp->e.highcyl - pbp->e.lowcyl + 1)
+		    * pbp->e.secpertrk * pbp->e.numheads
+		    * ((pbp->e.sizeblock << 2) / lp->d_secsize);
+		pp->p_offset = pbp->e.lowcyl * pbp->e.secpertrk
+		    * pbp->e.numheads
+		    * ((pbp->e.sizeblock << 2) / lp->d_secsize);
+		pp->p_fstype = adt.fstype;
+	}
+
+	/*
+	 * All partitions have been found. The disklabel is valid.
+	 */
+	lp->d_magic = lp->d_magic2 = DISKMAGIC;
+	lp->d_checksum = 0;
+	lp->d_checksum = dkcksum(lp);
+	return 0;
+}
Index: src/sys/arch/ofppc/stand/ofwboot/rdb.h
diff -u /dev/null src/sys/arch/ofppc/stand/ofwboot/rdb.h:1.1
--- /dev/null	Fri Sep 11 12:00:13 2009
+++ src/sys/arch/ofppc/stand/ofwboot/rdb.h	Fri Sep 11 12:00:12 2009
@@ -0,0 +1,39 @@
+/* $NetBSD: rdb.h,v 1.1 2009/09/11 12:00:12 phx Exp $ */
+
+/*-
+ * Copyright (c) 2009 Frank Wille.
+ * All rights reserved.
+ *
+ * Written by Frank Wille for The NetBSD Project.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#ifndef RDB_H_
+#define RDB_H_
+
+#include <sys/disklabel.h>
+#include "ofdev.h"
+
+int search_rdb_label(struct of_dev *, char *, struct disklabel *);
+
+#endif /* RDB_H_ */

Reply via email to