Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src Add DKWEDGE_METHOD_RDB option, which is Amiga Rigid Disk Blo...



details:   https://anonhg.NetBSD.org/src/rev/9835ec4ce59a
branches:  trunk
changeset: 822020:9835ec4ce59a
user:      rin <rin%NetBSD.org@localhost>
date:      Sun Feb 26 11:56:49 2017 +0000

description:
Add DKWEDGE_METHOD_RDB option, which is Amiga Rigid Disk Block (RDB)
partitioning detection method for dk(4).

diffstat:

 share/man/man4/dk.4           |    7 +-
 sys/conf/files                |    3 +-
 sys/dev/dkwedge/dkwedge_rdb.c |  373 ++++++++++++++++++++++++++++++++++++++++++
 sys/dev/files.dev             |    3 +-
 4 files changed, 382 insertions(+), 4 deletions(-)

diffs (truncated from 446 to 300 lines):

diff -r 6dfed7ba44c5 -r 9835ec4ce59a share/man/man4/dk.4
--- a/share/man/man4/dk.4       Sun Feb 26 11:51:38 2017 +0000
+++ b/share/man/man4/dk.4       Sun Feb 26 11:56:49 2017 +0000
@@ -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 @@
 .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 @@
 .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
diff -r 6dfed7ba44c5 -r 9835ec4ce59a sys/conf/files
--- a/sys/conf/files    Sun Feb 26 11:51:38 2017 +0000
+++ b/sys/conf/files    Sun Feb 26 11:56:49 2017 +0000
@@ -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 @@
                                DKWEDGE_METHOD_GPT
                                DKWEDGE_METHOD_MBR
                                DKWEDGE_METHOD_APPLE
+                               DKWEDGE_METHOD_RDB
 
 defflag        opt_veriexec.h          VERIFIED_EXEC_FP_SHA1
                                VERIFIED_EXEC_FP_SHA256
diff -r 6dfed7ba44c5 -r 9835ec4ce59a sys/dev/dkwedge/dkwedge_rdb.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/dkwedge/dkwedge_rdb.c     Sun Feb 26 11:56:49 2017 +0000
@@ -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);



Home | Main Index | Thread Index | Old Index