Annotation of sys/arch/hp300/stand/libsa/devopen.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: devopen.c,v 1.4 2006/08/17 06:31:10 miod Exp $ */
2: /* $NetBSD: devopen.c,v 1.7 1996/10/14 07:31:47 thorpej Exp $ */
3:
4: /*-
5: * Copyright (c) 1996 Jason R. Thorpe. All rights reserved.
6: * Copyright (c) 1993 John Brezak
7: * All rights reserved.
8: *
9: * Redistribution and use in source and binary forms, with or without
10: * modification, are permitted provided that the following conditions
11: * are met:
12: * 1. Redistributions of source code must retain the above copyright
13: * notice, this list of conditions and the following disclaimer.
14: * 2. Redistributions in binary form must reproduce the above copyright
15: * notice, this list of conditions and the following disclaimer in the
16: * documentation and/or other materials provided with the distribution.
17: * 3. The name of the author may not be used to endorse or promote products
18: * derived from this software without specific prior written permission.
19: *
20: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
21: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
24: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30: * POSSIBILITY OF SUCH DAMAGE.
31: */
32:
33: #include <sys/param.h>
34: #include <sys/reboot.h>
35:
36: #include <lib/libsa/stand.h>
37:
38: #include "samachdep.h"
39:
40: int atoi(char *);
41: int devlookup(const char *, int);
42: int devopen(struct open_file *, const char *, char **);
43: int devparse(const char *, int *, int *, int *, int *, int *, char **);
44: void usage(void);
45:
46: u_int opendev;
47:
48: #define ispart(c) ((c) >= 'a' && (c) <= 'h')
49:
50: int
51: atoi(char *cp)
52: {
53: int val = 0;
54:
55: while(isdigit(*cp))
56: val = val * 10 + (*cp++ - '0');
57: return(val);
58: }
59:
60: void
61: usage()
62: {
63: printf("Usage: device(adaptor, controller, drive, partition)file\n"
64: " <device><unit><partitionletter>:file\n");
65: }
66:
67: int
68: devlookup(const char *d, int len)
69: {
70: struct devsw *dp = devsw;
71: int i;
72:
73: for (i = 0; i < ndevs; i++, dp++) {
74: if (dp->dv_name && strncmp(dp->dv_name, d, len) == 0) {
75: /*
76: * Set the filesystem and startup up according to
77: * the device being opened.
78: */
79: switch (i) {
80: case 0: /* ct */
81: bcopy(file_system_rawfs, file_system,
82: sizeof(struct fs_ops));
83: break;
84:
85: case 2: /* hd */
86: bcopy(file_system_ufs, file_system,
87: sizeof(struct fs_ops));
88: break;
89:
90: case 4: /* sd */
91: bcopy(file_system_ufs, file_system,
92: sizeof(struct fs_ops));
93: bcopy(file_system_cd9660, &file_system[1],
94: sizeof(struct fs_ops));
95: nfsys = 2;
96: break;
97:
98: case 6: /* le */
99: bcopy(file_system_nfs, file_system,
100: sizeof(struct fs_ops));
101: break;
102:
103: default:
104: /* Agh! What happened?! */
105: goto bad;
106: }
107: return(i);
108: }
109: }
110:
111: bad:
112: printf("No such device - Configured devices are:\n");
113: for (dp = devsw, i = 0; i < ndevs; i++, dp++)
114: if (dp->dv_name)
115: printf(" %s", dp->dv_name);
116: printf("\n");
117: errno = ENODEV;
118: return(-1);
119: }
120:
121: /*
122: * Parse a device spec in one of two forms.
123: *
124: * dev(adapt, ctlr, unit, part)file
125: * [A-Za-z]*[0-9]*[A-Za-z]:file
126: * dev unit part
127: */
128: int
129: devparse(const char *fname, int *dev, int *adapt, int *ctlr, int *unit,
130: int *part, char **file)
131: {
132: int i;
133: char *s, *args[4];
134:
135: /* get device name and make lower case */
136: for (s = (char *)fname; *s && *s != '/' && *s != ':' && *s != '('; s++)
137: if (isupper(*s)) *s = tolower(*s);
138:
139: /* first form */
140: if (*s == '(') {
141: /* lookup device and get index */
142: if ((*dev = devlookup(fname, s - fname)) < 0)
143: goto baddev;
144:
145: /* tokenize device ident */
146: args[0] = ++s;
147: for (args[0] = s, i = 1; *s && *s != ')'; s++) {
148: if (*s == ',')
149: args[i++] = ++s;
150: }
151: switch(i) {
152: case 4:
153: *adapt = atoi(args[0]);
154: *ctlr = atoi(args[1]);
155: *unit = atoi(args[2]);
156: *part = atoi(args[3]);
157: break;
158: case 3:
159: *ctlr = atoi(args[0]);
160: *unit = atoi(args[1]);
161: *part = atoi(args[2]);
162: break;
163: case 2:
164: *unit = atoi(args[0]);
165: *part = atoi(args[1]);
166: break;
167: case 1:
168: *part = atoi(args[0]);
169: break;
170: case 0:
171: break;
172: }
173: *file = ++s;
174: }
175:
176: /* second form */
177: else if (*s == ':') {
178: int temp;
179:
180: /* isolate device */
181: for (s = (char *)fname; *s != ':' && !isdigit(*s); s++);
182:
183: /* lookup device and get index */
184: if ((*dev = devlookup(fname, s - fname)) < 0)
185: goto baddev;
186:
187: /* isolate unit */
188: if ((temp = atoi(s)) > 255)
189: goto bad;
190: *adapt = temp / 8;
191: *ctlr = temp % 8;
192: for (; isdigit(*s); s++);
193:
194: /* translate partition */
195: if (!ispart(*s))
196: goto bad;
197:
198: *part = *s++ - 'a';
199: if (*s != ':')
200: goto bad;
201: *file = ++s;
202: }
203:
204: /* no device present */
205: else
206: *file = (char *)fname;
207:
208: /* return the remaining unparsed part as the file to boot */
209: return(0);
210:
211: bad:
212: usage();
213:
214: baddev:
215: return(-1);
216: }
217:
218: int
219: devopen(struct open_file *f, const char *fname, char **file)
220: {
221: int error;
222: int dev, adapt, ctlr, unit, part;
223: struct devsw *dp = &devsw[0];
224:
225: dev = B_TYPE(bootdev);
226: adapt = B_ADAPTOR(bootdev);
227: ctlr = B_CONTROLLER(bootdev);
228: unit = B_UNIT(bootdev);
229: part = B_PARTITION(bootdev);
230:
231: if ((error = devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file)))
232: return(error);
233:
234: /*
235: * Set up filesystem type based on what device we're opening.
236: */
237: switch (dev) {
238: case 0: /* ct */
239: bcopy(file_system_rawfs, file_system, sizeof(struct fs_ops));
240: break;
241:
242: case 2: /* hd */
243: bcopy(file_system_ufs, file_system, sizeof(struct fs_ops));
244: break;
245:
246: case 4: /* sd */
247: bcopy(file_system_ufs, file_system, sizeof(struct fs_ops));
248: bcopy(file_system_cd9660, &file_system[1],
249: sizeof(struct fs_ops));
250: nfsys = 2;
251: break;
252:
253: case 6: /* le */
254: bcopy(file_system_nfs, file_system, sizeof(struct fs_ops));
255: break;
256:
257: default:
258: /* XXX what else should we do here? */
259: printf("WARNING: BOGUS BOOT DEV TYPE 0x%x!\n", dev);
260: return (EIO);
261: }
262:
263: dp = &devsw[dev];
264:
265: if (!dp->dv_open)
266: return(ENODEV);
267:
268: f->f_dev = dp;
269:
270: if ((error = (*dp->dv_open)(f, adapt, ctlr, part)) == 0) {
271: if ((error =
272: (*punitsw[dev].p_punit)(adapt, ctlr, &unit)) != 0) {
273: goto bad;
274: }
275: opendev = MAKEBOOTDEV(dev, adapt, ctlr, unit, part);
276: return(0);
277: }
278:
279: bad:
280: printf("%s(%d,%d,%d,%d): %s\n", devsw[dev].dv_name,
281: adapt, ctlr, unit, part, strerror(error));
282:
283: return(error);
284: }
CVSweb