Module Name: src
Committed By: rin
Date: Sun Feb 26 11:56:49 UTC 2017
Modified Files:
src/share/man/man4: dk.4
src/sys/conf: files
src/sys/dev: files.dev
Added Files:
src/sys/dev/dkwedge: dkwedge_rdb.c
Log Message:
Add DKWEDGE_METHOD_RDB option, which is Amiga Rigid Disk Block (RDB)
partitioning detection method for dk(4).
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/share/man/man4/dk.4
cvs rdiff -u -r1.1170 -r1.1171 src/sys/conf/files
cvs rdiff -u -r1.2 -r1.3 src/sys/dev/files.dev
cvs rdiff -u -r0 -r1.1 src/sys/dev/dkwedge/dkwedge_rdb.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/share/man/man4/dk.4
diff -u src/share/man/man4/dk.4:1.6 src/share/man/man4/dk.4:1.7
--- src/share/man/man4/dk.4:1.6 Fri Jul 13 22:58:45 2012
+++ src/share/man/man4/dk.4 Sun Feb 26 11:56:49 2017
@@ -1,4 +1,4 @@
-.\" $NetBSD: dk.4,v 1.6 2012/07/13 22:58:45 abs Exp $
+.\" $NetBSD: dk.4,v 1.7 2017/02/26 11:56:49 rin Exp $
.\"
.\" Copyright (c) 2006 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -29,7 +29,7 @@
.\"
.\" Jonathan A. Kollasch used vnd(4) as the template for this man page.
.\"
-.Dd May 19, 2010
+.Dd February 26, 2017
.Dt DK 4
.Os
.Sh NAME
@@ -42,6 +42,7 @@ driver
.Cd "options DKWEDGE_METHOD_BSDLABEL"
.Cd "options DKWEDGE_METHOD_GPT"
.Cd "options DKWEDGE_METHOD_MBR"
+.Cd "options DKWEDGE_METHOD_RDB"
.Sh DESCRIPTION
The
.Nm
@@ -63,6 +64,8 @@ Extensible Firmware Interface Globally U
.It Dv DKWEDGE_METHOD_MBR
IBM PC-compatible Master Boot Record (MBR) partitioning detection method,
with support for Extended MBRs.
+.It Dv DKWEDGE_METHOD_RDB
+Amiga Rigid Disk Block (RDB) partitioning detection method.
.El
.Sh FILES
.Bl -tag -width /dev/XXrXdkX -compact
Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1170 src/sys/conf/files:1.1171
--- src/sys/conf/files:1.1170 Thu Feb 16 08:12:43 2017
+++ src/sys/conf/files Sun Feb 26 11:56:49 2017
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.1170 2017/02/16 08:12:43 knakahara Exp $
+# $NetBSD: files,v 1.1171 2017/02/26 11:56:49 rin Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20150846
@@ -90,6 +90,7 @@ defflag opt_dkwedge.h DKWEDGE_AUTODISCO
DKWEDGE_METHOD_GPT
DKWEDGE_METHOD_MBR
DKWEDGE_METHOD_APPLE
+ DKWEDGE_METHOD_RDB
defflag opt_veriexec.h VERIFIED_EXEC_FP_SHA1
VERIFIED_EXEC_FP_SHA256
Index: src/sys/dev/files.dev
diff -u src/sys/dev/files.dev:1.2 src/sys/dev/files.dev:1.3
--- src/sys/dev/files.dev:1.2 Sat Dec 10 10:26:38 2016
+++ src/sys/dev/files.dev Sun Feb 26 11:56:49 2017
@@ -1,4 +1,4 @@
-# $NetBSD: files.dev,v 1.2 2016/12/10 10:26:38 mlelstv Exp $
+# $NetBSD: files.dev,v 1.3 2017/02/26 11:56:49 rin Exp $
file dev/bio.c bio needs-flag
file dev/ccd.c ccd
@@ -12,6 +12,7 @@ file dev/dkwedge/dkwedge_apple.c dkwedge
file dev/dkwedge/dkwedge_bsdlabel.c dkwedge_method_bsdlabel
file dev/dkwedge/dkwedge_gpt.c dkwedge_method_gpt
file dev/dkwedge/dkwedge_mbr.c dkwedge_method_mbr
+file dev/dkwedge/dkwedge_rdb.c dkwedge_method_rdb
file dev/firmload.c firmload
file dev/fss.c fss
file dev/keylock.c keylock
Added files:
Index: src/sys/dev/dkwedge/dkwedge_rdb.c
diff -u /dev/null src/sys/dev/dkwedge/dkwedge_rdb.c:1.1
--- /dev/null Sun Feb 26 11:56:49 2017
+++ src/sys/dev/dkwedge/dkwedge_rdb.c Sun Feb 26 11:56:49 2017
@@ -0,0 +1,373 @@
+/* $NetBSD: dkwedge_rdb.c,v 1.1 2017/02/26 11:56:49 rin Exp $ */
+
+/*
+ * Adapted from arch/amiga/amiga/disksubr.c:
+ *
+ * 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
+ */
+
+/*
+ * Copyright (c) 1994 Christian E. Hopps
+ *
+ * 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 7.16 (Berkeley) 5/4/91
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: dkwedge_rdb.c,v 1.1 2017/02/26 11:56:49 rin Exp $");
+
+#include <sys/param.h>
+#include <sys/disklabel_rdb.h>
+#include <sys/disk.h>
+#include <sys/endian.h>
+#include <sys/malloc.h>
+#ifdef _KERNEL
+#include <sys/systm.h>
+#endif
+
+/*
+ * In /usr/src/sys/dev/scsipi/sd.c, routine sdstart() adjusts the
+ * block numbers, it changes from DEV_BSIZE units to physical units:
+ * blkno = bp->b_blkno / (lp->d_secsize / DEV_BSIZE);
+ * As long as media with sector sizes of 512 bytes are used, this
+ * doesn't matter (divide by 1), but for successful usage of media with
+ * greater sector sizes (e.g. 640MB MO-media with 2048 bytes/sector)
+ * we must multiply block numbers with (lp->d_secsize / DEV_BSIZE)
+ * to keep "unchanged" physical block numbers.
+ */
+#define SD_C_ADJUSTS_NR
+#ifdef SD_C_ADJUSTS_NR
+#define ADJUST_NR(x) ((x) * (secsize / DEV_BSIZE))
+#else
+#define ADJUST_NR(x) (x)
+#endif
+
+/* XXX */
+#define PARANOID
+
+#ifdef _KERNEL
+#define DKW_MALLOC(SZ) malloc((SZ), M_DEVBUF, M_WAITOK)
+#define DKW_FREE(PTR) free((PTR), M_DEVBUF)
+#define DKW_REALLOC(PTR, NEWSZ) realloc((PTR), (NEWSZ), M_DEVBUF, M_WAITOK)
+#else
+#define DKW_MALLOC(SZ) malloc((SZ))
+#define DKW_FREE(PTR) free((PTR))
+#define DKW_REALLOC(PTR, NEWSZ) realloc((PTR), (NEWSZ))
+#endif
+
+static unsigned rdbchksum(void *);
+static unsigned char getarchtype(unsigned);
+static const char *archtype_to_ptype(unsigned char);
+
+static int
+dkwedge_discover_rdb(struct disk *pdk, struct vnode *vp)
+{
+ struct dkwedge_info dkw;
+ struct partblock *pbp;
+ struct rdblock *rbp;
+ void *bp;
+ int error;
+ unsigned blk_per_cyl, bufsize, nextb, secsize, tabsize;
+ const char *ptype;
+ unsigned char archtype;
+ bool found, root, swap;
+
+ secsize = bufsize = DEV_BSIZE << pdk->dk_blkshift;
+ while (bufsize < sizeof(struct partblock) ||
+ bufsize < sizeof(struct rdblock))
+ bufsize *= 2;
+ bp = DKW_MALLOC(bufsize);
+
+ /*
+ * find the RDB block
+ * XXX bsdlabel should be detected by the other method
+ */
+ for (nextb = 0; nextb < RDB_MAXBLOCKS; nextb++) {
+ error = dkwedge_read(pdk, vp, ADJUST_NR(nextb), bp, bufsize);
+ if (error) {
+ aprint_error("%s: unable to read RDB @ %u, "
+ "error = %d\n", pdk->dk_name, nextb, error);
+ error = ESRCH;
+ goto done;
+ }
+ rbp = (struct rdblock *)bp;
+ if (be32toh(rbp->id) == RDBLOCK_ID) {
+ if (rdbchksum(rbp) == 0)
+ break;
+ else
+ aprint_error("%s: RDB bad checksum @ %u\n",
+ pdk->dk_name, nextb);
+ }
+ }
+
+ if (nextb == RDB_MAXBLOCKS) {
+ error = ESRCH;
+ goto done;
+ }
+
+#ifdef PARANOID
+ unsigned newsecsize = be32toh(rbp->nbytes);
+ if (secsize != newsecsize) {
+ aprint_verbose("secsize changed from %u to %u\n",
+ secsize, newsecsize);
+ secsize = bufsize = newsecsize;
+ while (bufsize < sizeof(struct partblock) ||
+ bufsize < sizeof(struct rdblock))
+ bufsize *= 2;
+ bp = DKW_REALLOC(bp, bufsize);
+ }
+#endif
+
+ strlcpy(dkw.dkw_parent, pdk->dk_name, sizeof(dkw.dkw_parent));
+
+ found = root = swap = false;
+ /*
+ * scan for partition blocks
+ */
+ for (nextb = be32toh(rbp->partbhead); nextb != RDBNULL;
+ nextb = be32toh(pbp->next)) {
+ error = dkwedge_read(pdk, vp, ADJUST_NR(nextb), bp, bufsize);
+ if (error) {
+ aprint_error("%s: unable to read RDB partition block @ "
+ "%u, error = %d\n", pdk->dk_name, nextb, error);
+ error = ESRCH;
+ goto done;
+ }
+ pbp = (struct partblock *)bp;
+
+ if (be32toh(pbp->id) != PARTBLOCK_ID) {
+ aprint_error(
+ "%s: RDB partition block @ %u bad id\n",
+ pdk->dk_name, nextb);
+ error = ESRCH;
+ goto done;
+ }
+ if (rdbchksum(pbp)) {
+ aprint_error(
+ "%s: RDB partition block @ %u bad checksum\n",
+ pdk->dk_name, nextb);
+ error = ESRCH;
+ goto done;
+ }
+
+ tabsize = be32toh(pbp->e.tabsize);
+ if (tabsize < 11) {
+ /*
+ * not enough info, too funky for us.
+ * I don't want to skip I want it fixed.
+ */
+ aprint_error(
+ "%s: RDB partition block @ %u bad partition info "
+ "(environ < 11)\n",
+ pdk->dk_name, nextb);
+ error = ESRCH;
+ goto done;
+ }
+
+ /*
+ * XXXX should be ">" however some vendors don't know
+ * what a table size is so, we hack for them.
+ * the other checks can fail for all I care but this
+ * is a very common value. *sigh*.
+ */
+ if (tabsize >= 16)
+ archtype = getarchtype(be32toh(pbp->e.dostype));
+ else
+ archtype = ADT_UNKNOWN;
+
+ switch (archtype) {
+ case ADT_NETBSDROOT:
+ if (root) {
+ aprint_error("%s: more than one root RDB "
+ "partition, ignoring\n", pdk->dk_name);
+ continue;
+ }
+ root = true;
+ break;
+ case ADT_NETBSDSWAP:
+ if (swap) {
+ aprint_error("%s: more than one swap RDB "
+ "partition , ignoring\n", pdk->dk_name);
+ continue;
+ }
+ swap = true;
+ break;
+ default:
+ break;
+ }
+
+ if (pbp->partname[0] + 1 < sizeof(pbp->partname))
+ pbp->partname[pbp->partname[0] + 1] = 0;
+ else
+ pbp->partname[sizeof(pbp->partname) - 1] = 0;
+ strlcpy(dkw.dkw_wname, pbp->partname + 1,
+ sizeof(dkw.dkw_wname));
+
+ ptype = archtype_to_ptype(archtype);
+ strlcpy(dkw.dkw_ptype, ptype, sizeof(dkw.dkw_ptype));
+
+ blk_per_cyl =
+ be32toh(pbp->e.secpertrk) * be32toh(pbp->e.numheads)
+ * ((be32toh(pbp->e.sizeblock) << 2) / secsize);
+ dkw.dkw_size = (uint64_t)(be32toh(pbp->e.highcyl)
+ - be32toh(pbp->e.lowcyl) + 1) * blk_per_cyl;
+ dkw.dkw_offset = (daddr_t)be32toh(pbp->e.lowcyl) * blk_per_cyl;
+
+ error = dkwedge_add(&dkw);
+ if (error == EEXIST) {
+ aprint_error(
+ "%s: wedge named '%s' already exists, ignoring\n",
+ pdk->dk_name, dkw.dkw_wname);
+ } else if (error)
+ aprint_error("%s: error %d adding partition %s\n",
+ pdk->dk_name, error, dkw.dkw_wname);
+ else
+ found = true;
+ }
+
+ if (found)
+ error = 0;
+ else
+ error = ESRCH;
+done:
+ DKW_FREE(bp);
+ return error;
+}
+
+static unsigned
+rdbchksum(void *bdata)
+{
+ unsigned *blp, cnt, val;
+
+ blp = bdata;
+ cnt = be32toh(blp[1]);
+ val = 0;
+
+ while (cnt--)
+ val += be32toh(*blp++);
+ return(val);
+}
+
+static unsigned char
+getarchtype(unsigned dostype)
+{
+ unsigned t3, b1;
+
+ t3 = dostype & 0xffffff00;
+ b1 = dostype & 0x000000ff;
+
+ switch (t3) {
+ case DOST_NBR:
+ return ADT_NETBSDROOT;
+ case DOST_NBS:
+ return ADT_NETBSDSWAP;
+ case DOST_NBU:
+ return ADT_NETBSDUSER;
+ case DOST_MUFS: /* check for 'muFS'? */
+ case DOST_DOS:
+ return ADT_AMIGADOS;
+ case DOST_AMIX:
+ return ADT_AMIX;
+
+ case DOST_XXXBSD:
+#ifdef DIAGNOSTIC
+ aprint_verbose("deprecated dostype found: 0x%x\n",
+ dostype);
+#endif
+ switch (b1) {
+ case 'R':
+ return ADT_NETBSDROOT;
+ case 'S':
+ return ADT_NETBSDSWAP;
+ default:
+ return ADT_NETBSDUSER;
+ }
+
+ case DOST_EXT2:
+ return ADT_EXT2;
+ case DOST_RAID:
+ return ADT_RAID;
+ default:
+#ifdef DIAGNOSTIC
+ aprint_verbose("warning unknown dostype: 0x%x\n",
+ dostype);
+#endif
+ return ADT_UNKNOWN;
+ }
+}
+
+static const char *
+archtype_to_ptype(unsigned char archtype)
+{
+ switch (archtype) {
+ case ADT_NETBSDROOT:
+ case ADT_NETBSDUSER:
+ return DKW_PTYPE_FFS;
+ case ADT_NETBSDSWAP:
+ return DKW_PTYPE_SWAP;
+ case ADT_AMIGADOS:
+ return DKW_PTYPE_AMIGADOS;
+ case ADT_EXT2:
+ return DKW_PTYPE_EXT2FS;
+ default:
+ return DKW_PTYPE_UNKNOWN;
+ }
+}
+
+#ifdef _KERNEL
+DKWEDGE_DISCOVERY_METHOD_DECL(RDB, 15, dkwedge_discover_rdb);
+#endif