Add 16 partition support to the SPARC. From NetBSD PR#2675, by der Mouse,
authordownsj <downsj@openbsd.org>
Thu, 12 Sep 1996 04:33:27 +0000 (04:33 +0000)
committerdownsj <downsj@openbsd.org>
Thu, 12 Sep 1996 04:33:27 +0000 (04:33 +0000)
<mouse@Collatz.McRCIM.McGill.EDU>.

sys/arch/sparc/include/disklabel.h
sys/arch/sparc/include/sun_disklabel.h
sys/arch/sparc/sparc/disksubr.c

index 3b4601f..9c9b28b 100644 (file)
@@ -1,3 +1,4 @@
+/*     $OpenBSD: disklabel.h,v 1.2 1996/09/12 04:33:27 downsj Exp $    */
 /*     $NetBSD: disklabel.h,v 1.4 1995/09/01 17:20:31 pk Exp $ */
 
 /*
@@ -35,7 +36,7 @@
 
 #define        LABELSECTOR     0                       /* sector containing label */
 #define        LABELOFFSET     64                      /* offset of label in sector */
-#define        MAXPARTITIONS                         /* number of partitions */
+#define        MAXPARTITIONS   16                      /* number of partitions */
 #define        RAW_PART        2                       /* raw partition: xx?c */
 
 struct cpu_disklabel {
index 8f01b84..7556bd4 100644 (file)
@@ -1,3 +1,4 @@
+/*     $OpenBSD: sun_disklabel.h,v 1.5 1996/09/12 04:33:28 downsj Exp $        */
 /*     $NetBSD: sun_disklabel.h,v 1.6 1996/01/07 22:03:09 thorpej Exp $ */
 
 /*
@@ -88,7 +89,17 @@ struct sun_dkpart {
 
 struct sun_disklabel {                 /* total size = 512 bytes */
        char    sl_text[128];
+#if MAXPARTITIONS > 8
+#define SUNXPART (MAXPARTITIONS-8)
+       u_long  sl_xpsum;               /* additive cksum, [sl_xpmag,sl_xxx1) */
+       u_long  sl_xpmag;               /* "extended" magic number */
+#define SL_XPMAG (0x199d1fe2+SUNXPART)
+       struct sun_dkpart sl_xpart[SUNXPART];   /* "extended" partitions, i through p */
+       char    sl_xxx1[292-8-(8*SUNXPART)];    /* [292] including sl_x* */
+#else
+#define SUNXPART 0
        char    sl_xxx1[292];
+#endif
        u_short sl_rpm;                 /* rotational speed */
        u_short sl_pcylinders;          /* number of physical cyls */
        u_short sl_sparespercyl;        /* spare sectors per cylinder */
index 4446fd1..0e4ab2f 100644 (file)
@@ -1,3 +1,4 @@
+/*     $OpenBSD: disksubr.c,v 1.6 1996/09/12 04:33:29 downsj Exp $     */
 /*     $NetBSD: disksubr.c,v 1.16 1996/04/28 20:25:59 thorpej Exp $ */
 
 /*
@@ -285,14 +286,15 @@ bounds_check_with_label(bp, lp, wlabel)
 #define dkpart(dev) (minor(dev) & 7)
 
        struct partition *p = lp->d_partitions + dkpart(bp->b_dev);
-       int labelsect = lp->d_partitions[0].p_offset;
        int maxsz = p->p_size;
        int sz = (bp->b_bcount + DEV_BSIZE - 1) >> DEV_BSHIFT;
 
        /* overwriting disk label ? */
        /* XXX should also protect bootstrap in first 8K */
-       if (bp->b_blkno + p->p_offset <= LABELSECTOR + labelsect &&
-           (bp->b_flags & B_READ) == 0 && wlabel == 0) {
+       /* XXX this assumes everything <=LABELSECTOR is label! */
+       /*     But since LABELSECTOR is 0, that's ok for now. */
+       if ((bp->b_blkno + p->p_offset <= LABELSECTOR) &&
+           ((bp->b_flags & B_READ) == 0) && (wlabel == 0)) {
                bp->b_error = EROFS;
                goto bad;
        }
@@ -330,7 +332,7 @@ bad:
 
 /* What partition types to assume for Sun disklabels: */
 static u_char
-sun_fstypes[8] = {
+sun_fstypes[16] = {
        FS_BSDFFS,      /* a */
        FS_SWAP,        /* b */
        FS_OTHER,       /* c - whole disk */
@@ -339,8 +341,37 @@ sun_fstypes[8] = {
        FS_BSDFFS,      /* f */
        FS_BSDFFS,      /* g */
        FS_BSDFFS,      /* h */
+       FS_BSDFFS,      /* i */
+       FS_BSDFFS,      /* j */
+       FS_BSDFFS,      /* k */
+       FS_BSDFFS,      /* l */
+       FS_BSDFFS,      /* m */
+       FS_BSDFFS,      /* n */
+       FS_BSDFFS,      /* o */
+       FS_BSDFFS       /* p */
 };
 
+/*
+ * Given a struct sun_disklabel, assume it has an extended partition
+ * table and compute the correct value for sl_xpsum.
+ */
+static __inline u_long
+sun_extended_sum(sl)
+       struct sun_disklabel *sl;
+{
+       u_long lsum;
+       u_long *xp;
+       u_long *ep;
+
+       xp = (u_long *) &sl->sl_xpmag;
+       ep = (u_long *) &sl->sl_xxx1[0];
+
+       lsum = 0;
+       for (; xp < ep; xp++)
+               lsum += *xp;
+       return(lsum);
+}
+       
 /*
  * Given a SunOS disk label, set lp to a BSD disk label.
  * Returns NULL on success, else an error string.
@@ -388,7 +419,7 @@ disklabel_sun_to_bsd(cp, lp)
        lp->d_rpm          = sl->sl_rpm;
        lp->d_interleave   = sl->sl_interleave;
 
-       lp->d_npartitions = 8;
+       lp->d_npartitions = MAXPARTITIONS;
        /* These are as defined in <ufs/ffs/fs.h> */
        lp->d_bbsize = 8192;    /* XXX */
        lp->d_sbsize = 8192;    /* XXX */
@@ -414,6 +445,45 @@ disklabel_sun_to_bsd(cp, lp)
                }
        }
 
+#if SUNXPART > 0
+
+       /* Clear "extended" partition info, tentatively */
+       for (i = 0; i < SUNXPART; i++) {
+               npp = &lp->d_partitions[i+8];
+               npp->p_offset = 0;
+               npp->p_size = 0;
+               npp->p_fstype = FS_UNUSED;
+       }
+
+       /* Check to see if there's an "extended" partition table */
+       if (sl->sl_xpmag == SL_XPMAG) { /* probably... */
+               if (sun_extended_sum(sl) == sl->sl_xpsum) {     /* ...yes! */
+                       /*
+                        * There is.  Copy over the "extended" partitions.
+                        * This code parallels the loop for partitions a-h.
+                        *
+                        * XXX Abstract the common code?
+                        */
+                       for (i = 0; i < SUNXPART; i++) {
+                               spp = &sl->sl_xpart[i];
+                               npp = &lp->d_partitions[i+8];
+                               npp->p_offset = spp->sdkp_cyloffset * secpercyl;
+                               npp->p_size = spp->sdkp_nsectors;
+                               if (npp->p_size == 0) {
+                                       npp->p_fstype = FS_UNUSED;
+                               } else {
+                                       npp->p_fstype = sun_fstypes[i+8];
+                                       if (npp->p_fstype == FS_BSDFFS) {
+                                               npp->p_fsize = 1024;
+                                               npp->p_frag = 8;
+                                               npp->p_cpg = 16;
+                                       }
+                               }
+                       }
+               }
+       }
+#endif /* if SUNXPART > 0 */
+
        lp->d_checksum = 0;
        lp->d_checksum = dkcksum(lp);
        return (NULL);
@@ -464,6 +534,42 @@ disklabel_bsd_to_sun(lp, cp)
        }
        sl->sl_magic = SUN_DKMAGIC;
 
+#if SUNXPART > 0
+       /*
+        * The reason we load the extended table stuff only conditionally
+        * is so that a label that doesn't need it will have NULs there, like
+        * a "traditional" Sun label.  Since Suns seem to ignore everything
+        * between sl_text and sl_rpm, this probably doesn't matter, but it
+        * certainly doesn't hurt anything and it's easy to do.
+        */
+
+       /* Do we need to load the extended table? */
+       for (i = 0; i < SUNXPART; i++) {
+               if (lp->d_partitions[i+8].p_offset ||
+                   lp->d_partitions[i+8].p_size)
+                       break;
+       }
+       if (i < SUNXPART) { /* we do */
+               sl->sl_xpmag = SL_XPMAG;
+               for (i = 0; i < SUNXPART; i++) {
+                       spp = &sl->sl_xpart[i];
+                       npp = &lp->d_partitions[i+8];
+                       if (npp->p_offset % secpercyl)
+                               return(EINVAL);
+                       sl->sl_xpart[i].sdkp_cyloffset = npp->p_offset / secpercyl;
+                       sl->sl_xpart[i].sdkp_nsectors = npp->p_size;
+               }
+               sl->sl_xpsum = sun_extended_sum(sl);
+       } else {
+               sl->sl_xpmag = 0;
+               for (i = 0; i < SUNXPART; i++) {
+                       sl->sl_xpart[i].sdkp_cyloffset = 0;
+                       sl->sl_xpart[i].sdkp_nsectors = 0;
+               }
+               sl->sl_xpsum = 0;
+       }
+#endif /* if SUNXPART > 0 */
+
        /* Correct the XOR check. */
        sp1 = (u_short *)sl;
        sp2 = (u_short *)(sl + 1);