Deleted Added
full compact
pnp.c (38789) pnp.c (39178)
1/*
2 * mjs copyright
3 */
4/*
5 * "Plug and Play" functionality.
6 *
7 * We use the PnP enumerators to obtain identifiers for installed hardware,
8 * and the contents of a database to determine modules to be loaded to support
9 * such hardware.
10 */
11
12#include <stand.h>
1/*
2 * mjs copyright
3 */
4/*
5 * "Plug and Play" functionality.
6 *
7 * We use the PnP enumerators to obtain identifiers for installed hardware,
8 * and the contents of a database to determine modules to be loaded to support
9 * such hardware.
10 */
11
12#include <stand.h>
13#include <string.h>
13#include <bootstrap.h>
14
15static struct pnpinfo *pnp_devices = NULL;
16
14#include <bootstrap.h>
15
16static struct pnpinfo *pnp_devices = NULL;
17
17static void pnp_discard(void);
18static void pnp_discard(struct pnpinfo **list);
19static int pnp_readconf(char *path);
20static int pnp_scankernel(void);
18
19/*
20 * Perform complete enumeration sweep, and load required module(s) if possible.
21 */
22
21
22/*
23 * Perform complete enumeration sweep, and load required module(s) if possible.
24 */
25
26COMMAND_SET(pnpscan, "pnpscan", "scan for PnP devices", pnp_scan);
27
23int
28int
24pnp_autoload(void)
29pnp_scan(int argc, char *argv[])
25{
30{
26 int hdlr, idx;
31 int hdlr;
27
28 /* forget anything we think we knew */
32
33 /* forget anything we think we knew */
29 pnp_discard();
34 pnp_discard(&pnp_devices);
30
31 /* iterate over all of the handlers */
35
36 /* iterate over all of the handlers */
32 for (hdlr = 0; pnphandlers[hdlr]->pp_name != NULL; i++) {
37 for (hdlr = 0; pnphandlers[hdlr] != NULL; hdlr++) {
33 printf("Probing bus '%s'...\n", pnphandlers[hdlr]->pp_name);
38 printf("Probing bus '%s'...\n", pnphandlers[hdlr]->pp_name);
34 idx = 0;
35 while ((pi = pnphandlers[hdlr]->pp_enumerate(idx++)) != NULL) {
36 printf(" %s\n", pi->pi_ident);
37 pi->pi_handler = hdlr;
38 pi->pi_next = pnp_devices;
39 pnp_devices = pi;
40 }
39 pnphandlers[hdlr]->pp_enumerate(&pnp_devices);
41 }
40 }
42 /* find anything? */
43 if (pnp_devices != NULL) {
44 /* XXX hardcoded paths! should use loaddev? */
45 pnp_readconf("/boot/pnpdata.local");
46 pnp_readconf("/boot/pnpdata");
47
48 pnp_reload();
49 }
41 return(CMD_OK);
50}
51
52/*
53 * Try to load outstanding modules (eg. after disk change)
54 */
55int
42}
43
44/*
45 * Try to load outstanding modules (eg. after disk change)
46 */
47int
56pnp_reload(void)
48pnp_reload(char *fname)
57{
58 struct pnpinfo *pi;
59 char *modfname;
60
49{
50 struct pnpinfo *pi;
51 char *modfname;
52
61 /* try to load any modules that have been nominated */
62 for (pi = pnp_devices; pi != NULL; pi = pi->pi_next) {
63 /* Already loaded? */
64 if ((pi->pi_module != NULL) && (mod_findmodule(pi->pi_module, NULL) == NULL)) {
65 modfname = malloc(strlen(pi->pi_module + 3));
66 sprintf(modfname, "%s.ko", pi->pi_module); /* XXX implicit knowledge of KLD module filenames */
67 if (mod_load(pi->pi_module, pi->pi_argc, pi->pi_argv))
68 printf("Could not load module '%s' for device '%s'\n", modfname, pi->pi_ident);
69 free(modfname);
53 /* find anything? */
54 if (pnp_devices != NULL) {
55
56 /* check for kernel, assign modules handled by static drivers there */
57 if (pnp_scankernel()) {
58 command_errmsg = "cannot load drivers until kernel loaded";
59 return(CMD_ERROR);
70 }
60 }
61 if (fname == NULL) {
62 /* default paths */
63 pnp_readconf("/boot/pnpdata.local");
64 pnp_readconf("/boot/pnpdata");
65 } else {
66 if (pnp_readconf("fname")) {
67 sprintf(command_errbuf, "can't read PnP information from '%s'", fname);
68 return(CMD_ERROR);
69 }
70 }
71
72 /* try to load any modules that have been nominated */
73 for (pi = pnp_devices; pi != NULL; pi = pi->pi_next) {
74 /* Already loaded? */
75 if ((pi->pi_module != NULL) && (mod_findmodule(pi->pi_module, NULL) == NULL)) {
76 modfname = malloc(strlen(pi->pi_module + 3));
77 sprintf(modfname, "%s.ko", pi->pi_module); /* XXX implicit knowledge of KLD module filenames */
78 if (mod_load(pi->pi_module, pi->pi_argc, pi->pi_argv))
79 printf("Could not load module '%s' for device '%s'\n", modfname, pi->pi_ident->id_ident);
80 free(modfname);
81 }
82 }
71 }
83 }
84 return(CMD_OK);
72}
73
85}
86
74
75/*
87/*
76 * Throw away anything we think we know about PnP devices
88 * Throw away anything we think we know about PnP devices on (list)
77 */
78static void
89 */
90static void
79pnp_discard(void)
91pnp_discard(struct pnpinfo **list)
80{
81 struct pnpinfo *pi;
92{
93 struct pnpinfo *pi;
94 struct pnpident *id;
82
95
83 while (pnp_devices != NULL) {
84 pi = pnp_devices;
85 pnp_devices = pnp_devices->pi_next;
86 if (pi->pi_ident)
87 free(pi->pi_ident);
96 while (*list != NULL) {
97 pi = *list;
98 *list = (*list)->pi_next;
99 while (pi->pi_ident) {
100 id = pi->pi_ident;
101 pi->pi_ident = pi->pi_ident->id_next;
102 free(id);
103 }
88 if (pi->pi_module)
89 free(pi->pi_module);
90 if (pi->pi_argv)
91 free(pi->pi_argv);
92 free(pi);
93 }
94}
95

--- 13 unchanged lines hidden (view full) ---

109 *
110 * ident=<identifier> rev=<revision> module=<module> args=<arguments>
111 *
112 * This line describes an identifier:module mapping. The 'ident'
113 * and 'module' fields are required; the 'rev' field is currently
114 * ignored (but should be used), and the 'args' field must come
115 * last.
116 */
104 if (pi->pi_module)
105 free(pi->pi_module);
106 if (pi->pi_argv)
107 free(pi->pi_argv);
108 free(pi);
109 }
110}
111

--- 13 unchanged lines hidden (view full) ---

125 *
126 * ident=<identifier> rev=<revision> module=<module> args=<arguments>
127 *
128 * This line describes an identifier:module mapping. The 'ident'
129 * and 'module' fields are required; the 'rev' field is currently
130 * ignored (but should be used), and the 'args' field must come
131 * last.
132 */
117static void
133static int
118pnp_readconf(char *path)
119{
120 struct pnpinfo *pi;
134pnp_readconf(char *path)
135{
136 struct pnpinfo *pi;
137 struct pnpident *id;
121 int fd, line;
122 char lbuf[128], *currbus, *ident, *revision, *module, *args;
123 char *cp, *ep, *tp, c;
124
125 /* try to open the file */
126 if ((fd = open(path, O_RDONLY)) >= 0) {
127 line = 0;
128 currbus = NULL;

--- 21 unchanged lines hidden (view full) ---

150 continue;
151 }
152
153 /* XXX should we complain? */
154 if (currbus == NULL)
155 continue;
156
157 /* mapping */
138 int fd, line;
139 char lbuf[128], *currbus, *ident, *revision, *module, *args;
140 char *cp, *ep, *tp, c;
141
142 /* try to open the file */
143 if ((fd = open(path, O_RDONLY)) >= 0) {
144 line = 0;
145 currbus = NULL;

--- 21 unchanged lines hidden (view full) ---

167 continue;
168 }
169
170 /* XXX should we complain? */
171 if (currbus == NULL)
172 continue;
173
174 /* mapping */
158 for (ident = module = args = NULL; *cp != 0;) {
175 for (ident = module = args = revision = NULL; *cp != 0;) {
159
160 /* discard leading whitespace */
161 if (isspace(*cp)) {
162 cp++;
163 continue;
164 }
165
166 /* scan for terminator, separator */
176
177 /* discard leading whitespace */
178 if (isspace(*cp)) {
179 cp++;
180 continue;
181 }
182
183 /* scan for terminator, separator */
167 for (ep = cp; (*ep != 0) && (*ep != '=') && !isspace(ep); ep++)
184 for (ep = cp; (*ep != 0) && (*ep != '=') && !isspace(*ep); ep++)
168 ;
169
170 if (*ep == '=') {
171 *ep = 0;
185 ;
186
187 if (*ep == '=') {
188 *ep = 0;
172 for (tp = ep + 1; (*tp != 0) && !isspace(tp); tp++)
189 for (tp = ep + 1; (*tp != 0) && !isspace(*tp); tp++)
173 ;
174 c = *tp;
175 *tp = 0;
176 if ((ident == NULL) && !strcmp(cp, "ident")) {
177 ident = ep + 1;
178 } else if ((revision == NULL) && !strcmp(cp, "revision")) {
179 revision = ep + 1;
180 } else if ((args == NULL) && !strcmp(cp, "args")) {

--- 14 unchanged lines hidden (view full) ---

195
196 /* we must have at least ident and module set */
197 if ((ident == NULL) || (module == NULL)) {
198 printf("%s line %d: bad mapping\n", path, line);
199 continue;
200 }
201
202 /*
190 ;
191 c = *tp;
192 *tp = 0;
193 if ((ident == NULL) && !strcmp(cp, "ident")) {
194 ident = ep + 1;
195 } else if ((revision == NULL) && !strcmp(cp, "revision")) {
196 revision = ep + 1;
197 } else if ((args == NULL) && !strcmp(cp, "args")) {

--- 14 unchanged lines hidden (view full) ---

212
213 /* we must have at least ident and module set */
214 if ((ident == NULL) || (module == NULL)) {
215 printf("%s line %d: bad mapping\n", path, line);
216 continue;
217 }
218
219 /*
203 * Loop looking for module/bus that might match this
220 * Loop looking for module/bus that might match this, but aren't already
221 * assigned.
204 * XXX no revision parse/test here yet.
205 */
222 * XXX no revision parse/test here yet.
223 */
206 for (pi = pnp_modules; pi != NULL; pi = pi->pi_next) {
207 if (!strcmp(pnphandlers[pi->pi_handler]->pp_name, currbus) &&
208 !strcmp(pi->pi_indent, ident)) {
209 if (args != NULL)
210 if (parse(&pi->pi_argc, &pi->pi_argv, args)) {
211 printf("%s line %d: bad arguments\n", path, line);
224 for (pi = pnp_devices; pi != NULL; pi = pi->pi_next) {
225
226 /* no driver assigned, bus matches OK */
227 if ((pi->pi_module == NULL) &&
228 !strcmp(pi->pi_handler->pp_name, currbus)) {
229
230 /* scan idents, take first match */
231 for (id = pi->pi_ident; id != NULL; id = id->id_next)
232 if (!strcmp(id->id_ident, ident))
212 break;
233 break;
213 }
214 pi->pi_module = strdup(module);
234
235 /* find a match? */
236 if (id != NULL) {
237 if (args != NULL)
238 if (parse(&pi->pi_argc, &pi->pi_argv, args)) {
239 printf("%s line %d: bad arguments\n", path, line);
240 continue;
241 }
242 pi->pi_module = strdup(module);
243 printf("use module '%s' for %s:%s\n", module, pi->pi_handler->pp_name, id->id_ident);
244 }
215 }
216 }
217 }
218 close(fd);
219 }
245 }
246 }
247 }
248 close(fd);
249 }
250 return(CMD_OK);
220}
221
251}
252
253static int
254pnp_scankernel(void)
255{
256 return(CMD_OK);
257}
258
259/*
260 * Add a unique identifier to (pi)
261 */
262void
263pnp_addident(struct pnpinfo *pi, char *ident)
264{
265 struct pnpident *id, **idp;
266
267 if (pi->pi_ident == NULL) {
268 idp = &(pi->pi_ident);
269 } else {
270 for (id = pi->pi_ident; id->id_next != NULL; id = id->id_next)
271 if (!strcmp(id->id_ident, ident))
272 return; /* already have this one */
273 ;
274 idp = &(id->id_next);
275 }
276 *idp = malloc(sizeof(struct pnpident));
277 (*idp)->id_next = NULL;
278 (*idp)->id_ident = strdup(ident);
279}
280