subr_bus.c revision 130063
1/*- 2 * Copyright (c) 1997,1998,2003 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 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: head/sys/kern/subr_bus.c 130063 2004-06-04 10:23:00Z des $"); 29 30#include "opt_bus.h" 31 32#include <sys/param.h> 33#include <sys/conf.h> 34#include <sys/filio.h> 35#include <sys/lock.h> 36#include <sys/kernel.h> 37#include <sys/kobj.h> 38#include <sys/malloc.h> 39#include <sys/module.h> 40#include <sys/mutex.h> 41#include <sys/poll.h> 42#include <sys/proc.h> 43#include <sys/condvar.h> 44#include <sys/queue.h> 45#include <machine/bus.h> 46#include <sys/rman.h> 47#include <sys/selinfo.h> 48#include <sys/signalvar.h> 49#include <sys/sysctl.h> 50#include <sys/systm.h> 51#include <sys/uio.h> 52#include <sys/bus.h> 53 54#include <machine/stdarg.h> 55 56#include <vm/uma.h> 57 58SYSCTL_NODE(_hw, OID_AUTO, bus, CTLFLAG_RW, NULL, NULL); 59SYSCTL_NODE(, OID_AUTO, dev, CTLFLAG_RW, NULL, NULL); 60 61/* 62 * Used to attach drivers to devclasses. 63 */ 64typedef struct driverlink *driverlink_t; 65struct driverlink { 66 kobj_class_t driver; 67 TAILQ_ENTRY(driverlink) link; /* list of drivers in devclass */ 68}; 69 70/* 71 * Forward declarations 72 */ 73typedef TAILQ_HEAD(devclass_list, devclass) devclass_list_t; 74typedef TAILQ_HEAD(driver_list, driverlink) driver_list_t; 75typedef TAILQ_HEAD(device_list, device) device_list_t; 76 77struct devclass { 78 TAILQ_ENTRY(devclass) link; 79 devclass_t parent; /* parent in devclass hierarchy */ 80 driver_list_t drivers; /* bus devclasses store drivers for bus */ 81 char *name; 82 device_t *devices; /* array of devices indexed by unit */ 83 int maxunit; /* size of devices array */ 84 85 struct sysctl_ctx_list sysctl_ctx; 86 struct sysctl_oid *sysctl_tree; 87}; 88 89/* 90 * Implementation of device. 91 */ 92struct device { 93 /* 94 * A device is a kernel object. The first field must be the 95 * current ops table for the object. 96 */ 97 KOBJ_FIELDS; 98 99 /* 100 * Device hierarchy. 101 */ 102 TAILQ_ENTRY(device) link; /* list of devices in parent */ 103 TAILQ_ENTRY(device) devlink; /* global device list membership */ 104 device_t parent; 105 device_list_t children; /* list of subordinate devices */ 106 107 /* 108 * Details of this device. 109 */ 110 driver_t *driver; 111 devclass_t devclass; /* device class which we are in */ 112 int unit; 113 char* nameunit; /* name+unit e.g. foodev0 */ 114 char* desc; /* driver specific description */ 115 int busy; /* count of calls to device_busy() */ 116 device_state_t state; 117 u_int32_t devflags; /* api level flags for device_get_flags() */ 118 u_short flags; 119#define DF_ENABLED 1 /* device should be probed/attached */ 120#define DF_FIXEDCLASS 2 /* devclass specified at create time */ 121#define DF_WILDCARD 4 /* unit was originally wildcard */ 122#define DF_DESCMALLOCED 8 /* description was malloced */ 123#define DF_QUIET 16 /* don't print verbose attach message */ 124#define DF_DONENOMATCH 32 /* don't execute DEVICE_NOMATCH again */ 125#define DF_EXTERNALSOFTC 64 /* softc not allocated by us */ 126 u_char order; /* order from device_add_child_ordered() */ 127 u_char pad; 128 void *ivars; 129 void *softc; 130 131 struct sysctl_ctx_list sysctl_ctx; 132 struct sysctl_oid *sysctl_tree; 133}; 134 135struct device_op_desc { 136 unsigned int offset; /* offset in driver ops */ 137 struct method* method; /* internal method implementation */ 138 devop_t deflt; /* default implementation */ 139 const char* name; /* unique name (for registration) */ 140}; 141 142static MALLOC_DEFINE(M_BUS, "bus", "Bus data structures"); 143static MALLOC_DEFINE(M_BUS_SC, "bus-sc", "Bus data structures, softc"); 144 145#ifdef BUS_DEBUG 146 147static int bus_debug = 1; 148TUNABLE_INT("bus.debug", &bus_debug); 149SYSCTL_INT(_debug, OID_AUTO, bus_debug, CTLFLAG_RW, &bus_debug, 0, 150 "Debug bus code"); 151 152#define PDEBUG(a) if (bus_debug) {printf("%s:%d: ", __func__, __LINE__), printf a; printf("\n");} 153#define DEVICENAME(d) ((d)? device_get_name(d): "no device") 154#define DRIVERNAME(d) ((d)? d->name : "no driver") 155#define DEVCLANAME(d) ((d)? d->name : "no devclass") 156 157/* Produce the indenting, indent*2 spaces plus a '.' ahead of that to 158 * prevent syslog from deleting initial spaces 159 */ 160#define indentprintf(p) do { int iJ; printf("."); for (iJ=0; iJ<indent; iJ++) printf(" "); printf p ; } while (0) 161 162static void print_device_short(device_t dev, int indent); 163static void print_device(device_t dev, int indent); 164void print_device_tree_short(device_t dev, int indent); 165void print_device_tree(device_t dev, int indent); 166static void print_driver_short(driver_t *driver, int indent); 167static void print_driver(driver_t *driver, int indent); 168static void print_driver_list(driver_list_t drivers, int indent); 169static void print_devclass_short(devclass_t dc, int indent); 170static void print_devclass(devclass_t dc, int indent); 171void print_devclass_list_short(void); 172void print_devclass_list(void); 173 174#else 175/* Make the compiler ignore the function calls */ 176#define PDEBUG(a) /* nop */ 177#define DEVICENAME(d) /* nop */ 178#define DRIVERNAME(d) /* nop */ 179#define DEVCLANAME(d) /* nop */ 180 181#define print_device_short(d,i) /* nop */ 182#define print_device(d,i) /* nop */ 183#define print_device_tree_short(d,i) /* nop */ 184#define print_device_tree(d,i) /* nop */ 185#define print_driver_short(d,i) /* nop */ 186#define print_driver(d,i) /* nop */ 187#define print_driver_list(d,i) /* nop */ 188#define print_devclass_short(d,i) /* nop */ 189#define print_devclass(d,i) /* nop */ 190#define print_devclass_list_short() /* nop */ 191#define print_devclass_list() /* nop */ 192#endif 193 194/* 195 * dev sysctl tree 196 */ 197 198enum { 199 DEVCLASS_SYSCTL_PARENT, 200}; 201 202static int 203devclass_sysctl_handler(SYSCTL_HANDLER_ARGS) 204{ 205 devclass_t dc = (devclass_t)arg1; 206 const char *value; 207 char *buf; 208 int error; 209 210 buf = NULL; 211 switch (arg2) { 212 case DEVCLASS_SYSCTL_PARENT: 213 value = dc->parent ? dc->parent->name : NULL; 214 break; 215 default: 216 return (EINVAL); 217 } 218 if (value == NULL) 219 value = "?"; 220 error = SYSCTL_OUT(req, value, strlen(value)); 221 if (buf != NULL) 222 free(buf, M_BUS); 223 return (error); 224} 225 226static void 227devclass_sysctl_init(devclass_t dc) 228{ 229 230 if (dc->sysctl_tree != NULL) 231 return; 232 sysctl_ctx_init(&dc->sysctl_ctx); 233 dc->sysctl_tree = SYSCTL_ADD_NODE(&dc->sysctl_ctx, 234 SYSCTL_STATIC_CHILDREN(_dev), OID_AUTO, dc->name, 235 CTLFLAG_RD, 0, ""); 236 SYSCTL_ADD_PROC(&dc->sysctl_ctx, SYSCTL_CHILDREN(dc->sysctl_tree), 237 OID_AUTO, "%parent", CTLFLAG_RD, 238 dc, DEVCLASS_SYSCTL_PARENT, devclass_sysctl_handler, "A", 239 "parent class"); 240} 241 242enum { 243 DEVICE_SYSCTL_DESC, 244 DEVICE_SYSCTL_DRIVER, 245 DEVICE_SYSCTL_LOCATION, 246 DEVICE_SYSCTL_PNPINFO, 247 DEVICE_SYSCTL_PARENT, 248}; 249 250static int 251device_sysctl_handler(SYSCTL_HANDLER_ARGS) 252{ 253 device_t dev = (device_t)arg1; 254 const char *value; 255 char *buf; 256 int error; 257 258 buf = NULL; 259 switch (arg2) { 260 case DEVICE_SYSCTL_DESC: 261 value = dev->desc; 262 break; 263 case DEVICE_SYSCTL_DRIVER: 264 value = dev->driver ? dev->driver->name : NULL; 265 break; 266 case DEVICE_SYSCTL_LOCATION: 267 value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO); 268 bus_child_location_str(dev, buf, 1024); 269 break; 270 case DEVICE_SYSCTL_PNPINFO: 271 value = buf = malloc(1024, M_BUS, M_WAITOK | M_ZERO); 272 bus_child_pnpinfo_str(dev, buf, 1024); 273 break; 274 case DEVICE_SYSCTL_PARENT: 275 value = dev->parent ? dev->parent->nameunit : NULL; 276 break; 277 default: 278 return (EINVAL); 279 } 280 if (value == NULL) 281 value = "?"; 282 error = SYSCTL_OUT(req, value, strlen(value)); 283 if (buf != NULL) 284 free(buf, M_BUS); 285 return (error); 286} 287 288static void 289device_sysctl_init(device_t dev) 290{ 291 devclass_t dc = dev->devclass; 292 293 if (dev->sysctl_tree != NULL) 294 return; 295 devclass_sysctl_init(dc); 296 sysctl_ctx_init(&dev->sysctl_ctx); 297 dev->sysctl_tree = SYSCTL_ADD_NODE(&dev->sysctl_ctx, 298 SYSCTL_CHILDREN(dc->sysctl_tree), OID_AUTO, 299 dev->nameunit + strlen(dc->name), 300 CTLFLAG_RD, 0, ""); 301 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree), 302 OID_AUTO, "%desc", CTLFLAG_RD, 303 dev, DEVICE_SYSCTL_DESC, device_sysctl_handler, "A", 304 "device description"); 305 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree), 306 OID_AUTO, "%driver", CTLFLAG_RD, 307 dev, DEVICE_SYSCTL_DRIVER, device_sysctl_handler, "A", 308 "device driver name"); 309 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree), 310 OID_AUTO, "%location", CTLFLAG_RD, 311 dev, DEVICE_SYSCTL_LOCATION, device_sysctl_handler, "A", 312 "device location relative to parent"); 313 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree), 314 OID_AUTO, "%pnpinfo", CTLFLAG_RD, 315 dev, DEVICE_SYSCTL_PNPINFO, device_sysctl_handler, "A", 316 "device identification"); 317 SYSCTL_ADD_PROC(&dev->sysctl_ctx, SYSCTL_CHILDREN(dev->sysctl_tree), 318 OID_AUTO, "%parent", CTLFLAG_RD, 319 dev, DEVICE_SYSCTL_PARENT, device_sysctl_handler, "A", 320 "parent device"); 321} 322 323static void 324device_sysctl_fini(device_t dev) 325{ 326 if (dev->sysctl_tree == NULL) 327 return; 328 sysctl_ctx_free(&dev->sysctl_ctx); 329 dev->sysctl_tree = NULL; 330} 331 332/* 333 * /dev/devctl implementation 334 */ 335 336/* 337 * This design allows only one reader for /dev/devctl. This is not desirable 338 * in the long run, but will get a lot of hair out of this implementation. 339 * Maybe we should make this device a clonable device. 340 * 341 * Also note: we specifically do not attach a device to the device_t tree 342 * to avoid potential chicken and egg problems. One could argue that all 343 * of this belongs to the root node. One could also further argue that the 344 * sysctl interface that we have not might more properly be an ioctl 345 * interface, but at this stage of the game, I'm not inclined to rock that 346 * boat. 347 * 348 * I'm also not sure that the SIGIO support is done correctly or not, as 349 * I copied it from a driver that had SIGIO support that likely hasn't been 350 * tested since 3.4 or 2.2.8! 351 */ 352 353static int sysctl_devctl_disable(SYSCTL_HANDLER_ARGS); 354static int devctl_disable = 0; 355TUNABLE_INT("hw.bus.devctl_disable", &devctl_disable); 356SYSCTL_PROC(_hw_bus, OID_AUTO, devctl_disable, CTLTYPE_INT | CTLFLAG_RW, 0, 0, 357 sysctl_devctl_disable, "I", "devctl disable"); 358 359static d_open_t devopen; 360static d_close_t devclose; 361static d_read_t devread; 362static d_ioctl_t devioctl; 363static d_poll_t devpoll; 364 365#define CDEV_MAJOR 173 366static struct cdevsw dev_cdevsw = { 367 .d_version = D_VERSION, 368 .d_flags = D_NEEDGIANT, 369 .d_open = devopen, 370 .d_close = devclose, 371 .d_read = devread, 372 .d_ioctl = devioctl, 373 .d_poll = devpoll, 374 .d_name = "devctl", 375 .d_maj = CDEV_MAJOR, 376}; 377 378struct dev_event_info 379{ 380 char *dei_data; 381 TAILQ_ENTRY(dev_event_info) dei_link; 382}; 383 384TAILQ_HEAD(devq, dev_event_info); 385 386static struct dev_softc 387{ 388 int inuse; 389 int nonblock; 390 struct mtx mtx; 391 struct cv cv; 392 struct selinfo sel; 393 struct devq devq; 394 struct proc *async_proc; 395} devsoftc; 396 397static dev_t devctl_dev; 398 399static void 400devinit(void) 401{ 402 devctl_dev = make_dev(&dev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0600, 403 "devctl"); 404 mtx_init(&devsoftc.mtx, "dev mtx", "devd", MTX_DEF); 405 cv_init(&devsoftc.cv, "dev cv"); 406 TAILQ_INIT(&devsoftc.devq); 407} 408 409static int 410devopen(dev_t dev, int oflags, int devtype, d_thread_t *td) 411{ 412 if (devsoftc.inuse) 413 return (EBUSY); 414 /* move to init */ 415 devsoftc.inuse = 1; 416 devsoftc.nonblock = 0; 417 devsoftc.async_proc = NULL; 418 return (0); 419} 420 421static int 422devclose(dev_t dev, int fflag, int devtype, d_thread_t *td) 423{ 424 devsoftc.inuse = 0; 425 mtx_lock(&devsoftc.mtx); 426 cv_broadcast(&devsoftc.cv); 427 mtx_unlock(&devsoftc.mtx); 428 429 return (0); 430} 431 432/* 433 * The read channel for this device is used to report changes to 434 * userland in realtime. We are required to free the data as well as 435 * the n1 object because we allocate them separately. Also note that 436 * we return one record at a time. If you try to read this device a 437 * character at a time, you will loose the rest of the data. Listening 438 * programs are expected to cope. 439 */ 440static int 441devread(dev_t dev, struct uio *uio, int ioflag) 442{ 443 struct dev_event_info *n1; 444 int rv; 445 446 mtx_lock(&devsoftc.mtx); 447 while (TAILQ_EMPTY(&devsoftc.devq)) { 448 if (devsoftc.nonblock) { 449 mtx_unlock(&devsoftc.mtx); 450 return (EAGAIN); 451 } 452 rv = cv_wait_sig(&devsoftc.cv, &devsoftc.mtx); 453 if (rv) { 454 /* 455 * Need to translate ERESTART to EINTR here? -- jake 456 */ 457 mtx_unlock(&devsoftc.mtx); 458 return (rv); 459 } 460 } 461 n1 = TAILQ_FIRST(&devsoftc.devq); 462 TAILQ_REMOVE(&devsoftc.devq, n1, dei_link); 463 mtx_unlock(&devsoftc.mtx); 464 rv = uiomove(n1->dei_data, strlen(n1->dei_data), uio); 465 free(n1->dei_data, M_BUS); 466 free(n1, M_BUS); 467 return (rv); 468} 469 470static int 471devioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, d_thread_t *td) 472{ 473 switch (cmd) { 474 475 case FIONBIO: 476 if (*(int*)data) 477 devsoftc.nonblock = 1; 478 else 479 devsoftc.nonblock = 0; 480 return (0); 481 case FIOASYNC: 482 if (*(int*)data) 483 devsoftc.async_proc = td->td_proc; 484 else 485 devsoftc.async_proc = NULL; 486 return (0); 487 488 /* (un)Support for other fcntl() calls. */ 489 case FIOCLEX: 490 case FIONCLEX: 491 case FIONREAD: 492 case FIOSETOWN: 493 case FIOGETOWN: 494 default: 495 break; 496 } 497 return (ENOTTY); 498} 499 500static int 501devpoll(dev_t dev, int events, d_thread_t *td) 502{ 503 int revents = 0; 504 505 mtx_lock(&devsoftc.mtx); 506 if (events & (POLLIN | POLLRDNORM)) { 507 if (!TAILQ_EMPTY(&devsoftc.devq)) 508 revents = events & (POLLIN | POLLRDNORM); 509 else 510 selrecord(td, &devsoftc.sel); 511 } 512 mtx_unlock(&devsoftc.mtx); 513 514 return (revents); 515} 516 517/* 518 * Generic interface to queue data to the devctl device. It is 519 * assumed that data is properly formatted. It is further assumed 520 * that data is allocated. 521 */ 522void 523devctl_queue_data(char *data) 524{ 525 struct dev_event_info *n1 = NULL; 526 struct proc *p; 527 528 n1 = malloc(sizeof(*n1), M_BUS, M_NOWAIT); 529 if (n1 == NULL) 530 return; 531 n1->dei_data = data; 532 mtx_lock(&devsoftc.mtx); 533 TAILQ_INSERT_TAIL(&devsoftc.devq, n1, dei_link); 534 cv_broadcast(&devsoftc.cv); 535 mtx_unlock(&devsoftc.mtx); 536 selwakeup(&devsoftc.sel); 537 p = devsoftc.async_proc; 538 if (p != NULL) { 539 PROC_LOCK(p); 540 psignal(p, SIGIO); 541 PROC_UNLOCK(p); 542 } 543} 544 545/* 546 * Send a 'notification' to userland, using standard ways 547 */ 548void 549devctl_notify(const char *system, const char *subsystem, const char *type, 550 const char *data) 551{ 552 int len = 0; 553 char *msg; 554 555 if (system == NULL) 556 return; /* BOGUS! Must specify system. */ 557 if (subsystem == NULL) 558 return; /* BOGUS! Must specify subsystem. */ 559 if (type == NULL) 560 return; /* BOGUS! Must specify type. */ 561 len += strlen(" system=") + strlen(system); 562 len += strlen(" subsystem=") + strlen(subsystem); 563 len += strlen(" type=") + strlen(type); 564 /* add in the data message plus newline. */ 565 if (data != NULL) 566 len += strlen(data); 567 len += 3; /* '!', '\n', and NUL */ 568 msg = malloc(len, M_BUS, M_NOWAIT); 569 if (msg == NULL) 570 return; /* Drop it on the floor */ 571 snprintf(msg, len, "!system=%s subsystem=%s type=%s %s\n", system, 572 subsystem, type, data); 573 devctl_queue_data(msg); 574} 575 576/* 577 * Common routine that tries to make sending messages as easy as possible. 578 * We allocate memory for the data, copy strings into that, but do not 579 * free it unless there's an error. The dequeue part of the driver should 580 * free the data. We don't send data when the device is disabled. We do 581 * send data, even when we have no listeners, because we wish to avoid 582 * races relating to startup and restart of listening applications. 583 */ 584static void 585devaddq(const char *type, const char *what, device_t dev) 586{ 587 char *data = NULL; 588 char *loc; 589 const char *parstr; 590 591 if (devctl_disable) 592 return; 593 data = malloc(1024, M_BUS, M_NOWAIT); 594 if (data == NULL) 595 goto bad; 596 loc = malloc(1024, M_BUS, M_NOWAIT); 597 if (loc == NULL) 598 goto bad; 599 *loc = '\0'; 600 bus_child_location_str(dev, loc, 1024); 601 if (device_get_parent(dev) == NULL) 602 parstr = "."; /* Or '/' ? */ 603 else 604 parstr = device_get_nameunit(device_get_parent(dev)); 605 snprintf(data, 1024, "%s%s at %s on %s\n", type, what, loc, parstr); 606 free(loc, M_BUS); 607 devctl_queue_data(data); 608 return; 609bad: 610 free(data, M_BUS); 611 return; 612} 613 614/* 615 * A device was added to the tree. We are called just after it successfully 616 * attaches (that is, probe and attach success for this device). No call 617 * is made if a device is merely parented into the tree. See devnomatch 618 * if probe fails. If attach fails, no notification is sent (but maybe 619 * we should have a different message for this). 620 */ 621static void 622devadded(device_t dev) 623{ 624 devaddq("+", device_get_nameunit(dev), dev); 625} 626 627/* 628 * A device was removed from the tree. We are called just before this 629 * happens. 630 */ 631static void 632devremoved(device_t dev) 633{ 634 devaddq("-", device_get_nameunit(dev), dev); 635} 636 637/* 638 * Called when there's no match for this device. This is only called 639 * the first time that no match happens, so we don't keep getitng this 640 * message. Should that prove to be undesirable, we can change it. 641 * This is called when all drivers that can attach to a given bus 642 * decline to accept this device. Other errrors may not be detected. 643 */ 644static void 645devnomatch(device_t dev) 646{ 647 char *pnp = NULL; 648 649 pnp = malloc(1024, M_BUS, M_NOWAIT); 650 if (pnp == NULL) 651 return; 652 *pnp = '\0'; 653 bus_child_pnpinfo_str(dev, pnp, 1024); 654 devaddq("?", pnp, dev); 655 free(pnp, M_BUS); 656 return; 657} 658 659static int 660sysctl_devctl_disable(SYSCTL_HANDLER_ARGS) 661{ 662 struct dev_event_info *n1; 663 int dis, error; 664 665 dis = devctl_disable; 666 error = sysctl_handle_int(oidp, &dis, 0, req); 667 if (error || !req->newptr) 668 return (error); 669 mtx_lock(&devsoftc.mtx); 670 devctl_disable = dis; 671 if (dis) { 672 while (!TAILQ_EMPTY(&devsoftc.devq)) { 673 n1 = TAILQ_FIRST(&devsoftc.devq); 674 TAILQ_REMOVE(&devsoftc.devq, n1, dei_link); 675 free(n1->dei_data, M_BUS); 676 free(n1, M_BUS); 677 } 678 } 679 mtx_unlock(&devsoftc.mtx); 680 return (0); 681} 682 683/* End of /dev/devctl code */ 684 685TAILQ_HEAD(,device) bus_data_devices; 686static int bus_data_generation = 1; 687 688kobj_method_t null_methods[] = { 689 { 0, 0 } 690}; 691 692DEFINE_CLASS(null, null_methods, 0); 693 694/* 695 * Devclass implementation 696 */ 697 698static devclass_list_t devclasses = TAILQ_HEAD_INITIALIZER(devclasses); 699 700static devclass_t 701devclass_find_internal(const char *classname, const char *parentname, 702 int create) 703{ 704 devclass_t dc; 705 706 PDEBUG(("looking for %s", classname)); 707 if (!classname) 708 return (NULL); 709 710 TAILQ_FOREACH(dc, &devclasses, link) { 711 if (!strcmp(dc->name, classname)) 712 break; 713 } 714 715 if (create && !dc) { 716 PDEBUG(("creating %s", classname)); 717 dc = malloc(sizeof(struct devclass) + strlen(classname) + 1, 718 M_BUS, M_NOWAIT|M_ZERO); 719 if (!dc) 720 return (NULL); 721 dc->parent = NULL; 722 dc->name = (char*) (dc + 1); 723 strcpy(dc->name, classname); 724 TAILQ_INIT(&dc->drivers); 725 TAILQ_INSERT_TAIL(&devclasses, dc, link); 726 727 bus_data_generation_update(); 728 } 729 if (parentname && dc && !dc->parent) { 730 dc->parent = devclass_find_internal(parentname, 0, FALSE); 731 } 732 733 return (dc); 734} 735 736devclass_t 737devclass_create(const char *classname) 738{ 739 return (devclass_find_internal(classname, 0, TRUE)); 740} 741 742devclass_t 743devclass_find(const char *classname) 744{ 745 return (devclass_find_internal(classname, 0, FALSE)); 746} 747 748int 749devclass_add_driver(devclass_t dc, driver_t *driver) 750{ 751 driverlink_t dl; 752 int i; 753 754 PDEBUG(("%s", DRIVERNAME(driver))); 755 756 dl = malloc(sizeof *dl, M_BUS, M_NOWAIT|M_ZERO); 757 if (!dl) 758 return (ENOMEM); 759 760 /* 761 * Compile the driver's methods. Also increase the reference count 762 * so that the class doesn't get freed when the last instance 763 * goes. This means we can safely use static methods and avoids a 764 * double-free in devclass_delete_driver. 765 */ 766 kobj_class_compile((kobj_class_t) driver); 767 768 /* 769 * Make sure the devclass which the driver is implementing exists. 770 */ 771 devclass_find_internal(driver->name, 0, TRUE); 772 773 dl->driver = driver; 774 TAILQ_INSERT_TAIL(&dc->drivers, dl, link); 775 driver->refs++; 776 777 /* 778 * Call BUS_DRIVER_ADDED for any existing busses in this class. 779 */ 780 for (i = 0; i < dc->maxunit; i++) 781 if (dc->devices[i]) 782 BUS_DRIVER_ADDED(dc->devices[i], driver); 783 784 bus_data_generation_update(); 785 return (0); 786} 787 788int 789devclass_delete_driver(devclass_t busclass, driver_t *driver) 790{ 791 devclass_t dc = devclass_find(driver->name); 792 driverlink_t dl; 793 device_t dev; 794 int i; 795 int error; 796 797 PDEBUG(("%s from devclass %s", driver->name, DEVCLANAME(busclass))); 798 799 if (!dc) 800 return (0); 801 802 /* 803 * Find the link structure in the bus' list of drivers. 804 */ 805 TAILQ_FOREACH(dl, &busclass->drivers, link) { 806 if (dl->driver == driver) 807 break; 808 } 809 810 if (!dl) { 811 PDEBUG(("%s not found in %s list", driver->name, 812 busclass->name)); 813 return (ENOENT); 814 } 815 816 /* 817 * Disassociate from any devices. We iterate through all the 818 * devices in the devclass of the driver and detach any which are 819 * using the driver and which have a parent in the devclass which 820 * we are deleting from. 821 * 822 * Note that since a driver can be in multiple devclasses, we 823 * should not detach devices which are not children of devices in 824 * the affected devclass. 825 */ 826 for (i = 0; i < dc->maxunit; i++) { 827 if (dc->devices[i]) { 828 dev = dc->devices[i]; 829 if (dev->driver == driver && dev->parent && 830 dev->parent->devclass == busclass) { 831 if ((error = device_detach(dev)) != 0) 832 return (error); 833 device_set_driver(dev, NULL); 834 } 835 } 836 } 837 838 TAILQ_REMOVE(&busclass->drivers, dl, link); 839 free(dl, M_BUS); 840 841 driver->refs--; 842 if (driver->refs == 0) 843 kobj_class_free((kobj_class_t) driver); 844 845 bus_data_generation_update(); 846 return (0); 847} 848 849static driverlink_t 850devclass_find_driver_internal(devclass_t dc, const char *classname) 851{ 852 driverlink_t dl; 853 854 PDEBUG(("%s in devclass %s", classname, DEVCLANAME(dc))); 855 856 TAILQ_FOREACH(dl, &dc->drivers, link) { 857 if (!strcmp(dl->driver->name, classname)) 858 return (dl); 859 } 860 861 PDEBUG(("not found")); 862 return (NULL); 863} 864 865kobj_class_t 866devclass_find_driver(devclass_t dc, const char *classname) 867{ 868 driverlink_t dl; 869 870 dl = devclass_find_driver_internal(dc, classname); 871 if (dl) 872 return (dl->driver); 873 return (NULL); 874} 875 876const char * 877devclass_get_name(devclass_t dc) 878{ 879 return (dc->name); 880} 881 882device_t 883devclass_get_device(devclass_t dc, int unit) 884{ 885 if (dc == NULL || unit < 0 || unit >= dc->maxunit) 886 return (NULL); 887 return (dc->devices[unit]); 888} 889 890void * 891devclass_get_softc(devclass_t dc, int unit) 892{ 893 device_t dev; 894 895 dev = devclass_get_device(dc, unit); 896 if (!dev) 897 return (NULL); 898 899 return (device_get_softc(dev)); 900} 901 902int 903devclass_get_devices(devclass_t dc, device_t **devlistp, int *devcountp) 904{ 905 int i; 906 int count; 907 device_t *list; 908 909 count = 0; 910 for (i = 0; i < dc->maxunit; i++) 911 if (dc->devices[i]) 912 count++; 913 914 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO); 915 if (!list) 916 return (ENOMEM); 917 918 count = 0; 919 for (i = 0; i < dc->maxunit; i++) { 920 if (dc->devices[i]) { 921 list[count] = dc->devices[i]; 922 count++; 923 } 924 } 925 926 *devlistp = list; 927 *devcountp = count; 928 929 return (0); 930} 931 932int 933devclass_get_maxunit(devclass_t dc) 934{ 935 return (dc->maxunit); 936} 937 938int 939devclass_find_free_unit(devclass_t dc, int unit) 940{ 941 if (dc == NULL) 942 return (unit); 943 while (unit < dc->maxunit && dc->devices[unit] != NULL) 944 unit++; 945 return (unit); 946} 947 948void 949devclass_set_parent(devclass_t dc, devclass_t pdc) 950{ 951 dc->parent = pdc; 952} 953 954devclass_t 955devclass_get_parent(devclass_t dc) 956{ 957 return (dc->parent); 958} 959 960struct sysctl_ctx_list * 961devclass_get_sysctl_ctx(devclass_t dc) 962{ 963 return (&dc->sysctl_ctx); 964} 965 966struct sysctl_oid * 967devclass_get_sysctl_tree(devclass_t dc) 968{ 969 return (dc->sysctl_tree); 970} 971 972static int 973devclass_alloc_unit(devclass_t dc, int *unitp) 974{ 975 int unit = *unitp; 976 977 PDEBUG(("unit %d in devclass %s", unit, DEVCLANAME(dc))); 978 979 /* If we were given a wired unit number, check for existing device */ 980 /* XXX imp XXX */ 981 if (unit != -1) { 982 if (unit >= 0 && unit < dc->maxunit && 983 dc->devices[unit] != NULL) { 984 if (bootverbose) 985 printf("%s: %s%d already exists; skipping it\n", 986 dc->name, dc->name, *unitp); 987 return (EEXIST); 988 } 989 } else { 990 /* Unwired device, find the next available slot for it */ 991 unit = 0; 992 while (unit < dc->maxunit && dc->devices[unit] != NULL) 993 unit++; 994 } 995 996 /* 997 * We've selected a unit beyond the length of the table, so let's 998 * extend the table to make room for all units up to and including 999 * this one. 1000 */ 1001 if (unit >= dc->maxunit) { 1002 device_t *newlist; 1003 int newsize; 1004 1005 newsize = roundup((unit + 1), MINALLOCSIZE / sizeof(device_t)); 1006 newlist = malloc(sizeof(device_t) * newsize, M_BUS, M_NOWAIT); 1007 if (!newlist) 1008 return (ENOMEM); 1009 bcopy(dc->devices, newlist, sizeof(device_t) * dc->maxunit); 1010 bzero(newlist + dc->maxunit, 1011 sizeof(device_t) * (newsize - dc->maxunit)); 1012 if (dc->devices) 1013 free(dc->devices, M_BUS); 1014 dc->devices = newlist; 1015 dc->maxunit = newsize; 1016 } 1017 PDEBUG(("now: unit %d in devclass %s", unit, DEVCLANAME(dc))); 1018 1019 *unitp = unit; 1020 return (0); 1021} 1022 1023static int 1024devclass_add_device(devclass_t dc, device_t dev) 1025{ 1026 int buflen, error; 1027 1028 PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc))); 1029 1030 buflen = snprintf(NULL, 0, "%s%d$", dc->name, dev->unit); 1031 if (buflen < 0) 1032 return (ENOMEM); 1033 dev->nameunit = malloc(buflen, M_BUS, M_NOWAIT|M_ZERO); 1034 if (!dev->nameunit) 1035 return (ENOMEM); 1036 1037 if ((error = devclass_alloc_unit(dc, &dev->unit)) != 0) { 1038 free(dev->nameunit, M_BUS); 1039 dev->nameunit = NULL; 1040 return (error); 1041 } 1042 dc->devices[dev->unit] = dev; 1043 dev->devclass = dc; 1044 snprintf(dev->nameunit, buflen, "%s%d", dc->name, dev->unit); 1045 1046 return (0); 1047} 1048 1049static int 1050devclass_delete_device(devclass_t dc, device_t dev) 1051{ 1052 if (!dc || !dev) 1053 return (0); 1054 1055 PDEBUG(("%s in devclass %s", DEVICENAME(dev), DEVCLANAME(dc))); 1056 1057 if (dev->devclass != dc || dc->devices[dev->unit] != dev) 1058 panic("devclass_delete_device: inconsistent device class"); 1059 dc->devices[dev->unit] = NULL; 1060 if (dev->flags & DF_WILDCARD) 1061 dev->unit = -1; 1062 dev->devclass = NULL; 1063 free(dev->nameunit, M_BUS); 1064 dev->nameunit = NULL; 1065 1066 return (0); 1067} 1068 1069static device_t 1070make_device(device_t parent, const char *name, int unit) 1071{ 1072 device_t dev; 1073 devclass_t dc; 1074 1075 PDEBUG(("%s at %s as unit %d", name, DEVICENAME(parent), unit)); 1076 1077 if (name) { 1078 dc = devclass_find_internal(name, 0, TRUE); 1079 if (!dc) { 1080 printf("make_device: can't find device class %s\n", 1081 name); 1082 return (NULL); 1083 } 1084 } else { 1085 dc = NULL; 1086 } 1087 1088 dev = malloc(sizeof(struct device), M_BUS, M_NOWAIT|M_ZERO); 1089 if (!dev) 1090 return (NULL); 1091 1092 dev->parent = parent; 1093 TAILQ_INIT(&dev->children); 1094 kobj_init((kobj_t) dev, &null_class); 1095 dev->driver = NULL; 1096 dev->devclass = NULL; 1097 dev->unit = unit; 1098 dev->nameunit = NULL; 1099 dev->desc = NULL; 1100 dev->busy = 0; 1101 dev->devflags = 0; 1102 dev->flags = DF_ENABLED; 1103 dev->order = 0; 1104 if (unit == -1) 1105 dev->flags |= DF_WILDCARD; 1106 if (name) { 1107 dev->flags |= DF_FIXEDCLASS; 1108 if (devclass_add_device(dc, dev)) { 1109 kobj_delete((kobj_t) dev, M_BUS); 1110 return (NULL); 1111 } 1112 } 1113 dev->ivars = NULL; 1114 dev->softc = NULL; 1115 1116 dev->state = DS_NOTPRESENT; 1117 1118 TAILQ_INSERT_TAIL(&bus_data_devices, dev, devlink); 1119 bus_data_generation_update(); 1120 1121 return (dev); 1122} 1123 1124static int 1125device_print_child(device_t dev, device_t child) 1126{ 1127 int retval = 0; 1128 1129 if (device_is_alive(child)) 1130 retval += BUS_PRINT_CHILD(dev, child); 1131 else 1132 retval += device_printf(child, " not found\n"); 1133 1134 return (retval); 1135} 1136 1137device_t 1138device_add_child(device_t dev, const char *name, int unit) 1139{ 1140 return (device_add_child_ordered(dev, 0, name, unit)); 1141} 1142 1143device_t 1144device_add_child_ordered(device_t dev, int order, const char *name, int unit) 1145{ 1146 device_t child; 1147 device_t place; 1148 1149 PDEBUG(("%s at %s with order %d as unit %d", 1150 name, DEVICENAME(dev), order, unit)); 1151 1152 child = make_device(dev, name, unit); 1153 if (child == NULL) 1154 return (child); 1155 child->order = order; 1156 1157 TAILQ_FOREACH(place, &dev->children, link) { 1158 if (place->order > order) 1159 break; 1160 } 1161 1162 if (place) { 1163 /* 1164 * The device 'place' is the first device whose order is 1165 * greater than the new child. 1166 */ 1167 TAILQ_INSERT_BEFORE(place, child, link); 1168 } else { 1169 /* 1170 * The new child's order is greater or equal to the order of 1171 * any existing device. Add the child to the tail of the list. 1172 */ 1173 TAILQ_INSERT_TAIL(&dev->children, child, link); 1174 } 1175 1176 bus_data_generation_update(); 1177 return (child); 1178} 1179 1180int 1181device_delete_child(device_t dev, device_t child) 1182{ 1183 int error; 1184 device_t grandchild; 1185 1186 PDEBUG(("%s from %s", DEVICENAME(child), DEVICENAME(dev))); 1187 1188 /* remove children first */ 1189 while ( (grandchild = TAILQ_FIRST(&child->children)) ) { 1190 error = device_delete_child(child, grandchild); 1191 if (error) 1192 return (error); 1193 } 1194 1195 if ((error = device_detach(child)) != 0) 1196 return (error); 1197 if (child->devclass) 1198 devclass_delete_device(child->devclass, child); 1199 TAILQ_REMOVE(&dev->children, child, link); 1200 TAILQ_REMOVE(&bus_data_devices, child, devlink); 1201 device_set_desc(child, NULL); 1202 kobj_delete((kobj_t) child, M_BUS); 1203 1204 bus_data_generation_update(); 1205 return (0); 1206} 1207 1208/* 1209 * Find only devices attached to this bus. 1210 */ 1211device_t 1212device_find_child(device_t dev, const char *classname, int unit) 1213{ 1214 devclass_t dc; 1215 device_t child; 1216 1217 dc = devclass_find(classname); 1218 if (!dc) 1219 return (NULL); 1220 1221 child = devclass_get_device(dc, unit); 1222 if (child && child->parent == dev) 1223 return (child); 1224 return (NULL); 1225} 1226 1227static driverlink_t 1228first_matching_driver(devclass_t dc, device_t dev) 1229{ 1230 if (dev->devclass) 1231 return (devclass_find_driver_internal(dc, dev->devclass->name)); 1232 return (TAILQ_FIRST(&dc->drivers)); 1233} 1234 1235static driverlink_t 1236next_matching_driver(devclass_t dc, device_t dev, driverlink_t last) 1237{ 1238 if (dev->devclass) { 1239 driverlink_t dl; 1240 for (dl = TAILQ_NEXT(last, link); dl; dl = TAILQ_NEXT(dl, link)) 1241 if (!strcmp(dev->devclass->name, dl->driver->name)) 1242 return (dl); 1243 return (NULL); 1244 } 1245 return (TAILQ_NEXT(last, link)); 1246} 1247 1248static int 1249device_probe_child(device_t dev, device_t child) 1250{ 1251 devclass_t dc; 1252 driverlink_t best = 0; 1253 driverlink_t dl; 1254 int result, pri = 0; 1255 int hasclass = (child->devclass != 0); 1256 1257 dc = dev->devclass; 1258 if (!dc) 1259 panic("device_probe_child: parent device has no devclass"); 1260 1261 if (child->state == DS_ALIVE) 1262 return (0); 1263 1264 for (; dc; dc = dc->parent) { 1265 for (dl = first_matching_driver(dc, child); 1266 dl; 1267 dl = next_matching_driver(dc, child, dl)) { 1268 PDEBUG(("Trying %s", DRIVERNAME(dl->driver))); 1269 device_set_driver(child, dl->driver); 1270 if (!hasclass) 1271 device_set_devclass(child, dl->driver->name); 1272 result = DEVICE_PROBE(child); 1273 if (!hasclass) 1274 device_set_devclass(child, 0); 1275 1276 /* 1277 * If the driver returns SUCCESS, there can be 1278 * no higher match for this device. 1279 */ 1280 if (result == 0) { 1281 best = dl; 1282 pri = 0; 1283 break; 1284 } 1285 1286 /* 1287 * The driver returned an error so it 1288 * certainly doesn't match. 1289 */ 1290 if (result > 0) { 1291 device_set_driver(child, 0); 1292 continue; 1293 } 1294 1295 /* 1296 * A priority lower than SUCCESS, remember the 1297 * best matching driver. Initialise the value 1298 * of pri for the first match. 1299 */ 1300 if (best == 0 || result > pri) { 1301 best = dl; 1302 pri = result; 1303 continue; 1304 } 1305 } 1306 /* 1307 * If we have an unambiguous match in this devclass, 1308 * don't look in the parent. 1309 */ 1310 if (best && pri == 0) 1311 break; 1312 } 1313 1314 /* 1315 * If we found a driver, change state and initialise the devclass. 1316 */ 1317 if (best) { 1318 if (!child->devclass) 1319 device_set_devclass(child, best->driver->name); 1320 device_set_driver(child, best->driver); 1321 if (pri < 0) { 1322 /* 1323 * A bit bogus. Call the probe method again to make 1324 * sure that we have the right description. 1325 */ 1326 DEVICE_PROBE(child); 1327 } 1328 child->state = DS_ALIVE; 1329 1330 bus_data_generation_update(); 1331 return (0); 1332 } 1333 1334 return (ENXIO); 1335} 1336 1337device_t 1338device_get_parent(device_t dev) 1339{ 1340 return (dev->parent); 1341} 1342 1343int 1344device_get_children(device_t dev, device_t **devlistp, int *devcountp) 1345{ 1346 int count; 1347 device_t child; 1348 device_t *list; 1349 1350 count = 0; 1351 TAILQ_FOREACH(child, &dev->children, link) { 1352 count++; 1353 } 1354 1355 list = malloc(count * sizeof(device_t), M_TEMP, M_NOWAIT|M_ZERO); 1356 if (!list) 1357 return (ENOMEM); 1358 1359 count = 0; 1360 TAILQ_FOREACH(child, &dev->children, link) { 1361 list[count] = child; 1362 count++; 1363 } 1364 1365 *devlistp = list; 1366 *devcountp = count; 1367 1368 return (0); 1369} 1370 1371driver_t * 1372device_get_driver(device_t dev) 1373{ 1374 return (dev->driver); 1375} 1376 1377devclass_t 1378device_get_devclass(device_t dev) 1379{ 1380 return (dev->devclass); 1381} 1382 1383const char * 1384device_get_name(device_t dev) 1385{ 1386 if (dev != NULL && dev->devclass) 1387 return (devclass_get_name(dev->devclass)); 1388 return (NULL); 1389} 1390 1391const char * 1392device_get_nameunit(device_t dev) 1393{ 1394 return (dev->nameunit); 1395} 1396 1397int 1398device_get_unit(device_t dev) 1399{ 1400 return (dev->unit); 1401} 1402 1403const char * 1404device_get_desc(device_t dev) 1405{ 1406 return (dev->desc); 1407} 1408 1409u_int32_t 1410device_get_flags(device_t dev) 1411{ 1412 return (dev->devflags); 1413} 1414 1415struct sysctl_ctx_list * 1416device_get_sysctl_ctx(device_t dev) 1417{ 1418 return (&dev->sysctl_ctx); 1419} 1420 1421struct sysctl_oid * 1422device_get_sysctl_tree(device_t dev) 1423{ 1424 return (dev->sysctl_tree); 1425} 1426 1427int 1428device_print_prettyname(device_t dev) 1429{ 1430 const char *name = device_get_name(dev); 1431 1432 if (name == 0) 1433 return (printf("unknown: ")); 1434 return (printf("%s%d: ", name, device_get_unit(dev))); 1435} 1436 1437int 1438device_printf(device_t dev, const char * fmt, ...) 1439{ 1440 va_list ap; 1441 int retval; 1442 1443 retval = device_print_prettyname(dev); 1444 va_start(ap, fmt); 1445 retval += vprintf(fmt, ap); 1446 va_end(ap); 1447 return (retval); 1448} 1449 1450static void 1451device_set_desc_internal(device_t dev, const char* desc, int copy) 1452{ 1453 if (dev->desc && (dev->flags & DF_DESCMALLOCED)) { 1454 free(dev->desc, M_BUS); 1455 dev->flags &= ~DF_DESCMALLOCED; 1456 dev->desc = NULL; 1457 } 1458 1459 if (copy && desc) { 1460 dev->desc = malloc(strlen(desc) + 1, M_BUS, M_NOWAIT); 1461 if (dev->desc) { 1462 strcpy(dev->desc, desc); 1463 dev->flags |= DF_DESCMALLOCED; 1464 } 1465 } else { 1466 /* Avoid a -Wcast-qual warning */ 1467 dev->desc = (char *)(uintptr_t) desc; 1468 } 1469 1470 bus_data_generation_update(); 1471} 1472 1473void 1474device_set_desc(device_t dev, const char* desc) 1475{ 1476 device_set_desc_internal(dev, desc, FALSE); 1477} 1478 1479void 1480device_set_desc_copy(device_t dev, const char* desc) 1481{ 1482 device_set_desc_internal(dev, desc, TRUE); 1483} 1484 1485void 1486device_set_flags(device_t dev, u_int32_t flags) 1487{ 1488 dev->devflags = flags; 1489} 1490 1491void * 1492device_get_softc(device_t dev) 1493{ 1494 return (dev->softc); 1495} 1496 1497void 1498device_set_softc(device_t dev, void *softc) 1499{ 1500 if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) 1501 free(dev->softc, M_BUS_SC); 1502 dev->softc = softc; 1503 if (dev->softc) 1504 dev->flags |= DF_EXTERNALSOFTC; 1505 else 1506 dev->flags &= ~DF_EXTERNALSOFTC; 1507} 1508 1509void * 1510device_get_ivars(device_t dev) 1511{ 1512 1513 KASSERT(dev != NULL, ("device_get_ivars(NULL, ...)")); 1514 return (dev->ivars); 1515} 1516 1517void 1518device_set_ivars(device_t dev, void * ivars) 1519{ 1520 1521 KASSERT(dev != NULL, ("device_set_ivars(NULL, ...)")); 1522 dev->ivars = ivars; 1523} 1524 1525device_state_t 1526device_get_state(device_t dev) 1527{ 1528 return (dev->state); 1529} 1530 1531void 1532device_enable(device_t dev) 1533{ 1534 dev->flags |= DF_ENABLED; 1535} 1536 1537void 1538device_disable(device_t dev) 1539{ 1540 dev->flags &= ~DF_ENABLED; 1541} 1542 1543void 1544device_busy(device_t dev) 1545{ 1546 if (dev->state < DS_ATTACHED) 1547 panic("device_busy: called for unattached device"); 1548 if (dev->busy == 0 && dev->parent) 1549 device_busy(dev->parent); 1550 dev->busy++; 1551 dev->state = DS_BUSY; 1552} 1553 1554void 1555device_unbusy(device_t dev) 1556{ 1557 if (dev->state != DS_BUSY) 1558 panic("device_unbusy: called for non-busy device"); 1559 dev->busy--; 1560 if (dev->busy == 0) { 1561 if (dev->parent) 1562 device_unbusy(dev->parent); 1563 dev->state = DS_ATTACHED; 1564 } 1565} 1566 1567void 1568device_quiet(device_t dev) 1569{ 1570 dev->flags |= DF_QUIET; 1571} 1572 1573void 1574device_verbose(device_t dev) 1575{ 1576 dev->flags &= ~DF_QUIET; 1577} 1578 1579int 1580device_is_quiet(device_t dev) 1581{ 1582 return ((dev->flags & DF_QUIET) != 0); 1583} 1584 1585int 1586device_is_enabled(device_t dev) 1587{ 1588 return ((dev->flags & DF_ENABLED) != 0); 1589} 1590 1591int 1592device_is_alive(device_t dev) 1593{ 1594 return (dev->state >= DS_ALIVE); 1595} 1596 1597int 1598device_is_attached(device_t dev) 1599{ 1600 return (dev->state >= DS_ATTACHED); 1601} 1602 1603int 1604device_set_devclass(device_t dev, const char *classname) 1605{ 1606 devclass_t dc; 1607 int error; 1608 1609 if (!classname) { 1610 if (dev->devclass) 1611 devclass_delete_device(dev->devclass, dev); 1612 return (0); 1613 } 1614 1615 if (dev->devclass) { 1616 printf("device_set_devclass: device class already set\n"); 1617 return (EINVAL); 1618 } 1619 1620 dc = devclass_find_internal(classname, 0, TRUE); 1621 if (!dc) 1622 return (ENOMEM); 1623 1624 error = devclass_add_device(dc, dev); 1625 1626 bus_data_generation_update(); 1627 return (error); 1628} 1629 1630int 1631device_set_driver(device_t dev, driver_t *driver) 1632{ 1633 if (dev->state >= DS_ATTACHED) 1634 return (EBUSY); 1635 1636 if (dev->driver == driver) 1637 return (0); 1638 1639 if (dev->softc && !(dev->flags & DF_EXTERNALSOFTC)) { 1640 free(dev->softc, M_BUS_SC); 1641 dev->softc = NULL; 1642 } 1643 kobj_delete((kobj_t) dev, 0); 1644 dev->driver = driver; 1645 if (driver) { 1646 kobj_init((kobj_t) dev, (kobj_class_t) driver); 1647 if (!(dev->flags & DF_EXTERNALSOFTC) && driver->size > 0) { 1648 dev->softc = malloc(driver->size, M_BUS_SC, 1649 M_NOWAIT | M_ZERO); 1650 if (!dev->softc) { 1651 kobj_delete((kobj_t) dev, 0); 1652 kobj_init((kobj_t) dev, &null_class); 1653 dev->driver = NULL; 1654 return (ENOMEM); 1655 } 1656 } 1657 } else { 1658 kobj_init((kobj_t) dev, &null_class); 1659 } 1660 1661 bus_data_generation_update(); 1662 return (0); 1663} 1664 1665int 1666device_probe_and_attach(device_t dev) 1667{ 1668 int error; 1669 1670 if (dev->state >= DS_ALIVE) 1671 return (0); 1672 1673 if (!(dev->flags & DF_ENABLED)) { 1674 if (bootverbose) { 1675 device_print_prettyname(dev); 1676 printf("not probed (disabled)\n"); 1677 } 1678 return (0); 1679 } 1680 if ((error = device_probe_child(dev->parent, dev)) != 0) { 1681 if (!(dev->flags & DF_DONENOMATCH)) { 1682 BUS_PROBE_NOMATCH(dev->parent, dev); 1683 devnomatch(dev); 1684 dev->flags |= DF_DONENOMATCH; 1685 } 1686 return (error); 1687 } 1688 error = device_attach(dev); 1689 1690 return (error); 1691} 1692 1693int 1694device_attach(device_t dev) 1695{ 1696 int error; 1697 1698 device_sysctl_init(dev); 1699 if (!device_is_quiet(dev)) 1700 device_print_child(dev->parent, dev); 1701 if ((error = DEVICE_ATTACH(dev)) != 0) { 1702 printf("device_attach: %s%d attach returned %d\n", 1703 dev->driver->name, dev->unit, error); 1704 /* Unset the class; set in device_probe_child */ 1705 if (dev->devclass == 0) 1706 device_set_devclass(dev, 0); 1707 device_set_driver(dev, NULL); 1708 device_sysctl_fini(dev); 1709 dev->state = DS_NOTPRESENT; 1710 return (error); 1711 } 1712 dev->state = DS_ATTACHED; 1713 devadded(dev); 1714 return (0); 1715} 1716 1717int 1718device_detach(device_t dev) 1719{ 1720 int error; 1721 1722 PDEBUG(("%s", DEVICENAME(dev))); 1723 if (dev->state == DS_BUSY) 1724 return (EBUSY); 1725 if (dev->state != DS_ATTACHED) 1726 return (0); 1727 1728 if ((error = DEVICE_DETACH(dev)) != 0) 1729 return (error); 1730 devremoved(dev); 1731 device_printf(dev, "detached\n"); 1732 if (dev->parent) 1733 BUS_CHILD_DETACHED(dev->parent, dev); 1734 1735 if (!(dev->flags & DF_FIXEDCLASS)) 1736 devclass_delete_device(dev->devclass, dev); 1737 1738 dev->state = DS_NOTPRESENT; 1739 device_set_driver(dev, NULL); 1740 device_sysctl_fini(dev); 1741 1742 return (0); 1743} 1744 1745int 1746device_shutdown(device_t dev) 1747{ 1748 if (dev->state < DS_ATTACHED) 1749 return (0); 1750 return (DEVICE_SHUTDOWN(dev)); 1751} 1752 1753int 1754device_set_unit(device_t dev, int unit) 1755{ 1756 devclass_t dc; 1757 int err; 1758 1759 dc = device_get_devclass(dev); 1760 if (unit < dc->maxunit && dc->devices[unit]) 1761 return (EBUSY); 1762 err = devclass_delete_device(dc, dev); 1763 if (err) 1764 return (err); 1765 dev->unit = unit; 1766 err = devclass_add_device(dc, dev); 1767 if (err) 1768 return (err); 1769 1770 bus_data_generation_update(); 1771 return (0); 1772} 1773 1774/*======================================*/ 1775/* 1776 * Some useful method implementations to make life easier for bus drivers. 1777 */ 1778 1779void 1780resource_list_init(struct resource_list *rl) 1781{ 1782 SLIST_INIT(rl); 1783} 1784 1785void 1786resource_list_free(struct resource_list *rl) 1787{ 1788 struct resource_list_entry *rle; 1789 1790 while ((rle = SLIST_FIRST(rl)) != NULL) { 1791 if (rle->res) 1792 panic("resource_list_free: resource entry is busy"); 1793 SLIST_REMOVE_HEAD(rl, link); 1794 free(rle, M_BUS); 1795 } 1796} 1797 1798int 1799resource_list_add_next(struct resource_list *rl, int type, u_long start, 1800 u_long end, u_long count) 1801{ 1802 int rid; 1803 1804 rid = 0; 1805 while (resource_list_find(rl, type, rid) != NULL) 1806 rid++; 1807 resource_list_add(rl, type, rid, start, end, count); 1808 return (rid); 1809} 1810 1811void 1812resource_list_add(struct resource_list *rl, int type, int rid, 1813 u_long start, u_long end, u_long count) 1814{ 1815 struct resource_list_entry *rle; 1816 1817 rle = resource_list_find(rl, type, rid); 1818 if (!rle) { 1819 rle = malloc(sizeof(struct resource_list_entry), M_BUS, 1820 M_NOWAIT); 1821 if (!rle) 1822 panic("resource_list_add: can't record entry"); 1823 SLIST_INSERT_HEAD(rl, rle, link); 1824 rle->type = type; 1825 rle->rid = rid; 1826 rle->res = NULL; 1827 } 1828 1829 if (rle->res) 1830 panic("resource_list_add: resource entry is busy"); 1831 1832 rle->start = start; 1833 rle->end = end; 1834 rle->count = count; 1835} 1836 1837struct resource_list_entry * 1838resource_list_find(struct resource_list *rl, int type, int rid) 1839{ 1840 struct resource_list_entry *rle; 1841 1842 SLIST_FOREACH(rle, rl, link) { 1843 if (rle->type == type && rle->rid == rid) 1844 return (rle); 1845 } 1846 return (NULL); 1847} 1848 1849void 1850resource_list_delete(struct resource_list *rl, int type, int rid) 1851{ 1852 struct resource_list_entry *rle = resource_list_find(rl, type, rid); 1853 1854 if (rle) { 1855 if (rle->res != NULL) 1856 panic("resource_list_delete: resource has not been released"); 1857 SLIST_REMOVE(rl, rle, resource_list_entry, link); 1858 free(rle, M_BUS); 1859 } 1860} 1861 1862struct resource * 1863resource_list_alloc(struct resource_list *rl, device_t bus, device_t child, 1864 int type, int *rid, u_long start, u_long end, u_long count, u_int flags) 1865{ 1866 struct resource_list_entry *rle = 0; 1867 int passthrough = (device_get_parent(child) != bus); 1868 int isdefault = (start == 0UL && end == ~0UL); 1869 1870 if (passthrough) { 1871 return (BUS_ALLOC_RESOURCE(device_get_parent(bus), child, 1872 type, rid, start, end, count, flags)); 1873 } 1874 1875 rle = resource_list_find(rl, type, *rid); 1876 1877 if (!rle) 1878 return (NULL); /* no resource of that type/rid */ 1879 1880 if (rle->res) 1881 panic("resource_list_alloc: resource entry is busy"); 1882 1883 if (isdefault) { 1884 start = rle->start; 1885 count = ulmax(count, rle->count); 1886 end = ulmax(rle->end, start + count - 1); 1887 } 1888 1889 rle->res = BUS_ALLOC_RESOURCE(device_get_parent(bus), child, 1890 type, rid, start, end, count, flags); 1891 1892 /* 1893 * Record the new range. 1894 */ 1895 if (rle->res) { 1896 rle->start = rman_get_start(rle->res); 1897 rle->end = rman_get_end(rle->res); 1898 rle->count = count; 1899 } 1900 1901 return (rle->res); 1902} 1903 1904int 1905resource_list_release(struct resource_list *rl, device_t bus, device_t child, 1906 int type, int rid, struct resource *res) 1907{ 1908 struct resource_list_entry *rle = 0; 1909 int passthrough = (device_get_parent(child) != bus); 1910 int error; 1911 1912 if (passthrough) { 1913 return (BUS_RELEASE_RESOURCE(device_get_parent(bus), child, 1914 type, rid, res)); 1915 } 1916 1917 rle = resource_list_find(rl, type, rid); 1918 1919 if (!rle) 1920 panic("resource_list_release: can't find resource"); 1921 if (!rle->res) 1922 panic("resource_list_release: resource entry is not busy"); 1923 1924 error = BUS_RELEASE_RESOURCE(device_get_parent(bus), child, 1925 type, rid, res); 1926 if (error) 1927 return (error); 1928 1929 rle->res = NULL; 1930 return (0); 1931} 1932 1933int 1934resource_list_print_type(struct resource_list *rl, const char *name, int type, 1935 const char *format) 1936{ 1937 struct resource_list_entry *rle; 1938 int printed, retval; 1939 1940 printed = 0; 1941 retval = 0; 1942 /* Yes, this is kinda cheating */ 1943 SLIST_FOREACH(rle, rl, link) { 1944 if (rle->type == type) { 1945 if (printed == 0) 1946 retval += printf(" %s ", name); 1947 else 1948 retval += printf(","); 1949 printed++; 1950 retval += printf(format, rle->start); 1951 if (rle->count > 1) { 1952 retval += printf("-"); 1953 retval += printf(format, rle->start + 1954 rle->count - 1); 1955 } 1956 } 1957 } 1958 return (retval); 1959} 1960 1961/* 1962 * Call DEVICE_IDENTIFY for each driver. 1963 */ 1964int 1965bus_generic_probe(device_t dev) 1966{ 1967 devclass_t dc = dev->devclass; 1968 driverlink_t dl; 1969 1970 TAILQ_FOREACH(dl, &dc->drivers, link) { 1971 DEVICE_IDENTIFY(dl->driver, dev); 1972 } 1973 1974 return (0); 1975} 1976 1977int 1978bus_generic_attach(device_t dev) 1979{ 1980 device_t child; 1981 1982 TAILQ_FOREACH(child, &dev->children, link) { 1983 device_probe_and_attach(child); 1984 } 1985 1986 return (0); 1987} 1988 1989int 1990bus_generic_detach(device_t dev) 1991{ 1992 device_t child; 1993 int error; 1994 1995 if (dev->state != DS_ATTACHED) 1996 return (EBUSY); 1997 1998 TAILQ_FOREACH(child, &dev->children, link) { 1999 if ((error = device_detach(child)) != 0) 2000 return (error); 2001 } 2002 2003 return (0); 2004} 2005 2006int 2007bus_generic_shutdown(device_t dev) 2008{ 2009 device_t child; 2010 2011 TAILQ_FOREACH(child, &dev->children, link) { 2012 device_shutdown(child); 2013 } 2014 2015 return (0); 2016} 2017 2018int 2019bus_generic_suspend(device_t dev) 2020{ 2021 int error; 2022 device_t child, child2; 2023 2024 TAILQ_FOREACH(child, &dev->children, link) { 2025 error = DEVICE_SUSPEND(child); 2026 if (error) { 2027 for (child2 = TAILQ_FIRST(&dev->children); 2028 child2 && child2 != child; 2029 child2 = TAILQ_NEXT(child2, link)) 2030 DEVICE_RESUME(child2); 2031 return (error); 2032 } 2033 } 2034 return (0); 2035} 2036 2037int 2038bus_generic_resume(device_t dev) 2039{ 2040 device_t child; 2041 2042 TAILQ_FOREACH(child, &dev->children, link) { 2043 DEVICE_RESUME(child); 2044 /* if resume fails, there's nothing we can usefully do... */ 2045 } 2046 return (0); 2047} 2048 2049int 2050bus_print_child_header(device_t dev, device_t child) 2051{ 2052 int retval = 0; 2053 2054 if (device_get_desc(child)) { 2055 retval += device_printf(child, "<%s>", device_get_desc(child)); 2056 } else { 2057 retval += printf("%s", device_get_nameunit(child)); 2058 } 2059 2060 return (retval); 2061} 2062 2063int 2064bus_print_child_footer(device_t dev, device_t child) 2065{ 2066 return (printf(" on %s\n", device_get_nameunit(dev))); 2067} 2068 2069int 2070bus_generic_print_child(device_t dev, device_t child) 2071{ 2072 int retval = 0; 2073 2074 retval += bus_print_child_header(dev, child); 2075 retval += bus_print_child_footer(dev, child); 2076 2077 return (retval); 2078} 2079 2080int 2081bus_generic_read_ivar(device_t dev, device_t child, int index, 2082 uintptr_t * result) 2083{ 2084 return (ENOENT); 2085} 2086 2087int 2088bus_generic_write_ivar(device_t dev, device_t child, int index, 2089 uintptr_t value) 2090{ 2091 return (ENOENT); 2092} 2093 2094struct resource_list * 2095bus_generic_get_resource_list(device_t dev, device_t child) 2096{ 2097 return (NULL); 2098} 2099 2100void 2101bus_generic_driver_added(device_t dev, driver_t *driver) 2102{ 2103 device_t child; 2104 2105 DEVICE_IDENTIFY(driver, dev); 2106 TAILQ_FOREACH(child, &dev->children, link) { 2107 if (child->state == DS_NOTPRESENT) 2108 device_probe_and_attach(child); 2109 } 2110} 2111 2112int 2113bus_generic_setup_intr(device_t dev, device_t child, struct resource *irq, 2114 int flags, driver_intr_t *intr, void *arg, void **cookiep) 2115{ 2116 /* Propagate up the bus hierarchy until someone handles it. */ 2117 if (dev->parent) 2118 return (BUS_SETUP_INTR(dev->parent, child, irq, flags, 2119 intr, arg, cookiep)); 2120 return (EINVAL); 2121} 2122 2123int 2124bus_generic_teardown_intr(device_t dev, device_t child, struct resource *irq, 2125 void *cookie) 2126{ 2127 /* Propagate up the bus hierarchy until someone handles it. */ 2128 if (dev->parent) 2129 return (BUS_TEARDOWN_INTR(dev->parent, child, irq, cookie)); 2130 return (EINVAL); 2131} 2132 2133struct resource * 2134bus_generic_alloc_resource(device_t dev, device_t child, int type, int *rid, 2135 u_long start, u_long end, u_long count, u_int flags) 2136{ 2137 /* Propagate up the bus hierarchy until someone handles it. */ 2138 if (dev->parent) 2139 return (BUS_ALLOC_RESOURCE(dev->parent, child, type, rid, 2140 start, end, count, flags)); 2141 return (NULL); 2142} 2143 2144int 2145bus_generic_release_resource(device_t dev, device_t child, int type, int rid, 2146 struct resource *r) 2147{ 2148 /* Propagate up the bus hierarchy until someone handles it. */ 2149 if (dev->parent) 2150 return (BUS_RELEASE_RESOURCE(dev->parent, child, type, rid, 2151 r)); 2152 return (EINVAL); 2153} 2154 2155int 2156bus_generic_activate_resource(device_t dev, device_t child, int type, int rid, 2157 struct resource *r) 2158{ 2159 /* Propagate up the bus hierarchy until someone handles it. */ 2160 if (dev->parent) 2161 return (BUS_ACTIVATE_RESOURCE(dev->parent, child, type, rid, 2162 r)); 2163 return (EINVAL); 2164} 2165 2166int 2167bus_generic_deactivate_resource(device_t dev, device_t child, int type, 2168 int rid, struct resource *r) 2169{ 2170 /* Propagate up the bus hierarchy until someone handles it. */ 2171 if (dev->parent) 2172 return (BUS_DEACTIVATE_RESOURCE(dev->parent, child, type, rid, 2173 r)); 2174 return (EINVAL); 2175} 2176 2177int 2178bus_generic_config_intr(device_t dev, int irq, enum intr_trigger trig, 2179 enum intr_polarity pol) 2180{ 2181 2182 /* Propagate up the bus hierarchy until someone handles it. */ 2183 if (dev->parent) 2184 return (BUS_CONFIG_INTR(dev->parent, irq, trig, pol)); 2185 return (EINVAL); 2186} 2187 2188int 2189bus_generic_rl_get_resource(device_t dev, device_t child, int type, int rid, 2190 u_long *startp, u_long *countp) 2191{ 2192 struct resource_list * rl = NULL; 2193 struct resource_list_entry * rle = NULL; 2194 2195 rl = BUS_GET_RESOURCE_LIST(dev, child); 2196 if (!rl) 2197 return (EINVAL); 2198 2199 rle = resource_list_find(rl, type, rid); 2200 if (!rle) 2201 return (ENOENT); 2202 2203 if (startp) 2204 *startp = rle->start; 2205 if (countp) 2206 *countp = rle->count; 2207 2208 return (0); 2209} 2210 2211int 2212bus_generic_rl_set_resource(device_t dev, device_t child, int type, int rid, 2213 u_long start, u_long count) 2214{ 2215 struct resource_list * rl = NULL; 2216 2217 rl = BUS_GET_RESOURCE_LIST(dev, child); 2218 if (!rl) 2219 return (EINVAL); 2220 2221 resource_list_add(rl, type, rid, start, (start + count - 1), count); 2222 2223 return (0); 2224} 2225 2226void 2227bus_generic_rl_delete_resource(device_t dev, device_t child, int type, int rid) 2228{ 2229 struct resource_list * rl = NULL; 2230 2231 rl = BUS_GET_RESOURCE_LIST(dev, child); 2232 if (!rl) 2233 return; 2234 2235 resource_list_delete(rl, type, rid); 2236 2237 return; 2238} 2239 2240int 2241bus_generic_rl_release_resource(device_t dev, device_t child, int type, 2242 int rid, struct resource *r) 2243{ 2244 struct resource_list * rl = NULL; 2245 2246 rl = BUS_GET_RESOURCE_LIST(dev, child); 2247 if (!rl) 2248 return (EINVAL); 2249 2250 return (resource_list_release(rl, dev, child, type, rid, r)); 2251} 2252 2253struct resource * 2254bus_generic_rl_alloc_resource(device_t dev, device_t child, int type, 2255 int *rid, u_long start, u_long end, u_long count, u_int flags) 2256{ 2257 struct resource_list * rl = NULL; 2258 2259 rl = BUS_GET_RESOURCE_LIST(dev, child); 2260 if (!rl) 2261 return (NULL); 2262 2263 return (resource_list_alloc(rl, dev, child, type, rid, 2264 start, end, count, flags)); 2265} 2266 2267int 2268bus_generic_child_present(device_t bus, device_t child) 2269{ 2270 return (BUS_CHILD_PRESENT(device_get_parent(bus), bus)); 2271} 2272 2273/* 2274 * Some convenience functions to make it easier for drivers to use the 2275 * resource-management functions. All these really do is hide the 2276 * indirection through the parent's method table, making for slightly 2277 * less-wordy code. In the future, it might make sense for this code 2278 * to maintain some sort of a list of resources allocated by each device. 2279 */ 2280struct resource * 2281bus_alloc_resource(device_t dev, int type, int *rid, u_long start, u_long end, 2282 u_long count, u_int flags) 2283{ 2284 if (dev->parent == 0) 2285 return (0); 2286 return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end, 2287 count, flags)); 2288} 2289 2290int 2291bus_activate_resource(device_t dev, int type, int rid, struct resource *r) 2292{ 2293 if (dev->parent == 0) 2294 return (EINVAL); 2295 return (BUS_ACTIVATE_RESOURCE(dev->parent, dev, type, rid, r)); 2296} 2297 2298int 2299bus_deactivate_resource(device_t dev, int type, int rid, struct resource *r) 2300{ 2301 if (dev->parent == 0) 2302 return (EINVAL); 2303 return (BUS_DEACTIVATE_RESOURCE(dev->parent, dev, type, rid, r)); 2304} 2305 2306int 2307bus_release_resource(device_t dev, int type, int rid, struct resource *r) 2308{ 2309 if (dev->parent == 0) 2310 return (EINVAL); 2311 return (BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r)); 2312} 2313 2314int 2315bus_setup_intr(device_t dev, struct resource *r, int flags, 2316 driver_intr_t handler, void *arg, void **cookiep) 2317{ 2318 int error; 2319 2320 if (dev->parent != 0) { 2321 if ((flags &~ INTR_ENTROPY) == (INTR_TYPE_NET | INTR_MPSAFE) && 2322 !debug_mpsafenet) 2323 flags &= ~INTR_MPSAFE; 2324 error = BUS_SETUP_INTR(dev->parent, dev, r, flags, 2325 handler, arg, cookiep); 2326 if (error == 0) { 2327 if (!(flags & (INTR_MPSAFE | INTR_FAST))) 2328 device_printf(dev, "[GIANT-LOCKED]\n"); 2329 if (bootverbose && (flags & INTR_MPSAFE)) 2330 device_printf(dev, "[MPSAFE]\n"); 2331 if (flags & INTR_FAST) 2332 device_printf(dev, "[FAST]\n"); 2333 } 2334 } else 2335 error = EINVAL; 2336 return (error); 2337} 2338 2339int 2340bus_teardown_intr(device_t dev, struct resource *r, void *cookie) 2341{ 2342 if (dev->parent == 0) 2343 return (EINVAL); 2344 return (BUS_TEARDOWN_INTR(dev->parent, dev, r, cookie)); 2345} 2346 2347int 2348bus_set_resource(device_t dev, int type, int rid, 2349 u_long start, u_long count) 2350{ 2351 return (BUS_SET_RESOURCE(device_get_parent(dev), dev, type, rid, 2352 start, count)); 2353} 2354 2355int 2356bus_get_resource(device_t dev, int type, int rid, 2357 u_long *startp, u_long *countp) 2358{ 2359 return (BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid, 2360 startp, countp)); 2361} 2362 2363u_long 2364bus_get_resource_start(device_t dev, int type, int rid) 2365{ 2366 u_long start, count; 2367 int error; 2368 2369 error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid, 2370 &start, &count); 2371 if (error) 2372 return (0); 2373 return (start); 2374} 2375 2376u_long 2377bus_get_resource_count(device_t dev, int type, int rid) 2378{ 2379 u_long start, count; 2380 int error; 2381 2382 error = BUS_GET_RESOURCE(device_get_parent(dev), dev, type, rid, 2383 &start, &count); 2384 if (error) 2385 return (0); 2386 return (count); 2387} 2388 2389void 2390bus_delete_resource(device_t dev, int type, int rid) 2391{ 2392 BUS_DELETE_RESOURCE(device_get_parent(dev), dev, type, rid); 2393} 2394 2395int 2396bus_child_present(device_t child) 2397{ 2398 return (BUS_CHILD_PRESENT(device_get_parent(child), child)); 2399} 2400 2401int 2402bus_child_pnpinfo_str(device_t child, char *buf, size_t buflen) 2403{ 2404 device_t parent; 2405 2406 parent = device_get_parent(child); 2407 if (parent == NULL) { 2408 *buf = '\0'; 2409 return (0); 2410 } 2411 return (BUS_CHILD_PNPINFO_STR(parent, child, buf, buflen)); 2412} 2413 2414int 2415bus_child_location_str(device_t child, char *buf, size_t buflen) 2416{ 2417 device_t parent; 2418 2419 parent = device_get_parent(child); 2420 if (parent == NULL) { 2421 *buf = '\0'; 2422 return (0); 2423 } 2424 return (BUS_CHILD_LOCATION_STR(parent, child, buf, buflen)); 2425} 2426 2427static int 2428root_print_child(device_t dev, device_t child) 2429{ 2430 int retval = 0; 2431 2432 retval += bus_print_child_header(dev, child); 2433 retval += printf("\n"); 2434 2435 return (retval); 2436} 2437 2438static int 2439root_setup_intr(device_t dev, device_t child, driver_intr_t *intr, void *arg, 2440 void **cookiep) 2441{ 2442 /* 2443 * If an interrupt mapping gets to here something bad has happened. 2444 */ 2445 panic("root_setup_intr"); 2446} 2447 2448/* 2449 * If we get here, assume that the device is permanant and really is 2450 * present in the system. Removable bus drivers are expected to intercept 2451 * this call long before it gets here. We return -1 so that drivers that 2452 * really care can check vs -1 or some ERRNO returned higher in the food 2453 * chain. 2454 */ 2455static int 2456root_child_present(device_t dev, device_t child) 2457{ 2458 return (-1); 2459} 2460 2461static kobj_method_t root_methods[] = { 2462 /* Device interface */ 2463 KOBJMETHOD(device_shutdown, bus_generic_shutdown), 2464 KOBJMETHOD(device_suspend, bus_generic_suspend), 2465 KOBJMETHOD(device_resume, bus_generic_resume), 2466 2467 /* Bus interface */ 2468 KOBJMETHOD(bus_print_child, root_print_child), 2469 KOBJMETHOD(bus_read_ivar, bus_generic_read_ivar), 2470 KOBJMETHOD(bus_write_ivar, bus_generic_write_ivar), 2471 KOBJMETHOD(bus_setup_intr, root_setup_intr), 2472 KOBJMETHOD(bus_child_present, root_child_present), 2473 2474 { 0, 0 } 2475}; 2476 2477static driver_t root_driver = { 2478 "root", 2479 root_methods, 2480 1, /* no softc */ 2481}; 2482 2483device_t root_bus; 2484devclass_t root_devclass; 2485 2486static int 2487root_bus_module_handler(module_t mod, int what, void* arg) 2488{ 2489 switch (what) { 2490 case MOD_LOAD: 2491 TAILQ_INIT(&bus_data_devices); 2492 kobj_class_compile((kobj_class_t) &root_driver); 2493 root_bus = make_device(NULL, "root", 0); 2494 root_bus->desc = "System root bus"; 2495 kobj_init((kobj_t) root_bus, (kobj_class_t) &root_driver); 2496 root_bus->driver = &root_driver; 2497 root_bus->state = DS_ATTACHED; 2498 root_devclass = devclass_find_internal("root", 0, FALSE); 2499 devinit(); 2500 return (0); 2501 2502 case MOD_SHUTDOWN: 2503 device_shutdown(root_bus); 2504 return (0); 2505 } 2506 2507 return (0); 2508} 2509 2510static moduledata_t root_bus_mod = { 2511 "rootbus", 2512 root_bus_module_handler, 2513 0 2514}; 2515DECLARE_MODULE(rootbus, root_bus_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST); 2516 2517void 2518root_bus_configure(void) 2519{ 2520 device_t dev; 2521 2522 PDEBUG((".")); 2523 2524 TAILQ_FOREACH(dev, &root_bus->children, link) { 2525 device_probe_and_attach(dev); 2526 } 2527} 2528 2529int 2530driver_module_handler(module_t mod, int what, void *arg) 2531{ 2532 int error; 2533 struct driver_module_data *dmd; 2534 devclass_t bus_devclass; 2535 kobj_class_t driver; 2536 2537 dmd = (struct driver_module_data *)arg; 2538 bus_devclass = devclass_find_internal(dmd->dmd_busname, 0, TRUE); 2539 error = 0; 2540 2541 switch (what) { 2542 case MOD_LOAD: 2543 if (dmd->dmd_chainevh) 2544 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg); 2545 2546 driver = dmd->dmd_driver; 2547 PDEBUG(("Loading module: driver %s on bus %s", 2548 DRIVERNAME(driver), dmd->dmd_busname)); 2549 error = devclass_add_driver(bus_devclass, driver); 2550 if (error) 2551 break; 2552 2553 /* 2554 * If the driver has any base classes, make the 2555 * devclass inherit from the devclass of the driver's 2556 * first base class. This will allow the system to 2557 * search for drivers in both devclasses for children 2558 * of a device using this driver. 2559 */ 2560 if (driver->baseclasses) { 2561 const char *parentname; 2562 parentname = driver->baseclasses[0]->name; 2563 *dmd->dmd_devclass = 2564 devclass_find_internal(driver->name, 2565 parentname, TRUE); 2566 } else { 2567 *dmd->dmd_devclass = 2568 devclass_find_internal(driver->name, 0, TRUE); 2569 } 2570 break; 2571 2572 case MOD_UNLOAD: 2573 PDEBUG(("Unloading module: driver %s from bus %s", 2574 DRIVERNAME(dmd->dmd_driver), 2575 dmd->dmd_busname)); 2576 error = devclass_delete_driver(bus_devclass, 2577 dmd->dmd_driver); 2578 2579 if (!error && dmd->dmd_chainevh) 2580 error = dmd->dmd_chainevh(mod,what,dmd->dmd_chainarg); 2581 break; 2582 } 2583 2584 return (error); 2585} 2586 2587#ifdef BUS_DEBUG 2588 2589/* the _short versions avoid iteration by not calling anything that prints 2590 * more than oneliners. I love oneliners. 2591 */ 2592 2593static void 2594print_device_short(device_t dev, int indent) 2595{ 2596 if (!dev) 2597 return; 2598 2599 indentprintf(("device %d: <%s> %sparent,%schildren,%s%s%s%s,%sivars,%ssoftc,busy=%d\n", 2600 dev->unit, dev->desc, 2601 (dev->parent? "":"no "), 2602 (TAILQ_EMPTY(&dev->children)? "no ":""), 2603 (dev->flags&DF_ENABLED? "enabled,":"disabled,"), 2604 (dev->flags&DF_FIXEDCLASS? "fixed,":""), 2605 (dev->flags&DF_WILDCARD? "wildcard,":""), 2606 (dev->flags&DF_DESCMALLOCED? "descmalloced,":""), 2607 (dev->ivars? "":"no "), 2608 (dev->softc? "":"no "), 2609 dev->busy)); 2610} 2611 2612static void 2613print_device(device_t dev, int indent) 2614{ 2615 if (!dev) 2616 return; 2617 2618 print_device_short(dev, indent); 2619 2620 indentprintf(("Parent:\n")); 2621 print_device_short(dev->parent, indent+1); 2622 indentprintf(("Driver:\n")); 2623 print_driver_short(dev->driver, indent+1); 2624 indentprintf(("Devclass:\n")); 2625 print_devclass_short(dev->devclass, indent+1); 2626} 2627 2628void 2629print_device_tree_short(device_t dev, int indent) 2630/* print the device and all its children (indented) */ 2631{ 2632 device_t child; 2633 2634 if (!dev) 2635 return; 2636 2637 print_device_short(dev, indent); 2638 2639 TAILQ_FOREACH(child, &dev->children, link) { 2640 print_device_tree_short(child, indent+1); 2641 } 2642} 2643 2644void 2645print_device_tree(device_t dev, int indent) 2646/* print the device and all its children (indented) */ 2647{ 2648 device_t child; 2649 2650 if (!dev) 2651 return; 2652 2653 print_device(dev, indent); 2654 2655 TAILQ_FOREACH(child, &dev->children, link) { 2656 print_device_tree(child, indent+1); 2657 } 2658} 2659 2660static void 2661print_driver_short(driver_t *driver, int indent) 2662{ 2663 if (!driver) 2664 return; 2665 2666 indentprintf(("driver %s: softc size = %zd\n", 2667 driver->name, driver->size)); 2668} 2669 2670static void 2671print_driver(driver_t *driver, int indent) 2672{ 2673 if (!driver) 2674 return; 2675 2676 print_driver_short(driver, indent); 2677} 2678 2679 2680static void 2681print_driver_list(driver_list_t drivers, int indent) 2682{ 2683 driverlink_t driver; 2684 2685 TAILQ_FOREACH(driver, &drivers, link) { 2686 print_driver(driver->driver, indent); 2687 } 2688} 2689 2690static void 2691print_devclass_short(devclass_t dc, int indent) 2692{ 2693 if ( !dc ) 2694 return; 2695 2696 indentprintf(("devclass %s: max units = %d\n", dc->name, dc->maxunit)); 2697} 2698 2699static void 2700print_devclass(devclass_t dc, int indent) 2701{ 2702 int i; 2703 2704 if ( !dc ) 2705 return; 2706 2707 print_devclass_short(dc, indent); 2708 indentprintf(("Drivers:\n")); 2709 print_driver_list(dc->drivers, indent+1); 2710 2711 indentprintf(("Devices:\n")); 2712 for (i = 0; i < dc->maxunit; i++) 2713 if (dc->devices[i]) 2714 print_device(dc->devices[i], indent+1); 2715} 2716 2717void 2718print_devclass_list_short(void) 2719{ 2720 devclass_t dc; 2721 2722 printf("Short listing of devclasses, drivers & devices:\n"); 2723 TAILQ_FOREACH(dc, &devclasses, link) { 2724 print_devclass_short(dc, 0); 2725 } 2726} 2727 2728void 2729print_devclass_list(void) 2730{ 2731 devclass_t dc; 2732 2733 printf("Full listing of devclasses, drivers & devices:\n"); 2734 TAILQ_FOREACH(dc, &devclasses, link) { 2735 print_devclass(dc, 0); 2736 } 2737} 2738 2739#endif 2740 2741/* 2742 * User-space access to the device tree. 2743 * 2744 * We implement a small set of nodes: 2745 * 2746 * hw.bus Single integer read method to obtain the 2747 * current generation count. 2748 * hw.bus.devices Reads the entire device tree in flat space. 2749 * hw.bus.rman Resource manager interface 2750 * 2751 * We might like to add the ability to scan devclasses and/or drivers to 2752 * determine what else is currently loaded/available. 2753 */ 2754 2755static int 2756sysctl_bus(SYSCTL_HANDLER_ARGS) 2757{ 2758 struct u_businfo ubus; 2759 2760 ubus.ub_version = BUS_USER_VERSION; 2761 ubus.ub_generation = bus_data_generation; 2762 2763 return (SYSCTL_OUT(req, &ubus, sizeof(ubus))); 2764} 2765SYSCTL_NODE(_hw_bus, OID_AUTO, info, CTLFLAG_RW, sysctl_bus, 2766 "bus-related data"); 2767 2768static int 2769sysctl_devices(SYSCTL_HANDLER_ARGS) 2770{ 2771 int *name = (int *)arg1; 2772 u_int namelen = arg2; 2773 int index; 2774 struct device *dev; 2775 struct u_device udev; /* XXX this is a bit big */ 2776 int error; 2777 2778 if (namelen != 2) 2779 return (EINVAL); 2780 2781 if (bus_data_generation_check(name[0])) 2782 return (EINVAL); 2783 2784 index = name[1]; 2785 2786 /* 2787 * Scan the list of devices, looking for the requested index. 2788 */ 2789 TAILQ_FOREACH(dev, &bus_data_devices, devlink) { 2790 if (index-- == 0) 2791 break; 2792 } 2793 if (dev == NULL) 2794 return (ENOENT); 2795 2796 /* 2797 * Populate the return array. 2798 */ 2799 udev.dv_handle = (uintptr_t)dev; 2800 udev.dv_parent = (uintptr_t)dev->parent; 2801 if (dev->nameunit == NULL) 2802 udev.dv_name[0] = '\0'; 2803 else 2804 strlcpy(udev.dv_name, dev->nameunit, sizeof(udev.dv_name)); 2805 2806 if (dev->desc == NULL) 2807 udev.dv_desc[0] = '\0'; 2808 else 2809 strlcpy(udev.dv_desc, dev->desc, sizeof(udev.dv_desc)); 2810 if (dev->driver == NULL || dev->driver->name == NULL) 2811 udev.dv_drivername[0] = '\0'; 2812 else 2813 strlcpy(udev.dv_drivername, dev->driver->name, 2814 sizeof(udev.dv_drivername)); 2815 udev.dv_pnpinfo[0] = '\0'; 2816 udev.dv_location[0] = '\0'; 2817 bus_child_pnpinfo_str(dev, udev.dv_pnpinfo, sizeof(udev.dv_pnpinfo)); 2818 bus_child_location_str(dev, udev.dv_location, sizeof(udev.dv_location)); 2819 udev.dv_devflags = dev->devflags; 2820 udev.dv_flags = dev->flags; 2821 udev.dv_state = dev->state; 2822 error = SYSCTL_OUT(req, &udev, sizeof(udev)); 2823 return (error); 2824} 2825 2826SYSCTL_NODE(_hw_bus, OID_AUTO, devices, CTLFLAG_RD, sysctl_devices, 2827 "system device tree"); 2828 2829/* 2830 * Sysctl interface for scanning the resource lists. 2831 * 2832 * We take two input parameters; the index into the list of resource 2833 * managers, and the resource offset into the list. 2834 */ 2835static int 2836sysctl_rman(SYSCTL_HANDLER_ARGS) 2837{ 2838 int *name = (int *)arg1; 2839 u_int namelen = arg2; 2840 int rman_idx, res_idx; 2841 struct rman *rm; 2842 struct resource *res; 2843 struct u_rman urm; 2844 struct u_resource ures; 2845 int error; 2846 2847 if (namelen != 3) 2848 return (EINVAL); 2849 2850 if (bus_data_generation_check(name[0])) 2851 return (EINVAL); 2852 rman_idx = name[1]; 2853 res_idx = name[2]; 2854 2855 /* 2856 * Find the indexed resource manager 2857 */ 2858 TAILQ_FOREACH(rm, &rman_head, rm_link) { 2859 if (rman_idx-- == 0) 2860 break; 2861 } 2862 if (rm == NULL) 2863 return (ENOENT); 2864 2865 /* 2866 * If the resource index is -1, we want details on the 2867 * resource manager. 2868 */ 2869 if (res_idx == -1) { 2870 urm.rm_handle = (uintptr_t)rm; 2871 strlcpy(urm.rm_descr, rm->rm_descr, RM_TEXTLEN); 2872 urm.rm_start = rm->rm_start; 2873 urm.rm_size = rm->rm_end - rm->rm_start + 1; 2874 urm.rm_type = rm->rm_type; 2875 2876 error = SYSCTL_OUT(req, &urm, sizeof(urm)); 2877 return (error); 2878 } 2879 2880 /* 2881 * Find the indexed resource and return it. 2882 */ 2883 TAILQ_FOREACH(res, &rm->rm_list, r_link) { 2884 if (res_idx-- == 0) { 2885 ures.r_handle = (uintptr_t)res; 2886 ures.r_parent = (uintptr_t)res->r_rm; 2887 ures.r_device = (uintptr_t)res->r_dev; 2888 if (res->r_dev != NULL) { 2889 if (device_get_name(res->r_dev) != NULL) { 2890 snprintf(ures.r_devname, RM_TEXTLEN, 2891 "%s%d", 2892 device_get_name(res->r_dev), 2893 device_get_unit(res->r_dev)); 2894 } else { 2895 strlcpy(ures.r_devname, "nomatch", 2896 RM_TEXTLEN); 2897 } 2898 } else { 2899 ures.r_devname[0] = '\0'; 2900 } 2901 ures.r_start = res->r_start; 2902 ures.r_size = res->r_end - res->r_start + 1; 2903 ures.r_flags = res->r_flags; 2904 2905 error = SYSCTL_OUT(req, &ures, sizeof(ures)); 2906 return (error); 2907 } 2908 } 2909 return (ENOENT); 2910} 2911 2912SYSCTL_NODE(_hw_bus, OID_AUTO, rman, CTLFLAG_RD, sysctl_rman, 2913 "kernel resource manager"); 2914 2915int 2916bus_data_generation_check(int generation) 2917{ 2918 if (generation != bus_data_generation) 2919 return (1); 2920 2921 /* XXX generate optimised lists here? */ 2922 return (0); 2923} 2924 2925void 2926bus_data_generation_update(void) 2927{ 2928 bus_data_generation++; 2929} 2930