2 * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
35 #include <sys/systm.h>
37 #include <machine/bus.h>
39 #include <machine/resource.h>
41 #include <dev/bhnd/siba/sibareg.h>
43 #include <dev/bhnd/cores/chipc/chipcreg.h>
45 #include "nvram/bhnd_nvram.h"
47 #include "bhnd_chipc_if.h"
49 #include "bhnd_nvram_if.h"
50 #include "bhnd_nvram_map.h"
55 /* BHND core device description table. */
56 static const struct bhnd_core_desc {
59 bhnd_devclass_t class;
61 } bhnd_core_descs[] = {
62 #define BHND_CDESC(_mfg, _cid, _cls, _desc) \
63 { BHND_MFGID_ ## _mfg, BHND_COREID_ ## _cid, \
64 BHND_DEVCLASS_ ## _cls, _desc }
66 BHND_CDESC(BCM, CC, CC, "ChipCommon I/O Controller"),
67 BHND_CDESC(BCM, ILINE20, OTHER, "iLine20 HPNA"),
68 BHND_CDESC(BCM, SRAM, RAM, "SRAM"),
69 BHND_CDESC(BCM, SDRAM, RAM, "SDRAM"),
70 BHND_CDESC(BCM, PCI, PCI, "PCI Bridge"),
71 BHND_CDESC(BCM, MIPS, CPU, "BMIPS CPU"),
72 BHND_CDESC(BCM, ENET, ENET_MAC, "Fast Ethernet MAC"),
73 BHND_CDESC(BCM, CODEC, OTHER, "V.90 Modem Codec"),
74 BHND_CDESC(BCM, USB, USB_DUAL, "USB 1.1 Device/Host Controller"),
75 BHND_CDESC(BCM, ADSL, OTHER, "ADSL Core"),
76 BHND_CDESC(BCM, ILINE100, OTHER, "iLine100 HPNA"),
77 BHND_CDESC(BCM, IPSEC, OTHER, "IPsec Accelerator"),
78 BHND_CDESC(BCM, UTOPIA, OTHER, "UTOPIA ATM Core"),
79 BHND_CDESC(BCM, PCMCIA, PCCARD, "PCMCIA Bridge"),
80 BHND_CDESC(BCM, SOCRAM, RAM, "Internal Memory"),
81 BHND_CDESC(BCM, MEMC, MEMC, "MEMC SDRAM Controller"),
82 BHND_CDESC(BCM, OFDM, OTHER, "OFDM PHY"),
83 BHND_CDESC(BCM, EXTIF, OTHER, "External Interface"),
84 BHND_CDESC(BCM, D11, WLAN, "802.11 MAC/PHY/Radio"),
85 BHND_CDESC(BCM, APHY, WLAN_PHY, "802.11a PHY"),
86 BHND_CDESC(BCM, BPHY, WLAN_PHY, "802.11b PHY"),
87 BHND_CDESC(BCM, GPHY, WLAN_PHY, "802.11g PHY"),
88 BHND_CDESC(BCM, MIPS33, CPU, "BMIPS33 CPU"),
89 BHND_CDESC(BCM, USB11H, USB_HOST, "USB 1.1 Host Controller"),
90 BHND_CDESC(BCM, USB11D, USB_DEV, "USB 1.1 Device Controller"),
91 BHND_CDESC(BCM, USB20H, USB_HOST, "USB 2.0 Host Controller"),
92 BHND_CDESC(BCM, USB20D, USB_DEV, "USB 2.0 Device Controller"),
93 BHND_CDESC(BCM, SDIOH, OTHER, "SDIO Host Controller"),
94 BHND_CDESC(BCM, ROBO, OTHER, "RoboSwitch"),
95 BHND_CDESC(BCM, ATA100, OTHER, "Parallel ATA Controller"),
96 BHND_CDESC(BCM, SATAXOR, OTHER, "SATA DMA/XOR Controller"),
97 BHND_CDESC(BCM, GIGETH, ENET_MAC, "Gigabit Ethernet MAC"),
98 BHND_CDESC(BCM, PCIE, PCIE, "PCIe Bridge"),
99 BHND_CDESC(BCM, NPHY, WLAN_PHY, "802.11n 2x2 PHY"),
100 BHND_CDESC(BCM, SRAMC, MEMC, "SRAM Controller"),
101 BHND_CDESC(BCM, MINIMAC, OTHER, "MINI MAC/PHY"),
102 BHND_CDESC(BCM, ARM11, CPU, "ARM1176 CPU"),
103 BHND_CDESC(BCM, ARM7S, CPU, "ARM7TDMI-S CPU"),
104 BHND_CDESC(BCM, LPPHY, WLAN_PHY, "802.11a/b/g PHY"),
105 BHND_CDESC(BCM, PMU, PMU, "PMU"),
106 BHND_CDESC(BCM, SSNPHY, WLAN_PHY, "802.11n Single-Stream PHY"),
107 BHND_CDESC(BCM, SDIOD, OTHER, "SDIO Device Core"),
108 BHND_CDESC(BCM, ARMCM3, CPU, "ARM Cortex-M3 CPU"),
109 BHND_CDESC(BCM, HTPHY, WLAN_PHY, "802.11n 4x4 PHY"),
110 BHND_CDESC(MIPS,MIPS74K, CPU, "MIPS74k CPU"),
111 BHND_CDESC(BCM, GMAC, ENET_MAC, "Gigabit MAC core"),
112 BHND_CDESC(BCM, DMEMC, MEMC, "DDR1/DDR2 Memory Controller"),
113 BHND_CDESC(BCM, PCIERC, OTHER, "PCIe Root Complex"),
114 BHND_CDESC(BCM, OCP, SOC_BRIDGE, "OCP to OCP Bridge"),
115 BHND_CDESC(BCM, SC, OTHER, "Shared Common Core"),
116 BHND_CDESC(BCM, AHB, SOC_BRIDGE, "OCP to AHB Bridge"),
117 BHND_CDESC(BCM, SPIH, OTHER, "SPI Host Controller"),
118 BHND_CDESC(BCM, I2S, OTHER, "I2S Digital Audio Interface"),
119 BHND_CDESC(BCM, DMEMS, MEMC, "SDR/DDR1 Memory Controller"),
120 BHND_CDESC(BCM, UBUS_SHIM, OTHER, "BCM6362/UBUS WLAN SHIM"),
121 BHND_CDESC(BCM, PCIE2, PCIE, "PCIe Bridge (Gen2)"),
123 BHND_CDESC(ARM, APB_BRIDGE, SOC_BRIDGE, "BP135 AMBA3 AXI to APB Bridge"),
124 BHND_CDESC(ARM, PL301, SOC_ROUTER, "PL301 AMBA3 Interconnect"),
125 BHND_CDESC(ARM, EROM, EROM, "PL366 Device Enumeration ROM"),
126 BHND_CDESC(ARM, OOB_ROUTER, OTHER, "PL367 OOB Interrupt Router"),
127 BHND_CDESC(ARM, AXI_UNMAPPED, OTHER, "Unmapped Address Ranges"),
129 BHND_CDESC(BCM, 4706_CC, CC, "ChipCommon I/O Controller"),
130 BHND_CDESC(BCM, NS_PCIE2, PCIE, "PCIe Bridge (Gen2)"),
131 BHND_CDESC(BCM, NS_DMA, OTHER, "DMA engine"),
132 BHND_CDESC(BCM, NS_SDIO, OTHER, "SDIO 3.0 Host Controller"),
133 BHND_CDESC(BCM, NS_USB20H, USB_HOST, "USB 2.0 Host Controller"),
134 BHND_CDESC(BCM, NS_USB30H, USB_HOST, "USB 3.0 Host Controller"),
135 BHND_CDESC(BCM, NS_A9JTAG, OTHER, "ARM Cortex A9 JTAG Interface"),
136 BHND_CDESC(BCM, NS_DDR23_MEMC, MEMC, "Denali DDR2/DD3 Memory Controller"),
137 BHND_CDESC(BCM, NS_ROM, NVRAM, "System ROM"),
138 BHND_CDESC(BCM, NS_NAND, NVRAM, "NAND Flash Controller"),
139 BHND_CDESC(BCM, NS_QSPI, NVRAM, "QSPI Flash Controller"),
140 BHND_CDESC(BCM, NS_CC_B, CC_B, "ChipCommon B Auxiliary I/O Controller"),
141 BHND_CDESC(BCM, 4706_SOCRAM, RAM, "Internal Memory"),
142 BHND_CDESC(BCM, IHOST_ARMCA9, CPU, "ARM Cortex A9 CPU"),
143 BHND_CDESC(BCM, 4706_GMAC_CMN, ENET, "Gigabit MAC (Common)"),
144 BHND_CDESC(BCM, 4706_GMAC, ENET_MAC, "Gigabit MAC"),
145 BHND_CDESC(BCM, AMEMC, MEMC, "Denali DDR1/DDR2 Memory Controller"),
148 /* Derived from inspection of the BCM4331 cores that provide PrimeCell
149 * IDs. Due to lack of documentation, the surmised device name/purpose
150 * provided here may be incorrect. */
151 { BHND_MFGID_ARM, BHND_PRIMEID_EROM, BHND_DEVCLASS_OTHER,
152 "PL364 Device Enumeration ROM" },
153 { BHND_MFGID_ARM, BHND_PRIMEID_SWRAP, BHND_DEVCLASS_OTHER,
154 "PL368 Device Management Interface" },
155 { BHND_MFGID_ARM, BHND_PRIMEID_MWRAP, BHND_DEVCLASS_OTHER,
156 "PL369 Device Management Interface" },
162 * Return the name for a given JEP106 manufacturer ID.
164 * @param vendor A JEP106 Manufacturer ID, including the non-standard ARM 4-bit
165 * JEP106 continuation code.
168 bhnd_vendor_name(uint16_t vendor)
175 case BHND_MFGID_MIPS:
183 * Return the name of a port type.
186 bhnd_port_type_name(bhnd_port_type port_type)
189 case BHND_PORT_DEVICE:
191 case BHND_PORT_BRIDGE:
193 case BHND_PORT_AGENT:
201 * Return the name of an NVRAM source.
204 bhnd_nvram_src_name(bhnd_nvram_src nvram_src)
207 case BHND_NVRAM_SRC_FLASH:
209 case BHND_NVRAM_SRC_OTP:
211 case BHND_NVRAM_SRC_SPROM:
213 case BHND_NVRAM_SRC_UNKNOWN:
220 static const struct bhnd_core_desc *
221 bhnd_find_core_desc(uint16_t vendor, uint16_t device)
223 for (u_int i = 0; bhnd_core_descs[i].desc != NULL; i++) {
224 if (bhnd_core_descs[i].vendor != vendor)
227 if (bhnd_core_descs[i].device != device)
230 return (&bhnd_core_descs[i]);
237 * Return a human-readable name for a BHND core.
239 * @param vendor The core designer's JEDEC-106 Manufacturer ID
240 * @param device The core identifier.
243 bhnd_find_core_name(uint16_t vendor, uint16_t device)
245 const struct bhnd_core_desc *desc;
247 if ((desc = bhnd_find_core_desc(vendor, device)) == NULL)
254 * Return the device class for a BHND core.
256 * @param vendor The core designer's JEDEC-106 Manufacturer ID
257 * @param device The core identifier.
260 bhnd_find_core_class(uint16_t vendor, uint16_t device)
262 const struct bhnd_core_desc *desc;
264 if ((desc = bhnd_find_core_desc(vendor, device)) == NULL)
265 return (BHND_DEVCLASS_OTHER);
271 * Return a human-readable name for a BHND core.
273 * @param ci The core's info record.
276 bhnd_core_name(const struct bhnd_core_info *ci)
278 return bhnd_find_core_name(ci->vendor, ci->device);
282 * Return the device class for a BHND core.
284 * @param ci The core's info record.
287 bhnd_core_class(const struct bhnd_core_info *ci)
289 return bhnd_find_core_class(ci->vendor, ci->device);
293 * Write a human readable name representation of the given
294 * BHND_CHIPID_* constant to @p buffer.
296 * @param buffer Output buffer, or NULL to compute the required size.
297 * @param size Capacity of @p buffer, in bytes.
298 * @param chip_id Chip ID to be formatted.
300 * @return Returns the required number of bytes on success, or a negative
301 * integer on failure. No more than @p size-1 characters be written, with
302 * the @p size'th set to '\0'.
304 * @sa BHND_CHIPID_MAX_NAMELEN
307 bhnd_format_chip_id(char *buffer, size_t size, uint16_t chip_id)
309 /* All hex formatted IDs are within the range of 0x4000-0x9C3F (40000-1) */
310 if (chip_id >= 0x4000 && chip_id <= 0x9C3F)
311 return (snprintf(buffer, size, "BCM%hX", chip_id));
313 return (snprintf(buffer, size, "BCM%hu", chip_id));
317 * Initialize a core info record with data from from a bhnd-attached @p dev.
319 * @param dev A bhnd device.
320 * @param core The record to be initialized.
322 struct bhnd_core_info
323 bhnd_get_core_info(device_t dev) {
324 return (struct bhnd_core_info) {
325 .vendor = bhnd_get_vendor(dev),
326 .device = bhnd_get_device(dev),
327 .hwrev = bhnd_get_hwrev(dev),
328 .core_idx = bhnd_get_core_index(dev),
329 .unit = bhnd_get_core_unit(dev)
334 * Find a @p class child device with @p unit on @p dev.
336 * @param parent The bhnd-compatible bus to be searched.
337 * @param class The device class to match on.
338 * @param unit The core unit number; specify -1 to return the first match
339 * regardless of unit number.
341 * @retval device_t if a matching child device is found.
342 * @retval NULL if no matching child device is found.
345 bhnd_find_child(device_t dev, bhnd_devclass_t class, int unit)
347 struct bhnd_core_match md = {
348 BHND_MATCH_CORE_CLASS(class),
349 BHND_MATCH_CORE_UNIT(unit)
353 md.m.match.core_unit = 0;
355 return bhnd_match_child(dev, &md);
359 * Find the first child device on @p dev that matches @p desc.
361 * @param parent The bhnd-compatible bus to be searched.
362 * @param desc A match descriptor.
364 * @retval device_t if a matching child device is found.
365 * @retval NULL if no matching child device is found.
368 bhnd_match_child(device_t dev, const struct bhnd_core_match *desc)
375 error = device_get_children(dev, &devlistp, &devcnt);
380 for (int i = 0; i < devcnt; i++) {
381 struct bhnd_core_info ci = bhnd_get_core_info(devlistp[i]);
383 if (bhnd_core_matches(&ci, desc)) {
390 free(devlistp, M_TEMP);
395 * Walk up the bhnd device hierarchy to locate the root device
396 * to which the bhndb bridge is attached.
398 * This can be used from within bhnd host bridge drivers to locate the
399 * actual upstream host device.
401 * @param dev A bhnd device.
402 * @param bus_class The expected bus (e.g. "pci") to which the bridge root
403 * should be attached.
405 * @retval device_t if a matching parent device is found.
406 * @retval NULL @p dev is not attached via a bhndb bus
407 * @retval NULL no parent device is attached via @p bus_class.
410 bhnd_find_bridge_root(device_t dev, devclass_t bus_class)
412 devclass_t bhndb_class;
415 KASSERT(device_get_devclass(device_get_parent(dev)) == bhnd_devclass,
416 ("%s not a bhnd device", device_get_nameunit(dev)));
418 bhndb_class = devclass_find("bhndb");
420 /* Walk the device tree until we hit a bridge */
422 while ((parent = device_get_parent(parent)) != NULL) {
423 if (device_get_devclass(parent) == bhndb_class)
431 /* Search for a parent attached to the expected bus class */
432 while ((parent = device_get_parent(parent)) != NULL) {
435 bus = device_get_parent(parent);
436 if (bus != NULL && device_get_devclass(bus) == bus_class)
445 * Find the first core in @p cores that matches @p desc.
447 * @param cores The table to search.
448 * @param num_cores The length of @p cores.
449 * @param desc A match descriptor.
451 * @retval bhnd_core_info if a matching core is found.
452 * @retval NULL if no matching core is found.
454 const struct bhnd_core_info *
455 bhnd_match_core(const struct bhnd_core_info *cores, u_int num_cores,
456 const struct bhnd_core_match *desc)
458 for (u_int i = 0; i < num_cores; i++) {
459 if (bhnd_core_matches(&cores[i], desc))
468 * Find the first core in @p cores with the given @p class.
470 * @param cores The table to search.
471 * @param num_cores The length of @p cores.
472 * @param desc A match descriptor.
474 * @retval bhnd_core_info if a matching core is found.
475 * @retval NULL if no matching core is found.
477 const struct bhnd_core_info *
478 bhnd_find_core(const struct bhnd_core_info *cores, u_int num_cores,
479 bhnd_devclass_t class)
481 struct bhnd_core_match md = {
482 BHND_MATCH_CORE_CLASS(class)
485 return bhnd_match_core(cores, num_cores, &md);
490 * Create an equality match descriptor for @p core.
492 * @param core The core info to be matched on.
493 * @param desc On return, will be populated with a match descriptor for @p core.
495 struct bhnd_core_match
496 bhnd_core_get_match_desc(const struct bhnd_core_info *core)
498 return ((struct bhnd_core_match) {
499 BHND_MATCH_CORE_VENDOR(core->vendor),
500 BHND_MATCH_CORE_ID(core->device),
501 BHND_MATCH_CORE_REV(HWREV_EQ(core->hwrev)),
502 BHND_MATCH_CORE_CLASS(bhnd_core_class(core)),
503 BHND_MATCH_CORE_IDX(core->core_idx),
504 BHND_MATCH_CORE_UNIT(core->unit)
510 * Return true if the @p lhs is equal to @p rhs
512 * @param lhs The first bhnd core descriptor to compare.
513 * @param rhs The second bhnd core descriptor to compare.
515 * @retval true if @p lhs is equal to @p rhs
516 * @retval false if @p lhs is not equal to @p rhs
519 bhnd_cores_equal(const struct bhnd_core_info *lhs,
520 const struct bhnd_core_info *rhs)
522 struct bhnd_core_match md;
524 /* Use an equality match descriptor to perform the comparison */
525 md = bhnd_core_get_match_desc(rhs);
526 return (bhnd_core_matches(lhs, &md));
530 * Return true if the @p core matches @p desc.
532 * @param core A bhnd core descriptor.
533 * @param desc A match descriptor to compare against @p core.
535 * @retval true if @p core matches @p match
536 * @retval false if @p core does not match @p match.
539 bhnd_core_matches(const struct bhnd_core_info *core,
540 const struct bhnd_core_match *desc)
542 if (desc->m.match.core_vendor && desc->core_vendor != core->vendor)
545 if (desc->m.match.core_id && desc->core_id != core->device)
548 if (desc->m.match.core_unit && desc->core_unit != core->unit)
551 if (desc->m.match.core_rev &&
552 !bhnd_hwrev_matches(core->hwrev, &desc->core_rev))
555 if (desc->m.match.core_idx && desc->core_idx != core->core_idx)
558 if (desc->m.match.core_class &&
559 desc->core_class != bhnd_core_class(core))
566 * Return true if the @p chip matches @p desc.
568 * @param chip A bhnd chip identifier.
569 * @param desc A match descriptor to compare against @p chip.
571 * @retval true if @p chip matches @p match
572 * @retval false if @p chip does not match @p match.
575 bhnd_chip_matches(const struct bhnd_chipid *chip,
576 const struct bhnd_chip_match *desc)
578 if (desc->m.match.chip_id && chip->chip_id != desc->chip_id)
581 if (desc->m.match.chip_pkg && chip->chip_pkg != desc->chip_pkg)
584 if (desc->m.match.chip_rev &&
585 !bhnd_hwrev_matches(chip->chip_rev, &desc->chip_rev))
592 * Return true if the @p board matches @p desc.
594 * @param board The bhnd board info.
595 * @param desc A match descriptor to compare against @p board.
597 * @retval true if @p chip matches @p match
598 * @retval false if @p chip does not match @p match.
601 bhnd_board_matches(const struct bhnd_board_info *board,
602 const struct bhnd_board_match *desc)
604 if (desc->m.match.board_srom_rev &&
605 !bhnd_hwrev_matches(board->board_srom_rev, &desc->board_srom_rev))
608 if (desc->m.match.board_vendor &&
609 board->board_vendor != desc->board_vendor)
612 if (desc->m.match.board_type && board->board_type != desc->board_type)
615 if (desc->m.match.board_rev &&
616 !bhnd_hwrev_matches(board->board_rev, &desc->board_rev))
623 * Return true if the @p hwrev matches @p desc.
625 * @param hwrev A bhnd hardware revision.
626 * @param desc A match descriptor to compare against @p core.
628 * @retval true if @p hwrev matches @p match
629 * @retval false if @p hwrev does not match @p match.
632 bhnd_hwrev_matches(uint16_t hwrev, const struct bhnd_hwrev_match *desc)
634 if (desc->start != BHND_HWREV_INVALID &&
638 if (desc->end != BHND_HWREV_INVALID &&
646 * Return true if the @p dev matches @p desc.
648 * @param dev A bhnd device.
649 * @param desc A match descriptor to compare against @p dev.
651 * @retval true if @p dev matches @p match
652 * @retval false if @p dev does not match @p match.
655 bhnd_device_matches(device_t dev, const struct bhnd_device_match *desc)
657 struct bhnd_core_info core;
658 const struct bhnd_chipid *chip;
659 struct bhnd_board_info board;
663 /* Construct individual match descriptors */
664 struct bhnd_core_match m_core = { _BHND_CORE_MATCH_COPY(desc) };
665 struct bhnd_chip_match m_chip = { _BHND_CHIP_MATCH_COPY(desc) };
666 struct bhnd_board_match m_board = { _BHND_BOARD_MATCH_COPY(desc) };
668 /* Fetch and match core info */
669 if (m_core.m.match_flags) {
670 /* Only applicable to bhnd-attached cores */
671 parent = device_get_parent(dev);
672 if (device_get_devclass(parent) != bhnd_devclass) {
673 device_printf(dev, "attempting to match core "
674 "attributes against non-core device\n");
678 core = bhnd_get_core_info(dev);
679 if (!bhnd_core_matches(&core, &m_core))
683 /* Fetch and match chip info */
684 if (m_chip.m.match_flags) {
685 chip = bhnd_get_chipid(dev);
687 if (!bhnd_chip_matches(chip, &m_chip))
691 /* Fetch and match board info.
693 * This is not available until after NVRAM is up; earlier device
694 * matches should not include board requirements */
695 if (m_board.m.match_flags) {
696 if ((error = bhnd_read_board_info(dev, &board))) {
697 device_printf(dev, "failed to read required board info "
698 "during device matching: %d\n", error);
702 if (!bhnd_board_matches(&board, &m_board))
711 * Search @p table for an entry matching @p dev.
713 * @param dev A bhnd device to match against @p table.
714 * @param table The device table to search.
715 * @param entry_size The @p table entry size, in bytes.
717 * @retval bhnd_device the first matching device, if any.
718 * @retval NULL if no matching device is found in @p table.
720 const struct bhnd_device *
721 bhnd_device_lookup(device_t dev, const struct bhnd_device *table,
724 const struct bhnd_device *entry;
725 device_t hostb, parent;
726 bhnd_attach_type attach_type;
729 parent = device_get_parent(dev);
730 hostb = bhnd_find_hostb_device(parent);
731 attach_type = bhnd_get_attach_type(dev);
733 for (entry = table; !BHND_DEVICE_IS_END(entry); entry =
734 (const struct bhnd_device *) ((const char *) entry + entry_size))
736 /* match core info */
737 if (!bhnd_device_matches(dev, &entry->core))
740 /* match device flags */
741 dflags = entry->device_flags;
743 /* hostb implies BHND_ATTACH_ADAPTER requirement */
744 if (dflags & BHND_DF_HOSTB)
745 dflags |= BHND_DF_ADAPTER;
747 if (dflags & BHND_DF_ADAPTER)
748 if (attach_type != BHND_ATTACH_ADAPTER)
751 if (dflags & BHND_DF_HOSTB)
755 if (dflags & BHND_DF_SOC)
756 if (attach_type != BHND_ATTACH_NATIVE)
768 * Scan the device @p table for all quirk flags applicable to @p dev.
770 * @param dev A bhnd device to match against @p table.
771 * @param table The device table to search.
773 * @return returns all matching quirk flags.
776 bhnd_device_quirks(device_t dev, const struct bhnd_device *table,
779 const struct bhnd_device *dent;
780 const struct bhnd_device_quirk *qent, *qtable;
783 /* Locate the device entry */
784 if ((dent = bhnd_device_lookup(dev, table, entry_size)) == NULL)
787 /* Quirks table is optional */
788 qtable = dent->quirks_table;
792 /* Collect matching device quirk entries */
794 for (qent = qtable; !BHND_DEVICE_QUIRK_IS_END(qent); qent++) {
795 if (bhnd_device_matches(dev, &qent->desc))
796 quirks |= qent->quirks;
804 * Allocate bhnd(4) resources defined in @p rs from a parent bus.
806 * @param dev The device requesting ownership of the resources.
807 * @param rs A standard bus resource specification. This will be updated
808 * with the allocated resource's RIDs.
809 * @param res On success, the allocated bhnd resources.
812 * @retval non-zero if allocation of any non-RF_OPTIONAL resource fails,
813 * all allocated resources will be released and a regular
814 * unix error code will be returned.
817 bhnd_alloc_resources(device_t dev, struct resource_spec *rs,
818 struct bhnd_resource **res)
820 /* Initialize output array */
821 for (u_int i = 0; rs[i].type != -1; i++)
824 for (u_int i = 0; rs[i].type != -1; i++) {
825 res[i] = bhnd_alloc_resource_any(dev, rs[i].type, &rs[i].rid,
828 /* Clean up all allocations on failure */
829 if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) {
830 bhnd_release_resources(dev, rs, res);
839 * Release bhnd(4) resources defined in @p rs from a parent bus.
841 * @param dev The device that owns the resources.
842 * @param rs A standard bus resource specification previously initialized
843 * by @p bhnd_alloc_resources.
844 * @param res The bhnd resources to be released.
847 bhnd_release_resources(device_t dev, const struct resource_spec *rs,
848 struct bhnd_resource **res)
850 for (u_int i = 0; rs[i].type != -1; i++) {
854 bhnd_release_resource(dev, rs[i].type, rs[i].rid, res[i]);
860 * Parse the CHIPC_ID_* fields from the ChipCommon CHIPC_ID
861 * register, returning its bhnd_chipid representation.
863 * @param idreg The CHIPC_ID register value.
864 * @param enum_addr The enumeration address to include in the result.
867 * On early siba(4) devices, the ChipCommon core does not provide
868 * a valid CHIPC_ID_NUMCORE field. On these ChipCommon revisions
869 * (see CHIPC_NCORES_MIN_HWREV()), this function will parse and return
870 * an invalid `ncores` value.
873 bhnd_parse_chipid(uint32_t idreg, bhnd_addr_t enum_addr)
875 struct bhnd_chipid result;
877 /* Fetch the basic chip info */
878 result.chip_id = CHIPC_GET_BITS(idreg, CHIPC_ID_CHIP);
879 result.chip_pkg = CHIPC_GET_BITS(idreg, CHIPC_ID_PKG);
880 result.chip_rev = CHIPC_GET_BITS(idreg, CHIPC_ID_REV);
881 result.chip_type = CHIPC_GET_BITS(idreg, CHIPC_ID_BUS);
882 result.ncores = CHIPC_GET_BITS(idreg, CHIPC_ID_NUMCORE);
884 result.enum_addr = enum_addr;
891 * Determine the correct core count for a chip identification value that
892 * may contain an invalid core count.
894 * On some early siba(4) devices (see CHIPC_NCORES_MIN_HWREV()), the ChipCommon
895 * core does not provide a valid CHIPC_ID_NUMCORE field.
897 * @param cid The chip identification to be queried.
898 * @param chipc_hwrev The hardware revision of the ChipCommon core from which
900 * @param[out] ncores On success, will be set to the correct core count.
902 * @retval 0 If the core count is already correct, or was mapped to a
904 * @retval EINVAL If the core count is incorrect, but the chip was not
908 bhnd_chipid_fixed_ncores(const struct bhnd_chipid *cid, uint16_t chipc_hwrev,
911 /* bcma(4), and most siba(4) devices */
912 if (CHIPC_NCORES_MIN_HWREV(chipc_hwrev)) {
913 *ncores = cid->ncores;
917 /* broken siba(4) chipsets */
918 switch (cid->chip_id) {
919 case BHND_CHIPID_BCM4306:
922 case BHND_CHIPID_BCM4704:
925 case BHND_CHIPID_BCM5365:
927 * BCM5365 does support ID_NUMCORE in at least
928 * some of its revisions, but for unknown
929 * reasons, Broadcom's drivers always exclude
930 * the ChipCommon revision (0x5) used by BCM5365
931 * from the set of revisions supporting
932 * ID_NUMCORE, and instead supply a fixed value.
934 * Presumably, at least some of these devices
935 * shipped with a broken ID_NUMCORE value.
947 * Allocate the resource defined by @p rs via @p dev, use it
948 * to read the ChipCommon ID register relative to @p chipc_offset,
949 * then release the resource.
951 * @param dev The device owning @p rs.
952 * @param rs A resource spec that encompasses the ChipCommon register block.
953 * @param chipc_offset The offset of the ChipCommon registers within @p rs.
954 * @param[out] result the chip identification data.
957 * @retval non-zero if the ChipCommon identification data could not be read.
960 bhnd_read_chipid(device_t dev, struct resource_spec *rs,
961 bus_size_t chipc_offset, struct bhnd_chipid *result)
963 struct resource *res;
964 bhnd_addr_t enum_addr;
967 int error, rid, rtype;
973 /* Allocate the ChipCommon window resource and fetch the chipid data */
974 res = bus_alloc_resource_any(dev, rtype, &rid, RF_ACTIVE);
977 "failed to allocate bhnd chipc resource\n");
981 /* Fetch the basic chip info */
982 reg = bus_read_4(res, chipc_offset + CHIPC_ID);
983 chip_type = CHIPC_GET_BITS(reg, CHIPC_ID_BUS);
985 /* Fetch the EROMPTR */
986 if (BHND_CHIPTYPE_HAS_EROM(chip_type)) {
987 enum_addr = bus_read_4(res, chipc_offset + CHIPC_EROMPTR);
988 } else if (chip_type == BHND_CHIPTYPE_SIBA) {
989 /* siba(4) uses the ChipCommon base address as the enumeration
991 enum_addr = BHND_DEFAULT_CHIPC_ADDR;
993 device_printf(dev, "unknown chip type %hhu\n", chip_type);
998 *result = bhnd_parse_chipid(reg, enum_addr);
1000 /* Fix the core count on early siba(4) devices */
1001 if (chip_type == BHND_CHIPTYPE_SIBA) {
1003 uint16_t chipc_hwrev;
1006 * We need the ChipCommon revision to determine whether
1007 * the ncore field is valid.
1009 * We can safely assume the siba IDHIGH register is mapped
1010 * within the chipc register block.
1012 idh = bus_read_4(res, SB0_REG_ABS(SIBA_CFG0_IDHIGH));
1013 chipc_hwrev = SIBA_IDH_CORE_REV(idh);
1015 error = bhnd_chipid_fixed_ncores(result, chipc_hwrev,
1023 bus_release_resource(dev, rtype, rid, res);
1028 * Read an NVRAM variable's NUL-terminated string value.
1030 * @param dev A bhnd bus child device.
1031 * @param name The NVRAM variable name.
1032 * @param[out] buf A buffer large enough to hold @p len bytes. On
1033 * success, the NUL-terminated string value will be
1034 * written to this buffer. This argment may be NULL if
1035 * the value is not desired.
1036 * @param len The maximum capacity of @p buf.
1037 * @param[out] rlen On success, will be set to the actual size of
1038 * the requested value (including NUL termination). This
1039 * argment may be NULL if the size is not desired.
1042 * @retval ENOENT The requested variable was not found.
1043 * @retval ENODEV No valid NVRAM source could be found.
1044 * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too
1045 * small to hold the requested value.
1046 * @retval EFTYPE If the variable data cannot be coerced to a valid
1047 * string representation.
1048 * @retval ERANGE If value coercion would overflow @p type.
1049 * @retval non-zero If reading @p name otherwise fails, a regular unix
1050 * error code will be returned.
1053 bhnd_nvram_getvar_str(device_t dev, const char *name, char *buf, size_t len,
1060 error = bhnd_nvram_getvar(dev, name, buf, &larg,
1061 BHND_NVRAM_TYPE_STRING);
1069 * Read an NVRAM variable's unsigned integer value.
1071 * @param dev A bhnd bus child device.
1072 * @param name The NVRAM variable name.
1073 * @param[out] value On success, the requested value will be written
1075 * @param width The output integer type width (1, 2, or
1079 * @retval ENOENT The requested variable was not found.
1080 * @retval ENODEV No valid NVRAM source could be found.
1081 * @retval EFTYPE If the variable data cannot be coerced to a
1082 * a valid unsigned integer representation.
1083 * @retval ERANGE If value coercion would overflow (or underflow) an
1084 * unsigned representation of the given @p width.
1085 * @retval non-zero If reading @p name otherwise fails, a regular unix
1086 * error code will be returned.
1089 bhnd_nvram_getvar_uint(device_t dev, const char *name, void *value, int width)
1091 bhnd_nvram_type type;
1096 type = BHND_NVRAM_TYPE_UINT8;
1099 type = BHND_NVRAM_TYPE_UINT16;
1102 type = BHND_NVRAM_TYPE_UINT32;
1105 device_printf(dev, "unsupported NVRAM integer width: %d\n",
1111 return (bhnd_nvram_getvar(dev, name, value, &len, type));
1115 * Read an NVRAM variable's unsigned 8-bit integer value.
1117 * @param dev A bhnd bus child device.
1118 * @param name The NVRAM variable name.
1119 * @param[out] value On success, the requested value will be written
1123 * @retval ENOENT The requested variable was not found.
1124 * @retval ENODEV No valid NVRAM source could be found.
1125 * @retval EFTYPE If the variable data cannot be coerced to a
1126 * a valid unsigned integer representation.
1127 * @retval ERANGE If value coercion would overflow (or underflow) uint8_t.
1128 * @retval non-zero If reading @p name otherwise fails, a regular unix
1129 * error code will be returned.
1132 bhnd_nvram_getvar_uint8(device_t dev, const char *name, uint8_t *value)
1134 return (bhnd_nvram_getvar_uint(dev, name, value, sizeof(*value)));
1138 * Read an NVRAM variable's unsigned 16-bit integer value.
1140 * @param dev A bhnd bus child device.
1141 * @param name The NVRAM variable name.
1142 * @param[out] value On success, the requested value will be written
1146 * @retval ENOENT The requested variable was not found.
1147 * @retval ENODEV No valid NVRAM source could be found.
1148 * @retval EFTYPE If the variable data cannot be coerced to a
1149 * a valid unsigned integer representation.
1150 * @retval ERANGE If value coercion would overflow (or underflow)
1152 * @retval non-zero If reading @p name otherwise fails, a regular unix
1153 * error code will be returned.
1156 bhnd_nvram_getvar_uint16(device_t dev, const char *name, uint16_t *value)
1158 return (bhnd_nvram_getvar_uint(dev, name, value, sizeof(*value)));
1162 * Read an NVRAM variable's unsigned 32-bit integer value.
1164 * @param dev A bhnd bus child device.
1165 * @param name The NVRAM variable name.
1166 * @param[out] value On success, the requested value will be written
1170 * @retval ENOENT The requested variable was not found.
1171 * @retval ENODEV No valid NVRAM source could be found.
1172 * @retval EFTYPE If the variable data cannot be coerced to a
1173 * a valid unsigned integer representation.
1174 * @retval ERANGE If value coercion would overflow (or underflow)
1176 * @retval non-zero If reading @p name otherwise fails, a regular unix
1177 * error code will be returned.
1180 bhnd_nvram_getvar_uint32(device_t dev, const char *name, uint32_t *value)
1182 return (bhnd_nvram_getvar_uint(dev, name, value, sizeof(*value)));
1186 * Read an NVRAM variable's signed integer value.
1188 * @param dev A bhnd bus child device.
1189 * @param name The NVRAM variable name.
1190 * @param[out] value On success, the requested value will be written
1192 * @param width The output integer type width (1, 2, or
1196 * @retval ENOENT The requested variable was not found.
1197 * @retval ENODEV No valid NVRAM source could be found.
1198 * @retval EFTYPE If the variable data cannot be coerced to a
1199 * a valid integer representation.
1200 * @retval ERANGE If value coercion would overflow (or underflow) an
1201 * signed representation of the given @p width.
1202 * @retval non-zero If reading @p name otherwise fails, a regular unix
1203 * error code will be returned.
1206 bhnd_nvram_getvar_int(device_t dev, const char *name, void *value, int width)
1208 bhnd_nvram_type type;
1213 type = BHND_NVRAM_TYPE_INT8;
1216 type = BHND_NVRAM_TYPE_INT16;
1219 type = BHND_NVRAM_TYPE_INT32;
1222 device_printf(dev, "unsupported NVRAM integer width: %d\n",
1228 return (bhnd_nvram_getvar(dev, name, value, &len, type));
1232 * Read an NVRAM variable's signed 8-bit integer value.
1234 * @param dev A bhnd bus child device.
1235 * @param name The NVRAM variable name.
1236 * @param[out] value On success, the requested value will be written
1240 * @retval ENOENT The requested variable was not found.
1241 * @retval ENODEV No valid NVRAM source could be found.
1242 * @retval EFTYPE If the variable data cannot be coerced to a
1243 * a valid integer representation.
1244 * @retval ERANGE If value coercion would overflow (or underflow) int8_t.
1245 * @retval non-zero If reading @p name otherwise fails, a regular unix
1246 * error code will be returned.
1249 bhnd_nvram_getvar_int8(device_t dev, const char *name, int8_t *value)
1251 return (bhnd_nvram_getvar_int(dev, name, value, sizeof(*value)));
1255 * Read an NVRAM variable's signed 16-bit integer value.
1257 * @param dev A bhnd bus child device.
1258 * @param name The NVRAM variable name.
1259 * @param[out] value On success, the requested value will be written
1263 * @retval ENOENT The requested variable was not found.
1264 * @retval ENODEV No valid NVRAM source could be found.
1265 * @retval EFTYPE If the variable data cannot be coerced to a
1266 * a valid integer representation.
1267 * @retval ERANGE If value coercion would overflow (or underflow)
1269 * @retval non-zero If reading @p name otherwise fails, a regular unix
1270 * error code will be returned.
1273 bhnd_nvram_getvar_int16(device_t dev, const char *name, int16_t *value)
1275 return (bhnd_nvram_getvar_int(dev, name, value, sizeof(*value)));
1279 * Read an NVRAM variable's signed 32-bit integer value.
1281 * @param dev A bhnd bus child device.
1282 * @param name The NVRAM variable name.
1283 * @param[out] value On success, the requested value will be written
1287 * @retval ENOENT The requested variable was not found.
1288 * @retval ENODEV No valid NVRAM source could be found.
1289 * @retval EFTYPE If the variable data cannot be coerced to a
1290 * a valid integer representation.
1291 * @retval ERANGE If value coercion would overflow (or underflow)
1293 * @retval non-zero If reading @p name otherwise fails, a regular unix
1294 * error code will be returned.
1297 bhnd_nvram_getvar_int32(device_t dev, const char *name, int32_t *value)
1299 return (bhnd_nvram_getvar_int(dev, name, value, sizeof(*value)));
1304 * Read an NVRAM variable's array value.
1306 * @param dev A bhnd bus child device.
1307 * @param name The NVRAM variable name.
1308 * @param[out] buf A buffer large enough to hold @p size bytes.
1309 * On success, the requested value will be written
1311 * @param[in,out] size The required number of bytes to write to
1313 * @param type The desired array element data representation.
1316 * @retval ENOENT The requested variable was not found.
1317 * @retval ENODEV No valid NVRAM source could be found.
1318 * @retval ENXIO If less than @p size bytes are available.
1319 * @retval ENOMEM If a buffer of @p size is too small to hold the
1321 * @retval EFTYPE If the variable data cannot be coerced to a
1322 * a valid instance of @p type.
1323 * @retval ERANGE If value coercion would overflow (or underflow) a
1324 * representation of @p type.
1325 * @retval non-zero If reading @p name otherwise fails, a regular unix
1326 * error code will be returned.
1329 bhnd_nvram_getvar_array(device_t dev, const char *name, void *buf, size_t size,
1330 bhnd_nvram_type type)
1337 if ((error = bhnd_nvram_getvar(dev, name, buf, &nbytes, type)))
1340 /* Verify that the expected number of bytes were fetched */
1348 * Using the bhnd(4) bus-level core information and a custom core name,
1349 * populate @p dev's device description.
1351 * @param dev A bhnd-bus attached device.
1352 * @param dev_name The core's name (e.g. "SDIO Device Core")
1355 bhnd_set_custom_core_desc(device_t dev, const char *dev_name)
1357 const char *vendor_name;
1360 vendor_name = bhnd_get_vendor_name(dev);
1361 asprintf(&desc, M_BHND, "%s %s, rev %hhu", vendor_name, dev_name,
1362 bhnd_get_hwrev(dev));
1365 device_set_desc_copy(dev, desc);
1368 device_set_desc(dev, dev_name);
1373 * Using the bhnd(4) bus-level core information, populate @p dev's device
1376 * @param dev A bhnd-bus attached device.
1379 bhnd_set_default_core_desc(device_t dev)
1381 bhnd_set_custom_core_desc(dev, bhnd_get_device_name(dev));
1386 * Using the bhnd @p chip_id, populate the bhnd(4) bus @p dev's device
1389 * @param dev A bhnd-bus attached device.
1392 bhnd_set_default_bus_desc(device_t dev, const struct bhnd_chipid *chip_id)
1394 const char *bus_name;
1396 char chip_name[BHND_CHIPID_MAX_NAMELEN];
1398 /* Determine chip type's bus name */
1399 switch (chip_id->chip_type) {
1400 case BHND_CHIPTYPE_SIBA:
1401 bus_name = "SIBA bus";
1403 case BHND_CHIPTYPE_BCMA:
1404 case BHND_CHIPTYPE_BCMA_ALT:
1405 bus_name = "BCMA bus";
1407 case BHND_CHIPTYPE_UBUS:
1408 bus_name = "UBUS bus";
1411 bus_name = "Unknown Type";
1415 /* Format chip name */
1416 bhnd_format_chip_id(chip_name, sizeof(chip_name),
1419 /* Format and set device description */
1420 asprintf(&desc, M_BHND, "%s %s", chip_name, bus_name);
1422 device_set_desc_copy(dev, desc);
1425 device_set_desc(dev, bus_name);
1431 * Helper function for implementing BHND_BUS_IS_HW_DISABLED().
1433 * If a parent device is available, this implementation delegates the
1434 * request to the BHND_BUS_IS_HW_DISABLED() method on the parent of @p dev.
1436 * If no parent device is available (i.e. on a the bus root), the hardware
1437 * is assumed to be usable and false is returned.
1440 bhnd_bus_generic_is_hw_disabled(device_t dev, device_t child)
1442 if (device_get_parent(dev) != NULL)
1443 return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), child));
1449 * Helper function for implementing BHND_BUS_GET_CHIPID().
1451 * This implementation delegates the request to the BHND_BUS_GET_CHIPID()
1452 * method on the parent of @p dev. If no parent exists, the implementation
1455 const struct bhnd_chipid *
1456 bhnd_bus_generic_get_chipid(device_t dev, device_t child)
1458 if (device_get_parent(dev) != NULL)
1459 return (BHND_BUS_GET_CHIPID(device_get_parent(dev), child));
1461 panic("missing BHND_BUS_GET_CHIPID()");
1464 /* nvram board_info population macros for bhnd_bus_generic_read_board_info() */
1465 #define BHND_GV(_dest, _name) \
1466 bhnd_nvram_getvar_uint(child, BHND_NVAR_ ## _name, &_dest, \
1469 #define REQ_BHND_GV(_dest, _name) do { \
1470 if ((error = BHND_GV(_dest, _name))) { \
1471 device_printf(dev, \
1472 "error reading " __STRING(_name) ": %d\n", error); \
1477 #define OPT_BHND_GV(_dest, _name, _default) do { \
1478 if ((error = BHND_GV(_dest, _name))) { \
1479 if (error != ENOENT) { \
1480 device_printf(dev, \
1482 __STRING(_name) ": %d\n", error); \
1490 * Helper function for implementing BHND_BUS_READ_BOARDINFO().
1492 * This implementation populates @p info with information from NVRAM,
1493 * defaulting board_vendor and board_type fields to 0 if the
1494 * requested variables cannot be found.
1496 * This behavior is correct for most SoCs, but must be overridden on
1497 * bridged (PCI, PCMCIA, etc) devices to produce a complete bhnd_board_info
1501 bhnd_bus_generic_read_board_info(device_t dev, device_t child,
1502 struct bhnd_board_info *info)
1506 OPT_BHND_GV(info->board_vendor, BOARDVENDOR, 0);
1507 OPT_BHND_GV(info->board_type, BOARDTYPE, 0); /* srom >= 2 */
1508 REQ_BHND_GV(info->board_rev, BOARDREV);
1509 OPT_BHND_GV(info->board_srom_rev,SROMREV, 0); /* missing in
1512 REQ_BHND_GV(info->board_flags, BOARDFLAGS);
1513 OPT_BHND_GV(info->board_flags2, BOARDFLAGS2, 0); /* srom >= 4 */
1514 OPT_BHND_GV(info->board_flags3, BOARDFLAGS3, 0); /* srom >= 11 */
1524 * Helper function for implementing BHND_BUS_GET_NVRAM_VAR().
1526 * This implementation searches @p dev for a usable NVRAM child device.
1528 * If no usable child device is found on @p dev, the request is delegated to
1529 * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev.
1532 bhnd_bus_generic_get_nvram_var(device_t dev, device_t child, const char *name,
1533 void *buf, size_t *size, bhnd_nvram_type type)
1538 /* Make sure we're holding Giant for newbus */
1541 /* Look for a directly-attached NVRAM child */
1542 if ((nvram = device_find_child(dev, "bhnd_nvram", -1)) != NULL)
1543 return BHND_NVRAM_GETVAR(nvram, name, buf, size, type);
1545 /* Try to delegate to parent */
1546 if ((parent = device_get_parent(dev)) == NULL)
1549 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child,
1550 name, buf, size, type));
1554 * Helper function for implementing BHND_BUS_ALLOC_RESOURCE().
1556 * This implementation of BHND_BUS_ALLOC_RESOURCE() delegates allocation
1557 * of the underlying resource to BUS_ALLOC_RESOURCE(), and activation
1558 * to @p dev's BHND_BUS_ACTIVATE_RESOURCE().
1560 struct bhnd_resource *
1561 bhnd_bus_generic_alloc_resource(device_t dev, device_t child, int type,
1562 int *rid, rman_res_t start, rman_res_t end, rman_res_t count,
1565 struct bhnd_resource *br;
1566 struct resource *res;
1572 /* Allocate the real bus resource (without activating it) */
1573 res = BUS_ALLOC_RESOURCE(dev, child, type, rid, start, end, count,
1574 (flags & ~RF_ACTIVE));
1578 /* Allocate our bhnd resource wrapper. */
1579 br = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT);
1586 /* Attempt activation */
1587 if (flags & RF_ACTIVE) {
1588 error = BHND_BUS_ACTIVATE_RESOURCE(dev, child, type, *rid, br);
1597 BUS_RELEASE_RESOURCE(dev, child, type, *rid, res);
1604 * Helper function for implementing BHND_BUS_RELEASE_RESOURCE().
1606 * This implementation of BHND_BUS_RELEASE_RESOURCE() delegates release of
1607 * the backing resource to BUS_RELEASE_RESOURCE().
1610 bhnd_bus_generic_release_resource(device_t dev, device_t child, int type,
1611 int rid, struct bhnd_resource *r)
1615 if ((error = BUS_RELEASE_RESOURCE(dev, child, type, rid, r->res)))
1624 * Helper function for implementing BHND_BUS_ACTIVATE_RESOURCE().
1626 * This implementation of BHND_BUS_ACTIVATE_RESOURCE() first calls the
1627 * BHND_BUS_ACTIVATE_RESOURCE() method of the parent of @p dev.
1629 * If this fails, and if @p dev is the direct parent of @p child, standard
1630 * resource activation is attempted via bus_activate_resource(). This enables
1631 * direct use of the bhnd(4) resource APIs on devices that may not be attached
1632 * to a parent bhnd bus or bridge.
1635 bhnd_bus_generic_activate_resource(device_t dev, device_t child, int type,
1636 int rid, struct bhnd_resource *r)
1641 passthrough = (device_get_parent(child) != dev);
1643 /* Try to delegate to the parent */
1644 if (device_get_parent(dev) != NULL) {
1645 error = BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev),
1646 child, type, rid, r);
1651 /* If bhnd(4) activation has failed and we're the child's direct
1652 * parent, try falling back on standard resource activation.
1654 if (error && !passthrough) {
1655 error = bus_activate_resource(child, type, rid, r->res);
1664 * Helper function for implementing BHND_BUS_DEACTIVATE_RESOURCE().
1666 * This implementation of BHND_BUS_ACTIVATE_RESOURCE() simply calls the
1667 * BHND_BUS_ACTIVATE_RESOURCE() method of the parent of @p dev.
1670 bhnd_bus_generic_deactivate_resource(device_t dev, device_t child,
1671 int type, int rid, struct bhnd_resource *r)
1673 if (device_get_parent(dev) != NULL)
1674 return (BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev),
1675 child, type, rid, r));