14ad7e9b0SAdrian Chadd /*- 24ad7e9b0SAdrian Chadd * Copyright (c) 2015 Landon Fuller <landon@landonf.org> 34ad7e9b0SAdrian Chadd * All rights reserved. 44ad7e9b0SAdrian Chadd * 54ad7e9b0SAdrian Chadd * Redistribution and use in source and binary forms, with or without 64ad7e9b0SAdrian Chadd * modification, are permitted provided that the following conditions 74ad7e9b0SAdrian Chadd * are met: 84ad7e9b0SAdrian Chadd * 1. Redistributions of source code must retain the above copyright 94ad7e9b0SAdrian Chadd * notice, this list of conditions and the following disclaimer, 104ad7e9b0SAdrian Chadd * without modification. 114ad7e9b0SAdrian Chadd * 2. Redistributions in binary form must reproduce at minimum a disclaimer 124ad7e9b0SAdrian Chadd * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 134ad7e9b0SAdrian Chadd * redistribution must be conditioned upon including a substantially 144ad7e9b0SAdrian Chadd * similar Disclaimer requirement for further binary redistribution. 154ad7e9b0SAdrian Chadd * 164ad7e9b0SAdrian Chadd * NO WARRANTY 174ad7e9b0SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 184ad7e9b0SAdrian Chadd * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 194ad7e9b0SAdrian Chadd * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 204ad7e9b0SAdrian Chadd * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 214ad7e9b0SAdrian Chadd * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 224ad7e9b0SAdrian Chadd * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 234ad7e9b0SAdrian Chadd * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 244ad7e9b0SAdrian Chadd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 254ad7e9b0SAdrian Chadd * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 264ad7e9b0SAdrian Chadd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 274ad7e9b0SAdrian Chadd * THE POSSIBILITY OF SUCH DAMAGES. 284ad7e9b0SAdrian Chadd */ 294ad7e9b0SAdrian Chadd 304ad7e9b0SAdrian Chadd #include <sys/cdefs.h> 314ad7e9b0SAdrian Chadd __FBSDID("$FreeBSD$"); 324ad7e9b0SAdrian Chadd 334ad7e9b0SAdrian Chadd /* 344ad7e9b0SAdrian Chadd * Broadcom Home Networking Division (HND) Bus Driver. 354ad7e9b0SAdrian Chadd * 364ad7e9b0SAdrian Chadd * The Broadcom HND family of devices consists of both SoCs and host-connected 374ad7e9b0SAdrian Chadd * networking chipsets containing a common family of Broadcom IP cores, 384ad7e9b0SAdrian Chadd * including an integrated MIPS and/or ARM cores. 394ad7e9b0SAdrian Chadd * 404ad7e9b0SAdrian Chadd * HND devices expose a nearly identical interface whether accessible over a 414ad7e9b0SAdrian Chadd * native SoC interconnect, or when connected via a host interface such as 424ad7e9b0SAdrian Chadd * PCIe. As a result, the majority of hardware support code should be re-usable 434ad7e9b0SAdrian Chadd * across host drivers for HND networking chipsets, as well as FreeBSD support 444ad7e9b0SAdrian Chadd * for Broadcom MIPS/ARM HND SoCs. 454ad7e9b0SAdrian Chadd * 464ad7e9b0SAdrian Chadd * Earlier HND models used the siba(4) on-chip interconnect, while later models 474ad7e9b0SAdrian Chadd * use bcma(4); the programming model is almost entirely independent 484ad7e9b0SAdrian Chadd * of the actual underlying interconect. 494ad7e9b0SAdrian Chadd */ 504ad7e9b0SAdrian Chadd 514ad7e9b0SAdrian Chadd #include <sys/param.h> 524ad7e9b0SAdrian Chadd #include <sys/kernel.h> 534ad7e9b0SAdrian Chadd #include <sys/bus.h> 544ad7e9b0SAdrian Chadd #include <sys/module.h> 554ad7e9b0SAdrian Chadd #include <sys/systm.h> 564ad7e9b0SAdrian Chadd 574ad7e9b0SAdrian Chadd #include <machine/bus.h> 584ad7e9b0SAdrian Chadd #include <sys/rman.h> 594ad7e9b0SAdrian Chadd #include <machine/resource.h> 604ad7e9b0SAdrian Chadd 614ad7e9b0SAdrian Chadd #include "bhnd.h" 624ad7e9b0SAdrian Chadd #include "bhndvar.h" 634ad7e9b0SAdrian Chadd 644ad7e9b0SAdrian Chadd #include "bhnd_nvram_if.h" 654ad7e9b0SAdrian Chadd 664ad7e9b0SAdrian Chadd MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); 674ad7e9b0SAdrian Chadd 684ad7e9b0SAdrian Chadd /** 694ad7e9b0SAdrian Chadd * bhnd_generic_probe_nomatch() reporting configuration. 704ad7e9b0SAdrian Chadd */ 714ad7e9b0SAdrian Chadd static const struct bhnd_nomatch { 724ad7e9b0SAdrian Chadd uint16_t vendor; /**< core designer */ 734ad7e9b0SAdrian Chadd uint16_t device; /**< core id */ 744ad7e9b0SAdrian Chadd bool if_verbose; /**< print when bootverbose is set. */ 754ad7e9b0SAdrian Chadd } bhnd_nomatch_table[] = { 764ad7e9b0SAdrian Chadd { BHND_MFGID_ARM, BHND_COREID_OOB_ROUTER, true }, 774ad7e9b0SAdrian Chadd { BHND_MFGID_ARM, BHND_COREID_EROM, true }, 784ad7e9b0SAdrian Chadd { BHND_MFGID_ARM, BHND_COREID_PL301, true }, 794ad7e9b0SAdrian Chadd { BHND_MFGID_ARM, BHND_COREID_APB_BRIDGE, true }, 804ad7e9b0SAdrian Chadd { BHND_MFGID_ARM, BHND_COREID_AXI_UNMAPPED, false }, 814ad7e9b0SAdrian Chadd 824ad7e9b0SAdrian Chadd { BHND_MFGID_INVALID, BHND_COREID_INVALID, false } 834ad7e9b0SAdrian Chadd }; 844ad7e9b0SAdrian Chadd 854ad7e9b0SAdrian Chadd static device_t find_nvram_child(device_t dev); 864ad7e9b0SAdrian Chadd 874ad7e9b0SAdrian Chadd static int compare_ascending_probe_order(const void *lhs, 884ad7e9b0SAdrian Chadd const void *rhs); 894ad7e9b0SAdrian Chadd static int compare_descending_probe_order(const void *lhs, 904ad7e9b0SAdrian Chadd const void *rhs); 914ad7e9b0SAdrian Chadd 924ad7e9b0SAdrian Chadd /** 93386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of DEVICE_ATTACH(). 944ad7e9b0SAdrian Chadd * 95386fb140SAdrian Chadd * This implementation calls device_probe_and_attach() for each of the device's 96386fb140SAdrian Chadd * children, in bhnd probe order. 974ad7e9b0SAdrian Chadd */ 984ad7e9b0SAdrian Chadd int 994ad7e9b0SAdrian Chadd bhnd_generic_attach(device_t dev) 1004ad7e9b0SAdrian Chadd { 1014ad7e9b0SAdrian Chadd device_t *devs; 1024ad7e9b0SAdrian Chadd int ndevs; 1034ad7e9b0SAdrian Chadd int error; 1044ad7e9b0SAdrian Chadd 1054ad7e9b0SAdrian Chadd if (device_is_attached(dev)) 1064ad7e9b0SAdrian Chadd return (EBUSY); 1074ad7e9b0SAdrian Chadd 1084ad7e9b0SAdrian Chadd if ((error = device_get_children(dev, &devs, &ndevs))) 1094ad7e9b0SAdrian Chadd return (error); 1104ad7e9b0SAdrian Chadd 1114ad7e9b0SAdrian Chadd qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 1124ad7e9b0SAdrian Chadd for (int i = 0; i < ndevs; i++) { 1134ad7e9b0SAdrian Chadd device_t child = devs[i]; 1144ad7e9b0SAdrian Chadd device_probe_and_attach(child); 1154ad7e9b0SAdrian Chadd } 1164ad7e9b0SAdrian Chadd 1174ad7e9b0SAdrian Chadd free(devs, M_TEMP); 1184ad7e9b0SAdrian Chadd return (0); 1194ad7e9b0SAdrian Chadd } 1204ad7e9b0SAdrian Chadd 1214ad7e9b0SAdrian Chadd /** 122386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of DEVICE_DETACH(). 1234ad7e9b0SAdrian Chadd * 124386fb140SAdrian Chadd * This implementation calls device_detach() for each of the the device's 125386fb140SAdrian Chadd * children, in reverse bhnd probe order, terminating if any call to 126386fb140SAdrian Chadd * device_detach() fails. 1274ad7e9b0SAdrian Chadd */ 1284ad7e9b0SAdrian Chadd int 1294ad7e9b0SAdrian Chadd bhnd_generic_detach(device_t dev) 1304ad7e9b0SAdrian Chadd { 1314ad7e9b0SAdrian Chadd device_t *devs; 1324ad7e9b0SAdrian Chadd int ndevs; 1334ad7e9b0SAdrian Chadd int error; 1344ad7e9b0SAdrian Chadd 1354ad7e9b0SAdrian Chadd if (!device_is_attached(dev)) 1364ad7e9b0SAdrian Chadd return (EBUSY); 1374ad7e9b0SAdrian Chadd 1384ad7e9b0SAdrian Chadd if ((error = device_get_children(dev, &devs, &ndevs))) 1394ad7e9b0SAdrian Chadd return (error); 1404ad7e9b0SAdrian Chadd 1414ad7e9b0SAdrian Chadd /* Detach in the reverse of attach order */ 1424ad7e9b0SAdrian Chadd qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 1434ad7e9b0SAdrian Chadd for (int i = 0; i < ndevs; i++) { 1444ad7e9b0SAdrian Chadd device_t child = devs[i]; 1454ad7e9b0SAdrian Chadd 1464ad7e9b0SAdrian Chadd /* Terminate on first error */ 1474ad7e9b0SAdrian Chadd if ((error = device_detach(child))) 1484ad7e9b0SAdrian Chadd goto cleanup; 1494ad7e9b0SAdrian Chadd } 1504ad7e9b0SAdrian Chadd 1514ad7e9b0SAdrian Chadd cleanup: 1524ad7e9b0SAdrian Chadd free(devs, M_TEMP); 1534ad7e9b0SAdrian Chadd return (error); 1544ad7e9b0SAdrian Chadd } 1554ad7e9b0SAdrian Chadd 1564ad7e9b0SAdrian Chadd /** 157386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN(). 1584ad7e9b0SAdrian Chadd * 159386fb140SAdrian Chadd * This implementation calls device_shutdown() for each of the device's 160386fb140SAdrian Chadd * children, in reverse bhnd probe order, terminating if any call to 161386fb140SAdrian Chadd * device_shutdown() fails. 1624ad7e9b0SAdrian Chadd */ 1634ad7e9b0SAdrian Chadd int 1644ad7e9b0SAdrian Chadd bhnd_generic_shutdown(device_t dev) 1654ad7e9b0SAdrian Chadd { 1664ad7e9b0SAdrian Chadd device_t *devs; 1674ad7e9b0SAdrian Chadd int ndevs; 1684ad7e9b0SAdrian Chadd int error; 1694ad7e9b0SAdrian Chadd 1704ad7e9b0SAdrian Chadd if (!device_is_attached(dev)) 1714ad7e9b0SAdrian Chadd return (EBUSY); 1724ad7e9b0SAdrian Chadd 1734ad7e9b0SAdrian Chadd if ((error = device_get_children(dev, &devs, &ndevs))) 1744ad7e9b0SAdrian Chadd return (error); 1754ad7e9b0SAdrian Chadd 1764ad7e9b0SAdrian Chadd /* Shutdown in the reverse of attach order */ 1774ad7e9b0SAdrian Chadd qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 1784ad7e9b0SAdrian Chadd for (int i = 0; i < ndevs; i++) { 1794ad7e9b0SAdrian Chadd device_t child = devs[i]; 1804ad7e9b0SAdrian Chadd 1814ad7e9b0SAdrian Chadd /* Terminate on first error */ 1824ad7e9b0SAdrian Chadd if ((error = device_shutdown(child))) 1834ad7e9b0SAdrian Chadd goto cleanup; 1844ad7e9b0SAdrian Chadd } 1854ad7e9b0SAdrian Chadd 1864ad7e9b0SAdrian Chadd cleanup: 1874ad7e9b0SAdrian Chadd free(devs, M_TEMP); 1884ad7e9b0SAdrian Chadd return (error); 1894ad7e9b0SAdrian Chadd } 1904ad7e9b0SAdrian Chadd 1914ad7e9b0SAdrian Chadd /** 192386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of DEVICE_RESUME(). 1934ad7e9b0SAdrian Chadd * 194386fb140SAdrian Chadd * This implementation calls BUS_RESUME_CHILD() for each of the device's 195386fb140SAdrian Chadd * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD() 196386fb140SAdrian Chadd * fails. 1974ad7e9b0SAdrian Chadd */ 1984ad7e9b0SAdrian Chadd int 1994ad7e9b0SAdrian Chadd bhnd_generic_resume(device_t dev) 2004ad7e9b0SAdrian Chadd { 2014ad7e9b0SAdrian Chadd device_t *devs; 2024ad7e9b0SAdrian Chadd int ndevs; 2034ad7e9b0SAdrian Chadd int error; 2044ad7e9b0SAdrian Chadd 2054ad7e9b0SAdrian Chadd if (!device_is_attached(dev)) 2064ad7e9b0SAdrian Chadd return (EBUSY); 2074ad7e9b0SAdrian Chadd 2084ad7e9b0SAdrian Chadd if ((error = device_get_children(dev, &devs, &ndevs))) 2094ad7e9b0SAdrian Chadd return (error); 2104ad7e9b0SAdrian Chadd 2114ad7e9b0SAdrian Chadd qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 2124ad7e9b0SAdrian Chadd for (int i = 0; i < ndevs; i++) { 2134ad7e9b0SAdrian Chadd device_t child = devs[i]; 2144ad7e9b0SAdrian Chadd 2154ad7e9b0SAdrian Chadd /* Terminate on first error */ 2164ad7e9b0SAdrian Chadd if ((error = BUS_RESUME_CHILD(device_get_parent(child), child))) 2174ad7e9b0SAdrian Chadd goto cleanup; 2184ad7e9b0SAdrian Chadd } 2194ad7e9b0SAdrian Chadd 2204ad7e9b0SAdrian Chadd cleanup: 2214ad7e9b0SAdrian Chadd free(devs, M_TEMP); 2224ad7e9b0SAdrian Chadd return (error); 2234ad7e9b0SAdrian Chadd } 2244ad7e9b0SAdrian Chadd 2254ad7e9b0SAdrian Chadd /** 226386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND(). 2274ad7e9b0SAdrian Chadd * 228386fb140SAdrian Chadd * This implementation calls BUS_SUSPEND_CHILD() for each of the device's 229386fb140SAdrian Chadd * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD() 230386fb140SAdrian Chadd * fails, the suspend operation is terminated and any devices that were 231386fb140SAdrian Chadd * suspended are resumed immediately by calling their BUS_RESUME_CHILD() 232386fb140SAdrian Chadd * methods. 2334ad7e9b0SAdrian Chadd */ 2344ad7e9b0SAdrian Chadd int 2354ad7e9b0SAdrian Chadd bhnd_generic_suspend(device_t dev) 2364ad7e9b0SAdrian Chadd { 2374ad7e9b0SAdrian Chadd device_t *devs; 2384ad7e9b0SAdrian Chadd int ndevs; 2394ad7e9b0SAdrian Chadd int error; 2404ad7e9b0SAdrian Chadd 2414ad7e9b0SAdrian Chadd if (!device_is_attached(dev)) 2424ad7e9b0SAdrian Chadd return (EBUSY); 2434ad7e9b0SAdrian Chadd 2444ad7e9b0SAdrian Chadd if ((error = device_get_children(dev, &devs, &ndevs))) 2454ad7e9b0SAdrian Chadd return (error); 2464ad7e9b0SAdrian Chadd 2474ad7e9b0SAdrian Chadd /* Suspend in the reverse of attach order */ 2484ad7e9b0SAdrian Chadd qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 2494ad7e9b0SAdrian Chadd for (int i = 0; i < ndevs; i++) { 2504ad7e9b0SAdrian Chadd device_t child = devs[i]; 2514ad7e9b0SAdrian Chadd error = BUS_SUSPEND_CHILD(device_get_parent(child), child); 2524ad7e9b0SAdrian Chadd 2534ad7e9b0SAdrian Chadd /* On error, resume suspended devices and then terminate */ 2544ad7e9b0SAdrian Chadd if (error) { 2554ad7e9b0SAdrian Chadd for (int j = 0; j < i; j++) { 2564ad7e9b0SAdrian Chadd BUS_RESUME_CHILD(device_get_parent(devs[j]), 2574ad7e9b0SAdrian Chadd devs[j]); 2584ad7e9b0SAdrian Chadd } 2594ad7e9b0SAdrian Chadd 2604ad7e9b0SAdrian Chadd goto cleanup; 2614ad7e9b0SAdrian Chadd } 2624ad7e9b0SAdrian Chadd } 2634ad7e9b0SAdrian Chadd 2644ad7e9b0SAdrian Chadd cleanup: 2654ad7e9b0SAdrian Chadd free(devs, M_TEMP); 2664ad7e9b0SAdrian Chadd return (error); 2674ad7e9b0SAdrian Chadd } 2684ad7e9b0SAdrian Chadd 2694ad7e9b0SAdrian Chadd /* 2704ad7e9b0SAdrian Chadd * Ascending comparison of bhnd device's probe order. 2714ad7e9b0SAdrian Chadd */ 2724ad7e9b0SAdrian Chadd static int 2734ad7e9b0SAdrian Chadd compare_ascending_probe_order(const void *lhs, const void *rhs) 2744ad7e9b0SAdrian Chadd { 2754ad7e9b0SAdrian Chadd device_t ldev, rdev; 2764ad7e9b0SAdrian Chadd int lorder, rorder; 2774ad7e9b0SAdrian Chadd 2784ad7e9b0SAdrian Chadd ldev = (*(const device_t *) lhs); 2794ad7e9b0SAdrian Chadd rdev = (*(const device_t *) rhs); 2804ad7e9b0SAdrian Chadd 2814ad7e9b0SAdrian Chadd lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev); 2824ad7e9b0SAdrian Chadd rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev); 2834ad7e9b0SAdrian Chadd 2844ad7e9b0SAdrian Chadd if (lorder < rorder) { 2854ad7e9b0SAdrian Chadd return (-1); 2864ad7e9b0SAdrian Chadd } else if (lorder > rorder) { 2874ad7e9b0SAdrian Chadd return (1); 2884ad7e9b0SAdrian Chadd } else { 2894ad7e9b0SAdrian Chadd return (0); 2904ad7e9b0SAdrian Chadd } 2914ad7e9b0SAdrian Chadd } 2924ad7e9b0SAdrian Chadd 2934ad7e9b0SAdrian Chadd /* 2944ad7e9b0SAdrian Chadd * Descending comparison of bhnd device's probe order. 2954ad7e9b0SAdrian Chadd */ 2964ad7e9b0SAdrian Chadd static int 2974ad7e9b0SAdrian Chadd compare_descending_probe_order(const void *lhs, const void *rhs) 2984ad7e9b0SAdrian Chadd { 2994ad7e9b0SAdrian Chadd return (compare_ascending_probe_order(rhs, lhs)); 3004ad7e9b0SAdrian Chadd } 3014ad7e9b0SAdrian Chadd 3024ad7e9b0SAdrian Chadd /** 303386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER(). 3044ad7e9b0SAdrian Chadd * 3054ad7e9b0SAdrian Chadd * This implementation determines probe ordering based on the device's class 3064ad7e9b0SAdrian Chadd * and other properties, including whether the device is serving as a host 3074ad7e9b0SAdrian Chadd * bridge. 3084ad7e9b0SAdrian Chadd */ 3094ad7e9b0SAdrian Chadd int 3104ad7e9b0SAdrian Chadd bhnd_generic_get_probe_order(device_t dev, device_t child) 3114ad7e9b0SAdrian Chadd { 3124ad7e9b0SAdrian Chadd switch (bhnd_get_class(child)) { 3134ad7e9b0SAdrian Chadd case BHND_DEVCLASS_CC: 3144ad7e9b0SAdrian Chadd return (BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST); 3154ad7e9b0SAdrian Chadd 3164ad7e9b0SAdrian Chadd case BHND_DEVCLASS_CC_B: 3174ad7e9b0SAdrian Chadd /* fall through */ 3184ad7e9b0SAdrian Chadd case BHND_DEVCLASS_PMU: 3194ad7e9b0SAdrian Chadd return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY); 3204ad7e9b0SAdrian Chadd 3214ad7e9b0SAdrian Chadd case BHND_DEVCLASS_SOC_ROUTER: 3224ad7e9b0SAdrian Chadd return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE); 3234ad7e9b0SAdrian Chadd 3244ad7e9b0SAdrian Chadd case BHND_DEVCLASS_SOC_BRIDGE: 3254ad7e9b0SAdrian Chadd return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST); 3264ad7e9b0SAdrian Chadd 3274ad7e9b0SAdrian Chadd case BHND_DEVCLASS_CPU: 3284ad7e9b0SAdrian Chadd return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST); 3294ad7e9b0SAdrian Chadd 3304ad7e9b0SAdrian Chadd case BHND_DEVCLASS_RAM: 3314ad7e9b0SAdrian Chadd /* fall through */ 3324ad7e9b0SAdrian Chadd case BHND_DEVCLASS_MEMC: 3334ad7e9b0SAdrian Chadd return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY); 3344ad7e9b0SAdrian Chadd 3354ad7e9b0SAdrian Chadd case BHND_DEVCLASS_NVRAM: 3364ad7e9b0SAdrian Chadd return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY); 3374ad7e9b0SAdrian Chadd 3384ad7e9b0SAdrian Chadd case BHND_DEVCLASS_PCI: 3394ad7e9b0SAdrian Chadd case BHND_DEVCLASS_PCIE: 3404ad7e9b0SAdrian Chadd case BHND_DEVCLASS_PCCARD: 3414ad7e9b0SAdrian Chadd case BHND_DEVCLASS_ENET: 3424ad7e9b0SAdrian Chadd case BHND_DEVCLASS_ENET_MAC: 3434ad7e9b0SAdrian Chadd case BHND_DEVCLASS_ENET_PHY: 3444ad7e9b0SAdrian Chadd case BHND_DEVCLASS_WLAN: 3454ad7e9b0SAdrian Chadd case BHND_DEVCLASS_WLAN_MAC: 3464ad7e9b0SAdrian Chadd case BHND_DEVCLASS_WLAN_PHY: 3474ad7e9b0SAdrian Chadd case BHND_DEVCLASS_EROM: 3484ad7e9b0SAdrian Chadd case BHND_DEVCLASS_OTHER: 3494ad7e9b0SAdrian Chadd case BHND_DEVCLASS_INVALID: 3504ad7e9b0SAdrian Chadd if (bhnd_is_hostb_device(child)) 3514ad7e9b0SAdrian Chadd return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY); 3524ad7e9b0SAdrian Chadd 3534ad7e9b0SAdrian Chadd return (BHND_PROBE_DEFAULT); 354*054ae231SAdrian Chadd default: 355*054ae231SAdrian Chadd return (BHND_PROBE_DEFAULT); 3564ad7e9b0SAdrian Chadd } 3574ad7e9b0SAdrian Chadd } 3584ad7e9b0SAdrian Chadd 3594ad7e9b0SAdrian Chadd /** 360386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID(). 3614ad7e9b0SAdrian Chadd * 3624ad7e9b0SAdrian Chadd * This implementation assumes that port and region numbers are 0-indexed and 3634ad7e9b0SAdrian Chadd * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and 3644ad7e9b0SAdrian Chadd * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall 3654ad7e9b0SAdrian Chadd * within the defined range. 3664ad7e9b0SAdrian Chadd */ 367386fb140SAdrian Chadd static bool 3684ad7e9b0SAdrian Chadd bhnd_generic_is_region_valid(device_t dev, device_t child, 3694ad7e9b0SAdrian Chadd bhnd_port_type type, u_int port, u_int region) 3704ad7e9b0SAdrian Chadd { 3714ad7e9b0SAdrian Chadd if (port >= bhnd_get_port_count(child, type)) 3724ad7e9b0SAdrian Chadd return (false); 3734ad7e9b0SAdrian Chadd 3744ad7e9b0SAdrian Chadd if (region >= bhnd_get_region_count(child, type, port)) 3754ad7e9b0SAdrian Chadd return (false); 3764ad7e9b0SAdrian Chadd 3774ad7e9b0SAdrian Chadd return (true); 3784ad7e9b0SAdrian Chadd } 3794ad7e9b0SAdrian Chadd 3804ad7e9b0SAdrian Chadd /** 3814ad7e9b0SAdrian Chadd * Find an NVRAM child device on @p dev, if any. 3824ad7e9b0SAdrian Chadd * 3834ad7e9b0SAdrian Chadd * @retval device_t An NVRAM device. 3844ad7e9b0SAdrian Chadd * @retval NULL If no NVRAM device is found. 3854ad7e9b0SAdrian Chadd */ 3864ad7e9b0SAdrian Chadd static device_t 3874ad7e9b0SAdrian Chadd find_nvram_child(device_t dev) 3884ad7e9b0SAdrian Chadd { 3894ad7e9b0SAdrian Chadd device_t chipc, nvram; 3904ad7e9b0SAdrian Chadd 3914ad7e9b0SAdrian Chadd /* Look for a directly-attached NVRAM child */ 3924ad7e9b0SAdrian Chadd nvram = device_find_child(dev, devclass_get_name(bhnd_nvram_devclass), 3934ad7e9b0SAdrian Chadd -1); 3944ad7e9b0SAdrian Chadd if (nvram == NULL) 3954ad7e9b0SAdrian Chadd return (NULL); 3964ad7e9b0SAdrian Chadd 3974ad7e9b0SAdrian Chadd /* Further checks require a bhnd(4) bus */ 3984ad7e9b0SAdrian Chadd if (device_get_devclass(dev) != bhnd_devclass) 3994ad7e9b0SAdrian Chadd return (NULL); 4004ad7e9b0SAdrian Chadd 4014ad7e9b0SAdrian Chadd /* Look for a ChipCommon-attached OTP device */ 4024ad7e9b0SAdrian Chadd if ((chipc = bhnd_find_child(dev, BHND_DEVCLASS_CC, -1)) != NULL) { 4034ad7e9b0SAdrian Chadd /* Recursively search the ChipCommon device */ 4044ad7e9b0SAdrian Chadd if ((nvram = find_nvram_child(chipc)) != NULL) 4054ad7e9b0SAdrian Chadd return (nvram); 4064ad7e9b0SAdrian Chadd } 4074ad7e9b0SAdrian Chadd 4084ad7e9b0SAdrian Chadd /* Not found */ 4094ad7e9b0SAdrian Chadd return (NULL); 4104ad7e9b0SAdrian Chadd } 4114ad7e9b0SAdrian Chadd 4124ad7e9b0SAdrian Chadd /** 413386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of BHND_BUS_READ_NVRAM_VAR(). 4144ad7e9b0SAdrian Chadd * 4154ad7e9b0SAdrian Chadd * This implementation searches @p dev for a valid NVRAM device. If no NVRAM 4164ad7e9b0SAdrian Chadd * child device is found on @p dev, the request is delegated to the 4174ad7e9b0SAdrian Chadd * BHND_BUS_READ_NVRAM_VAR() method on the parent 4184ad7e9b0SAdrian Chadd * of @p dev. 4194ad7e9b0SAdrian Chadd */ 420386fb140SAdrian Chadd static int 4214ad7e9b0SAdrian Chadd bhnd_generic_read_nvram_var(device_t dev, device_t child, const char *name, 4224ad7e9b0SAdrian Chadd void *buf, size_t *size) 4234ad7e9b0SAdrian Chadd { 4244ad7e9b0SAdrian Chadd device_t nvram; 4254ad7e9b0SAdrian Chadd 4264ad7e9b0SAdrian Chadd /* Try to find an NVRAM device applicable to @p child */ 4274ad7e9b0SAdrian Chadd if ((nvram = find_nvram_child(dev)) == NULL) 4284ad7e9b0SAdrian Chadd return (BHND_BUS_READ_NVRAM_VAR(device_get_parent(dev), child, 4294ad7e9b0SAdrian Chadd name, buf, size)); 4304ad7e9b0SAdrian Chadd 4314ad7e9b0SAdrian Chadd return BHND_NVRAM_GETVAR(nvram, name, buf, size); 4324ad7e9b0SAdrian Chadd } 4334ad7e9b0SAdrian Chadd 4344ad7e9b0SAdrian Chadd /** 435386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD(). 4364ad7e9b0SAdrian Chadd * 4374ad7e9b0SAdrian Chadd * This implementation requests the device's struct resource_list via 4384ad7e9b0SAdrian Chadd * BUS_GET_RESOURCE_LIST. 4394ad7e9b0SAdrian Chadd */ 4404ad7e9b0SAdrian Chadd int 4414ad7e9b0SAdrian Chadd bhnd_generic_print_child(device_t dev, device_t child) 4424ad7e9b0SAdrian Chadd { 4434ad7e9b0SAdrian Chadd struct resource_list *rl; 4444ad7e9b0SAdrian Chadd int retval = 0; 4454ad7e9b0SAdrian Chadd 4464ad7e9b0SAdrian Chadd retval += bus_print_child_header(dev, child); 4474ad7e9b0SAdrian Chadd 4484ad7e9b0SAdrian Chadd rl = BUS_GET_RESOURCE_LIST(dev, child); 4494ad7e9b0SAdrian Chadd if (rl != NULL) { 4504ad7e9b0SAdrian Chadd retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, 451f8fd3fb5SJustin Hibbits "%#jx"); 4524ad7e9b0SAdrian Chadd } 4534ad7e9b0SAdrian Chadd 4544ad7e9b0SAdrian Chadd retval += printf(" at core %u", bhnd_get_core_index(child)); 4554ad7e9b0SAdrian Chadd 4564ad7e9b0SAdrian Chadd retval += bus_print_child_domain(dev, child); 4574ad7e9b0SAdrian Chadd retval += bus_print_child_footer(dev, child); 4584ad7e9b0SAdrian Chadd 4594ad7e9b0SAdrian Chadd return (retval); 4604ad7e9b0SAdrian Chadd } 4614ad7e9b0SAdrian Chadd 4624ad7e9b0SAdrian Chadd /** 463386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH(). 4644ad7e9b0SAdrian Chadd * 4654ad7e9b0SAdrian Chadd * This implementation requests the device's struct resource_list via 4664ad7e9b0SAdrian Chadd * BUS_GET_RESOURCE_LIST. 4674ad7e9b0SAdrian Chadd */ 4684ad7e9b0SAdrian Chadd void 4694ad7e9b0SAdrian Chadd bhnd_generic_probe_nomatch(device_t dev, device_t child) 4704ad7e9b0SAdrian Chadd { 4714ad7e9b0SAdrian Chadd struct resource_list *rl; 4724ad7e9b0SAdrian Chadd const struct bhnd_nomatch *nm; 4734ad7e9b0SAdrian Chadd bool report; 4744ad7e9b0SAdrian Chadd 4754ad7e9b0SAdrian Chadd /* Fetch reporting configuration for this device */ 4764ad7e9b0SAdrian Chadd report = true; 4774ad7e9b0SAdrian Chadd for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) { 4784ad7e9b0SAdrian Chadd if (nm->vendor != bhnd_get_vendor(child)) 4794ad7e9b0SAdrian Chadd continue; 4804ad7e9b0SAdrian Chadd 4814ad7e9b0SAdrian Chadd if (nm->device != bhnd_get_device(child)) 4824ad7e9b0SAdrian Chadd continue; 4834ad7e9b0SAdrian Chadd 4844ad7e9b0SAdrian Chadd report = false; 4854ad7e9b0SAdrian Chadd if (bootverbose && nm->if_verbose) 4864ad7e9b0SAdrian Chadd report = true; 4874ad7e9b0SAdrian Chadd break; 4884ad7e9b0SAdrian Chadd } 4894ad7e9b0SAdrian Chadd 4904ad7e9b0SAdrian Chadd if (!report) 4914ad7e9b0SAdrian Chadd return; 4924ad7e9b0SAdrian Chadd 4934ad7e9b0SAdrian Chadd /* Print the non-matched device info */ 4944ad7e9b0SAdrian Chadd device_printf(dev, "<%s %s>", bhnd_get_vendor_name(child), 4954ad7e9b0SAdrian Chadd bhnd_get_device_name(child)); 4964ad7e9b0SAdrian Chadd 4974ad7e9b0SAdrian Chadd rl = BUS_GET_RESOURCE_LIST(dev, child); 4984ad7e9b0SAdrian Chadd if (rl != NULL) 499f8fd3fb5SJustin Hibbits resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); 5004ad7e9b0SAdrian Chadd 5014ad7e9b0SAdrian Chadd printf(" at core %u (no driver attached)\n", 5024ad7e9b0SAdrian Chadd bhnd_get_core_index(child)); 5034ad7e9b0SAdrian Chadd } 5044ad7e9b0SAdrian Chadd 5054ad7e9b0SAdrian Chadd /** 5064ad7e9b0SAdrian Chadd * Default implementation of BUS_CHILD_PNPINFO_STR(). 5074ad7e9b0SAdrian Chadd */ 5084ad7e9b0SAdrian Chadd static int 5094ad7e9b0SAdrian Chadd bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf, 5104ad7e9b0SAdrian Chadd size_t buflen) 5114ad7e9b0SAdrian Chadd { 5124ad7e9b0SAdrian Chadd if (device_get_parent(child) != dev) { 5134ad7e9b0SAdrian Chadd return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child, 5144ad7e9b0SAdrian Chadd buf, buflen)); 5154ad7e9b0SAdrian Chadd } 5164ad7e9b0SAdrian Chadd 5174ad7e9b0SAdrian Chadd snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx", 5184ad7e9b0SAdrian Chadd bhnd_get_vendor(child), bhnd_get_device(child), 5194ad7e9b0SAdrian Chadd bhnd_get_hwrev(child)); 5204ad7e9b0SAdrian Chadd 5214ad7e9b0SAdrian Chadd return (0); 5224ad7e9b0SAdrian Chadd } 5234ad7e9b0SAdrian Chadd 5244ad7e9b0SAdrian Chadd /** 525386fb140SAdrian Chadd * Default implementation of BUS_CHILD_LOCATION_STR(). 5264ad7e9b0SAdrian Chadd */ 5274ad7e9b0SAdrian Chadd static int 5284ad7e9b0SAdrian Chadd bhnd_child_location_str(device_t dev, device_t child, char *buf, 5294ad7e9b0SAdrian Chadd size_t buflen) 5304ad7e9b0SAdrian Chadd { 5314ad7e9b0SAdrian Chadd bhnd_addr_t addr; 5324ad7e9b0SAdrian Chadd bhnd_size_t size; 5334ad7e9b0SAdrian Chadd 5344ad7e9b0SAdrian Chadd if (device_get_parent(child) != dev) { 5354ad7e9b0SAdrian Chadd return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child, 5364ad7e9b0SAdrian Chadd buf, buflen)); 5374ad7e9b0SAdrian Chadd } 5384ad7e9b0SAdrian Chadd 5394ad7e9b0SAdrian Chadd 5404ad7e9b0SAdrian Chadd if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) { 5414ad7e9b0SAdrian Chadd /* No device default port/region */ 5424ad7e9b0SAdrian Chadd if (buflen > 0) 5434ad7e9b0SAdrian Chadd *buf = '\0'; 5444ad7e9b0SAdrian Chadd return (0); 5454ad7e9b0SAdrian Chadd } 5464ad7e9b0SAdrian Chadd 5474ad7e9b0SAdrian Chadd snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr); 5484ad7e9b0SAdrian Chadd return (0); 5494ad7e9b0SAdrian Chadd } 5504ad7e9b0SAdrian Chadd 5514ad7e9b0SAdrian Chadd /** 5524ad7e9b0SAdrian Chadd * Helper function for implementing BUS_SUSPEND_CHILD(). 5534ad7e9b0SAdrian Chadd * 5544ad7e9b0SAdrian Chadd * TODO: Power management 5554ad7e9b0SAdrian Chadd * 5564ad7e9b0SAdrian Chadd * If @p child is not a direct child of @p dev, suspension is delegated to 5574ad7e9b0SAdrian Chadd * the @p dev parent. 5584ad7e9b0SAdrian Chadd */ 5594ad7e9b0SAdrian Chadd int 5604ad7e9b0SAdrian Chadd bhnd_generic_suspend_child(device_t dev, device_t child) 5614ad7e9b0SAdrian Chadd { 5624ad7e9b0SAdrian Chadd if (device_get_parent(child) != dev) 5634ad7e9b0SAdrian Chadd BUS_SUSPEND_CHILD(device_get_parent(dev), child); 5644ad7e9b0SAdrian Chadd 5654ad7e9b0SAdrian Chadd return bus_generic_suspend_child(dev, child); 5664ad7e9b0SAdrian Chadd } 5674ad7e9b0SAdrian Chadd 5684ad7e9b0SAdrian Chadd /** 5694ad7e9b0SAdrian Chadd * Helper function for implementing BUS_RESUME_CHILD(). 5704ad7e9b0SAdrian Chadd * 5714ad7e9b0SAdrian Chadd * TODO: Power management 5724ad7e9b0SAdrian Chadd * 5734ad7e9b0SAdrian Chadd * If @p child is not a direct child of @p dev, suspension is delegated to 5744ad7e9b0SAdrian Chadd * the @p dev parent. 5754ad7e9b0SAdrian Chadd */ 5764ad7e9b0SAdrian Chadd int 5774ad7e9b0SAdrian Chadd bhnd_generic_resume_child(device_t dev, device_t child) 5784ad7e9b0SAdrian Chadd { 5794ad7e9b0SAdrian Chadd if (device_get_parent(child) != dev) 5804ad7e9b0SAdrian Chadd BUS_RESUME_CHILD(device_get_parent(dev), child); 5814ad7e9b0SAdrian Chadd 5824ad7e9b0SAdrian Chadd return bus_generic_resume_child(dev, child); 5834ad7e9b0SAdrian Chadd } 5844ad7e9b0SAdrian Chadd 5854ad7e9b0SAdrian Chadd /* 5864ad7e9b0SAdrian Chadd * Delegate all indirect I/O to the parent device. When inherited by 5874ad7e9b0SAdrian Chadd * non-bridged bus implementations, resources will never be marked as 5884ad7e9b0SAdrian Chadd * indirect, and these methods should never be called. 5894ad7e9b0SAdrian Chadd */ 5904ad7e9b0SAdrian Chadd 5914ad7e9b0SAdrian Chadd static uint8_t 5924ad7e9b0SAdrian Chadd bhnd_read_1(device_t dev, device_t child, struct bhnd_resource *r, 5934ad7e9b0SAdrian Chadd bus_size_t offset) 5944ad7e9b0SAdrian Chadd { 5954ad7e9b0SAdrian Chadd return (BHND_BUS_READ_1(device_get_parent(dev), child, r, offset)); 5964ad7e9b0SAdrian Chadd } 5974ad7e9b0SAdrian Chadd 5984ad7e9b0SAdrian Chadd static uint16_t 5994ad7e9b0SAdrian Chadd bhnd_read_2(device_t dev, device_t child, struct bhnd_resource *r, 6004ad7e9b0SAdrian Chadd bus_size_t offset) 6014ad7e9b0SAdrian Chadd { 6024ad7e9b0SAdrian Chadd return (BHND_BUS_READ_2(device_get_parent(dev), child, r, offset)); 6034ad7e9b0SAdrian Chadd } 6044ad7e9b0SAdrian Chadd 6054ad7e9b0SAdrian Chadd static uint32_t 6064ad7e9b0SAdrian Chadd bhnd_read_4(device_t dev, device_t child, struct bhnd_resource *r, 6074ad7e9b0SAdrian Chadd bus_size_t offset) 6084ad7e9b0SAdrian Chadd { 6094ad7e9b0SAdrian Chadd return (BHND_BUS_READ_4(device_get_parent(dev), child, r, offset)); 6104ad7e9b0SAdrian Chadd } 6114ad7e9b0SAdrian Chadd 6124ad7e9b0SAdrian Chadd static void 6134ad7e9b0SAdrian Chadd bhnd_write_1(device_t dev, device_t child, struct bhnd_resource *r, 6144ad7e9b0SAdrian Chadd bus_size_t offset, uint8_t value) 6154ad7e9b0SAdrian Chadd { 6164ad7e9b0SAdrian Chadd BHND_BUS_WRITE_1(device_get_parent(dev), child, r, offset, value); 6174ad7e9b0SAdrian Chadd } 6184ad7e9b0SAdrian Chadd 6194ad7e9b0SAdrian Chadd static void 6204ad7e9b0SAdrian Chadd bhnd_write_2(device_t dev, device_t child, struct bhnd_resource *r, 6214ad7e9b0SAdrian Chadd bus_size_t offset, uint16_t value) 6224ad7e9b0SAdrian Chadd { 6234ad7e9b0SAdrian Chadd BHND_BUS_WRITE_2(device_get_parent(dev), child, r, offset, value); 6244ad7e9b0SAdrian Chadd } 6254ad7e9b0SAdrian Chadd 6264ad7e9b0SAdrian Chadd static void 6274ad7e9b0SAdrian Chadd bhnd_write_4(device_t dev, device_t child, struct bhnd_resource *r, 6284ad7e9b0SAdrian Chadd bus_size_t offset, uint32_t value) 6294ad7e9b0SAdrian Chadd { 6304ad7e9b0SAdrian Chadd BHND_BUS_WRITE_4(device_get_parent(dev), child, r, offset, value); 6314ad7e9b0SAdrian Chadd } 6324ad7e9b0SAdrian Chadd 6334ad7e9b0SAdrian Chadd static void 6344ad7e9b0SAdrian Chadd bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r, 6354ad7e9b0SAdrian Chadd bus_size_t offset, bus_size_t length, int flags) 6364ad7e9b0SAdrian Chadd { 6374ad7e9b0SAdrian Chadd BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length, 6384ad7e9b0SAdrian Chadd flags); 6394ad7e9b0SAdrian Chadd } 6404ad7e9b0SAdrian Chadd 6414ad7e9b0SAdrian Chadd static device_method_t bhnd_methods[] = { 6424ad7e9b0SAdrian Chadd /* Device interface */ \ 6434ad7e9b0SAdrian Chadd DEVMETHOD(device_attach, bhnd_generic_attach), 6444ad7e9b0SAdrian Chadd DEVMETHOD(device_detach, bhnd_generic_detach), 6454ad7e9b0SAdrian Chadd DEVMETHOD(device_shutdown, bhnd_generic_shutdown), 6464ad7e9b0SAdrian Chadd DEVMETHOD(device_suspend, bhnd_generic_suspend), 6474ad7e9b0SAdrian Chadd DEVMETHOD(device_resume, bhnd_generic_resume), 6484ad7e9b0SAdrian Chadd 6494ad7e9b0SAdrian Chadd /* Bus interface */ 6504ad7e9b0SAdrian Chadd DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), 6514ad7e9b0SAdrian Chadd DEVMETHOD(bus_print_child, bhnd_generic_print_child), 6524ad7e9b0SAdrian Chadd DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str), 6534ad7e9b0SAdrian Chadd DEVMETHOD(bus_child_location_str, bhnd_child_location_str), 6544ad7e9b0SAdrian Chadd 6554ad7e9b0SAdrian Chadd DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child), 6564ad7e9b0SAdrian Chadd DEVMETHOD(bus_resume_child, bhnd_generic_resume_child), 6574ad7e9b0SAdrian Chadd 6584ad7e9b0SAdrian Chadd DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 6594ad7e9b0SAdrian Chadd DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 6604ad7e9b0SAdrian Chadd DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 6614ad7e9b0SAdrian Chadd DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 6624ad7e9b0SAdrian Chadd DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 6634ad7e9b0SAdrian Chadd DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 6644ad7e9b0SAdrian Chadd DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 6654ad7e9b0SAdrian Chadd DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 6664ad7e9b0SAdrian Chadd 6674ad7e9b0SAdrian Chadd DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 6684ad7e9b0SAdrian Chadd DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 6694ad7e9b0SAdrian Chadd DEVMETHOD(bus_config_intr, bus_generic_config_intr), 6704ad7e9b0SAdrian Chadd DEVMETHOD(bus_bind_intr, bus_generic_bind_intr), 6714ad7e9b0SAdrian Chadd DEVMETHOD(bus_describe_intr, bus_generic_describe_intr), 6724ad7e9b0SAdrian Chadd 6734ad7e9b0SAdrian Chadd DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), 6744ad7e9b0SAdrian Chadd 6754ad7e9b0SAdrian Chadd /* BHND interface */ 676386fb140SAdrian Chadd DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid), 6774ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order), 678386fb140SAdrian Chadd DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), 679386fb140SAdrian Chadd DEVMETHOD(bhnd_bus_is_hostb_device, bhnd_bus_generic_is_hostb_device), 680386fb140SAdrian Chadd DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), 681386fb140SAdrian Chadd DEVMETHOD(bhnd_bus_read_nvram_var, bhnd_generic_read_nvram_var), 6824ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_read_1, bhnd_read_1), 6834ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_read_2, bhnd_read_2), 6844ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_read_4, bhnd_read_4), 6854ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_write_1, bhnd_write_1), 6864ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_write_2, bhnd_write_2), 6874ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_write_4, bhnd_write_4), 6884ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), 6894ad7e9b0SAdrian Chadd 6904ad7e9b0SAdrian Chadd DEVMETHOD_END 6914ad7e9b0SAdrian Chadd }; 6924ad7e9b0SAdrian Chadd 6934ad7e9b0SAdrian Chadd devclass_t bhnd_devclass; /**< bhnd bus. */ 6944ad7e9b0SAdrian Chadd devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */ 6954ad7e9b0SAdrian Chadd devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */ 6964ad7e9b0SAdrian Chadd 6974ad7e9b0SAdrian Chadd DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc)); 6984ad7e9b0SAdrian Chadd MODULE_VERSION(bhnd, 1); 699