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