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 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures"); 654ad7e9b0SAdrian Chadd 664ad7e9b0SAdrian Chadd /** 674ad7e9b0SAdrian Chadd * bhnd_generic_probe_nomatch() reporting configuration. 684ad7e9b0SAdrian Chadd */ 694ad7e9b0SAdrian Chadd static const struct bhnd_nomatch { 704ad7e9b0SAdrian Chadd uint16_t vendor; /**< core designer */ 714ad7e9b0SAdrian Chadd uint16_t device; /**< core id */ 724ad7e9b0SAdrian Chadd bool if_verbose; /**< print when bootverbose is set. */ 734ad7e9b0SAdrian Chadd } bhnd_nomatch_table[] = { 744ad7e9b0SAdrian Chadd { BHND_MFGID_ARM, BHND_COREID_OOB_ROUTER, true }, 754ad7e9b0SAdrian Chadd { BHND_MFGID_ARM, BHND_COREID_EROM, true }, 764ad7e9b0SAdrian Chadd { BHND_MFGID_ARM, BHND_COREID_PL301, true }, 774ad7e9b0SAdrian Chadd { BHND_MFGID_ARM, BHND_COREID_APB_BRIDGE, true }, 784ad7e9b0SAdrian Chadd { BHND_MFGID_ARM, BHND_COREID_AXI_UNMAPPED, false }, 794ad7e9b0SAdrian Chadd 804ad7e9b0SAdrian Chadd { BHND_MFGID_INVALID, BHND_COREID_INVALID, false } 814ad7e9b0SAdrian Chadd }; 824ad7e9b0SAdrian Chadd 834ad7e9b0SAdrian Chadd static int compare_ascending_probe_order(const void *lhs, 844ad7e9b0SAdrian Chadd const void *rhs); 854ad7e9b0SAdrian Chadd static int compare_descending_probe_order(const void *lhs, 864ad7e9b0SAdrian Chadd const void *rhs); 874ad7e9b0SAdrian Chadd 884ad7e9b0SAdrian Chadd /** 89386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of DEVICE_ATTACH(). 904ad7e9b0SAdrian Chadd * 91386fb140SAdrian Chadd * This implementation calls device_probe_and_attach() for each of the device's 92386fb140SAdrian Chadd * children, in bhnd probe order. 934ad7e9b0SAdrian Chadd */ 944ad7e9b0SAdrian Chadd int 954ad7e9b0SAdrian Chadd bhnd_generic_attach(device_t dev) 964ad7e9b0SAdrian Chadd { 974ad7e9b0SAdrian Chadd device_t *devs; 984ad7e9b0SAdrian Chadd int ndevs; 994ad7e9b0SAdrian Chadd int error; 1004ad7e9b0SAdrian Chadd 1014ad7e9b0SAdrian Chadd if (device_is_attached(dev)) 1024ad7e9b0SAdrian Chadd return (EBUSY); 1034ad7e9b0SAdrian Chadd 1044ad7e9b0SAdrian Chadd if ((error = device_get_children(dev, &devs, &ndevs))) 1054ad7e9b0SAdrian Chadd return (error); 1064ad7e9b0SAdrian Chadd 1074ad7e9b0SAdrian Chadd qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 1084ad7e9b0SAdrian Chadd for (int i = 0; i < ndevs; i++) { 1094ad7e9b0SAdrian Chadd device_t child = devs[i]; 1104ad7e9b0SAdrian Chadd device_probe_and_attach(child); 1114ad7e9b0SAdrian Chadd } 1124ad7e9b0SAdrian Chadd 1134ad7e9b0SAdrian Chadd free(devs, M_TEMP); 1144ad7e9b0SAdrian Chadd return (0); 1154ad7e9b0SAdrian Chadd } 1164ad7e9b0SAdrian Chadd 1174ad7e9b0SAdrian Chadd /** 118386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of DEVICE_DETACH(). 1194ad7e9b0SAdrian Chadd * 120*cef367e6SEitan Adler * This implementation calls device_detach() for each of the device's 121386fb140SAdrian Chadd * children, in reverse bhnd probe order, terminating if any call to 122386fb140SAdrian Chadd * device_detach() fails. 1234ad7e9b0SAdrian Chadd */ 1244ad7e9b0SAdrian Chadd int 1254ad7e9b0SAdrian Chadd bhnd_generic_detach(device_t dev) 1264ad7e9b0SAdrian Chadd { 1274ad7e9b0SAdrian Chadd device_t *devs; 1284ad7e9b0SAdrian Chadd int ndevs; 1294ad7e9b0SAdrian Chadd int error; 1304ad7e9b0SAdrian Chadd 1314ad7e9b0SAdrian Chadd if (!device_is_attached(dev)) 1324ad7e9b0SAdrian Chadd return (EBUSY); 1334ad7e9b0SAdrian Chadd 1344ad7e9b0SAdrian Chadd if ((error = device_get_children(dev, &devs, &ndevs))) 1354ad7e9b0SAdrian Chadd return (error); 1364ad7e9b0SAdrian Chadd 1374ad7e9b0SAdrian Chadd /* Detach in the reverse of attach order */ 1384ad7e9b0SAdrian Chadd qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 1394ad7e9b0SAdrian Chadd for (int i = 0; i < ndevs; i++) { 1404ad7e9b0SAdrian Chadd device_t child = devs[i]; 1414ad7e9b0SAdrian Chadd 1424ad7e9b0SAdrian Chadd /* Terminate on first error */ 1434ad7e9b0SAdrian Chadd if ((error = device_detach(child))) 1444ad7e9b0SAdrian Chadd goto cleanup; 1454ad7e9b0SAdrian Chadd } 1464ad7e9b0SAdrian Chadd 1474ad7e9b0SAdrian Chadd cleanup: 1484ad7e9b0SAdrian Chadd free(devs, M_TEMP); 1494ad7e9b0SAdrian Chadd return (error); 1504ad7e9b0SAdrian Chadd } 1514ad7e9b0SAdrian Chadd 1524ad7e9b0SAdrian Chadd /** 153386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN(). 1544ad7e9b0SAdrian Chadd * 155386fb140SAdrian Chadd * This implementation calls device_shutdown() for each of the device's 156386fb140SAdrian Chadd * children, in reverse bhnd probe order, terminating if any call to 157386fb140SAdrian Chadd * device_shutdown() fails. 1584ad7e9b0SAdrian Chadd */ 1594ad7e9b0SAdrian Chadd int 1604ad7e9b0SAdrian Chadd bhnd_generic_shutdown(device_t dev) 1614ad7e9b0SAdrian Chadd { 1624ad7e9b0SAdrian Chadd device_t *devs; 1634ad7e9b0SAdrian Chadd int ndevs; 1644ad7e9b0SAdrian Chadd int error; 1654ad7e9b0SAdrian Chadd 1664ad7e9b0SAdrian Chadd if (!device_is_attached(dev)) 1674ad7e9b0SAdrian Chadd return (EBUSY); 1684ad7e9b0SAdrian Chadd 1694ad7e9b0SAdrian Chadd if ((error = device_get_children(dev, &devs, &ndevs))) 1704ad7e9b0SAdrian Chadd return (error); 1714ad7e9b0SAdrian Chadd 1724ad7e9b0SAdrian Chadd /* Shutdown in the reverse of attach order */ 1734ad7e9b0SAdrian Chadd qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 1744ad7e9b0SAdrian Chadd for (int i = 0; i < ndevs; i++) { 1754ad7e9b0SAdrian Chadd device_t child = devs[i]; 1764ad7e9b0SAdrian Chadd 1774ad7e9b0SAdrian Chadd /* Terminate on first error */ 1784ad7e9b0SAdrian Chadd if ((error = device_shutdown(child))) 1794ad7e9b0SAdrian Chadd goto cleanup; 1804ad7e9b0SAdrian Chadd } 1814ad7e9b0SAdrian Chadd 1824ad7e9b0SAdrian Chadd cleanup: 1834ad7e9b0SAdrian Chadd free(devs, M_TEMP); 1844ad7e9b0SAdrian Chadd return (error); 1854ad7e9b0SAdrian Chadd } 1864ad7e9b0SAdrian Chadd 1874ad7e9b0SAdrian Chadd /** 188386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of DEVICE_RESUME(). 1894ad7e9b0SAdrian Chadd * 190386fb140SAdrian Chadd * This implementation calls BUS_RESUME_CHILD() for each of the device's 191386fb140SAdrian Chadd * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD() 192386fb140SAdrian Chadd * fails. 1934ad7e9b0SAdrian Chadd */ 1944ad7e9b0SAdrian Chadd int 1954ad7e9b0SAdrian Chadd bhnd_generic_resume(device_t dev) 1964ad7e9b0SAdrian Chadd { 1974ad7e9b0SAdrian Chadd device_t *devs; 1984ad7e9b0SAdrian Chadd int ndevs; 1994ad7e9b0SAdrian Chadd int error; 2004ad7e9b0SAdrian Chadd 2014ad7e9b0SAdrian Chadd if (!device_is_attached(dev)) 2024ad7e9b0SAdrian Chadd return (EBUSY); 2034ad7e9b0SAdrian Chadd 2044ad7e9b0SAdrian Chadd if ((error = device_get_children(dev, &devs, &ndevs))) 2054ad7e9b0SAdrian Chadd return (error); 2064ad7e9b0SAdrian Chadd 2074ad7e9b0SAdrian Chadd qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order); 2084ad7e9b0SAdrian Chadd for (int i = 0; i < ndevs; i++) { 2094ad7e9b0SAdrian Chadd device_t child = devs[i]; 2104ad7e9b0SAdrian Chadd 2114ad7e9b0SAdrian Chadd /* Terminate on first error */ 2124ad7e9b0SAdrian Chadd if ((error = BUS_RESUME_CHILD(device_get_parent(child), child))) 2134ad7e9b0SAdrian Chadd goto cleanup; 2144ad7e9b0SAdrian Chadd } 2154ad7e9b0SAdrian Chadd 2164ad7e9b0SAdrian Chadd cleanup: 2174ad7e9b0SAdrian Chadd free(devs, M_TEMP); 2184ad7e9b0SAdrian Chadd return (error); 2194ad7e9b0SAdrian Chadd } 2204ad7e9b0SAdrian Chadd 2214ad7e9b0SAdrian Chadd /** 222386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND(). 2234ad7e9b0SAdrian Chadd * 224386fb140SAdrian Chadd * This implementation calls BUS_SUSPEND_CHILD() for each of the device's 225386fb140SAdrian Chadd * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD() 226386fb140SAdrian Chadd * fails, the suspend operation is terminated and any devices that were 227386fb140SAdrian Chadd * suspended are resumed immediately by calling their BUS_RESUME_CHILD() 228386fb140SAdrian Chadd * methods. 2294ad7e9b0SAdrian Chadd */ 2304ad7e9b0SAdrian Chadd int 2314ad7e9b0SAdrian Chadd bhnd_generic_suspend(device_t dev) 2324ad7e9b0SAdrian Chadd { 2334ad7e9b0SAdrian Chadd device_t *devs; 2344ad7e9b0SAdrian Chadd int ndevs; 2354ad7e9b0SAdrian Chadd int error; 2364ad7e9b0SAdrian Chadd 2374ad7e9b0SAdrian Chadd if (!device_is_attached(dev)) 2384ad7e9b0SAdrian Chadd return (EBUSY); 2394ad7e9b0SAdrian Chadd 2404ad7e9b0SAdrian Chadd if ((error = device_get_children(dev, &devs, &ndevs))) 2414ad7e9b0SAdrian Chadd return (error); 2424ad7e9b0SAdrian Chadd 2434ad7e9b0SAdrian Chadd /* Suspend in the reverse of attach order */ 2444ad7e9b0SAdrian Chadd qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order); 2454ad7e9b0SAdrian Chadd for (int i = 0; i < ndevs; i++) { 2464ad7e9b0SAdrian Chadd device_t child = devs[i]; 2474ad7e9b0SAdrian Chadd error = BUS_SUSPEND_CHILD(device_get_parent(child), child); 2484ad7e9b0SAdrian Chadd 2494ad7e9b0SAdrian Chadd /* On error, resume suspended devices and then terminate */ 2504ad7e9b0SAdrian Chadd if (error) { 2514ad7e9b0SAdrian Chadd for (int j = 0; j < i; j++) { 2524ad7e9b0SAdrian Chadd BUS_RESUME_CHILD(device_get_parent(devs[j]), 2534ad7e9b0SAdrian Chadd devs[j]); 2544ad7e9b0SAdrian Chadd } 2554ad7e9b0SAdrian Chadd 2564ad7e9b0SAdrian Chadd goto cleanup; 2574ad7e9b0SAdrian Chadd } 2584ad7e9b0SAdrian Chadd } 2594ad7e9b0SAdrian Chadd 2604ad7e9b0SAdrian Chadd cleanup: 2614ad7e9b0SAdrian Chadd free(devs, M_TEMP); 2624ad7e9b0SAdrian Chadd return (error); 2634ad7e9b0SAdrian Chadd } 2644ad7e9b0SAdrian Chadd 2654ad7e9b0SAdrian Chadd /* 2664ad7e9b0SAdrian Chadd * Ascending comparison of bhnd device's probe order. 2674ad7e9b0SAdrian Chadd */ 2684ad7e9b0SAdrian Chadd static int 2694ad7e9b0SAdrian Chadd compare_ascending_probe_order(const void *lhs, const void *rhs) 2704ad7e9b0SAdrian Chadd { 2714ad7e9b0SAdrian Chadd device_t ldev, rdev; 2724ad7e9b0SAdrian Chadd int lorder, rorder; 2734ad7e9b0SAdrian Chadd 2744ad7e9b0SAdrian Chadd ldev = (*(const device_t *) lhs); 2754ad7e9b0SAdrian Chadd rdev = (*(const device_t *) rhs); 2764ad7e9b0SAdrian Chadd 2774ad7e9b0SAdrian Chadd lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev); 2784ad7e9b0SAdrian Chadd rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev); 2794ad7e9b0SAdrian Chadd 2804ad7e9b0SAdrian Chadd if (lorder < rorder) { 2814ad7e9b0SAdrian Chadd return (-1); 2824ad7e9b0SAdrian Chadd } else if (lorder > rorder) { 2834ad7e9b0SAdrian Chadd return (1); 2844ad7e9b0SAdrian Chadd } else { 2854ad7e9b0SAdrian Chadd return (0); 2864ad7e9b0SAdrian Chadd } 2874ad7e9b0SAdrian Chadd } 2884ad7e9b0SAdrian Chadd 2894ad7e9b0SAdrian Chadd /* 2904ad7e9b0SAdrian Chadd * Descending comparison of bhnd device's probe order. 2914ad7e9b0SAdrian Chadd */ 2924ad7e9b0SAdrian Chadd static int 2934ad7e9b0SAdrian Chadd compare_descending_probe_order(const void *lhs, const void *rhs) 2944ad7e9b0SAdrian Chadd { 2954ad7e9b0SAdrian Chadd return (compare_ascending_probe_order(rhs, lhs)); 2964ad7e9b0SAdrian Chadd } 2974ad7e9b0SAdrian Chadd 2984ad7e9b0SAdrian Chadd /** 299386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER(). 3004ad7e9b0SAdrian Chadd * 3014ad7e9b0SAdrian Chadd * This implementation determines probe ordering based on the device's class 3024ad7e9b0SAdrian Chadd * and other properties, including whether the device is serving as a host 3034ad7e9b0SAdrian Chadd * bridge. 3044ad7e9b0SAdrian Chadd */ 3054ad7e9b0SAdrian Chadd int 3064ad7e9b0SAdrian Chadd bhnd_generic_get_probe_order(device_t dev, device_t child) 3074ad7e9b0SAdrian Chadd { 3084ad7e9b0SAdrian Chadd switch (bhnd_get_class(child)) { 3094ad7e9b0SAdrian Chadd case BHND_DEVCLASS_CC: 310d567592bSAdrian Chadd /* Must be early enough to provide NVRAM access to the 311d567592bSAdrian Chadd * host bridge */ 312d567592bSAdrian Chadd return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST); 3134ad7e9b0SAdrian Chadd 3144ad7e9b0SAdrian Chadd case BHND_DEVCLASS_CC_B: 3154ad7e9b0SAdrian Chadd /* fall through */ 3164ad7e9b0SAdrian Chadd case BHND_DEVCLASS_PMU: 3174ad7e9b0SAdrian Chadd return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY); 3184ad7e9b0SAdrian Chadd 3194ad7e9b0SAdrian Chadd case BHND_DEVCLASS_SOC_ROUTER: 3204ad7e9b0SAdrian Chadd return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE); 3214ad7e9b0SAdrian Chadd 3224ad7e9b0SAdrian Chadd case BHND_DEVCLASS_SOC_BRIDGE: 3234ad7e9b0SAdrian Chadd return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST); 3244ad7e9b0SAdrian Chadd 3254ad7e9b0SAdrian Chadd case BHND_DEVCLASS_CPU: 3264ad7e9b0SAdrian Chadd return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST); 3274ad7e9b0SAdrian Chadd 3284ad7e9b0SAdrian Chadd case BHND_DEVCLASS_RAM: 3294ad7e9b0SAdrian Chadd /* fall through */ 3304ad7e9b0SAdrian Chadd case BHND_DEVCLASS_MEMC: 3314ad7e9b0SAdrian Chadd return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY); 3324ad7e9b0SAdrian Chadd 3334ad7e9b0SAdrian Chadd case BHND_DEVCLASS_NVRAM: 3344ad7e9b0SAdrian Chadd return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY); 3354ad7e9b0SAdrian Chadd 3364ad7e9b0SAdrian Chadd case BHND_DEVCLASS_PCI: 3374ad7e9b0SAdrian Chadd case BHND_DEVCLASS_PCIE: 3384ad7e9b0SAdrian Chadd case BHND_DEVCLASS_PCCARD: 3394ad7e9b0SAdrian Chadd case BHND_DEVCLASS_ENET: 3404ad7e9b0SAdrian Chadd case BHND_DEVCLASS_ENET_MAC: 3414ad7e9b0SAdrian Chadd case BHND_DEVCLASS_ENET_PHY: 3424ad7e9b0SAdrian Chadd case BHND_DEVCLASS_WLAN: 3434ad7e9b0SAdrian Chadd case BHND_DEVCLASS_WLAN_MAC: 3444ad7e9b0SAdrian Chadd case BHND_DEVCLASS_WLAN_PHY: 3454ad7e9b0SAdrian Chadd case BHND_DEVCLASS_EROM: 3464ad7e9b0SAdrian Chadd case BHND_DEVCLASS_OTHER: 3474ad7e9b0SAdrian Chadd case BHND_DEVCLASS_INVALID: 348d9352570SAdrian Chadd if (bhnd_find_hostb_device(dev) == child) 3494ad7e9b0SAdrian Chadd return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY); 3504ad7e9b0SAdrian Chadd 3514ad7e9b0SAdrian Chadd return (BHND_PROBE_DEFAULT); 352054ae231SAdrian Chadd default: 353054ae231SAdrian Chadd return (BHND_PROBE_DEFAULT); 3544ad7e9b0SAdrian Chadd } 3554ad7e9b0SAdrian Chadd } 3564ad7e9b0SAdrian Chadd 3574ad7e9b0SAdrian Chadd /** 358386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID(). 3594ad7e9b0SAdrian Chadd * 3604ad7e9b0SAdrian Chadd * This implementation assumes that port and region numbers are 0-indexed and 3614ad7e9b0SAdrian Chadd * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and 3624ad7e9b0SAdrian Chadd * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall 3634ad7e9b0SAdrian Chadd * within the defined range. 3644ad7e9b0SAdrian Chadd */ 365386fb140SAdrian Chadd static bool 3664ad7e9b0SAdrian Chadd bhnd_generic_is_region_valid(device_t dev, device_t child, 3674ad7e9b0SAdrian Chadd bhnd_port_type type, u_int port, u_int region) 3684ad7e9b0SAdrian Chadd { 3694ad7e9b0SAdrian Chadd if (port >= bhnd_get_port_count(child, type)) 3704ad7e9b0SAdrian Chadd return (false); 3714ad7e9b0SAdrian Chadd 3724ad7e9b0SAdrian Chadd if (region >= bhnd_get_region_count(child, type, port)) 3734ad7e9b0SAdrian Chadd return (false); 3744ad7e9b0SAdrian Chadd 3754ad7e9b0SAdrian Chadd return (true); 3764ad7e9b0SAdrian Chadd } 3774ad7e9b0SAdrian Chadd 3784ad7e9b0SAdrian Chadd /** 379386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD(). 3804ad7e9b0SAdrian Chadd * 3814ad7e9b0SAdrian Chadd * This implementation requests the device's struct resource_list via 3824ad7e9b0SAdrian Chadd * BUS_GET_RESOURCE_LIST. 3834ad7e9b0SAdrian Chadd */ 3844ad7e9b0SAdrian Chadd int 3854ad7e9b0SAdrian Chadd bhnd_generic_print_child(device_t dev, device_t child) 3864ad7e9b0SAdrian Chadd { 3874ad7e9b0SAdrian Chadd struct resource_list *rl; 3884ad7e9b0SAdrian Chadd int retval = 0; 3894ad7e9b0SAdrian Chadd 3904ad7e9b0SAdrian Chadd retval += bus_print_child_header(dev, child); 3914ad7e9b0SAdrian Chadd 3924ad7e9b0SAdrian Chadd rl = BUS_GET_RESOURCE_LIST(dev, child); 3934ad7e9b0SAdrian Chadd if (rl != NULL) { 3944ad7e9b0SAdrian Chadd retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, 395f8fd3fb5SJustin Hibbits "%#jx"); 3964ad7e9b0SAdrian Chadd } 3974ad7e9b0SAdrian Chadd 3984ad7e9b0SAdrian Chadd retval += printf(" at core %u", bhnd_get_core_index(child)); 3994ad7e9b0SAdrian Chadd 4004ad7e9b0SAdrian Chadd retval += bus_print_child_domain(dev, child); 4014ad7e9b0SAdrian Chadd retval += bus_print_child_footer(dev, child); 4024ad7e9b0SAdrian Chadd 4034ad7e9b0SAdrian Chadd return (retval); 4044ad7e9b0SAdrian Chadd } 4054ad7e9b0SAdrian Chadd 4064ad7e9b0SAdrian Chadd /** 407386fb140SAdrian Chadd * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH(). 4084ad7e9b0SAdrian Chadd * 4094ad7e9b0SAdrian Chadd * This implementation requests the device's struct resource_list via 4104ad7e9b0SAdrian Chadd * BUS_GET_RESOURCE_LIST. 4114ad7e9b0SAdrian Chadd */ 4124ad7e9b0SAdrian Chadd void 4134ad7e9b0SAdrian Chadd bhnd_generic_probe_nomatch(device_t dev, device_t child) 4144ad7e9b0SAdrian Chadd { 4154ad7e9b0SAdrian Chadd struct resource_list *rl; 4164ad7e9b0SAdrian Chadd const struct bhnd_nomatch *nm; 4174ad7e9b0SAdrian Chadd bool report; 4184ad7e9b0SAdrian Chadd 4194ad7e9b0SAdrian Chadd /* Fetch reporting configuration for this device */ 4204ad7e9b0SAdrian Chadd report = true; 4214ad7e9b0SAdrian Chadd for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) { 4224ad7e9b0SAdrian Chadd if (nm->vendor != bhnd_get_vendor(child)) 4234ad7e9b0SAdrian Chadd continue; 4244ad7e9b0SAdrian Chadd 4254ad7e9b0SAdrian Chadd if (nm->device != bhnd_get_device(child)) 4264ad7e9b0SAdrian Chadd continue; 4274ad7e9b0SAdrian Chadd 4284ad7e9b0SAdrian Chadd report = false; 4294ad7e9b0SAdrian Chadd if (bootverbose && nm->if_verbose) 4304ad7e9b0SAdrian Chadd report = true; 4314ad7e9b0SAdrian Chadd break; 4324ad7e9b0SAdrian Chadd } 4334ad7e9b0SAdrian Chadd 4344ad7e9b0SAdrian Chadd if (!report) 4354ad7e9b0SAdrian Chadd return; 4364ad7e9b0SAdrian Chadd 4374ad7e9b0SAdrian Chadd /* Print the non-matched device info */ 4384ad7e9b0SAdrian Chadd device_printf(dev, "<%s %s>", bhnd_get_vendor_name(child), 4394ad7e9b0SAdrian Chadd bhnd_get_device_name(child)); 4404ad7e9b0SAdrian Chadd 4414ad7e9b0SAdrian Chadd rl = BUS_GET_RESOURCE_LIST(dev, child); 4424ad7e9b0SAdrian Chadd if (rl != NULL) 443f8fd3fb5SJustin Hibbits resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx"); 4444ad7e9b0SAdrian Chadd 4454ad7e9b0SAdrian Chadd printf(" at core %u (no driver attached)\n", 4464ad7e9b0SAdrian Chadd bhnd_get_core_index(child)); 4474ad7e9b0SAdrian Chadd } 4484ad7e9b0SAdrian Chadd 4494ad7e9b0SAdrian Chadd /** 4504ad7e9b0SAdrian Chadd * Default implementation of BUS_CHILD_PNPINFO_STR(). 4514ad7e9b0SAdrian Chadd */ 4524ad7e9b0SAdrian Chadd static int 4534ad7e9b0SAdrian Chadd bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf, 4544ad7e9b0SAdrian Chadd size_t buflen) 4554ad7e9b0SAdrian Chadd { 4564ad7e9b0SAdrian Chadd if (device_get_parent(child) != dev) { 4574ad7e9b0SAdrian Chadd return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child, 4584ad7e9b0SAdrian Chadd buf, buflen)); 4594ad7e9b0SAdrian Chadd } 4604ad7e9b0SAdrian Chadd 4614ad7e9b0SAdrian Chadd snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx", 4624ad7e9b0SAdrian Chadd bhnd_get_vendor(child), bhnd_get_device(child), 4634ad7e9b0SAdrian Chadd bhnd_get_hwrev(child)); 4644ad7e9b0SAdrian Chadd 4654ad7e9b0SAdrian Chadd return (0); 4664ad7e9b0SAdrian Chadd } 4674ad7e9b0SAdrian Chadd 4684ad7e9b0SAdrian Chadd /** 469386fb140SAdrian Chadd * Default implementation of BUS_CHILD_LOCATION_STR(). 4704ad7e9b0SAdrian Chadd */ 4714ad7e9b0SAdrian Chadd static int 4724ad7e9b0SAdrian Chadd bhnd_child_location_str(device_t dev, device_t child, char *buf, 4734ad7e9b0SAdrian Chadd size_t buflen) 4744ad7e9b0SAdrian Chadd { 4754ad7e9b0SAdrian Chadd bhnd_addr_t addr; 4764ad7e9b0SAdrian Chadd bhnd_size_t size; 4774ad7e9b0SAdrian Chadd 4784ad7e9b0SAdrian Chadd if (device_get_parent(child) != dev) { 4794ad7e9b0SAdrian Chadd return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child, 4804ad7e9b0SAdrian Chadd buf, buflen)); 4814ad7e9b0SAdrian Chadd } 4824ad7e9b0SAdrian Chadd 4834ad7e9b0SAdrian Chadd 4844ad7e9b0SAdrian Chadd if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) { 4854ad7e9b0SAdrian Chadd /* No device default port/region */ 4864ad7e9b0SAdrian Chadd if (buflen > 0) 4874ad7e9b0SAdrian Chadd *buf = '\0'; 4884ad7e9b0SAdrian Chadd return (0); 4894ad7e9b0SAdrian Chadd } 4904ad7e9b0SAdrian Chadd 4914ad7e9b0SAdrian Chadd snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr); 4924ad7e9b0SAdrian Chadd return (0); 4934ad7e9b0SAdrian Chadd } 4944ad7e9b0SAdrian Chadd 4954ad7e9b0SAdrian Chadd /** 4964ad7e9b0SAdrian Chadd * Helper function for implementing BUS_SUSPEND_CHILD(). 4974ad7e9b0SAdrian Chadd * 4984ad7e9b0SAdrian Chadd * TODO: Power management 4994ad7e9b0SAdrian Chadd * 5004ad7e9b0SAdrian Chadd * If @p child is not a direct child of @p dev, suspension is delegated to 5014ad7e9b0SAdrian Chadd * the @p dev parent. 5024ad7e9b0SAdrian Chadd */ 5034ad7e9b0SAdrian Chadd int 5044ad7e9b0SAdrian Chadd bhnd_generic_suspend_child(device_t dev, device_t child) 5054ad7e9b0SAdrian Chadd { 5064ad7e9b0SAdrian Chadd if (device_get_parent(child) != dev) 5074ad7e9b0SAdrian Chadd BUS_SUSPEND_CHILD(device_get_parent(dev), child); 5084ad7e9b0SAdrian Chadd 5094ad7e9b0SAdrian Chadd return bus_generic_suspend_child(dev, child); 5104ad7e9b0SAdrian Chadd } 5114ad7e9b0SAdrian Chadd 5124ad7e9b0SAdrian Chadd /** 5134ad7e9b0SAdrian Chadd * Helper function for implementing BUS_RESUME_CHILD(). 5144ad7e9b0SAdrian Chadd * 5154ad7e9b0SAdrian Chadd * TODO: Power management 5164ad7e9b0SAdrian Chadd * 5174ad7e9b0SAdrian Chadd * If @p child is not a direct child of @p dev, suspension is delegated to 5184ad7e9b0SAdrian Chadd * the @p dev parent. 5194ad7e9b0SAdrian Chadd */ 5204ad7e9b0SAdrian Chadd int 5214ad7e9b0SAdrian Chadd bhnd_generic_resume_child(device_t dev, device_t child) 5224ad7e9b0SAdrian Chadd { 5234ad7e9b0SAdrian Chadd if (device_get_parent(child) != dev) 5244ad7e9b0SAdrian Chadd BUS_RESUME_CHILD(device_get_parent(dev), child); 5254ad7e9b0SAdrian Chadd 5264ad7e9b0SAdrian Chadd return bus_generic_resume_child(dev, child); 5274ad7e9b0SAdrian Chadd } 5284ad7e9b0SAdrian Chadd 5294ad7e9b0SAdrian Chadd /* 5304ad7e9b0SAdrian Chadd * Delegate all indirect I/O to the parent device. When inherited by 5314ad7e9b0SAdrian Chadd * non-bridged bus implementations, resources will never be marked as 5324ad7e9b0SAdrian Chadd * indirect, and these methods should never be called. 5334ad7e9b0SAdrian Chadd */ 534a73ac06dSAdrian Chadd #define BHND_IO_READ(_type, _name, _method) \ 535a73ac06dSAdrian Chadd static _type \ 536a73ac06dSAdrian Chadd bhnd_read_ ## _name (device_t dev, device_t child, \ 537a73ac06dSAdrian Chadd struct bhnd_resource *r, bus_size_t offset) \ 538a73ac06dSAdrian Chadd { \ 539a73ac06dSAdrian Chadd return (BHND_BUS_READ_ ## _method( \ 540a73ac06dSAdrian Chadd device_get_parent(dev), child, r, offset)); \ 5414ad7e9b0SAdrian Chadd } 5424ad7e9b0SAdrian Chadd 543a73ac06dSAdrian Chadd #define BHND_IO_WRITE(_type, _name, _method) \ 544a73ac06dSAdrian Chadd static void \ 545a73ac06dSAdrian Chadd bhnd_write_ ## _name (device_t dev, device_t child, \ 546a73ac06dSAdrian Chadd struct bhnd_resource *r, bus_size_t offset, _type value) \ 547a73ac06dSAdrian Chadd { \ 548a73ac06dSAdrian Chadd return (BHND_BUS_WRITE_ ## _method( \ 549a73ac06dSAdrian Chadd device_get_parent(dev), child, r, offset, \ 550a73ac06dSAdrian Chadd value)); \ 5514ad7e9b0SAdrian Chadd } 5524ad7e9b0SAdrian Chadd 553a73ac06dSAdrian Chadd #define BHND_IO_MULTI(_type, _rw, _name, _method) \ 554a73ac06dSAdrian Chadd static void \ 555a73ac06dSAdrian Chadd bhnd_ ## _rw ## _multi_ ## _name (device_t dev, device_t child, \ 556a73ac06dSAdrian Chadd struct bhnd_resource *r, bus_size_t offset, _type *datap, \ 557a73ac06dSAdrian Chadd bus_size_t count) \ 558a73ac06dSAdrian Chadd { \ 559a73ac06dSAdrian Chadd BHND_BUS_ ## _method(device_get_parent(dev), child, r, \ 560a73ac06dSAdrian Chadd offset, datap, count); \ 5614ad7e9b0SAdrian Chadd } 5624ad7e9b0SAdrian Chadd 563a73ac06dSAdrian Chadd #define BHND_IO_METHODS(_type, _size) \ 564a73ac06dSAdrian Chadd BHND_IO_READ(_type, _size, _size) \ 565a73ac06dSAdrian Chadd BHND_IO_WRITE(_type, _size, _size) \ 566a73ac06dSAdrian Chadd \ 567a73ac06dSAdrian Chadd BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \ 568a73ac06dSAdrian Chadd BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \ 569a73ac06dSAdrian Chadd \ 570a73ac06dSAdrian Chadd BHND_IO_MULTI(_type, read, _size, READ_MULTI_ ## _size) \ 571a73ac06dSAdrian Chadd BHND_IO_MULTI(_type, write, _size, WRITE_MULTI_ ## _size) \ 572a73ac06dSAdrian Chadd \ 573a73ac06dSAdrian Chadd BHND_IO_MULTI(_type, read, stream_ ## _size, \ 574a73ac06dSAdrian Chadd READ_MULTI_STREAM_ ## _size) \ 575a73ac06dSAdrian Chadd BHND_IO_MULTI(_type, write, stream_ ## _size, \ 576a73ac06dSAdrian Chadd WRITE_MULTI_STREAM_ ## _size) \ 5774ad7e9b0SAdrian Chadd 578a73ac06dSAdrian Chadd BHND_IO_METHODS(uint8_t, 1); 579a73ac06dSAdrian Chadd BHND_IO_METHODS(uint16_t, 2); 580a73ac06dSAdrian Chadd BHND_IO_METHODS(uint32_t, 4); 5814ad7e9b0SAdrian Chadd 5824ad7e9b0SAdrian Chadd static void 5834ad7e9b0SAdrian Chadd bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r, 5844ad7e9b0SAdrian Chadd bus_size_t offset, bus_size_t length, int flags) 5854ad7e9b0SAdrian Chadd { 5864ad7e9b0SAdrian Chadd BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length, 5874ad7e9b0SAdrian Chadd flags); 5884ad7e9b0SAdrian Chadd } 5894ad7e9b0SAdrian Chadd 5904ad7e9b0SAdrian Chadd static device_method_t bhnd_methods[] = { 5914ad7e9b0SAdrian Chadd /* Device interface */ \ 5924ad7e9b0SAdrian Chadd DEVMETHOD(device_attach, bhnd_generic_attach), 5934ad7e9b0SAdrian Chadd DEVMETHOD(device_detach, bhnd_generic_detach), 5944ad7e9b0SAdrian Chadd DEVMETHOD(device_shutdown, bhnd_generic_shutdown), 5954ad7e9b0SAdrian Chadd DEVMETHOD(device_suspend, bhnd_generic_suspend), 5964ad7e9b0SAdrian Chadd DEVMETHOD(device_resume, bhnd_generic_resume), 5974ad7e9b0SAdrian Chadd 5984ad7e9b0SAdrian Chadd /* Bus interface */ 5994ad7e9b0SAdrian Chadd DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch), 6004ad7e9b0SAdrian Chadd DEVMETHOD(bus_print_child, bhnd_generic_print_child), 6014ad7e9b0SAdrian Chadd DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str), 6024ad7e9b0SAdrian Chadd DEVMETHOD(bus_child_location_str, bhnd_child_location_str), 6034ad7e9b0SAdrian Chadd 6044ad7e9b0SAdrian Chadd DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child), 6054ad7e9b0SAdrian Chadd DEVMETHOD(bus_resume_child, bhnd_generic_resume_child), 6064ad7e9b0SAdrian Chadd 6074ad7e9b0SAdrian Chadd DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource), 6084ad7e9b0SAdrian Chadd DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource), 6094ad7e9b0SAdrian Chadd DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource), 6104ad7e9b0SAdrian Chadd DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource), 6114ad7e9b0SAdrian Chadd DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource), 6124ad7e9b0SAdrian Chadd DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource), 6134ad7e9b0SAdrian Chadd DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 6144ad7e9b0SAdrian Chadd DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 6154ad7e9b0SAdrian Chadd 6164ad7e9b0SAdrian Chadd DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 6174ad7e9b0SAdrian Chadd DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 6184ad7e9b0SAdrian Chadd DEVMETHOD(bus_config_intr, bus_generic_config_intr), 6194ad7e9b0SAdrian Chadd DEVMETHOD(bus_bind_intr, bus_generic_bind_intr), 6204ad7e9b0SAdrian Chadd DEVMETHOD(bus_describe_intr, bus_generic_describe_intr), 6214ad7e9b0SAdrian Chadd 6224ad7e9b0SAdrian Chadd DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag), 6234ad7e9b0SAdrian Chadd 6244ad7e9b0SAdrian Chadd /* BHND interface */ 625386fb140SAdrian Chadd DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid), 6264ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order), 627386fb140SAdrian Chadd DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid), 628386fb140SAdrian Chadd DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled), 629d567592bSAdrian Chadd DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_bus_generic_get_nvram_var), 6304ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_read_1, bhnd_read_1), 6314ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_read_2, bhnd_read_2), 6324ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_read_4, bhnd_read_4), 6334ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_write_1, bhnd_write_1), 6344ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_write_2, bhnd_write_2), 6354ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_write_4, bhnd_write_4), 636a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1), 637a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2), 638a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4), 639a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1), 640a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2), 641a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4), 642a73ac06dSAdrian Chadd 643a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1), 644a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2), 645a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4), 646a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1), 647a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2), 648a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4), 649a73ac06dSAdrian Chadd 650a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1), 651a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2), 652a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4), 653a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1), 654a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2), 655a73ac06dSAdrian Chadd DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4), 656a73ac06dSAdrian Chadd 6574ad7e9b0SAdrian Chadd DEVMETHOD(bhnd_bus_barrier, bhnd_barrier), 6584ad7e9b0SAdrian Chadd 6594ad7e9b0SAdrian Chadd DEVMETHOD_END 6604ad7e9b0SAdrian Chadd }; 6614ad7e9b0SAdrian Chadd 6624ad7e9b0SAdrian Chadd devclass_t bhnd_devclass; /**< bhnd bus. */ 6634ad7e9b0SAdrian Chadd devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */ 6644ad7e9b0SAdrian Chadd devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */ 6654ad7e9b0SAdrian Chadd 6664ad7e9b0SAdrian Chadd DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc)); 6674ad7e9b0SAdrian Chadd MODULE_VERSION(bhnd, 1); 668