Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/libsa/dev.c
34677 views
1
/* $NetBSD: dev.c,v 1.4 1994/10/30 21:48:23 cgd Exp $ */
2
3
/*-
4
* Copyright (c) 1993
5
* The Regents of the University of California. 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. Neither the name of the University nor the names of its contributors
16
* may be used to endorse or promote products derived from this software
17
* without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
* SUCH DAMAGE.
30
*/
31
32
#include <sys/param.h>
33
#include <sys/reboot.h>
34
35
#include "stand.h"
36
37
int
38
nodev(void)
39
{
40
return (ENXIO);
41
}
42
43
void
44
nullsys(void)
45
{
46
}
47
48
/* ARGSUSED */
49
int
50
noioctl(struct open_file *f __unused, u_long cmd __unused, void *data __unused)
51
{
52
return (EINVAL);
53
}
54
55
char *
56
devformat(struct devdesc *d)
57
{
58
static char name[DEV_DEVLEN];
59
60
if (d->d_dev->dv_fmtdev != NULL)
61
return (d->d_dev->dv_fmtdev(d));
62
snprintf(name, sizeof(name), "%s%d:", d->d_dev->dv_name, d->d_unit);
63
return (name);
64
}
65
66
/* NB: devspec points to the remainder of the device name after dv_name */
67
static int
68
default_parsedev(struct devdesc **dev, const char *devspec,
69
const char **path)
70
{
71
struct devdesc *idev;
72
int unit, err;
73
char *cp;
74
75
idev = malloc(sizeof(struct devdesc));
76
if (idev == NULL)
77
return (ENOMEM);
78
79
unit = 0;
80
cp = (char *)devspec; /* strtol interface, alas */
81
82
if (*devspec != '\0' && *devspec != ':') {
83
errno = 0;
84
unit = strtol(devspec, &cp, 0);
85
if (errno != 0 || cp == devspec) {
86
err = EUNIT;
87
goto fail;
88
}
89
}
90
if (*cp != '\0' && *cp != ':') {
91
err = EINVAL;
92
goto fail;
93
}
94
95
idev->d_unit = unit;
96
if (path != NULL)
97
*path = (*cp == 0) ? cp : cp + 1;
98
*dev = idev;
99
return (0);
100
fail:
101
free(idev);
102
return (err);
103
}
104
105
/* NB: devspec points to the whole device spec, and possible trailing path */
106
int
107
devparse(struct devdesc **dev, const char *devspec, const char **path)
108
{
109
struct devdesc *idev;
110
struct devsw *dv;
111
int i, err;
112
const char *np;
113
114
/* minimum length check */
115
if (strlen(devspec) < 2)
116
return (EINVAL);
117
118
/* look for a device that matches */
119
for (i = 0; devsw[i] != NULL; i++) {
120
dv = devsw[i];
121
if (dv->dv_match != NULL) {
122
if (dv->dv_match(dv, devspec) != 0)
123
break;
124
} else {
125
if (!strncmp(devspec, dv->dv_name, strlen(dv->dv_name)))
126
break;
127
}
128
}
129
if (devsw[i] == NULL)
130
return (ENOENT);
131
idev = NULL;
132
err = 0;
133
if (dv->dv_parsedev) {
134
err = dv->dv_parsedev(&idev, devspec, path);
135
} else {
136
np = devspec + strlen(dv->dv_name);
137
err = default_parsedev(&idev, np, path);
138
}
139
if (err != 0)
140
return (err);
141
142
idev->d_dev = dv;
143
if (dev != NULL)
144
*dev = idev;
145
else
146
free(idev);
147
return (0);
148
}
149
150
int
151
devinit(void)
152
{
153
int err = 0;
154
155
/*
156
* March through the device switch probing for things.
157
*/
158
for (int i = 0; devsw[i] != NULL; i++) {
159
if (devsw[i]->dv_init != NULL) {
160
if ((devsw[i]->dv_init)() != 0) {
161
err++;
162
}
163
}
164
}
165
return (err);
166
}
167
168
void
169
dev_cleanup(void)
170
{
171
int i;
172
173
/* Call cleanup routines */
174
for (i = 0; devsw[i] != NULL; ++i)
175
if (devsw[i]->dv_cleanup != NULL)
176
(devsw[i]->dv_cleanup)();
177
}
178
179