1*57298Shibler /* 2*57298Shibler * Copyright (c) 1992 University of Utah. 3*57298Shibler * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 4*57298Shibler * All rights reserved. 5*57298Shibler * 6*57298Shibler * This code is derived from software contributed to Berkeley by 7*57298Shibler * the Systems Programming Group of the University of Utah Computer 8*57298Shibler * Science Department. 9*57298Shibler * 10*57298Shibler * %sccs.include.redist.c% 11*57298Shibler * 12*57298Shibler * from: Utah $Hdr: label.c 1.1 92/12/05$ 13*57298Shibler * 14*57298Shibler * @(#)label.c 7.1 (Berkeley) 12/26/92 15*57298Shibler */ 16*57298Shibler 17*57298Shibler /* 18*57298Shibler * Derived from routines in ufs/ufs/ufs_disksubr.c. 19*57298Shibler */ 20*57298Shibler 21*57298Shibler #include <sys/param.h> 22*57298Shibler #include <sys/disklabel.h> 23*57298Shibler #include <stand/saio.h> 24*57298Shibler 25*57298Shibler /* 26*57298Shibler * Attempt to read a disk label from a device using the indicated stategy 27*57298Shibler * routine. Returns NULL on success and an error string on failure. 28*57298Shibler */ 29*57298Shibler char * 30*57298Shibler readdisklabel(io, strat, lp) 31*57298Shibler struct iob *io; 32*57298Shibler int (*strat)(); 33*57298Shibler register struct disklabel *lp; 34*57298Shibler { 35*57298Shibler struct iob liob; 36*57298Shibler struct disklabel *dlp; 37*57298Shibler char *msg = NULL; 38*57298Shibler 39*57298Shibler liob.i_adapt = io->i_adapt; 40*57298Shibler liob.i_ctlr = io->i_ctlr; 41*57298Shibler liob.i_unit = io->i_unit; 42*57298Shibler liob.i_part = 2; 43*57298Shibler liob.i_boff = 0; 44*57298Shibler liob.i_cyloff = 0; 45*57298Shibler liob.i_bn = LABELSECTOR; 46*57298Shibler liob.i_ma = liob.i_buf; 47*57298Shibler liob.i_cc = lp->d_secsize ? lp->d_secsize : DEV_BSIZE; 48*57298Shibler if ((*strat)(&liob, F_READ) == -1) 49*57298Shibler return ("I/O error"); 50*57298Shibler 51*57298Shibler for (dlp = (struct disklabel *)liob.i_buf; 52*57298Shibler dlp <= (struct disklabel *)(liob.i_buf+DEV_BSIZE-sizeof(*dlp)); 53*57298Shibler dlp = (struct disklabel *)((char *)dlp + sizeof(long))) { 54*57298Shibler if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) { 55*57298Shibler if (msg == NULL) 56*57298Shibler msg = "no disk label"; 57*57298Shibler } else if (dlp->d_npartitions > MAXPARTITIONS || dkcksum(dlp)) 58*57298Shibler msg = "disk label corrupted"; 59*57298Shibler else { 60*57298Shibler *lp = *dlp; 61*57298Shibler msg = NULL; 62*57298Shibler break; 63*57298Shibler } 64*57298Shibler } 65*57298Shibler return (msg); 66*57298Shibler } 67*57298Shibler 68*57298Shibler /* 69*57298Shibler * Compute checksum for disk label. 70*57298Shibler */ 71*57298Shibler dkcksum(lp) 72*57298Shibler register struct disklabel *lp; 73*57298Shibler { 74*57298Shibler register u_short *start, *end; 75*57298Shibler register u_short sum = 0; 76*57298Shibler 77*57298Shibler start = (u_short *)lp; 78*57298Shibler end = (u_short *)&lp->d_partitions[lp->d_npartitions]; 79*57298Shibler while (start < end) 80*57298Shibler sum ^= *start++; 81*57298Shibler return (sum); 82*57298Shibler } 83