xref: /netbsd-src/sys/arch/prep/stand/boot/devopen.c (revision 481fca6e59249d8ffcf24fef7cfbe7b131bfb080)
1 /*	$NetBSD: devopen.c,v 1.1 2000/02/29 15:21:49 nonaka 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 <lib/libsa/stand.h>
32 
33 #define	ispart(c)	((c) >= 'a' && (c) <= 'h')
34 
35 int atoi __P((char *));
36 int devlookup __P((char *));
37 int devparse __P((const char *, int *, int *, int *, int *, int *, char **));
38 
39 int
40 atoi(cp)
41 	char *cp;
42 {
43 	int val = 0;
44 
45 	while (isdigit(*cp))
46 		val = val * 10 + (*cp++ - '0');
47 	return (val);
48 }
49 
50 int
51 devlookup(d)
52 	char *d;
53 {
54 	struct devsw *dp = devsw;
55 	int i;
56 
57 	for (i = 0; i < ndevs; i++, dp++)
58 		if (dp->dv_name && strcmp(dp->dv_name, d) == 0)
59 			return (i);
60 
61 	printf("No such device - Configured devices are:\n");
62 	for (dp = devsw, i = 0; i < ndevs; i++, dp++)
63 		if (dp->dv_name)
64 			printf(" %s", dp->dv_name);
65 	printf("\n");
66 	return (-1);
67 }
68 
69 /*
70  * Parse a device spec in one of two forms.
71  *   dev(ctlr, unit, part)file
72  */
73 int
74 devparse(fname, dev, adapt, ctlr, unit, part, file)
75 	const char *fname;
76 	int *dev;
77 	int *adapt;
78 	int *ctlr;
79 	int *unit;
80 	int *part;
81 	char **file;
82 {
83 	int argc, flag;
84 	char *s, *args[3];
85 	extern char nametmp[];
86 
87 	/* get device name and make lower case */
88 	strcpy(nametmp, (char *)fname);
89 	for (s = nametmp; *s && *s != '('; s++)
90 		if (isupper(*s)) *s = tolower(*s);
91 
92 	if (*s == '(') {
93 		/* lookup device and get index */
94 		*s = NULL;
95 		if ((*dev = devlookup(nametmp)) < 0)
96 		    goto baddev;
97 
98 		/* tokenize device ident */
99 		for (++s, flag = 0, argc = 0; *s && *s != ')'; s++) {
100 			if (*s != ',') {
101 				if (!flag) {
102 					flag++;
103 					args[argc++] = s;
104 				}
105 			} else {
106 				if (flag) {
107 					*s = NULL;
108 					flag = 0;
109 				}
110 			}
111 		}
112 		if (*s == ')')
113 			*s = NULL;
114 
115 		switch (argc) {
116 		case 3:
117 		    *part = atoi(args[2]);
118 		    /* FALL THROUGH */
119 		case 2:
120 		    *unit = atoi(args[1]);
121 		    /* FALL THROUGH */
122 		case 1:
123 		    *ctlr = atoi(args[0]);
124 		    break;
125 		}
126 		*file = ++s;
127 	} else {
128 		/* no device present */
129 		*file = (char *)fname;
130 	}
131 	return (0);
132 
133 baddev:
134 	return (EINVAL);
135 }
136 
137 int
138 devopen(f, fname, file)
139 	struct open_file *f;
140 	const char *fname;
141 	char **file;
142 {
143 	int error;
144 	int dev = 0, ctlr = 0, unit = 0, part = 0;
145 	int adapt = 0;
146 	struct devsw *dp = &devsw[0];
147 
148 	if ((error =
149 	    devparse(fname, &dev, &adapt, &ctlr, &unit, &part, file)) != 0)
150 		return (error);
151 
152 	dp = &devsw[dev];
153 	if (!dp->dv_open)
154 		return (ENODEV);
155 
156 	f->f_dev = dp;
157 	if ((error = (*dp->dv_open)(f, ctlr, unit, part)) == 0)
158 		return (0);
159 
160 	printf("%s(%d,%d,%d): %s\n", devsw[dev].dv_name,
161 		ctlr, unit, part, strerror(error));
162 
163 	return (error);
164 }
165