1 /*
2  * Copyright (c) 1992, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This software was developed by the Computer Systems Engineering group
6  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
7  * contributed to Berkeley.
8  *
9  * All advertising materials mentioning features or use of this software
10  * must display the following acknowledgement:
11  *	This product includes software developed by the University of
12  *	California, Lawrence Berkeley Laboratory.
13  *
14  * %sccs.include.redist.c%
15  *
16  *	@(#)sun_disklabel.c	8.1 (Berkeley) 06/11/93
17  *
18  * from: $Header: sun_disklabel.c,v 1.5 92/06/17 07:04:12 torek Exp $
19  */
20 
21 /*
22  * SunOS disk label code.
23  */
24 
25 #include <sys/param.h>
26 #include <sys/disklabel.h>
27 #include <sys/device.h>
28 #include <sys/disk.h>
29 #include <sys/ioctl.h>
30 
31 #include <sparc/sunos/sun_disklabel.h>
32 
33 /*
34  * Take a sector (cp) containing a SunOS disk label and set lp to a BSD
35  * disk label.
36  */
37 int
38 sun_disklabel(cp, lp)
39 	register caddr_t cp;
40 	register struct disklabel *lp;
41 {
42 	register u_short *sp;
43 	register struct sun_disklabel *sl;
44 	register int i, v;
45 
46 	sp = (u_short *)(cp + sizeof(struct sun_disklabel));
47 	--sp;
48 	v = 0;
49 	while (sp >= (u_short *)cp)
50 		v ^= *sp--;
51 	if (v)
52 		return (0);
53 	sl = (struct sun_disklabel *)cp;
54 	lp->d_magic = 0;	/* denote as pseudo */
55 	lp->d_ncylinders = sl->sl_ncylinders;
56 	lp->d_acylinders = sl->sl_acylinders;
57 	v = (lp->d_ntracks = sl->sl_ntracks) *
58 	    (lp->d_nsectors = sl->sl_nsectors);
59 	lp->d_secpercyl = v;
60 	lp->d_npartitions = 8;
61 	for (i = 0; i < 8; i++) {
62 		lp->d_partitions[i].p_offset =
63 		    sl->sl_part[i].sdkp_cyloffset * v;
64 		lp->d_partitions[i].p_size = sl->sl_part[i].sdkp_nsectors;
65 	}
66 	return (1);
67 }
68 
69 int
70 sun_dkioctl(dk, cmd, data, partition)
71 	struct dkdevice *dk;
72 	int cmd;
73 	caddr_t data;
74 	int partition;
75 {
76 	register struct partition *p;
77 
78 	switch (cmd) {
79 
80 	case DKIOCGGEOM:
81 #define geom ((struct sun_dkgeom *)data)
82 		bzero(data, sizeof(*geom));
83 		geom->sdkc_ncylinders = dk->dk_label.d_ncylinders;
84 		geom->sdkc_acylinders = dk->dk_label.d_acylinders;
85 		geom->sdkc_ntracks = dk->dk_label.d_ntracks;
86 		geom->sdkc_nsectors = dk->dk_label.d_nsectors;
87 		geom->sdkc_interleave = dk->dk_label.d_interleave;
88 		geom->sdkc_sparespercyl = dk->dk_label.d_sparespercyl;
89 		geom->sdkc_rpm = dk->dk_label.d_rpm;
90 		geom->sdkc_pcylinders =
91 		    dk->dk_label.d_ncylinders + dk->dk_label.d_acylinders;
92 #undef	geom
93 		break;
94 
95 	case DKIOCINFO:
96 		/* Homey don't do DKIOCINFO */
97 		bzero(data, sizeof(struct sun_dkctlr));
98 		break;
99 
100 	case DKIOCGPART:
101 		if (dk->dk_label.d_secpercyl == 0)
102 			return (ERANGE);	/* XXX */
103 		p = &dk->dk_label.d_partitions[partition];
104 		if (p->p_offset % dk->dk_label.d_secpercyl != 0)
105 			return (ERANGE);	/* XXX */
106 #define part ((struct sun_dkpart *)data)
107 		part->sdkp_cyloffset = p->p_offset / dk->dk_label.d_secpercyl;
108 		part->sdkp_nsectors = p->p_size;
109 #undef	part
110 		break;
111 
112 	default:
113 		return (-1);
114 	}
115 	return (0);
116 }
117