summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/sparc/include/disklabel.h3
-rw-r--r--sys/arch/sparc/include/sun_disklabel.h11
-rw-r--r--sys/arch/sparc/sparc/disksubr.c116
3 files changed, 124 insertions, 6 deletions
diff --git a/sys/arch/sparc/include/disklabel.h b/sys/arch/sparc/include/disklabel.h
index 3b4601fb0f2..9c9b28b1e1a 100644
--- a/sys/arch/sparc/include/disklabel.h
+++ b/sys/arch/sparc/include/disklabel.h
@@ -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 8 /* number of partitions */
+#define MAXPARTITIONS 16 /* number of partitions */
#define RAW_PART 2 /* raw partition: xx?c */
struct cpu_disklabel {
diff --git a/sys/arch/sparc/include/sun_disklabel.h b/sys/arch/sparc/include/sun_disklabel.h
index 8f01b84115d..7556bd4c7cd 100644
--- a/sys/arch/sparc/include/sun_disklabel.h
+++ b/sys/arch/sparc/include/sun_disklabel.h
@@ -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 */
diff --git a/sys/arch/sparc/sparc/disksubr.c b/sys/arch/sparc/sparc/disksubr.c
index 4446fd1927f..0e4ab2f726f 100644
--- a/sys/arch/sparc/sparc/disksubr.c
+++ b/sys/arch/sparc/sparc/disksubr.c
@@ -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,9 +341,38 @@ 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);