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 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 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.38 1999/08/14 13:32:25 n_hibma 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> 35 #include <sys/bus_private.h> 36 #include <sys/systm.h> 37 #include <machine/bus.h> 38 #include <sys/rman.h> 39 #include <machine/stdarg.h> /* for device_printf() */ 40 41 #include "opt_bus.h" 42 43 #ifdef BUS_DEBUG 44 #define PDEBUG(a) (printf(__FUNCTION__ ":%d: ", __LINE__), printf a, printf("\n")) 45 #define DEVICENAME(d) ((d)? device_get_name(d): "no device") 46 #define DRIVERNAME(d) ((d)? d->name : "no driver") 47 #define DEVCLANAME(d) ((d)? d->name : "no devclass") 48 49 /* Produce the indenting, indent*2 spaces plus a '.' ahead of that to 50 * prevent syslog from deleting initial spaces 51 */ 52 #define indentprintf(p) do { int iJ; printf("."); for (iJ=0; iJ<indent; iJ++) printf(" "); printf p ; } while(0) 53 54 static void print_method_list(device_method_t *m, int indent); 55 static void print_device_ops(device_ops_t ops, int indent); 56 static void print_device_short(device_t dev, int indent); 57 static void print_device(device_t dev, int indent); 58 void print_device_tree_short(device_t dev, int indent); 59 void print_device_tree(device_t dev, int indent); 60 static void print_driver_short(driver_t *driver, int indent); 61 static void print_driver(driver_t *driver, int indent); 62 static void print_driver_list(driver_list_t drivers, int indent); 63 static void print_devclass_short(devclass_t dc, int indent); 64 static void print_devclass(devclass_t dc, int indent); 65 void print_devclass_list_short(void); 66 void print_devclass_list(void); 67 68 #else 69 /* Make the compiler ignore the function calls */ 70 #define PDEBUG(a) /* nop */ 71 #define DEVICENAME(d) /* nop */ 72 #define DRIVERNAME(d) /* nop */ 73 #define DEVCLANAME(d) /* nop */ 74 75 #define print_method_list(m,i) /* nop */ 76 #define print_device_ops(o,i) /* nop */ 77 #define print_device_short(d,i) /* nop */ 78 #define print_device(d,i) /* nop */ 79 #define print_device_tree_short(d,i) /* nop */ 80 #define print_device_tree(d,i) /* nop */ 81 #define print_driver_short(d,i) /* nop */ 82 #define print_driver(d,i) /* nop */ 83 #define print_driver_list(d,i) /* nop */ 84 #define print_devclass_short(d,i) /* nop */ 85 #define print_devclass(d,i) /* nop */ 86 #define print_devclass_list_short() /* nop */ 87 #define print_devclass_list() /* nop */ 88 #endif 89 90 #ifdef DEVICE_SYSCTLS 91 static void device_register_oids(device_t dev); 92 static void device_unregister_oids(device_t dev); 93 #endif 94 95 /* 96 * Method table handling 97 */ 98 static int error_method(void); 99 static int next_method_offset = 1; 100 101 LIST_HEAD(methodlist, method) methods; 102 struct method { 103 LIST_ENTRY(method) link; /* linked list of methods */ 104 int offset; /* offset in method table */ 105 int refs; /* count of device_op_desc users */ 106 devop_t deflt; /* default implementation */ 107 char* name; /* unique name of method */ 108 }; 109 110 static void 111 register_method(struct device_op_desc *desc) 112 { 113 struct method* m; 114 115 if (desc->method) { 116 desc->method->refs++; 117 return; 118 } 119 120 /* 121 * Make sure that desc->deflt is always valid to simplify dispatch. 122 */ 123 if (!desc->deflt) 124 desc->deflt = error_method; 125 126 for (m = LIST_FIRST(&methods); m; m = LIST_NEXT(m, link)) { 127 if (!strcmp(m->name, desc->name)) { 128 desc->offset = m->offset; 129 desc->method = m; 130 m->refs++; 131 PDEBUG(("method %p has the same name, %s, with offset %d", 132 (void *)m, desc->name, desc->offset)); 133 return; 134 } 135 } 136 137 m = (struct method *) malloc(sizeof(struct method) 138 + strlen(desc->name) + 1, 139 M_DEVBUF, M_NOWAIT); 140 if (!m) 141 panic("register_method: out of memory"); 142 bzero(m, sizeof(struct method) + strlen(desc->name) + 1); 143 m->offset = next_method_offset++; 144 m->refs = 1; 145 m->deflt = desc->deflt; 146 m->name = (char*) (m + 1); 147 strcpy(m->name, desc->name); 148 LIST_INSERT_HEAD(&methods, m, link); 149 150 desc->offset = m->offset; 151 desc->method = m; 152 } 153 154 static void 155 unregister_method(struct device_op_desc *desc) 156 { 157 struct method *m = desc->method; 158 m->refs--; 159 if (m->refs == 0) { 160 PDEBUG(("method %s, reached refcount 0", desc->name)); 161 LIST_REMOVE(m, link); 162 free(m, M_DEVBUF); 163 desc->method = 0; 164 } 165 } 166 167 static int error_method(void) 168 { 169 return ENXIO; 170 } 171 172 static struct device_ops null_ops = { 173 1, 174 { error_method } 175 }; 176 177 static void 178 compile_methods(driver_t *driver) 179 { 180 device_ops_t ops; 181 struct device_method *m; 182 struct method *cm; 183 int i; 184 185 /* 186 * First register any methods which need it. 187 */ 188 for (i = 0, m = driver->methods; m->desc; i++, m++) 189 register_method(m->desc); 190 191 /* 192 * Then allocate the compiled op table. 193 */ 194 ops = malloc(sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t), 195 M_DEVBUF, M_NOWAIT); 196 if (!ops) 197 panic("compile_methods: out of memory"); 198 bzero(ops, sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t)); 199 200 ops->maxoffset = next_method_offset; 201 /* Fill in default methods and then overwrite with driver methods */ 202 for (i = 0; i < next_method_offset; i++) 203 ops->methods[i] = error_method; 204 for (cm = LIST_FIRST(&methods); cm; cm = LIST_NEXT(cm, link)) { 205 if (cm->deflt) 206 ops->methods[cm->offset] = cm->deflt; 207 } 208 for (i = 0, m = driver->methods; m->desc; i++, m++) 209 ops->methods[m->desc->offset] = m->func; 210 PDEBUG(("%s has %d method%s, wasting %d bytes", 211 DRIVERNAME(driver), i, (i==1?"":"s"), 212 (next_method_offset-i)*sizeof(devop_t))); 213 214 driver->ops = ops; 215 } 216 217 static void 218 free_methods(driver_t *driver) 219 { 220 int i; 221 struct device_method *m; 222 223 /* 224 * Unregister any methods which are no longer used. 225 */ 226 for (i = 0, m = driver->methods; m->desc; i++, m++) 227 unregister_method(m->desc); 228 229 /* 230 * Free memory and clean up. 231 */ 232 free(driver->ops, M_DEVBUF); 233 driver->ops = 0; 234 } 235 236 /* 237 * Devclass implementation 238 */ 239 240 static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses); 241 242 static devclass_t 243 devclass_find_internal(const char *classname, int create) 244 { 245 devclass_t dc; 246 247 PDEBUG(("looking for %s", classname)); 248 if (!classname) 249 return NULL; 250 251 for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link)) 252 if (!strcmp(dc->name, classname)) 253 return dc; 254 255 PDEBUG(("%s not found%s", classname, (create? ", creating": ""))); 256 if (create) { 257 dc = malloc(sizeof(struct devclass) + strlen(classname) + 1, 258 M_DEVBUF, M_NOWAIT); 259 if (!dc) 260 return NULL; 261 bzero(dc, sizeof(struct devclass) + strlen(classname) + 1); 262 dc->name = (char*) (dc + 1); 263 strcpy(dc->name, classname); 264 dc->devices = NULL; 265 dc->maxunit = 0; 266 dc->nextunit = 0; 267 TAILQ_INIT(&dc->drivers); 268 TAILQ_INSERT_TAIL(&devclasses, dc, link); 269 } 270 271 return dc; 272 } 273 274 devclass_t 275 devclass_create(const char *classname) 276 { 277 return devclass_find_internal(classname, TRUE); 278 } 279 280 devclass_t 281 devclass_find(const char *classname) 282 { 283 return devclass_find_internal(classname, FALSE); 284 } 285 286 int 287 devclass_add_driver(devclass_t dc, driver_t *driver) 288 { 289 driverlink_t dl; 290 int i; 291 292 PDEBUG(("%s", DRIVERNAME(driver))); 293 294 dl = malloc(sizeof *dl, M_DEVBUF, M_NOWAIT); 295 if (!dl) 296 return ENOMEM; 297 bzero(dl, sizeof *dl); 298 299 /* 300 * Compile the driver's methods. 301 */ 302 if (!driver->ops) 303 compile_methods(driver); 304 305 /* 306 * Make sure the devclass which the driver is implementing exists. 307 */ 308 devclass_find_internal(driver->name, TRUE); 309 310 dl->driver = driver; 311 TAILQ_INSERT_TAIL(&dc->drivers, dl, link); 312 driver->refs++; 313 314 /* 315 * Call BUS_DRIVER_ADDED for any existing busses in this class. 316 */ 317 for (i = 0; i < dc->maxunit; i++) 318 if (dc->devices[i]) 319 BUS_DRIVER_ADDED(dc->devices[i], driver); 320 321 return 0; 322 } 323 324 int 325 devclass_delete_driver(devclass_t busclass, driver_t *driver) 326 { 327 devclass_t dc = devclass_find(driver->name); 328 driverlink_t dl; 329 device_t dev; 330 int i; 331 int error; 332 333 PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass))); 334 335 if (!dc) 336 return 0; 337 338 /* 339 * Find the link structure in the bus' list of drivers. 340 */ 341 for (dl = TAILQ_FIRST(&busclass->drivers); dl; 342 dl = TAILQ_NEXT(dl, link)) { 343 if (dl->driver == driver) 344 break; 345 } 346 347 if (!dl) { 348 PDEBUG(("%s not found in %s list", driver->name, busclass->name)); 349 return ENOENT; 350 } 351 352 /* 353 * Disassociate from any devices. We iterate through all the 354 * devices in the devclass of the driver and detach any which are 355 * using the driver and which have a parent in the devclass which 356 * we are deleting from. 357 * 358 * Note that since a driver can be in multiple devclasses, we 359 * should not detach devices which are not children of devices in 360 * the affected devclass. 361 */ 362 for (i = 0; i < dc->maxunit; i++) { 363 if (dc->devices[i]) { 364 dev = dc->devices[i]; 365 if (dev->driver == driver 366 && dev->parent && dev->parent->devclass == busclass) { 367 if ((error = device_detach(dev)) != 0) 368 return error; 369 device_set_driver(dev, NULL); 370 } 371 } 372 } 373 374 TAILQ_REMOVE(&busclass->drivers, dl, link); 375 free(dl, M_DEVBUF); 376 377 driver->refs--; 378 if (driver->refs == 0) 379 free_methods(driver); 380 381 return 0; 382 } 383 384 static driverlink_t 385 devclass_find_driver_internal(devclass_t dc, const char *classname) 386 { 387 driverlink_t dl; 388 389 PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc))); 390 391 for (dl = TAILQ_FIRST(&dc->drivers); dl; dl = TAILQ_NEXT(dl, link)) { 392 if (!strcmp(dl->driver->name, classname)) 393 return dl; 394 } 395 396 PDEBUG(("not found")); 397 return NULL; 398 } 399 400 driver_t * 401 devclass_find_driver(devclass_t dc, const char *classname) 402 { 403 driverlink_t dl; 404 405 dl = devclass_find_driver_internal(dc, classname); 406 if (dl) 407 return dl->driver; 408 else 409 return NULL; 410 } 411 412 const char * 413 devclass_get_name(devclass_t dc) 414 { 415 return dc->name; 416 } 417 418 device_t 419 devclass_get_device(devclass_t dc, int unit) 420 { 421 if (dc == NULL || unit < 0 || unit >= dc->maxunit) 422 return NULL; 423 return dc->devices[unit]; 424 } 425 426 void * 427 devclass_get_softc(devclass_t dc, int unit) 428 { 429 device_t dev; 430 431 if (unit < 0 || unit >= dc->maxunit) 432 return NULL; 433 dev = dc->devices[unit]; 434 if (!dev || dev->state < DS_ATTACHED) 435 return NULL; 436 return dev->softc; 437 } 438 439 int 440 devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp) 441 { 442 int i; 443 int count; 444 device_t *list; 445 446 count = 0; 447 for (i = 0; i < dc->maxunit; i++) 448 if (dc->devices[i]) 449 count++; 450 451 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT); 452 if (!list) 453 return ENOMEM; 454 bzero(list, count * sizeof(device_t)); 455 456 count = 0; 457 for (i = 0; i < dc->maxunit; i++) 458 if (dc->devices[i]) { 459 list[count] = dc->devices[i]; 460 count++; 461 } 462 463 *devlistp = list; 464 *devcountp = count; 465 466 return 0; 467 } 468 469 int 470 devclass_get_maxunit(devclass_t dc) 471 { 472 return dc->maxunit; 473 } 474 475 static int 476 devclass_alloc_unit(devclass_t dc, int *unitp) 477 { 478 int unit = *unitp; 479 480 PDEBUG(("unit %d in devclass %s", unit, DEVCLANAME(dc))); 481 482 /* 483 * If we have been given a wired unit number, check for existing 484 * device. 485 */ 486 if (unit != -1) { 487 device_t dev; 488 dev = devclass_get_device(dc, unit); 489 if (dev) { 490 printf("devclass_alloc_unit: %s%d already exists, using next available unit number\n", dc->name, unit); 491 unit = -1; 492 } 493 } 494 495 if (unit == -1) { 496 unit = dc->nextunit; 497 dc->nextunit++; 498 } else if (dc->nextunit <= unit) 499 dc->nextunit = unit + 1; 500 501 if (unit >= dc->maxunit) { 502 device_t *newlist; 503 int newsize; 504 505 newsize = (dc->maxunit ? 2 * dc->maxunit 506 : MINALLOCSIZE / sizeof(device_t)); 507 newlist = malloc(sizeof(device_t) * newsize, M_DEVBUF, M_NOWAIT); 508 if (!newlist) 509 return ENOMEM; 510 bcopy(dc->devices, newlist, sizeof(device_t) * dc->maxunit); 511 bzero(newlist + dc->maxunit, 512 sizeof(device_t) * (newsize - dc->maxunit)); 513 if (dc->devices) 514 free(dc->devices, M_DEVBUF); 515 dc->devices = newlist; 516 dc->maxunit = newsize; 517 } 518 PDEBUG(("now: unit %d in devclass %s", unit, DEVCLANAME(dc))); 519 520 *unitp = unit; 521 return 0; 522 } 523 524 static int 525 devclass_add_device(devclass_t dc, device_t dev) 526 { 527 int buflen, error; 528 529 PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc))); 530 531 buflen = strlen(dc->name) + 5; 532 dev->nameunit = malloc(buflen, M_DEVBUF, M_NOWAIT); 533 if (!dev->nameunit) 534 return ENOMEM; 535 bzero(dev->nameunit, buflen); 536 537 if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0) { 538 free(dev->nameunit, M_DEVBUF); 539 dev->nameunit = NULL; 540 return error; 541 } 542 dc->devices[dev->unit] = dev; 543 dev->devclass = dc; 544 snprintf(dev->nameunit, buflen, "%s%d", dc->name, dev->unit); 545 546 #ifdef DEVICE_SYSCTLS 547 device_register_oids(dev); 548 #endif 549 550 return 0; 551 } 552 553 static int 554 devclass_delete_device(devclass_t dc, device_t dev) 555 { 556 if (!dc || !dev) 557 return 0; 558 559 PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc))); 560 561 if (dev->devclass != dc 562 || dc->devices[dev->unit] != dev) 563 panic("devclass_delete_device: inconsistent device class"); 564 dc->devices[dev->unit] = NULL; 565 if (dev->flags & DF_WILDCARD) 566 dev->unit = -1; 567 dev->devclass = NULL; 568 free(dev->nameunit, M_DEVBUF); 569 dev->nameunit = NULL; 570 while (dc->nextunit > 0 && dc->devices[dc->nextunit - 1] == NULL) 571 dc->nextunit--; 572 573 #ifdef DEVICE_SYSCTLS 574 device_unregister_oids(dev); 575 #endif 576 577 return 0; 578 } 579 580 static device_t 581 make_device(device_t parent, const char *name, 582 int unit, void *ivars) 583 { 584 device_t dev; 585 devclass_t dc; 586 587 PDEBUG(("%s at %s as unit %d with%s ivars", 588 name, DEVICENAME(parent), unit, (ivars? "":"out"))); 589 590 if (name) { 591 dc = devclass_find_internal(name, TRUE); 592 if (!dc) { 593 printf("make_device: can't find device class %s\n", name); 594 return NULL; 595 } 596 } else 597 dc = NULL; 598 599 dev = malloc(sizeof(struct device), M_DEVBUF, M_NOWAIT); 600 if (!dev) 601 return 0; 602 bzero(dev, sizeof(struct device)); 603 604 dev->parent = parent; 605 TAILQ_INIT(&dev->children); 606 dev->ops = &null_ops; 607 dev->driver = NULL; 608 dev->devclass = NULL; 609 dev->unit = unit; 610 dev->nameunit = NULL; 611 dev->desc = NULL; 612 dev->busy = 0; 613 dev->flags = DF_ENABLED; 614 dev->order = 0; 615 if (unit == -1) 616 dev->flags |= DF_WILDCARD; 617 if (name) { 618 dev->flags |= DF_FIXEDCLASS; 619 devclass_add_device(dc, dev); 620 } 621 dev->ivars = ivars; 622 dev->softc = NULL; 623 624 dev->state = DS_NOTPRESENT; 625 626 return dev; 627 } 628 629 static int 630 device_print_child(device_t dev, device_t child) 631 { 632 int retval = 0; 633 634 if (device_is_alive(child)) { 635 retval += BUS_PRINT_CHILD(dev, child); 636 } else 637 retval += device_printf(child, " not found\n"); 638 639 return (retval); 640 } 641 642 device_t 643 device_add_child(device_t dev, const char *name, int unit, void *ivars) 644 { 645 return device_add_child_ordered(dev, 0, name, unit, ivars); 646 } 647 648 device_t 649 device_add_child_ordered(device_t dev, int order, 650 const char *name, int unit, void *ivars) 651 { 652 device_t child; 653 device_t place; 654 655 PDEBUG(("%s at %s with order %d as unit %d with%s ivars", 656 name, DEVICENAME(dev), order, unit, (ivars? "":"out"))); 657 658 child = make_device(dev, name, unit, ivars); 659 if (child == NULL) 660 return child; 661 child->order = order; 662 663 TAILQ_FOREACH(place, &dev->children, link) 664 if (place->order > order) 665 break; 666 667 if (place) { 668 /* 669 * The device 'place' is the first device whose order is 670 * greater than the new child. 671 */ 672 TAILQ_INSERT_BEFORE(place, child, link); 673 } else { 674 /* 675 * The new child's order is greater or equal to the order of 676 * any existing device. Add the child to the tail of the list. 677 */ 678 TAILQ_INSERT_TAIL(&dev->children, child, link); 679 } 680 681 return child; 682 } 683 684 int 685 device_delete_child(device_t dev, device_t child) 686 { 687 int error; 688 device_t grandchild; 689 690 PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev))); 691 692 /* remove children first */ 693 while ( (grandchild = TAILQ_FIRST(&child->children)) ) { 694 error = device_delete_child(child, grandchild); 695 if (error) 696 return error; 697 } 698 699 if ((error = device_detach(child)) != 0) 700 return error; 701 if (child->devclass) 702 devclass_delete_device(child->devclass, child); 703 TAILQ_REMOVE(&dev->children, child, link); 704 device_set_desc(child, NULL); 705 free(child, M_DEVBUF); 706 707 return 0; 708 } 709 710 /* 711 * Find only devices attached to this bus. 712 */ 713 device_t 714 device_find_child(device_t dev, const char *classname, int unit) 715 { 716 devclass_t dc; 717 device_t child; 718 719 dc = devclass_find(classname); 720 if (!dc) 721 return NULL; 722 723 child = devclass_get_device(dc, unit); 724 if (child && child->parent == dev) 725 return child; 726 return NULL; 727 } 728 729 static driverlink_t 730 first_matching_driver(devclass_t dc, device_t dev) 731 { 732 if (dev->devclass) 733 return devclass_find_driver_internal(dc, dev->devclass->name); 734 else 735 return TAILQ_FIRST(&dc->drivers); 736 } 737 738 static driverlink_t 739 next_matching_driver(devclass_t dc, device_t dev, driverlink_t last) 740 { 741 if (dev->devclass) { 742 driverlink_t dl; 743 for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link)) 744 if (!strcmp(dev->devclass->name, dl->driver->name)) 745 return dl; 746 return NULL; 747 } else 748 return TAILQ_NEXT(last, link); 749 } 750 751 static int 752 device_probe_child(device_t dev, device_t child) 753 { 754 devclass_t dc; 755 driverlink_t best = 0; 756 driverlink_t dl; 757 int result, pri = 0; 758 759 dc = dev->devclass; 760 if (dc == NULL) 761 panic("device_probe_child: parent device has no devclass"); 762 763 if (child->state == DS_ALIVE) 764 return 0; 765 766 for (dl = first_matching_driver(dc, child); 767 dl; 768 dl = next_matching_driver(dc, child, dl)) { 769 PDEBUG(("Trying %s", DRIVERNAME(dl->driver))); 770 device_set_driver(child, dl->driver); 771 result = DEVICE_PROBE(child); 772 773 /* 774 * If the driver returns SUCCESS, there can be no higher match 775 * for this device. 776 */ 777 if (result == 0) { 778 best = dl; 779 pri = 0; 780 break; 781 } 782 783 /* 784 * The driver returned an error so it certainly doesn't match. 785 */ 786 if (result > 0) 787 continue; 788 789 /* 790 * A priority lower than SUCCESS, remember the best matching 791 * driver. Initialise the value of pri for the first match. 792 */ 793 if (best == 0 || result > pri) { 794 best = dl; 795 pri = result; 796 continue; 797 } 798 } 799 800 /* 801 * If we found a driver, change state and initialise the devclass. 802 */ 803 if (best) { 804 if (!child->devclass) 805 device_set_devclass(child, best->driver->name); 806 device_set_driver(child, best->driver); 807 if (pri < 0) { 808 /* 809 * A bit bogus. Call the probe method again to make sure 810 * that we have the right description. 811 */ 812 DEVICE_PROBE(child); 813 } 814 child->state = DS_ALIVE; 815 return 0; 816 } 817 818 return ENXIO; 819 } 820 821 device_t 822 device_get_parent(device_t dev) 823 { 824 return dev->parent; 825 } 826 827 int 828 device_get_children(device_t dev, device_t **devlistp, int *devcountp) 829 { 830 int count; 831 device_t child; 832 device_t *list; 833 834 count = 0; 835 for (child = TAILQ_FIRST(&dev->children); child; 836 child = TAILQ_NEXT(child, link)) 837 count++; 838 839 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT); 840 if (!list) 841 return ENOMEM; 842 bzero(list, count * sizeof(device_t)); 843 844 count = 0; 845 for (child = TAILQ_FIRST(&dev->children); child; 846 child = TAILQ_NEXT(child, link)) { 847 list[count] = child; 848 count++; 849 } 850 851 *devlistp = list; 852 *devcountp = count; 853 854 return 0; 855 } 856 857 driver_t * 858 device_get_driver(device_t dev) 859 { 860 return dev->driver; 861 } 862 863 devclass_t 864 device_get_devclass(device_t dev) 865 { 866 return dev->devclass; 867 } 868 869 const char * 870 device_get_name(device_t dev) 871 { 872 if (dev->devclass) 873 return devclass_get_name(dev->devclass); 874 return NULL; 875 } 876 877 const char * 878 device_get_nameunit(device_t dev) 879 { 880 return dev->nameunit; 881 } 882 883 int 884 device_get_unit(device_t dev) 885 { 886 return dev->unit; 887 } 888 889 const char * 890 device_get_desc(device_t dev) 891 { 892 return dev->desc; 893 } 894 895 int 896 device_print_prettyname(device_t dev) 897 { 898 const char *name = device_get_name(dev); 899 900 if (name == 0) 901 name = "(no driver assigned)"; 902 return(printf("%s%d: ", name, device_get_unit(dev))); 903 } 904 905 int 906 device_printf(device_t dev, const char * fmt, ...) 907 { 908 va_list ap; 909 int retval; 910 911 retval = device_print_prettyname(dev); 912 va_start(ap, fmt); 913 retval += vprintf(fmt, ap); 914 va_end(ap); 915 return retval; 916 } 917 918 static void 919 device_set_desc_internal(device_t dev, const char* desc, int copy) 920 { 921 if (dev->desc && (dev->flags & DF_DESCMALLOCED)) { 922 free(dev->desc, M_DEVBUF); 923 dev->flags &= ~DF_DESCMALLOCED; 924 dev->desc = NULL; 925 } 926 927 if (copy && desc) { 928 dev->desc = malloc(strlen(desc) + 1, M_DEVBUF, M_NOWAIT); 929 if (dev->desc) { 930 strcpy(dev->desc, desc); 931 dev->flags |= DF_DESCMALLOCED; 932 } 933 } else 934 /* Avoid a -Wcast-qual warning */ 935 dev->desc = (char *)(uintptr_t) desc; 936 937 #ifdef DEVICE_SYSCTLS 938 { 939 struct sysctl_oid *oid = &dev->oid[1]; 940 oid->oid_arg1 = dev->desc ? dev->desc : ""; 941 oid->oid_arg2 = dev->desc ? strlen(dev->desc) : 0; 942 } 943 #endif 944 } 945 946 void 947 device_set_desc(device_t dev, const char* desc) 948 { 949 device_set_desc_internal(dev, desc, FALSE); 950 } 951 952 void 953 device_set_desc_copy(device_t dev, const char* desc) 954 { 955 device_set_desc_internal(dev, desc, TRUE); 956 } 957 958 void * 959 device_get_softc(device_t dev) 960 { 961 return dev->softc; 962 } 963 964 void * 965 device_get_ivars(device_t dev) 966 { 967 return dev->ivars; 968 } 969 970 device_state_t 971 device_get_state(device_t dev) 972 { 973 return dev->state; 974 } 975 976 void 977 device_enable(device_t dev) 978 { 979 dev->flags |= DF_ENABLED; 980 } 981 982 void 983 device_disable(device_t dev) 984 { 985 dev->flags &= ~DF_ENABLED; 986 } 987 988 void 989 device_busy(device_t dev) 990 { 991 if (dev->state < DS_ATTACHED) 992 panic("device_busy: called for unattached device"); 993 if (dev->busy == 0 && dev->parent) 994 device_busy(dev->parent); 995 dev->busy++; 996 dev->state = DS_BUSY; 997 } 998 999 void 1000 device_unbusy(device_t dev) 1001 { 1002 if (dev->state != DS_BUSY) 1003 panic("device_unbusy: called for non-busy device"); 1004 dev->busy--; 1005 if (dev->busy == 0) { 1006 if (dev->parent) 1007 device_unbusy(dev->parent); 1008 dev->state = DS_ATTACHED; 1009 } 1010 } 1011 1012 void 1013 device_quiet(device_t dev) 1014 { 1015 dev->flags |= DF_QUIET; 1016 } 1017 1018 void 1019 device_verbose(device_t dev) 1020 { 1021 dev->flags &= ~DF_QUIET; 1022 } 1023 1024 int 1025 device_is_quiet(device_t dev) 1026 { 1027 return (dev->flags & DF_QUIET) != 0; 1028 } 1029 1030 int 1031 device_is_enabled(device_t dev) 1032 { 1033 return (dev->flags & DF_ENABLED) != 0; 1034 } 1035 1036 int 1037 device_is_alive(device_t dev) 1038 { 1039 return dev->state >= DS_ALIVE; 1040 } 1041 1042 int 1043 device_set_devclass(device_t dev, const char *classname) 1044 { 1045 devclass_t dc; 1046 1047 if (dev->devclass) { 1048 printf("device_set_devclass: device class already set\n"); 1049 return EINVAL; 1050 } 1051 1052 dc = devclass_find_internal(classname, TRUE); 1053 if (!dc) 1054 return ENOMEM; 1055 1056 return devclass_add_device(dc, dev); 1057 } 1058 1059 int 1060 device_set_driver(device_t dev, driver_t *driver) 1061 { 1062 if (dev->state >= DS_ATTACHED) 1063 return EBUSY; 1064 1065 if (dev->driver == driver) 1066 return 0; 1067 1068 if (dev->softc) { 1069 free(dev->softc, M_DEVBUF); 1070 dev->softc = NULL; 1071 } 1072 dev->ops = &null_ops; 1073 dev->driver = driver; 1074 if (driver) { 1075 dev->ops = driver->ops; 1076 dev->softc = malloc(driver->softc, M_DEVBUF, M_NOWAIT); 1077 if (!dev->softc) { 1078 dev->ops = &null_ops; 1079 dev->driver = NULL; 1080 return ENOMEM; 1081 } 1082 bzero(dev->softc, driver->softc); 1083 } 1084 return 0; 1085 } 1086 1087 int 1088 device_probe_and_attach(device_t dev) 1089 { 1090 device_t bus = dev->parent; 1091 int error = 0; 1092 1093 if (dev->state >= DS_ALIVE) 1094 return 0; 1095 1096 if (dev->flags & DF_ENABLED) { 1097 error = device_probe_child(bus, dev); 1098 if (!error) { 1099 if (!device_is_quiet(dev)) 1100 device_print_child(bus, dev); 1101 error = DEVICE_ATTACH(dev); 1102 if (!error) 1103 dev->state = DS_ATTACHED; 1104 else { 1105 printf("device_probe_and_attach: %s%d attach returned %d\n", 1106 dev->driver->name, dev->unit, error); 1107 device_set_driver(dev, NULL); 1108 dev->state = DS_NOTPRESENT; 1109 } 1110 } else { 1111 BUS_PROBE_NOMATCH(bus, dev); 1112 } 1113 } else { 1114 device_print_prettyname(dev); 1115 printf("not probed (disabled)\n"); 1116 } 1117 1118 return error; 1119 } 1120 1121 int 1122 device_detach(device_t dev) 1123 { 1124 int error; 1125 1126 PDEBUG(("%s", DEVICENAME(dev))); 1127 if (dev->state == DS_BUSY) 1128 return EBUSY; 1129 if (dev->state != DS_ATTACHED) 1130 return 0; 1131 1132 if ((error = DEVICE_DETACH(dev)) != 0) 1133 return error; 1134 if (dev->parent) 1135 BUS_CHILD_DETACHED(dev->parent, dev); 1136 1137 if (!(dev->flags & DF_FIXEDCLASS)) 1138 devclass_delete_device(dev->devclass, dev); 1139 1140 dev->state = DS_NOTPRESENT; 1141 device_set_driver(dev, NULL); 1142 1143 return 0; 1144 } 1145 1146 int 1147 device_shutdown(device_t dev) 1148 { 1149 if (dev->state < DS_ATTACHED) 1150 return 0; 1151 return DEVICE_SHUTDOWN(dev); 1152 } 1153 1154 #ifdef DEVICE_SYSCTLS 1155 1156 /* 1157 * Sysctl nodes for devices. 1158 */ 1159 1160 SYSCTL_NODE(_hw, OID_AUTO, devices, CTLFLAG_RW, 0, "A list of all devices"); 1161 1162 static int 1163 sysctl_handle_children SYSCTL_HANDLER_ARGS 1164 { 1165 device_t dev = arg1; 1166 device_t child; 1167 int first = 1, error = 0; 1168 1169 for (child = TAILQ_FIRST(&dev->children); child; 1170 child = TAILQ_NEXT(child, link)) { 1171 if (child->nameunit) { 1172 if (!first) { 1173 error = SYSCTL_OUT(req, ",", 1); 1174 if (error) return error; 1175 } else { 1176 first = 0; 1177 } 1178 error = SYSCTL_OUT(req, child->nameunit, strlen(child->nameunit)); 1179 if (error) return error; 1180 } 1181 } 1182 1183 error = SYSCTL_OUT(req, "", 1); 1184 1185 return error; 1186 } 1187 1188 static int 1189 sysctl_handle_state SYSCTL_HANDLER_ARGS 1190 { 1191 device_t dev = arg1; 1192 1193 switch (dev->state) { 1194 case DS_NOTPRESENT: 1195 return SYSCTL_OUT(req, "notpresent", sizeof("notpresent")); 1196 case DS_ALIVE: 1197 return SYSCTL_OUT(req, "alive", sizeof("alive")); 1198 case DS_ATTACHED: 1199 return SYSCTL_OUT(req, "attached", sizeof("attached")); 1200 case DS_BUSY: 1201 return SYSCTL_OUT(req, "busy", sizeof("busy")); 1202 } 1203 1204 return 0; 1205 } 1206 1207 static void 1208 device_register_oids(device_t dev) 1209 { 1210 struct sysctl_oid* oid; 1211 1212 oid = &dev->oid[0]; 1213 bzero(oid, sizeof(*oid)); 1214 oid->oid_parent = &sysctl__hw_devices_children; 1215 oid->oid_number = OID_AUTO; 1216 oid->oid_kind = CTLTYPE_NODE | CTLFLAG_RW; 1217 oid->oid_arg1 = &dev->oidlist[0]; 1218 oid->oid_arg2 = 0; 1219 oid->oid_name = dev->nameunit; 1220 oid->oid_handler = 0; 1221 oid->oid_fmt = "N"; 1222 SLIST_INIT(&dev->oidlist[0]); 1223 sysctl_register_oid(oid); 1224 1225 oid = &dev->oid[1]; 1226 bzero(oid, sizeof(*oid)); 1227 oid->oid_parent = &dev->oidlist[0]; 1228 oid->oid_number = OID_AUTO; 1229 oid->oid_kind = CTLTYPE_STRING | CTLFLAG_RD; 1230 oid->oid_arg1 = dev->desc ? dev->desc : ""; 1231 oid->oid_arg2 = dev->desc ? strlen(dev->desc) : 0; 1232 oid->oid_name = "desc"; 1233 oid->oid_handler = sysctl_handle_string; 1234 oid->oid_fmt = "A"; 1235 sysctl_register_oid(oid); 1236 1237 oid = &dev->oid[2]; 1238 bzero(oid, sizeof(*oid)); 1239 oid->oid_parent = &dev->oidlist[0]; 1240 oid->oid_number = OID_AUTO; 1241 oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD; 1242 oid->oid_arg1 = dev; 1243 oid->oid_arg2 = 0; 1244 oid->oid_name = "children"; 1245 oid->oid_handler = sysctl_handle_children; 1246 oid->oid_fmt = "A"; 1247 sysctl_register_oid(oid); 1248 1249 oid = &dev->oid[3]; 1250 bzero(oid, sizeof(*oid)); 1251 oid->oid_parent = &dev->oidlist[0]; 1252 oid->oid_number = OID_AUTO; 1253 oid->oid_kind = CTLTYPE_INT | CTLFLAG_RD; 1254 oid->oid_arg1 = dev; 1255 oid->oid_arg2 = 0; 1256 oid->oid_name = "state"; 1257 oid->oid_handler = sysctl_handle_state; 1258 oid->oid_fmt = "A"; 1259 sysctl_register_oid(oid); 1260 } 1261 1262 static void 1263 device_unregister_oids(device_t dev) 1264 { 1265 sysctl_unregister_oid(&dev->oid[0]); 1266 sysctl_unregister_oid(&dev->oid[1]); 1267 sysctl_unregister_oid(&dev->oid[2]); 1268 } 1269 1270 #endif 1271 1272 /*======================================*/ 1273 /* 1274 * Access functions for device resources. 1275 */ 1276 1277 /* Supplied by config(8) in ioconf.c */ 1278 extern struct config_device config_devtab[]; 1279 extern int devtab_count; 1280 1281 /* Runtime version */ 1282 struct config_device *devtab = config_devtab; 1283 1284 static int 1285 resource_new_name(char *name, int unit) 1286 { 1287 struct config_device *new; 1288 1289 new = malloc((devtab_count + 1) * sizeof(*new), M_TEMP, M_NOWAIT); 1290 if (new == NULL) 1291 return -1; 1292 if (devtab && devtab_count > 0) 1293 bcopy(devtab, new, devtab_count * sizeof(*new)); 1294 bzero(&new[devtab_count], sizeof(*new)); 1295 new[devtab_count].name = malloc(strlen(name) + 1, M_TEMP, M_NOWAIT); 1296 if (new[devtab_count].name == NULL) { 1297 free(new, M_TEMP); 1298 return -1; 1299 } 1300 strcpy(new[devtab_count].name, name); 1301 new[devtab_count].unit = unit; 1302 new[devtab_count].resource_count = 0; 1303 new[devtab_count].resources = NULL; 1304 devtab = new; 1305 return devtab_count++; 1306 } 1307 1308 static int 1309 resource_new_resname(int j, char *resname, resource_type type) 1310 { 1311 struct config_resource *new; 1312 int i; 1313 1314 i = devtab[j].resource_count; 1315 new = malloc((i + 1) * sizeof(*new), M_TEMP, M_NOWAIT); 1316 if (new == NULL) 1317 return -1; 1318 if (devtab[j].resources && i > 0) 1319 bcopy(devtab[j].resources, new, i * sizeof(*new)); 1320 bzero(&new[i], sizeof(*new)); 1321 new[i].name = malloc(strlen(resname) + 1, M_TEMP, M_NOWAIT); 1322 if (new[i].name == NULL) { 1323 free(new, M_TEMP); 1324 return -1; 1325 } 1326 strcpy(new[i].name, resname); 1327 new[i].type = type; 1328 if (devtab[j].resources) 1329 free(devtab[j].resources, M_TEMP); 1330 devtab[j].resources = new; 1331 devtab[j].resource_count = i + 1; 1332 return i; 1333 } 1334 1335 static int 1336 resource_match_string(int i, char *resname, char *value) 1337 { 1338 int j; 1339 struct config_resource *res; 1340 1341 for (j = 0, res = devtab[i].resources; 1342 j < devtab[i].resource_count; j++, res++) 1343 if (!strcmp(res->name, resname) 1344 && res->type == RES_STRING 1345 && !strcmp(res->u.stringval, value)) 1346 return j; 1347 return -1; 1348 } 1349 1350 static int 1351 resource_find(const char *name, int unit, char *resname, 1352 struct config_resource **result) 1353 { 1354 int i, j; 1355 struct config_resource *res; 1356 1357 /* 1358 * First check specific instances, then generic. 1359 */ 1360 for (i = 0; i < devtab_count; i++) { 1361 if (devtab[i].unit < 0) 1362 continue; 1363 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) { 1364 res = devtab[i].resources; 1365 for (j = 0; j < devtab[i].resource_count; j++, res++) 1366 if (!strcmp(res->name, resname)) { 1367 *result = res; 1368 return 0; 1369 } 1370 } 1371 } 1372 for (i = 0; i < devtab_count; i++) { 1373 if (devtab[i].unit >= 0) 1374 continue; 1375 /* XXX should this `&& devtab[i].unit == unit' be here? */ 1376 /* XXX if so, then the generic match does nothing */ 1377 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) { 1378 res = devtab[i].resources; 1379 for (j = 0; j < devtab[i].resource_count; j++, res++) 1380 if (!strcmp(res->name, resname)) { 1381 *result = res; 1382 return 0; 1383 } 1384 } 1385 } 1386 return ENOENT; 1387 } 1388 1389 int 1390 resource_int_value(const char *name, int unit, char *resname, int *result) 1391 { 1392 int error; 1393 struct config_resource *res; 1394 1395 if ((error = resource_find(name, unit, resname, &res)) != 0) 1396 return error; 1397 if (res->type != RES_INT) 1398 return EFTYPE; 1399 *result = res->u.intval; 1400 return 0; 1401 } 1402 1403 int 1404 resource_long_value(const char *name, int unit, char *resname, long *result) 1405 { 1406 int error; 1407 struct config_resource *res; 1408 1409 if ((error = resource_find(name, unit, resname, &res)) != 0) 1410 return error; 1411 if (res->type != RES_LONG) 1412 return EFTYPE; 1413 *result = res->u.longval; 1414 return 0; 1415 } 1416 1417 int 1418 resource_string_value(const char *name, int unit, char *resname, char **result) 1419 { 1420 int error; 1421 struct config_resource *res; 1422 1423 if ((error = resource_find(name, unit, resname, &res)) != 0) 1424 return error; 1425 if (res->type != RES_STRING) 1426 return EFTYPE; 1427 *result = res->u.stringval; 1428 return 0; 1429 } 1430 1431 int 1432 resource_query_string(int i, char *resname, char *value) 1433 { 1434 if (i < 0) 1435 i = 0; 1436 else 1437 i = i + 1; 1438 for (; i < devtab_count; i++) 1439 if (resource_match_string(i, resname, value) >= 0) 1440 return i; 1441 return -1; 1442 } 1443 1444 int 1445 resource_locate(int i, char *resname) 1446 { 1447 if (i < 0) 1448 i = 0; 1449 else 1450 i = i + 1; 1451 for (; i < devtab_count; i++) 1452 if (!strcmp(devtab[i].name, resname)) 1453 return i; 1454 return -1; 1455 } 1456 1457 int 1458 resource_count(void) 1459 { 1460 return devtab_count; 1461 } 1462 1463 char * 1464 resource_query_name(int i) 1465 { 1466 return devtab[i].name; 1467 } 1468 1469 int 1470 resource_query_unit(int i) 1471 { 1472 return devtab[i].unit; 1473 } 1474 1475 static int 1476 resource_create(char *name, int unit, char *resname, resource_type type, 1477 struct config_resource **result) 1478 { 1479 int i, j; 1480 struct config_resource *res = NULL; 1481 1482 for (i = 0; i < devtab_count; i++) { 1483 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) { 1484 res = devtab[i].resources; 1485 break; 1486 } 1487 } 1488 if (res == NULL) { 1489 i = resource_new_name(name, unit); 1490 if (i < 0) 1491 return ENOMEM; 1492 res = devtab[i].resources; 1493 } 1494 for (j = 0; j < devtab[i].resource_count; j++, res++) { 1495 if (!strcmp(res->name, resname)) { 1496 *result = res; 1497 return 0; 1498 } 1499 } 1500 j = resource_new_resname(i, resname, type); 1501 if (j < 0) 1502 return ENOMEM; 1503 res = &devtab[i].resources[j]; 1504 *result = res; 1505 return 0; 1506 } 1507 1508 int 1509 resource_set_int(char *name, int unit, char *resname, int value) 1510 { 1511 int error; 1512 struct config_resource *res; 1513 1514 error = resource_create(name, unit, resname, RES_INT, &res); 1515 if (error) 1516 return error; 1517 if (res->type != RES_INT) 1518 return EFTYPE; 1519 res->u.intval = value; 1520 return 0; 1521 } 1522 1523 int 1524 resource_set_long(char *name, int unit, char *resname, long value) 1525 { 1526 int error; 1527 struct config_resource *res; 1528 1529 error = resource_create(name, unit, resname, RES_LONG, &res); 1530 if (error) 1531 return error; 1532 if (res->type != RES_LONG) 1533 return EFTYPE; 1534 res->u.longval = value; 1535 return 0; 1536 } 1537 1538 int 1539 resource_set_string(char *name, int unit, char *resname, char *value) 1540 { 1541 int error; 1542 struct config_resource *res; 1543 1544 error = resource_create(name, unit, resname, RES_STRING, &res); 1545 if (error) 1546 return error; 1547 if (res->type != RES_STRING) 1548 return EFTYPE; 1549 if (res->u.stringval) 1550 free(res->u.stringval, M_TEMP); 1551 res->u.stringval = malloc(strlen(value) + 1, M_TEMP, M_NOWAIT); 1552 if (res->u.stringval == NULL) 1553 return ENOMEM; 1554 strcpy(res->u.stringval, value); 1555 return 0; 1556 } 1557 1558 1559 static void 1560 resource_cfgload(void *dummy __unused) 1561 { 1562 struct config_resource *res, *cfgres; 1563 int i, j; 1564 int error; 1565 char *name, *resname; 1566 int unit; 1567 resource_type type; 1568 char *stringval; 1569 int config_devtab_count; 1570 1571 config_devtab_count = devtab_count; 1572 devtab = NULL; 1573 devtab_count = 0; 1574 1575 for (i = 0; i < config_devtab_count; i++) { 1576 name = config_devtab[i].name; 1577 unit = config_devtab[i].unit; 1578 1579 for (j = 0; j < config_devtab[i].resource_count; j++) { 1580 cfgres = config_devtab[i].resources; 1581 resname = cfgres[j].name; 1582 type = cfgres[j].type; 1583 error = resource_create(name, unit, resname, type, 1584 &res); 1585 if (error) { 1586 printf("create resource %s%d: error %d\n", 1587 name, unit, error); 1588 continue; 1589 } 1590 if (res->type != type) { 1591 printf("type mismatch %s%d: %d != %d\n", 1592 name, unit, res->type, type); 1593 continue; 1594 } 1595 switch (type) { 1596 case RES_INT: 1597 res->u.intval = cfgres[j].u.intval; 1598 break; 1599 case RES_LONG: 1600 res->u.longval = cfgres[j].u.longval; 1601 break; 1602 case RES_STRING: 1603 if (res->u.stringval) 1604 free(res->u.stringval, M_TEMP); 1605 stringval = cfgres[j].u.stringval; 1606 res->u.stringval = malloc(strlen(stringval) + 1, 1607 M_TEMP, M_NOWAIT); 1608 if (res->u.stringval == NULL) 1609 break; 1610 strcpy(res->u.stringval, stringval); 1611 break; 1612 default: 1613 panic("unknown resource type %d\n", type); 1614 } 1615 } 1616 } 1617 } 1618 SYSINIT(cfgload, SI_SUB_KMEM, SI_ORDER_ANY + 50, resource_cfgload, 0) 1619 1620 1621 /*======================================*/ 1622 /* 1623 * Some useful method implementations to make life easier for bus drivers. 1624 */ 1625 1626 void 1627 resource_list_init(struct resource_list *rl) 1628 { 1629 SLIST_INIT(rl); 1630 } 1631 1632 void 1633 resource_list_free(struct resource_list *rl) 1634 { 1635 struct resource_list_entry *rle; 1636 1637 while ((rle = SLIST_FIRST(rl)) != NULL) { 1638 if (rle->res) 1639 panic("resource_list_free: resource entry is busy"); 1640 SLIST_REMOVE_HEAD(rl, link); 1641 free(rle, M_DEVBUF); 1642 } 1643 } 1644 1645 void 1646 resource_list_add(struct resource_list *rl, 1647 int type, int rid, 1648 u_long start, u_long end, u_long count) 1649 { 1650 struct resource_list_entry *rle; 1651 1652 rle = resource_list_find(rl, type, rid); 1653 if (!rle) { 1654 rle = malloc(sizeof(struct resource_list_entry), M_DEVBUF, M_NOWAIT); 1655 if (!rle) 1656 panic("resource_list_add: can't record entry"); 1657 SLIST_INSERT_HEAD(rl, rle, link); 1658 rle->type = type; 1659 rle->rid = rid; 1660 rle->res = NULL; 1661 } 1662 1663 if (rle->res) 1664 panic("resource_list_add: resource entry is busy"); 1665 1666 rle->start = start; 1667 rle->end = end; 1668 rle->count = count; 1669 } 1670 1671 struct resource_list_entry* 1672 resource_list_find(struct resource_list *rl, 1673 int type, int rid) 1674 { 1675 struct resource_list_entry *rle; 1676 1677 SLIST_FOREACH(rle, rl, link) 1678 if (rle->type == type && rle->rid == rid) 1679 return rle; 1680 return NULL; 1681 } 1682 1683 void 1684 resource_list_delete(struct resource_list *rl, 1685 int type, int rid) 1686 { 1687 struct resource_list_entry *rle = resource_list_find(rl, type, rid); 1688 1689 if (rle) { 1690 SLIST_REMOVE(rl, rle, resource_list_entry, link); 1691 free(rle, M_DEVBUF); 1692 } 1693 } 1694 1695 struct resource * 1696 resource_list_alloc(device_t bus, device_t child, 1697 int type, int *rid, 1698 u_long start, u_long end, 1699 u_long count, u_int flags) 1700 { 1701 struct resource_list *rl; 1702 struct resource_list_entry *rle = 0; 1703 int passthrough = (device_get_parent(child) != bus); 1704 int isdefault = (start == 0UL && end == ~0UL); 1705 1706 if (passthrough) { 1707 return BUS_ALLOC_RESOURCE(device_get_parent(bus), child, 1708 type, rid, 1709 start, end, count, flags); 1710 } 1711 1712 rl = device_get_ivars(child); 1713 rle = resource_list_find(rl, type, *rid); 1714 1715 if (!rle) 1716 return 0; /* no resource of that type/rid */ 1717 if (rle->res) 1718 panic("resource_list_alloc: resource entry is busy"); 1719 1720 if (isdefault) { 1721 start = rle->start; 1722 count = max(count, rle->count); 1723 end = max(rle->end, start + count - 1); 1724 } 1725 1726 rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, 1727 type, rid, start, end, count, flags); 1728 1729 /* 1730 * Record the new range. 1731 */ 1732 if (rle->res) { 1733 rle->start = rman_get_start(rle->res); 1734 rle->end = rman_get_end(rle->res); 1735 rle->count = count; 1736 } 1737 1738 return rle->res; 1739 } 1740 1741 int 1742 resource_list_release(device_t bus, device_t child, 1743 int type, int rid, struct resource *res) 1744 { 1745 struct resource_list *rl; 1746 struct resource_list_entry *rle = 0; 1747 int passthrough = (device_get_parent(child) != bus); 1748 int error; 1749 1750 if (passthrough) { 1751 return BUS_RELEASE_RESOURCE(device_get_parent(bus), child, 1752 type, rid, res); 1753 } 1754 1755 rl = device_get_ivars(child); 1756 rle = resource_list_find(rl, type, rid); 1757 1758 if (!rle) 1759 panic("resource_list_release: can't find resource"); 1760 if (!rle->res) 1761 panic("resource_list_release: resource entry is not busy"); 1762 1763 error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, 1764 type, rid, res); 1765 if (error) 1766 return error; 1767 1768 rle->res = NULL; 1769 return 0; 1770 } 1771 1772 /* 1773 * Call DEVICE_IDENTIFY for each driver. 1774 */ 1775 int 1776 bus_generic_probe(device_t dev) 1777 { 1778 devclass_t dc = dev->devclass; 1779 driverlink_t dl; 1780 1781 for (dl = TAILQ_FIRST(&dc->drivers); dl; dl = TAILQ_NEXT(dl, link)) 1782 DEVICE_IDENTIFY(dl->driver, dev); 1783 1784 return 0; 1785 } 1786 1787 int 1788 bus_generic_attach(device_t dev) 1789 { 1790 device_t child; 1791 1792 for (child = TAILQ_FIRST(&dev->children); 1793 child; child = TAILQ_NEXT(child, link)) 1794 device_probe_and_attach(child); 1795 1796 return 0; 1797 } 1798 1799 int 1800 bus_generic_detach(device_t dev) 1801 { 1802 device_t child; 1803 int error; 1804 1805 if (dev->state != DS_ATTACHED) 1806 return EBUSY; 1807 1808 for (child = TAILQ_FIRST(&dev->children); 1809 child; child = TAILQ_NEXT(child, link)) 1810 if ((error = device_detach(child)) != 0) 1811 return error; 1812 1813 return 0; 1814 } 1815 1816 int 1817 bus_generic_shutdown(device_t dev) 1818 { 1819 device_t child; 1820 1821 for (child = TAILQ_FIRST(&dev->children); 1822 child; child = TAILQ_NEXT(child, link)) 1823 device_shutdown(child); 1824 1825 return 0; 1826 } 1827 1828 int 1829 bus_generic_suspend(device_t dev) 1830 { 1831 int error; 1832 device_t child, child2; 1833 1834 for (child = TAILQ_FIRST(&dev->children); 1835 child; child = TAILQ_NEXT(child, link)) { 1836 error = DEVICE_SUSPEND(child); 1837 if (error) { 1838 for (child2 = TAILQ_FIRST(&dev->children); 1839 child2 && child2 != child; 1840 child2 = TAILQ_NEXT(child2, link)) 1841 DEVICE_RESUME(child2); 1842 return (error); 1843 } 1844 } 1845 return 0; 1846 } 1847 1848 int 1849 bus_generic_resume(device_t dev) 1850 { 1851 device_t child; 1852 1853 for (child = TAILQ_FIRST(&dev->children); 1854 child; child = TAILQ_NEXT(child, link)) { 1855 DEVICE_RESUME(child); 1856 /* if resume fails, there's nothing we can usefully do... */ 1857 } 1858 return 0; 1859 } 1860 1861 int 1862 bus_print_child_header (device_t dev, device_t child) 1863 { 1864 int retval = 0; 1865 1866 if (device_get_desc(child)) { 1867 retval += device_printf(child, "<%s>", 1868 device_get_desc(child)); 1869 } else { 1870 retval += printf("%s", device_get_nameunit(child)); 1871 } 1872 1873 return (retval); 1874 } 1875 1876 int 1877 bus_print_child_footer (device_t dev, device_t child) 1878 { 1879 return(printf(" on %s\n", device_get_nameunit(dev))); 1880 } 1881 1882 int 1883 bus_generic_print_child(device_t dev, device_t child) 1884 { 1885 int retval = 0; 1886 1887 retval += bus_print_child_header(dev, child); 1888 retval += bus_print_child_footer(dev, child); 1889 1890 return (retval); 1891 } 1892 1893 int 1894 bus_generic_read_ivar(device_t dev, device_t child, int index, 1895 uintptr_t * result) 1896 { 1897 return ENOENT; 1898 } 1899 1900 int 1901 bus_generic_write_ivar(device_t dev, device_t child, int index, 1902 uintptr_t value) 1903 { 1904 return ENOENT; 1905 } 1906 1907 void 1908 bus_generic_driver_added(device_t dev, driver_t *driver) 1909 { 1910 device_t child; 1911 1912 for (child = TAILQ_FIRST(&dev->children); 1913 child; child = TAILQ_NEXT(child, link)) 1914 if (child->state == DS_NOTPRESENT) 1915 device_probe_and_attach(child); 1916 } 1917 1918 int 1919 bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq, 1920 int flags, driver_intr_t *intr, void *arg, 1921 void **cookiep) 1922 { 1923 /* Propagate up the bus hierarchy until someone handles it. */ 1924 if (dev->parent) 1925 return (BUS_SETUP_INTR(dev->parent, child, irq, flags, 1926 intr, arg, cookiep)); 1927 else 1928 return (EINVAL); 1929 } 1930 1931 int 1932 bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq, 1933 void *cookie) 1934 { 1935 /* Propagate up the bus hierarchy until someone handles it. */ 1936 if (dev->parent) 1937 return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie)); 1938 else 1939 return (EINVAL); 1940 } 1941 1942 struct resource * 1943 bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid, 1944 u_long start, u_long end, u_long count, u_int flags) 1945 { 1946 /* Propagate up the bus hierarchy until someone handles it. */ 1947 if (dev->parent) 1948 return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid, 1949 start, end, count, flags)); 1950 else 1951 return (NULL); 1952 } 1953 1954 int 1955 bus_generic_release_resource(device_t dev, device_t child, int type, int rid, 1956 struct resource *r) 1957 { 1958 /* Propagate up the bus hierarchy until someone handles it. */ 1959 if (dev->parent) 1960 return (BUS_RELEASE_RESOURCE(dev->parent, child, type, rid, 1961 r)); 1962 else 1963 return (EINVAL); 1964 } 1965 1966 int 1967 bus_generic_activate_resource(device_t dev, device_t child, int type, int rid, 1968 struct resource *r) 1969 { 1970 /* Propagate up the bus hierarchy until someone handles it. */ 1971 if (dev->parent) 1972 return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid, 1973 r)); 1974 else 1975 return (EINVAL); 1976 } 1977 1978 int 1979 bus_generic_deactivate_resource(device_t dev, device_t child, int type, 1980 int rid, struct resource *r) 1981 { 1982 /* Propagate up the bus hierarchy until someone handles it. */ 1983 if (dev->parent) 1984 return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid, 1985 r)); 1986 else 1987 return (EINVAL); 1988 } 1989 1990 /* 1991 * Some convenience functions to make it easier for drivers to use the 1992 * resource-management functions. All these really do is hide the 1993 * indirection through the parent's method table, making for slightly 1994 * less-wordy code. In the future, it might make sense for this code 1995 * to maintain some sort of a list of resources allocated by each device. 1996 */ 1997 struct resource * 1998 bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end, 1999 u_long count, u_int flags) 2000 { 2001 if (dev->parent == 0) 2002 return (0); 2003 return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end, 2004 count, flags)); 2005 } 2006 2007 int 2008 bus_activate_resource(device_t dev, int type, int rid, struct resource *r) 2009 { 2010 if (dev->parent == 0) 2011 return (EINVAL); 2012 return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r)); 2013 } 2014 2015 int 2016 bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r) 2017 { 2018 if (dev->parent == 0) 2019 return (EINVAL); 2020 return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r)); 2021 } 2022 2023 int 2024 bus_release_resource(device_t dev, int type, int rid, struct resource *r) 2025 { 2026 if (dev->parent == 0) 2027 return (EINVAL); 2028 return (BUS_RELEASE_RESOURCE(dev->parent, dev, 2029 type, rid, r)); 2030 } 2031 2032 int 2033 bus_setup_intr(device_t dev, struct resource *r, int flags, 2034 driver_intr_t handler, void *arg, void **cookiep) 2035 { 2036 if (dev->parent == 0) 2037 return (EINVAL); 2038 return (BUS_SETUP_INTR(dev->parent, dev, r, flags, 2039 handler, arg, cookiep)); 2040 } 2041 2042 int 2043 bus_teardown_intr(device_t dev, struct resource *r, void *cookie) 2044 { 2045 if (dev->parent == 0) 2046 return (EINVAL); 2047 return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie)); 2048 } 2049 2050 static int 2051 root_print_child(device_t dev, device_t child) 2052 { 2053 return (0); 2054 } 2055 2056 static int 2057 root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg, 2058 void **cookiep) 2059 { 2060 /* 2061 * If an interrupt mapping gets to here something bad has happened. 2062 */ 2063 panic("root_setup_intr"); 2064 } 2065 2066 static device_method_t root_methods[] = { 2067 /* Device interface */ 2068 DEVMETHOD(device_shutdown, bus_generic_shutdown), 2069 DEVMETHOD(device_suspend, bus_generic_suspend), 2070 DEVMETHOD(device_resume, bus_generic_resume), 2071 2072 /* Bus interface */ 2073 DEVMETHOD(bus_print_child, root_print_child), 2074 DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), 2075 DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), 2076 DEVMETHOD(bus_setup_intr, root_setup_intr), 2077 2078 { 0, 0 } 2079 }; 2080 2081 static driver_t root_driver = { 2082 "root", 2083 root_methods, 2084 1, /* no softc */ 2085 }; 2086 2087 device_t root_bus; 2088 devclass_t root_devclass; 2089 2090 static int 2091 root_bus_module_handler(module_t mod, int what, void* arg) 2092 { 2093 switch (what) { 2094 case MOD_LOAD: 2095 compile_methods(&root_driver); 2096 root_bus = make_device(NULL, "root", 0, NULL); 2097 root_bus->desc = "System root bus"; 2098 root_bus->ops = root_driver.ops; 2099 root_bus->driver = &root_driver; 2100 root_bus->state = DS_ATTACHED; 2101 root_devclass = devclass_find_internal("root", FALSE); 2102 return 0; 2103 2104 case MOD_SHUTDOWN: 2105 device_shutdown(root_bus); 2106 return 0; 2107 } 2108 2109 return 0; 2110 } 2111 2112 static moduledata_t root_bus_mod = { 2113 "rootbus", 2114 root_bus_module_handler, 2115 0 2116 }; 2117 DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 2118 2119 void 2120 root_bus_configure(void) 2121 { 2122 device_t dev; 2123 2124 PDEBUG((".")); 2125 2126 for (dev = TAILQ_FIRST(&root_bus->children); dev; 2127 dev = TAILQ_NEXT(dev, link)) { 2128 device_probe_and_attach(dev); 2129 } 2130 } 2131 2132 int 2133 driver_module_handler(module_t mod, int what, void *arg) 2134 { 2135 int error, i; 2136 struct driver_module_data *dmd; 2137 devclass_t bus_devclass; 2138 2139 dmd = (struct driver_module_data *)arg; 2140 bus_devclass = devclass_find_internal(dmd->dmd_busname, TRUE); 2141 error = 0; 2142 2143 switch (what) { 2144 case MOD_LOAD: 2145 if (dmd->dmd_chainevh) 2146 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg); 2147 2148 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) { 2149 PDEBUG(("Loading module: driver %s on bus %s", 2150 DRIVERNAME(dmd->dmd_drivers[i]), 2151 dmd->dmd_busname)); 2152 error = devclass_add_driver(bus_devclass, 2153 dmd->dmd_drivers[i]); 2154 } 2155 if (error) 2156 break; 2157 2158 /* 2159 * The drivers loaded in this way are assumed to all 2160 * implement the same devclass. 2161 */ 2162 *dmd->dmd_devclass = 2163 devclass_find_internal(dmd->dmd_drivers[0]->name, 2164 TRUE); 2165 break; 2166 2167 case MOD_UNLOAD: 2168 for (i = 0; !error && i < dmd->dmd_ndrivers; i++) { 2169 PDEBUG(("Unloading module: driver %s from bus %s", 2170 DRIVERNAME(dmd->dmd_drivers[i]), 2171 dmd->dmd_busname)); 2172 error = devclass_delete_driver(bus_devclass, 2173 dmd->dmd_drivers[i]); 2174 } 2175 2176 if (!error && dmd->dmd_chainevh) 2177 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg); 2178 break; 2179 } 2180 2181 return (error); 2182 } 2183 2184 #ifdef BUS_DEBUG 2185 2186 /* the _short versions avoid iteration by not calling anything that prints 2187 * more than oneliners. I love oneliners. 2188 */ 2189 2190 static void 2191 print_method_list(device_method_t *m, int indent) 2192 { 2193 int i; 2194 2195 if (!m) 2196 return; 2197 2198 for (i = 0; m->desc; i++, m++) 2199 indentprintf(("method %d: %s, offset=%d\n", 2200 i, m->desc->name, m->desc->offset)); 2201 } 2202 2203 static void 2204 print_device_ops(device_ops_t ops, int indent) 2205 { 2206 int i; 2207 int count = 0; 2208 2209 if (!ops) 2210 return; 2211 2212 /* we present a list of the methods that are pointing to the 2213 * error_method, but ignore the 0'th elements; it is always 2214 * error_method. 2215 */ 2216 for (i = 1; i < ops->maxoffset; i++) { 2217 if (ops->methods[i] == error_method) { 2218 if (count == 0) 2219 indentprintf(("error_method:")); 2220 printf(" %d", i); 2221 count++; 2222 } 2223 } 2224 if (count) 2225 printf("\n"); 2226 2227 indentprintf(("(%d method%s, %d valid, %d error_method%s)\n", 2228 ops->maxoffset-1, (ops->maxoffset-1 == 1? "":"s"), 2229 ops->maxoffset-1-count, 2230 count, (count == 1? "":"'s"))); 2231 } 2232 2233 static void 2234 print_device_short(device_t dev, int indent) 2235 { 2236 if (!dev) 2237 return; 2238 2239 indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s,%sivars,%ssoftc,busy=%d\n", 2240 dev->unit, dev->desc, 2241 (dev->parent? "":"no "), 2242 (TAILQ_EMPTY(&dev->children)? "no ":""), 2243 (dev->flags&DF_ENABLED? "enabled,":"disabled,"), 2244 (dev->flags&DF_FIXEDCLASS? "fixed,":""), 2245 (dev->flags&DF_WILDCARD? "wildcard,":""), 2246 (dev->flags&DF_DESCMALLOCED? "descmalloced,":""), 2247 (dev->ivars? "":"no "), 2248 (dev->softc? "":"no "), 2249 dev->busy)); 2250 } 2251 2252 static void 2253 print_device(device_t dev, int indent) 2254 { 2255 if (!dev) 2256 return; 2257 2258 print_device_short(dev, indent); 2259 2260 indentprintf(("Parent:\n")); 2261 print_device_short(dev->parent, indent+1); 2262 indentprintf(("Methods:\n")); 2263 print_device_ops(dev->ops, indent+1); 2264 indentprintf(("Driver:\n")); 2265 print_driver_short(dev->driver, indent+1); 2266 indentprintf(("Devclass:\n")); 2267 print_devclass_short(dev->devclass, indent+1); 2268 } 2269 2270 void 2271 print_device_tree_short(device_t dev, int indent) 2272 /* print the device and all its children (indented) */ 2273 { 2274 device_t child; 2275 2276 if (!dev) 2277 return; 2278 2279 print_device_short(dev, indent); 2280 2281 for (child = TAILQ_FIRST(&dev->children); child; 2282 child = TAILQ_NEXT(child, link)) 2283 print_device_tree_short(child, indent+1); 2284 } 2285 2286 void 2287 print_device_tree(device_t dev, int indent) 2288 /* print the device and all its children (indented) */ 2289 { 2290 device_t child; 2291 2292 if (!dev) 2293 return; 2294 2295 print_device(dev, indent); 2296 2297 for (child = TAILQ_FIRST(&dev->children); child; 2298 child = TAILQ_NEXT(child, link)) 2299 print_device_tree(child, indent+1); 2300 } 2301 2302 static void 2303 print_driver_short(driver_t *driver, int indent) 2304 { 2305 if (!driver) 2306 return; 2307 2308 indentprintf(("driver %s: softc size = %d\n", 2309 driver->name, driver->softc)); 2310 } 2311 2312 static void 2313 print_driver(driver_t *driver, int indent) 2314 { 2315 if (!driver) 2316 return; 2317 2318 print_driver_short(driver, indent); 2319 indentprintf(("Methods:\n")); 2320 print_method_list(driver->methods, indent+1); 2321 indentprintf(("Operations:\n")); 2322 print_device_ops(driver->ops, indent+1); 2323 } 2324 2325 2326 static void 2327 print_driver_list(driver_list_t drivers, int indent) 2328 { 2329 driverlink_t driver; 2330 2331 for (driver = TAILQ_FIRST(&drivers); driver; 2332 driver = TAILQ_NEXT(driver, link)) 2333 print_driver(driver->driver, indent); 2334 } 2335 2336 static void 2337 print_devclass_short(devclass_t dc, int indent) 2338 { 2339 if ( !dc ) 2340 return; 2341 2342 indentprintf(("devclass %s: max units = %d, next unit = %d\n", 2343 dc->name, dc->maxunit, dc->nextunit)); 2344 } 2345 2346 static void 2347 print_devclass(devclass_t dc, int indent) 2348 { 2349 int i; 2350 2351 if ( !dc ) 2352 return; 2353 2354 print_devclass_short(dc, indent); 2355 indentprintf(("Drivers:\n")); 2356 print_driver_list(dc->drivers, indent+1); 2357 2358 indentprintf(("Devices:\n")); 2359 for (i = 0; i < dc->maxunit; i++) 2360 if (dc->devices[i]) 2361 print_device(dc->devices[i], indent+1); 2362 } 2363 2364 void 2365 print_devclass_list_short(void) 2366 { 2367 devclass_t dc; 2368 2369 printf("Short listing of devclasses, drivers & devices:\n"); 2370 for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link)) 2371 print_devclass_short(dc, 0); 2372 } 2373 2374 void 2375 print_devclass_list(void) 2376 { 2377 devclass_t dc; 2378 2379 printf("Full listing of devclasses, drivers & devices:\n"); 2380 for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link)) 2381 print_devclass(dc, 0); 2382 } 2383 2384 #endif 2385