Deleted Added
full compact
subr_bus.c (45107) subr_bus.c (45720)
1/*-
2 * Copyright (c) 1997,1998 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

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

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 1997,1998 Doug Rabson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

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

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $Id: subr_bus.c,v 1.15 1999/01/27 21:49:57 dillon Exp $
26 * $Id: subr_bus.c,v 1.16 1999/03/29 08:54:20 dfr Exp $
27 */
28
29#include <sys/param.h>
30#include <sys/queue.h>
31#include <sys/malloc.h>
32#include <sys/kernel.h>
33#include <sys/module.h>
34#include <sys/sysctl.h>

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

89static void device_register_oids(device_t dev);
90static void device_unregister_oids(device_t dev);
91#endif
92
93/*
94 * Method table handling
95 */
96static int next_method_offset = 1;
27 */
28
29#include <sys/param.h>
30#include <sys/queue.h>
31#include <sys/malloc.h>
32#include <sys/kernel.h>
33#include <sys/module.h>
34#include <sys/sysctl.h>

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

89static void device_register_oids(device_t dev);
90static void device_unregister_oids(device_t dev);
91#endif
92
93/*
94 * Method table handling
95 */
96static int next_method_offset = 1;
97static int methods_count = 0;
98static int methods_size = 0;
99
97
98LIST_HEAD(methodlist, method) methods;
100struct method {
99struct method {
101 int offset;
102 char* name;
100 LIST_ENTRY(method) link; /* linked list of methods */
101 int offset; /* offset in method table */
102 int refs; /* count of device_op_desc users */
103 char* name; /* unique name of method */
103};
104
104};
105
105static struct method *methods = 0;
106
107static void
108register_method(struct device_op_desc *desc)
109{
106static void
107register_method(struct device_op_desc *desc)
108{
110 int i;
111 struct method* m;
112
109 struct method* m;
110
113 for (i = 0; i < methods_count; i++)
114 if (!strcmp(methods[i].name, desc->name)) {
115 desc->offset = methods[i].offset;
116 PDEBUG(("methods[%d] has the same name, %s, with offset %d",
117 i, desc->name, desc->offset));
111 if (desc->method) {
112 desc->method->refs++;
113 return;
114 }
115
116 for (m = LIST_FIRST(&methods); m; m = LIST_NEXT(m, link)) {
117 if (!strcmp(m->name, desc->name)) {
118 desc->offset = m->offset;
119 desc->method = m;
120 m->refs++;
121 PDEBUG(("methods %x has the same name, %s, with offset %d",
122 m, desc->name, desc->offset));
118 return;
119 }
123 return;
124 }
125 }
120
126
121 if (methods_count == methods_size) {
122 struct method* p;
123
124 methods_size += 10;
125 p = (struct method*) malloc(methods_size * sizeof(struct method),
126 M_DEVBUF, M_NOWAIT);
127 if (!p)
127 m = (struct method *) malloc(sizeof(struct method)
128 + strlen(desc->name) + 1,
129 M_DEVBUF, M_NOWAIT);
130 if (!m)
128 panic("register_method: out of memory");
131 panic("register_method: out of memory");
129 if (methods) {
130 bcopy(methods, p, methods_count * sizeof(struct method));
131 free(methods, M_DEVBUF);
132 }
133 methods = p;
134 }
135 m = &methods[methods_count++];
136 m->name = malloc(strlen(desc->name) + 1, M_DEVBUF, M_NOWAIT);
137 if (!m->name)
138 panic("register_method: out of memory");
132 bzero(m, sizeof(struct method) + strlen(desc->name) + 1);
133 m->offset = next_method_offset++;
134 m->refs = 1;
135 m->name = (char*) (m + 1);
139 strcpy(m->name, desc->name);
136 strcpy(m->name, desc->name);
140 desc->offset = m->offset = next_method_offset++;
137 LIST_INSERT_HEAD(&methods, m, link);
138
139 desc->offset = m->offset;
140 desc->method = m;
141}
142
141}
142
143static void
144unregister_method(struct device_op_desc *desc)
145{
146 struct method *m = desc->method;
147 m->refs--;
148 if (m->refs == 0) {
149 LIST_REMOVE(m, link);
150 free(m, M_DEVBUF);
151 }
152 desc->method = 0;
153}
154
143static int error_method(void)
144{
145 return ENXIO;
146}
147
148static struct device_ops null_ops = {
149 1,
150 { error_method }

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

156 device_ops_t ops;
157 struct device_method *m;
158 int i;
159
160 /*
161 * First register any methods which need it.
162 */
163 for (i = 0, m = driver->methods; m->desc; i++, m++)
155static int error_method(void)
156{
157 return ENXIO;
158}
159
160static struct device_ops null_ops = {
161 1,
162 { error_method }

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

168 device_ops_t ops;
169 struct device_method *m;
170 int i;
171
172 /*
173 * First register any methods which need it.
174 */
175 for (i = 0, m = driver->methods; m->desc; i++, m++)
164 if (!m->desc->offset)
165 register_method(m->desc);
166 else
167 PDEBUG(("offset not equal to zero, method desc %d left as is", i));
176 register_method(m->desc);
168
169 /*
170 * Then allocate the compiled op table.
171 */
172 ops = malloc(sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t),
173 M_DEVBUF, M_NOWAIT);
174 if (!ops)
175 panic("compile_methods: out of memory");
177
178 /*
179 * Then allocate the compiled op table.
180 */
181 ops = malloc(sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t),
182 M_DEVBUF, M_NOWAIT);
183 if (!ops)
184 panic("compile_methods: out of memory");
185 bzero(ops, sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t));
176
177 ops->maxoffset = next_method_offset;
178 for (i = 0; i < next_method_offset; i++)
179 ops->methods[i] = error_method;
180 for (i = 0, m = driver->methods; m->desc; i++, m++)
181 ops->methods[m->desc->offset] = m->func;
182 PDEBUG(("%s has %d method%s, wasting %d bytes",
183 DRIVERNAME(driver), i, (i==1?"":"s"),
184 (next_method_offset-i)*sizeof(devop_t)));
185
186 driver->ops = ops;
187}
188
186
187 ops->maxoffset = next_method_offset;
188 for (i = 0; i < next_method_offset; i++)
189 ops->methods[i] = error_method;
190 for (i = 0, m = driver->methods; m->desc; i++, m++)
191 ops->methods[m->desc->offset] = m->func;
192 PDEBUG(("%s has %d method%s, wasting %d bytes",
193 DRIVERNAME(driver), i, (i==1?"":"s"),
194 (next_method_offset-i)*sizeof(devop_t)));
195
196 driver->ops = ops;
197}
198
199static void
200free_methods(driver_t *driver)
201{
202 int i;
203 struct device_method *m;
204
205 /*
206 * Unregister any methods which are no longer used.
207 */
208 for (i = 0, m = driver->methods; m->desc; i++, m++)
209 unregister_method(m->desc);
210
211 /*
212 * Free memory and clean up.
213 */
214 free(driver->ops, M_DEVBUF);
215 driver->ops = 0;
216}
217
189/*
190 * Devclass implementation
191 */
192
193static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses);
194
195static devclass_t
196devclass_find_internal(const char *classname, int create)

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

206 return dc;
207
208 PDEBUG(("%s not found%s", classname, (create? ", creating": "")));
209 if (create) {
210 dc = malloc(sizeof(struct devclass) + strlen(classname) + 1,
211 M_DEVBUF, M_NOWAIT);
212 if (!dc)
213 return NULL;
218/*
219 * Devclass implementation
220 */
221
222static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses);
223
224static devclass_t
225devclass_find_internal(const char *classname, int create)

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

235 return dc;
236
237 PDEBUG(("%s not found%s", classname, (create? ", creating": "")));
238 if (create) {
239 dc = malloc(sizeof(struct devclass) + strlen(classname) + 1,
240 M_DEVBUF, M_NOWAIT);
241 if (!dc)
242 return NULL;
243 bzero(dc, sizeof(struct devclass) + strlen(classname) + 1);
214 dc->name = (char*) (dc + 1);
215 strcpy(dc->name, classname);
216 dc->devices = NULL;
217 dc->maxunit = 0;
218 dc->nextunit = 0;
219 TAILQ_INIT(&dc->drivers);
220 TAILQ_INSERT_TAIL(&devclasses, dc, link);
221 }

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

228{
229 return devclass_find_internal(classname, FALSE);
230}
231
232int
233devclass_add_driver(devclass_t dc, driver_t *driver)
234{
235 driverlink_t dl;
244 dc->name = (char*) (dc + 1);
245 strcpy(dc->name, classname);
246 dc->devices = NULL;
247 dc->maxunit = 0;
248 dc->nextunit = 0;
249 TAILQ_INIT(&dc->drivers);
250 TAILQ_INSERT_TAIL(&devclasses, dc, link);
251 }

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

258{
259 return devclass_find_internal(classname, FALSE);
260}
261
262int
263devclass_add_driver(devclass_t dc, driver_t *driver)
264{
265 driverlink_t dl;
266 int i;
236
237 PDEBUG(("%s", DRIVERNAME(driver)));
238
239 dl = malloc(sizeof *dl, M_DEVBUF, M_NOWAIT);
240 if (!dl)
241 return ENOMEM;
267
268 PDEBUG(("%s", DRIVERNAME(driver)));
269
270 dl = malloc(sizeof *dl, M_DEVBUF, M_NOWAIT);
271 if (!dl)
272 return ENOMEM;
273 bzero(dl, sizeof *dl);
242
243 /*
274
275 /*
244 * Compile the drivers methods.
276 * Compile the driver's methods.
245 */
277 */
246 compile_methods(driver);
278 if (!driver->ops)
279 compile_methods(driver);
247
248 /*
249 * Make sure the devclass which the driver is implementing exists.
250 */
251 devclass_find_internal(driver->name, TRUE);
252
253 dl->driver = driver;
254 TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
280
281 /*
282 * Make sure the devclass which the driver is implementing exists.
283 */
284 devclass_find_internal(driver->name, TRUE);
285
286 dl->driver = driver;
287 TAILQ_INSERT_TAIL(&dc->drivers, dl, link);
288 driver->refs++;
255
289
290 /*
291 * Call BUS_DRIVER_ADDED for any existing busses in this class.
292 */
293 for (i = 0; i < dc->maxunit; i++)
294 if (dc->devices[i])
295 BUS_DRIVER_ADDED(dc->devices[i], driver);
296
256 return 0;
257}
258
259int
260devclass_delete_driver(devclass_t busclass, driver_t *driver)
261{
262 devclass_t dc = devclass_find(driver->name);
263 driverlink_t dl;

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

304 device_set_driver(dev, NULL);
305 }
306 }
307 }
308
309 TAILQ_REMOVE(&busclass->drivers, dl, link);
310 free(dl, M_DEVBUF);
311
297 return 0;
298}
299
300int
301devclass_delete_driver(devclass_t busclass, driver_t *driver)
302{
303 devclass_t dc = devclass_find(driver->name);
304 driverlink_t dl;

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

345 device_set_driver(dev, NULL);
346 }
347 }
348 }
349
350 TAILQ_REMOVE(&busclass->drivers, dl, link);
351 free(dl, M_DEVBUF);
352
353 driver->refs--;
354 if (driver->refs == 0)
355 free_methods(driver);
356
312 return 0;
313}
314
315static driverlink_t
316devclass_find_driver_internal(devclass_t dc, const char *classname)
317{
318 driverlink_t dl;
319

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

377 count = 0;
378 for (i = 0; i < dc->maxunit; i++)
379 if (dc->devices[i])
380 count++;
381
382 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT);
383 if (!list)
384 return ENOMEM;
357 return 0;
358}
359
360static driverlink_t
361devclass_find_driver_internal(devclass_t dc, const char *classname)
362{
363 driverlink_t dl;
364

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

422 count = 0;
423 for (i = 0; i < dc->maxunit; i++)
424 if (dc->devices[i])
425 count++;
426
427 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT);
428 if (!list)
429 return ENOMEM;
430 bzero(list, count * sizeof(device_t));
385
386 count = 0;
387 for (i = 0; i < dc->maxunit; i++)
388 if (dc->devices[i]) {
389 list[count] = dc->devices[i];
390 count++;
391 }
392

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

457 int buflen, error;
458
459 PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
460
461 buflen = strlen(dc->name) + 5;
462 dev->nameunit = malloc(buflen, M_DEVBUF, M_NOWAIT);
463 if (!dev->nameunit)
464 return ENOMEM;
431
432 count = 0;
433 for (i = 0; i < dc->maxunit; i++)
434 if (dc->devices[i]) {
435 list[count] = dc->devices[i];
436 count++;
437 }
438

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

503 int buflen, error;
504
505 PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc)));
506
507 buflen = strlen(dc->name) + 5;
508 dev->nameunit = malloc(buflen, M_DEVBUF, M_NOWAIT);
509 if (!dev->nameunit)
510 return ENOMEM;
511 bzero(dev->nameunit, buflen);
465
466 if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0) {
467 free(dev->nameunit, M_DEVBUF);
468 dev->nameunit = NULL;
469 return error;
470 }
471 dc->devices[dev->unit] = dev;
472 dev->devclass = dc;

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

523 return NULL;
524 }
525 } else
526 dc = NULL;
527
528 dev = malloc(sizeof(struct device), M_DEVBUF, M_NOWAIT);
529 if (!dev)
530 return 0;
512
513 if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0) {
514 free(dev->nameunit, M_DEVBUF);
515 dev->nameunit = NULL;
516 return error;
517 }
518 dc->devices[dev->unit] = dev;
519 dev->devclass = dc;

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

570 return NULL;
571 }
572 } else
573 dc = NULL;
574
575 dev = malloc(sizeof(struct device), M_DEVBUF, M_NOWAIT);
576 if (!dev)
577 return 0;
578 bzero(dev, sizeof(struct device));
531
532 dev->parent = parent;
533 TAILQ_INIT(&dev->children);
534 dev->ops = &null_ops;
535 dev->driver = NULL;
536 dev->devclass = NULL;
537 dev->unit = unit;
538 dev->nameunit = NULL;

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

716 count = 0;
717 for (child = TAILQ_FIRST(&dev->children); child;
718 child = TAILQ_NEXT(child, link))
719 count++;
720
721 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT);
722 if (!list)
723 return ENOMEM;
579
580 dev->parent = parent;
581 TAILQ_INIT(&dev->children);
582 dev->ops = &null_ops;
583 dev->driver = NULL;
584 dev->devclass = NULL;
585 dev->unit = unit;
586 dev->nameunit = NULL;

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

764 count = 0;
765 for (child = TAILQ_FIRST(&dev->children); child;
766 child = TAILQ_NEXT(child, link))
767 count++;
768
769 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT);
770 if (!list)
771 return ENOMEM;
772 bzero(list, count * sizeof(device_t));
724
725 count = 0;
726 for (child = TAILQ_FIRST(&dev->children); child;
727 child = TAILQ_NEXT(child, link)) {
728 list[count] = child;
729 count++;
730 }
731

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

1141{
1142 sysctl_unregister_oid(&dev->oid[0]);
1143 sysctl_unregister_oid(&dev->oid[1]);
1144 sysctl_unregister_oid(&dev->oid[2]);
1145}
1146
1147#endif
1148
773
774 count = 0;
775 for (child = TAILQ_FIRST(&dev->children); child;
776 child = TAILQ_NEXT(child, link)) {
777 list[count] = child;
778 count++;
779 }
780

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

1190{
1191 sysctl_unregister_oid(&dev->oid[0]);
1192 sysctl_unregister_oid(&dev->oid[1]);
1193 sysctl_unregister_oid(&dev->oid[2]);
1194}
1195
1196#endif
1197
1198/*======================================*/
1149/*
1150 * Access functions for device resources.
1151 */
1199/*
1200 * Access functions for device resources.
1201 */
1152extern struct config_device devtab[];
1202
1203/* Supplied by config(8) in ioconf.c */
1204extern struct config_device config_devtab[];
1153extern int devtab_count;
1154
1205extern int devtab_count;
1206
1207/* Runtime version */
1208struct config_device *devtab = config_devtab;
1209
1155static int
1210static int
1211resource_new_name(char *name, int unit)
1212{
1213 struct config_device *new;
1214
1215 new = malloc((devtab_count + 1) * sizeof(*new), M_TEMP, M_NOWAIT);
1216 if (new == NULL)
1217 return -1;
1218 if (devtab && devtab_count > 0)
1219 bcopy(devtab, new, devtab_count * sizeof(*new));
1220 bzero(&new[devtab_count], sizeof(*new));
1221 new[devtab_count].name = malloc(strlen(name) + 1, M_TEMP, M_NOWAIT);
1222 if (new[devtab_count].name == NULL) {
1223 free(new, M_TEMP);
1224 return -1;
1225 }
1226 strcpy(new[devtab_count].name, name);
1227 new[devtab_count].unit = unit;
1228 new[devtab_count].resource_count = 0;
1229 new[devtab_count].resources = NULL;
1230 devtab = new;
1231 return devtab_count++;
1232}
1233
1234static int
1235resource_new_resname(int j, char *resname, resource_type type)
1236{
1237 struct config_resource *new;
1238 int i;
1239
1240 i = devtab[j].resource_count;
1241 new = malloc((i + 1) * sizeof(*new), M_TEMP, M_NOWAIT);
1242 if (new == NULL)
1243 return -1;
1244 if (devtab[j].resources && i > 0)
1245 bcopy(devtab[j].resources, new, i * sizeof(*new));
1246 bzero(&new[i], sizeof(*new));
1247 new[i].name = malloc(strlen(resname) + 1, M_TEMP, M_NOWAIT);
1248 if (new[i].name == NULL) {
1249 free(new, M_TEMP);
1250 return -1;
1251 }
1252 strcpy(new[i].name, resname);
1253 new[i].type = type;
1254 if (devtab[j].resources)
1255 free(devtab[j].resources, M_TEMP);
1256 devtab[j].resources = new;
1257 devtab[j].resource_count = i + 1;
1258 return i;
1259}
1260
1261static int
1156resource_match_string(int i, char *resname, char *value)
1157{
1158 int j;
1159 struct config_resource *res;
1160
1161 for (j = 0, res = devtab[i].resources;
1162 j < devtab[i].resource_count; j++, res++)
1163 if (!strcmp(res->name, resname)
1164 && res->type == RES_STRING
1165 && !strcmp(res->u.stringval, value))
1262resource_match_string(int i, char *resname, char *value)
1263{
1264 int j;
1265 struct config_resource *res;
1266
1267 for (j = 0, res = devtab[i].resources;
1268 j < devtab[i].resource_count; j++, res++)
1269 if (!strcmp(res->name, resname)
1270 && res->type == RES_STRING
1271 && !strcmp(res->u.stringval, value))
1166 return TRUE;
1167 return FALSE;
1272 return j;
1273 return -1;
1168}
1169
1170static int
1171resource_find(const char *name, int unit, char *resname,
1172 struct config_resource **result)
1173{
1174 int i, j;
1175 struct config_resource *res;

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

1204 return ENOENT;
1205}
1206
1207int
1208resource_int_value(const char *name, int unit, char *resname, int *result)
1209{
1210 int error;
1211 struct config_resource *res;
1274}
1275
1276static int
1277resource_find(const char *name, int unit, char *resname,
1278 struct config_resource **result)
1279{
1280 int i, j;
1281 struct config_resource *res;

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

1310 return ENOENT;
1311}
1312
1313int
1314resource_int_value(const char *name, int unit, char *resname, int *result)
1315{
1316 int error;
1317 struct config_resource *res;
1318
1212 if ((error = resource_find(name, unit, resname, &res)) != 0)
1213 return error;
1214 if (res->type != RES_INT)
1215 return EFTYPE;
1216 *result = res->u.intval;
1217 return 0;
1218}
1219
1220int
1221resource_long_value(const char *name, int unit, char *resname, long *result)
1222{
1223 int error;
1224 struct config_resource *res;
1319 if ((error = resource_find(name, unit, resname, &res)) != 0)
1320 return error;
1321 if (res->type != RES_INT)
1322 return EFTYPE;
1323 *result = res->u.intval;
1324 return 0;
1325}
1326
1327int
1328resource_long_value(const char *name, int unit, char *resname, long *result)
1329{
1330 int error;
1331 struct config_resource *res;
1332
1225 if ((error = resource_find(name, unit, resname, &res)) != 0)
1226 return error;
1227 if (res->type != RES_LONG)
1228 return EFTYPE;
1229 *result = res->u.longval;
1230 return 0;
1231}
1232
1233int
1234resource_string_value(const char *name, int unit, char *resname, char **result)
1235{
1236 int error;
1237 struct config_resource *res;
1333 if ((error = resource_find(name, unit, resname, &res)) != 0)
1334 return error;
1335 if (res->type != RES_LONG)
1336 return EFTYPE;
1337 *result = res->u.longval;
1338 return 0;
1339}
1340
1341int
1342resource_string_value(const char *name, int unit, char *resname, char **result)
1343{
1344 int error;
1345 struct config_resource *res;
1346
1238 if ((error = resource_find(name, unit, resname, &res)) != 0)
1239 return error;
1240 if (res->type != RES_STRING)
1241 return EFTYPE;
1242 *result = res->u.stringval;
1243 return 0;
1244}
1245
1246int
1247resource_query_string(int i, char *resname, char *value)
1248{
1249 if (i < 0)
1250 i = 0;
1251 else
1252 i = i + 1;
1253 for (; i < devtab_count; i++)
1347 if ((error = resource_find(name, unit, resname, &res)) != 0)
1348 return error;
1349 if (res->type != RES_STRING)
1350 return EFTYPE;
1351 *result = res->u.stringval;
1352 return 0;
1353}
1354
1355int
1356resource_query_string(int i, char *resname, char *value)
1357{
1358 if (i < 0)
1359 i = 0;
1360 else
1361 i = i + 1;
1362 for (; i < devtab_count; i++)
1254 if (resource_match_string(i, resname, value))
1363 if (resource_match_string(i, resname, value) >= 0)
1255 return i;
1256 return -1;
1257}
1258
1364 return i;
1365 return -1;
1366}
1367
1368int
1369resource_locate(int i, char *resname)
1370{
1371 if (i < 0)
1372 i = 0;
1373 else
1374 i = i + 1;
1375 for (; i < devtab_count; i++)
1376 if (!strcmp(devtab[i].name, resname))
1377 return i;
1378 return -1;
1379}
1380
1381int
1382resource_count(void)
1383{
1384 return devtab_count;
1385}
1386
1259char *
1260resource_query_name(int i)
1261{
1262 return devtab[i].name;
1263}
1264
1265int
1266resource_query_unit(int i)
1267{
1268 return devtab[i].unit;
1269}
1270
1387char *
1388resource_query_name(int i)
1389{
1390 return devtab[i].name;
1391}
1392
1393int
1394resource_query_unit(int i)
1395{
1396 return devtab[i].unit;
1397}
1398
1399static int
1400resource_create(char *name, int unit, char *resname, resource_type type,
1401 struct config_resource **result)
1402{
1403 int i, j;
1404 struct config_resource *res = NULL;
1271
1405
1406 for (i = 0; i < devtab_count; i++) {
1407 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) {
1408 res = devtab[i].resources;
1409 break;
1410 }
1411 }
1412 if (res == NULL) {
1413 i = resource_new_name(name, unit);
1414 if (i < 0)
1415 return ENOMEM;
1416 res = devtab[i].resources;
1417 }
1418 for (j = 0; j < devtab[i].resource_count; j++, res++) {
1419 if (!strcmp(res->name, resname)) {
1420 *result = res;
1421 return 0;
1422 }
1423 }
1424 j = resource_new_resname(i, resname, type);
1425 if (j < 0)
1426 return ENOMEM;
1427 res = &devtab[i].resources[j];
1428 *result = res;
1429 return 0;
1430}
1431
1432int
1433resource_set_int(int i, char *resname, int value)
1434{
1435 int error;
1436 struct config_resource *res;
1437
1438printf("resource_set_int\n");
1439 if (i < 0 || i >= devtab_count)
1440 return EINVAL;
1441 error = resource_create(devtab[i].name, devtab[i].unit, resname,
1442 RES_INT, &res);
1443 if (error)
1444 return error;
1445 if (res->type != RES_INT)
1446 return EFTYPE;
1447 res->u.intval = value;
1448 return 0;
1449}
1450
1451int
1452resource_set_long(int i, char *resname, long value)
1453{
1454 int error;
1455 struct config_resource *res;
1456
1457printf("resource_set_long\n");
1458 if (i < 0 || i >= devtab_count)
1459 return EINVAL;
1460 error = resource_create(devtab[i].name, devtab[i].unit, resname,
1461 RES_LONG, &res);
1462 if (error)
1463 return error;
1464 if (res->type != RES_LONG)
1465 return EFTYPE;
1466 res->u.longval = value;
1467 return 0;
1468}
1469
1470int
1471resource_set_string(int i, char *resname, char *value)
1472{
1473 int error;
1474 struct config_resource *res;
1475
1476printf("resource_set_string\n");
1477 if (i < 0 || i >= devtab_count)
1478 return EINVAL;
1479 error = resource_create(devtab[i].name, devtab[i].unit, resname,
1480 RES_STRING, &res);
1481 if (error)
1482 return error;
1483 if (res->type != RES_STRING)
1484 return EFTYPE;
1485 if (res->u.stringval)
1486 free(res->u.stringval, M_TEMP);
1487 res->u.stringval = malloc(strlen(value) + 1, M_TEMP, M_NOWAIT);
1488 if (res->u.stringval == NULL)
1489 return ENOMEM;
1490 strcpy(res->u.stringval, value);
1491 return 0;
1492}
1493
1494
1495static void
1496resource_cfgload(void *dummy __unused)
1497{
1498 struct config_resource *res, *cfgres;
1499 int i, j;
1500 int error;
1501 char *name, *resname;
1502 int unit;
1503 resource_type type;
1504 char *stringval;
1505 int config_devtab_count;
1506
1507 config_devtab_count = devtab_count;
1508 devtab = NULL;
1509 devtab_count = 0;
1510
1511 for (i = 0; i < config_devtab_count; i++) {
1512 name = config_devtab[i].name;
1513 unit = config_devtab[i].unit;
1514
1515 for (j = 0; j < config_devtab[i].resource_count; j++) {
1516 cfgres = config_devtab[i].resources;
1517 resname = cfgres[j].name;
1518 type = cfgres[j].type;
1519 error = resource_create(name, unit, resname, type,
1520 &res);
1521 if (error) {
1522 printf("create resource %s%d: error %d\n",
1523 name, unit, error);
1524 continue;
1525 }
1526 if (res->type != type) {
1527 printf("type mismatch %s%d: %d != %d\n",
1528 name, unit, res->type, type);
1529 continue;
1530 }
1531 switch (type) {
1532 case RES_INT:
1533 res->u.intval = cfgres[j].u.intval;
1534 break;
1535 case RES_LONG:
1536 res->u.longval = cfgres[j].u.longval;
1537 break;
1538 case RES_STRING:
1539 if (res->u.stringval)
1540 free(res->u.stringval, M_TEMP);
1541 stringval = cfgres[j].u.stringval;
1542 res->u.stringval = malloc(strlen(stringval) + 1,
1543 M_TEMP, M_NOWAIT);
1544 if (res->u.stringval == NULL)
1545 break;
1546 strcpy(res->u.stringval, stringval);
1547 break;
1548 default:
1549 panic("unknown resource type %d\n", type);
1550 }
1551 }
1552 }
1553}
1554SYSINIT(cfgload, SI_SUB_KMEM, SI_ORDER_ANY + 50, resource_cfgload, 0)
1555
1556
1557/*======================================*/
1272/*
1273 * Some useful method implementations to make life easier for bus drivers.
1274 */
1275int
1276bus_generic_attach(device_t dev)
1277{
1278 device_t child;
1279

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

1303
1304int
1305bus_generic_shutdown(device_t dev)
1306{
1307 device_t child;
1308
1309 for (child = TAILQ_FIRST(&dev->children);
1310 child; child = TAILQ_NEXT(child, link))
1558/*
1559 * Some useful method implementations to make life easier for bus drivers.
1560 */
1561int
1562bus_generic_attach(device_t dev)
1563{
1564 device_t child;
1565

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

1589
1590int
1591bus_generic_shutdown(device_t dev)
1592{
1593 device_t child;
1594
1595 for (child = TAILQ_FIRST(&dev->children);
1596 child; child = TAILQ_NEXT(child, link))
1311 DEVICE_SHUTDOWN(child);
1597 device_shutdown(child);
1312
1313 return 0;
1314}
1315
1316int
1317bus_generic_suspend(device_t dev)
1318{
1319 int error;

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

1361
1362int
1363bus_generic_write_ivar(device_t dev, device_t child, int index,
1364 uintptr_t value)
1365{
1366 return ENOENT;
1367}
1368
1598
1599 return 0;
1600}
1601
1602int
1603bus_generic_suspend(device_t dev)
1604{
1605 int error;

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

1647
1648int
1649bus_generic_write_ivar(device_t dev, device_t child, int index,
1650 uintptr_t value)
1651{
1652 return ENOENT;
1653}
1654
1655void
1656bus_generic_driver_added(device_t dev, driver_t *driver)
1657{
1658 device_t child;
1659
1660 for (child = TAILQ_FIRST(&dev->children);
1661 child; child = TAILQ_NEXT(child, link))
1662 if (child->state == DS_NOTPRESENT)
1663 device_probe_and_attach(child);
1664}
1665
1369int
1370bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
1371 driver_intr_t *intr, void *arg, void **cookiep)
1372{
1373 /* Propagate up the bus hierarchy until someone handles it. */
1374 if (dev->parent)
1375 return (BUS_SETUP_INTR(dev->parent, child, irq, intr, arg,
1376 cookiep));

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

1508 /*
1509 * If an interrupt mapping gets to here something bad has happened.
1510 */
1511 panic("root_setup_intr");
1512}
1513
1514static device_method_t root_methods[] = {
1515 /* Device interface */
1666int
1667bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq,
1668 driver_intr_t *intr, void *arg, void **cookiep)
1669{
1670 /* Propagate up the bus hierarchy until someone handles it. */
1671 if (dev->parent)
1672 return (BUS_SETUP_INTR(dev->parent, child, irq, intr, arg,
1673 cookiep));

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

1805 /*
1806 * If an interrupt mapping gets to here something bad has happened.
1807 */
1808 panic("root_setup_intr");
1809}
1810
1811static device_method_t root_methods[] = {
1812 /* Device interface */
1813 DEVMETHOD(device_shutdown, bus_generic_shutdown),
1516 DEVMETHOD(device_suspend, bus_generic_suspend),
1517 DEVMETHOD(device_resume, bus_generic_resume),
1518
1519 /* Bus interface */
1520 DEVMETHOD(bus_print_child, root_print_child),
1521 DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
1522 DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
1523 DEVMETHOD(bus_setup_intr, root_setup_intr),

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

1543 compile_methods(&root_driver);
1544 root_bus = make_device(NULL, "root", 0, NULL);
1545 root_bus->desc = "System root bus";
1546 root_bus->ops = root_driver.ops;
1547 root_bus->driver = &root_driver;
1548 root_bus->state = DS_ATTACHED;
1549 root_devclass = devclass_find_internal("root", FALSE);
1550 return 0;
1814 DEVMETHOD(device_suspend, bus_generic_suspend),
1815 DEVMETHOD(device_resume, bus_generic_resume),
1816
1817 /* Bus interface */
1818 DEVMETHOD(bus_print_child, root_print_child),
1819 DEVMETHOD(bus_read_ivar, bus_generic_read_ivar),
1820 DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
1821 DEVMETHOD(bus_setup_intr, root_setup_intr),

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

1841 compile_methods(&root_driver);
1842 root_bus = make_device(NULL, "root", 0, NULL);
1843 root_bus->desc = "System root bus";
1844 root_bus->ops = root_driver.ops;
1845 root_bus->driver = &root_driver;
1846 root_bus->state = DS_ATTACHED;
1847 root_devclass = devclass_find_internal("root", FALSE);
1848 return 0;
1849
1850 case MOD_SHUTDOWN:
1851 device_shutdown(root_bus);
1852 return 0;
1551 }
1552
1553 return 0;
1554}
1555
1556static moduledata_t root_bus_mod = {
1557 "rootbus",
1558 root_bus_module_handler,

--- 275 unchanged lines hidden ---
1853 }
1854
1855 return 0;
1856}
1857
1858static moduledata_t root_bus_mod = {
1859 "rootbus",
1860 root_bus_module_handler,

--- 275 unchanged lines hidden ---