Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/x68k/x68k Support BSD style disklabel on harddisks.



details:   https://anonhg.NetBSD.org/src/rev/78e4f4317bb4
branches:  trunk
changeset: 518100:78e4f4317bb4
user:      minoura <minoura%NetBSD.org@localhost>
date:      Sat Nov 24 16:08:25 2001 +0000

description:
Support BSD style disklabel on harddisks.
XXX need consistency check between the native label and the BSD label.

diffstat:

 sys/arch/x68k/x68k/disksubr.c |  327 +++++++++++++++++++++++++----------------
 1 files changed, 201 insertions(+), 126 deletions(-)

diffs (truncated from 482 to 300 lines):

diff -r 04e0c514e88b -r 78e4f4317bb4 sys/arch/x68k/x68k/disksubr.c
--- a/sys/arch/x68k/x68k/disksubr.c     Sat Nov 24 15:46:08 2001 +0000
+++ b/sys/arch/x68k/x68k/disksubr.c     Sat Nov 24 16:08:25 2001 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: disksubr.c,v 1.14 2000/11/20 08:24:23 chs Exp $        */
+/*     $NetBSD: disksubr.c,v 1.15 2001/11/24 16:08:25 minoura Exp $    */
 
 /*
  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
@@ -44,6 +44,13 @@
 #include <sys/syslog.h>
 #include <sys/disk.h>
 
+/* get rid of DEV_BSIZE dependency */
+#define DEF_BSIZE      DEV_BSIZE  /* default sector size = 512 */
+
+static void parttbl_consistency_check(struct disklabel *,
+                                     struct dos_partition *);
+
+
 /*
  * Attempt to read a disk label from a device
  * using the indicated stategy routine.
@@ -52,11 +59,6 @@
  * 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.
- *
  * Returns null on success and an error string on failure.
  */
 char *
@@ -66,18 +68,22 @@
        struct disklabel *lp;
        struct cpu_disklabel *osdep;
 {
-       struct dos_partition *dp = osdep->dosparts;
+       struct dos_partition *dp = 0;
        struct dkbad *bdp = &osdep->bad;
        struct buf *bp;
        struct disklabel *dlp;
        char *msg = NULL;
-       int dospartoff, cyl, i;
+       int i, labelsz;
 
+       if (osdep)
+               dp = osdep->dosparts;
        /* minimal requirements for archtypal disk label */
        if (lp->d_secsize == 0)
-               lp->d_secsize = DEV_BSIZE;
+               lp->d_secsize = DEF_BSIZE;
        if (lp->d_secperunit == 0)
                lp->d_secperunit = 0x1fffffff;
+       if (lp->d_secpercyl == 0)
+               lp->d_secpercyl = 0x1fffffff;
        lp->d_npartitions = RAW_PART + 1;
        for (i = 0; i < RAW_PART; i++) {
                lp->d_partitions[i].p_size = 0;
@@ -91,43 +97,73 @@
        bp = geteblk((int)lp->d_secsize);
        bp->b_dev = dev;
 
-       /* do dos partitions in the process of getting disklabel? */
-       dospartoff = 0;
-       cyl = LABELSECTOR / lp->d_secpercyl;
-       if (dp) {
-               bp->b_blkno = DOSBBSECTOR;
-               bp->b_bcount = lp->d_secsize;
-               bp->b_flags |= B_READ;
-               bp->b_cylinder = DOSBBSECTOR / lp->d_secpercyl;
-               (*strat)(bp);
+       /* read BSD disklabel first */
+       bp->b_blkno = LABELSECTOR;
+       bp->b_cylinder = LABELSECTOR/lp->d_secpercyl;
+       labelsz = howmany(LABELOFFSET+sizeof(struct disklabel), lp->d_secsize)
+               * lp->d_secsize;
+       bp->b_bcount = labelsz; /* to support < 512B/sector disks */
+       bp->b_flags |= B_READ;
+       (*strat)(bp);
 
-               if (biowait(bp)) {
-                       msg = "dos boot record I/O error";
-                       goto done;
+       /* if successful, locate disk label within block and validate */
+       if (biowait(bp)) {
+               msg = "disk label I/O error";
+               goto dodospart;
+       }
+       for (dlp = (struct disklabel *)bp->b_data;
+            dlp <= (struct disklabel *)(bp->b_data + labelsz - sizeof(*dlp));
+            dlp = (struct disklabel *)((uint8_t *)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;
                }
-               if (bcmp(bp->b_data, "X68SCSI1", 8) != 0) {
-                       msg = "no disk label";
+       }
+
+dodospart:
+       /* next do the Human68k-style partition table */
+       /* Human68k does not support > 2048B/sector devices (?) */
+       if (lp->d_secsize >= 2048) {
+               if (msg)
                        goto done;
-               }
+               goto dobadsect;
+       }
+       bp->b_blkno = DOSPARTOFF * DEF_BSIZE / lp->d_secsize;
+                               /* DOSPARTOFF in DEV_BSIZE unit */
+       bp->b_cylinder = DOSBBSECTOR / lp->d_secpercyl;
+       labelsz = howmany(sizeof(struct cpu_disklabel),
+                         lp->d_secsize) * lp->d_secsize;
+       bp->b_bcount = labelsz; /* to support < 512B/sector disks */
+       bp->b_flags &= ~(B_DONE);
+       (*strat)(bp);
 
-               /* read partition record */
-               bp->b_blkno = DOSPARTOFF;
-               bp->b_bcount = lp->d_secsize;
-               bp->b_flags &= ~(B_DONE);
-               bp->b_flags |= B_READ;
-               bp->b_cylinder = DOSPARTOFF / lp->d_secpercyl;
-               (*strat)(bp);
+       /* if successful, wander through Human68k partition table */
+       if (biowait(bp))
+               goto done;
+       if (strncmp(bp->b_data, "X68K", 4) != 0) {
+               /* Human68k-style partition table does not exist */
+               if (msg)
+                       goto done;
+               goto dobadsect;
+       }
 
-               /* if successful, wander through dos partition table */
-               if (biowait(bp)) {
-                       msg = "dos partition I/O error";
-                       goto done;
-               }
-
-               /* XXX how do we check veracity/bounds of this? */
+       /* XXX how do we check veracity/bounds of this? */
+       if (dp)
                bcopy(bp->b_data + sizeof(*dp) /*DOSPARTOFF*/, dp,
                      NDOSPART * sizeof(*dp));
+       else
+               dp = (void*) (bp->b_data + sizeof(*dp) /*DOSPARTOFF*/);
 
+       /* if BSD disklabel does not exist, fall back to Human68k partition */
+       if (msg != NULL) {
+               msg = NULL;
                lp->d_bbsize = 8192;
                lp->d_sbsize = 2048;
                for (i = 0; i < NDOSPART; i++, dp++)
@@ -138,9 +174,6 @@
                                int start = dp->dp_start * 2;
                                int size = dp->dp_size * 2;
 
-                               /* need sector address for SCSI */
-                               dospartoff = start; /* XXX */
-
                                /* update disklabel with details */
                                lp->d_partitions[part].p_size = size;
                                lp->d_partitions[part].p_offset =  start;
@@ -168,41 +201,11 @@
                                if (lp->d_npartitions <= part)
                                        lp->d_npartitions = part + 1;
                        }
-               goto done;
+       } else {
+               parttbl_consistency_check(lp, dp);
        }
 
-       /* next, dig out disk label */
-       bp->b_blkno = dospartoff + LABELSECTOR;
-       bp->b_cylinder = cyl;
-       bp->b_bcount = lp->d_secsize;
-       bp->b_flags &= ~(B_DONE);
-       bp->b_flags |= B_READ;
-       (*strat)(bp);
-
-       /* if successful, locate disk label within block and validate */
-       if (biowait(bp)) {
-               msg = "disk label I/O error";
-               goto done;
-       }
-       for (dlp = (struct disklabel *)bp->b_data;
-           dlp <= (struct disklabel *)(bp->b_data+DEV_BSIZE-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;
-               }
-       }
-
-       if (msg)
-               goto done;
-
+dobadsect:
        /* obtain bad sector table if requested and present */
        if (bdp && (lp->d_flags & D_BADSECT)) {
                struct dkbad *db;
@@ -213,10 +216,10 @@
                        bp->b_flags &= ~(B_DONE);
                        bp->b_flags |= B_READ;
                        bp->b_blkno = lp->d_secperunit - lp->d_nsectors + i;
-                       if (lp->d_secsize > DEV_BSIZE)
-                               bp->b_blkno *= lp->d_secsize / DEV_BSIZE;
+                       if (lp->d_secsize > DEF_BSIZE)
+                               bp->b_blkno *= lp->d_secsize / DEF_BSIZE;
                        else
-                               bp->b_blkno /= DEV_BSIZE / lp->d_secsize;
+                               bp->b_blkno /= DEF_BSIZE / lp->d_secsize;
                        bp->b_bcount = lp->d_secsize;
                        bp->b_cylinder = lp->d_ncylinders - 1;
                        (*strat)(bp);
@@ -259,7 +262,7 @@
 
        /* sanity clause */
        if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0
-               || (nlp->d_secsize % DEV_BSIZE) != 0)
+               /*|| (nlp->d_secsize % DEV_BSIZE) != 0*/)
                        return(EINVAL);
 
        /* special case to allow disklabel to be invalidated */
@@ -272,6 +275,8 @@
            dkcksum(nlp) != 0)
                return (EINVAL);
 
+       if (osdep)
+               parttbl_consistency_check(nlp, osdep->dosparts);
        /* XXX missing check if other dos partitions will be overwritten */
 
        while (openmask != 0) {
@@ -310,39 +315,77 @@
        struct disklabel *lp;
        struct cpu_disklabel *osdep;
 {
-       struct dos_partition *dp = osdep->dosparts;
+       struct dos_partition *dp = 0;
        struct buf *bp;
        struct disklabel *dlp;
-       int error, dospartoff, cyl, i;
+       int error, labelsz, i;
        char *np;
 
+       if (osdep)
+               dp = osdep->dosparts;
+       /* sanity clause */
+       if (lp->d_secpercyl == 0 || lp->d_secsize == 0
+               /*|| (lp->d_secsize % DEF_BSIZE) != 0*/)
+                       return(EINVAL);
+       if (dp)
+               parttbl_consistency_check(lp, dp);
+
        /* get a buffer and initialize it */
        bp = geteblk((int)lp->d_secsize);
        bp->b_dev = dev;
 
+       /* attempt to write BSD disklabel first */
+       bp->b_blkno = LABELSECTOR;
+       bp->b_cylinder = LABELSECTOR / lp->d_secpercyl;
+       labelsz = howmany(LABELOFFSET+sizeof(struct disklabel), lp->d_secsize)
+               * lp->d_secsize;
+       bp->b_bcount = labelsz; /* to support < 512B/sector disks */
+       bp->b_flags |= B_READ;
+       (*strat)(bp);
+
+       /* if successful, locate disk label within block and validate */
+       if (biowait(bp))
+               goto dodospart;
+       error = ESRCH;
+       for (dlp = (struct disklabel *)bp->b_data;
+            dlp <= (struct disklabel *)(bp->b_data + labelsz - 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_READ|B_DONE);
+                       bp->b_flags |= B_WRITE;
+                       (*strat)(bp);
+                       error = biowait(bp);
+                       break;



Home | Main Index | Thread Index | Old Index