1 /* $NetBSD: devopen.c,v 1.2 2018/03/06 22:13:14 christos Exp $ */
2
3 /*-
4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Ralph Campbell.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * @(#)devopen.c 8.1 (Berkeley) 6/10/93
35 */
36
37 #include <lib/libsa/stand.h>
38 #include <lib/libkern/libkern.h>
39
40 /*
41 * Decode the string 'fname', open the device and return the remaining
42 * file name if any.
43 */
44 int
devopen(struct open_file * f,const char * fname,char ** file)45 devopen(struct open_file *f,
46 const char *fname,
47 char **file) /* out */
48 {
49 int ctlr = 0, unit = 0, part = 0;
50 int c, rc;
51 char device_name[20];
52 const char *cp;
53 char *ncp;
54 #if !defined(LIBSA_SINGLE_DEVICE)
55 int i;
56 struct devsw *dp;
57 #endif
58
59 cp = fname;
60 ncp = device_name;
61
62 /*
63 * Require the form CTRL/DEVNAME(UNIT,PART)/FILENAME
64 * e.g. '0/ace(0,0)/netbsd' '0/tftp(0,0)/netbsd'
65 */
66
67 /* get controller number */
68 c = *cp++;
69 if (c < '0' || c > '9')
70 return ENXIO;
71 ctlr = c - '0';
72
73 c = *cp++;
74 if (c != '/')
75 return ENXIO;
76
77 /* get device name */
78 while ((c = *cp) != '\0') {
79 if ((c == '(') || (c == '/')) {
80 cp++;
81 break;
82 }
83 if (ncp < device_name + sizeof(device_name) - 1)
84 *ncp++ = c;
85 cp++;
86 }
87 if (ncp == device_name)
88 return ENXIO;
89
90 /* get device number */
91 c = *cp++;
92 if (c < '0' || c > '9')
93 return ENXIO;
94 unit = c - '0';
95
96 c = *cp++;
97 if (c != ',')
98 return (ENXIO);
99
100 /* get partition number */
101 c = *cp++;
102 if (c < '0' || c > '9')
103 return ENXIO;
104 part = c - '0';
105
106 c = *cp++;
107 if (c != ')')
108 return ENXIO;
109
110 *ncp = '\0';
111
112 #ifdef LIBSA_SINGLE_DEVICE
113 rc = DEV_OPEN(dp)(f, ctlr, unit, part);
114 #else /* !LIBSA_SINGLE_DEVICE */
115 for (dp = devsw, i = 0; i < ndevs; dp++, i++)
116 if (dp->dv_name && strcmp(device_name, dp->dv_name) == 0)
117 goto fnd;
118 printf("Unknown device '%s'\nKnown devices are:", device_name);
119 for (dp = devsw, i = 0; i < ndevs; dp++, i++)
120 if (dp->dv_name)
121 printf(" %s", dp->dv_name);
122 printf("\n");
123 return ENXIO;
124
125 fnd:
126 #ifdef BOOTNET
127 if (strcmp(device_name, "tftp") == 0)
128 rc = (dp->dv_open)(f, device_name);
129 else
130 #endif /* BOOTNET */
131 rc = (dp->dv_open)(f, ctlr, unit, part, cp);
132 #endif /* !LIBSA_SINGLE_DEVICE */
133 if (rc)
134 return rc;
135
136 #ifndef LIBSA_SINGLE_DEVICE
137 f->f_dev = dp;
138 #endif
139 if (file && *cp != '\0')
140 *file = (char *)cp; /* XXX */
141 return 0;
142 }
143