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 --- |