1 /*- 2 * Copyright (c) 2015 Landon Fuller <landon@landonf.org> 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 * without modification. 11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13 * redistribution must be conditioned upon including a substantially 14 * similar Disclaimer requirement for further binary redistribution. 15 * 16 * NO WARRANTY 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27 * THE POSSIBILITY OF SUCH DAMAGES. 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 /* 34 * Broadcom Home Networking Division (HND) Bus Driver. 35 * 36 * The Broadcom HND family of devices consists of both SoCs and host-connected 37 * networking chipsets containing a common family of Broadcom IP cores, 38 * including an integrated MIPS and/or ARM cores. 39 * 40 * HND devices expose a nearly identical interface whether accessible over a 41 * native SoC interconnect, or when connected via a host interface such as 42 * PCIe. As a result, the majority of hardware support code should be re-usable 43 * across host drivers for HND networking chipsets, as well as FreeBSD support 44 * for Broadcom MIPS/ARM HND SoCs. 45 * 46 * Earlier HND models used the siba(4) on-chip interconnect, while later models 47 * use bcma(4); the programming model is almost entirely independent 48 * of the actual underlying interconect. 49 */ 50 51 #include <sys/param.h> 52 #include <sys/kernel.h> 53 #include <sys/bus.h> 54 #include <sys/module.h> 55 #include <sys/systm.h> 56 57 #include <machine/bus.h> 58 #include <sys/rman.h> 59 #include <machine/resource.h> 60 61 #include "nvram/bhnd_nvram.h" 62 63 #include "bhnd_chipc_if.h" 64 #include "bhnd_nvram_if.h" 65 66 #include "bhnd.h" 67 #include "bhndvar.h" 68 69 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); 70 71 /** 72 * bhnd_generic_probe_nomatch() reporting configuration. 73 */ 74 static const struct bhnd_nomatch { 75 uint16_t vendor; /**< core designer */ 76 uint16_t device; /**< core id */ 77 bool if_verbose; /**< print when bootverbose is set. */ 78 } bhnd_nomatch_table[] = { 79 { BHND_MFGID_ARM, BHND_COREID_OOB_ROUTER, true }, 80 { BHND_MFGID_ARM, BHND_COREID_EROM, true }, 81 { BHND_MFGID_ARM, BHND_COREID_PL301, true }, 82 { BHND_MFGID_ARM, BHND_COREID_APB_BRIDGE, true }, 83 { BHND_MFGID_ARM, BHND_COREID_AXI_UNMAPPED, false }, 84 85 { BHND_MFGID_INVALID, BHND_COREID_INVALID, false } 86 }; 87 88 static device_t find_nvram_child(device_t dev); 89 90 static int compare_ascending_probe_order(const void *lhs, 91 const void *rhs); 92 static int compare_descending_probe_order(const void *lhs, 93 const void *rhs); 94 95 /** 96 * Default bhnd(4) bus driver implementation of DEVICE_ATTACH(). 97 * 98 * This implementation calls device_probe_and_attach() for each of the device's 99 * children, in bhnd probe order. 100 */ 101 int 102 bhnd_generic_attach(device_t dev) 103 { 104 device_t *devs; 105 int ndevs; 106 int error; 107 108 if (device_is_attached(dev)) 109 return (EBUSY); 110 111 if ((error = device_get_children(dev, &devs, &ndevs))) 112 return (error); 113 114 qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 115 for (int i = 0; i < ndevs; i++) { 116 device_t child = devs[i]; 117 device_probe_and_attach(child); 118 } 119 120 free(devs, M_TEMP); 121 return (0); 122 } 123 124 /** 125 * Default bhnd(4) bus driver implementation of DEVICE_DETACH(). 126 * 127 * This implementation calls device_detach() for each of the the device's 128 * children, in reverse bhnd probe order, terminating if any call to 129 * device_detach() fails. 130 */ 131 int 132 bhnd_generic_detach(device_t dev) 133 { 134 device_t *devs; 135 int ndevs; 136 int error; 137 138 if (!device_is_attached(dev)) 139 return (EBUSY); 140 141 if ((error = device_get_children(dev, &devs, &ndevs))) 142 return (error); 143 144 /* Detach in the reverse of attach order */ 145 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 146 for (int i = 0; i < ndevs; i++) { 147 device_t child = devs[i]; 148 149 /* Terminate on first error */ 150 if ((error = device_detach(child))) 151 goto cleanup; 152 } 153 154 cleanup: 155 free(devs, M_TEMP); 156 return (error); 157 } 158 159 /** 160 * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN(). 161 * 162 * This implementation calls device_shutdown() for each of the device's 163 * children, in reverse bhnd probe order, terminating if any call to 164 * device_shutdown() fails. 165 */ 166 int 167 bhnd_generic_shutdown(device_t dev) 168 { 169 device_t *devs; 170 int ndevs; 171 int error; 172 173 if (!device_is_attached(dev)) 174 return (EBUSY); 175 176 if ((error = device_get_children(dev, &devs, &ndevs))) 177 return (error); 178 179 /* Shutdown in the reverse of attach order */ 180 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 181 for (int i = 0; i < ndevs; i++) { 182 device_t child = devs[i]; 183 184 /* Terminate on first error */ 185 if ((error = device_shutdown(child))) 186 goto cleanup; 187 } 188 189 cleanup: 190 free(devs, M_TEMP); 191 return (error); 192 } 193 194 /** 195 * Default bhnd(4) bus driver implementation of DEVICE_RESUME(). 196 * 197 * This implementation calls BUS_RESUME_CHILD() for each of the device's 198 * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD() 199 * fails. 200 */ 201 int 202 bhnd_generic_resume(device_t dev) 203 { 204 device_t *devs; 205 int ndevs; 206 int error; 207 208 if (!device_is_attached(dev)) 209 return (EBUSY); 210 211 if ((error = device_get_children(dev, &devs, &ndevs))) 212 return (error); 213 214 qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 215 for (int i = 0; i < ndevs; i++) { 216 device_t child = devs[i]; 217 218 /* Terminate on first error */ 219 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child))) 220 goto cleanup; 221 } 222 223 cleanup: 224 free(devs, M_TEMP); 225 return (error); 226 } 227 228 /** 229 * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND(). 230 * 231 * This implementation calls BUS_SUSPEND_CHILD() for each of the device's 232 * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD() 233 * fails, the suspend operation is terminated and any devices that were 234 * suspended are resumed immediately by calling their BUS_RESUME_CHILD() 235 * methods. 236 */ 237 int 238 bhnd_generic_suspend(device_t dev) 239 { 240 device_t *devs; 241 int ndevs; 242 int error; 243 244 if (!device_is_attached(dev)) 245 return (EBUSY); 246 247 if ((error = device_get_children(dev, &devs, &ndevs))) 248 return (error); 249 250 /* Suspend in the reverse of attach order */ 251 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 252 for (int i = 0; i < ndevs; i++) { 253 device_t child = devs[i]; 254 error = BUS_SUSPEND_CHILD(device_get_parent(child), child); 255 256 /* On error, resume suspended devices and then terminate */ 257 if (error) { 258 for (int j = 0; j < i; j++) { 259 BUS_RESUME_CHILD(device_get_parent(devs[j]), 260 devs[j]); 261 } 262 263 goto cleanup; 264 } 265 } 266 267 cleanup: 268 free(devs, M_TEMP); 269 return (error); 270 } 271 272 /* 273 * Ascending comparison of bhnd device's probe order. 274 */ 275 static int 276 compare_ascending_probe_order(const void *lhs, const void *rhs) 277 { 278 device_t ldev, rdev; 279 int lorder, rorder; 280 281 ldev = (*(const device_t *) lhs); 282 rdev = (*(const device_t *) rhs); 283 284 lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev); 285 rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev); 286 287 if (lorder < rorder) { 288 return (-1); 289 } else if (lorder > rorder) { 290 return (1); 291 } else { 292 return (0); 293 } 294 } 295 296 /* 297 * Descending comparison of bhnd device's probe order. 298 */ 299 static int 300 compare_descending_probe_order(const void *lhs, const void *rhs) 301 { 302 return (compare_ascending_probe_order(rhs, lhs)); 303 } 304 305 /** 306 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER(). 307 * 308 * This implementation determines probe ordering based on the device's class 309 * and other properties, including whether the device is serving as a host 310 * bridge. 311 */ 312 int 313 bhnd_generic_get_probe_order(device_t dev, device_t child) 314 { 315 switch (bhnd_get_class(child)) { 316 case BHND_DEVCLASS_CC: 317 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST); 318 319 case BHND_DEVCLASS_CC_B: 320 /* fall through */ 321 case BHND_DEVCLASS_PMU: 322 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY); 323 324 case BHND_DEVCLASS_SOC_ROUTER: 325 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE); 326 327 case BHND_DEVCLASS_SOC_BRIDGE: 328 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST); 329 330 case BHND_DEVCLASS_CPU: 331 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST); 332 333 case BHND_DEVCLASS_RAM: 334 /* fall through */ 335 case BHND_DEVCLASS_MEMC: 336 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY); 337 338 case BHND_DEVCLASS_NVRAM: 339 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY); 340 341 case BHND_DEVCLASS_PCI: 342 case BHND_DEVCLASS_PCIE: 343 case BHND_DEVCLASS_PCCARD: 344 case BHND_DEVCLASS_ENET: 345 case BHND_DEVCLASS_ENET_MAC: 346 case BHND_DEVCLASS_ENET_PHY: 347 case BHND_DEVCLASS_WLAN: 348 case BHND_DEVCLASS_WLAN_MAC: 349 case BHND_DEVCLASS_WLAN_PHY: 350 case BHND_DEVCLASS_EROM: 351 case BHND_DEVCLASS_OTHER: 352 case BHND_DEVCLASS_INVALID: 353 if (bhnd_find_hostb_device(dev) == child) 354 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY); 355 356 return (BHND_PROBE_DEFAULT); 357 default: 358 return (BHND_PROBE_DEFAULT); 359 } 360 } 361 362 /** 363 * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID(). 364 * 365 * This implementation assumes that port and region numbers are 0-indexed and 366 * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and 367 * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall 368 * within the defined range. 369 */ 370 static bool 371 bhnd_generic_is_region_valid(device_t dev, device_t child, 372 bhnd_port_type type, u_int port, u_int region) 373 { 374 if (port >= bhnd_get_port_count(child, type)) 375 return (false); 376 377 if (region >= bhnd_get_region_count(child, type, port)) 378 return (false); 379 380 return (true); 381 } 382 383 /** 384 * Find an NVRAM child device on @p dev, if any. 385 * 386 * @retval device_t An NVRAM device. 387 * @retval NULL If no NVRAM device is found. 388 */ 389 static device_t 390 find_nvram_child(device_t dev) 391 { 392 device_t chipc, nvram; 393 394 /* Look for a directly-attached NVRAM child */ 395 nvram = device_find_child(dev, "bhnd_nvram", 0); 396 if (nvram != NULL) 397 return (nvram); 398 399 /* Remaining checks are only applicable when searching a bhnd(4) 400 * bus. */ 401 if (device_get_devclass(dev) != bhnd_devclass) 402 return (NULL); 403 404 /* Look for a ChipCommon device */ 405 if ((chipc = bhnd_find_child(dev, BHND_DEVCLASS_CC, -1)) != NULL) { 406 bhnd_nvram_src_t src; 407 408 /* Query the NVRAM source and determine whether it's 409 * accessible via the ChipCommon device */ 410 src = BHND_CHIPC_NVRAM_SRC(chipc); 411 if (BHND_NVRAM_SRC_CC(src)) 412 return (chipc); 413 } 414 415 /* Not found */ 416 return (NULL); 417 } 418 419 /** 420 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_NVRAM_VAR(). 421 * 422 * This implementation searches @p dev for a usable NVRAM child device: 423 * - The first child device implementing the bhnd_nvram devclass is 424 * returned, otherwise 425 * - If @p dev is a bhnd(4) bus, a ChipCommon core that advertises an 426 * attached NVRAM source. 427 * 428 * If no usable child device is found on @p dev, the request is delegated to 429 * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev. 430 */ 431 static int 432 bhnd_generic_get_nvram_var(device_t dev, device_t child, const char *name, 433 void *buf, size_t *size) 434 { 435 device_t nvram; 436 437 /* Try to find an NVRAM device applicable to @p child */ 438 if ((nvram = find_nvram_child(dev)) == NULL) 439 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child, 440 name, buf, size)); 441 442 return BHND_NVRAM_GETVAR(nvram, name, buf, size); 443 } 444 445 /** 446 * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD(). 447 * 448 * This implementation requests the device's struct resource_list via 449 * BUS_GET_RESOURCE_LIST. 450 */ 451 int 452 bhnd_generic_print_child(device_t dev, device_t child) 453 { 454 struct resource_list *rl; 455 int retval = 0; 456 457 retval += bus_print_child_header(dev, child); 458 459 rl = BUS_GET_RESOURCE_LIST(dev, child); 460 if (rl != NULL) { 461 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, 462 "%#jx"); 463 } 464 465 retval += printf(" at core %u", bhnd_get_core_index(child)); 466 467 retval += bus_print_child_domain(dev, child); 468 retval += bus_print_child_footer(dev, child); 469 470 return (retval); 471 } 472 473 /** 474 * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH(). 475 * 476 * This implementation requests the device's struct resource_list via 477 * BUS_GET_RESOURCE_LIST. 478 */ 479 void 480 bhnd_generic_probe_nomatch(device_t dev, device_t child) 481 { 482 struct resource_list *rl; 483 const struct bhnd_nomatch *nm; 484 bool report; 485 486 /* Fetch reporting configuration for this device */ 487 report = true; 488 for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) { 489 if (nm->vendor != bhnd_get_vendor(child)) 490 continue; 491 492 if (nm->device != bhnd_get_device(child)) 493 continue; 494 495 report = false; 496 if (bootverbose && nm->if_verbose) 497 report = true; 498 break; 499 } 500 501 if (!report) 502 return; 503 504 /* Print the non-matched device info */ 505 device_printf(dev, "<%s %s>", bhnd_get_vendor_name(child), 506 bhnd_get_device_name(child)); 507 508 rl = BUS_GET_RESOURCE_LIST(dev, child); 509 if (rl != NULL) 510 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); 511 512 printf(" at core %u (no driver attached)\n", 513 bhnd_get_core_index(child)); 514 } 515 516 /** 517 * Default implementation of BUS_CHILD_PNPINFO_STR(). 518 */ 519 static int 520 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf, 521 size_t buflen) 522 { 523 if (device_get_parent(child) != dev) { 524 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child, 525 buf, buflen)); 526 } 527 528 snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx", 529 bhnd_get_vendor(child), bhnd_get_device(child), 530 bhnd_get_hwrev(child)); 531 532 return (0); 533 } 534 535 /** 536 * Default implementation of BUS_CHILD_LOCATION_STR(). 537 */ 538 static int 539 bhnd_child_location_str(device_t dev, device_t child, char *buf, 540 size_t buflen) 541 { 542 bhnd_addr_t addr; 543 bhnd_size_t size; 544 545 if (device_get_parent(child) != dev) { 546 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child, 547 buf, buflen)); 548 } 549 550 551 if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) { 552 /* No device default port/region */ 553 if (buflen > 0) 554 *buf = '\0'; 555 return (0); 556 } 557 558 snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr); 559 return (0); 560 } 561 562 /** 563 * Helper function for implementing BUS_SUSPEND_CHILD(). 564 * 565 * TODO: Power management 566 * 567 * If @p child is not a direct child of @p dev, suspension is delegated to 568 * the @p dev parent. 569 */ 570 int 571 bhnd_generic_suspend_child(device_t dev, device_t child) 572 { 573 if (device_get_parent(child) != dev) 574 BUS_SUSPEND_CHILD(device_get_parent(dev), child); 575 576 return bus_generic_suspend_child(dev, child); 577 } 578 579 /** 580 * Helper function for implementing BUS_RESUME_CHILD(). 581 * 582 * TODO: Power management 583 * 584 * If @p child is not a direct child of @p dev, suspension is delegated to 585 * the @p dev parent. 586 */ 587 int 588 bhnd_generic_resume_child(device_t dev, device_t child) 589 { 590 if (device_get_parent(child) != dev) 591 BUS_RESUME_CHILD(device_get_parent(dev), child); 592 593 return bus_generic_resume_child(dev, child); 594 } 595 596 /* 597 * Delegate all indirect I/O to the parent device. When inherited by 598 * non-bridged bus implementations, resources will never be marked as 599 * indirect, and these methods should never be called. 600 */ 601 #define BHND_IO_READ(_type, _name, _method) \ 602 static _type \ 603 bhnd_read_ ## _name (device_t dev, device_t child, \ 604 struct bhnd_resource *r, bus_size_t offset) \ 605 { \ 606 return (BHND_BUS_READ_ ## _method( \ 607 device_get_parent(dev), child, r, offset)); \ 608 } 609 610 #define BHND_IO_WRITE(_type, _name, _method) \ 611 static void \ 612 bhnd_write_ ## _name (device_t dev, device_t child, \ 613 struct bhnd_resource *r, bus_size_t offset, _type value) \ 614 { \ 615 return (BHND_BUS_WRITE_ ## _method( \ 616 device_get_parent(dev), child, r, offset, \ 617 value)); \ 618 } 619 620 #define BHND_IO_MULTI(_type, _rw, _name, _method) \ 621 static void \ 622 bhnd_ ## _rw ## _multi_ ## _name (device_t dev, device_t child, \ 623 struct bhnd_resource *r, bus_size_t offset, _type *datap, \ 624 bus_size_t count) \ 625 { \ 626 BHND_BUS_ ## _method(device_get_parent(dev), child, r, \ 627 offset, datap, count); \ 628 } 629 630 #define BHND_IO_METHODS(_type, _size) \ 631 BHND_IO_READ(_type, _size, _size) \ 632 BHND_IO_WRITE(_type, _size, _size) \ 633 \ 634 BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \ 635 BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \ 636 \ 637 BHND_IO_MULTI(_type, read, _size, READ_MULTI_ ## _size) \ 638 BHND_IO_MULTI(_type, write, _size, WRITE_MULTI_ ## _size) \ 639 \ 640 BHND_IO_MULTI(_type, read, stream_ ## _size, \ 641 READ_MULTI_STREAM_ ## _size) \ 642 BHND_IO_MULTI(_type, write, stream_ ## _size, \ 643 WRITE_MULTI_STREAM_ ## _size) \ 644 645 BHND_IO_METHODS(uint8_t, 1); 646 BHND_IO_METHODS(uint16_t, 2); 647 BHND_IO_METHODS(uint32_t, 4); 648 649 static void 650 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r, 651 bus_size_t offset, bus_size_t length, int flags) 652 { 653 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length, 654 flags); 655 } 656 657 static device_method_t bhnd_methods[] = { 658 /* Device interface */ \ 659 DEVMETHOD(device_attach, bhnd_generic_attach), 660 DEVMETHOD(device_detach, bhnd_generic_detach), 661 DEVMETHOD(device_shutdown, bhnd_generic_shutdown), 662 DEVMETHOD(device_suspend, bhnd_generic_suspend), 663 DEVMETHOD(device_resume, bhnd_generic_resume), 664 665 /* Bus interface */ 666 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), 667 DEVMETHOD(bus_print_child, bhnd_generic_print_child), 668 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str), 669 DEVMETHOD(bus_child_location_str, bhnd_child_location_str), 670 671 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child), 672 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child), 673 674 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 675 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 676 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 677 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 678 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 679 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 680 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 681 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 682 683 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 684 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 685 DEVMETHOD(bus_config_intr, bus_generic_config_intr), 686 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr), 687 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr), 688 689 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), 690 691 /* BHND interface */ 692 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid), 693 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order), 694 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), 695 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), 696 DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_generic_get_nvram_var), 697 DEVMETHOD(bhnd_bus_read_1, bhnd_read_1), 698 DEVMETHOD(bhnd_bus_read_2, bhnd_read_2), 699 DEVMETHOD(bhnd_bus_read_4, bhnd_read_4), 700 DEVMETHOD(bhnd_bus_write_1, bhnd_write_1), 701 DEVMETHOD(bhnd_bus_write_2, bhnd_write_2), 702 DEVMETHOD(bhnd_bus_write_4, bhnd_write_4), 703 DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1), 704 DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2), 705 DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4), 706 DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1), 707 DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2), 708 DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4), 709 710 DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1), 711 DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2), 712 DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4), 713 DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1), 714 DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2), 715 DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4), 716 717 DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1), 718 DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2), 719 DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4), 720 DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1), 721 DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2), 722 DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4), 723 724 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), 725 726 DEVMETHOD_END 727 }; 728 729 devclass_t bhnd_devclass; /**< bhnd bus. */ 730 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */ 731 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */ 732 733 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc)); 734 MODULE_VERSION(bhnd, 1); 735