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