1ca987d46SWarner Losh /* $NetBSD: dev.c,v 1.4 1994/10/30 21:48:23 cgd Exp $ */
2ca987d46SWarner Losh
3ca987d46SWarner Losh /*-
4ca987d46SWarner Losh * Copyright (c) 1993
5ca987d46SWarner Losh * The Regents of the University of California. All rights reserved.
6ca987d46SWarner Losh *
7ca987d46SWarner Losh * Redistribution and use in source and binary forms, with or without
8ca987d46SWarner Losh * modification, are permitted provided that the following conditions
9ca987d46SWarner Losh * are met:
10ca987d46SWarner Losh * 1. Redistributions of source code must retain the above copyright
11ca987d46SWarner Losh * notice, this list of conditions and the following disclaimer.
12ca987d46SWarner Losh * 2. Redistributions in binary form must reproduce the above copyright
13ca987d46SWarner Losh * notice, this list of conditions and the following disclaimer in the
14ca987d46SWarner Losh * documentation and/or other materials provided with the distribution.
15ca987d46SWarner Losh * 3. Neither the name of the University nor the names of its contributors
16ca987d46SWarner Losh * may be used to endorse or promote products derived from this software
17ca987d46SWarner Losh * without specific prior written permission.
18ca987d46SWarner Losh *
19ca987d46SWarner Losh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20ca987d46SWarner Losh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21ca987d46SWarner Losh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22ca987d46SWarner Losh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23ca987d46SWarner Losh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24ca987d46SWarner Losh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25ca987d46SWarner Losh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26ca987d46SWarner Losh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27ca987d46SWarner Losh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28ca987d46SWarner Losh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29ca987d46SWarner Losh * SUCH DAMAGE.
30ca987d46SWarner Losh */
31ca987d46SWarner Losh
32ca987d46SWarner Losh #include <sys/param.h>
33ca987d46SWarner Losh #include <sys/reboot.h>
34ca987d46SWarner Losh
35ca987d46SWarner Losh #include "stand.h"
36ca987d46SWarner Losh
37ca987d46SWarner Losh int
nodev(void)381f629966SAlfonso nodev(void)
39ca987d46SWarner Losh {
40ca987d46SWarner Losh return (ENXIO);
41ca987d46SWarner Losh }
42ca987d46SWarner Losh
43ca987d46SWarner Losh void
nullsys(void)441f629966SAlfonso nullsys(void)
45ca987d46SWarner Losh {
46ca987d46SWarner Losh }
47ca987d46SWarner Losh
48ca987d46SWarner Losh /* ARGSUSED */
49ca987d46SWarner Losh int
noioctl(struct open_file * f __unused,u_long cmd __unused,void * data __unused)501f629966SAlfonso noioctl(struct open_file *f __unused, u_long cmd __unused, void *data __unused)
51ca987d46SWarner Losh {
52ca987d46SWarner Losh return (EINVAL);
53ca987d46SWarner Losh }
54dc472f67SWarner Losh
55dc472f67SWarner Losh char *
devformat(struct devdesc * d)56dc472f67SWarner Losh devformat(struct devdesc *d)
57dc472f67SWarner Losh {
58dc472f67SWarner Losh static char name[DEV_DEVLEN];
59dc472f67SWarner Losh
60dc472f67SWarner Losh if (d->d_dev->dv_fmtdev != NULL)
61dc472f67SWarner Losh return (d->d_dev->dv_fmtdev(d));
62dc472f67SWarner Losh snprintf(name, sizeof(name), "%s%d:", d->d_dev->dv_name, d->d_unit);
63dc472f67SWarner Losh return (name);
64dc472f67SWarner Losh }
65781ca0afSWarner Losh
66781ca0afSWarner Losh /* NB: devspec points to the remainder of the device name after dv_name */
67781ca0afSWarner Losh static int
default_parsedev(struct devdesc ** dev,const char * devspec,const char ** path)68781ca0afSWarner Losh default_parsedev(struct devdesc **dev, const char *devspec,
69781ca0afSWarner Losh const char **path)
70781ca0afSWarner Losh {
71781ca0afSWarner Losh struct devdesc *idev;
72781ca0afSWarner Losh int unit, err;
73781ca0afSWarner Losh char *cp;
74781ca0afSWarner Losh
75781ca0afSWarner Losh idev = malloc(sizeof(struct devdesc));
76781ca0afSWarner Losh if (idev == NULL)
77781ca0afSWarner Losh return (ENOMEM);
78781ca0afSWarner Losh
79781ca0afSWarner Losh unit = 0;
80781ca0afSWarner Losh cp = (char *)devspec; /* strtol interface, alas */
81781ca0afSWarner Losh
82781ca0afSWarner Losh if (*devspec != '\0' && *devspec != ':') {
83781ca0afSWarner Losh errno = 0;
84781ca0afSWarner Losh unit = strtol(devspec, &cp, 0);
85781ca0afSWarner Losh if (errno != 0 || cp == devspec) {
86781ca0afSWarner Losh err = EUNIT;
87781ca0afSWarner Losh goto fail;
88781ca0afSWarner Losh }
89781ca0afSWarner Losh }
90781ca0afSWarner Losh if (*cp != '\0' && *cp != ':') {
91781ca0afSWarner Losh err = EINVAL;
92781ca0afSWarner Losh goto fail;
93781ca0afSWarner Losh }
94781ca0afSWarner Losh
95781ca0afSWarner Losh idev->d_unit = unit;
96781ca0afSWarner Losh if (path != NULL)
97781ca0afSWarner Losh *path = (*cp == 0) ? cp : cp + 1;
98781ca0afSWarner Losh *dev = idev;
99781ca0afSWarner Losh return (0);
100781ca0afSWarner Losh fail:
101781ca0afSWarner Losh free(idev);
102781ca0afSWarner Losh return (err);
103781ca0afSWarner Losh }
104781ca0afSWarner Losh
105781ca0afSWarner Losh /* NB: devspec points to the whole device spec, and possible trailing path */
106781ca0afSWarner Losh int
devparse(struct devdesc ** dev,const char * devspec,const char ** path)107781ca0afSWarner Losh devparse(struct devdesc **dev, const char *devspec, const char **path)
108781ca0afSWarner Losh {
109781ca0afSWarner Losh struct devdesc *idev;
110781ca0afSWarner Losh struct devsw *dv;
111781ca0afSWarner Losh int i, err;
112781ca0afSWarner Losh const char *np;
113781ca0afSWarner Losh
114781ca0afSWarner Losh /* minimum length check */
115781ca0afSWarner Losh if (strlen(devspec) < 2)
116781ca0afSWarner Losh return (EINVAL);
117781ca0afSWarner Losh
118781ca0afSWarner Losh /* look for a device that matches */
119781ca0afSWarner Losh for (i = 0; devsw[i] != NULL; i++) {
120781ca0afSWarner Losh dv = devsw[i];
121a07cef5aSWarner Losh if (dv->dv_match != NULL) {
122a07cef5aSWarner Losh if (dv->dv_match(dv, devspec) != 0)
123a07cef5aSWarner Losh break;
124a07cef5aSWarner Losh } else {
125781ca0afSWarner Losh if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
126781ca0afSWarner Losh break;
127781ca0afSWarner Losh }
128a07cef5aSWarner Losh }
129781ca0afSWarner Losh if (devsw[i] == NULL)
130781ca0afSWarner Losh return (ENOENT);
131781ca0afSWarner Losh idev = NULL;
132781ca0afSWarner Losh err = 0;
133781ca0afSWarner Losh if (dv->dv_parsedev) {
13433bbe5ddSWarner Losh err = dv->dv_parsedev(&idev, devspec, path);
135781ca0afSWarner Losh } else {
136781ca0afSWarner Losh np = devspec + strlen(dv->dv_name);
137781ca0afSWarner Losh err = default_parsedev(&idev, np, path);
138781ca0afSWarner Losh }
139781ca0afSWarner Losh if (err != 0)
140781ca0afSWarner Losh return (err);
141781ca0afSWarner Losh
142781ca0afSWarner Losh idev->d_dev = dv;
143781ca0afSWarner Losh if (dev != NULL)
144781ca0afSWarner Losh *dev = idev;
145781ca0afSWarner Losh else
146781ca0afSWarner Losh free(idev);
147781ca0afSWarner Losh return (0);
148781ca0afSWarner Losh }
14966012c8fSWarner Losh
15066012c8fSWarner Losh int
devinit(void)15166012c8fSWarner Losh devinit(void)
15266012c8fSWarner Losh {
15366012c8fSWarner Losh int err = 0;
15466012c8fSWarner Losh
15566012c8fSWarner Losh /*
15666012c8fSWarner Losh * March through the device switch probing for things.
15766012c8fSWarner Losh */
15866012c8fSWarner Losh for (int i = 0; devsw[i] != NULL; i++) {
15966012c8fSWarner Losh if (devsw[i]->dv_init != NULL) {
16066012c8fSWarner Losh if ((devsw[i]->dv_init)() != 0) {
16166012c8fSWarner Losh err++;
16266012c8fSWarner Losh }
16366012c8fSWarner Losh }
16466012c8fSWarner Losh }
16566012c8fSWarner Losh return (err);
16666012c8fSWarner Losh }
167*bf020787SWarner Losh
168*bf020787SWarner Losh void
dev_cleanup(void)169*bf020787SWarner Losh dev_cleanup(void)
170*bf020787SWarner Losh {
171*bf020787SWarner Losh int i;
172*bf020787SWarner Losh
173*bf020787SWarner Losh /* Call cleanup routines */
174*bf020787SWarner Losh for (i = 0; devsw[i] != NULL; ++i)
175*bf020787SWarner Losh if (devsw[i]->dv_cleanup != NULL)
176*bf020787SWarner Losh (devsw[i]->dv_cleanup)();
177*bf020787SWarner Losh }
178