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 64 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); 65 66 /** 67 * bhnd_generic_probe_nomatch() reporting configuration. 68 */ 69 static 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 83 static int compare_ascending_probe_order(const void *lhs, 84 const void *rhs); 85 static 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 */ 94 int 95 bhnd_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 */ 124 int 125 bhnd_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 147 cleanup: 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 */ 159 int 160 bhnd_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 182 cleanup: 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 */ 194 int 195 bhnd_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 216 cleanup: 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 */ 230 int 231 bhnd_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 260 cleanup: 261 free(devs, M_TEMP); 262 return (error); 263 } 264 265 /* 266 * Ascending comparison of bhnd device's probe order. 267 */ 268 static int 269 compare_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 */ 292 static int 293 compare_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 */ 305 int 306 bhnd_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 */ 365 static bool 366 bhnd_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 */ 384 int 385 bhnd_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 */ 412 void 413 bhnd_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 */ 452 static int 453 bhnd_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 */ 471 static int 472 bhnd_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 * Helper function for implementing BUS_SUSPEND_CHILD(). 497 * 498 * TODO: Power management 499 * 500 * If @p child is not a direct child of @p dev, suspension is delegated to 501 * the @p dev parent. 502 */ 503 int 504 bhnd_generic_suspend_child(device_t dev, device_t child) 505 { 506 if (device_get_parent(child) != dev) 507 BUS_SUSPEND_CHILD(device_get_parent(dev), child); 508 509 return bus_generic_suspend_child(dev, child); 510 } 511 512 /** 513 * Helper function for implementing BUS_RESUME_CHILD(). 514 * 515 * TODO: Power management 516 * 517 * If @p child is not a direct child of @p dev, suspension is delegated to 518 * the @p dev parent. 519 */ 520 int 521 bhnd_generic_resume_child(device_t dev, device_t child) 522 { 523 if (device_get_parent(child) != dev) 524 BUS_RESUME_CHILD(device_get_parent(dev), child); 525 526 return bus_generic_resume_child(dev, child); 527 } 528 529 /* 530 * Delegate all indirect I/O to the parent device. When inherited by 531 * non-bridged bus implementations, resources will never be marked as 532 * indirect, and these methods will never be called. 533 */ 534 #define BHND_IO_READ(_type, _name, _method) \ 535 static _type \ 536 bhnd_read_ ## _name (device_t dev, device_t child, \ 537 struct bhnd_resource *r, bus_size_t offset) \ 538 { \ 539 return (BHND_BUS_READ_ ## _method( \ 540 device_get_parent(dev), child, r, offset)); \ 541 } 542 543 #define BHND_IO_WRITE(_type, _name, _method) \ 544 static void \ 545 bhnd_write_ ## _name (device_t dev, device_t child, \ 546 struct bhnd_resource *r, bus_size_t offset, _type value) \ 547 { \ 548 return (BHND_BUS_WRITE_ ## _method( \ 549 device_get_parent(dev), child, r, offset, \ 550 value)); \ 551 } 552 553 #define BHND_IO_MISC(_type, _op, _method) \ 554 static void \ 555 bhnd_ ## _op (device_t dev, device_t child, \ 556 struct bhnd_resource *r, bus_size_t offset, _type datap, \ 557 bus_size_t count) \ 558 { \ 559 BHND_BUS_ ## _method(device_get_parent(dev), child, r, \ 560 offset, datap, count); \ 561 } 562 563 #define BHND_IO_METHODS(_type, _size) \ 564 BHND_IO_READ(_type, _size, _size) \ 565 BHND_IO_WRITE(_type, _size, _size) \ 566 \ 567 BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \ 568 BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \ 569 \ 570 BHND_IO_MISC(_type*, read_multi_ ## _size, \ 571 READ_MULTI_ ## _size) \ 572 BHND_IO_MISC(_type*, write_multi_ ## _size, \ 573 WRITE_MULTI_ ## _size) \ 574 \ 575 BHND_IO_MISC(_type*, read_multi_stream_ ## _size, \ 576 READ_MULTI_STREAM_ ## _size) \ 577 BHND_IO_MISC(_type*, write_multi_stream_ ## _size, \ 578 WRITE_MULTI_STREAM_ ## _size) \ 579 \ 580 BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size) \ 581 BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \ 582 \ 583 BHND_IO_MISC(_type*, read_region_ ## _size, \ 584 READ_REGION_ ## _size) \ 585 BHND_IO_MISC(_type*, write_region_ ## _size, \ 586 WRITE_REGION_ ## _size) \ 587 \ 588 BHND_IO_MISC(_type*, read_region_stream_ ## _size, \ 589 READ_REGION_STREAM_ ## _size) \ 590 BHND_IO_MISC(_type*, write_region_stream_ ## _size, \ 591 WRITE_REGION_STREAM_ ## _size) \ 592 593 BHND_IO_METHODS(uint8_t, 1); 594 BHND_IO_METHODS(uint16_t, 2); 595 BHND_IO_METHODS(uint32_t, 4); 596 597 static void 598 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r, 599 bus_size_t offset, bus_size_t length, int flags) 600 { 601 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length, 602 flags); 603 } 604 605 static device_method_t bhnd_methods[] = { 606 /* Device interface */ \ 607 DEVMETHOD(device_attach, bhnd_generic_attach), 608 DEVMETHOD(device_detach, bhnd_generic_detach), 609 DEVMETHOD(device_shutdown, bhnd_generic_shutdown), 610 DEVMETHOD(device_suspend, bhnd_generic_suspend), 611 DEVMETHOD(device_resume, bhnd_generic_resume), 612 613 /* Bus interface */ 614 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), 615 DEVMETHOD(bus_print_child, bhnd_generic_print_child), 616 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str), 617 DEVMETHOD(bus_child_location_str, bhnd_child_location_str), 618 619 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child), 620 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child), 621 622 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 623 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 624 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 625 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 626 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 627 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 628 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 629 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 630 631 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 632 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 633 DEVMETHOD(bus_config_intr, bus_generic_config_intr), 634 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr), 635 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr), 636 637 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), 638 639 /* BHND interface */ 640 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid), 641 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order), 642 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), 643 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), 644 DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_bus_generic_get_nvram_var), 645 646 /* BHND interface (bus I/O) */ 647 DEVMETHOD(bhnd_bus_read_1, bhnd_read_1), 648 DEVMETHOD(bhnd_bus_read_2, bhnd_read_2), 649 DEVMETHOD(bhnd_bus_read_4, bhnd_read_4), 650 DEVMETHOD(bhnd_bus_write_1, bhnd_write_1), 651 DEVMETHOD(bhnd_bus_write_2, bhnd_write_2), 652 DEVMETHOD(bhnd_bus_write_4, bhnd_write_4), 653 654 DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1), 655 DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2), 656 DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4), 657 DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1), 658 DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2), 659 DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4), 660 661 DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1), 662 DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2), 663 DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4), 664 DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1), 665 DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2), 666 DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4), 667 668 DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1), 669 DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2), 670 DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4), 671 DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1), 672 DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2), 673 DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4), 674 675 DEVMETHOD(bhnd_bus_set_multi_1, bhnd_set_multi_1), 676 DEVMETHOD(bhnd_bus_set_multi_2, bhnd_set_multi_2), 677 DEVMETHOD(bhnd_bus_set_multi_4, bhnd_set_multi_4), 678 679 DEVMETHOD(bhnd_bus_set_region_1, bhnd_set_region_1), 680 DEVMETHOD(bhnd_bus_set_region_2, bhnd_set_region_2), 681 DEVMETHOD(bhnd_bus_set_region_4, bhnd_set_region_4), 682 683 DEVMETHOD(bhnd_bus_read_region_1, bhnd_read_region_1), 684 DEVMETHOD(bhnd_bus_read_region_2, bhnd_read_region_2), 685 DEVMETHOD(bhnd_bus_read_region_4, bhnd_read_region_4), 686 DEVMETHOD(bhnd_bus_write_region_1, bhnd_write_region_1), 687 DEVMETHOD(bhnd_bus_write_region_2, bhnd_write_region_2), 688 DEVMETHOD(bhnd_bus_write_region_4, bhnd_write_region_4), 689 690 DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1), 691 DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2), 692 DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4), 693 DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1), 694 DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2), 695 DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4), 696 697 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), 698 699 DEVMETHOD_END 700 }; 701 702 devclass_t bhnd_devclass; /**< bhnd bus. */ 703 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */ 704 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */ 705 706 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc)); 707 MODULE_VERSION(bhnd, 1); 708