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