Home | History | Annotate | Line # | Download | only in sun
disksubr.c revision 1.9.30.1
      1  1.9.30.1     skrll /*	$NetBSD: disksubr.c,v 1.9.30.1 2009/04/28 07:36:38 skrll Exp $ */
      2       1.1    bouyer 
      3       1.4     perry /*
      4       1.1    bouyer  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
      5       1.1    bouyer  * All rights reserved.
      6       1.1    bouyer  *
      7       1.1    bouyer  * Redistribution and use in source and binary forms, with or without
      8       1.1    bouyer  * modification, are permitted provided that the following conditions
      9       1.1    bouyer  * are met:
     10       1.1    bouyer  * 1. Redistributions of source code must retain the above copyright
     11       1.1    bouyer  *    notice, this list of conditions and the following disclaimer.
     12       1.1    bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     13       1.1    bouyer  *    notice, this list of conditions and the following disclaimer in the
     14       1.1    bouyer  *    documentation and/or other materials provided with the distribution.
     15       1.1    bouyer  * 3. Neither the name of the University nor the names of its contributors
     16       1.1    bouyer  *    may be used to endorse or promote products derived from this software
     17       1.1    bouyer  *    without specific prior written permission.
     18       1.1    bouyer  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     19       1.1    bouyer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     20       1.1    bouyer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     21       1.1    bouyer  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     22       1.1    bouyer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     23       1.1    bouyer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     24       1.1    bouyer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     25       1.1    bouyer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     26       1.1    bouyer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     27       1.1    bouyer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     28       1.1    bouyer  * SUCH DAMAGE.
     29       1.1    bouyer  */
     30       1.1    bouyer 
     31       1.1    bouyer /*
     32       1.1    bouyer  * Copyright (c) 1994, 1995 Gordon W. Ross
     33       1.1    bouyer  * Copyright (c) 1994 Theo de Raadt
     34       1.1    bouyer  * All rights reserved.
     35       1.1    bouyer  *
     36       1.1    bouyer  * Redistribution and use in source and binary forms, with or without
     37       1.1    bouyer  * modification, are permitted provided that the following conditions
     38       1.1    bouyer  * are met:
     39       1.1    bouyer  * 1. Redistributions of source code must retain the above copyright
     40       1.1    bouyer  *    notice, this list of conditions and the following disclaimer.
     41       1.1    bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     42       1.1    bouyer  *    notice, this list of conditions and the following disclaimer in the
     43       1.1    bouyer  *    documentation and/or other materials provided with the distribution.
     44       1.1    bouyer  *
     45       1.1    bouyer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     46       1.1    bouyer  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     47       1.1    bouyer  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     48       1.1    bouyer  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     49       1.1    bouyer  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     50       1.1    bouyer  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     51       1.1    bouyer  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     52       1.1    bouyer  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     53       1.1    bouyer  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     54       1.1    bouyer  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     55       1.1    bouyer  */
     56       1.1    bouyer 
     57       1.1    bouyer #include <sys/cdefs.h>
     58  1.9.30.1     skrll __KERNEL_RCSID(0, "$NetBSD: disksubr.c,v 1.9.30.1 2009/04/28 07:36:38 skrll Exp $");
     59       1.1    bouyer 
     60       1.1    bouyer #include <sys/param.h>
     61       1.1    bouyer #include <sys/systm.h>
     62       1.1    bouyer #include <sys/buf.h>
     63       1.1    bouyer #include <sys/ioccom.h>
     64       1.1    bouyer #include <sys/device.h>
     65       1.1    bouyer #include <sys/disklabel.h>
     66       1.1    bouyer #include <sys/disk.h>
     67       1.1    bouyer #include <sys/dkbad.h>
     68       1.1    bouyer 
     69       1.1    bouyer #include <dev/sun/disklabel.h>
     70       1.1    bouyer 
     71       1.1    bouyer #if LABELSECTOR != 0
     72       1.1    bouyer #error  "Default value of LABELSECTOR no longer zero?"
     73       1.1    bouyer #endif
     74       1.1    bouyer 
     75       1.6  christos static	const char *disklabel_sun_to_bsd(char *, struct disklabel *);
     76       1.3     perry static	int disklabel_bsd_to_sun(struct disklabel *, char *);
     77       1.1    bouyer 
     78       1.1    bouyer /*
     79       1.1    bouyer  * Attempt to read a disk label from a device
     80       1.1    bouyer  * using the indicated strategy routine.
     81       1.1    bouyer  * The label must be partly set up before this:
     82       1.1    bouyer  * secpercyl, secsize and anything required for a block i/o read
     83       1.1    bouyer  * operation in the driver's strategy/start routines
     84       1.1    bouyer  * must be filled in before calling us.
     85       1.1    bouyer  *
     86       1.1    bouyer  * Return buffer for use in signalling errors if requested.
     87       1.1    bouyer  *
     88       1.1    bouyer  * Returns null on success and an error string on failure.
     89       1.1    bouyer  */
     90       1.1    bouyer const char *
     91  1.9.30.1     skrll readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *clp)
     92       1.1    bouyer {
     93       1.1    bouyer 	struct buf *bp;
     94       1.1    bouyer 	struct disklabel *dlp;
     95       1.1    bouyer 	struct sun_disklabel *slp;
     96       1.1    bouyer 	int error;
     97       1.1    bouyer 
     98       1.1    bouyer 	/* minimal requirements for archtypal disk label */
     99       1.1    bouyer 	if (lp->d_secperunit == 0)
    100       1.1    bouyer 		lp->d_secperunit = 0x1fffffff;
    101       1.1    bouyer 	if (lp->d_npartitions == 0) {
    102       1.1    bouyer 		lp->d_npartitions = RAW_PART + 1;
    103       1.1    bouyer 		if (lp->d_partitions[RAW_PART].p_size == 0)
    104       1.1    bouyer 			lp->d_partitions[RAW_PART].p_size = 0x1fffffff;
    105       1.1    bouyer 		lp->d_partitions[RAW_PART].p_offset = 0;
    106       1.1    bouyer 	}
    107       1.1    bouyer 
    108       1.1    bouyer 	/* obtain buffer to probe drive with */
    109       1.1    bouyer 	bp = geteblk((int)lp->d_secsize);
    110       1.1    bouyer 
    111       1.1    bouyer 	/* next, dig out disk label */
    112       1.1    bouyer 	bp->b_dev = dev;
    113       1.1    bouyer 	bp->b_blkno = LABELSECTOR;
    114       1.1    bouyer 	bp->b_cylinder = 0;
    115       1.1    bouyer 	bp->b_bcount = lp->d_secsize;
    116       1.1    bouyer 	bp->b_flags |= B_READ;
    117       1.1    bouyer 	(*strat)(bp);
    118       1.1    bouyer 
    119       1.1    bouyer 	/* if successful, locate disk label within block and validate */
    120       1.1    bouyer 	error = biowait(bp);
    121       1.1    bouyer 	if (error == 0) {
    122       1.1    bouyer 		/* Save the whole block in case it has info we need. */
    123       1.1    bouyer 		memcpy(clp->cd_block, bp->b_data, sizeof(clp->cd_block));
    124       1.1    bouyer 	}
    125       1.9        ad 	brelse(bp, 0);
    126       1.1    bouyer 	if (error)
    127       1.1    bouyer 		return ("disk label read error");
    128       1.1    bouyer 
    129       1.1    bouyer 	/* Check for a NetBSD disk label at LABELOFFSET */
    130       1.1    bouyer 	dlp = (struct disklabel *) (clp->cd_block + LABELOFFSET);
    131       1.1    bouyer 	if (dlp->d_magic == DISKMAGIC) {
    132       1.1    bouyer 		if (dkcksum(dlp))
    133       1.1    bouyer 			return ("NetBSD disk label corrupted");
    134       1.1    bouyer 		*lp = *dlp;
    135       1.1    bouyer 		return (NULL);
    136       1.1    bouyer 	}
    137       1.1    bouyer 
    138       1.1    bouyer 	/* Check for a Sun disk label (for PROM compatibility). */
    139       1.1    bouyer 	slp = (struct sun_disklabel *) clp->cd_block;
    140       1.1    bouyer 	if (slp->sl_magic == SUN_DKMAGIC)
    141       1.1    bouyer 		return (disklabel_sun_to_bsd(clp->cd_block, lp));
    142       1.1    bouyer 
    143       1.1    bouyer 	/*
    144       1.1    bouyer 	 * Check for a NetBSD disk label somewhere in LABELSECTOR
    145       1.1    bouyer 	 * (compat with others big-endian boxes)
    146       1.1    bouyer 	 */
    147       1.1    bouyer 	for (dlp = (struct disklabel *)clp->cd_block;
    148       1.1    bouyer 	    dlp <= (struct disklabel *)((char *)clp->cd_block +
    149       1.1    bouyer 	    DEV_BSIZE - sizeof(*dlp));
    150       1.1    bouyer 	    dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
    151       1.1    bouyer 		if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
    152       1.1    bouyer 			continue;
    153       1.1    bouyer 		}
    154       1.1    bouyer 		if (dlp->d_npartitions > MAXPARTITIONS || dkcksum(dlp) != 0)
    155       1.1    bouyer 			return("NetBSD disk label corrupted");
    156       1.1    bouyer 		else {
    157       1.1    bouyer 			*lp = *dlp;
    158       1.1    bouyer 			return(NULL);
    159       1.1    bouyer 		}
    160       1.1    bouyer 	}
    161       1.1    bouyer 
    162       1.1    bouyer 	memset(clp->cd_block, 0, sizeof(clp->cd_block));
    163       1.1    bouyer 	return ("no disk label");
    164       1.1    bouyer }
    165       1.1    bouyer 
    166       1.1    bouyer /*
    167       1.1    bouyer  * Check new disk label for sensibility
    168       1.1    bouyer  * before setting it.
    169       1.1    bouyer  */
    170       1.1    bouyer int
    171  1.9.30.1     skrll setdisklabel(struct disklabel *olp, struct disklabel *nlp, u_long openmask, struct cpu_disklabel *clp)
    172       1.1    bouyer {
    173       1.1    bouyer 	int i;
    174       1.1    bouyer 	struct partition *opp, *npp;
    175       1.1    bouyer 
    176       1.1    bouyer 	/* sanity clause */
    177       1.1    bouyer 	if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0 ||
    178       1.1    bouyer 	    (nlp->d_secsize % DEV_BSIZE) != 0)
    179       1.1    bouyer 		return(EINVAL);
    180       1.1    bouyer 
    181       1.1    bouyer 	/* special case to allow disklabel to be invalidated */
    182       1.1    bouyer 	if (nlp->d_magic == 0xffffffff) {
    183       1.1    bouyer 		*olp = *nlp;
    184       1.1    bouyer 		return (0);
    185       1.1    bouyer 	}
    186       1.1    bouyer 
    187       1.1    bouyer 	if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
    188       1.1    bouyer 	    dkcksum(nlp) != 0)
    189       1.1    bouyer 		return (EINVAL);
    190       1.1    bouyer 
    191       1.1    bouyer 	while ((i = ffs(openmask)) != 0) {
    192       1.1    bouyer 		i--;
    193       1.1    bouyer 		openmask &= ~(1 << i);
    194       1.1    bouyer 		if (nlp->d_npartitions <= i)
    195       1.1    bouyer 			return (EBUSY);
    196       1.1    bouyer 		opp = &olp->d_partitions[i];
    197       1.1    bouyer 		npp = &nlp->d_partitions[i];
    198       1.1    bouyer 		if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size)
    199       1.1    bouyer 			return (EBUSY);
    200       1.1    bouyer 	}
    201       1.1    bouyer 
    202       1.1    bouyer 	*olp = *nlp;
    203       1.1    bouyer 	return (0);
    204       1.1    bouyer }
    205       1.1    bouyer 
    206       1.1    bouyer /*
    207       1.1    bouyer  * Write disk label back to device after modification.
    208       1.1    bouyer  * Current label is already in clp->cd_block[]
    209       1.1    bouyer  */
    210       1.1    bouyer int
    211  1.9.30.1     skrll writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp, struct cpu_disklabel *clp)
    212       1.1    bouyer {
    213       1.1    bouyer 	struct buf *bp;
    214       1.1    bouyer 	int error;
    215       1.1    bouyer 	struct disklabel *dlp;
    216       1.1    bouyer 	struct sun_disklabel *slp;
    217       1.1    bouyer 
    218       1.1    bouyer 	/*
    219       1.1    bouyer 	 * Embed native label in a piece of wasteland.
    220       1.1    bouyer 	 */
    221       1.1    bouyer 	if (sizeof(struct disklabel) > sizeof slp->sl_bsdlabel)
    222       1.1    bouyer 		return EFBIG;
    223       1.1    bouyer 
    224       1.1    bouyer 	slp = (struct sun_disklabel *)clp->cd_block;
    225       1.1    bouyer 	memset(slp->sl_bsdlabel, 0, sizeof(slp->sl_bsdlabel));
    226       1.1    bouyer 	dlp = (struct disklabel *)slp->sl_bsdlabel;
    227       1.1    bouyer 	*dlp = *lp;
    228       1.1    bouyer 
    229       1.1    bouyer 	/* Build a SunOS compatible label around the native label */
    230       1.1    bouyer 	error = disklabel_bsd_to_sun(lp, clp->cd_block);
    231       1.1    bouyer 	if (error)
    232       1.1    bouyer 		return (error);
    233       1.1    bouyer 
    234       1.1    bouyer 	/* Get a buffer and copy the new label into it. */
    235       1.1    bouyer 	bp = geteblk((int)lp->d_secsize);
    236       1.1    bouyer 	memcpy(bp->b_data, clp->cd_block, sizeof(clp->cd_block));
    237       1.1    bouyer 
    238       1.1    bouyer 	/* Write out the updated label. */
    239       1.1    bouyer 	bp->b_dev = dev;
    240       1.1    bouyer 	bp->b_blkno = LABELSECTOR;
    241       1.1    bouyer 	bp->b_cylinder = 0;
    242       1.1    bouyer 	bp->b_bcount = lp->d_secsize;
    243       1.1    bouyer 	bp->b_flags |= B_WRITE;
    244       1.1    bouyer 	(*strat)(bp);
    245       1.1    bouyer 	error = biowait(bp);
    246       1.9        ad 	brelse(bp, 0);
    247       1.1    bouyer 
    248       1.1    bouyer 	return (error);
    249       1.1    bouyer }
    250       1.1    bouyer 
    251       1.1    bouyer /************************************************************************
    252       1.1    bouyer  *
    253       1.1    bouyer  * The rest of this was taken from arch/sparc/scsi/sun_disklabel.c
    254       1.1    bouyer  * and then substantially rewritten by Gordon W. Ross
    255       1.1    bouyer  *
    256       1.1    bouyer  ************************************************************************/
    257       1.1    bouyer 
    258       1.1    bouyer /* What partition types to assume for Sun disklabels: */
    259       1.1    bouyer static u_char
    260       1.1    bouyer sun_fstypes[8] = {
    261       1.1    bouyer 	FS_BSDFFS,	/* a */
    262       1.1    bouyer 	FS_SWAP,	/* b */
    263       1.1    bouyer 	FS_OTHER,	/* c - whole disk */
    264       1.1    bouyer 	FS_BSDFFS,	/* d */
    265       1.1    bouyer 	FS_BSDFFS,	/* e */
    266       1.1    bouyer 	FS_BSDFFS,	/* f */
    267       1.1    bouyer 	FS_BSDFFS,	/* g */
    268       1.1    bouyer 	FS_BSDFFS,	/* h */
    269       1.1    bouyer };
    270       1.1    bouyer 
    271       1.1    bouyer /*
    272       1.1    bouyer  * Given a SunOS disk label, set lp to a BSD disk label.
    273       1.1    bouyer  * Returns NULL on success, else an error string.
    274       1.1    bouyer  *
    275       1.1    bouyer  * The BSD label is cleared out before this is called.
    276       1.1    bouyer  */
    277       1.5  christos static const char *
    278  1.9.30.1     skrll disklabel_sun_to_bsd(char *cp, struct disklabel *lp)
    279       1.1    bouyer {
    280       1.1    bouyer 	struct sun_disklabel *sl;
    281       1.1    bouyer 	struct partition *npp;
    282       1.1    bouyer 	struct sun_dkpart *spp;
    283       1.1    bouyer 	int i, secpercyl;
    284       1.1    bouyer 	u_short cksum, *sp1, *sp2;
    285       1.1    bouyer 
    286       1.1    bouyer 	sl = (struct sun_disklabel *)cp;
    287       1.1    bouyer 
    288       1.1    bouyer 	/* Verify the XOR check. */
    289       1.1    bouyer 	sp1 = (u_short *)sl;
    290       1.1    bouyer 	sp2 = (u_short *)(sl + 1);
    291       1.1    bouyer 	cksum = 0;
    292       1.1    bouyer 	while (sp1 < sp2)
    293       1.1    bouyer 		cksum ^= *sp1++;
    294       1.1    bouyer 	if (cksum != 0)
    295       1.1    bouyer 		return("SunOS disk label, bad checksum");
    296       1.1    bouyer 
    297       1.1    bouyer 	/* Format conversion. */
    298       1.1    bouyer 	lp->d_magic = DISKMAGIC;
    299       1.1    bouyer 	lp->d_magic2 = DISKMAGIC;
    300       1.1    bouyer 	memcpy(lp->d_packname, sl->sl_text, sizeof(lp->d_packname));
    301       1.1    bouyer 
    302       1.1    bouyer 	lp->d_secsize = 512;
    303       1.1    bouyer 	lp->d_nsectors   = sl->sl_nsectors;
    304       1.1    bouyer 	lp->d_ntracks    = sl->sl_ntracks;
    305       1.1    bouyer 	lp->d_ncylinders = sl->sl_ncylinders;
    306       1.1    bouyer 
    307       1.1    bouyer 	secpercyl = sl->sl_nsectors * sl->sl_ntracks;
    308       1.1    bouyer 	lp->d_secpercyl  = secpercyl;
    309       1.1    bouyer 	lp->d_secperunit = secpercyl * sl->sl_ncylinders;
    310       1.1    bouyer 
    311       1.1    bouyer 	lp->d_sparespercyl = sl->sl_sparespercyl;
    312       1.1    bouyer 	lp->d_acylinders   = sl->sl_acylinders;
    313       1.1    bouyer 	lp->d_rpm          = sl->sl_rpm;
    314       1.1    bouyer 	lp->d_interleave   = sl->sl_interleave;
    315       1.1    bouyer 
    316       1.1    bouyer 	lp->d_npartitions = 8;
    317       1.1    bouyer 	/* These are as defined in <ufs/ffs/fs.h> */
    318       1.1    bouyer 	lp->d_bbsize = 8192;	/* XXX */
    319       1.1    bouyer 	lp->d_sbsize = 8192;	/* XXX */
    320       1.1    bouyer 
    321       1.1    bouyer 	for (i = 0; i < 8; i++) {
    322       1.1    bouyer 		spp = &sl->sl_part[i];
    323       1.1    bouyer 		npp = &lp->d_partitions[i];
    324       1.1    bouyer 		npp->p_offset = spp->sdkp_cyloffset * secpercyl;
    325       1.1    bouyer 		npp->p_size = spp->sdkp_nsectors;
    326       1.1    bouyer 		if (npp->p_size == 0) {
    327       1.1    bouyer 			npp->p_fstype = FS_UNUSED;
    328       1.1    bouyer 		} else {
    329       1.1    bouyer 			npp->p_fstype = sun_fstypes[i];
    330       1.1    bouyer 			if (npp->p_fstype == FS_BSDFFS) {
    331       1.1    bouyer 				/*
    332       1.1    bouyer 				 * The sun label does not store the FFS fields,
    333       1.1    bouyer 				 * so just set them with default values here.
    334       1.1    bouyer 				 */
    335       1.1    bouyer 				npp->p_fsize = 1024;
    336       1.1    bouyer 				npp->p_frag = 8;
    337       1.1    bouyer 				npp->p_cpg = 16;
    338       1.1    bouyer 			}
    339       1.1    bouyer 		}
    340       1.1    bouyer 	}
    341       1.1    bouyer 
    342       1.1    bouyer 	lp->d_checksum = 0;
    343       1.1    bouyer 	lp->d_checksum = dkcksum(lp);
    344       1.1    bouyer 	return (NULL);
    345       1.1    bouyer }
    346       1.1    bouyer 
    347       1.1    bouyer /*
    348       1.1    bouyer  * Given a BSD disk label, update the Sun disklabel
    349       1.1    bouyer  * pointed to by cp with the new info.  Note that the
    350       1.1    bouyer  * Sun disklabel may have other info we need to keep.
    351       1.1    bouyer  * Returns zero or error code.
    352       1.1    bouyer  */
    353       1.1    bouyer static int
    354  1.9.30.1     skrll disklabel_bsd_to_sun(struct disklabel *lp, char *cp)
    355       1.1    bouyer {
    356       1.1    bouyer 	struct sun_disklabel *sl;
    357       1.1    bouyer 	struct partition *npp;
    358       1.1    bouyer 	struct sun_dkpart *spp;
    359       1.1    bouyer 	int i, secpercyl;
    360       1.1    bouyer 	u_short cksum, *sp1, *sp2;
    361       1.1    bouyer 
    362       1.1    bouyer 	if (lp->d_secsize != 512)
    363       1.1    bouyer 		return (EINVAL);
    364       1.1    bouyer 
    365       1.1    bouyer 	sl = (struct sun_disklabel *)cp;
    366       1.1    bouyer 
    367       1.1    bouyer 	/*
    368       1.1    bouyer 	 * Format conversion.
    369       1.1    bouyer 	 */
    370       1.1    bouyer 	memcpy(sl->sl_text, lp->d_packname, sizeof(lp->d_packname));
    371       1.1    bouyer 	sl->sl_rpm = lp->d_rpm;
    372       1.1    bouyer 	sl->sl_pcylinders   = lp->d_ncylinders + lp->d_acylinders; /* XXX */
    373       1.1    bouyer 	sl->sl_sparespercyl = lp->d_sparespercyl;
    374       1.1    bouyer 	sl->sl_interleave   = lp->d_interleave;
    375       1.1    bouyer 	sl->sl_ncylinders   = lp->d_ncylinders;
    376       1.1    bouyer 	sl->sl_acylinders   = lp->d_acylinders;
    377       1.1    bouyer 	sl->sl_ntracks      = lp->d_ntracks;
    378       1.1    bouyer 	sl->sl_nsectors     = lp->d_nsectors;
    379       1.1    bouyer 
    380       1.1    bouyer 	secpercyl = sl->sl_nsectors * sl->sl_ntracks;
    381       1.1    bouyer 	for (i = 0; i < 8; i++) {
    382       1.1    bouyer 		spp = &sl->sl_part[i];
    383       1.1    bouyer 		npp = &lp->d_partitions[i];
    384       1.1    bouyer 
    385       1.1    bouyer 		/*
    386       1.1    bouyer 		 * SunOS partitions must start on a cylinder boundary.
    387       1.1    bouyer 		 * Note this restriction is forced upon NetBSD/sparc
    388       1.1    bouyer 		 * labels too, since we want to keep both labels
    389       1.1    bouyer 		 * synchronised.
    390       1.1    bouyer 		 */
    391       1.1    bouyer 		if (npp->p_offset % secpercyl)
    392       1.1    bouyer 			return (EINVAL);
    393       1.1    bouyer 		spp->sdkp_cyloffset = npp->p_offset / secpercyl;
    394       1.1    bouyer 		spp->sdkp_nsectors = npp->p_size;
    395       1.1    bouyer 	}
    396       1.1    bouyer 	sl->sl_magic = SUN_DKMAGIC;
    397       1.1    bouyer 
    398       1.1    bouyer 	/* Compute the XOR check. */
    399       1.1    bouyer 	sp1 = (u_short *)sl;
    400       1.1    bouyer 	sp2 = (u_short *)(sl + 1);
    401       1.1    bouyer 	sl->sl_cksum = cksum = 0;
    402       1.1    bouyer 	while (sp1 < sp2)
    403       1.1    bouyer 		cksum ^= *sp1++;
    404       1.1    bouyer 	sl->sl_cksum = cksum;
    405       1.1    bouyer 
    406       1.1    bouyer 	return (0);
    407       1.1    bouyer }
    408       1.1    bouyer 
    409       1.1    bouyer /*
    410       1.1    bouyer  * Search the bad sector table looking for the specified sector.
    411       1.1    bouyer  * Return index if found.
    412       1.1    bouyer  * Return -1 if not found.
    413       1.1    bouyer  */
    414       1.1    bouyer int
    415  1.9.30.1     skrll isbad(struct dkbad *bt, int cyl, int trk, int sec)
    416       1.1    bouyer {
    417       1.1    bouyer 	int i;
    418       1.1    bouyer 	long blk, bblk;
    419       1.1    bouyer 
    420       1.1    bouyer 	blk = ((long)cyl << 16) + (trk << 8) + sec;
    421       1.1    bouyer 	for (i = 0; i < 126; i++) {
    422       1.1    bouyer 		bblk = ((long)bt->bt_bad[i].bt_cyl << 16) +
    423       1.1    bouyer 			bt->bt_bad[i].bt_trksec;
    424       1.1    bouyer 		if (blk == bblk)
    425       1.1    bouyer 			return (i);
    426       1.1    bouyer 		if (blk < bblk || bblk < 0)
    427       1.1    bouyer 			break;
    428       1.1    bouyer 	}
    429       1.1    bouyer 	return (-1);
    430       1.1    bouyer }
    431