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