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