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