155098Storek /*
2*63325Sbostic  * Copyright (c) 1992, 1993
3*63325Sbostic  *	The Regents of the University of California.  All rights reserved.
455098Storek  *
555098Storek  * This software was developed by the Computer Systems Engineering group
655098Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
755098Storek  * contributed to Berkeley.
855098Storek  *
955505Sbostic  * All advertising materials mentioning features or use of this software
1055505Sbostic  * must display the following acknowledgement:
1155505Sbostic  *	This product includes software developed by the University of
1258993Storek  *	California, Lawrence Berkeley Laboratory.
1355505Sbostic  *
1455098Storek  * %sccs.include.redist.c%
1555098Storek  *
16*63325Sbostic  *	@(#)sun_disklabel.c	8.1 (Berkeley) 06/11/93
1755098Storek  *
1855098Storek  * from: $Header: sun_disklabel.c,v 1.5 92/06/17 07:04:12 torek Exp $
1955098Storek  */
2055098Storek 
2155098Storek /*
2255098Storek  * SunOS disk label code.
2355098Storek  */
2455098Storek 
2556543Sbostic #include <sys/param.h>
2656543Sbostic #include <sys/disklabel.h>
2756543Sbostic #include <sys/device.h>
2856543Sbostic #include <sys/disk.h>
2956543Sbostic #include <sys/ioctl.h>
3055098Storek 
3156543Sbostic #include <sparc/sunos/sun_disklabel.h>
3255098Storek 
3355098Storek /*
3455098Storek  * Take a sector (cp) containing a SunOS disk label and set lp to a BSD
3555098Storek  * disk label.
3655098Storek  */
3755098Storek int
sun_disklabel(cp,lp)3855098Storek sun_disklabel(cp, lp)
3955098Storek 	register caddr_t cp;
4055098Storek 	register struct disklabel *lp;
4155098Storek {
4255098Storek 	register u_short *sp;
4355098Storek 	register struct sun_disklabel *sl;
4455098Storek 	register int i, v;
4555098Storek 
4655098Storek 	sp = (u_short *)(cp + sizeof(struct sun_disklabel));
4755098Storek 	--sp;
4855098Storek 	v = 0;
4955098Storek 	while (sp >= (u_short *)cp)
5055098Storek 		v ^= *sp--;
5155098Storek 	if (v)
5255098Storek 		return (0);
5355098Storek 	sl = (struct sun_disklabel *)cp;
5455098Storek 	lp->d_magic = 0;	/* denote as pseudo */
5555098Storek 	lp->d_ncylinders = sl->sl_ncylinders;
5655098Storek 	lp->d_acylinders = sl->sl_acylinders;
5755098Storek 	v = (lp->d_ntracks = sl->sl_ntracks) *
5855098Storek 	    (lp->d_nsectors = sl->sl_nsectors);
5955098Storek 	lp->d_secpercyl = v;
6055098Storek 	lp->d_npartitions = 8;
6155098Storek 	for (i = 0; i < 8; i++) {
6255098Storek 		lp->d_partitions[i].p_offset =
6355098Storek 		    sl->sl_part[i].sdkp_cyloffset * v;
6455098Storek 		lp->d_partitions[i].p_size = sl->sl_part[i].sdkp_nsectors;
6555098Storek 	}
6655098Storek 	return (1);
6755098Storek }
6855098Storek 
6955098Storek int
sun_dkioctl(dk,cmd,data,partition)7055098Storek sun_dkioctl(dk, cmd, data, partition)
7155098Storek 	struct dkdevice *dk;
7255098Storek 	int cmd;
7355098Storek 	caddr_t data;
7455098Storek 	int partition;
7555098Storek {
7655098Storek 	register struct partition *p;
7755098Storek 
7855098Storek 	switch (cmd) {
7955098Storek 
8055098Storek 	case DKIOCGGEOM:
8155098Storek #define geom ((struct sun_dkgeom *)data)
8255098Storek 		bzero(data, sizeof(*geom));
8355098Storek 		geom->sdkc_ncylinders = dk->dk_label.d_ncylinders;
8455098Storek 		geom->sdkc_acylinders = dk->dk_label.d_acylinders;
8555098Storek 		geom->sdkc_ntracks = dk->dk_label.d_ntracks;
8655098Storek 		geom->sdkc_nsectors = dk->dk_label.d_nsectors;
8755098Storek 		geom->sdkc_interleave = dk->dk_label.d_interleave;
8855098Storek 		geom->sdkc_sparespercyl = dk->dk_label.d_sparespercyl;
8955098Storek 		geom->sdkc_rpm = dk->dk_label.d_rpm;
9055098Storek 		geom->sdkc_pcylinders =
9155098Storek 		    dk->dk_label.d_ncylinders + dk->dk_label.d_acylinders;
9255098Storek #undef	geom
9355098Storek 		break;
9455098Storek 
9555098Storek 	case DKIOCINFO:
9655098Storek 		/* Homey don't do DKIOCINFO */
9755098Storek 		bzero(data, sizeof(struct sun_dkctlr));
9855098Storek 		break;
9955098Storek 
10055098Storek 	case DKIOCGPART:
10155098Storek 		if (dk->dk_label.d_secpercyl == 0)
10255098Storek 			return (ERANGE);	/* XXX */
10355098Storek 		p = &dk->dk_label.d_partitions[partition];
10455098Storek 		if (p->p_offset % dk->dk_label.d_secpercyl != 0)
10555098Storek 			return (ERANGE);	/* XXX */
10655098Storek #define part ((struct sun_dkpart *)data)
10755098Storek 		part->sdkp_cyloffset = p->p_offset / dk->dk_label.d_secpercyl;
10855098Storek 		part->sdkp_nsectors = p->p_size;
10955098Storek #undef	part
11055098Storek 		break;
11155098Storek 
11255098Storek 	default:
11355098Storek 		return (-1);
11455098Storek 	}
11555098Storek 	return (0);
11655098Storek }
117