xref: /csrg-svn/sys/hp300/stand/label.c (revision 63165)
157298Shibler /*
257298Shibler  * Copyright (c) 1992 University of Utah.
3*63165Sbostic  * Copyright (c) 1982, 1986, 1988, 1993
4*63165Sbostic  *	The Regents of the University of California.  All rights reserved.
557298Shibler  *
657298Shibler  * This code is derived from software contributed to Berkeley by
757298Shibler  * the Systems Programming Group of the University of Utah Computer
857298Shibler  * Science Department.
957298Shibler  *
1057298Shibler  * %sccs.include.redist.c%
1157298Shibler  *
1257298Shibler  * from: Utah $Hdr: label.c 1.1 92/12/05$
1357298Shibler  *
14*63165Sbostic  *	@(#)label.c	8.1 (Berkeley) 06/10/93
1557298Shibler  */
1657298Shibler 
1757298Shibler /*
1857298Shibler  * Derived from routines in ufs/ufs/ufs_disksubr.c.
1957298Shibler  */
2057298Shibler 
2157298Shibler #include <sys/param.h>
2257298Shibler #include <sys/disklabel.h>
2360329Smckusick #include <stand.att/saio.h>
2457298Shibler 
2557298Shibler /*
2657298Shibler  * Attempt to read a disk label from a device using the indicated stategy
2757298Shibler  * routine.  Returns NULL on success and an error string on failure.
2857298Shibler  */
2957298Shibler char *
readdisklabel(io,strat,lp)3057298Shibler readdisklabel(io, strat, lp)
3157298Shibler 	struct iob *io;
3257298Shibler 	int (*strat)();
3357298Shibler 	register struct disklabel *lp;
3457298Shibler {
3557298Shibler 	struct iob liob;
3657298Shibler 	struct disklabel *dlp;
3757298Shibler 	char *msg = NULL;
3857298Shibler 
3957298Shibler 	liob.i_adapt = io->i_adapt;
4057298Shibler 	liob.i_ctlr = io->i_ctlr;
4157298Shibler 	liob.i_unit = io->i_unit;
4257298Shibler 	liob.i_part = 2;
4357298Shibler 	liob.i_boff = 0;
4457298Shibler 	liob.i_cyloff = 0;
4557298Shibler 	liob.i_bn = LABELSECTOR;
4657298Shibler 	liob.i_ma = liob.i_buf;
4757298Shibler 	liob.i_cc = lp->d_secsize ? lp->d_secsize : DEV_BSIZE;
4857298Shibler 	if ((*strat)(&liob, F_READ) == -1)
4957298Shibler 		return ("I/O error");
5057298Shibler 
5157298Shibler 	for (dlp = (struct disklabel *)liob.i_buf;
5257298Shibler 	     dlp <= (struct disklabel *)(liob.i_buf+DEV_BSIZE-sizeof(*dlp));
5357298Shibler 	     dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
5457298Shibler 		if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
5557298Shibler 			if (msg == NULL)
5657298Shibler 				msg = "no disk label";
5757298Shibler 		} else if (dlp->d_npartitions > MAXPARTITIONS || dkcksum(dlp))
5857298Shibler 			msg = "disk label corrupted";
5957298Shibler 		else {
6057298Shibler 			*lp = *dlp;
6157298Shibler 			msg = NULL;
6257298Shibler 			break;
6357298Shibler 		}
6457298Shibler 	}
6557298Shibler 	return (msg);
6657298Shibler }
6757298Shibler 
6857298Shibler /*
6957298Shibler  * Compute checksum for disk label.
7057298Shibler  */
dkcksum(lp)7157298Shibler dkcksum(lp)
7257298Shibler 	register struct disklabel *lp;
7357298Shibler {
7457298Shibler 	register u_short *start, *end;
7557298Shibler 	register u_short sum = 0;
7657298Shibler 
7757298Shibler 	start = (u_short *)lp;
7857298Shibler 	end = (u_short *)&lp->d_partitions[lp->d_npartitions];
7957298Shibler 	while (start < end)
8057298Shibler 		sum ^= *start++;
8157298Shibler 	return (sum);
8257298Shibler }
83