/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2015-2016 Landon Fuller <[email protected]>4* Copyright (c) 2017 The FreeBSD Foundation5* All rights reserved.6*7* Portions of this software were developed by Landon Fuller8* under sponsorship from the FreeBSD Foundation.9*10* Redistribution and use in source and binary forms, with or without11* modification, are permitted provided that the following conditions12* are met:13* 1. Redistributions of source code must retain the above copyright14* notice, this list of conditions and the following disclaimer,15* without modification.16* 2. Redistributions in binary form must reproduce at minimum a disclaimer17* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any18* redistribution must be conditioned upon including a substantially19* similar Disclaimer requirement for further binary redistribution.20*21* NO WARRANTY22* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS23* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT24* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY25* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL26* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,27* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF28* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS29* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER30* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)31* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF32* THE POSSIBILITY OF SUCH DAMAGES.33*34*/3536#ifndef _BHND_BHND_H_37#define _BHND_BHND_H_3839#include <sys/param.h>40#include <sys/bus.h>41#include <sys/lock.h>42#include <sys/mutex.h>4344#include <machine/bus.h>4546#include "bhnd_ids.h"47#include "bhnd_types.h"48#include "bhnd_erom_types.h"49#include "bhnd_debug.h"50#include "bhnd_bus_if.h"51#include "bhnd_match.h"5253#include "nvram/bhnd_nvram.h"5455#define BHND_CHIPID_MAX_NAMELEN 32 /**< maximum buffer required for a56bhnd_format_chip_id() */5758/**59* bhnd child instance variables60*/61enum bhnd_device_vars {62BHND_IVAR_VENDOR, /**< Designer's JEP-106 manufacturer ID. */63BHND_IVAR_DEVICE, /**< Part number */64BHND_IVAR_HWREV, /**< Core revision */65BHND_IVAR_DEVICE_CLASS, /**< Core class (@sa bhnd_devclass_t) */66BHND_IVAR_VENDOR_NAME, /**< Core vendor name */67BHND_IVAR_DEVICE_NAME, /**< Core name */68BHND_IVAR_CORE_INDEX, /**< Bus-assigned core number */69BHND_IVAR_CORE_UNIT, /**< Bus-assigned core unit number,70assigned sequentially (starting at 0) for71each vendor/device pair. */72BHND_IVAR_PMU_INFO, /**< Internal bus-managed PMU state */73};7475/**76* bhnd device probe priority bands.77*/78enum {79BHND_PROBE_ROOT = 0, /**< Nexus or host bridge */80BHND_PROBE_BUS = 1000, /**< Buses and bridges */81BHND_PROBE_CPU = 2000, /**< CPU devices */82BHND_PROBE_INTERRUPT = 3000, /**< Interrupt controllers. */83BHND_PROBE_TIMER = 4000, /**< Timers and clocks. */84BHND_PROBE_RESOURCE = 5000, /**< Resource discovery (including NVRAM/SPROM) */85BHND_PROBE_DEFAULT = 6000, /**< Default device priority */86};8788/**89* Constants defining fine grained ordering within a BHND_PROBE_* priority band.90*91* Example:92* @code93* BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST94* @endcode95*/96enum {97BHND_PROBE_ORDER_FIRST = 0,98BHND_PROBE_ORDER_EARLY = 25,99BHND_PROBE_ORDER_MIDDLE = 50,100BHND_PROBE_ORDER_LATE = 75,101BHND_PROBE_ORDER_LAST = 100102103};104105/**106* Per-core IOCTL flags common to all bhnd(4) cores.107*/108enum {109BHND_IOCTL_BIST = 0x8000, /**< Initiate a built-in self-test (BIST). Must be cleared110after BIST results are read via BHND_IOST_BIST_* */111BHND_IOCTL_PME = 0x4000, /**< Enable posting of power management events by the core. */112BHND_IOCTL_CFLAGS = 0x3FFC, /**< Reserved for core-specific ioctl flags. */113BHND_IOCTL_CLK_FORCE = 0x0002, /**< Force disable of clock gating, resulting in all clocks114being distributed within the core. Should be set when115asserting/deasserting reset to ensure the reset signal116fully propagates to the entire core. */117BHND_IOCTL_CLK_EN = 0x0001, /**< If cleared, the core clock will be disabled. Should be118set during normal operation, and cleared when the core is119held in reset. */120};121122/**123* Per-core IOST flags common to all bhnd(4) cores.124*/125enum {126BHND_IOST_BIST_DONE = 0x8000, /**< Set upon BIST completion (see BHND_IOCTL_BIST), and cleared127if 0 is written to BHND_IOCTL_BIST. */128BHND_IOST_BIST_FAIL = 0x4000, /**< Set upon detection of a BIST error; the value is unspecified129if BIST has not completed and BHND_IOST_BIST_DONE is not set. */130BHND_IOST_CLK = 0x2000, /**< Set if the core has requested that gated clocks be enabled, or131cleared otherwise. The value is undefined if a core does not132support clock gating. */133BHND_IOST_DMA64 = 0x1000, /**< Set if this core supports 64-bit DMA */134BHND_IOST_CFLAGS = 0x0FFC, /**< Reserved for core-specific status flags. */135};136137/*138* Simplified accessors for bhnd device ivars139*/140#define BHND_ACCESSOR(var, ivar, type) \141__BUS_ACCESSOR(bhnd, var, BHND, ivar, type)142143BHND_ACCESSOR(vendor, VENDOR, uint16_t);144BHND_ACCESSOR(device, DEVICE, uint16_t);145BHND_ACCESSOR(hwrev, HWREV, uint8_t);146BHND_ACCESSOR(class, DEVICE_CLASS, bhnd_devclass_t);147BHND_ACCESSOR(vendor_name, VENDOR_NAME, const char *);148BHND_ACCESSOR(device_name, DEVICE_NAME, const char *);149BHND_ACCESSOR(core_index, CORE_INDEX, u_int);150BHND_ACCESSOR(core_unit, CORE_UNIT, int);151BHND_ACCESSOR(pmu_info, PMU_INFO, void *);152153#undef BHND_ACCESSOR154155/**156* A bhnd(4) board descriptor.157*/158struct bhnd_board_info {159uint16_t board_vendor; /**< Board vendor (PCI-SIG vendor ID).160*161* On PCI devices, this will default to162* the PCI subsystem vendor ID, but may163* be overridden by the 'boardtype'164* NVRAM variable.165*166* On SoCs, this will default to167* PCI_VENDOR_BROADCOM, but may be168* overridden by the 'boardvendor'169* NVRAM variable.170*/171uint16_t board_type; /**< Board type (See BHND_BOARD_*)172*173* This value is usually a174* Broadcom-assigned reference board175* identifier (see BHND_BOARD_*), but176* may be set to an arbitrary value177* assigned by the board vendor.178*179* On PCI devices, this will default180* to the PCI subsystem ID, but may be181* overridden by the 'boardtype'182* NVRAM variable.183*184* On SoCs, this will always be185* populated with the value of the186* 'boardtype' NVRAM variable.187*/188uint16_t board_devid; /**< Board device ID.189*190* On PCI devices, this will default191* to the PCI device ID, but may192* be overridden by the 'devid'193* NVRAM variable.194*/195uint16_t board_rev; /**< Board revision. */196uint8_t board_srom_rev; /**< Board SROM format revision */197198uint32_t board_flags; /**< Board flags (see BHND_BFL_*) */199uint32_t board_flags2; /**< Board flags 2 (see BHND_BFL2_*) */200uint32_t board_flags3; /**< Board flags 3 (see BHND_BFL3_*) */201};202203/**204* Chip Identification205*206* This is read from the ChipCommon ID register; on earlier bhnd(4) devices207* where ChipCommon is unavailable, known values must be supplied.208*/209struct bhnd_chipid {210uint16_t chip_id; /**< chip id (BHND_CHIPID_*) */211uint8_t chip_rev; /**< chip revision */212uint8_t chip_pkg; /**< chip package (BHND_PKGID_*) */213uint8_t chip_type; /**< chip type (BHND_CHIPTYPE_*) */214uint32_t chip_caps; /**< chip capabilities (BHND_CAP_*) */215216bhnd_addr_t enum_addr; /**< chip_type-specific enumeration217* address; either the siba(4) base218* core register block, or the bcma(4)219* EROM core address. */220221uint8_t ncores; /**< number of cores, if known. 0 if222* not available. */223};224225/**226* Chip capabilities227*/228enum bhnd_cap {229BHND_CAP_BP64 = (1<<0), /**< Backplane supports 64-bit230* addressing */231BHND_CAP_PMU = (1<<1), /**< PMU is present */232};233234/**235* A bhnd(4) core descriptor.236*/237struct bhnd_core_info {238uint16_t vendor; /**< JEP-106 vendor (BHND_MFGID_*) */239uint16_t device; /**< device */240uint16_t hwrev; /**< hardware revision */241u_int core_idx; /**< bus-assigned core index */242int unit; /**< bus-assigned core unit */243};244245/**246* bhnd(4) DMA address widths.247*/248typedef enum {249BHND_DMA_ADDR_30BIT = 30, /**< 30-bit DMA */250BHND_DMA_ADDR_32BIT = 32, /**< 32-bit DMA */251BHND_DMA_ADDR_64BIT = 64, /**< 64-bit DMA */252} bhnd_dma_addrwidth;253254/**255* Convert an address width (in bits) to its corresponding mask.256*/257#define BHND_DMA_ADDR_BITMASK(_width) \258((_width >= 64) ? ~0ULL : \259(_width == 0) ? 0x0 : \260((1ULL << (_width)) - 1)) \261262/**263* bhnd(4) DMA address translation descriptor.264*/265struct bhnd_dma_translation {266/**267* Host-to-device physical address translation.268*269* This may be added to the host physical address to produce a device270* DMA address.271*/272bhnd_addr_t base_addr;273274/**275* Device-addressable address mask.276*277* This defines the device's DMA address range, excluding any bits278* reserved for mapping the address to the base_addr.279*/280bhnd_addr_t addr_mask;281282/**283* Device-addressable extended address mask.284*285* If a per-core bhnd(4) DMA engine supports the 'addrext' control286* field, it can be used to provide address bits excluded by addr_mask.287*288* Support for DMA extended address changes – including coordination289* with the core providing DMA translation – is handled transparently by290* the DMA engine. For example, on PCI(e) Wi-Fi chipsets, the Wi-Fi291* core DMA engine will (in effect) update the PCI core's DMA292* sbtopcitranslation base address to map the full address prior to293* performing a DMA transaction.294*/295bhnd_addr_t addrext_mask;296297/**298* Translation flags (see bhnd_dma_translation_flags).299*/300uint32_t flags;301};302#define BHND_DMA_TRANSLATION_TABLE_END { 0, 0, 0, 0 }303304#define BHND_DMA_IS_TRANSLATION_TABLE_END(_dt) \305((_dt)->base_addr == 0 && (_dt)->addr_mask == 0 && \306(_dt)->addrext_mask == 0 && (_dt)->flags == 0)307308/**309* bhnd(4) DMA address translation flags.310*/311enum bhnd_dma_translation_flags {312/**313* The translation remaps the device's physical address space.314*315* This is used in conjunction with BHND_DMA_TRANSLATION_BYTESWAPPED to316* define a DMA translation that provides byteswapped access to317* physical memory on big-endian MIPS SoCs.318*/319BHND_DMA_TRANSLATION_PHYSMAP = (1<<0),320321/**322* Provides a byte-swapped mapping; write requests will be byte-swapped323* before being written to memory, and read requests will be324* byte-swapped before being returned.325*326* This is primarily used to perform efficient byte swapping of DMA327* data on embedded MIPS SoCs executing in big-endian mode.328*/329BHND_DMA_TRANSLATION_BYTESWAPPED = (1<<1),330};331332/**333* A bhnd(4) bus resource.334*335* This provides an abstract interface to per-core resources that may require336* bus-level remapping of address windows prior to access.337*/338struct bhnd_resource {339struct resource *res; /**< the system resource. */340bool direct; /**< false if the resource requires341* bus window remapping before it342* is MMIO accessible. */343};344345/** Wrap the active resource @p _r in a bhnd_resource structure */346#define BHND_DIRECT_RESOURCE(_r) ((struct bhnd_resource) { \347.res = (_r), \348.direct = true, \349})350351/**352* Device quirk table descriptor.353*/354struct bhnd_device_quirk {355struct bhnd_device_match desc; /**< device match descriptor */356uint32_t quirks; /**< quirk flags */357};358359#define BHND_CORE_QUIRK(_rev, _flags) \360{{ BHND_MATCH_CORE_REV(_rev) }, (_flags) }361362#define BHND_CHIP_QUIRK(_chip, _rev, _flags) \363{{ BHND_MATCH_CHIP_IR(BCM ## _chip, _rev) }, (_flags) }364365#define BHND_PKG_QUIRK(_chip, _pkg, _flags) \366{{ BHND_MATCH_CHIP_IP(BCM ## _chip, BCM ## _chip ## _pkg) }, (_flags) }367368#define BHND_BOARD_QUIRK(_board, _flags) \369{{ BHND_MATCH_BOARD_TYPE(_board) }, \370(_flags) }371#define BHND_DEVICE_QUIRK_END { { BHND_MATCH_ANY }, 0 }372#define BHND_DEVICE_QUIRK_IS_END(_q) \373(((_q)->desc.m.match_flags == 0) && (_q)->quirks == 0)374375enum {376BHND_DF_ANY = 0,377BHND_DF_HOSTB = (1<<0), /**< core is serving as the bus' host378* bridge. implies BHND_DF_ADAPTER */379BHND_DF_SOC = (1<<1), /**< core is attached to a native380bus (BHND_ATTACH_NATIVE) */381BHND_DF_ADAPTER = (1<<2), /**< core is attached to a bridged382* adapter (BHND_ATTACH_ADAPTER) */383};384385/** Device probe table descriptor */386struct bhnd_device {387const struct bhnd_device_match core; /**< core match descriptor */388const char *desc; /**< device description, or NULL. */389const struct bhnd_device_quirk *quirks_table; /**< quirks table for this device, or NULL */390uint32_t device_flags; /**< required BHND_DF_* flags */391};392393#define _BHND_DEVICE(_vendor, _device, _desc, _quirks, \394_flags, ...) \395{ { BHND_MATCH_CORE(BHND_MFGID_ ## _vendor, \396BHND_COREID_ ## _device) }, _desc, _quirks, \397_flags }398399#define BHND_DEVICE(_vendor, _device, _desc, _quirks, ...) \400_BHND_DEVICE(_vendor, _device, _desc, _quirks, \401## __VA_ARGS__, 0)402#define BHND_DEVICE_END { { BHND_MATCH_ANY }, NULL, NULL, 0 }403#define BHND_DEVICE_IS_END(_d) \404(BHND_MATCH_IS_ANY(&(_d)->core) && (_d)->desc == NULL)405406/**407* bhnd device sort order.408*/409typedef enum {410BHND_DEVICE_ORDER_ATTACH, /**< sort by bhnd(4) device attach order;411child devices should be probed/attached412in this order */413BHND_DEVICE_ORDER_DETACH, /**< sort by bhnd(4) device detach order;414child devices should be detached, suspended,415and shutdown in this order */416} bhnd_device_order;417418/**419* A registry of bhnd service providers.420*/421struct bhnd_service_registry {422STAILQ_HEAD(,bhnd_service_entry) entries; /**< registered services */423struct mtx lock; /**< state lock */424};425426/**427* bhnd service provider flags.428*/429enum {430BHND_SPF_INHERITED = (1<<0), /**< service provider reference was inherited from431a parent bus, and should be deregistered when the432last active reference is released */433};434435const char *bhnd_vendor_name(uint16_t vendor);436const char *bhnd_port_type_name(bhnd_port_type port_type);437const char *bhnd_nvram_src_name(bhnd_nvram_src nvram_src);438439const char *bhnd_find_core_name(uint16_t vendor,440uint16_t device);441bhnd_devclass_t bhnd_find_core_class(uint16_t vendor,442uint16_t device);443444const char *bhnd_core_name(const struct bhnd_core_info *ci);445bhnd_devclass_t bhnd_core_class(const struct bhnd_core_info *ci);446447int bhnd_format_chip_id(char *buffer, size_t size,448uint16_t chip_id);449450device_t bhnd_bus_match_child(device_t bus,451const struct bhnd_core_match *desc);452453device_t bhnd_bus_find_child(device_t bus,454bhnd_devclass_t class, int unit);455456int bhnd_bus_get_children(device_t bus,457device_t **devlistp, int *devcountp,458bhnd_device_order order);459460void bhnd_bus_free_children(device_t *devlist);461462int bhnd_bus_probe_children(device_t bus);463464int bhnd_sort_devices(device_t *devlist,465size_t devcount, bhnd_device_order order);466467device_t bhnd_find_bridge_root(device_t dev,468devclass_t bus_class);469470const struct bhnd_core_info *bhnd_match_core(471const struct bhnd_core_info *cores,472u_int num_cores,473const struct bhnd_core_match *desc);474475const struct bhnd_core_info *bhnd_find_core(476const struct bhnd_core_info *cores,477u_int num_cores, bhnd_devclass_t class);478479struct bhnd_core_match bhnd_core_get_match_desc(480const struct bhnd_core_info *core);481482bool bhnd_cores_equal(483const struct bhnd_core_info *lhs,484const struct bhnd_core_info *rhs);485486bool bhnd_core_matches(487const struct bhnd_core_info *core,488const struct bhnd_core_match *desc);489490bool bhnd_chip_matches(491const struct bhnd_chipid *chipid,492const struct bhnd_chip_match *desc);493494bool bhnd_board_matches(495const struct bhnd_board_info *info,496const struct bhnd_board_match *desc);497498bool bhnd_hwrev_matches(uint16_t hwrev,499const struct bhnd_hwrev_match *desc);500501bool bhnd_device_matches(device_t dev,502const struct bhnd_device_match *desc);503504const struct bhnd_device *bhnd_device_lookup(device_t dev,505const struct bhnd_device *table,506size_t entry_size);507508uint32_t bhnd_device_quirks(device_t dev,509const struct bhnd_device *table,510size_t entry_size);511512struct bhnd_core_info bhnd_get_core_info(device_t dev);513514int bhnd_alloc_resources(device_t dev,515struct resource_spec *rs,516struct bhnd_resource **res);517518void bhnd_release_resources(device_t dev,519const struct resource_spec *rs,520struct bhnd_resource **res);521522void bhnd_set_custom_core_desc(device_t dev,523const char *name);524void bhnd_set_default_core_desc(device_t dev);525526void bhnd_set_default_bus_desc(device_t dev,527const struct bhnd_chipid *chip_id);528529int bhnd_nvram_getvar_str(device_t dev,530const char *name, char *buf, size_t len,531size_t *rlen);532533int bhnd_nvram_getvar_uint(device_t dev,534const char *name, void *value, int width);535int bhnd_nvram_getvar_uint8(device_t dev,536const char *name, uint8_t *value);537int bhnd_nvram_getvar_uint16(device_t dev,538const char *name, uint16_t *value);539int bhnd_nvram_getvar_uint32(device_t dev,540const char *name, uint32_t *value);541542int bhnd_nvram_getvar_int(device_t dev,543const char *name, void *value, int width);544int bhnd_nvram_getvar_int8(device_t dev,545const char *name, int8_t *value);546int bhnd_nvram_getvar_int16(device_t dev,547const char *name, int16_t *value);548int bhnd_nvram_getvar_int32(device_t dev,549const char *name, int32_t *value);550551int bhnd_nvram_getvar_array(device_t dev,552const char *name, void *buf, size_t count,553bhnd_nvram_type type);554555int bhnd_service_registry_init(556struct bhnd_service_registry *bsr);557int bhnd_service_registry_fini(558struct bhnd_service_registry *bsr);559int bhnd_service_registry_add(560struct bhnd_service_registry *bsr,561device_t provider,562bhnd_service_t service,563uint32_t flags);564int bhnd_service_registry_remove(565struct bhnd_service_registry *bsr,566device_t provider,567bhnd_service_t service);568device_t bhnd_service_registry_retain(569struct bhnd_service_registry *bsr,570bhnd_service_t service);571bool bhnd_service_registry_release(572struct bhnd_service_registry *bsr,573device_t provider,574bhnd_service_t service);575576int bhnd_bus_generic_register_provider(577device_t dev, device_t child,578device_t provider, bhnd_service_t service);579int bhnd_bus_generic_deregister_provider(580device_t dev, device_t child,581device_t provider, bhnd_service_t service);582device_t bhnd_bus_generic_retain_provider(device_t dev,583device_t child, bhnd_service_t service);584void bhnd_bus_generic_release_provider(device_t dev,585device_t child, device_t provider,586bhnd_service_t service);587588int bhnd_bus_generic_sr_register_provider(589device_t dev, device_t child,590device_t provider, bhnd_service_t service);591int bhnd_bus_generic_sr_deregister_provider(592device_t dev, device_t child,593device_t provider, bhnd_service_t service);594device_t bhnd_bus_generic_sr_retain_provider(device_t dev,595device_t child, bhnd_service_t service);596void bhnd_bus_generic_sr_release_provider(device_t dev,597device_t child, device_t provider,598bhnd_service_t service);599600bool bhnd_bus_generic_is_hw_disabled(device_t dev,601device_t child);602bool bhnd_bus_generic_is_region_valid(device_t dev,603device_t child, bhnd_port_type type,604u_int port, u_int region);605int bhnd_bus_generic_get_nvram_var(device_t dev,606device_t child, const char *name,607void *buf, size_t *size,608bhnd_nvram_type type);609const struct bhnd_chipid *bhnd_bus_generic_get_chipid(device_t dev,610device_t child);611int bhnd_bus_generic_get_dma_translation(612device_t dev, device_t child, u_int width,613uint32_t flags, bus_dma_tag_t *dmat,614struct bhnd_dma_translation *translation);615int bhnd_bus_generic_read_board_info(device_t dev,616device_t child,617struct bhnd_board_info *info);618struct bhnd_resource *bhnd_bus_generic_alloc_resource (device_t dev,619device_t child, int type, int rid,620rman_res_t start, rman_res_t end,621rman_res_t count, u_int flags);622int bhnd_bus_generic_release_resource (device_t dev,623device_t child, struct bhnd_resource *r);624int bhnd_bus_generic_activate_resource (device_t dev,625device_t child, struct bhnd_resource *r);626int bhnd_bus_generic_deactivate_resource (device_t dev,627device_t child, struct bhnd_resource *r);628uintptr_t bhnd_bus_generic_get_intr_domain(device_t dev,629device_t child, bool self);630631/**632* Return the bhnd(4) bus driver's device enumeration parser class633*634* @param driver A bhnd bus driver instance.635*/636static inline bhnd_erom_class_t *637bhnd_driver_get_erom_class(driver_t *driver)638{639return (BHND_BUS_GET_EROM_CLASS(driver));640}641642/**643* Return the active host bridge core for the bhnd bus, if any, or NULL if644* not found.645*646* @param dev A bhnd bus device.647*/648static inline device_t649bhnd_bus_find_hostb_device(device_t dev) {650return (BHND_BUS_FIND_HOSTB_DEVICE(dev));651}652653/**654* Register a provider for a given @p service.655*656* @param dev The device to register as a service provider657* with its parent bus.658* @param service The service for which @p dev will be registered.659*660* @retval 0 success661* @retval EEXIST if an entry for @p service already exists.662* @retval non-zero if registering @p dev otherwise fails, a regular663* unix error code will be returned.664*/665static inline int666bhnd_register_provider(device_t dev, bhnd_service_t service)667{668return (BHND_BUS_REGISTER_PROVIDER(device_get_parent(dev), dev, dev,669service));670}671672/**673* Attempt to remove a service provider registration for @p dev.674*675* @param dev The device to be deregistered as a service provider.676* @param service The service for which @p dev will be deregistered, or677* BHND_SERVICE_INVALID to remove all service registrations678* for @p dev.679*680* @retval 0 success681* @retval EBUSY if active references to @p dev exist; @see682* bhnd_retain_provider() and bhnd_release_provider().683*/684static inline int685bhnd_deregister_provider(device_t dev, bhnd_service_t service)686{687return (BHND_BUS_DEREGISTER_PROVIDER(device_get_parent(dev), dev, dev,688service));689}690691/**692* Retain and return a reference to the registered @p service provider, if any.693*694* @param dev The requesting device.695* @param service The service for which a provider should be returned.696*697* On success, the caller assumes ownership the returned provider, and698* is responsible for releasing this reference via699* BHND_BUS_RELEASE_PROVIDER().700*701* @retval device_t success702* @retval NULL if no provider is registered for @p service.703*/704static inline device_t705bhnd_retain_provider(device_t dev, bhnd_service_t service)706{707return (BHND_BUS_RETAIN_PROVIDER(device_get_parent(dev), dev,708service));709}710711/**712* Release a reference to a provider device previously returned by713* bhnd_retain_provider().714*715* @param dev The requesting device.716* @param provider The provider to be released.717* @param service The service for which @p provider was previously retained.718*/719static inline void720bhnd_release_provider(device_t dev, device_t provider,721bhnd_service_t service)722{723return (BHND_BUS_RELEASE_PROVIDER(device_get_parent(dev), dev,724provider, service));725}726727/**728* Return true if the hardware components required by @p dev are known to be729* unpopulated or otherwise unusable.730*731* In some cases, enumerated devices may have pins that are left floating, or732* the hardware may otherwise be non-functional; this method allows a parent733* device to explicitly specify if a successfully enumerated @p dev should734* be disabled.735*736* @param dev A bhnd bus child device.737*/738static inline bool739bhnd_is_hw_disabled(device_t dev) {740return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), dev));741}742743/**744* Return the BHND chip identification info for the bhnd bus.745*746* @param dev A bhnd bus child device.747*/748static inline const struct bhnd_chipid *749bhnd_get_chipid(device_t dev) {750return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev));751};752753/**754* Read the current value of a bhnd(4) device's per-core I/O control register.755*756* @param dev The bhnd bus child device to be queried.757* @param[out] ioctl On success, the I/O control register value.758*759* @retval 0 success760* @retval EINVAL If @p child is not a direct child of @p dev.761* @retval ENODEV If agent/config space for @p child is unavailable.762* @retval non-zero If reading the IOCTL register otherwise fails, a regular763* unix error code will be returned.764*/765static inline int766bhnd_read_ioctl(device_t dev, uint16_t *ioctl)767{768return (BHND_BUS_READ_IOCTL(device_get_parent(dev), dev, ioctl));769}770771/**772* Write @p value and @p mask to a bhnd(4) device's per-core I/O control773* register.774*775* @param dev The bhnd bus child device for which the IOCTL register will be776* written.777* @param value The value to be written (see BHND_IOCTL_*).778* @param mask Only the bits defined by @p mask will be updated from @p value.779*780* @retval 0 success781* @retval EINVAL If @p child is not a direct child of @p dev.782* @retval ENODEV If agent/config space for @p child is unavailable.783* @retval non-zero If writing the IOCTL register otherwise fails, a regular784* unix error code will be returned.785*/786static inline int787bhnd_write_ioctl(device_t dev, uint16_t value, uint16_t mask)788{789return (BHND_BUS_WRITE_IOCTL(device_get_parent(dev), dev, value, mask));790}791792/**793* Read the current value of a bhnd(4) device's per-core I/O status register.794*795* @param dev The bhnd bus child device to be queried.796* @param[out] iost On success, the I/O status register value.797*798* @retval 0 success799* @retval EINVAL If @p child is not a direct child of @p dev.800* @retval ENODEV If agent/config space for @p child is unavailable.801* @retval non-zero If reading the IOST register otherwise fails, a regular802* unix error code will be returned.803*/804static inline int805bhnd_read_iost(device_t dev, uint16_t *iost)806{807return (BHND_BUS_READ_IOST(device_get_parent(dev), dev, iost));808}809810/**811* Return true if the given bhnd device's hardware is currently held812* in a RESET state or otherwise not clocked (BHND_IOCTL_CLK_EN).813*814* @param dev The device to query.815*816* @retval true If @p dev is held in RESET or not clocked (BHND_IOCTL_CLK_EN),817* or an error occurred determining @p dev's hardware state.818* @retval false If @p dev is clocked and is not held in RESET.819*/820static inline bool821bhnd_is_hw_suspended(device_t dev)822{823return (BHND_BUS_IS_HW_SUSPENDED(device_get_parent(dev), dev));824}825826/**827* Place the bhnd(4) device's hardware into a low-power RESET state with828* the @p reset_ioctl I/O control flags set, and then bring the hardware out of829* RESET with the @p ioctl I/O control flags set.830*831* Any clock or resource PMU requests previously made by @p child will be832* invalidated.833*834* @param dev The device to be reset.835* @param ioctl Device-specific I/O control flags to be set when bringing836* the core out of its RESET state (see BHND_IOCTL_*).837* @param reset_ioctl Device-specific I/O control flags to be set when placing838* the core into its RESET state.839*840* @retval 0 success841* @retval non-zero error842*/843static inline int844bhnd_reset_hw(device_t dev, uint16_t ioctl, uint16_t reset_ioctl)845{846return (BHND_BUS_RESET_HW(device_get_parent(dev), dev, ioctl,847reset_ioctl));848}849850/**851* Suspend @p child's hardware in a low-power reset state.852*853* Any clock or resource PMU requests previously made by @p dev will be854* invalidated.855*856* The hardware may be brought out of reset via bhnd_reset_hw().857*858* @param dev The device to be suspended.859*860* @retval 0 success861* @retval non-zero error862*/863static inline int864bhnd_suspend_hw(device_t dev, uint16_t ioctl)865{866return (BHND_BUS_SUSPEND_HW(device_get_parent(dev), dev, ioctl));867}868869/**870* Return the BHND attachment type of the parent bhnd bus.871*872* @param dev A bhnd bus child device.873*874* @retval BHND_ATTACH_ADAPTER if the bus is resident on a bridged adapter,875* such as a WiFi chipset.876* @retval BHND_ATTACH_NATIVE if the bus provides hardware services (clock,877* CPU, etc) to a directly attached native host.878*/879static inline bhnd_attach_type880bhnd_get_attach_type (device_t dev) {881return (BHND_BUS_GET_ATTACH_TYPE(device_get_parent(dev), dev));882}883884/**885* Find the best available DMA address translation capable of mapping a886* physical host address to a BHND DMA device address of @p width with887* @p flags.888*889* @param dev A bhnd bus child device.890* @param width The address width within which the translation window must891* reside (see BHND_DMA_ADDR_*).892* @param flags Required translation flags (see BHND_DMA_TRANSLATION_*).893* @param[out] dmat On success, will be populated with a DMA tag specifying the894* @p translation DMA address restrictions. This argment may be NULL if the DMA895* tag is not desired.896* the set of valid host DMA addresses reachable via @p translation.897* @param[out] translation On success, will be populated with a DMA address898* translation descriptor for @p child. This argment may be NULL if the899* descriptor is not desired.900*901* @retval 0 success902* @retval ENODEV If DMA is not supported.903* @retval ENOENT If no DMA translation matching @p width and @p flags is904* available.905* @retval non-zero If determining the DMA address translation for @p child906* otherwise fails, a regular unix error code will be returned.907*/908static inline int909bhnd_get_dma_translation(device_t dev, u_int width, uint32_t flags,910bus_dma_tag_t *dmat, struct bhnd_dma_translation *translation)911{912return (BHND_BUS_GET_DMA_TRANSLATION(device_get_parent(dev), dev, width,913flags, dmat, translation));914}915916/**917* Attempt to read the BHND board identification from the bhnd bus.918*919* This relies on NVRAM access, and will fail if a valid NVRAM device cannot920* be found, or is not yet attached.921*922* @param dev The bhnd device requesting board info.923* @param[out] info On success, will be populated with the bhnd(4) device's924* board information.925*926* @retval 0 success927* @retval ENODEV No valid NVRAM source could be found.928* @retval non-zero If reading @p name otherwise fails, a regular unix929* error code will be returned.930*/931static inline int932bhnd_read_board_info(device_t dev, struct bhnd_board_info *info)933{934return (BHND_BUS_READ_BOARD_INFO(device_get_parent(dev), dev, info));935}936937/**938* Return the number of interrupt lines assigned to @p dev.939*940* @param dev A bhnd bus child device.941*/942static inline u_int943bhnd_get_intr_count(device_t dev)944{945return (BHND_BUS_GET_INTR_COUNT(device_get_parent(dev), dev));946}947948/**949* Get the backplane interrupt vector of the @p intr line attached to @p dev.950*951* @param dev A bhnd bus child device.952* @param intr The index of the interrupt line being queried.953* @param[out] ivec On success, the assigned hardware interrupt vector will be954* written to this pointer.955*956* On bcma(4) devices, this returns the OOB bus line assigned to the957* interrupt.958*959* On siba(4) devices, this returns the target OCP slave flag number assigned960* to the interrupt.961*962* @retval 0 success963* @retval ENXIO If @p intr exceeds the number of interrupt lines964* assigned to @p child.965*/966static inline int967bhnd_get_intr_ivec(device_t dev, u_int intr, u_int *ivec)968{969return (BHND_BUS_GET_INTR_IVEC(device_get_parent(dev), dev, intr,970ivec));971}972973/**974* Map the given @p intr to an IRQ number; until unmapped, this IRQ may be used975* to allocate a resource of type SYS_RES_IRQ.976*977* On success, the caller assumes ownership of the interrupt mapping, and978* is responsible for releasing the mapping via bhnd_unmap_intr().979*980* @param dev The requesting device.981* @param intr The interrupt being mapped.982* @param[out] irq On success, the bus interrupt value mapped for @p intr.983*984* @retval 0 If an interrupt was assigned.985* @retval non-zero If mapping an interrupt otherwise fails, a regular986* unix error code will be returned.987*/988static inline int989bhnd_map_intr(device_t dev, u_int intr, rman_res_t *irq)990{991return (BHND_BUS_MAP_INTR(device_get_parent(dev), dev, intr, irq));992}993994/**995* Unmap an bus interrupt previously mapped via bhnd_map_intr().996*997* @param dev The requesting device.998* @param irq The interrupt value being unmapped.999*/1000static inline void1001bhnd_unmap_intr(device_t dev, rman_res_t irq)1002{1003return (BHND_BUS_UNMAP_INTR(device_get_parent(dev), dev, irq));1004}10051006/**1007* Allocate and enable per-core PMU request handling for @p child.1008*1009* The region containing the core's PMU register block (if any) must be1010* allocated via bus_alloc_resource(9) (or bhnd_alloc_resource) before1011* calling bhnd_alloc_pmu(), and must not be released until after1012* calling bhnd_release_pmu().1013*1014* @param dev The requesting bhnd device.1015*1016* @retval 0 success1017* @retval non-zero If allocating PMU request state otherwise fails, a1018* regular unix error code will be returned.1019*/1020static inline int1021bhnd_alloc_pmu(device_t dev)1022{1023return (BHND_BUS_ALLOC_PMU(device_get_parent(dev), dev));1024}10251026/**1027* Release any per-core PMU resources allocated for @p child. Any outstanding1028* PMU requests are are discarded.1029*1030* @param dev The requesting bhnd device.1031*1032* @retval 0 success1033* @retval non-zero If releasing PMU request state otherwise fails, a1034* regular unix error code will be returned, and1035* the core state will be left unmodified.1036*/1037static inline int1038bhnd_release_pmu(device_t dev)1039{1040return (BHND_BUS_RELEASE_PMU(device_get_parent(dev), dev));1041}10421043/**1044* Return the transition latency required for @p clock in microseconds, if1045* known.1046*1047* The BHND_CLOCK_HT latency value is suitable for use as the D11 core's1048* 'fastpwrup_dly' value.1049*1050* @note A driver must ask the bhnd bus to allocate PMU request state1051* via BHND_BUS_ALLOC_PMU() before querying PMU clocks.1052*1053* @param dev The requesting bhnd device.1054* @param clock The clock to be queried for transition latency.1055* @param[out] latency On success, the transition latency of @p clock in1056* microseconds.1057*1058* @retval 0 success1059* @retval ENODEV If the transition latency for @p clock is not available.1060*/1061static inline int1062bhnd_get_clock_latency(device_t dev, bhnd_clock clock, u_int *latency)1063{1064return (BHND_BUS_GET_CLOCK_LATENCY(device_get_parent(dev), dev, clock,1065latency));1066}10671068/**1069* Return the frequency for @p clock in Hz, if known.1070*1071* @param dev The requesting bhnd device.1072* @param clock The clock to be queried.1073* @param[out] freq On success, the frequency of @p clock in Hz.1074*1075* @note A driver must ask the bhnd bus to allocate PMU request state1076* via BHND_BUS_ALLOC_PMU() before querying PMU clocks.1077*1078* @retval 0 success1079* @retval ENODEV If the frequency for @p clock is not available.1080*/1081static inline int1082bhnd_get_clock_freq(device_t dev, bhnd_clock clock, u_int *freq)1083{1084return (BHND_BUS_GET_CLOCK_FREQ(device_get_parent(dev), dev, clock,1085freq));1086}10871088/**1089* Request that @p clock (or faster) be routed to @p dev.1090*1091* @note A driver must ask the bhnd bus to allocate clock request state1092* via bhnd_alloc_pmu() before it can request clock resources.1093*1094* @note Any outstanding PMU clock requests will be discarded upon calling1095* BHND_BUS_RESET_HW() or BHND_BUS_SUSPEND_HW().1096*1097* @param dev The bhnd(4) device to which @p clock should be routed.1098* @param clock The requested clock source.1099*1100* @retval 0 success1101* @retval ENODEV If an unsupported clock was requested.1102* @retval ENXIO If the PMU has not been initialized or is otherwise unvailable,1103*/1104static inline int1105bhnd_request_clock(device_t dev, bhnd_clock clock)1106{1107return (BHND_BUS_REQUEST_CLOCK(device_get_parent(dev), dev, clock));1108}11091110/**1111* Request that @p clocks be powered on behalf of @p dev.1112*1113* This will power any clock sources (e.g. XTAL, PLL, etc) required for1114* @p clocks and wait until they are ready, discarding any previous1115* requests by @p dev.1116*1117* @note A driver must ask the bhnd bus to allocate clock request state1118* via bhnd_alloc_pmu() before it can request clock resources.1119*1120* @note Any outstanding PMU clock requests will be discarded upon calling1121* BHND_BUS_RESET_HW() or BHND_BUS_SUSPEND_HW().1122*1123* @param dev The requesting bhnd(4) device.1124* @param clocks The clock(s) to be enabled.1125*1126* @retval 0 success1127* @retval ENODEV If an unsupported clock was requested.1128* @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.1129*/1130static inline int1131bhnd_enable_clocks(device_t dev, uint32_t clocks)1132{1133return (BHND_BUS_ENABLE_CLOCKS(device_get_parent(dev), dev, clocks));1134}11351136/**1137* Power up an external PMU-managed resource assigned to @p dev.1138*1139* @note A driver must ask the bhnd bus to allocate PMU request state1140* via bhnd_alloc_pmu() before it can request PMU resources.1141*1142* @note Any outstanding PMU resource requests will be released upon calling1143* bhnd_reset_hw() or bhnd_suspend_hw().1144*1145* @param dev The requesting bhnd(4) device.1146* @param rsrc The core-specific external resource identifier.1147*1148* @retval 0 success1149* @retval ENODEV If the PMU does not support @p rsrc.1150* @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.1151*/1152static inline int1153bhnd_request_ext_rsrc(device_t dev, u_int rsrc)1154{1155return (BHND_BUS_REQUEST_EXT_RSRC(device_get_parent(dev), dev, rsrc));1156}11571158/**1159* Power down an external PMU-managed resource assigned to @p dev.1160*1161* A driver must ask the bhnd bus to allocate PMU request state1162* via bhnd_alloc_pmu() before it can request PMU resources.1163*1164* @param dev The requesting bhnd(4) device.1165* @param rsrc The core-specific external resource identifier.1166*1167* @retval 0 success1168* @retval ENODEV If the PMU does not support @p rsrc.1169* @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.1170*/1171static inline int1172bhnd_release_ext_rsrc(device_t dev, u_int rsrc)1173{1174return (BHND_BUS_RELEASE_EXT_RSRC(device_get_parent(dev), dev, rsrc));1175}11761177/**1178* Read @p width bytes at @p offset from the bus-specific agent/config1179* space of @p dev.1180*1181* @param dev The bhnd device for which @p offset should be read.1182* @param offset The offset to be read.1183* @param[out] value On success, the will be set to the @p width value read1184* at @p offset.1185* @param width The size of the access. Must be 1, 2 or 4 bytes.1186*1187* The exact behavior of this method is bus-specific. In the case of1188* bcma(4), this method provides access to the first agent port of @p child.1189*1190* @note Device drivers should only use this API for functionality1191* that is not available via another bhnd(4) function.1192*1193* @retval 0 success1194* @retval EINVAL If @p child is not a direct child of @p dev.1195* @retval EINVAL If @p width is not one of 1, 2, or 4 bytes.1196* @retval ENODEV If accessing agent/config space for @p child is unsupported.1197* @retval EFAULT If reading @p width at @p offset exceeds the bounds of1198* the mapped agent/config space for @p child.1199*/1200static inline uint32_t1201bhnd_read_config(device_t dev, bus_size_t offset, void *value, u_int width)1202{1203return (BHND_BUS_READ_CONFIG(device_get_parent(dev), dev, offset,1204value, width));1205}12061207/**1208* Write @p width bytes at @p offset to the bus-specific agent/config1209* space of @p dev.1210*1211* @param dev The bhnd device for which @p offset should be read.1212* @param offset The offset to be written.1213* @param value A pointer to the value to be written.1214* @param width The size of @p value. Must be 1, 2 or 4 bytes.1215*1216* The exact behavior of this method is bus-specific. In the case of1217* bcma(4), this method provides access to the first agent port of @p child.1218*1219* @note Device drivers should only use this API for functionality1220* that is not available via another bhnd(4) function.1221*1222* @retval 0 success1223* @retval EINVAL If @p child is not a direct child of @p dev.1224* @retval EINVAL If @p width is not one of 1, 2, or 4 bytes.1225* @retval ENODEV If accessing agent/config space for @p child is unsupported.1226* @retval EFAULT If reading @p width at @p offset exceeds the bounds of1227* the mapped agent/config space for @p child.1228*/1229static inline int1230bhnd_write_config(device_t dev, bus_size_t offset, const void *value,1231u_int width)1232{1233return (BHND_BUS_WRITE_CONFIG(device_get_parent(dev), dev, offset,1234value, width));1235}12361237/**1238* Read an NVRAM variable, coerced to the requested @p type.1239*1240* @param dev A bhnd bus child device.1241* @param name The NVRAM variable name.1242* @param[out] buf A buffer large enough to hold @p len bytes. On1243* success, the requested value will be written to1244* this buffer. This argment may be NULL if1245* the value is not desired.1246* @param[in,out] len The maximum capacity of @p buf. On success,1247* will be set to the actual size of the requested1248* value.1249* @param type The desired data representation to be written1250* to @p buf.1251*1252* @retval 0 success1253* @retval ENOENT The requested variable was not found.1254* @retval ENODEV No valid NVRAM source could be found.1255* @retval ENOMEM If a buffer of @p size is too small to hold the1256* requested value.1257* @retval EOPNOTSUPP If the value cannot be coerced to @p type.1258* @retval ERANGE If value coercion would overflow @p type.1259* @retval non-zero If reading @p name otherwise fails, a regular unix1260* error code will be returned.1261*/1262static inline int1263bhnd_nvram_getvar(device_t dev, const char *name, void *buf, size_t *len,1264bhnd_nvram_type type)1265{1266return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, buf,1267len, type));1268}12691270/**1271* Allocate a resource from a device's parent bhnd(4) bus.1272*1273* @param dev The device requesting resource ownership.1274* @param type The type of resource to allocate. This may be any type supported1275* by the standard bus APIs.1276* @param rid The bus-specific handle identifying the resource being allocated.1277* @param start The start address of the resource.1278* @param end The end address of the resource.1279* @param count The size of the resource.1280* @param flags The flags for the resource to be allocated. These may be any1281* values supported by the standard bus APIs.1282*1283* To request the resource's default addresses, pass @p start and1284* @p end values of @c 0 and @c ~0, respectively, and1285* a @p count of @c 1.1286*1287* @retval NULL The resource could not be allocated.1288* @retval resource The allocated resource.1289*/1290static inline struct bhnd_resource *1291bhnd_alloc_resource(device_t dev, int type, int rid, rman_res_t start,1292rman_res_t end, rman_res_t count, u_int flags)1293{1294return BHND_BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, rid,1295start, end, count, flags);1296}12971298/**1299* Allocate a resource from a device's parent bhnd(4) bus, using the1300* resource's default start, end, and count values.1301*1302* @param dev The device requesting resource ownership.1303* @param type The type of resource to allocate. This may be any type supported1304* by the standard bus APIs.1305* @param rid The bus-specific handle identifying the resource being allocated.1306* @param flags The flags for the resource to be allocated. These may be any1307* values supported by the standard bus APIs.1308*1309* @retval NULL The resource could not be allocated.1310* @retval resource The allocated resource.1311*/1312static inline struct bhnd_resource *1313bhnd_alloc_resource_any(device_t dev, int type, int rid, u_int flags)1314{1315return bhnd_alloc_resource(dev, type, rid, 0, ~0, 1, flags);1316}13171318/**1319* Activate a previously allocated bhnd resource.1320*1321* @param dev The device holding ownership of the allocated resource.1322* @param r A pointer to the resource returned by bhnd_alloc_resource or1323* BHND_BUS_ALLOC_RESOURCE.1324*1325* @retval 0 success1326* @retval non-zero an error occurred while activating the resource.1327*/1328static inline int1329bhnd_activate_resource(device_t dev, struct bhnd_resource *r)1330{1331return BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev), dev, r);1332}13331334/**1335* Deactivate a previously activated bhnd resource.1336*1337* @param dev The device holding ownership of the activated resource.1338* @param r A pointer to the resource returned by bhnd_alloc_resource or1339* BHND_BUS_ALLOC_RESOURCE.1340*1341* @retval 0 success1342* @retval non-zero an error occurred while activating the resource.1343*/1344static inline int1345bhnd_deactivate_resource(device_t dev, struct bhnd_resource *r)1346{1347return BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), dev, r);1348}13491350/**1351* Free a resource allocated by bhnd_alloc_resource().1352*1353* @param dev The device holding ownership of the resource.1354* @param r A pointer to the resource returned by bhnd_alloc_resource or1355* BHND_ALLOC_RESOURCE.1356*1357* @retval 0 success1358* @retval non-zero an error occurred while activating the resource.1359*/1360static inline int1361bhnd_release_resource(device_t dev, struct bhnd_resource *r)1362{1363return BHND_BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, r);1364}13651366/**1367* Return true if @p region_num is a valid region on @p port_num of1368* @p type attached to @p dev.1369*1370* @param dev A bhnd bus child device.1371* @param type The port type being queried.1372* @param port The port number being queried.1373* @param region The region number being queried.1374*/1375static inline bool1376bhnd_is_region_valid(device_t dev, bhnd_port_type type, u_int port,1377u_int region)1378{1379return (BHND_BUS_IS_REGION_VALID(device_get_parent(dev), dev, type,1380port, region));1381}13821383/**1384* Return the number of ports of type @p type attached to @p def.1385*1386* @param dev A bhnd bus child device.1387* @param type The port type being queried.1388*/1389static inline u_int1390bhnd_get_port_count(device_t dev, bhnd_port_type type) {1391return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), dev, type));1392}13931394/**1395* Return the number of memory regions mapped to @p child @p port of1396* type @p type.1397*1398* @param dev A bhnd bus child device.1399* @param port The port number being queried.1400* @param type The port type being queried.1401*/1402static inline u_int1403bhnd_get_region_count(device_t dev, bhnd_port_type type, u_int port) {1404return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), dev, type,1405port));1406}14071408/**1409* Return the resource-ID for a memory region on the given device port.1410*1411* @param dev A bhnd bus child device.1412* @param type The port type.1413* @param port The port identifier.1414* @param region The identifier of the memory region on @p port.1415*1416* @retval int The RID for the given @p port and @p region on @p device.1417* @retval -1 No such port/region found.1418*/1419static inline int1420bhnd_get_port_rid(device_t dev, bhnd_port_type type, u_int port, u_int region)1421{1422return BHND_BUS_GET_PORT_RID(device_get_parent(dev), dev, type, port,1423region);1424}14251426/**1427* Decode a port / region pair on @p dev defined by @p rid.1428*1429* @param dev A bhnd bus child device.1430* @param type The resource type.1431* @param rid The resource identifier.1432* @param[out] port_type The decoded port type.1433* @param[out] port The decoded port identifier.1434* @param[out] region The decoded region identifier.1435*1436* @retval 0 success1437* @retval non-zero No matching port/region found.1438*/1439static inline int1440bhnd_decode_port_rid(device_t dev, int type, int rid, bhnd_port_type *port_type,1441u_int *port, u_int *region)1442{1443return BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), dev, type, rid,1444port_type, port, region);1445}14461447/**1448* Get the address and size of @p region on @p port.1449*1450* @param dev A bhnd bus child device.1451* @param port_type The port type.1452* @param port The port identifier.1453* @param region The identifier of the memory region on @p port.1454* @param[out] region_addr The region's base address.1455* @param[out] region_size The region's size.1456*1457* @retval 0 success1458* @retval non-zero No matching port/region found.1459*/1460static inline int1461bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port,1462u_int region, bhnd_addr_t *region_addr, bhnd_size_t *region_size)1463{1464return BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), dev, port_type,1465port, region, region_addr, region_size);1466}14671468/*1469* bhnd bus-level equivalents of the bus_(read|write|set|barrier|...)1470* macros (compatible with bhnd_resource).1471*1472* Generated with bhnd/tools/bus_macro.sh1473*/1474#define bhnd_bus_barrier(r, o, l, f) \1475(((r)->direct) ? \1476bus_barrier((r)->res, (o), (l), (f)) : \1477BHND_BUS_BARRIER( \1478device_get_parent(rman_get_device((r)->res)), \1479rman_get_device((r)->res), (r), (o), (l), (f)))1480#define bhnd_bus_read_1(r, o) \1481(((r)->direct) ? \1482bus_read_1((r)->res, (o)) : \1483BHND_BUS_READ_1( \1484device_get_parent(rman_get_device((r)->res)), \1485rman_get_device((r)->res), (r), (o)))1486#define bhnd_bus_read_multi_1(r, o, d, c) \1487(((r)->direct) ? \1488bus_read_multi_1((r)->res, (o), (d), (c)) : \1489BHND_BUS_READ_MULTI_1( \1490device_get_parent(rman_get_device((r)->res)), \1491rman_get_device((r)->res), (r), (o), (d), (c)))1492#define bhnd_bus_read_region_1(r, o, d, c) \1493(((r)->direct) ? \1494bus_read_region_1((r)->res, (o), (d), (c)) : \1495BHND_BUS_READ_REGION_1( \1496device_get_parent(rman_get_device((r)->res)), \1497rman_get_device((r)->res), (r), (o), (d), (c)))1498#define bhnd_bus_write_1(r, o, v) \1499(((r)->direct) ? \1500bus_write_1((r)->res, (o), (v)) : \1501BHND_BUS_WRITE_1( \1502device_get_parent(rman_get_device((r)->res)), \1503rman_get_device((r)->res), (r), (o), (v)))1504#define bhnd_bus_write_multi_1(r, o, d, c) \1505(((r)->direct) ? \1506bus_write_multi_1((r)->res, (o), (d), (c)) : \1507BHND_BUS_WRITE_MULTI_1( \1508device_get_parent(rman_get_device((r)->res)), \1509rman_get_device((r)->res), (r), (o), (d), (c)))1510#define bhnd_bus_write_region_1(r, o, d, c) \1511(((r)->direct) ? \1512bus_write_region_1((r)->res, (o), (d), (c)) : \1513BHND_BUS_WRITE_REGION_1( \1514device_get_parent(rman_get_device((r)->res)), \1515rman_get_device((r)->res), (r), (o), (d), (c)))1516#define bhnd_bus_read_stream_1(r, o) \1517(((r)->direct) ? \1518bus_read_stream_1((r)->res, (o)) : \1519BHND_BUS_READ_STREAM_1( \1520device_get_parent(rman_get_device((r)->res)), \1521rman_get_device((r)->res), (r), (o)))1522#define bhnd_bus_read_multi_stream_1(r, o, d, c) \1523(((r)->direct) ? \1524bus_read_multi_stream_1((r)->res, (o), (d), (c)) : \1525BHND_BUS_READ_MULTI_STREAM_1( \1526device_get_parent(rman_get_device((r)->res)), \1527rman_get_device((r)->res), (r), (o), (d), (c)))1528#define bhnd_bus_read_region_stream_1(r, o, d, c) \1529(((r)->direct) ? \1530bus_read_region_stream_1((r)->res, (o), (d), (c)) : \1531BHND_BUS_READ_REGION_STREAM_1( \1532device_get_parent(rman_get_device((r)->res)), \1533rman_get_device((r)->res), (r), (o), (d), (c)))1534#define bhnd_bus_write_stream_1(r, o, v) \1535(((r)->direct) ? \1536bus_write_stream_1((r)->res, (o), (v)) : \1537BHND_BUS_WRITE_STREAM_1( \1538device_get_parent(rman_get_device((r)->res)), \1539rman_get_device((r)->res), (r), (o), (v)))1540#define bhnd_bus_write_multi_stream_1(r, o, d, c) \1541(((r)->direct) ? \1542bus_write_multi_stream_1((r)->res, (o), (d), (c)) : \1543BHND_BUS_WRITE_MULTI_STREAM_1( \1544device_get_parent(rman_get_device((r)->res)), \1545rman_get_device((r)->res), (r), (o), (d), (c)))1546#define bhnd_bus_write_region_stream_1(r, o, d, c) \1547(((r)->direct) ? \1548bus_write_region_stream_1((r)->res, (o), (d), (c)) : \1549BHND_BUS_WRITE_REGION_STREAM_1( \1550device_get_parent(rman_get_device((r)->res)), \1551rman_get_device((r)->res), (r), (o), (d), (c)))1552#define bhnd_bus_set_multi_1(r, o, v, c) \1553(((r)->direct) ? \1554bus_set_multi_1((r)->res, (o), (v), (c)) : \1555BHND_BUS_SET_MULTI_1( \1556device_get_parent(rman_get_device((r)->res)), \1557rman_get_device((r)->res), (r), (o), (v), (c)))1558#define bhnd_bus_set_region_1(r, o, v, c) \1559(((r)->direct) ? \1560bus_set_region_1((r)->res, (o), (v), (c)) : \1561BHND_BUS_SET_REGION_1( \1562device_get_parent(rman_get_device((r)->res)), \1563rman_get_device((r)->res), (r), (o), (v), (c)))1564#define bhnd_bus_read_2(r, o) \1565(((r)->direct) ? \1566bus_read_2((r)->res, (o)) : \1567BHND_BUS_READ_2( \1568device_get_parent(rman_get_device((r)->res)), \1569rman_get_device((r)->res), (r), (o)))1570#define bhnd_bus_read_multi_2(r, o, d, c) \1571(((r)->direct) ? \1572bus_read_multi_2((r)->res, (o), (d), (c)) : \1573BHND_BUS_READ_MULTI_2( \1574device_get_parent(rman_get_device((r)->res)), \1575rman_get_device((r)->res), (r), (o), (d), (c)))1576#define bhnd_bus_read_region_2(r, o, d, c) \1577(((r)->direct) ? \1578bus_read_region_2((r)->res, (o), (d), (c)) : \1579BHND_BUS_READ_REGION_2( \1580device_get_parent(rman_get_device((r)->res)), \1581rman_get_device((r)->res), (r), (o), (d), (c)))1582#define bhnd_bus_write_2(r, o, v) \1583(((r)->direct) ? \1584bus_write_2((r)->res, (o), (v)) : \1585BHND_BUS_WRITE_2( \1586device_get_parent(rman_get_device((r)->res)), \1587rman_get_device((r)->res), (r), (o), (v)))1588#define bhnd_bus_write_multi_2(r, o, d, c) \1589(((r)->direct) ? \1590bus_write_multi_2((r)->res, (o), (d), (c)) : \1591BHND_BUS_WRITE_MULTI_2( \1592device_get_parent(rman_get_device((r)->res)), \1593rman_get_device((r)->res), (r), (o), (d), (c)))1594#define bhnd_bus_write_region_2(r, o, d, c) \1595(((r)->direct) ? \1596bus_write_region_2((r)->res, (o), (d), (c)) : \1597BHND_BUS_WRITE_REGION_2( \1598device_get_parent(rman_get_device((r)->res)), \1599rman_get_device((r)->res), (r), (o), (d), (c)))1600#define bhnd_bus_read_stream_2(r, o) \1601(((r)->direct) ? \1602bus_read_stream_2((r)->res, (o)) : \1603BHND_BUS_READ_STREAM_2( \1604device_get_parent(rman_get_device((r)->res)), \1605rman_get_device((r)->res), (r), (o)))1606#define bhnd_bus_read_multi_stream_2(r, o, d, c) \1607(((r)->direct) ? \1608bus_read_multi_stream_2((r)->res, (o), (d), (c)) : \1609BHND_BUS_READ_MULTI_STREAM_2( \1610device_get_parent(rman_get_device((r)->res)), \1611rman_get_device((r)->res), (r), (o), (d), (c)))1612#define bhnd_bus_read_region_stream_2(r, o, d, c) \1613(((r)->direct) ? \1614bus_read_region_stream_2((r)->res, (o), (d), (c)) : \1615BHND_BUS_READ_REGION_STREAM_2( \1616device_get_parent(rman_get_device((r)->res)), \1617rman_get_device((r)->res), (r), (o), (d), (c)))1618#define bhnd_bus_write_stream_2(r, o, v) \1619(((r)->direct) ? \1620bus_write_stream_2((r)->res, (o), (v)) : \1621BHND_BUS_WRITE_STREAM_2( \1622device_get_parent(rman_get_device((r)->res)), \1623rman_get_device((r)->res), (r), (o), (v)))1624#define bhnd_bus_write_multi_stream_2(r, o, d, c) \1625(((r)->direct) ? \1626bus_write_multi_stream_2((r)->res, (o), (d), (c)) : \1627BHND_BUS_WRITE_MULTI_STREAM_2( \1628device_get_parent(rman_get_device((r)->res)), \1629rman_get_device((r)->res), (r), (o), (d), (c)))1630#define bhnd_bus_write_region_stream_2(r, o, d, c) \1631(((r)->direct) ? \1632bus_write_region_stream_2((r)->res, (o), (d), (c)) : \1633BHND_BUS_WRITE_REGION_STREAM_2( \1634device_get_parent(rman_get_device((r)->res)), \1635rman_get_device((r)->res), (r), (o), (d), (c)))1636#define bhnd_bus_set_multi_2(r, o, v, c) \1637(((r)->direct) ? \1638bus_set_multi_2((r)->res, (o), (v), (c)) : \1639BHND_BUS_SET_MULTI_2( \1640device_get_parent(rman_get_device((r)->res)), \1641rman_get_device((r)->res), (r), (o), (v), (c)))1642#define bhnd_bus_set_region_2(r, o, v, c) \1643(((r)->direct) ? \1644bus_set_region_2((r)->res, (o), (v), (c)) : \1645BHND_BUS_SET_REGION_2( \1646device_get_parent(rman_get_device((r)->res)), \1647rman_get_device((r)->res), (r), (o), (v), (c)))1648#define bhnd_bus_read_4(r, o) \1649(((r)->direct) ? \1650bus_read_4((r)->res, (o)) : \1651BHND_BUS_READ_4( \1652device_get_parent(rman_get_device((r)->res)), \1653rman_get_device((r)->res), (r), (o)))1654#define bhnd_bus_read_multi_4(r, o, d, c) \1655(((r)->direct) ? \1656bus_read_multi_4((r)->res, (o), (d), (c)) : \1657BHND_BUS_READ_MULTI_4( \1658device_get_parent(rman_get_device((r)->res)), \1659rman_get_device((r)->res), (r), (o), (d), (c)))1660#define bhnd_bus_read_region_4(r, o, d, c) \1661(((r)->direct) ? \1662bus_read_region_4((r)->res, (o), (d), (c)) : \1663BHND_BUS_READ_REGION_4( \1664device_get_parent(rman_get_device((r)->res)), \1665rman_get_device((r)->res), (r), (o), (d), (c)))1666#define bhnd_bus_write_4(r, o, v) \1667(((r)->direct) ? \1668bus_write_4((r)->res, (o), (v)) : \1669BHND_BUS_WRITE_4( \1670device_get_parent(rman_get_device((r)->res)), \1671rman_get_device((r)->res), (r), (o), (v)))1672#define bhnd_bus_write_multi_4(r, o, d, c) \1673(((r)->direct) ? \1674bus_write_multi_4((r)->res, (o), (d), (c)) : \1675BHND_BUS_WRITE_MULTI_4( \1676device_get_parent(rman_get_device((r)->res)), \1677rman_get_device((r)->res), (r), (o), (d), (c)))1678#define bhnd_bus_write_region_4(r, o, d, c) \1679(((r)->direct) ? \1680bus_write_region_4((r)->res, (o), (d), (c)) : \1681BHND_BUS_WRITE_REGION_4( \1682device_get_parent(rman_get_device((r)->res)), \1683rman_get_device((r)->res), (r), (o), (d), (c)))1684#define bhnd_bus_read_stream_4(r, o) \1685(((r)->direct) ? \1686bus_read_stream_4((r)->res, (o)) : \1687BHND_BUS_READ_STREAM_4( \1688device_get_parent(rman_get_device((r)->res)), \1689rman_get_device((r)->res), (r), (o)))1690#define bhnd_bus_read_multi_stream_4(r, o, d, c) \1691(((r)->direct) ? \1692bus_read_multi_stream_4((r)->res, (o), (d), (c)) : \1693BHND_BUS_READ_MULTI_STREAM_4( \1694device_get_parent(rman_get_device((r)->res)), \1695rman_get_device((r)->res), (r), (o), (d), (c)))1696#define bhnd_bus_read_region_stream_4(r, o, d, c) \1697(((r)->direct) ? \1698bus_read_region_stream_4((r)->res, (o), (d), (c)) : \1699BHND_BUS_READ_REGION_STREAM_4( \1700device_get_parent(rman_get_device((r)->res)), \1701rman_get_device((r)->res), (r), (o), (d), (c)))1702#define bhnd_bus_write_stream_4(r, o, v) \1703(((r)->direct) ? \1704bus_write_stream_4((r)->res, (o), (v)) : \1705BHND_BUS_WRITE_STREAM_4( \1706device_get_parent(rman_get_device((r)->res)), \1707rman_get_device((r)->res), (r), (o), (v)))1708#define bhnd_bus_write_multi_stream_4(r, o, d, c) \1709(((r)->direct) ? \1710bus_write_multi_stream_4((r)->res, (o), (d), (c)) : \1711BHND_BUS_WRITE_MULTI_STREAM_4( \1712device_get_parent(rman_get_device((r)->res)), \1713rman_get_device((r)->res), (r), (o), (d), (c)))1714#define bhnd_bus_write_region_stream_4(r, o, d, c) \1715(((r)->direct) ? \1716bus_write_region_stream_4((r)->res, (o), (d), (c)) : \1717BHND_BUS_WRITE_REGION_STREAM_4( \1718device_get_parent(rman_get_device((r)->res)), \1719rman_get_device((r)->res), (r), (o), (d), (c)))1720#define bhnd_bus_set_multi_4(r, o, v, c) \1721(((r)->direct) ? \1722bus_set_multi_4((r)->res, (o), (v), (c)) : \1723BHND_BUS_SET_MULTI_4( \1724device_get_parent(rman_get_device((r)->res)), \1725rman_get_device((r)->res), (r), (o), (v), (c)))1726#define bhnd_bus_set_region_4(r, o, v, c) \1727(((r)->direct) ? \1728bus_set_region_4((r)->res, (o), (v), (c)) : \1729BHND_BUS_SET_REGION_4( \1730device_get_parent(rman_get_device((r)->res)), \1731rman_get_device((r)->res), (r), (o), (v), (c)))17321733#endif /* _BHND_BHND_H_ */173417351736