xref: /onnv-gate/usr/src/uts/common/io/pcmcia/pclabel.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <sys/errno.h>
30*0Sstevel@tonic-gate #include <sys/param.h>
31*0Sstevel@tonic-gate #include <sys/systm.h>
32*0Sstevel@tonic-gate #include <sys/user.h>
33*0Sstevel@tonic-gate #include <sys/buf.h>
34*0Sstevel@tonic-gate #include <sys/file.h>
35*0Sstevel@tonic-gate #include <sys/cmn_err.h>
36*0Sstevel@tonic-gate #include <sys/uio.h>
37*0Sstevel@tonic-gate #include <sys/kmem.h>
38*0Sstevel@tonic-gate #include <sys/sysmacros.h>
39*0Sstevel@tonic-gate #include <sys/stat.h>
40*0Sstevel@tonic-gate #include <sys/scsi/scsi.h>
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate #include <sys/fdio.h>
43*0Sstevel@tonic-gate 
44*0Sstevel@tonic-gate #include <sys/errno.h>
45*0Sstevel@tonic-gate #include <sys/open.h>
46*0Sstevel@tonic-gate #include <sys/debug.h>
47*0Sstevel@tonic-gate #include <sys/varargs.h>
48*0Sstevel@tonic-gate #include <sys/fs/pc_label.h>
49*0Sstevel@tonic-gate 
50*0Sstevel@tonic-gate #include <sys/hdio.h>
51*0Sstevel@tonic-gate #include <sys/dkio.h>
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate #include <sys/dklabel.h>
54*0Sstevel@tonic-gate 
55*0Sstevel@tonic-gate #include <sys/vtoc.h>
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate 
58*0Sstevel@tonic-gate #include <sys/types.h>
59*0Sstevel@tonic-gate #include <sys/conf.h>
60*0Sstevel@tonic-gate #include <sys/dditypes.h>
61*0Sstevel@tonic-gate #include <sys/ddi.h>
62*0Sstevel@tonic-gate #include <sys/sunddi.h>
63*0Sstevel@tonic-gate #include <sys/dktp/cm.h>
64*0Sstevel@tonic-gate 
65*0Sstevel@tonic-gate #include <sys/dktp/fdisk.h>
66*0Sstevel@tonic-gate 
67*0Sstevel@tonic-gate #include <sys/pctypes.h>
68*0Sstevel@tonic-gate 
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate /* Future WORK */
71*0Sstevel@tonic-gate /* Card Services header files should be removed.  When pcata.h is split  */
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate #include <sys/cis.h>
74*0Sstevel@tonic-gate #include <sys/cis_handlers.h>
75*0Sstevel@tonic-gate #include <sys/cs_types.h>
76*0Sstevel@tonic-gate #include <sys/cs.h>
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate #include <sys/fs/pc_label.h>
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate #include <sys/pctypes.h>
81*0Sstevel@tonic-gate #include <sys/pcmcia/pcata.h>
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate static	int	pcdsklbl_chk(struct dk_label *, unsigned short *);
84*0Sstevel@tonic-gate static	void	pcdsklbl_preplb(ata_unit_t *unitp);
85*0Sstevel@tonic-gate static	int	pcdsklbl_rdvtoc(ata_unit_t *unitp, buf_t *bp);
86*0Sstevel@tonic-gate 
87*0Sstevel@tonic-gate /*
88*0Sstevel@tonic-gate  * accepts pointer to buffer containing the on-disk label data
89*0Sstevel@tonic-gate  *	data could be VTOC8 or VTOC16
90*0Sstevel@tonic-gate  *	data could be in a struct buf or in lbl
91*0Sstevel@tonic-gate  *
92*0Sstevel@tonic-gate  * verifies magic numbers in label and checksum
93*0Sstevel@tonic-gate  *
94*0Sstevel@tonic-gate  * if the parameter pointing to the checksum points to a location
95*0Sstevel@tonic-gate  * within the label, this routine will generate the checksum
96*0Sstevel@tonic-gate  */
97*0Sstevel@tonic-gate static int
pcdsklbl_chk(struct dk_label * lbp,unsigned short * cksum)98*0Sstevel@tonic-gate pcdsklbl_chk(struct dk_label *lbp, unsigned short *cksum)
99*0Sstevel@tonic-gate {
100*0Sstevel@tonic-gate 	short	*sp;
101*0Sstevel@tonic-gate 	short	count;
102*0Sstevel@tonic-gate 	unsigned short	sum;
103*0Sstevel@tonic-gate 
104*0Sstevel@tonic-gate 	/*
105*0Sstevel@tonic-gate 	 * Check magic number of the label
106*0Sstevel@tonic-gate 	 */
107*0Sstevel@tonic-gate 	if (lbp->dkl_magic != DKL_MAGIC) {
108*0Sstevel@tonic-gate #ifdef ATA_DEBUG
109*0Sstevel@tonic-gate 		if (pcata_debug & DLBL) {
110*0Sstevel@tonic-gate 			cmn_err(CE_CONT, "pcdsklbl_chk: "
111*0Sstevel@tonic-gate 				"magic: 0x%x not MAGIC:0x%x\n",
112*0Sstevel@tonic-gate 				lbp->dkl_magic,
113*0Sstevel@tonic-gate 				DKL_MAGIC);
114*0Sstevel@tonic-gate 		}
115*0Sstevel@tonic-gate #endif
116*0Sstevel@tonic-gate 		return (DDI_FAILURE);
117*0Sstevel@tonic-gate 	}
118*0Sstevel@tonic-gate 	if (lbp->dkl_vtoc.v_sanity != VTOC_SANE) {
119*0Sstevel@tonic-gate #ifdef ATA_DEBUG
120*0Sstevel@tonic-gate 		if (pcata_debug & DLBL) {
121*0Sstevel@tonic-gate 			cmn_err(CE_CONT, "pcdsklbl_chk: "
122*0Sstevel@tonic-gate 				"sanity: 0x%x not SANE:0x%x\n",
123*0Sstevel@tonic-gate 				lbp->dkl_vtoc.v_sanity,
124*0Sstevel@tonic-gate 				VTOC_SANE);
125*0Sstevel@tonic-gate 		}
126*0Sstevel@tonic-gate #endif
127*0Sstevel@tonic-gate 		return (DDI_FAILURE);
128*0Sstevel@tonic-gate 	}
129*0Sstevel@tonic-gate 	if (lbp->dkl_vtoc.v_version != V_VERSION) {
130*0Sstevel@tonic-gate #ifdef ATA_DEBUG
131*0Sstevel@tonic-gate 		if (pcata_debug & DLBL) {
132*0Sstevel@tonic-gate 			cmn_err(CE_CONT, "pcdsklbl_chk: "
133*0Sstevel@tonic-gate 				"version: 0x%x not 0x%x\n",
134*0Sstevel@tonic-gate 				lbp->dkl_vtoc.v_version,
135*0Sstevel@tonic-gate 				V_VERSION);
136*0Sstevel@tonic-gate 		}
137*0Sstevel@tonic-gate #endif
138*0Sstevel@tonic-gate 		return (DDI_FAILURE);
139*0Sstevel@tonic-gate 	}
140*0Sstevel@tonic-gate 
141*0Sstevel@tonic-gate 	/*
142*0Sstevel@tonic-gate 	 * Check the checksum of the label
143*0Sstevel@tonic-gate 	 */
144*0Sstevel@tonic-gate 	sp = (short *)lbp;
145*0Sstevel@tonic-gate 	sum = 0;
146*0Sstevel@tonic-gate 	count = sizeof (struct dk_label) / sizeof (short);
147*0Sstevel@tonic-gate 	while (count--)  {
148*0Sstevel@tonic-gate 		sum ^= *sp++;
149*0Sstevel@tonic-gate 	}
150*0Sstevel@tonic-gate 
151*0Sstevel@tonic-gate 	*cksum = sum;
152*0Sstevel@tonic-gate 	if (sum)
153*0Sstevel@tonic-gate 		return (DDI_FAILURE);
154*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
155*0Sstevel@tonic-gate }
156*0Sstevel@tonic-gate 
157*0Sstevel@tonic-gate void
pcinit_pmap(ata_unit_t * unitp)158*0Sstevel@tonic-gate pcinit_pmap(ata_unit_t *unitp)
159*0Sstevel@tonic-gate {
160*0Sstevel@tonic-gate 	dsk_label_t		*lblp = &unitp->lbl;
161*0Sstevel@tonic-gate 	struct partition	*pmapp = lblp->pmap;
162*0Sstevel@tonic-gate 	uint32_t		disksize;	/* maximum block number */
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	/*
165*0Sstevel@tonic-gate 	 * clear pmap (all 20 slices)
166*0Sstevel@tonic-gate 	 */
167*0Sstevel@tonic-gate 	bzero((caddr_t)pmapp, sizeof (struct partition) * NUM_PARTS);
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate 	/*
170*0Sstevel@tonic-gate 	 * calc total blocks on device
171*0Sstevel@tonic-gate 	 */
172*0Sstevel@tonic-gate 	disksize = (unitp->au_cyl + unitp->au_acyl)
173*0Sstevel@tonic-gate 		 * unitp->au_hd * unitp->au_sec;
174*0Sstevel@tonic-gate 
175*0Sstevel@tonic-gate 	/*
176*0Sstevel@tonic-gate 	 * The whole disk is represented here (this is the p0 partition.)
177*0Sstevel@tonic-gate 	 */
178*0Sstevel@tonic-gate 	pmapp[FDISK_OFFSET].p_tag	= 0;
179*0Sstevel@tonic-gate 	pmapp[FDISK_OFFSET].p_flag	= V_UNMNT;
180*0Sstevel@tonic-gate 	pmapp[FDISK_OFFSET].p_start	= 0;
181*0Sstevel@tonic-gate 	pmapp[FDISK_OFFSET].p_size	= disksize;
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 	lblp->fdiskpresent	= 0;		/* NO MBR fdisk record */
184*0Sstevel@tonic-gate 	lblp->uidx		= FDISK_OFFSET; /* NO unix fdisk partition */
185*0Sstevel@tonic-gate }
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate /*
188*0Sstevel@tonic-gate  * read sector 0 of the disk and call fdisk parse
189*0Sstevel@tonic-gate  */
190*0Sstevel@tonic-gate int
pcfdisk_read(buf_t * bp,ata_unit_t * unitp)191*0Sstevel@tonic-gate pcfdisk_read(buf_t *bp, ata_unit_t *unitp)
192*0Sstevel@tonic-gate {
193*0Sstevel@tonic-gate 	int		ret;
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate 	/*
196*0Sstevel@tonic-gate 	 * read fdisk sector (device block 0)
197*0Sstevel@tonic-gate 	 */
198*0Sstevel@tonic-gate 	bp->b_bcount = 1 * DEV_BSIZE;
199*0Sstevel@tonic-gate 	bp->b_flags = B_READ;
200*0Sstevel@tonic-gate 	bp->b_blkno = 0;
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate 	(void) pcata_strategy(bp);
203*0Sstevel@tonic-gate 	if (biowait(bp))
204*0Sstevel@tonic-gate 		return (DDI_FAILURE);
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate 	ret = pcfdisk_parse(bp, unitp);
207*0Sstevel@tonic-gate 	return (ret);
208*0Sstevel@tonic-gate }
209*0Sstevel@tonic-gate 
210*0Sstevel@tonic-gate /*
211*0Sstevel@tonic-gate  * We have this wonderful scenario
212*0Sstevel@tonic-gate  * where there exists two different kinds of labeling schemes,
213*0Sstevel@tonic-gate  * the x86/ppc vs. Sparc
214*0Sstevel@tonic-gate  *
215*0Sstevel@tonic-gate  * Procedurely we do the following
216*0Sstevel@tonic-gate  *	clear pmap[s0-s15,p0-p5]
217*0Sstevel@tonic-gate  *	set pmap[p0] to entire disk
218*0Sstevel@tonic-gate  *	set uidx = p0
219*0Sstevel@tonic-gate  *
220*0Sstevel@tonic-gate  *	read disk block 0 and check for fdisk record
221*0Sstevel@tonic-gate  *	if (fdisk record exists) {
222*0Sstevel@tonic-gate  *		set pmap[p1-p4]
223*0Sstevel@tonic-gate  *		if (Solaris partiton exists) {
224*0Sstevel@tonic-gate  *			set uidx to px
225*0Sstevel@tonic-gate  *		}
226*0Sstevel@tonic-gate  *	}
227*0Sstevel@tonic-gate  *
228*0Sstevel@tonic-gate  *	if (fdisk record does not exist OR a Solaris partiton exists) {
229*0Sstevel@tonic-gate  *		read disk block 1 of pmap[uidx] and check for VTOC
230*0Sstevel@tonic-gate  *		if (VTOC exists) {
231*0Sstevel@tonic-gate  *			set pmap[s0-s15] from vtoc
232*0Sstevel@tonic-gate  *		}
233*0Sstevel@tonic-gate  *		set pmap[s2] to entire Solaris partition
234*0Sstevel@tonic-gate  *	}
235*0Sstevel@tonic-gate  *
236*0Sstevel@tonic-gate  *	for s0 to s15
237*0Sstevel@tonic-gate  *		add start address of pmap[uidx] to pmap [s0-s15]
238*0Sstevel@tonic-gate  *		(do not change incore vtoc record)
239*0Sstevel@tonic-gate  */
240*0Sstevel@tonic-gate 
241*0Sstevel@tonic-gate int
pcfdisk_parse(buf_t * bp,ata_unit_t * unitp)242*0Sstevel@tonic-gate pcfdisk_parse(buf_t *bp, ata_unit_t *unitp)
243*0Sstevel@tonic-gate {
244*0Sstevel@tonic-gate 	dsk_label_t		*lblp = &unitp->lbl;
245*0Sstevel@tonic-gate 	struct partition	*pmapp = lblp->pmap;
246*0Sstevel@tonic-gate 	struct mboot		*mbp;
247*0Sstevel@tonic-gate 	struct ipart		*fdp;
248*0Sstevel@tonic-gate 	int			i;
249*0Sstevel@tonic-gate 	struct ipart		fdisk[FD_NUMPART];
250*0Sstevel@tonic-gate 
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 	/* check to see if valid fdisk record exists */
253*0Sstevel@tonic-gate 	mbp = (struct mboot *)bp->b_un.b_addr;
254*0Sstevel@tonic-gate #ifdef ATA_DEBUG
255*0Sstevel@tonic-gate 	if (pcata_debug & DLBL)
256*0Sstevel@tonic-gate 		cmn_err(CE_CONT, "pcfdisk_parse "
257*0Sstevel@tonic-gate 			"fdisk signature=%04x  MBB_MAGIC=%04x\n",
258*0Sstevel@tonic-gate 			ltohs(mbp->signature),
259*0Sstevel@tonic-gate 			MBB_MAGIC);
260*0Sstevel@tonic-gate #endif
261*0Sstevel@tonic-gate 	if (ltohs(mbp->signature) == MBB_MAGIC) {
262*0Sstevel@tonic-gate 
263*0Sstevel@tonic-gate 		/* fdisk record exists */
264*0Sstevel@tonic-gate 		lblp->fdiskpresent = 1;
265*0Sstevel@tonic-gate 
266*0Sstevel@tonic-gate 		/* copy fdisk table so it is aligned on 4 byte boundry */
267*0Sstevel@tonic-gate 		fdp = fdisk;
268*0Sstevel@tonic-gate 		bcopy((caddr_t)&(mbp->parts[0]), (caddr_t)fdp, sizeof (fdisk));
269*0Sstevel@tonic-gate 
270*0Sstevel@tonic-gate 		for (i = 1; i <= FD_NUMPART; i++, fdp++) {
271*0Sstevel@tonic-gate 			int	num, rel;
272*0Sstevel@tonic-gate 
273*0Sstevel@tonic-gate #ifdef ATA_DEBUG
274*0Sstevel@tonic-gate 			if (pcata_debug & DLBL)
275*0Sstevel@tonic-gate 				cmn_err(CE_CONT, "%d sy=%02x rel=%7d num=%7d\n",
276*0Sstevel@tonic-gate 					i,
277*0Sstevel@tonic-gate 					fdp->systid,
278*0Sstevel@tonic-gate 					ltohi(fdp->relsect),
279*0Sstevel@tonic-gate 					ltohi(fdp->numsect));
280*0Sstevel@tonic-gate #endif
281*0Sstevel@tonic-gate 
282*0Sstevel@tonic-gate 			/*
283*0Sstevel@tonic-gate 			 * make sure numbers are reasonable
284*0Sstevel@tonic-gate 			 * XXX/lcl partitions can still overlap
285*0Sstevel@tonic-gate 			 * XXX/lcl in fdisk.h,  num and rel are signed
286*0Sstevel@tonic-gate 			 */
287*0Sstevel@tonic-gate 			rel = ltohi(fdp->relsect);
288*0Sstevel@tonic-gate 			num = ltohi(fdp->numsect);
289*0Sstevel@tonic-gate 
290*0Sstevel@tonic-gate 			if (fdp->systid == 0 ||
291*0Sstevel@tonic-gate 					rel < 0 ||
292*0Sstevel@tonic-gate 					num <= 0 ||
293*0Sstevel@tonic-gate 					rel+num > pmapp[FDISK_OFFSET].p_size) {
294*0Sstevel@tonic-gate 				continue;
295*0Sstevel@tonic-gate 			}
296*0Sstevel@tonic-gate 
297*0Sstevel@tonic-gate 			pmapp[i+FDISK_OFFSET].p_tag  = fdp->systid;
298*0Sstevel@tonic-gate 			pmapp[i+FDISK_OFFSET].p_flag = 0;
299*0Sstevel@tonic-gate 			pmapp[i+FDISK_OFFSET].p_start = rel;
300*0Sstevel@tonic-gate 			pmapp[i+FDISK_OFFSET].p_size = num;
301*0Sstevel@tonic-gate 			if (fdp->systid == SUNIXOS || fdp->systid == SUNIXOS2) {
302*0Sstevel@tonic-gate 				if (lblp->uidx == FDISK_OFFSET)
303*0Sstevel@tonic-gate 					lblp->uidx = i+FDISK_OFFSET;
304*0Sstevel@tonic-gate 				else if (fdp->bootid == ACTIVE)
305*0Sstevel@tonic-gate 					lblp->uidx = i+FDISK_OFFSET;
306*0Sstevel@tonic-gate 			}
307*0Sstevel@tonic-gate 		}
308*0Sstevel@tonic-gate 	}
309*0Sstevel@tonic-gate 
310*0Sstevel@tonic-gate 	/*
311*0Sstevel@tonic-gate 	 * Partitions p0 - p4 are established correctly
312*0Sstevel@tonic-gate 	 * now check for Solaris vtoc
313*0Sstevel@tonic-gate 	 */
314*0Sstevel@tonic-gate 
315*0Sstevel@tonic-gate 	/*
316*0Sstevel@tonic-gate 	 * if there is no MBR (fdisk label)
317*0Sstevel@tonic-gate 	 * or there is an FDISK label which defines a Solaris partition
318*0Sstevel@tonic-gate 	 * then call rdvtoc.
319*0Sstevel@tonic-gate 	 *
320*0Sstevel@tonic-gate 	 * note: if fdisk does exist, but does not define a Solaris partiton
321*0Sstevel@tonic-gate 	 *	s0-s15 are set to zero length
322*0Sstevel@tonic-gate 	 */
323*0Sstevel@tonic-gate 	if (!lblp->fdiskpresent || lblp->uidx != FDISK_OFFSET) {
324*0Sstevel@tonic-gate 		/* failures leave pmap in the correct state, so we don't care */
325*0Sstevel@tonic-gate 		(void) pcdsklbl_rdvtoc(unitp, bp);
326*0Sstevel@tonic-gate 	}
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate #ifdef ATA_DEBUG
329*0Sstevel@tonic-gate 	if (pcata_debug & DLBL) {
330*0Sstevel@tonic-gate 		cmn_err(CE_CONT, "DEFINED PARTITIONS\n");
331*0Sstevel@tonic-gate 		for (i = 0; i <= NUM_PARTS; i++)
332*0Sstevel@tonic-gate 			if (pmapp[i].p_size > 0)
333*0Sstevel@tonic-gate 				cmn_err(CE_CONT, "s%2d  beg=%6ld  siz=%ld\n",
334*0Sstevel@tonic-gate 					i,
335*0Sstevel@tonic-gate 					pmapp[i].p_start,
336*0Sstevel@tonic-gate 					pmapp[i].p_size);
337*0Sstevel@tonic-gate 	}
338*0Sstevel@tonic-gate #endif
339*0Sstevel@tonic-gate 
340*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
341*0Sstevel@tonic-gate }
342*0Sstevel@tonic-gate 
343*0Sstevel@tonic-gate static int
pcdsklbl_rdvtoc(ata_unit_t * unitp,buf_t * bp)344*0Sstevel@tonic-gate pcdsklbl_rdvtoc(ata_unit_t *unitp, buf_t *bp)
345*0Sstevel@tonic-gate {
346*0Sstevel@tonic-gate 	dsk_label_t	*lblp	= &unitp->lbl;
347*0Sstevel@tonic-gate 	struct dk_label *lbp;			/* points to data in buf_t */
348*0Sstevel@tonic-gate 	unsigned short	sum;
349*0Sstevel@tonic-gate 	int		i;
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate 	/*
352*0Sstevel@tonic-gate 	 * read the label from the uidx partition (p0-p4)
353*0Sstevel@tonic-gate 	 */
354*0Sstevel@tonic-gate 	bp->b_bcount = 1 * DEV_BSIZE;
355*0Sstevel@tonic-gate 	bp->b_flags = B_READ;
356*0Sstevel@tonic-gate 	bp->b_blkno = lblp->pmap[lblp->uidx].p_start+VTOC_OFFSET;
357*0Sstevel@tonic-gate 	(void) pcata_strategy(bp);
358*0Sstevel@tonic-gate 	if (biowait(bp)) {
359*0Sstevel@tonic-gate 		return (DDI_FAILURE);
360*0Sstevel@tonic-gate 	}
361*0Sstevel@tonic-gate 
362*0Sstevel@tonic-gate 	lbp = (struct dk_label *)bp->b_un.b_addr;
363*0Sstevel@tonic-gate 	if (!lbp) {
364*0Sstevel@tonic-gate 		return (DDI_FAILURE);
365*0Sstevel@tonic-gate 	}
366*0Sstevel@tonic-gate 
367*0Sstevel@tonic-gate 	/*
368*0Sstevel@tonic-gate 	 * check label
369*0Sstevel@tonic-gate 	 */
370*0Sstevel@tonic-gate 	if (pcdsklbl_chk(lbp, &sum) == DDI_SUCCESS) {
371*0Sstevel@tonic-gate 
372*0Sstevel@tonic-gate 		/*
373*0Sstevel@tonic-gate 		 * record label information
374*0Sstevel@tonic-gate 		 * copy the data from the buf_t memory to the lblp memory
375*0Sstevel@tonic-gate 		 */
376*0Sstevel@tonic-gate 		bcopy((caddr_t)lbp, (caddr_t)&lblp->ondsklbl, sizeof (*lbp));
377*0Sstevel@tonic-gate 	} else {
378*0Sstevel@tonic-gate #ifdef	ATA_DEBUG
379*0Sstevel@tonic-gate 		if (pcata_debug & DLBL)
380*0Sstevel@tonic-gate 			cmn_err(CE_CONT, "vtoc label has invalid checksum\n");
381*0Sstevel@tonic-gate #endif
382*0Sstevel@tonic-gate 		/*
383*0Sstevel@tonic-gate 		 * Since there is no valid vtoc and there should be
384*0Sstevel@tonic-gate 		 * create one based on the solaris partition (possibly p0)
385*0Sstevel@tonic-gate 		 */
386*0Sstevel@tonic-gate 		pcdsklbl_preplb(unitp);
387*0Sstevel@tonic-gate 	}
388*0Sstevel@tonic-gate 
389*0Sstevel@tonic-gate 	/*
390*0Sstevel@tonic-gate 	 * adjust the lbp to point to data in the lbl structures
391*0Sstevel@tonic-gate 	 * rather than the data in the buf_t structure
392*0Sstevel@tonic-gate 	 * this is where the data was left by either the bcopy or preplb
393*0Sstevel@tonic-gate 	 */
394*0Sstevel@tonic-gate 	lbp = &lblp->ondsklbl;
395*0Sstevel@tonic-gate 
396*0Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
397*0Sstevel@tonic-gate 	bcopy((caddr_t)&lbp->dkl_vtoc.v_part,
398*0Sstevel@tonic-gate 		(caddr_t)lblp->pmap, sizeof (lbp->dkl_vtoc.v_part));
399*0Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_8)
400*0Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
401*0Sstevel@tonic-gate 		/*
402*0Sstevel@tonic-gate 		 * convert SUNOS (VTOC8) info
403*0Sstevel@tonic-gate 		 */
404*0Sstevel@tonic-gate 		lblp->pmap[i].p_tag   = lbp->dkl_vtoc.v_part[i].p_tag;
405*0Sstevel@tonic-gate 		lblp->pmap[i].p_flag  = lbp->dkl_vtoc.v_part[i].p_flag;
406*0Sstevel@tonic-gate 		lblp->pmap[i].p_start = lbp->dkl_map[i].dkl_cylno *
407*0Sstevel@tonic-gate 			lblp->ondsklbl.dkl_nhead * lblp->ondsklbl.dkl_nsect;
408*0Sstevel@tonic-gate 		lblp->pmap[i].p_size  = lbp->dkl_map[i].dkl_nblk;
409*0Sstevel@tonic-gate 	}
410*0Sstevel@tonic-gate #else
411*0Sstevel@tonic-gate #error No VTOC format defined.
412*0Sstevel@tonic-gate #endif
413*0Sstevel@tonic-gate 
414*0Sstevel@tonic-gate 	/*
415*0Sstevel@tonic-gate 	 * adjust the offsets of slices 0-15 or 0-7 by the base of the uidx
416*0Sstevel@tonic-gate 	 */
417*0Sstevel@tonic-gate 	for (i = 0; i < NDKMAP; i++) {
418*0Sstevel@tonic-gate 		/*
419*0Sstevel@tonic-gate 		 * Initialize logical partition info when VTOC is read.
420*0Sstevel@tonic-gate 		 */
421*0Sstevel@tonic-gate #if defined(_SUNOS_VTOC_8)
422*0Sstevel@tonic-gate 		lblp->un_map[i].dkl_cylno =  lbp->dkl_map[i].dkl_cylno;
423*0Sstevel@tonic-gate 		lblp->un_map[i].dkl_nblk =  lbp->dkl_map[i].dkl_nblk;
424*0Sstevel@tonic-gate #endif
425*0Sstevel@tonic-gate 		lblp->pmap[i].p_start += lblp->pmap[lblp->uidx].p_start;
426*0Sstevel@tonic-gate 	}
427*0Sstevel@tonic-gate 
428*0Sstevel@tonic-gate 	return (DDI_SUCCESS);
429*0Sstevel@tonic-gate }
430*0Sstevel@tonic-gate 
431*0Sstevel@tonic-gate /*
432*0Sstevel@tonic-gate  * Using the disk size information in unit and the partition data (p0-p4)
433*0Sstevel@tonic-gate  *	construct a default device label
434*0Sstevel@tonic-gate  *	Note - all offsets for slices 0-15 are zero based
435*0Sstevel@tonic-gate  *	(do not include the offset of the partition which defines s2)
436*0Sstevel@tonic-gate  *
437*0Sstevel@tonic-gate  * There is a number of cases we have to worry about:
438*0Sstevel@tonic-gate  *
439*0Sstevel@tonic-gate  *   1) There is an fdisk partition but no Solaris partition.
440*0Sstevel@tonic-gate  *	In this case the s2 slice size is zero since a valid
441*0Sstevel@tonic-gate  *	Solaris partition must be present for us to decide the
442*0Sstevel@tonic-gate  *	the size of the Solaris partition.
443*0Sstevel@tonic-gate  *
444*0Sstevel@tonic-gate  *   2)	There is an fdisk parition and a Solaris partition.
445*0Sstevel@tonic-gate  *	We got here because the Solaris partition was not labeled
446*0Sstevel@tonic-gate  *	or the label has been corrupted, declare the entire Solaris
447*0Sstevel@tonic-gate  *	parition as the s2 slice
448*0Sstevel@tonic-gate  *
449*0Sstevel@tonic-gate  *   3) There is no fdisk partition.
450*0Sstevel@tonic-gate  *	We have to declare the entire disk as the s2 slice,
451*0Sstevel@tonic-gate  *	with some room for the fdisk partition (I think)
452*0Sstevel@tonic-gate  */
453*0Sstevel@tonic-gate static void
pcdsklbl_preplb(ata_unit_t * unitp)454*0Sstevel@tonic-gate pcdsklbl_preplb(ata_unit_t *unitp)
455*0Sstevel@tonic-gate {
456*0Sstevel@tonic-gate 	dsk_label_t	*lblp	= &unitp->lbl;
457*0Sstevel@tonic-gate 	struct dk_label	*odlp	= &lblp->ondsklbl;	/* on disk label */
458*0Sstevel@tonic-gate 	int		s2size;
459*0Sstevel@tonic-gate 	int		nspc;
460*0Sstevel@tonic-gate 
461*0Sstevel@tonic-gate 	/* sectors per cylinder */
462*0Sstevel@tonic-gate 	nspc				= unitp->au_hd * unitp->au_sec;
463*0Sstevel@tonic-gate 
464*0Sstevel@tonic-gate 	bzero((caddr_t)odlp, sizeof (struct dk_label));
465*0Sstevel@tonic-gate 
466*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_nparts		= V_NUMPAR;
467*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_sanity		= VTOC_SANE;
468*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_version	= V_VERSION;
469*0Sstevel@tonic-gate 
470*0Sstevel@tonic-gate 	odlp->dkl_pcyl			= lblp->pmap[lblp->uidx].p_size / nspc;
471*0Sstevel@tonic-gate 	odlp->dkl_acyl			= 2;
472*0Sstevel@tonic-gate 	odlp->dkl_ncyl			= odlp->dkl_pcyl - odlp->dkl_acyl;
473*0Sstevel@tonic-gate 
474*0Sstevel@tonic-gate 	odlp->dkl_nhead			= unitp->au_hd;
475*0Sstevel@tonic-gate 	odlp->dkl_nsect			= unitp->au_sec;
476*0Sstevel@tonic-gate 
477*0Sstevel@tonic-gate 	odlp->dkl_rpm			= 3600;
478*0Sstevel@tonic-gate 
479*0Sstevel@tonic-gate 	odlp->dkl_intrlv		= 1;
480*0Sstevel@tonic-gate 	odlp->dkl_apc			= 0;
481*0Sstevel@tonic-gate 	odlp->dkl_magic			= DKL_MAGIC;
482*0Sstevel@tonic-gate 
483*0Sstevel@tonic-gate 	/*
484*0Sstevel@tonic-gate 	 * set size of s2 from uidx
485*0Sstevel@tonic-gate 	 */
486*0Sstevel@tonic-gate 	s2size				= lblp->pmap[lblp->uidx].p_size;
487*0Sstevel@tonic-gate 
488*0Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
489*0Sstevel@tonic-gate 	/*
490*0Sstevel@tonic-gate 	 * If this is x86/PowerPC format label
491*0Sstevel@tonic-gate 	 */
492*0Sstevel@tonic-gate 
493*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_sectorsz	= NBPSCTR;
494*0Sstevel@tonic-gate 
495*0Sstevel@tonic-gate 	/* Add full disk slice as slice 2 to the disk */
496*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_part[USLICE_WHOLE].p_start	= 0;
497*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_part[USLICE_WHOLE].p_size	= s2size;
498*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_part[USLICE_WHOLE].p_tag	= V_BACKUP;
499*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_part[USLICE_WHOLE].p_flag	= V_UNMNT;
500*0Sstevel@tonic-gate 
501*0Sstevel@tonic-gate 	/* Boot slice */
502*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_part[8].p_start	= 0;
503*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_part[8].p_size		= nspc;
504*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_part[8].p_tag		= V_BOOT;
505*0Sstevel@tonic-gate 	odlp->dkl_vtoc.v_part[8].p_flag		= V_UNMNT;
506*0Sstevel@tonic-gate 
507*0Sstevel@tonic-gate 	(void) sprintf(odlp->dkl_vtoc.v_asciilabel,
508*0Sstevel@tonic-gate 		    "DEFAULT cyl %d alt %d hd %d sec %d",
509*0Sstevel@tonic-gate 			odlp->dkl_ncyl,
510*0Sstevel@tonic-gate 			odlp->dkl_acyl,
511*0Sstevel@tonic-gate 			odlp->dkl_nhead,
512*0Sstevel@tonic-gate 			odlp->dkl_nsect);
513*0Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_8)
514*0Sstevel@tonic-gate 
515*0Sstevel@tonic-gate 	/* Add full disk slice as slice 2 to the disk */
516*0Sstevel@tonic-gate 	odlp->dkl_map[USLICE_WHOLE].dkl_cylno	= 0;
517*0Sstevel@tonic-gate 	odlp->dkl_map[USLICE_WHOLE].dkl_nblk	= s2size;
518*0Sstevel@tonic-gate 
519*0Sstevel@tonic-gate 	(void) sprintf(odlp->dkl_asciilabel,
520*0Sstevel@tonic-gate 		    "DEFAULT cyl %d alt %d hd %d sec %d",
521*0Sstevel@tonic-gate 			odlp->dkl_ncyl,
522*0Sstevel@tonic-gate 			odlp->dkl_acyl,
523*0Sstevel@tonic-gate 			odlp->dkl_nhead,
524*0Sstevel@tonic-gate 			odlp->dkl_nsect);
525*0Sstevel@tonic-gate #else
526*0Sstevel@tonic-gate #error No VTOC format defined.
527*0Sstevel@tonic-gate #endif
528*0Sstevel@tonic-gate 
529*0Sstevel@tonic-gate 	/*
530*0Sstevel@tonic-gate 	 * an on-disk label has been constructed above
531*0Sstevel@tonic-gate 	 * call pcdsklbl_chk with the 2nd parm pointing into the label
532*0Sstevel@tonic-gate 	 * will generate a correct checksum in the label
533*0Sstevel@tonic-gate 	 */
534*0Sstevel@tonic-gate 	(void) pcdsklbl_chk(&lblp->ondsklbl, &(lblp->ondsklbl.dkl_cksum));
535*0Sstevel@tonic-gate }
536*0Sstevel@tonic-gate 
537*0Sstevel@tonic-gate int
pcdsklbl_wrvtoc(dsk_label_t * lblp,struct vtoc * vtocp,buf_t * bp)538*0Sstevel@tonic-gate pcdsklbl_wrvtoc(dsk_label_t *lblp, struct vtoc *vtocp, buf_t *bp)
539*0Sstevel@tonic-gate {
540*0Sstevel@tonic-gate 	register struct dk_label *lbp, *dp;
541*0Sstevel@tonic-gate 	int	status;
542*0Sstevel@tonic-gate 	int	backup_block;
543*0Sstevel@tonic-gate 	int	count;
544*0Sstevel@tonic-gate 
545*0Sstevel@tonic-gate 	/*
546*0Sstevel@tonic-gate 	 * Data is originated from vtoc. One copy of the data is stored in
547*0Sstevel@tonic-gate 	 * lblp->ondsklbl. This is what we think of as the copy of the lable
548*0Sstevel@tonic-gate 	 * on this held in memory. The other copy (to the lbp) is to be
549*0Sstevel@tonic-gate 	 * written out to the disk.
550*0Sstevel@tonic-gate 	 */
551*0Sstevel@tonic-gate 	dp = &lblp->ondsklbl;
552*0Sstevel@tonic-gate 
553*0Sstevel@tonic-gate 	bp->b_bcount = 1 * DEV_BSIZE;
554*0Sstevel@tonic-gate 	bp->b_flags = B_WRITE;
555*0Sstevel@tonic-gate 
556*0Sstevel@tonic-gate 	lbp = (struct dk_label *)bp->b_un.b_addr;
557*0Sstevel@tonic-gate 
558*0Sstevel@tonic-gate 	pcdsklbl_vtoc_to_ondsklabel(lblp, vtocp);
559*0Sstevel@tonic-gate 	*lbp = lblp->ondsklbl;
560*0Sstevel@tonic-gate 
561*0Sstevel@tonic-gate 	/*
562*0Sstevel@tonic-gate 	 * check label
563*0Sstevel@tonic-gate 	 */
564*0Sstevel@tonic-gate 	bp->b_blkno = lblp->pmap[lblp->uidx].p_start + VTOC_OFFSET;
565*0Sstevel@tonic-gate 
566*0Sstevel@tonic-gate #ifdef ATA_DEBUG
567*0Sstevel@tonic-gate 	if (pcata_debug & DLBL)
568*0Sstevel@tonic-gate 		cmn_err(CE_NOTE, "dsklbl_wrvtoc:  calling strategy \n");
569*0Sstevel@tonic-gate #endif
570*0Sstevel@tonic-gate 	(void) pcata_strategy(bp);
571*0Sstevel@tonic-gate 	status = biowait(bp);
572*0Sstevel@tonic-gate 
573*0Sstevel@tonic-gate 	if (status != 0 || dp->dkl_acyl == 0)
574*0Sstevel@tonic-gate 		return (status);
575*0Sstevel@tonic-gate 
576*0Sstevel@tonic-gate 	/*
577*0Sstevel@tonic-gate 	 * DO backup copies of vtoc
578*0Sstevel@tonic-gate 	 */
579*0Sstevel@tonic-gate 
580*0Sstevel@tonic-gate 	backup_block = ((dp->dkl_ncyl + dp->dkl_acyl - 1) *
581*0Sstevel@tonic-gate 			(dp->dkl_nhead * dp->dkl_nsect)) +
582*0Sstevel@tonic-gate 			((dp->dkl_nhead - 1) * dp->dkl_nsect) + 1;
583*0Sstevel@tonic-gate 
584*0Sstevel@tonic-gate 	bcopy((caddr_t)&(lblp->ondsklbl), (caddr_t)lbp, sizeof (*lbp));
585*0Sstevel@tonic-gate 	for (count = 1; count < 6; count++) {
586*0Sstevel@tonic-gate 
587*0Sstevel@tonic-gate 		bp->b_blkno = lblp->pmap[lblp->uidx].p_start+backup_block;
588*0Sstevel@tonic-gate 
589*0Sstevel@tonic-gate 		/* issue read */
590*0Sstevel@tonic-gate 		(void) pcata_strategy(bp);
591*0Sstevel@tonic-gate 		if (biowait(bp))
592*0Sstevel@tonic-gate 			return (bp->b_error);
593*0Sstevel@tonic-gate 
594*0Sstevel@tonic-gate 		backup_block += 2;
595*0Sstevel@tonic-gate 	}
596*0Sstevel@tonic-gate 	return (0);
597*0Sstevel@tonic-gate }
598*0Sstevel@tonic-gate 
599*0Sstevel@tonic-gate 
600*0Sstevel@tonic-gate 
601*0Sstevel@tonic-gate void
pcdsklbl_ondsklabel_to_vtoc(dsk_label_t * lblp,struct vtoc * vtocp)602*0Sstevel@tonic-gate pcdsklbl_ondsklabel_to_vtoc(dsk_label_t *lblp, struct vtoc *vtocp)
603*0Sstevel@tonic-gate {
604*0Sstevel@tonic-gate 
605*0Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
606*0Sstevel@tonic-gate 	bcopy((caddr_t)&lblp->ondsklbl.dkl_vtoc, (caddr_t)vtocp,
607*0Sstevel@tonic-gate 		sizeof (*vtocp));
608*0Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_8)
609*0Sstevel@tonic-gate 	int i;
610*0Sstevel@tonic-gate 	uint32_t nblks;
611*0Sstevel@tonic-gate 	struct dk_map2 *lpart;
612*0Sstevel@tonic-gate #ifdef _SYSCALL32
613*0Sstevel@tonic-gate 	struct dk_map32 *lmap;
614*0Sstevel@tonic-gate #else
615*0Sstevel@tonic-gate 	struct dk_map	*lmap;
616*0Sstevel@tonic-gate #endif
617*0Sstevel@tonic-gate 	struct partition *vpart;
618*0Sstevel@tonic-gate 	/*
619*0Sstevel@tonic-gate 	 * Data is originated from vtoc. One copy of the data is stored in
620*0Sstevel@tonic-gate 	 * lblp->ondsklbl. This is what we think of as the copy of the label
621*0Sstevel@tonic-gate 	 * on the disk held in memory. The other copy (to the lbp) is to be
622*0Sstevel@tonic-gate 	 * written out to the disk.
623*0Sstevel@tonic-gate 	 */
624*0Sstevel@tonic-gate 
625*0Sstevel@tonic-gate 	/*
626*0Sstevel@tonic-gate 	 * Put appropriate vtoc structure fields into the disk label
627*0Sstevel@tonic-gate 	 *
628*0Sstevel@tonic-gate 	 */
629*0Sstevel@tonic-gate 	bcopy((caddr_t)(lblp->ondsklbl.dkl_vtoc.v_bootinfo),
630*0Sstevel@tonic-gate 		(caddr_t)vtocp->v_bootinfo, sizeof (vtocp->v_bootinfo));
631*0Sstevel@tonic-gate 
632*0Sstevel@tonic-gate 	/* For now may want to add the sectorsz field to the generic structur */
633*0Sstevel@tonic-gate 	vtocp->v_sectorsz = NBPSCTR;	/* sector size in bytes */
634*0Sstevel@tonic-gate 
635*0Sstevel@tonic-gate 	vtocp->v_sanity = lblp->ondsklbl.dkl_vtoc.v_sanity;
636*0Sstevel@tonic-gate 	vtocp->v_version = lblp->ondsklbl.dkl_vtoc.v_version;
637*0Sstevel@tonic-gate 
638*0Sstevel@tonic-gate 	bcopy((caddr_t)lblp->ondsklbl.dkl_vtoc.v_volume,
639*0Sstevel@tonic-gate 		(caddr_t)vtocp->v_volume, LEN_DKL_VVOL);
640*0Sstevel@tonic-gate 
641*0Sstevel@tonic-gate 	vtocp->v_nparts = lblp->ondsklbl.dkl_vtoc.v_nparts;
642*0Sstevel@tonic-gate 
643*0Sstevel@tonic-gate 	bcopy((caddr_t)lblp->ondsklbl.dkl_vtoc.v_reserved,
644*0Sstevel@tonic-gate 		(caddr_t)vtocp->v_reserved, sizeof (vtocp->v_reserved));
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate 	/*
647*0Sstevel@tonic-gate 	 * Note the conversion from starting sector number
648*0Sstevel@tonic-gate 	 * to starting cylinder number.
649*0Sstevel@tonic-gate 	 */
650*0Sstevel@tonic-gate 	/* Bug Check this		*/
651*0Sstevel@tonic-gate 	nblks = lblp->ondsklbl.dkl_nsect * lblp->ondsklbl.dkl_nhead;
652*0Sstevel@tonic-gate 
653*0Sstevel@tonic-gate 	lmap = lblp->ondsklbl.dkl_map;
654*0Sstevel@tonic-gate 	lpart = (struct dk_map2 *)lblp->ondsklbl.dkl_vtoc.v_part;
655*0Sstevel@tonic-gate 	vpart = vtocp->v_part;
656*0Sstevel@tonic-gate 
657*0Sstevel@tonic-gate 	for (i = 0; i < (int)vtocp->v_nparts; i++) {
658*0Sstevel@tonic-gate 		vpart->p_tag = lpart->p_tag;
659*0Sstevel@tonic-gate 		vpart->p_flag = lpart->p_flag;
660*0Sstevel@tonic-gate 		vpart->p_start = lmap->dkl_cylno * nblks;
661*0Sstevel@tonic-gate 		vpart->p_size = lmap->dkl_nblk;
662*0Sstevel@tonic-gate 
663*0Sstevel@tonic-gate 		lmap++;
664*0Sstevel@tonic-gate 		lpart++;
665*0Sstevel@tonic-gate 		vpart++;
666*0Sstevel@tonic-gate 	}
667*0Sstevel@tonic-gate 
668*0Sstevel@tonic-gate 	bcopy((caddr_t)lblp->ondsklbl.dkl_vtoc.v_timestamp,
669*0Sstevel@tonic-gate 		(caddr_t)vtocp->timestamp, sizeof (vtocp->timestamp));
670*0Sstevel@tonic-gate 
671*0Sstevel@tonic-gate 	bcopy((caddr_t)lblp->ondsklbl.dkl_asciilabel,
672*0Sstevel@tonic-gate 		(caddr_t)vtocp->v_asciilabel,
673*0Sstevel@tonic-gate 		LEN_DKL_ASCII);
674*0Sstevel@tonic-gate 
675*0Sstevel@tonic-gate #else
676*0Sstevel@tonic-gate #error No VTOC format defined.
677*0Sstevel@tonic-gate #endif
678*0Sstevel@tonic-gate }
679*0Sstevel@tonic-gate 
680*0Sstevel@tonic-gate void
pcdsklbl_vtoc_to_ondsklabel(dsk_label_t * lblp,struct vtoc * vtocp)681*0Sstevel@tonic-gate pcdsklbl_vtoc_to_ondsklabel(dsk_label_t *lblp, struct vtoc *vtocp)
682*0Sstevel@tonic-gate {
683*0Sstevel@tonic-gate #if defined(_SUNOS_VTOC_16)
684*0Sstevel@tonic-gate 	bcopy((caddr_t)vtocp, (caddr_t)&(lblp->ondsklbl.dkl_vtoc),
685*0Sstevel@tonic-gate 							sizeof (*vtocp));
686*0Sstevel@tonic-gate #elif defined(_SUNOS_VTOC_8)
687*0Sstevel@tonic-gate 	/*
688*0Sstevel@tonic-gate 	 * Put appropriate vtoc structure fields into the disk label
689*0Sstevel@tonic-gate 	 *
690*0Sstevel@tonic-gate 	 */
691*0Sstevel@tonic-gate 	{
692*0Sstevel@tonic-gate 	int i;
693*0Sstevel@tonic-gate 	uint32_t nblks;
694*0Sstevel@tonic-gate 	struct dk_map2 *lpart;
695*0Sstevel@tonic-gate #ifdef _SYSCALL32
696*0Sstevel@tonic-gate 	struct dk_map32 *lmap;
697*0Sstevel@tonic-gate #else
698*0Sstevel@tonic-gate 	struct dk_map	*lmap;
699*0Sstevel@tonic-gate #endif
700*0Sstevel@tonic-gate 	struct partition *vpart;
701*0Sstevel@tonic-gate 	register struct dk_label *dp;
702*0Sstevel@tonic-gate 
703*0Sstevel@tonic-gate 	/*
704*0Sstevel@tonic-gate 	 * Data is originated from vtoc. One copy of the data is stored in
705*0Sstevel@tonic-gate 	 * lblp->ondsklbl. This is what we think of as the copy of the label
706*0Sstevel@tonic-gate 	 * on this disk held in memory.
707*0Sstevel@tonic-gate 	 */
708*0Sstevel@tonic-gate 
709*0Sstevel@tonic-gate 	dp = &lblp->ondsklbl;
710*0Sstevel@tonic-gate 
711*0Sstevel@tonic-gate 	bcopy((caddr_t)vtocp->v_bootinfo,
712*0Sstevel@tonic-gate 		(caddr_t)(lblp->ondsklbl.dkl_vtoc.v_bootinfo),
713*0Sstevel@tonic-gate 		sizeof (vtocp->v_bootinfo));
714*0Sstevel@tonic-gate 
715*0Sstevel@tonic-gate 	lblp->ondsklbl.dkl_vtoc.v_sanity = vtocp->v_sanity;
716*0Sstevel@tonic-gate 	lblp->ondsklbl.dkl_vtoc.v_version = vtocp->v_version;
717*0Sstevel@tonic-gate 
718*0Sstevel@tonic-gate 	bcopy((caddr_t)vtocp->v_volume,
719*0Sstevel@tonic-gate 		(caddr_t)lblp->ondsklbl.dkl_vtoc.v_volume,
720*0Sstevel@tonic-gate 		LEN_DKL_VVOL);
721*0Sstevel@tonic-gate 
722*0Sstevel@tonic-gate 	lblp->ondsklbl.dkl_vtoc.v_nparts = vtocp->v_nparts;
723*0Sstevel@tonic-gate 
724*0Sstevel@tonic-gate 	bcopy((caddr_t)vtocp->v_reserved,
725*0Sstevel@tonic-gate 		(caddr_t)lblp->ondsklbl.dkl_vtoc.v_reserved,
726*0Sstevel@tonic-gate 		sizeof (vtocp->v_reserved));
727*0Sstevel@tonic-gate 
728*0Sstevel@tonic-gate 	/*
729*0Sstevel@tonic-gate 	 * Note the conversion from starting sector number
730*0Sstevel@tonic-gate 	 * to starting cylinder number.
731*0Sstevel@tonic-gate 	 */
732*0Sstevel@tonic-gate 	nblks = dp->dkl_nsect * dp->dkl_nhead;
733*0Sstevel@tonic-gate 	lmap = lblp->ondsklbl.dkl_map;
734*0Sstevel@tonic-gate 	lpart = (struct dk_map2 *)lblp->ondsklbl.dkl_vtoc.v_part;
735*0Sstevel@tonic-gate 	vpart = vtocp->v_part;
736*0Sstevel@tonic-gate 
737*0Sstevel@tonic-gate 	for (i = 0; i < (int)vtocp->v_nparts; i++) {
738*0Sstevel@tonic-gate 		lpart->p_tag  = vpart->p_tag;
739*0Sstevel@tonic-gate 		lpart->p_flag = vpart->p_flag;
740*0Sstevel@tonic-gate 		lmap->dkl_cylno = vpart->p_start / nblks;
741*0Sstevel@tonic-gate 		lmap->dkl_nblk = vpart->p_size;
742*0Sstevel@tonic-gate 
743*0Sstevel@tonic-gate 		lmap++;
744*0Sstevel@tonic-gate 		lpart++;
745*0Sstevel@tonic-gate 		vpart++;
746*0Sstevel@tonic-gate 	}
747*0Sstevel@tonic-gate 
748*0Sstevel@tonic-gate 	bcopy((caddr_t)vtocp->timestamp,
749*0Sstevel@tonic-gate 		(caddr_t)lblp->ondsklbl.dkl_vtoc.v_timestamp,
750*0Sstevel@tonic-gate 		sizeof (vtocp->timestamp));
751*0Sstevel@tonic-gate 
752*0Sstevel@tonic-gate 	bcopy((caddr_t)vtocp->v_asciilabel,
753*0Sstevel@tonic-gate 		(caddr_t)lblp->ondsklbl.dkl_asciilabel,
754*0Sstevel@tonic-gate 		LEN_DKL_ASCII);
755*0Sstevel@tonic-gate 
756*0Sstevel@tonic-gate 	}
757*0Sstevel@tonic-gate #else
758*0Sstevel@tonic-gate #error No VTOC format defined.
759*0Sstevel@tonic-gate #endif
760*0Sstevel@tonic-gate 
761*0Sstevel@tonic-gate 	lblp->ondsklbl.dkl_cksum = 0;
762*0Sstevel@tonic-gate 	(void) pcdsklbl_chk(&lblp->ondsklbl, &(lblp->ondsklbl.dkl_cksum));
763*0Sstevel@tonic-gate }
764*0Sstevel@tonic-gate 
765*0Sstevel@tonic-gate void
pcdsklbl_dgtoug(struct dk_geom * up,struct dk_label * dp)766*0Sstevel@tonic-gate pcdsklbl_dgtoug(struct dk_geom *up, struct dk_label *dp)
767*0Sstevel@tonic-gate {
768*0Sstevel@tonic-gate 
769*0Sstevel@tonic-gate #ifdef ATA_DEBUG
770*0Sstevel@tonic-gate 	cmn_err(CE_CONT, "pcdsklbl_dgtoug:  pcyl = %d ncyl = %d acyl = %d"
771*0Sstevel@tonic-gate 		" head= %d sect = %d intrlv = %d \n",
772*0Sstevel@tonic-gate 		dp->dkl_pcyl,
773*0Sstevel@tonic-gate 		dp->dkl_ncyl,
774*0Sstevel@tonic-gate 		dp->dkl_acyl,
775*0Sstevel@tonic-gate 		dp->dkl_nhead,
776*0Sstevel@tonic-gate 		dp->dkl_nsect,
777*0Sstevel@tonic-gate 		dp->dkl_intrlv);
778*0Sstevel@tonic-gate #endif
779*0Sstevel@tonic-gate 
780*0Sstevel@tonic-gate 	up->dkg_pcyl   = dp->dkl_pcyl;
781*0Sstevel@tonic-gate 	up->dkg_ncyl   = dp->dkl_ncyl;
782*0Sstevel@tonic-gate 	up->dkg_acyl   = dp->dkl_acyl;
783*0Sstevel@tonic-gate #if !defined(__sparc)
784*0Sstevel@tonic-gate 	up->dkg_bcyl   = dp->dkl_bcyl;
785*0Sstevel@tonic-gate #endif
786*0Sstevel@tonic-gate 	up->dkg_nhead  = dp->dkl_nhead;
787*0Sstevel@tonic-gate 	up->dkg_nsect  = dp->dkl_nsect;
788*0Sstevel@tonic-gate 	up->dkg_intrlv = dp->dkl_intrlv;
789*0Sstevel@tonic-gate 	up->dkg_apc    = dp->dkl_apc;
790*0Sstevel@tonic-gate 	up->dkg_rpm    = dp->dkl_rpm;
791*0Sstevel@tonic-gate 	up->dkg_write_reinstruct = dp->dkl_write_reinstruct;
792*0Sstevel@tonic-gate 	up->dkg_read_reinstruct  = dp->dkl_read_reinstruct;
793*0Sstevel@tonic-gate }
794*0Sstevel@tonic-gate 
795*0Sstevel@tonic-gate 
796*0Sstevel@tonic-gate 
797*0Sstevel@tonic-gate 
798*0Sstevel@tonic-gate void
pcdsklbl_ugtodg(struct dk_geom * up,struct dk_label * dp)799*0Sstevel@tonic-gate pcdsklbl_ugtodg(struct dk_geom *up, struct dk_label *dp)
800*0Sstevel@tonic-gate {
801*0Sstevel@tonic-gate 	dp->dkl_pcyl   = up->dkg_pcyl;
802*0Sstevel@tonic-gate 	dp->dkl_ncyl   = up->dkg_ncyl;
803*0Sstevel@tonic-gate 	dp->dkl_acyl   = up->dkg_acyl;
804*0Sstevel@tonic-gate #if !defined(__sparc)
805*0Sstevel@tonic-gate 	dp->dkl_bcyl   = up->dkg_bcyl;
806*0Sstevel@tonic-gate #endif
807*0Sstevel@tonic-gate 	dp->dkl_nhead  = up->dkg_nhead;
808*0Sstevel@tonic-gate 	dp->dkl_nsect  = up->dkg_nsect;
809*0Sstevel@tonic-gate 	dp->dkl_intrlv = up->dkg_intrlv;
810*0Sstevel@tonic-gate 	dp->dkl_apc    = up->dkg_apc;
811*0Sstevel@tonic-gate 	dp->dkl_rpm    = up->dkg_rpm;
812*0Sstevel@tonic-gate 	dp->dkl_write_reinstruct = up->dkg_write_reinstruct;
813*0Sstevel@tonic-gate 	dp->dkl_read_reinstruct  = up->dkg_read_reinstruct;
814*0Sstevel@tonic-gate }
815