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