1*c20fcc6fSjdc /* $NetBSD: disksubr.c,v 1.17 2020/05/03 06:31:02 jdc Exp $ */
26fb817f5Sbouyer
36fb817f5Sbouyer /*
46fb817f5Sbouyer * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
56fb817f5Sbouyer * All rights reserved.
66fb817f5Sbouyer *
76fb817f5Sbouyer * Redistribution and use in source and binary forms, with or without
86fb817f5Sbouyer * modification, are permitted provided that the following conditions
96fb817f5Sbouyer * are met:
106fb817f5Sbouyer * 1. Redistributions of source code must retain the above copyright
116fb817f5Sbouyer * notice, this list of conditions and the following disclaimer.
126fb817f5Sbouyer * 2. Redistributions in binary form must reproduce the above copyright
136fb817f5Sbouyer * notice, this list of conditions and the following disclaimer in the
146fb817f5Sbouyer * documentation and/or other materials provided with the distribution.
156fb817f5Sbouyer * 3. Neither the name of the University nor the names of its contributors
166fb817f5Sbouyer * may be used to endorse or promote products derived from this software
176fb817f5Sbouyer * without specific prior written permission.
186fb817f5Sbouyer * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
196fb817f5Sbouyer * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
206fb817f5Sbouyer * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
216fb817f5Sbouyer * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
226fb817f5Sbouyer * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
236fb817f5Sbouyer * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
246fb817f5Sbouyer * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
256fb817f5Sbouyer * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
266fb817f5Sbouyer * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
276fb817f5Sbouyer * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
286fb817f5Sbouyer * SUCH DAMAGE.
296fb817f5Sbouyer */
306fb817f5Sbouyer
316fb817f5Sbouyer /*
326fb817f5Sbouyer * Copyright (c) 1994, 1995 Gordon W. Ross
336fb817f5Sbouyer * Copyright (c) 1994 Theo de Raadt
346fb817f5Sbouyer * All rights reserved.
356fb817f5Sbouyer *
366fb817f5Sbouyer * Redistribution and use in source and binary forms, with or without
376fb817f5Sbouyer * modification, are permitted provided that the following conditions
386fb817f5Sbouyer * are met:
396fb817f5Sbouyer * 1. Redistributions of source code must retain the above copyright
406fb817f5Sbouyer * notice, this list of conditions and the following disclaimer.
416fb817f5Sbouyer * 2. Redistributions in binary form must reproduce the above copyright
426fb817f5Sbouyer * notice, this list of conditions and the following disclaimer in the
436fb817f5Sbouyer * documentation and/or other materials provided with the distribution.
446fb817f5Sbouyer *
456fb817f5Sbouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
466fb817f5Sbouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
476fb817f5Sbouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
486fb817f5Sbouyer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
496fb817f5Sbouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
506fb817f5Sbouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
516fb817f5Sbouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
526fb817f5Sbouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
536fb817f5Sbouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
546fb817f5Sbouyer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
556fb817f5Sbouyer */
566fb817f5Sbouyer
576fb817f5Sbouyer #include <sys/cdefs.h>
58*c20fcc6fSjdc __KERNEL_RCSID(0, "$NetBSD: disksubr.c,v 1.17 2020/05/03 06:31:02 jdc Exp $");
596fb817f5Sbouyer
606fb817f5Sbouyer #include <sys/param.h>
616fb817f5Sbouyer #include <sys/systm.h>
626fb817f5Sbouyer #include <sys/buf.h>
636fb817f5Sbouyer #include <sys/ioccom.h>
646fb817f5Sbouyer #include <sys/device.h>
656fb817f5Sbouyer #include <sys/disklabel.h>
666fb817f5Sbouyer #include <sys/disk.h>
676fb817f5Sbouyer #include <sys/dkbad.h>
686fb817f5Sbouyer
696fb817f5Sbouyer #include <dev/sun/disklabel.h>
706fb817f5Sbouyer
716fb817f5Sbouyer #if LABELSECTOR != 0
726fb817f5Sbouyer #error "Default value of LABELSECTOR no longer zero?"
736fb817f5Sbouyer #endif
746fb817f5Sbouyer
75309409f7Schristos static const char *disklabel_sun_to_bsd(char *, struct disklabel *);
7618db93c7Sperry static int disklabel_bsd_to_sun(struct disklabel *, char *);
776fb817f5Sbouyer
786fb817f5Sbouyer /*
796fb817f5Sbouyer * Attempt to read a disk label from a device
806fb817f5Sbouyer * using the indicated strategy routine.
816fb817f5Sbouyer * The label must be partly set up before this:
826fb817f5Sbouyer * secpercyl, secsize and anything required for a block i/o read
836fb817f5Sbouyer * operation in the driver's strategy/start routines
846fb817f5Sbouyer * must be filled in before calling us.
856fb817f5Sbouyer *
866fb817f5Sbouyer * Return buffer for use in signalling errors if requested.
876fb817f5Sbouyer *
886fb817f5Sbouyer * Returns null on success and an error string on failure.
896fb817f5Sbouyer */
906fb817f5Sbouyer const char *
readdisklabel(dev_t dev,void (* strat)(struct buf *),struct disklabel * lp,struct cpu_disklabel * clp)917cc9af7dSdsl readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *clp)
926fb817f5Sbouyer {
936fb817f5Sbouyer struct buf *bp;
946fb817f5Sbouyer struct disklabel *dlp;
956fb817f5Sbouyer struct sun_disklabel *slp;
966fb817f5Sbouyer int error;
976fb817f5Sbouyer
986fb817f5Sbouyer /* minimal requirements for archtypal disk label */
996fb817f5Sbouyer if (lp->d_secperunit == 0)
1006fb817f5Sbouyer lp->d_secperunit = 0x1fffffff;
1016fb817f5Sbouyer if (lp->d_npartitions == 0) {
1026fb817f5Sbouyer lp->d_npartitions = RAW_PART + 1;
1036fb817f5Sbouyer if (lp->d_partitions[RAW_PART].p_size == 0)
1046fb817f5Sbouyer lp->d_partitions[RAW_PART].p_size = 0x1fffffff;
1056fb817f5Sbouyer lp->d_partitions[RAW_PART].p_offset = 0;
1066fb817f5Sbouyer }
107*c20fcc6fSjdc if (lp->d_secsize == 0)
108*c20fcc6fSjdc return ("sector size 0");
1096fb817f5Sbouyer
1106fb817f5Sbouyer /* obtain buffer to probe drive with */
1116fb817f5Sbouyer bp = geteblk((int)lp->d_secsize);
1126fb817f5Sbouyer
1136fb817f5Sbouyer /* next, dig out disk label */
1146fb817f5Sbouyer bp->b_dev = dev;
1156fb817f5Sbouyer bp->b_blkno = LABELSECTOR;
1166fb817f5Sbouyer bp->b_cylinder = 0;
1176fb817f5Sbouyer bp->b_bcount = lp->d_secsize;
1186fb817f5Sbouyer bp->b_flags |= B_READ;
1196fb817f5Sbouyer (*strat)(bp);
1206fb817f5Sbouyer
1216fb817f5Sbouyer /* if successful, locate disk label within block and validate */
1226fb817f5Sbouyer error = biowait(bp);
1236fb817f5Sbouyer if (error == 0) {
1246fb817f5Sbouyer /* Save the whole block in case it has info we need. */
1256fb817f5Sbouyer memcpy(clp->cd_block, bp->b_data, sizeof(clp->cd_block));
1266fb817f5Sbouyer }
127c97e9c4eSad brelse(bp, 0);
1286fb817f5Sbouyer if (error)
1296fb817f5Sbouyer return ("disk label read error");
1306fb817f5Sbouyer
1316fb817f5Sbouyer /* Check for a NetBSD disk label at LABELOFFSET */
1326fb817f5Sbouyer dlp = (struct disklabel *) (clp->cd_block + LABELOFFSET);
1336fb817f5Sbouyer if (dlp->d_magic == DISKMAGIC) {
1346fb817f5Sbouyer if (dkcksum(dlp))
1356fb817f5Sbouyer return ("NetBSD disk label corrupted");
1366fb817f5Sbouyer *lp = *dlp;
1376fb817f5Sbouyer return (NULL);
1386fb817f5Sbouyer }
1396fb817f5Sbouyer
1406fb817f5Sbouyer /* Check for a Sun disk label (for PROM compatibility). */
1416fb817f5Sbouyer slp = (struct sun_disklabel *) clp->cd_block;
1426fb817f5Sbouyer if (slp->sl_magic == SUN_DKMAGIC)
1436fb817f5Sbouyer return (disklabel_sun_to_bsd(clp->cd_block, lp));
1446fb817f5Sbouyer
1456fb817f5Sbouyer /*
1466fb817f5Sbouyer * Check for a NetBSD disk label somewhere in LABELSECTOR
1476fb817f5Sbouyer * (compat with others big-endian boxes)
1486fb817f5Sbouyer */
1496fb817f5Sbouyer for (dlp = (struct disklabel *)clp->cd_block;
1506fb817f5Sbouyer dlp <= (struct disklabel *)((char *)clp->cd_block +
1516fb817f5Sbouyer DEV_BSIZE - sizeof(*dlp));
1526fb817f5Sbouyer dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
1536fb817f5Sbouyer if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
1546fb817f5Sbouyer continue;
1556fb817f5Sbouyer }
1566fb817f5Sbouyer if (dlp->d_npartitions > MAXPARTITIONS || dkcksum(dlp) != 0)
1576fb817f5Sbouyer return("NetBSD disk label corrupted");
1586fb817f5Sbouyer else {
1596fb817f5Sbouyer *lp = *dlp;
1606fb817f5Sbouyer return(NULL);
1616fb817f5Sbouyer }
1626fb817f5Sbouyer }
1636fb817f5Sbouyer
1646fb817f5Sbouyer memset(clp->cd_block, 0, sizeof(clp->cd_block));
165b9dbf5baSmartin return NULL;
1666fb817f5Sbouyer }
1676fb817f5Sbouyer
1686fb817f5Sbouyer /*
1696fb817f5Sbouyer * Write disk label back to device after modification.
1706fb817f5Sbouyer * Current label is already in clp->cd_block[]
1716fb817f5Sbouyer */
1726fb817f5Sbouyer int
writedisklabel(dev_t dev,void (* strat)(struct buf *),struct disklabel * lp,struct cpu_disklabel * clp)1737cc9af7dSdsl writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *clp)
1746fb817f5Sbouyer {
1756fb817f5Sbouyer struct buf *bp;
1766fb817f5Sbouyer int error;
1776fb817f5Sbouyer struct disklabel *dlp;
1786fb817f5Sbouyer struct sun_disklabel *slp;
1796fb817f5Sbouyer
1806fb817f5Sbouyer /*
1816fb817f5Sbouyer * Embed native label in a piece of wasteland.
1826fb817f5Sbouyer */
1836fb817f5Sbouyer if (sizeof(struct disklabel) > sizeof slp->sl_bsdlabel)
1846fb817f5Sbouyer return EFBIG;
1856fb817f5Sbouyer
1866fb817f5Sbouyer slp = (struct sun_disklabel *)clp->cd_block;
1876fb817f5Sbouyer memset(slp->sl_bsdlabel, 0, sizeof(slp->sl_bsdlabel));
1886fb817f5Sbouyer dlp = (struct disklabel *)slp->sl_bsdlabel;
1896fb817f5Sbouyer *dlp = *lp;
1906fb817f5Sbouyer
1916fb817f5Sbouyer /* Build a SunOS compatible label around the native label */
1926fb817f5Sbouyer error = disklabel_bsd_to_sun(lp, clp->cd_block);
1936fb817f5Sbouyer if (error)
1946fb817f5Sbouyer return (error);
1956fb817f5Sbouyer
1966fb817f5Sbouyer /* Get a buffer and copy the new label into it. */
1976fb817f5Sbouyer bp = geteblk((int)lp->d_secsize);
1986fb817f5Sbouyer memcpy(bp->b_data, clp->cd_block, sizeof(clp->cd_block));
1996fb817f5Sbouyer
2006fb817f5Sbouyer /* Write out the updated label. */
2016fb817f5Sbouyer bp->b_dev = dev;
2026fb817f5Sbouyer bp->b_blkno = LABELSECTOR;
2036fb817f5Sbouyer bp->b_cylinder = 0;
2046fb817f5Sbouyer bp->b_bcount = lp->d_secsize;
2056fb817f5Sbouyer bp->b_flags |= B_WRITE;
2066fb817f5Sbouyer (*strat)(bp);
2076fb817f5Sbouyer error = biowait(bp);
208c97e9c4eSad brelse(bp, 0);
2096fb817f5Sbouyer
2106fb817f5Sbouyer return (error);
2116fb817f5Sbouyer }
2126fb817f5Sbouyer
2136fb817f5Sbouyer /************************************************************************
2146fb817f5Sbouyer *
2156fb817f5Sbouyer * The rest of this was taken from arch/sparc/scsi/sun_disklabel.c
2166fb817f5Sbouyer * and then substantially rewritten by Gordon W. Ross
2176fb817f5Sbouyer *
2186fb817f5Sbouyer ************************************************************************/
2196fb817f5Sbouyer
2206fb817f5Sbouyer /* What partition types to assume for Sun disklabels: */
2216fb817f5Sbouyer static u_char
2226fb817f5Sbouyer sun_fstypes[8] = {
2236fb817f5Sbouyer FS_BSDFFS, /* a */
2246fb817f5Sbouyer FS_SWAP, /* b */
2256fb817f5Sbouyer FS_OTHER, /* c - whole disk */
2266fb817f5Sbouyer FS_BSDFFS, /* d */
2276fb817f5Sbouyer FS_BSDFFS, /* e */
2286fb817f5Sbouyer FS_BSDFFS, /* f */
2296fb817f5Sbouyer FS_BSDFFS, /* g */
2306fb817f5Sbouyer FS_BSDFFS, /* h */
2316fb817f5Sbouyer };
2326fb817f5Sbouyer
2336fb817f5Sbouyer /*
2346fb817f5Sbouyer * Given a SunOS disk label, set lp to a BSD disk label.
2356fb817f5Sbouyer * Returns NULL on success, else an error string.
2366fb817f5Sbouyer *
2376fb817f5Sbouyer * The BSD label is cleared out before this is called.
2386fb817f5Sbouyer */
239f1faf374Schristos static const char *
disklabel_sun_to_bsd(char * cp,struct disklabel * lp)240454af1c0Sdsl disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
2416fb817f5Sbouyer {
2426fb817f5Sbouyer struct sun_disklabel *sl;
2436fb817f5Sbouyer struct partition *npp;
2446fb817f5Sbouyer struct sun_dkpart *spp;
2456fb817f5Sbouyer int i, secpercyl;
246d6bdba58Smartin unsigned int secpblck;
2476fb817f5Sbouyer u_short cksum, *sp1, *sp2;
2486fb817f5Sbouyer
2496fb817f5Sbouyer sl = (struct sun_disklabel *)cp;
2506fb817f5Sbouyer
2516fb817f5Sbouyer /* Verify the XOR check. */
2526fb817f5Sbouyer sp1 = (u_short *)sl;
2536fb817f5Sbouyer sp2 = (u_short *)(sl + 1);
2546fb817f5Sbouyer cksum = 0;
2556fb817f5Sbouyer while (sp1 < sp2)
2566fb817f5Sbouyer cksum ^= *sp1++;
2576fb817f5Sbouyer if (cksum != 0)
2586fb817f5Sbouyer return("SunOS disk label, bad checksum");
2596fb817f5Sbouyer
2606fb817f5Sbouyer /* Format conversion. */
2616fb817f5Sbouyer lp->d_magic = DISKMAGIC;
2626fb817f5Sbouyer lp->d_magic2 = DISKMAGIC;
2636fb817f5Sbouyer memcpy(lp->d_packname, sl->sl_text, sizeof(lp->d_packname));
2646fb817f5Sbouyer
265d6bdba58Smartin secpblck = lp->d_secsize / 512;
266d6bdba58Smartin if (secpblck == 0) secpblck = 1; /* can't happen */
2676fb817f5Sbouyer lp->d_secsize = 512;
2686fb817f5Sbouyer lp->d_nsectors = sl->sl_nsectors;
2696fb817f5Sbouyer lp->d_ntracks = sl->sl_ntracks;
2706fb817f5Sbouyer lp->d_ncylinders = sl->sl_ncylinders;
2716fb817f5Sbouyer
2726fb817f5Sbouyer secpercyl = sl->sl_nsectors * sl->sl_ntracks;
2736fb817f5Sbouyer lp->d_secpercyl = secpercyl;
2746fb817f5Sbouyer lp->d_secperunit = secpercyl * sl->sl_ncylinders;
2756fb817f5Sbouyer
2766fb817f5Sbouyer lp->d_sparespercyl = sl->sl_sparespercyl;
2776fb817f5Sbouyer lp->d_acylinders = sl->sl_acylinders;
2786fb817f5Sbouyer lp->d_rpm = sl->sl_rpm;
2796fb817f5Sbouyer lp->d_interleave = sl->sl_interleave;
2806fb817f5Sbouyer
2816fb817f5Sbouyer lp->d_npartitions = 8;
2826fb817f5Sbouyer /* These are as defined in <ufs/ffs/fs.h> */
2836fb817f5Sbouyer lp->d_bbsize = 8192; /* XXX */
2846fb817f5Sbouyer lp->d_sbsize = 8192; /* XXX */
2856fb817f5Sbouyer
2866fb817f5Sbouyer for (i = 0; i < 8; i++) {
2876fb817f5Sbouyer spp = &sl->sl_part[i];
2886fb817f5Sbouyer npp = &lp->d_partitions[i];
289d6bdba58Smartin
290238cb98aSmartin if (npp->p_fstype == FS_ISO9660
291d6bdba58Smartin && spp->sdkp_cyloffset * secpercyl == npp->p_offset*secpblck
292d6bdba58Smartin && spp->sdkp_nsectors <= npp->p_size*secpblck
293238cb98aSmartin && npp->p_size > 0 && spp->sdkp_nsectors > 0) {
294238cb98aSmartin /*
295238cb98aSmartin * This happens for example on sunlabel'd hybrid
296238cb98aSmartin * (ffs + ISO9660) CDs, like our install CDs.
297238cb98aSmartin * The cd driver has initialized a valid ISO9660
298238cb98aSmartin * partition (including session parameters), so
299238cb98aSmartin * we better not overwrite it.
300238cb98aSmartin */
301d6bdba58Smartin npp->p_offset *= secpblck;
302d6bdba58Smartin npp->p_size = spp->sdkp_nsectors;
303d6bdba58Smartin npp->p_cdsession *= secpblck;
304238cb98aSmartin continue;
305238cb98aSmartin }
3066fb817f5Sbouyer npp->p_offset = spp->sdkp_cyloffset * secpercyl;
3076fb817f5Sbouyer npp->p_size = spp->sdkp_nsectors;
3086fb817f5Sbouyer if (npp->p_size == 0) {
3096fb817f5Sbouyer npp->p_fstype = FS_UNUSED;
3106fb817f5Sbouyer } else {
3116fb817f5Sbouyer npp->p_fstype = sun_fstypes[i];
3126fb817f5Sbouyer if (npp->p_fstype == FS_BSDFFS) {
3136fb817f5Sbouyer /*
3146fb817f5Sbouyer * The sun label does not store the FFS fields,
3156fb817f5Sbouyer * so just set them with default values here.
3166fb817f5Sbouyer */
3176fb817f5Sbouyer npp->p_fsize = 1024;
3186fb817f5Sbouyer npp->p_frag = 8;
3196fb817f5Sbouyer npp->p_cpg = 16;
3206fb817f5Sbouyer }
3216fb817f5Sbouyer }
3226fb817f5Sbouyer }
3236fb817f5Sbouyer
3246fb817f5Sbouyer lp->d_checksum = 0;
3256fb817f5Sbouyer lp->d_checksum = dkcksum(lp);
3266fb817f5Sbouyer return (NULL);
3276fb817f5Sbouyer }
3286fb817f5Sbouyer
3296fb817f5Sbouyer /*
3306fb817f5Sbouyer * Given a BSD disk label, update the Sun disklabel
3316fb817f5Sbouyer * pointed to by cp with the new info. Note that the
3326fb817f5Sbouyer * Sun disklabel may have other info we need to keep.
3336fb817f5Sbouyer * Returns zero or error code.
3346fb817f5Sbouyer */
3356fb817f5Sbouyer static int
disklabel_bsd_to_sun(struct disklabel * lp,char * cp)336454af1c0Sdsl disklabel_bsd_to_sun(struct disklabel *lp, char *cp)
3376fb817f5Sbouyer {
3386fb817f5Sbouyer struct sun_disklabel *sl;
3396fb817f5Sbouyer struct partition *npp;
3406fb817f5Sbouyer struct sun_dkpart *spp;
3416fb817f5Sbouyer int i, secpercyl;
3426fb817f5Sbouyer u_short cksum, *sp1, *sp2;
3436fb817f5Sbouyer
3446fb817f5Sbouyer if (lp->d_secsize != 512)
3456fb817f5Sbouyer return (EINVAL);
3466fb817f5Sbouyer
3476fb817f5Sbouyer sl = (struct sun_disklabel *)cp;
3486fb817f5Sbouyer
3496fb817f5Sbouyer /*
3506fb817f5Sbouyer * Format conversion.
3516fb817f5Sbouyer */
3526fb817f5Sbouyer memcpy(sl->sl_text, lp->d_packname, sizeof(lp->d_packname));
3536fb817f5Sbouyer sl->sl_rpm = lp->d_rpm;
3546fb817f5Sbouyer sl->sl_pcylinders = lp->d_ncylinders + lp->d_acylinders; /* XXX */
3556fb817f5Sbouyer sl->sl_sparespercyl = lp->d_sparespercyl;
3566fb817f5Sbouyer sl->sl_interleave = lp->d_interleave;
3576fb817f5Sbouyer sl->sl_ncylinders = lp->d_ncylinders;
3586fb817f5Sbouyer sl->sl_acylinders = lp->d_acylinders;
3596fb817f5Sbouyer sl->sl_ntracks = lp->d_ntracks;
3606fb817f5Sbouyer sl->sl_nsectors = lp->d_nsectors;
3616fb817f5Sbouyer
3626fb817f5Sbouyer secpercyl = sl->sl_nsectors * sl->sl_ntracks;
3636fb817f5Sbouyer for (i = 0; i < 8; i++) {
3646fb817f5Sbouyer spp = &sl->sl_part[i];
3656fb817f5Sbouyer npp = &lp->d_partitions[i];
3666fb817f5Sbouyer
3676fb817f5Sbouyer /*
3686fb817f5Sbouyer * SunOS partitions must start on a cylinder boundary.
3696fb817f5Sbouyer * Note this restriction is forced upon NetBSD/sparc
3706fb817f5Sbouyer * labels too, since we want to keep both labels
3716fb817f5Sbouyer * synchronised.
3726fb817f5Sbouyer */
3736fb817f5Sbouyer if (npp->p_offset % secpercyl)
3746fb817f5Sbouyer return (EINVAL);
3756fb817f5Sbouyer spp->sdkp_cyloffset = npp->p_offset / secpercyl;
3766fb817f5Sbouyer spp->sdkp_nsectors = npp->p_size;
3776fb817f5Sbouyer }
3786fb817f5Sbouyer sl->sl_magic = SUN_DKMAGIC;
3796fb817f5Sbouyer
3806fb817f5Sbouyer /* Compute the XOR check. */
3816fb817f5Sbouyer sp1 = (u_short *)sl;
3826fb817f5Sbouyer sp2 = (u_short *)(sl + 1);
3836fb817f5Sbouyer sl->sl_cksum = cksum = 0;
3846fb817f5Sbouyer while (sp1 < sp2)
3856fb817f5Sbouyer cksum ^= *sp1++;
3866fb817f5Sbouyer sl->sl_cksum = cksum;
3876fb817f5Sbouyer
3886fb817f5Sbouyer return (0);
3896fb817f5Sbouyer }
3906fb817f5Sbouyer
3916fb817f5Sbouyer /*
3926fb817f5Sbouyer * Search the bad sector table looking for the specified sector.
3936fb817f5Sbouyer * Return index if found.
3946fb817f5Sbouyer * Return -1 if not found.
3956fb817f5Sbouyer */
3966fb817f5Sbouyer int
isbad(struct dkbad * bt,int cyl,int trk,int sec)39782357f6dSdsl isbad(struct dkbad *bt, int cyl, int trk, int sec)
3986fb817f5Sbouyer {
3996fb817f5Sbouyer int i;
4006fb817f5Sbouyer long blk, bblk;
4016fb817f5Sbouyer
4026fb817f5Sbouyer blk = ((long)cyl << 16) + (trk << 8) + sec;
4036fb817f5Sbouyer for (i = 0; i < 126; i++) {
4046fb817f5Sbouyer bblk = ((long)bt->bt_bad[i].bt_cyl << 16) +
4056fb817f5Sbouyer bt->bt_bad[i].bt_trksec;
4066fb817f5Sbouyer if (blk == bblk)
4076fb817f5Sbouyer return (i);
4086fb817f5Sbouyer if (blk < bblk || bblk < 0)
4096fb817f5Sbouyer break;
4106fb817f5Sbouyer }
4116fb817f5Sbouyer return (-1);
4126fb817f5Sbouyer }
413