xref: /csrg-svn/sys/hp300/stand/label.c (revision 57298)
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