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 "bhnd.h" 62#include "bhndvar.h" 63 64MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); 65 66/** 67 * bhnd_generic_probe_nomatch() reporting configuration. 68 */ 69static const struct bhnd_nomatch { 70 uint16_t vendor; /**< core designer */ 71 uint16_t device; /**< core id */ 72 bool if_verbose; /**< print when bootverbose is set. */ 73} bhnd_nomatch_table[] = { 74 { BHND_MFGID_ARM, BHND_COREID_OOB_ROUTER, true }, 75 { BHND_MFGID_ARM, BHND_COREID_EROM, true }, 76 { BHND_MFGID_ARM, BHND_COREID_PL301, true }, 77 { BHND_MFGID_ARM, BHND_COREID_APB_BRIDGE, true }, 78 { BHND_MFGID_ARM, BHND_COREID_AXI_UNMAPPED, false }, 79 80 { BHND_MFGID_INVALID, BHND_COREID_INVALID, false } 81}; 82 83static int compare_ascending_probe_order(const void *lhs, 84 const void *rhs); 85static int compare_descending_probe_order(const void *lhs, 86 const void *rhs); 87 88/** 89 * Default bhnd(4) bus driver implementation of DEVICE_ATTACH(). 90 * 91 * This implementation calls device_probe_and_attach() for each of the device's 92 * children, in bhnd probe order. 93 */ 94int 95bhnd_generic_attach(device_t dev) 96{ 97 device_t *devs; 98 int ndevs; 99 int error; 100 101 if (device_is_attached(dev)) 102 return (EBUSY); 103 104 if ((error = device_get_children(dev, &devs, &ndevs))) 105 return (error); 106 107 qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 108 for (int i = 0; i < ndevs; i++) { 109 device_t child = devs[i]; 110 device_probe_and_attach(child); 111 } 112 113 free(devs, M_TEMP); 114 return (0); 115} 116 117/** 118 * Default bhnd(4) bus driver implementation of DEVICE_DETACH(). 119 * 120 * This implementation calls device_detach() for each of the device's 121 * children, in reverse bhnd probe order, terminating if any call to 122 * device_detach() fails. 123 */ 124int 125bhnd_generic_detach(device_t dev) 126{ 127 device_t *devs; 128 int ndevs; 129 int error; 130 131 if (!device_is_attached(dev)) 132 return (EBUSY); 133 134 if ((error = device_get_children(dev, &devs, &ndevs))) 135 return (error); 136 137 /* Detach in the reverse of attach order */ 138 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 139 for (int i = 0; i < ndevs; i++) { 140 device_t child = devs[i]; 141 142 /* Terminate on first error */ 143 if ((error = device_detach(child))) 144 goto cleanup; 145 } 146 147cleanup: 148 free(devs, M_TEMP); 149 return (error); 150} 151 152/** 153 * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN(). 154 * 155 * This implementation calls device_shutdown() for each of the device's 156 * children, in reverse bhnd probe order, terminating if any call to 157 * device_shutdown() fails. 158 */ 159int 160bhnd_generic_shutdown(device_t dev) 161{ 162 device_t *devs; 163 int ndevs; 164 int error; 165 166 if (!device_is_attached(dev)) 167 return (EBUSY); 168 169 if ((error = device_get_children(dev, &devs, &ndevs))) 170 return (error); 171 172 /* Shutdown in the reverse of attach order */ 173 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 174 for (int i = 0; i < ndevs; i++) { 175 device_t child = devs[i]; 176 177 /* Terminate on first error */ 178 if ((error = device_shutdown(child))) 179 goto cleanup; 180 } 181 182cleanup: 183 free(devs, M_TEMP); 184 return (error); 185} 186 187/** 188 * Default bhnd(4) bus driver implementation of DEVICE_RESUME(). 189 * 190 * This implementation calls BUS_RESUME_CHILD() for each of the device's 191 * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD() 192 * fails. 193 */ 194int 195bhnd_generic_resume(device_t dev) 196{ 197 device_t *devs; 198 int ndevs; 199 int error; 200 201 if (!device_is_attached(dev)) 202 return (EBUSY); 203 204 if ((error = device_get_children(dev, &devs, &ndevs))) 205 return (error); 206 207 qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 208 for (int i = 0; i < ndevs; i++) { 209 device_t child = devs[i]; 210 211 /* Terminate on first error */ 212 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child))) 213 goto cleanup; 214 } 215 216cleanup: 217 free(devs, M_TEMP); 218 return (error); 219} 220 221/** 222 * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND(). 223 * 224 * This implementation calls BUS_SUSPEND_CHILD() for each of the device's 225 * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD() 226 * fails, the suspend operation is terminated and any devices that were 227 * suspended are resumed immediately by calling their BUS_RESUME_CHILD() 228 * methods. 229 */ 230int 231bhnd_generic_suspend(device_t dev) 232{ 233 device_t *devs; 234 int ndevs; 235 int error; 236 237 if (!device_is_attached(dev)) 238 return (EBUSY); 239 240 if ((error = device_get_children(dev, &devs, &ndevs))) 241 return (error); 242 243 /* Suspend in the reverse of attach order */ 244 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 245 for (int i = 0; i < ndevs; i++) { 246 device_t child = devs[i]; 247 error = BUS_SUSPEND_CHILD(device_get_parent(child), child); 248 249 /* On error, resume suspended devices and then terminate */ 250 if (error) { 251 for (int j = 0; j < i; j++) { 252 BUS_RESUME_CHILD(device_get_parent(devs[j]), 253 devs[j]); 254 } 255 256 goto cleanup; 257 } 258 } 259 260cleanup: 261 free(devs, M_TEMP); 262 return (error); 263} 264 265/* 266 * Ascending comparison of bhnd device's probe order. 267 */ 268static int 269compare_ascending_probe_order(const void *lhs, const void *rhs) 270{ 271 device_t ldev, rdev; 272 int lorder, rorder; 273 274 ldev = (*(const device_t *) lhs); 275 rdev = (*(const device_t *) rhs); 276 277 lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev); 278 rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev); 279 280 if (lorder < rorder) { 281 return (-1); 282 } else if (lorder > rorder) { 283 return (1); 284 } else { 285 return (0); 286 } 287} 288 289/* 290 * Descending comparison of bhnd device's probe order. 291 */ 292static int 293compare_descending_probe_order(const void *lhs, const void *rhs) 294{ 295 return (compare_ascending_probe_order(rhs, lhs)); 296} 297 298/** 299 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER(). 300 * 301 * This implementation determines probe ordering based on the device's class 302 * and other properties, including whether the device is serving as a host 303 * bridge. 304 */ 305int 306bhnd_generic_get_probe_order(device_t dev, device_t child) 307{ 308 switch (bhnd_get_class(child)) { 309 case BHND_DEVCLASS_CC: 310 /* Must be early enough to provide NVRAM access to the 311 * host bridge */ 312 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST); 313 314 case BHND_DEVCLASS_CC_B: 315 /* fall through */ 316 case BHND_DEVCLASS_PMU: 317 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY); 318 319 case BHND_DEVCLASS_SOC_ROUTER: 320 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE); 321 322 case BHND_DEVCLASS_SOC_BRIDGE: 323 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST); 324 325 case BHND_DEVCLASS_CPU: 326 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST); 327 328 case BHND_DEVCLASS_RAM: 329 /* fall through */ 330 case BHND_DEVCLASS_MEMC: 331 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY); 332 333 case BHND_DEVCLASS_NVRAM: 334 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY); 335 336 case BHND_DEVCLASS_PCI: 337 case BHND_DEVCLASS_PCIE: 338 case BHND_DEVCLASS_PCCARD: 339 case BHND_DEVCLASS_ENET: 340 case BHND_DEVCLASS_ENET_MAC: 341 case BHND_DEVCLASS_ENET_PHY: 342 case BHND_DEVCLASS_WLAN: 343 case BHND_DEVCLASS_WLAN_MAC: 344 case BHND_DEVCLASS_WLAN_PHY: 345 case BHND_DEVCLASS_EROM: 346 case BHND_DEVCLASS_OTHER: 347 case BHND_DEVCLASS_INVALID: 348 if (bhnd_find_hostb_device(dev) == child) 349 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY); 350 351 return (BHND_PROBE_DEFAULT); 352 default: 353 return (BHND_PROBE_DEFAULT); 354 } 355} 356 357/** 358 * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID(). 359 * 360 * This implementation assumes that port and region numbers are 0-indexed and 361 * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and 362 * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall 363 * within the defined range. 364 */ 365static bool 366bhnd_generic_is_region_valid(device_t dev, device_t child, 367 bhnd_port_type type, u_int port, u_int region) 368{ 369 if (port >= bhnd_get_port_count(child, type)) 370 return (false); 371 372 if (region >= bhnd_get_region_count(child, type, port)) 373 return (false); 374 375 return (true); 376} 377 378/** 379 * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD(). 380 * 381 * This implementation requests the device's struct resource_list via 382 * BUS_GET_RESOURCE_LIST. 383 */ 384int 385bhnd_generic_print_child(device_t dev, device_t child) 386{ 387 struct resource_list *rl; 388 int retval = 0; 389 390 retval += bus_print_child_header(dev, child); 391 392 rl = BUS_GET_RESOURCE_LIST(dev, child); 393 if (rl != NULL) { 394 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, 395 "%#jx"); 396 } 397 398 retval += printf(" at core %u", bhnd_get_core_index(child)); 399 400 retval += bus_print_child_domain(dev, child); 401 retval += bus_print_child_footer(dev, child); 402 403 return (retval); 404} 405 406/** 407 * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH(). 408 * 409 * This implementation requests the device's struct resource_list via 410 * BUS_GET_RESOURCE_LIST. 411 */ 412void 413bhnd_generic_probe_nomatch(device_t dev, device_t child) 414{ 415 struct resource_list *rl; 416 const struct bhnd_nomatch *nm; 417 bool report; 418 419 /* Fetch reporting configuration for this device */ 420 report = true; 421 for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) { 422 if (nm->vendor != bhnd_get_vendor(child)) 423 continue; 424 425 if (nm->device != bhnd_get_device(child)) 426 continue; 427 428 report = false; 429 if (bootverbose && nm->if_verbose) 430 report = true; 431 break; 432 } 433 434 if (!report) 435 return; 436 437 /* Print the non-matched device info */ 438 device_printf(dev, "<%s %s>", bhnd_get_vendor_name(child), 439 bhnd_get_device_name(child)); 440 441 rl = BUS_GET_RESOURCE_LIST(dev, child); 442 if (rl != NULL) 443 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); 444 445 printf(" at core %u (no driver attached)\n", 446 bhnd_get_core_index(child)); 447} 448 449/** 450 * Default implementation of BUS_CHILD_PNPINFO_STR(). 451 */ 452static int 453bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf, 454 size_t buflen) 455{ 456 if (device_get_parent(child) != dev) { 457 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child, 458 buf, buflen)); 459 } 460 461 snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx", 462 bhnd_get_vendor(child), bhnd_get_device(child), 463 bhnd_get_hwrev(child)); 464 465 return (0); 466} 467 468/** 469 * Default implementation of BUS_CHILD_LOCATION_STR(). 470 */ 471static int 472bhnd_child_location_str(device_t dev, device_t child, char *buf, 473 size_t buflen) 474{ 475 bhnd_addr_t addr; 476 bhnd_size_t size; 477 478 if (device_get_parent(child) != dev) { 479 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child, 480 buf, buflen)); 481 } 482 483 484 if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) { 485 /* No device default port/region */ 486 if (buflen > 0) 487 *buf = '\0'; 488 return (0); 489 } 490 491 snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr); 492 return (0); 493} 494 495/** 496 * Default bhnd(4) bus driver implementation of BUS_ADD_CHILD(). 497 * 498 * This implementation manages internal bhnd(4) state, and must be called 499 * by subclassing drivers. 500 */ 501device_t 502bhnd_generic_add_child(device_t dev, u_int order, const char *name, int unit) 503{ 504 struct bhnd_devinfo *dinfo; 505 device_t child; 506 507 child = device_add_child_ordered(dev, order, name, unit); 508 if (child == NULL) 509 return (NULL); 510 511 if ((dinfo = BHND_BUS_ALLOC_DEVINFO(dev)) == NULL) { 512 device_delete_child(dev, child); 513 return (NULL); 514 } 515 516 device_set_ivars(child, dinfo); 517 518 /* Inform concrete bus driver. */ 519 BHND_BUS_CHILD_ADDED(dev, child); 520 521 return (child); 522} 523 524/** 525 * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED(). 526 * 527 * This implementation manages internal bhnd(4) state, and must be called 528 * by subclassing drivers. 529 */ 530void 531bhnd_generic_child_deleted(device_t dev, device_t child) 532{ 533 struct bhnd_softc *sc; 534 struct bhnd_devinfo *dinfo; 535 536 sc = device_get_softc(dev); 537 538 /* Free device info */ 539 if ((dinfo = device_get_ivars(child)) != NULL) 540 BHND_BUS_FREE_DEVINFO(dev, dinfo); 541} 542 543/** 544 * Helper function for implementing BUS_SUSPEND_CHILD(). 545 * 546 * TODO: Power management 547 * 548 * If @p child is not a direct child of @p dev, suspension is delegated to 549 * the @p dev parent. 550 */ 551int 552bhnd_generic_suspend_child(device_t dev, device_t child) 553{ 554 if (device_get_parent(child) != dev) 555 BUS_SUSPEND_CHILD(device_get_parent(dev), child); 556 557 return bus_generic_suspend_child(dev, child); 558} 559 560/** 561 * Helper function for implementing BUS_RESUME_CHILD(). 562 * 563 * TODO: Power management 564 * 565 * If @p child is not a direct child of @p dev, suspension is delegated to 566 * the @p dev parent. 567 */ 568int 569bhnd_generic_resume_child(device_t dev, device_t child) 570{ 571 if (device_get_parent(child) != dev) 572 BUS_RESUME_CHILD(device_get_parent(dev), child); 573 574 return bus_generic_resume_child(dev, child); 575} 576 577/* 578 * Delegate all indirect I/O to the parent device. When inherited by 579 * non-bridged bus implementations, resources will never be marked as 580 * indirect, and these methods will never be called. 581 */ 582#define BHND_IO_READ(_type, _name, _method) \ 583static _type \ 584bhnd_read_ ## _name (device_t dev, device_t child, \ 585 struct bhnd_resource *r, bus_size_t offset) \ 586{ \ 587 return (BHND_BUS_READ_ ## _method( \ 588 device_get_parent(dev), child, r, offset)); \ 589} 590 591#define BHND_IO_WRITE(_type, _name, _method) \ 592static void \ 593bhnd_write_ ## _name (device_t dev, device_t child, \ 594 struct bhnd_resource *r, bus_size_t offset, _type value) \ 595{ \ 596 return (BHND_BUS_WRITE_ ## _method( \ 597 device_get_parent(dev), child, r, offset, \ 598 value)); \ 599} 600 601#define BHND_IO_MISC(_type, _op, _method) \ 602static void \ 603bhnd_ ## _op (device_t dev, device_t child, \ 604 struct bhnd_resource *r, bus_size_t offset, _type datap, \ 605 bus_size_t count) \ 606{ \ 607 BHND_BUS_ ## _method(device_get_parent(dev), child, r, \ 608 offset, datap, count); \ 609} 610 611#define BHND_IO_METHODS(_type, _size) \ 612 BHND_IO_READ(_type, _size, _size) \ 613 BHND_IO_WRITE(_type, _size, _size) \ 614 \ 615 BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \ 616 BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \ 617 \ 618 BHND_IO_MISC(_type*, read_multi_ ## _size, \ 619 READ_MULTI_ ## _size) \ 620 BHND_IO_MISC(_type*, write_multi_ ## _size, \ 621 WRITE_MULTI_ ## _size) \ 622 \ 623 BHND_IO_MISC(_type*, read_multi_stream_ ## _size, \ 624 READ_MULTI_STREAM_ ## _size) \ 625 BHND_IO_MISC(_type*, write_multi_stream_ ## _size, \ 626 WRITE_MULTI_STREAM_ ## _size) \ 627 \ 628 BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size) \ 629 BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \ 630 \ 631 BHND_IO_MISC(_type*, read_region_ ## _size, \ 632 READ_REGION_ ## _size) \ 633 BHND_IO_MISC(_type*, write_region_ ## _size, \ 634 WRITE_REGION_ ## _size) \ 635 \ 636 BHND_IO_MISC(_type*, read_region_stream_ ## _size, \ 637 READ_REGION_STREAM_ ## _size) \ 638 BHND_IO_MISC(_type*, write_region_stream_ ## _size, \ 639 WRITE_REGION_STREAM_ ## _size) \ 640 641BHND_IO_METHODS(uint8_t, 1); 642BHND_IO_METHODS(uint16_t, 2); 643BHND_IO_METHODS(uint32_t, 4); 644 645static void 646bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r, 647 bus_size_t offset, bus_size_t length, int flags) 648{ 649 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length, 650 flags); 651} 652 653static device_method_t bhnd_methods[] = { 654 /* Device interface */ \ 655 DEVMETHOD(device_attach, bhnd_generic_attach), 656 DEVMETHOD(device_detach, bhnd_generic_detach), 657 DEVMETHOD(device_shutdown, bhnd_generic_shutdown), 658 DEVMETHOD(device_suspend, bhnd_generic_suspend), 659 DEVMETHOD(device_resume, bhnd_generic_resume), 660 661 /* Bus interface */ 662 DEVMETHOD(bus_add_child, bhnd_generic_add_child), 663 DEVMETHOD(bus_child_deleted, bhnd_generic_child_deleted), 664 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), 665 DEVMETHOD(bus_print_child, bhnd_generic_print_child), 666 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str), 667 DEVMETHOD(bus_child_location_str, bhnd_child_location_str), 668 669 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child), 670 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child), 671 672 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 673 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 674 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 675 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 676 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 677 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 678 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 679 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 680 681 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 682 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 683 DEVMETHOD(bus_config_intr, bus_generic_config_intr), 684 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr), 685 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr), 686 687 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), 688 689 /* BHND interface */ 690 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid), 691 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order), 692 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), 693 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), 694 DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_bus_generic_get_nvram_var), 695 696 /* BHND interface (bus I/O) */ 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 704 DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1), 705 DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2), 706 DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4), 707 DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1), 708 DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2), 709 DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4), 710 711 DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1), 712 DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2), 713 DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4), 714 DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1), 715 DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2), 716 DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4), 717 718 DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1), 719 DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2), 720 DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4), 721 DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1), 722 DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2), 723 DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4), 724 725 DEVMETHOD(bhnd_bus_set_multi_1, bhnd_set_multi_1), 726 DEVMETHOD(bhnd_bus_set_multi_2, bhnd_set_multi_2), 727 DEVMETHOD(bhnd_bus_set_multi_4, bhnd_set_multi_4), 728 729 DEVMETHOD(bhnd_bus_set_region_1, bhnd_set_region_1), 730 DEVMETHOD(bhnd_bus_set_region_2, bhnd_set_region_2), 731 DEVMETHOD(bhnd_bus_set_region_4, bhnd_set_region_4), 732 733 DEVMETHOD(bhnd_bus_read_region_1, bhnd_read_region_1), 734 DEVMETHOD(bhnd_bus_read_region_2, bhnd_read_region_2), 735 DEVMETHOD(bhnd_bus_read_region_4, bhnd_read_region_4), 736 DEVMETHOD(bhnd_bus_write_region_1, bhnd_write_region_1), 737 DEVMETHOD(bhnd_bus_write_region_2, bhnd_write_region_2), 738 DEVMETHOD(bhnd_bus_write_region_4, bhnd_write_region_4), 739 740 DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1), 741 DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2), 742 DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4), 743 DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1), 744 DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2), 745 DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4), 746 747 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), 748 749 DEVMETHOD_END 750}; 751 752devclass_t bhnd_devclass; /**< bhnd bus. */ 753devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */ 754devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */ 755 756DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc)); 757MODULE_VERSION(bhnd, 1); 758