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