devopen.c revision 1.3 1 /* $NetBSD: devopen.c,v 1.3 1999/06/28 01:20:44 sakamoto Exp $ */
2
3 /*-
4 * Copyright (c) 1993 John Brezak
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include <stand.h>
32 #include <sys/param.h>
33 #include <sys/reboot.h>
34
35 #define ispart(c) ((c) >= 'a' && (c) <= 'h')
36
37 int
38 atoi(cp)
39 char *cp;
40 {
41 int val = 0;
42
43 while (isdigit(*cp))
44 val = val * 10 + (*cp++ - '0');
45 return (val);
46 }
47
48 int
49 devlookup(d)
50 char *d;
51 {
52 struct devsw *dp = devsw;
53 int i;
54
55 for (i = 0; i < ndevs; i++, dp++)
56 if (dp->dv_name && strcmp(dp->dv_name, d) == 0)
57 return (i);
58
59 printf("No such device - Configured devices are:\n");
60 for (dp = devsw, i = 0; i < ndevs; i++, dp++)
61 if (dp->dv_name)
62 printf(" %s", dp->dv_name);
63 printf("\n");
64 return (-1);
65 }
66
67 /*
68 * Parse a device spec in one of two forms.
69 * dev(ctlr, unit, part)file
70 */
71 int
72 devparse(fname, dev, adapt, ctlr, unit, part, file)
73 const char *fname;
74 int *dev;
75 int *adapt;
76 int *ctlr;
77 int *unit;
78 int *part;
79 char **file;
80 {
81 int argc, flag;
82 char *s, *args[3];
83 extern char nametmp[];
84
85 /* get device name and make lower case */
86 strcpy(nametmp, (char *)fname);
87 for (s = nametmp; *s && *s != '('; s++)
88 if (isupper(*s)) *s = tolower(*s);
89
90 if (*s == '(') {
91 /* lookup device and get index */
92 *s = NULL;
93 if ((*dev = devlookup(nametmp, s - nametmp)) < 0)
94 goto baddev;
95
96 /* tokenize device ident */
97 for (++s, flag = 0, argc = 0; *s && *s != ')'; s++) {
98 if (*s != ',') {
99 if (!flag) {
100 flag++;
101 args[argc++] = s;
102 }
103 } else {
104 if (flag) {
105 *s = NULL;
106 flag = 0;
107 }
108 }
109 }
110 if (*s == ')')
111 *s = NULL;
112
113 switch (argc) {
114 case 3:
115 *part = atoi(args[2]);
116 /* FALL THROUGH */
117 case 2:
118 *unit = atoi(args[1]);
119 /* FALL THROUGH */
120 case 1:
121 *ctlr = atoi(args[0]);
122 break;
123 }
124 *file = ++s;
125 } else {
126 /* no device present */
127 *file = (char *)fname;
128 }
129 return (0);
130
131 baddev:
132 return (EINVAL);
133 }
134
135 int
136 devopen(f, fname, file)
137 struct open_file *f;
138 const char *fname;
139 char **file;
140 {
141 int error;
142 int dev = 0, ctlr = 0, unit = 0, part = 0;
143 int adapt = 0;
144 struct devsw *dp = &devsw[0];
145
146 if ((error =
147 devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file)) != 0)
148 return (error);
149
150 dp = &devsw[dev];
151 if (!dp->dv_open)
152 return (ENODEV);
153
154 f->f_dev = dp;
155 if ((error = (*dp->dv_open)(f, ctlr, unit, part)) == 0)
156 return (0);
157
158 printf("%s(%d,%d,%d): %s\n", devsw[dev].dv_name,
159 ctlr, unit, part, strerror(error));
160
161 return (error);
162 }
163