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