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.4 1998/07/22 08:35:52 dfr Exp $ 27 */ 28 29 #include <sys/param.h> 30 #include <sys/queue.h> 31 #include <sys/malloc.h> 32 #include <sys/kernel.h> 33 #include <sys/module.h> 34 #include <sys/bus_private.h> 35 #include <sys/systm.h> 36 37 /* 38 * Method table handling 39 */ 40 41 static int next_method_offset = 1; 42 static int methods_count = 0; 43 static int methods_size = 0; 44 45 struct method { 46 int offset; 47 char* name; 48 }; 49 50 static struct method *methods = 0; 51 52 static void 53 register_method(struct device_op_desc *desc) 54 { 55 int i; 56 struct method* m; 57 58 for (i = 0; i < methods_count; i++) 59 if (!strcmp(methods[i].name, desc->name)) { 60 desc->offset = methods[i].offset; 61 return; 62 } 63 64 if (methods_count == methods_size) { 65 struct method* p; 66 67 methods_size += 10; 68 p = (struct method*) malloc(methods_size * sizeof(struct method), 69 M_DEVBUF, M_NOWAIT); 70 if (!p) 71 panic("register_method: out of memory"); 72 if (methods) { 73 bcopy(methods, p, methods_count * sizeof(struct method)); 74 free(methods, M_DEVBUF); 75 } 76 methods = p; 77 } 78 m = &methods[methods_count++]; 79 m->name = malloc(strlen(desc->name) + 1, M_DEVBUF, M_NOWAIT); 80 if (!m->name) 81 panic("register_method: out of memory"); 82 strcpy(m->name, desc->name); 83 desc->offset = m->offset = next_method_offset++; 84 } 85 86 static int error_method(void) 87 { 88 return ENXIO; 89 } 90 91 static struct device_ops null_ops = { 92 1, 93 { error_method } 94 }; 95 96 static void 97 compile_methods(driver_t *driver) 98 { 99 device_ops_t ops; 100 struct device_method *m; 101 int i; 102 103 /* 104 * First register any methods which need it. 105 */ 106 for (i = 0, m = driver->methods; m->desc; i++, m++) 107 if (!m->desc->offset) 108 register_method(m->desc); 109 110 /* 111 * Then allocate the compiled op table. 112 */ 113 ops = malloc(sizeof(struct device_ops) + (next_method_offset-1) * sizeof(devop_t), 114 M_DEVBUF, M_NOWAIT); 115 if (!ops) 116 panic("compile_methods: out of memory"); 117 ops->maxoffset = next_method_offset; 118 for (i = 0; i < next_method_offset; i++) 119 ops->methods[i] = error_method; 120 for (i = 0, m = driver->methods; m->desc; i++, m++) 121 ops->methods[m->desc->offset] = m->func; 122 driver->ops = ops; 123 } 124 125 /* 126 * Devclass implementation 127 */ 128 129 static devclass_list_t devclasses; 130 131 static void 132 devclass_init(void) 133 { 134 TAILQ_INIT(&devclasses); 135 } 136 137 static devclass_t 138 devclass_find_internal(const char *classname, int create) 139 { 140 devclass_t dc; 141 142 for (dc = TAILQ_FIRST(&devclasses); dc; dc = TAILQ_NEXT(dc, link)) 143 if (!strcmp(dc->name, classname)) 144 return dc; 145 146 if (create) { 147 dc = malloc(sizeof(struct devclass) + strlen(classname) + 1, 148 M_DEVBUF, M_NOWAIT); 149 if (!dc) 150 return NULL; 151 dc->name = (char*) (dc + 1); 152 strcpy(dc->name, classname); 153 dc->devices = NULL; 154 dc->maxunit = 0; 155 dc->nextunit = 0; 156 TAILQ_INIT(&dc->drivers); 157 TAILQ_INSERT_TAIL(&devclasses, dc, link); 158 } 159 160 return dc; 161 } 162 163 devclass_t 164 devclass_find(const char *classname) 165 { 166 return devclass_find_internal(classname, FALSE); 167 } 168 169 int 170 devclass_add_driver(devclass_t dc, driver_t *driver) 171 { 172 /* 173 * Compile the drivers methods. 174 */ 175 compile_methods(driver); 176 177 /* 178 * Make sure the devclass which the driver is implementing exists. 179 */ 180 devclass_find_internal(driver->name, TRUE); 181 182 TAILQ_INSERT_TAIL(&dc->drivers, driver, link); 183 184 return 0; 185 } 186 187 int 188 devclass_delete_driver(devclass_t dc, driver_t *driver) 189 { 190 device_t bus; 191 device_t dev; 192 int i; 193 int error; 194 195 /* 196 * Disassociate from any devices. We iterate through all the 197 * devices attached to any bus in this class. 198 */ 199 for (i = 0; i < dc->maxunit; i++) { 200 if (dc->devices[i]) { 201 bus = dc->devices[i]->parent; 202 for (dev = TAILQ_FIRST(&bus->children); dev; 203 dev = TAILQ_NEXT(dev, link)) 204 if (dev->driver == driver) { 205 if (error = DEVICE_DETACH(dev)) 206 return error; 207 device_set_driver(dev, NULL); 208 } 209 } 210 } 211 212 TAILQ_REMOVE(&dc->drivers, driver, link); 213 return 0; 214 } 215 216 driver_t * 217 devclass_find_driver(devclass_t dc, const char *classname) 218 { 219 driver_t *driver; 220 221 for (driver = TAILQ_FIRST(&dc->drivers); driver; 222 driver = TAILQ_NEXT(driver, link)) 223 if (!strcmp(driver->name, classname)) 224 return driver; 225 226 return NULL; 227 } 228 229 const char * 230 devclass_get_name(devclass_t dc) 231 { 232 return dc->name; 233 } 234 235 device_t 236 devclass_get_device(devclass_t dc, int unit) 237 { 238 if (unit < 0 || unit >= dc->maxunit) 239 return NULL; 240 return dc->devices[unit]; 241 } 242 243 void * 244 devclass_get_softc(devclass_t dc, int unit) 245 { 246 device_t dev; 247 248 if (unit < 0 || unit >= dc->maxunit) 249 return NULL; 250 dev = dc->devices[unit]; 251 if (!dev || dev->state < DS_ATTACHED) 252 return NULL; 253 return dev->softc; 254 } 255 256 int 257 devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp) 258 { 259 int i; 260 int count; 261 device_t dev; 262 device_t *list; 263 264 count = 0; 265 for (i = 0; i < dc->maxunit; i++) 266 if (dc->devices[i]) 267 count++; 268 269 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT); 270 if (!list) 271 return ENOMEM; 272 273 count = 0; 274 for (i = 0; i < dc->maxunit; i++) 275 if (dc->devices[i]) { 276 list[count] = dc->devices[i]; 277 count++; 278 } 279 280 *devlistp = list; 281 *devcountp = count; 282 283 return 0; 284 } 285 286 int 287 devclass_get_maxunit(devclass_t dc) 288 { 289 return dc->maxunit; 290 } 291 292 static int 293 devclass_alloc_unit(devclass_t dc, int *unitp) 294 { 295 int unit = *unitp; 296 297 /* 298 * If we have been given a wired unit number, check for existing 299 * device. 300 */ 301 if (unit != -1) { 302 device_t dev; 303 dev = devclass_get_device(dc, unit); 304 if (dev) { 305 printf("devclass_alloc_unit: %s%d already exists, using next available unit number\n", dc->name, unit); 306 unit = -1; 307 } 308 } 309 310 if (unit == -1) { 311 unit = dc->nextunit; 312 dc->nextunit++; 313 } else if (dc->nextunit <= unit) 314 dc->nextunit = unit + 1; 315 316 if (unit >= dc->maxunit) { 317 device_t *newlist; 318 int newsize; 319 320 newsize = (dc->maxunit ? 2 * dc->maxunit 321 : MINALLOCSIZE / sizeof(device_t)); 322 newlist = malloc(sizeof(device_t) * newsize, M_DEVBUF, M_NOWAIT); 323 if (!newlist) 324 return ENOMEM; 325 bcopy(dc->devices, newlist, sizeof(device_t) * dc->maxunit); 326 bzero(newlist + dc->maxunit, 327 sizeof(device_t) * (newsize - dc->maxunit)); 328 if (dc->devices) 329 free(dc->devices, M_DEVBUF); 330 dc->devices = newlist; 331 dc->maxunit = newsize; 332 } 333 334 *unitp = unit; 335 return 0; 336 } 337 338 static int 339 devclass_add_device(devclass_t dc, device_t dev) 340 { 341 int error; 342 343 if (error = devclass_alloc_unit(dc, &dev->unit)) 344 return error; 345 dc->devices[dev->unit] = dev; 346 dev->devclass = dc; 347 return 0; 348 } 349 350 static int 351 devclass_delete_device(devclass_t dc, device_t dev) 352 { 353 if (dev->devclass != dc 354 || dc->devices[dev->unit] != dev) 355 panic("devclass_delete_device: inconsistent device class"); 356 dc->devices[dev->unit] = NULL; 357 if (dev->flags & DF_WILDCARD) 358 dev->unit = -1; 359 dev->devclass = NULL; 360 while (dc->nextunit > 0 && dc->devices[dc->nextunit - 1] == NULL) 361 dc->nextunit--; 362 return 0; 363 } 364 365 static device_t 366 make_device(device_t parent, const char *name, 367 int unit, void *ivars) 368 { 369 driver_t *driver; 370 device_t dev; 371 devclass_t dc; 372 int error; 373 374 if (name) { 375 dc = devclass_find_internal(name, TRUE); 376 if (!dc) { 377 printf("make_device: can't find device class %s\n", name); 378 return NULL; 379 } 380 381 if (error = devclass_alloc_unit(dc, &unit)) 382 return NULL; 383 } else 384 dc = NULL; 385 386 dev = malloc(sizeof(struct device), M_DEVBUF, M_NOWAIT); 387 if (!dev) 388 return 0; 389 390 dev->parent = parent; 391 TAILQ_INIT(&dev->children); 392 dev->ops = &null_ops; 393 dev->driver = NULL; 394 dev->devclass = dc; 395 dev->unit = unit; 396 dev->desc = NULL; 397 dev->busy = 0; 398 dev->flags = DF_ENABLED; 399 if (unit == -1) 400 dev->flags |= DF_WILDCARD; 401 if (name) 402 dev->flags |= DF_FIXEDCLASS; 403 dev->ivars = ivars; 404 dev->softc = NULL; 405 406 if (dc) 407 dc->devices[unit] = dev; 408 409 dev->state = DS_NOTPRESENT; 410 411 return dev; 412 } 413 414 static void 415 device_print_child(device_t dev, device_t child) 416 { 417 printf("%s%d", device_get_name(child), device_get_unit(child)); 418 if (device_is_alive(child)) { 419 if (device_get_desc(child)) 420 printf(": <%s>", device_get_desc(child)); 421 BUS_PRINT_CHILD(dev, child); 422 } else 423 printf(" not found"); 424 printf("\n"); 425 } 426 427 device_t 428 device_add_child(device_t dev, const char *name, int unit, void *ivars) 429 { 430 device_t child; 431 432 child = make_device(dev, name, unit, ivars); 433 434 TAILQ_INSERT_TAIL(&dev->children, child, link); 435 436 return child; 437 } 438 439 device_t 440 device_add_child_after(device_t dev, device_t place, const char *name, 441 int unit, void *ivars) 442 { 443 device_t child; 444 445 child = make_device(dev, name, unit, ivars); 446 447 if (place) { 448 TAILQ_INSERT_AFTER(&dev->children, place, dev, link); 449 } else { 450 TAILQ_INSERT_HEAD(&dev->children, dev, link); 451 } 452 453 return child; 454 } 455 456 int 457 device_delete_child(device_t dev, device_t child) 458 { 459 int error; 460 461 if (error = DEVICE_DETACH(child)) 462 return error; 463 if (child->devclass) 464 devclass_delete_device(child->devclass, child); 465 TAILQ_REMOVE(&dev->children, child, link); 466 free(dev, M_DEVBUF); 467 468 return 0; 469 } 470 471 /* 472 * Find only devices attached to this bus. 473 */ 474 device_t 475 device_find_child(device_t dev, const char *classname, int unit) 476 { 477 devclass_t dc; 478 device_t child; 479 480 dc = devclass_find(classname); 481 if (!dc) 482 return NULL; 483 484 child = devclass_get_device(dc, unit); 485 if (child && child->parent == dev) 486 return child; 487 return NULL; 488 } 489 490 static driver_t * 491 first_matching_driver(devclass_t dc, device_t dev) 492 { 493 if (dev->devclass) 494 return devclass_find_driver(dc, dev->devclass->name); 495 else 496 return TAILQ_FIRST(&dc->drivers); 497 } 498 499 static driver_t * 500 next_matching_driver(devclass_t dc, device_t dev, driver_t *last) 501 { 502 if (dev->devclass) { 503 driver_t *driver; 504 for (driver = TAILQ_NEXT(last, link); driver; 505 driver = TAILQ_NEXT(driver, link)) 506 if (!strcmp(dev->devclass->name, driver->name)) 507 return driver; 508 return NULL; 509 } else 510 return TAILQ_NEXT(last, link); 511 } 512 513 static int 514 device_probe_child(device_t dev, device_t child) 515 { 516 devclass_t dc; 517 driver_t *driver; 518 void *softc; 519 520 dc = dev->devclass; 521 if (dc == NULL) 522 panic("device_probe_child: parent device has no devclass"); 523 524 if (child->state == DS_ALIVE) 525 return 0; 526 527 for (driver = first_matching_driver(dc, child); 528 driver; 529 driver = next_matching_driver(dc, child, driver)) { 530 device_set_driver(child, driver); 531 if (DEVICE_PROBE(child) == 0) { 532 if (!child->devclass) 533 device_set_devclass(child, driver->name); 534 child->state = DS_ALIVE; 535 return 0; 536 } 537 } 538 539 return ENXIO; 540 } 541 542 device_t 543 device_get_parent(device_t dev) 544 { 545 return dev->parent; 546 } 547 548 driver_t * 549 device_get_driver(device_t dev) 550 { 551 return dev->driver; 552 } 553 554 devclass_t 555 device_get_devclass(device_t dev) 556 { 557 return dev->devclass; 558 } 559 560 const char * 561 device_get_name(device_t dev) 562 { 563 if (dev->devclass) 564 return devclass_get_name(dev->devclass); 565 return NULL; 566 } 567 568 int 569 device_get_unit(device_t dev) 570 { 571 return dev->unit; 572 } 573 574 const char * 575 device_get_desc(device_t dev) 576 { 577 return dev->desc; 578 } 579 580 void 581 device_set_desc(device_t dev, const char* desc) 582 { 583 dev->desc = desc; 584 } 585 586 void * 587 device_get_softc(device_t dev) 588 { 589 return dev->softc; 590 } 591 592 void * 593 device_get_ivars(device_t dev) 594 { 595 return dev->ivars; 596 } 597 598 device_state_t 599 device_get_state(device_t dev) 600 { 601 return dev->state; 602 } 603 604 void 605 device_enable(device_t dev) 606 { 607 dev->flags |= DF_ENABLED; 608 } 609 610 void 611 device_disable(device_t dev) 612 { 613 dev->flags &= ~DF_ENABLED; 614 } 615 616 void 617 device_busy(device_t dev) 618 { 619 if (dev->state < DS_ATTACHED) 620 panic("device_busy: called for unattached device"); 621 if (dev->busy == 0 && dev->parent) 622 device_busy(dev->parent); 623 dev->busy++; 624 dev->state = DS_BUSY; 625 } 626 627 void 628 device_unbusy(device_t dev) 629 { 630 if (dev->state != DS_BUSY) 631 panic("device_unbusy: called for non-busy device"); 632 dev->busy--; 633 if (dev->busy == 0) { 634 if (dev->parent) 635 device_unbusy(dev->parent); 636 dev->state = DS_ATTACHED; 637 } 638 } 639 640 int 641 device_is_enabled(device_t dev) 642 { 643 return (dev->flags & DF_ENABLED) != 0; 644 } 645 646 int 647 device_is_alive(device_t dev) 648 { 649 return dev->state >= DS_ALIVE; 650 } 651 652 int 653 device_set_devclass(device_t dev, const char *classname) 654 { 655 devclass_t dc; 656 657 if (dev->devclass) { 658 printf("device_set_devclass: device class already set\n"); 659 return EINVAL; 660 } 661 662 dc = devclass_find_internal(classname, TRUE); 663 if (!dc) 664 return ENOMEM; 665 666 return devclass_add_device(dc, dev); 667 } 668 669 int 670 device_set_driver(device_t dev, driver_t *driver) 671 { 672 if (dev->state >= DS_ATTACHED) 673 return EBUSY; 674 675 if (dev->driver == driver) 676 return 0; 677 678 if (dev->softc) { 679 free(dev->softc, M_DEVBUF); 680 dev->softc = NULL; 681 } 682 dev->ops = &null_ops; 683 dev->driver = driver; 684 if (driver) { 685 dev->ops = driver->ops; 686 dev->softc = malloc(driver->softc, M_DEVBUF, M_NOWAIT); 687 bzero(dev->softc, driver->softc); 688 } 689 return 0; 690 } 691 692 int 693 device_probe_and_attach(device_t dev) 694 { 695 device_t bus = dev->parent; 696 int error; 697 698 if (dev->state >= DS_ALIVE) 699 return 0; 700 701 if (dev->flags & DF_ENABLED) { 702 device_probe_child(bus, dev); 703 device_print_child(bus, dev); 704 if (dev->state == DS_ALIVE) { 705 error = DEVICE_ATTACH(dev); 706 if (!error) 707 dev->state = DS_ATTACHED; 708 else { 709 printf("device_probe_and_attach: %s%d attach returned %d\n", 710 dev->driver->name, dev->unit, error); 711 device_set_driver(dev, NULL); 712 dev->state = DS_NOTPRESENT; 713 } 714 } 715 } else 716 printf("%s%d: disabled, not probed.\n", 717 dev->devclass->name, dev->unit); 718 719 return 0; 720 } 721 722 int 723 device_detach(device_t dev) 724 { 725 int error; 726 727 if (dev->state == DS_BUSY) 728 return EBUSY; 729 if (dev->state != DS_ATTACHED) 730 return 0; 731 732 if (error = DEVICE_DETACH(dev)) 733 return error; 734 735 if (!(dev->flags & DF_FIXEDCLASS)) 736 devclass_delete_device(dev->devclass, dev); 737 738 dev->state = DS_NOTPRESENT; 739 device_set_driver(dev, NULL); 740 741 return 0; 742 } 743 744 int 745 device_shutdown(device_t dev) 746 { 747 if (dev->state < DS_ATTACHED) 748 return 0; 749 return DEVICE_SHUTDOWN(dev); 750 } 751 752 /* 753 * Access functions for device resources. 754 */ 755 extern struct config_device devtab[]; 756 extern int devtab_count; 757 758 static int 759 resource_match_string(int i, char *resname, char *value) 760 { 761 int j; 762 struct resource *res; 763 764 for (j = 0, res = devtab[i].resources; 765 j < devtab[i].resource_count; j++, res++) 766 if (!strcmp(res->name, resname) 767 && res->type == RES_STRING 768 && !strcmp(res->u.stringval, value)) 769 return TRUE; 770 return FALSE; 771 } 772 773 static int 774 resource_find(const char *name, int unit, char *resname, struct resource **result) 775 { 776 int i, j; 777 struct resource *res; 778 779 /* 780 * First check specific instances, then generic. 781 */ 782 for (i = 0; i < devtab_count; i++) { 783 if (devtab[i].unit < 0) 784 continue; 785 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) { 786 res = devtab[i].resources; 787 for (j = 0; j < devtab[i].resource_count; j++, res++) 788 if (!strcmp(res->name, resname)) { 789 *result = res; 790 return 0; 791 } 792 } 793 } 794 for (i = 0; i < devtab_count; i++) { 795 if (devtab[i].unit >= 0) 796 continue; 797 if (!strcmp(devtab[i].name, name) && devtab[i].unit == unit) { 798 res = devtab[i].resources; 799 for (j = 0; j < devtab[i].resource_count; j++, res++) 800 if (!strcmp(res->name, resname)) { 801 *result = res; 802 return 0; 803 } 804 } 805 } 806 return ENOENT; 807 } 808 809 int 810 resource_int_value(const char *name, int unit, char *resname, int *result) 811 { 812 int error; 813 struct resource *res; 814 if ((error = resource_find(name, unit, resname, &res)) != 0) 815 return error; 816 if (res->type != RES_INT) 817 return EFTYPE; 818 *result = res->u.intval; 819 return 0; 820 } 821 822 int 823 resource_long_value(const char *name, int unit, char *resname, long *result) 824 { 825 int error; 826 struct resource *res; 827 if ((error = resource_find(name, unit, resname, &res)) != 0) 828 return error; 829 if (res->type != RES_LONG) 830 return EFTYPE; 831 *result = res->u.longval; 832 return 0; 833 } 834 835 int 836 resource_string_value(const char *name, int unit, char *resname, char **result) 837 { 838 int error; 839 struct resource *res; 840 if ((error = resource_find(name, unit, resname, &res)) != 0) 841 return error; 842 if (res->type != RES_STRING) 843 return EFTYPE; 844 *result = res->u.stringval; 845 return 0; 846 } 847 848 int 849 resource_query_string(int i, char *resname, char *value) 850 { 851 if (i < 0) 852 i = 0; 853 else 854 i = i + 1; 855 for (; i < devtab_count; i++) 856 if (resource_match_string(i, resname, value)) 857 return i; 858 return -1; 859 } 860 861 char * 862 resource_query_name(int i) 863 { 864 return devtab[i].name; 865 } 866 867 int 868 resource_query_unit(int i) 869 { 870 return devtab[i].unit; 871 } 872 873 874 /* 875 * Some useful method implementations to make life easier for bus drivers. 876 */ 877 int 878 bus_generic_attach(device_t dev) 879 { 880 device_t child; 881 int error; 882 883 for (child = TAILQ_FIRST(&dev->children); 884 child; child = TAILQ_NEXT(child, link)) 885 device_probe_and_attach(child); 886 887 return 0; 888 } 889 890 int 891 bus_generic_detach(device_t dev) 892 { 893 device_t child; 894 int error; 895 896 if (dev->state != DS_ATTACHED) 897 return EBUSY; 898 899 for (child = TAILQ_FIRST(&dev->children); 900 child; child = TAILQ_NEXT(child, link)) 901 DEVICE_DETACH(child); 902 903 return 0; 904 } 905 906 int 907 bus_generic_shutdown(device_t dev) 908 { 909 device_t child; 910 911 for (child = TAILQ_FIRST(&dev->children); 912 child; child = TAILQ_NEXT(child, link)) 913 DEVICE_SHUTDOWN(child); 914 915 return 0; 916 } 917 918 void 919 bus_generic_print_child(device_t dev, device_t child) 920 { 921 } 922 923 int 924 bus_generic_read_ivar(device_t dev, device_t child, int index, u_long* result) 925 { 926 return ENOENT; 927 } 928 929 int 930 bus_generic_write_ivar(device_t dev, device_t child, int index, u_long value) 931 { 932 return ENOENT; 933 } 934 935 void * 936 bus_generic_create_intr(device_t dev, device_t child, int irq, driver_intr_t *intr, void *arg) 937 { 938 /* Propagate up the bus hierarchy until someone handles it. */ 939 if (dev->parent) 940 return BUS_CREATE_INTR(dev->parent, dev, irq, intr, arg); 941 else 942 return NULL; 943 } 944 945 int 946 bus_generic_connect_intr(device_t dev, void *ih) 947 { 948 /* Propagate up the bus hierarchy until someone handles it. */ 949 if (dev->parent) 950 return BUS_CONNECT_INTR(dev->parent, ih); 951 else 952 return EINVAL; 953 } 954 955 static int root_create_intr(device_t dev, device_t child, 956 driver_intr_t *intr, void *arg) 957 { 958 /* 959 * If an interrupt mapping gets to here something bad has happened. 960 * Should probably panic. 961 */ 962 return EINVAL; 963 } 964 965 static device_method_t root_methods[] = { 966 /* Bus interface */ 967 DEVMETHOD(bus_print_child, bus_generic_print_child), 968 DEVMETHOD(bus_read_ivar, bus_generic_read_ivar), 969 DEVMETHOD(bus_write_ivar, bus_generic_write_ivar), 970 DEVMETHOD(bus_create_intr, root_create_intr), 971 972 { 0, 0 } 973 }; 974 975 static driver_t root_driver = { 976 "root", 977 root_methods, 978 DRIVER_TYPE_MISC, 979 1, /* no softc */ 980 }; 981 982 device_t root_bus; 983 devclass_t root_devclass; 984 985 static int 986 root_bus_module_handler(module_t mod, modeventtype_t what, void* arg) 987 { 988 switch (what) { 989 case MOD_LOAD: 990 devclass_init(); 991 compile_methods(&root_driver); 992 root_bus = make_device(NULL, "root", 0, NULL); 993 root_bus->ops = root_driver.ops; 994 root_bus->driver = &root_driver; 995 root_bus->state = DS_ATTACHED; 996 root_devclass = devclass_find("root"); 997 return 0; 998 } 999 1000 return 0; 1001 } 1002 1003 static moduledata_t root_bus_mod = { 1004 "rootbus", 1005 root_bus_module_handler, 1006 0 1007 }; 1008 DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 1009 1010 void 1011 root_bus_configure() 1012 { 1013 device_t dev; 1014 int error; 1015 1016 for (dev = TAILQ_FIRST(&root_bus->children); dev; 1017 dev = TAILQ_NEXT(dev, link)) { 1018 device_probe_and_attach(dev); 1019 } 1020 } 1021 1022 int 1023 driver_module_handler(module_t mod, modeventtype_t what, void* arg) 1024 { 1025 struct driver_module_data* data = (struct driver_module_data*) arg; 1026 devclass_t bus_devclass = devclass_find_internal(data->busname, TRUE); 1027 int error; 1028 1029 switch (what) { 1030 case MOD_LOAD: 1031 if (error = devclass_add_driver(bus_devclass, 1032 data->driver)) 1033 return error; 1034 *data->devclass = 1035 devclass_find_internal(data->driver->name, TRUE); 1036 break; 1037 1038 case MOD_UNLOAD: 1039 if (error = devclass_delete_driver(bus_devclass, 1040 data->driver)) 1041 return error; 1042 break; 1043 } 1044 1045 if (data->chainevh) 1046 return data->chainevh(mod, what, data->chainarg); 1047 else 1048 return 0; 1049 } 1050