summaryrefslogtreecommitdiffstats
path: root/sys/i386/isa/diskslice_machdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/isa/diskslice_machdep.c')
-rw-r--r--sys/i386/isa/diskslice_machdep.c84
1 files changed, 54 insertions, 30 deletions
diff --git a/sys/i386/isa/diskslice_machdep.c b/sys/i386/isa/diskslice_machdep.c
index 2d43fb3..3c35445 100644
--- a/sys/i386/isa/diskslice_machdep.c
+++ b/sys/i386/isa/diskslice_machdep.c
@@ -35,7 +35,7 @@
*
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
- * $Id$
+ * $Id: diskslice_machdep.c,v 1.3 1995/01/23 02:31:53 phk Exp $
*/
#include <stddef.h>
@@ -59,6 +59,7 @@ dsinit(dname, dev, strat, lp, sspp)
struct dos_partition *dp;
struct dos_partition *dp0;
int error;
+ int max_ncyls;
int max_nsectors;
int max_ntracks;
u_long secpercyl;
@@ -67,22 +68,19 @@ dsinit(dname, dev, strat, lp, sspp)
struct diskslices *ssp;
/*
- * Free old slices "struct", if any, and allocate a dummy new one.
+ * Allocate a dummy slices "struct" and initialize it to contain
+ * only an empty compatibility slice (pointing to itself) and a
+ * whole disk slice (which may be a dummy if the label is a dummy).
+ * If there is an error, then these slices become the only slices.
*/
- if (*sspp != NULL)
- free(*sspp, M_DEVBUF);
- ssp = malloc(offsetof(struct diskslices, dss_slices) + sizeof(*sp),
- M_DEVBUF, M_WAITOK);
+ ssp = malloc(offsetof(struct diskslices, dss_slices)
+ + BASE_SLICE * sizeof *sp, M_DEVBUF, M_WAITOK);
*sspp = ssp;
-
- /*
- * Initialize dummy slice. If there is an error, this becomes the
- * only slice, and no more restrictive than the (dummy) label.
- */
+ ssp->dss_first_bsd_slice = COMPATIBILITY_SLICE;
+ ssp->dss_nslices = BASE_SLICE;
sp = &ssp->dss_slices[0];
- bzero(sp, sizeof *sp);
- sp->ds_size = lp->d_secperunit;
- ssp->dss_nslices = 1;
+ bzero(sp, BASE_SLICE * sizeof *sp);
+ sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
/* Read master boot record. */
bp = geteblk((int)lp->d_secsize);
@@ -109,6 +107,7 @@ dsinit(dname, dev, strat, lp, sspp)
* Perhaps skip entries with 0 size.
* Perhaps only look at entries of type DOSPTYP_386BSD.
*/
+ max_ncyls = 0;
max_nsectors = 0;
max_ntracks = 0;
dp0 = (struct dos_partition *)(cp + DOSPARTOFF);
@@ -116,6 +115,9 @@ dsinit(dname, dev, strat, lp, sspp)
int nsectors;
int ntracks;
+ max_ncyls = DPCYL(dp->dp_ecyl, dp->dp_esect);
+ if (max_ncyls < max_ncyls)
+ max_ncyls = max_ncyls;
nsectors = DPSECT(dp->dp_esect);
if (max_nsectors < nsectors)
max_nsectors = nsectors;
@@ -129,7 +131,7 @@ dsinit(dname, dev, strat, lp, sspp)
* TODO:
* As above.
* Check for overlaps.
- * Check or adjust against d_ncylinders and d_secperunit.
+ * Check against d_secperunit if the latter is reliable.
*/
error = 0;
secpercyl = max_nsectors * max_ntracks;
@@ -169,39 +171,61 @@ dsinit(dname, dev, strat, lp, sspp)
/*
* We're not handling extended partitions yet, so there are always
- * 1 + NDOSPART slices.
+ * BASE_SLICE + NDOSPART slices.
*/
- if (dkslice(dev) >= 1 + NDOSPART) {
+ if (dkslice(dev) >= BASE_SLICE + NDOSPART) {
error = ENXIO;
goto done;
}
/*
* Accept the DOS partition table.
- * Free dummy slices "struct" and allocate a real new one.
+ * First adjust the label (we have been careful not to change it
+ * before we can guarantee success).
+ */
+ if (secpercyl != 0) {
+ u_long secperunit;
+
+ lp->d_nsectors = max_nsectors;
+ lp->d_ntracks = max_ntracks;
+ lp->d_secpercyl = secpercyl;
+ secperunit = secpercyl * max_ncyls;
+ if (lp->d_secperunit < secperunit)
+ lp->d_secperunit = secperunit;
+ }
+
+ /*
+ * Free the dummy slices "struct" and allocate a real new one.
+ * Initialize special slices as above.
*/
free(ssp, M_DEVBUF);
ssp = malloc(offsetof(struct diskslices, dss_slices)
- + (1 + NDOSPART) * sizeof(*sp), M_DEVBUF, M_WAITOK);
+ + (BASE_SLICE + NDOSPART) * sizeof *sp,
+ M_DEVBUF, M_WAITOK);
*sspp = ssp;
+ ssp->dss_first_bsd_slice = COMPATIBILITY_SLICE;
+ ssp->dss_nslices = BASE_SLICE + NDOSPART;
sp = &ssp->dss_slices[0];
- bzero(sp, (1 + NDOSPART) * sizeof *sp);
- sp->ds_size = lp->d_secperunit;
- sp++;
+ bzero(sp, (BASE_SLICE + NDOSPART) * sizeof *sp);
+ sp[WHOLE_DISK_SLICE].ds_size = lp->d_secperunit;
+
+ /* Initialize normal slices. */
+ sp += BASE_SLICE;
for (dp = dp0, slice = 1; slice <= NDOSPART; dp++, slice++, sp++) {
+ if (dp->dp_typ == DOSPTYP_386BSD
+ && ssp->dss_first_bsd_slice == COMPATIBILITY_SLICE) {
+ ssp->dss_first_bsd_slice = BASE_SLICE + slice - 1;
+ ssp->dss_slices[COMPATIBILITY_SLICE].ds_offset
+ = dp->dp_start;
+ ssp->dss_slices[COMPATIBILITY_SLICE].ds_size
+ = dp->dp_size;
+ }
sp->ds_offset = dp->dp_start;
sp->ds_size = dp->dp_size;
- }
- ssp->dss_nslices = 1 + NDOSPART;
- if (max_nsectors != 0) {
- lp->d_nsectors = max_nsectors;
- lp->d_ntracks = max_ntracks;
- lp->d_secpercyl = secpercyl;
- }
#if 0
- lp->d_secperunit = what?;
lp->d_subtype |= (lp->d_subtype & 3) + (slice - 1) | DSTYPE_INDOSPART;
#endif
+ }
done:
bp->b_flags = B_INVAL | B_AGE;
OpenPOWER on IntegriCloud