Annotation of sys/arch/alpha/alpha/disksubr.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: disksubr.c,v 1.89 2007/06/20 18:15:45 deraadt Exp $ */
2: /* $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $ */
3:
4: /*
5: * Copyright (c) 1997 Niklas Hallqvist
6: * Copyright (c) 1996 Theo de Raadt
7: * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
8: * All rights reserved.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. Neither the name of the University nor the names of its contributors
19: * may be used to endorse or promote products derived from this software
20: * without specific prior written permission.
21: *
22: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32: * SUCH DAMAGE.
33: */
34:
35: #include <sys/param.h>
36: #include <sys/systm.h>
37: #include <sys/buf.h>
38: #include <sys/disklabel.h>
39: #include <sys/disk.h>
40:
41: /*
42: * Attempt to read a disk label from a device
43: * using the indicated strategy routine.
44: * The label must be partly set up before this:
45: * secpercyl, secsize and anything required for a block i/o read
46: * operation in the driver's strategy/start routines
47: * must be filled in before calling us.
48: *
49: * Returns null on success and an error string on failure.
50: */
51: char *
52: readdisklabel(dev_t dev, void (*strat)(struct buf *),
53: struct disklabel *lp, int spoofonly)
54: {
55: struct buf *bp = NULL;
56: char *msg;
57:
58: if ((msg = initdisklabel(lp)))
59: goto done;
60:
61: /* get a buffer and initialize it */
62: bp = geteblk((int)lp->d_secsize);
63: bp->b_dev = dev;
64:
65: if (spoofonly)
66: goto doslabel;
67:
68: bp->b_blkno = LABELSECTOR;
69: bp->b_bcount = lp->d_secsize;
70: bp->b_flags = B_BUSY | B_READ;
71: (*strat)(bp);
72: if (biowait(bp)) {
73: msg = "disk label read error";
74: goto done;
75: }
76:
77: msg = checkdisklabel(bp->b_data + LABELOFFSET, lp);
78: if (msg == NULL)
79: goto done;
80:
81: doslabel:
82: msg = readdoslabel(bp, strat, lp, NULL, spoofonly);
83: if (msg == NULL)
84: goto done;
85:
86: #if defined(CD9660)
87: if (iso_disklabelspoof(dev, strat, lp) == 0) {
88: msg = NULL;
89: goto done;
90: }
91: #endif
92: #if defined(UDF)
93: if (udf_disklabelspoof(dev, strat, lp) == 0) {
94: msg = NULL;
95: goto done;
96: }
97: #endif
98:
99: done:
100: if (bp) {
101: bp->b_flags |= B_INVAL;
102: brelse(bp);
103: }
104: return (msg);
105: }
106:
107: /*
108: * Write disk label back to device after modification.
109: */
110: int
111: writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp)
112: {
113: u_int64_t csum = 0, *p;
114: struct disklabel *dlp;
115: struct buf *bp = NULL;
116: int error, i;
117:
118: /* get a buffer and initialize it */
119: bp = geteblk((int)lp->d_secsize);
120: bp->b_dev = dev;
121:
122: bp->b_blkno = LABELSECTOR;
123: bp->b_bcount = lp->d_secsize;
124: bp->b_flags = B_BUSY | B_READ;
125: (*strat)(bp);
126: if ((error = biowait(bp)) != 0)
127: goto done;
128:
129: /* Write it in the regular place. */
130: dlp = (struct disklabel *)(bp->b_data + LABELOFFSET);
131: *dlp = *lp;
132:
133: /* Alpha bootblocks require a checksum over the sector */
134: for (i = 0, p = (u_int64_t *)bp->b_data; i < 63; i++)
135: csum += *p++;
136: *p = csum;
137:
138: bp->b_flags = B_BUSY | B_WRITE;
139: (*strat)(bp);
140: error = biowait(bp);
141:
142: done:
143: if (bp) {
144: bp->b_flags |= B_INVAL;
145: brelse(bp);
146: }
147: return (error);
148: }
CVSweb