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