diff options
author | phk <phk@FreeBSD.org> | 1999-08-29 09:12:54 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1999-08-29 09:12:54 +0000 |
commit | 9f769de84a627ae63c179cfabe0189d8a2c305ca (patch) | |
tree | b058288c206255af340550232c57d1078b710999 /sys/pc98 | |
parent | e4ee1710042ac83d1d2a3ec52e8a211d1b4b8caf (diff) | |
download | FreeBSD-src-9f769de84a627ae63c179cfabe0189d8a2c305ca.zip FreeBSD-src-9f769de84a627ae63c179cfabe0189d8a2c305ca.tar.gz |
Merge alpha and pc98 changes into i386 MBR handling code and replace all
three copies with one copy in MI land.
Diffstat (limited to 'sys/pc98')
-rw-r--r-- | sys/pc98/conf/GENERIC | 2 | ||||
-rw-r--r-- | sys/pc98/conf/GENERIC98 | 2 | ||||
-rw-r--r-- | sys/pc98/conf/files.pc98 | 2 | ||||
-rw-r--r-- | sys/pc98/pc98/atcompat_diskslice.c | 464 |
4 files changed, 5 insertions, 465 deletions
diff --git a/sys/pc98/conf/GENERIC b/sys/pc98/conf/GENERIC index 02c3d89..66e7681 100644 --- a/sys/pc98/conf/GENERIC +++ b/sys/pc98/conf/GENERIC @@ -269,3 +269,5 @@ pseudo-device gzip # Exec gzipped a.out's # The `bpf' pseudo-device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! pseudo-device bpf #Berkeley packet filter + +pseudo-device compat_atdisk diff --git a/sys/pc98/conf/GENERIC98 b/sys/pc98/conf/GENERIC98 index 02c3d89..66e7681 100644 --- a/sys/pc98/conf/GENERIC98 +++ b/sys/pc98/conf/GENERIC98 @@ -269,3 +269,5 @@ pseudo-device gzip # Exec gzipped a.out's # The `bpf' pseudo-device enables the Berkeley Packet Filter. # Be aware of the administrative consequences of enabling this! pseudo-device bpf #Berkeley packet filter + +pseudo-device compat_atdisk diff --git a/sys/pc98/conf/files.pc98 b/sys/pc98/conf/files.pc98 index 4cf6390..b2c4dc3 100644 --- a/sys/pc98/conf/files.pc98 +++ b/sys/pc98/conf/files.pc98 @@ -180,7 +180,6 @@ i386/isa/ctx.c optional ctx i386/isa/cx.c optional cx i386/isa/cy.c optional cy pc98/pc98/diskslice_machdep.c standard -pc98/pc98/atcompat_diskslice.c optional compat_atdisk i386/isa/elink.c optional ep i386/isa/elink.c optional ie pc98/pc98/fd.c optional fd @@ -369,6 +368,7 @@ i4b/layer1/i4b_tel_s08.c optional isic i4b/layer1/i4b_tel_s0P.c optional isic i4b/layer1/i4b_usr_sti.c optional isic isa/psm.c optional psm +kern/subr_diskmbr.c optional compat_atdisk libkern/bcd.c standard libkern/divdi3.c standard libkern/index.c standard diff --git a/sys/pc98/pc98/atcompat_diskslice.c b/sys/pc98/pc98/atcompat_diskslice.c deleted file mode 100644 index 2bd03d0..0000000 --- a/sys/pc98/pc98/atcompat_diskslice.c +++ /dev/null @@ -1,464 +0,0 @@ -/*- - * Copyright (c) 1994 Bruce D. Evans. - * All rights reserved. - * - * Copyright (c) 1982, 1986, 1988 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * 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 $ - * $FreeBSD$ - */ - -/* - * atcompat_diskslice.c by KATO Takenori - * This file is created from diskslice_machdpe.c to support IBM-PC's HDD - * for FreeBSD(98). - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/buf.h> -#include <sys/conf.h> -#ifdef PC98 -#undef PC98 -#endif -#include <sys/disklabel.h> -#define DOSPTYP_EXTENDED 5 -#define DOSPTYP_EXTENDEDX 15 -#define DOSPTYP_ONTRACK 84 -#define PC98 -#include <sys/diskslice.h> -#include <sys/malloc.h> -#include <sys/syslog.h> - -#define TRACE(str) do { if (dsi_debug) printf str; } while (0) - -static volatile u_char dsi_debug; - -static struct dos_partition historical_bogus_partition_table[NDOSPART] = { - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, - { 0x80, 0, 1, 0, DOSPTYP_386BSD, 255, 255, 255, 0, 50000, }, -}; - -static int check_part __P((char *sname, struct dos_partition *dp, - u_long offset, int nsectors, int ntracks, - u_long mbr_offset)); -static void atcompat_extended __P((char *dname, dev_t dev, - struct disklabel *lp, struct diskslices *ssp, - u_long ext_offset, u_long ext_size, - u_long base_ext_offset, int nsectors, int ntracks, - u_long mbr_offset)); - -static int -check_part(sname, dp, offset, nsectors, ntracks, mbr_offset ) - char *sname; - struct dos_partition *dp; - u_long offset; - int nsectors; - int ntracks; - u_long mbr_offset; -{ - int chs_ecyl; - int chs_esect; - int chs_scyl; - int chs_ssect; - int error; - u_long esector; - u_long esector1; - u_long secpercyl; - u_long ssector; - u_long ssector1; - - secpercyl = (u_long)nsectors * ntracks; - chs_scyl = DPCYL(dp->dp_scyl, dp->dp_ssect); - chs_ssect = DPSECT(dp->dp_ssect); - ssector = chs_ssect - 1 + dp->dp_shd * nsectors + chs_scyl * secpercyl - + mbr_offset; - ssector1 = offset + dp->dp_start; - - /* - * If ssector1 is on a cylinder >= 1024, then ssector can't be right. - * Allow the C/H/S for it to be 1023/ntracks-1/nsectors, or correct - * apart from the cylinder being reduced modulo 1024. Always allow - * 1023/255/63. - */ - if ((ssector < ssector1 - && ((chs_ssect == nsectors && dp->dp_shd == ntracks - 1 - && chs_scyl == 1023) - || (secpercyl != 0 - && (ssector1 - ssector) % (1024 * secpercyl) == 0))) - || (dp->dp_scyl == 255 && dp->dp_shd == 255 - && dp->dp_ssect == 255)) { - TRACE(("%s: C/H/S start %d/%d/%d, start %lu: allow\n", - sname, chs_scyl, dp->dp_shd, chs_ssect, ssector1)); - ssector = ssector1; - } - - chs_ecyl = DPCYL(dp->dp_ecyl, dp->dp_esect); - chs_esect = DPSECT(dp->dp_esect); - esector = chs_esect - 1 + dp->dp_ehd * nsectors + chs_ecyl * secpercyl - + mbr_offset; - esector1 = ssector1 + dp->dp_size - 1; - - /* Allow certain bogus C/H/S values for esector, as above. */ - if ((esector < esector1 - && ((chs_esect == nsectors && dp->dp_ehd == ntracks - 1 - && chs_ecyl == 1023) - || (secpercyl != 0 - && (esector1 - esector) % (1024 * secpercyl) == 0))) - || (dp->dp_ecyl == 255 && dp->dp_ehd == 255 - && dp->dp_esect == 255)) { - TRACE(("%s: C/H/S end %d/%d/%d, end %lu: allow\n", - sname, chs_ecyl, dp->dp_ehd, chs_esect, esector1)); - esector = esector1; - } - - error = (ssector == ssector1 && esector == esector1) ? 0 : EINVAL; - if (bootverbose) - printf("%s: type 0x%x, start %lu, end = %lu, size %lu %s\n", - sname, dp->dp_typ, ssector1, esector1, - (u_long)dp->dp_size, error ? "" : ": OK"); - if (ssector != ssector1 && bootverbose) - printf("%s: C/H/S start %d/%d/%d (%lu) != start %lu: invalid\n", - sname, chs_scyl, dp->dp_shd, chs_ssect, - ssector, ssector1); - if (esector != esector1 && bootverbose) - printf("%s: C/H/S end %d/%d/%d (%lu) != end %lu: invalid\n", - sname, chs_ecyl, dp->dp_ehd, chs_esect, - esector, esector1); - return (error); -} - -int atcompat_dsinit __P((char *dname, dev_t dev, struct disklabel *lp, struct diskslices **sspp)); -int -atcompat_dsinit(dname, dev, lp, sspp) - char *dname; - dev_t dev; - struct disklabel *lp; - struct diskslices **sspp; -{ - struct buf *bp; - u_char *cp; - int dospart; - struct dos_partition *dp; - struct dos_partition *dp0; - int error; - int max_ncyls; - int max_nsectors; - int max_ntracks; - u_long mbr_offset; - char partname[2]; - u_long secpercyl; - char *sname; - struct diskslice *sp; - struct diskslices *ssp; - - mbr_offset = DOSBBSECTOR; -reread_mbr: - /* Read master boot record. */ - bp = geteblk((int)lp->d_secsize); - bp->b_dev = dkmodpart(dkmodslice(dev, WHOLE_DISK_SLICE), RAW_PART); - bp->b_blkno = mbr_offset; - bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_READ; - BUF_STRATEGY(bp, 1); - if (biowait(bp) != 0) { - diskerr(bp, dname, "error reading primary partition table", - LOG_PRINTF, 0, (struct disklabel *)NULL); - printf("\n"); - error = EIO; - goto done; - } - - /* Weakly verify it. */ - cp = bp->b_data; - sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART, - partname); - if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) { - if (bootverbose) - printf("%s: invalid primary partition table: no magic\n", - sname); - error = EINVAL; - goto done; - } - dp0 = (struct dos_partition *)(cp + DOSPARTOFF); - - /* Check for "Ontrack Diskmanager". */ - for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) { - if (dp->dp_typ == DOSPTYP_ONTRACK) { - if (bootverbose) - printf( - "%s: Found \"Ontrack Disk Manager\" on this disk.\n", sname); - bp->b_flags |= B_INVAL | B_AGE; - brelse(bp); - mbr_offset = 63; - goto reread_mbr; - } - } - - if (bcmp(dp0, historical_bogus_partition_table, - sizeof historical_bogus_partition_table) == 0) { - TRACE(("%s: invalid primary partition table: historical\n", - sname)); - error = EINVAL; - goto done; - } - - /* Guess the geometry. */ - /* - * TODO: - * Perhaps skip entries with 0 size. - * Perhaps only look at entries of type DOSPTYP_386BSD. - */ - max_ncyls = 0; - max_nsectors = 0; - max_ntracks = 0; - for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) { - int ncyls; - int nsectors; - int ntracks; - - ncyls = DPCYL(dp->dp_ecyl, dp->dp_esect) + 1; - if (max_ncyls < ncyls) - max_ncyls = ncyls; - nsectors = DPSECT(dp->dp_esect); - if (max_nsectors < nsectors) - max_nsectors = nsectors; - ntracks = dp->dp_ehd + 1; - if (max_ntracks < ntracks) - max_ntracks = ntracks; - } - - /* - * Check that we have guessed the geometry right by checking the - * partition entries. - */ - /* - * TODO: - * As above. - * Check for overlaps. - * Check against d_secperunit if the latter is reliable. - */ - error = 0; - for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++) { - if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0 - && dp->dp_start == 0 && dp->dp_size == 0) - continue; - sname = dsname(dev, dkunit(dev), BASE_SLICE + dospart, - RAW_PART, partname); - - /* - * Temporarily ignore errors from this check. We could - * simplify things by accepting the table eariler if we - * always ignore errors here. Perhaps we should always - * accept the table if the magic is right but not let - * bad entries affect the geometry. - */ - check_part(sname, dp, mbr_offset, max_nsectors, max_ntracks, - mbr_offset); - } - if (error != 0) - goto done; - - /* - * Accept the DOS partition table. - * First adjust the label (we have been careful not to change it - * before we can guarantee success). - */ - secpercyl = (u_long)max_nsectors * max_ntracks; - 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; - lp->d_ncylinders = lp->d_secperunit / secpercyl; - } - - /* - * We are passed a pointer to a suitably initialized minimal - * slices "struct" with no dangling pointers in it. Replace it - * by a maximal one. This usually oversizes the "struct", but - * enlarging it while searching for logical drives would be - * inconvenient. - */ - free(*sspp, M_DEVBUF); - ssp = dsmakeslicestruct(MAX_SLICES, lp); - *sspp = ssp; - - /* Initialize normal slices. */ - sp = &ssp->dss_slices[BASE_SLICE]; - for (dospart = 0, dp = dp0; dospart < NDOSPART; dospart++, dp++, sp++) { - sp->ds_offset = mbr_offset + dp->dp_start; - sp->ds_size = dp->dp_size; - sp->ds_type = dp->dp_typ; -#ifdef PC98 - /* fake up FreeBSD(98) */ - if (sp->ds_type == DOSPTYP_386BSD) - sp->ds_type = 0x94; -#endif -#if 0 - lp->d_subtype |= (lp->d_subtype & 3) | dospart - | DSTYPE_INDOSPART; -#endif - } - ssp->dss_nslices = BASE_SLICE + NDOSPART; - - /* Handle extended partitions. */ - sp -= NDOSPART; - for (dospart = 0; dospart < NDOSPART; dospart++, sp++) - if (sp->ds_type == DOSPTYP_EXTENDED || - sp->ds_type == DOSPTYP_EXTENDEDX) - atcompat_extended(dname, bp->b_dev, lp, ssp, - sp->ds_offset, sp->ds_size, sp->ds_offset, - max_nsectors, max_ntracks, mbr_offset); - -done: - bp->b_flags |= B_INVAL | B_AGE; - brelse(bp); - if (error == EINVAL) - error = 0; - return (error); -} - -static void -atcompat_extended(dname, dev, lp, ssp, ext_offset, ext_size, base_ext_offset, - nsectors, ntracks, mbr_offset) - char *dname; - dev_t dev; - struct disklabel *lp; - struct diskslices *ssp; - u_long ext_offset; - u_long ext_size; - u_long base_ext_offset; - int nsectors; - int ntracks; - u_long mbr_offset; -{ - struct buf *bp; - u_char *cp; - int dospart; - struct dos_partition *dp; - u_long ext_offsets[NDOSPART]; - u_long ext_sizes[NDOSPART]; - char partname[2]; - int slice; - char *sname; - struct diskslice *sp; - - /* Read extended boot record. */ - bp = geteblk((int)lp->d_secsize); - bp->b_dev = dev; - bp->b_blkno = ext_offset; - bp->b_bcount = lp->d_secsize; - bp->b_flags |= B_READ; - BUF_STRATEGY(bp, 1); - if (biowait(bp) != 0) { - diskerr(bp, dname, "error reading extended partition table", - LOG_PRINTF, 0, (struct disklabel *)NULL); - printf("\n"); - goto done; - } - - /* Weakly verify it. */ - cp = bp->b_data; - if (cp[0x1FE] != 0x55 || cp[0x1FF] != 0xAA) { - sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, RAW_PART, - partname); - if (bootverbose) - printf("%s: invalid extended partition table: no magic\n", - sname); - goto done; - } - - for (dospart = 0, - dp = (struct dos_partition *)(bp->b_data + DOSPARTOFF), - slice = ssp->dss_nslices, sp = &ssp->dss_slices[slice]; - dospart < NDOSPART; dospart++, dp++) { - ext_sizes[dospart] = 0; - if (dp->dp_scyl == 0 && dp->dp_shd == 0 && dp->dp_ssect == 0 - && dp->dp_start == 0 && dp->dp_size == 0) - continue; - if (dp->dp_typ == DOSPTYP_EXTENDED || - dp->dp_typ == DOSPTYP_EXTENDEDX) { - char buf[32]; - - sname = dsname(dev, dkunit(dev), WHOLE_DISK_SLICE, - RAW_PART, partname); - snprintf(buf, sizeof(buf), "%s", sname); - if (strlen(buf) < sizeof buf - 11) - strcat(buf, "<extended>"); - check_part(buf, dp, base_ext_offset, nsectors, - ntracks, mbr_offset); - ext_offsets[dospart] = base_ext_offset + dp->dp_start; - ext_sizes[dospart] = dp->dp_size; - } else { - sname = dsname(dev, dkunit(dev), slice, RAW_PART, - partname); - check_part(sname, dp, ext_offset, nsectors, ntracks, - mbr_offset); - if (slice >= MAX_SLICES) { - printf("%s: too many slices\n", sname); - slice++; - continue; - } - sp->ds_offset = ext_offset + dp->dp_start; - sp->ds_size = dp->dp_size; - sp->ds_type = dp->dp_typ; -#ifdef PC98 - /* fake up FreeBSD(98) */ - if (sp->ds_type == DOSPTYP_386BSD) - sp->ds_type = 0x94; -#endif - ssp->dss_nslices++; - slice++; - sp++; - } - } - - /* If we found any more slices, recursively find all the subslices. */ - for (dospart = 0; dospart < NDOSPART; dospart++) - if (ext_sizes[dospart] != 0) - atcompat_extended(dname, dev, lp, ssp, - ext_offsets[dospart], ext_sizes[dospart], - base_ext_offset, nsectors, ntracks, - mbr_offset); - -done: - bp->b_flags |= B_INVAL | B_AGE; - brelse(bp); -} |