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