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 #include "bhnd_nvram_if.h" 65 66 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); 67 68 /** 69 * bhnd_generic_probe_nomatch() reporting configuration. 70 */ 71 static const struct bhnd_nomatch { 72 uint16_t vendor; /**< core designer */ 73 uint16_t device; /**< core id */ 74 bool if_verbose; /**< print when bootverbose is set. */ 75 } bhnd_nomatch_table[] = { 76 { BHND_MFGID_ARM, BHND_COREID_OOB_ROUTER, true }, 77 { BHND_MFGID_ARM, BHND_COREID_EROM, true }, 78 { BHND_MFGID_ARM, BHND_COREID_PL301, true }, 79 { BHND_MFGID_ARM, BHND_COREID_APB_BRIDGE, true }, 80 { BHND_MFGID_ARM, BHND_COREID_AXI_UNMAPPED, false }, 81 82 { BHND_MFGID_INVALID, BHND_COREID_INVALID, false } 83 }; 84 85 static device_t find_nvram_child(device_t dev); 86 87 static int compare_ascending_probe_order(const void *lhs, 88 const void *rhs); 89 static int compare_descending_probe_order(const void *lhs, 90 const void *rhs); 91 92 /** 93 * Default bhnd(4) bus driver implementation of DEVICE_ATTACH(). 94 * 95 * This implementation calls device_probe_and_attach() for each of the device's 96 * children, in bhnd probe order. 97 */ 98 int 99 bhnd_generic_attach(device_t dev) 100 { 101 device_t *devs; 102 int ndevs; 103 int error; 104 105 if (device_is_attached(dev)) 106 return (EBUSY); 107 108 if ((error = device_get_children(dev, &devs, &ndevs))) 109 return (error); 110 111 qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 112 for (int i = 0; i < ndevs; i++) { 113 device_t child = devs[i]; 114 device_probe_and_attach(child); 115 } 116 117 free(devs, M_TEMP); 118 return (0); 119 } 120 121 /** 122 * Default bhnd(4) bus driver implementation of DEVICE_DETACH(). 123 * 124 * This implementation calls device_detach() for each of the the device's 125 * children, in reverse bhnd probe order, terminating if any call to 126 * device_detach() fails. 127 */ 128 int 129 bhnd_generic_detach(device_t dev) 130 { 131 device_t *devs; 132 int ndevs; 133 int error; 134 135 if (!device_is_attached(dev)) 136 return (EBUSY); 137 138 if ((error = device_get_children(dev, &devs, &ndevs))) 139 return (error); 140 141 /* Detach in the reverse of attach order */ 142 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 143 for (int i = 0; i < ndevs; i++) { 144 device_t child = devs[i]; 145 146 /* Terminate on first error */ 147 if ((error = device_detach(child))) 148 goto cleanup; 149 } 150 151 cleanup: 152 free(devs, M_TEMP); 153 return (error); 154 } 155 156 /** 157 * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN(). 158 * 159 * This implementation calls device_shutdown() for each of the device's 160 * children, in reverse bhnd probe order, terminating if any call to 161 * device_shutdown() fails. 162 */ 163 int 164 bhnd_generic_shutdown(device_t dev) 165 { 166 device_t *devs; 167 int ndevs; 168 int error; 169 170 if (!device_is_attached(dev)) 171 return (EBUSY); 172 173 if ((error = device_get_children(dev, &devs, &ndevs))) 174 return (error); 175 176 /* Shutdown in the reverse of attach order */ 177 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 178 for (int i = 0; i < ndevs; i++) { 179 device_t child = devs[i]; 180 181 /* Terminate on first error */ 182 if ((error = device_shutdown(child))) 183 goto cleanup; 184 } 185 186 cleanup: 187 free(devs, M_TEMP); 188 return (error); 189 } 190 191 /** 192 * Default bhnd(4) bus driver implementation of DEVICE_RESUME(). 193 * 194 * This implementation calls BUS_RESUME_CHILD() for each of the device's 195 * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD() 196 * fails. 197 */ 198 int 199 bhnd_generic_resume(device_t dev) 200 { 201 device_t *devs; 202 int ndevs; 203 int error; 204 205 if (!device_is_attached(dev)) 206 return (EBUSY); 207 208 if ((error = device_get_children(dev, &devs, &ndevs))) 209 return (error); 210 211 qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 212 for (int i = 0; i < ndevs; i++) { 213 device_t child = devs[i]; 214 215 /* Terminate on first error */ 216 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child))) 217 goto cleanup; 218 } 219 220 cleanup: 221 free(devs, M_TEMP); 222 return (error); 223 } 224 225 /** 226 * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND(). 227 * 228 * This implementation calls BUS_SUSPEND_CHILD() for each of the device's 229 * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD() 230 * fails, the suspend operation is terminated and any devices that were 231 * suspended are resumed immediately by calling their BUS_RESUME_CHILD() 232 * methods. 233 */ 234 int 235 bhnd_generic_suspend(device_t dev) 236 { 237 device_t *devs; 238 int ndevs; 239 int error; 240 241 if (!device_is_attached(dev)) 242 return (EBUSY); 243 244 if ((error = device_get_children(dev, &devs, &ndevs))) 245 return (error); 246 247 /* Suspend in the reverse of attach order */ 248 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 249 for (int i = 0; i < ndevs; i++) { 250 device_t child = devs[i]; 251 error = BUS_SUSPEND_CHILD(device_get_parent(child), child); 252 253 /* On error, resume suspended devices and then terminate */ 254 if (error) { 255 for (int j = 0; j < i; j++) { 256 BUS_RESUME_CHILD(device_get_parent(devs[j]), 257 devs[j]); 258 } 259 260 goto cleanup; 261 } 262 } 263 264 cleanup: 265 free(devs, M_TEMP); 266 return (error); 267 } 268 269 /* 270 * Ascending comparison of bhnd device's probe order. 271 */ 272 static int 273 compare_ascending_probe_order(const void *lhs, const void *rhs) 274 { 275 device_t ldev, rdev; 276 int lorder, rorder; 277 278 ldev = (*(const device_t *) lhs); 279 rdev = (*(const device_t *) rhs); 280 281 lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev); 282 rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev); 283 284 if (lorder < rorder) { 285 return (-1); 286 } else if (lorder > rorder) { 287 return (1); 288 } else { 289 return (0); 290 } 291 } 292 293 /* 294 * Descending comparison of bhnd device's probe order. 295 */ 296 static int 297 compare_descending_probe_order(const void *lhs, const void *rhs) 298 { 299 return (compare_ascending_probe_order(rhs, lhs)); 300 } 301 302 /** 303 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER(). 304 * 305 * This implementation determines probe ordering based on the device's class 306 * and other properties, including whether the device is serving as a host 307 * bridge. 308 */ 309 int 310 bhnd_generic_get_probe_order(device_t dev, device_t child) 311 { 312 switch (bhnd_get_class(child)) { 313 case BHND_DEVCLASS_CC: 314 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST); 315 316 case BHND_DEVCLASS_CC_B: 317 /* fall through */ 318 case BHND_DEVCLASS_PMU: 319 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY); 320 321 case BHND_DEVCLASS_SOC_ROUTER: 322 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE); 323 324 case BHND_DEVCLASS_SOC_BRIDGE: 325 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST); 326 327 case BHND_DEVCLASS_CPU: 328 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST); 329 330 case BHND_DEVCLASS_RAM: 331 /* fall through */ 332 case BHND_DEVCLASS_MEMC: 333 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY); 334 335 case BHND_DEVCLASS_NVRAM: 336 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY); 337 338 case BHND_DEVCLASS_PCI: 339 case BHND_DEVCLASS_PCIE: 340 case BHND_DEVCLASS_PCCARD: 341 case BHND_DEVCLASS_ENET: 342 case BHND_DEVCLASS_ENET_MAC: 343 case BHND_DEVCLASS_ENET_PHY: 344 case BHND_DEVCLASS_WLAN: 345 case BHND_DEVCLASS_WLAN_MAC: 346 case BHND_DEVCLASS_WLAN_PHY: 347 case BHND_DEVCLASS_EROM: 348 case BHND_DEVCLASS_OTHER: 349 case BHND_DEVCLASS_INVALID: 350 if (bhnd_is_hostb_device(child)) 351 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY); 352 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 * Find an NVRAM child device on @p dev, if any. 380 * 381 * @retval device_t An NVRAM device. 382 * @retval NULL If no NVRAM device is found. 383 */ 384 static device_t 385 find_nvram_child(device_t dev) 386 { 387 device_t chipc, nvram; 388 389 /* Look for a directly-attached NVRAM child */ 390 nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass), 391 -1); 392 if (nvram == NULL) 393 return (NULL); 394 395 /* Further checks require a bhnd(4) bus */ 396 if (device_get_devclass(dev) != bhnd_devclass) 397 return (NULL); 398 399 /* Look for a ChipCommon-attached OTP device */ 400 if ((chipc = bhnd_find_child(dev, BHND_DEVCLASS_CC, -1)) != NULL) { 401 /* Recursively search the ChipCommon device */ 402 if ((nvram = find_nvram_child(chipc)) != NULL) 403 return (nvram); 404 } 405 406 /* Not found */ 407 return (NULL); 408 } 409 410 /** 411 * Default bhnd(4) bus driver implementation of BHND_BUS_READ_NVRAM_VAR(). 412 * 413 * This implementation searches @p dev for a valid NVRAM device. If no NVRAM 414 * child device is found on @p dev, the request is delegated to the 415 * BHND_BUS_READ_NVRAM_VAR() method on the parent 416 * of @p dev. 417 */ 418 static int 419 bhnd_generic_read_nvram_var(device_t dev, device_t child, const char *name, 420 void *buf, size_t *size) 421 { 422 device_t nvram; 423 424 /* Try to find an NVRAM device applicable to @p child */ 425 if ((nvram = find_nvram_child(dev)) == NULL) 426 return (BHND_BUS_READ_NVRAM_VAR(device_get_parent(dev), child, 427 name, buf, size)); 428 429 return BHND_NVRAM_GETVAR(nvram, name, buf, size); 430 } 431 432 /** 433 * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD(). 434 * 435 * This implementation requests the device's struct resource_list via 436 * BUS_GET_RESOURCE_LIST. 437 */ 438 int 439 bhnd_generic_print_child(device_t dev, device_t child) 440 { 441 struct resource_list *rl; 442 int retval = 0; 443 444 retval += bus_print_child_header(dev, child); 445 446 rl = BUS_GET_RESOURCE_LIST(dev, child); 447 if (rl != NULL) { 448 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, 449 "%#jx"); 450 } 451 452 retval += printf(" at core %u", bhnd_get_core_index(child)); 453 454 retval += bus_print_child_domain(dev, child); 455 retval += bus_print_child_footer(dev, child); 456 457 return (retval); 458 } 459 460 /** 461 * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH(). 462 * 463 * This implementation requests the device's struct resource_list via 464 * BUS_GET_RESOURCE_LIST. 465 */ 466 void 467 bhnd_generic_probe_nomatch(device_t dev, device_t child) 468 { 469 struct resource_list *rl; 470 const struct bhnd_nomatch *nm; 471 bool report; 472 473 /* Fetch reporting configuration for this device */ 474 report = true; 475 for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) { 476 if (nm->vendor != bhnd_get_vendor(child)) 477 continue; 478 479 if (nm->device != bhnd_get_device(child)) 480 continue; 481 482 report = false; 483 if (bootverbose && nm->if_verbose) 484 report = true; 485 break; 486 } 487 488 if (!report) 489 return; 490 491 /* Print the non-matched device info */ 492 device_printf(dev, "<%s %s>", bhnd_get_vendor_name(child), 493 bhnd_get_device_name(child)); 494 495 rl = BUS_GET_RESOURCE_LIST(dev, child); 496 if (rl != NULL) 497 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); 498 499 printf(" at core %u (no driver attached)\n", 500 bhnd_get_core_index(child)); 501 } 502 503 /** 504 * Default implementation of BUS_CHILD_PNPINFO_STR(). 505 */ 506 static int 507 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf, 508 size_t buflen) 509 { 510 if (device_get_parent(child) != dev) { 511 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child, 512 buf, buflen)); 513 } 514 515 snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx", 516 bhnd_get_vendor(child), bhnd_get_device(child), 517 bhnd_get_hwrev(child)); 518 519 return (0); 520 } 521 522 /** 523 * Default implementation of BUS_CHILD_LOCATION_STR(). 524 */ 525 static int 526 bhnd_child_location_str(device_t dev, device_t child, char *buf, 527 size_t buflen) 528 { 529 bhnd_addr_t addr; 530 bhnd_size_t size; 531 532 if (device_get_parent(child) != dev) { 533 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child, 534 buf, buflen)); 535 } 536 537 538 if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) { 539 /* No device default port/region */ 540 if (buflen > 0) 541 *buf = '\0'; 542 return (0); 543 } 544 545 snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr); 546 return (0); 547 } 548 549 /** 550 * Helper function for implementing BUS_SUSPEND_CHILD(). 551 * 552 * TODO: Power management 553 * 554 * If @p child is not a direct child of @p dev, suspension is delegated to 555 * the @p dev parent. 556 */ 557 int 558 bhnd_generic_suspend_child(device_t dev, device_t child) 559 { 560 if (device_get_parent(child) != dev) 561 BUS_SUSPEND_CHILD(device_get_parent(dev), child); 562 563 return bus_generic_suspend_child(dev, child); 564 } 565 566 /** 567 * Helper function for implementing BUS_RESUME_CHILD(). 568 * 569 * TODO: Power management 570 * 571 * If @p child is not a direct child of @p dev, suspension is delegated to 572 * the @p dev parent. 573 */ 574 int 575 bhnd_generic_resume_child(device_t dev, device_t child) 576 { 577 if (device_get_parent(child) != dev) 578 BUS_RESUME_CHILD(device_get_parent(dev), child); 579 580 return bus_generic_resume_child(dev, child); 581 } 582 583 /* 584 * Delegate all indirect I/O to the parent device. When inherited by 585 * non-bridged bus implementations, resources will never be marked as 586 * indirect, and these methods should never be called. 587 */ 588 589 static uint8_t 590 bhnd_read_1(device_t dev, device_t child, struct bhnd_resource *r, 591 bus_size_t offset) 592 { 593 return (BHND_BUS_READ_1(device_get_parent(dev), child, r, offset)); 594 } 595 596 static uint16_t 597 bhnd_read_2(device_t dev, device_t child, struct bhnd_resource *r, 598 bus_size_t offset) 599 { 600 return (BHND_BUS_READ_2(device_get_parent(dev), child, r, offset)); 601 } 602 603 static uint32_t 604 bhnd_read_4(device_t dev, device_t child, struct bhnd_resource *r, 605 bus_size_t offset) 606 { 607 return (BHND_BUS_READ_4(device_get_parent(dev), child, r, offset)); 608 } 609 610 static void 611 bhnd_write_1(device_t dev, device_t child, struct bhnd_resource *r, 612 bus_size_t offset, uint8_t value) 613 { 614 BHND_BUS_WRITE_1(device_get_parent(dev), child, r, offset, value); 615 } 616 617 static void 618 bhnd_write_2(device_t dev, device_t child, struct bhnd_resource *r, 619 bus_size_t offset, uint16_t value) 620 { 621 BHND_BUS_WRITE_2(device_get_parent(dev), child, r, offset, value); 622 } 623 624 static void 625 bhnd_write_4(device_t dev, device_t child, struct bhnd_resource *r, 626 bus_size_t offset, uint32_t value) 627 { 628 BHND_BUS_WRITE_4(device_get_parent(dev), child, r, offset, value); 629 } 630 631 static void 632 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r, 633 bus_size_t offset, bus_size_t length, int flags) 634 { 635 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length, 636 flags); 637 } 638 639 static device_method_t bhnd_methods[] = { 640 /* Device interface */ \ 641 DEVMETHOD(device_attach, bhnd_generic_attach), 642 DEVMETHOD(device_detach, bhnd_generic_detach), 643 DEVMETHOD(device_shutdown, bhnd_generic_shutdown), 644 DEVMETHOD(device_suspend, bhnd_generic_suspend), 645 DEVMETHOD(device_resume, bhnd_generic_resume), 646 647 /* Bus interface */ 648 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), 649 DEVMETHOD(bus_print_child, bhnd_generic_print_child), 650 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str), 651 DEVMETHOD(bus_child_location_str, bhnd_child_location_str), 652 653 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child), 654 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child), 655 656 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 657 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 658 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 659 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 660 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 661 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 662 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 663 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 664 665 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 666 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 667 DEVMETHOD(bus_config_intr, bus_generic_config_intr), 668 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr), 669 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr), 670 671 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), 672 673 /* BHND interface */ 674 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid), 675 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order), 676 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), 677 DEVMETHOD(bhnd_bus_is_hostb_device, bhnd_bus_generic_is_hostb_device), 678 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), 679 DEVMETHOD(bhnd_bus_read_nvram_var, bhnd_generic_read_nvram_var), 680 DEVMETHOD(bhnd_bus_read_1, bhnd_read_1), 681 DEVMETHOD(bhnd_bus_read_2, bhnd_read_2), 682 DEVMETHOD(bhnd_bus_read_4, bhnd_read_4), 683 DEVMETHOD(bhnd_bus_write_1, bhnd_write_1), 684 DEVMETHOD(bhnd_bus_write_2, bhnd_write_2), 685 DEVMETHOD(bhnd_bus_write_4, bhnd_write_4), 686 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), 687 688 DEVMETHOD_END 689 }; 690 691 devclass_t bhnd_devclass; /**< bhnd bus. */ 692 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */ 693 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */ 694 695 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc)); 696 MODULE_VERSION(bhnd, 1); 697