1 /*- 2 * Copyright (c) 2015-2016 Landon Fuller <landon@landonf.org> 3 * Copyright (c) 2017 The FreeBSD Foundation 4 * All rights reserved. 5 * 6 * Portions of this software were developed by Landon Fuller 7 * under sponsorship from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer, 14 * without modification. 15 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 16 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 17 * redistribution must be conditioned upon including a substantially 18 * similar Disclaimer requirement for further binary redistribution. 19 * 20 * NO WARRANTY 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 24 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 25 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 26 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 29 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * THE POSSIBILITY OF SUCH DAMAGES. 32 */ 33 34 #include <sys/cdefs.h> 35 __FBSDID("$FreeBSD$"); 36 37 #include <sys/param.h> 38 #include <sys/bus.h> 39 #include <sys/refcount.h> 40 #include <sys/systm.h> 41 42 #include <machine/bus.h> 43 #include <sys/rman.h> 44 #include <machine/resource.h> 45 46 #include <dev/bhnd/siba/sibareg.h> 47 48 #include <dev/bhnd/cores/chipc/chipcreg.h> 49 50 #include "nvram/bhnd_nvram.h" 51 52 #include "bhnd_chipc_if.h" 53 54 #include "bhnd_nvram_if.h" 55 #include "bhnd_nvram_map.h" 56 57 #include "bhndreg.h" 58 #include "bhndvar.h" 59 #include "bhnd_private.h" 60 61 static void bhnd_service_registry_free_entry( 62 struct bhnd_service_entry *entry); 63 64 static int compare_ascending_probe_order(const void *lhs, const void *rhs); 65 static int compare_descending_probe_order(const void *lhs, 66 const void *rhs); 67 68 /* BHND core device description table. */ 69 static const struct bhnd_core_desc { 70 uint16_t vendor; 71 uint16_t device; 72 bhnd_devclass_t class; 73 const char *desc; 74 } bhnd_core_descs[] = { 75 #define BHND_CDESC(_mfg, _cid, _cls, _desc) \ 76 { BHND_MFGID_ ## _mfg, BHND_COREID_ ## _cid, \ 77 BHND_DEVCLASS_ ## _cls, _desc } 78 79 BHND_CDESC(BCM, CC, CC, "ChipCommon I/O Controller"), 80 BHND_CDESC(BCM, ILINE20, OTHER, "iLine20 HPNA"), 81 BHND_CDESC(BCM, SRAM, RAM, "SRAM"), 82 BHND_CDESC(BCM, SDRAM, RAM, "SDRAM"), 83 BHND_CDESC(BCM, PCI, PCI, "PCI Bridge"), 84 BHND_CDESC(BCM, MIPS, CPU, "BMIPS CPU"), 85 BHND_CDESC(BCM, ENET, ENET_MAC, "Fast Ethernet MAC"), 86 BHND_CDESC(BCM, CODEC, OTHER, "V.90 Modem Codec"), 87 BHND_CDESC(BCM, USB, USB_DUAL, "USB 1.1 Device/Host Controller"), 88 BHND_CDESC(BCM, ADSL, OTHER, "ADSL Core"), 89 BHND_CDESC(BCM, ILINE100, OTHER, "iLine100 HPNA"), 90 BHND_CDESC(BCM, IPSEC, OTHER, "IPsec Accelerator"), 91 BHND_CDESC(BCM, UTOPIA, OTHER, "UTOPIA ATM Core"), 92 BHND_CDESC(BCM, PCMCIA, PCCARD, "PCMCIA Bridge"), 93 BHND_CDESC(BCM, SOCRAM, RAM, "Internal Memory"), 94 BHND_CDESC(BCM, MEMC, MEMC, "MEMC SDRAM Controller"), 95 BHND_CDESC(BCM, OFDM, OTHER, "OFDM PHY"), 96 BHND_CDESC(BCM, EXTIF, OTHER, "External Interface"), 97 BHND_CDESC(BCM, D11, WLAN, "802.11 MAC/PHY/Radio"), 98 BHND_CDESC(BCM, APHY, WLAN_PHY, "802.11a PHY"), 99 BHND_CDESC(BCM, BPHY, WLAN_PHY, "802.11b PHY"), 100 BHND_CDESC(BCM, GPHY, WLAN_PHY, "802.11g PHY"), 101 BHND_CDESC(BCM, MIPS33, CPU, "BMIPS33 CPU"), 102 BHND_CDESC(BCM, USB11H, USB_HOST, "USB 1.1 Host Controller"), 103 BHND_CDESC(BCM, USB11D, USB_DEV, "USB 1.1 Device Controller"), 104 BHND_CDESC(BCM, USB20H, USB_HOST, "USB 2.0 Host Controller"), 105 BHND_CDESC(BCM, USB20D, USB_DEV, "USB 2.0 Device Controller"), 106 BHND_CDESC(BCM, SDIOH, OTHER, "SDIO Host Controller"), 107 BHND_CDESC(BCM, ROBO, OTHER, "RoboSwitch"), 108 BHND_CDESC(BCM, ATA100, OTHER, "Parallel ATA Controller"), 109 BHND_CDESC(BCM, SATAXOR, OTHER, "SATA DMA/XOR Controller"), 110 BHND_CDESC(BCM, GIGETH, ENET_MAC, "Gigabit Ethernet MAC"), 111 BHND_CDESC(BCM, PCIE, PCIE, "PCIe Bridge"), 112 BHND_CDESC(BCM, NPHY, WLAN_PHY, "802.11n 2x2 PHY"), 113 BHND_CDESC(BCM, SRAMC, MEMC, "SRAM Controller"), 114 BHND_CDESC(BCM, MINIMAC, OTHER, "MINI MAC/PHY"), 115 BHND_CDESC(BCM, ARM11, CPU, "ARM1176 CPU"), 116 BHND_CDESC(BCM, ARM7S, CPU, "ARM7TDMI-S CPU"), 117 BHND_CDESC(BCM, LPPHY, WLAN_PHY, "802.11a/b/g PHY"), 118 BHND_CDESC(BCM, PMU, PMU, "PMU"), 119 BHND_CDESC(BCM, SSNPHY, WLAN_PHY, "802.11n Single-Stream PHY"), 120 BHND_CDESC(BCM, SDIOD, OTHER, "SDIO Device Core"), 121 BHND_CDESC(BCM, ARMCM3, CPU, "ARM Cortex-M3 CPU"), 122 BHND_CDESC(BCM, HTPHY, WLAN_PHY, "802.11n 4x4 PHY"), 123 BHND_CDESC(MIPS,MIPS74K, CPU, "MIPS74k CPU"), 124 BHND_CDESC(BCM, GMAC, ENET_MAC, "Gigabit MAC core"), 125 BHND_CDESC(BCM, DMEMC, MEMC, "DDR1/DDR2 Memory Controller"), 126 BHND_CDESC(BCM, PCIERC, OTHER, "PCIe Root Complex"), 127 BHND_CDESC(BCM, OCP, SOC_BRIDGE, "OCP to OCP Bridge"), 128 BHND_CDESC(BCM, SC, OTHER, "Shared Common Core"), 129 BHND_CDESC(BCM, AHB, SOC_BRIDGE, "OCP to AHB Bridge"), 130 BHND_CDESC(BCM, SPIH, OTHER, "SPI Host Controller"), 131 BHND_CDESC(BCM, I2S, OTHER, "I2S Digital Audio Interface"), 132 BHND_CDESC(BCM, DMEMS, MEMC, "SDR/DDR1 Memory Controller"), 133 BHND_CDESC(BCM, UBUS_SHIM, OTHER, "BCM6362/UBUS WLAN SHIM"), 134 BHND_CDESC(BCM, PCIE2, PCIE, "PCIe Bridge (Gen2)"), 135 136 BHND_CDESC(ARM, APB_BRIDGE, SOC_BRIDGE, "BP135 AMBA3 AXI to APB Bridge"), 137 BHND_CDESC(ARM, PL301, SOC_ROUTER, "PL301 AMBA3 Interconnect"), 138 BHND_CDESC(ARM, EROM, EROM, "PL366 Device Enumeration ROM"), 139 BHND_CDESC(ARM, OOB_ROUTER, OTHER, "PL367 OOB Interrupt Router"), 140 BHND_CDESC(ARM, AXI_UNMAPPED, OTHER, "Unmapped Address Ranges"), 141 142 BHND_CDESC(BCM, 4706_CC, CC, "ChipCommon I/O Controller"), 143 BHND_CDESC(BCM, NS_PCIE2, PCIE, "PCIe Bridge (Gen2)"), 144 BHND_CDESC(BCM, NS_DMA, OTHER, "DMA engine"), 145 BHND_CDESC(BCM, NS_SDIO, OTHER, "SDIO 3.0 Host Controller"), 146 BHND_CDESC(BCM, NS_USB20H, USB_HOST, "USB 2.0 Host Controller"), 147 BHND_CDESC(BCM, NS_USB30H, USB_HOST, "USB 3.0 Host Controller"), 148 BHND_CDESC(BCM, NS_A9JTAG, OTHER, "ARM Cortex A9 JTAG Interface"), 149 BHND_CDESC(BCM, NS_DDR23_MEMC, MEMC, "Denali DDR2/DD3 Memory Controller"), 150 BHND_CDESC(BCM, NS_ROM, NVRAM, "System ROM"), 151 BHND_CDESC(BCM, NS_NAND, NVRAM, "NAND Flash Controller"), 152 BHND_CDESC(BCM, NS_QSPI, NVRAM, "QSPI Flash Controller"), 153 BHND_CDESC(BCM, NS_CC_B, CC_B, "ChipCommon B Auxiliary I/O Controller"), 154 BHND_CDESC(BCM, 4706_SOCRAM, RAM, "Internal Memory"), 155 BHND_CDESC(BCM, IHOST_ARMCA9, CPU, "ARM Cortex A9 CPU"), 156 BHND_CDESC(BCM, 4706_GMAC_CMN, ENET, "Gigabit MAC (Common)"), 157 BHND_CDESC(BCM, 4706_GMAC, ENET_MAC, "Gigabit MAC"), 158 BHND_CDESC(BCM, AMEMC, MEMC, "Denali DDR1/DDR2 Memory Controller"), 159 #undef BHND_CDESC 160 161 /* Derived from inspection of the BCM4331 cores that provide PrimeCell 162 * IDs. Due to lack of documentation, the surmised device name/purpose 163 * provided here may be incorrect. */ 164 { BHND_MFGID_ARM, BHND_PRIMEID_EROM, BHND_DEVCLASS_OTHER, 165 "PL364 Device Enumeration ROM" }, 166 { BHND_MFGID_ARM, BHND_PRIMEID_SWRAP, BHND_DEVCLASS_OTHER, 167 "PL368 Device Management Interface" }, 168 { BHND_MFGID_ARM, BHND_PRIMEID_MWRAP, BHND_DEVCLASS_OTHER, 169 "PL369 Device Management Interface" }, 170 171 { 0, 0, 0, NULL } 172 }; 173 174 /** 175 * Return the name for a given JEP106 manufacturer ID. 176 * 177 * @param vendor A JEP106 Manufacturer ID, including the non-standard ARM 4-bit 178 * JEP106 continuation code. 179 */ 180 const char * 181 bhnd_vendor_name(uint16_t vendor) 182 { 183 switch (vendor) { 184 case BHND_MFGID_ARM: 185 return "ARM"; 186 case BHND_MFGID_BCM: 187 return "Broadcom"; 188 case BHND_MFGID_MIPS: 189 return "MIPS"; 190 default: 191 return "unknown"; 192 } 193 } 194 195 /** 196 * Return the name of a port type. 197 */ 198 const char * 199 bhnd_port_type_name(bhnd_port_type port_type) 200 { 201 switch (port_type) { 202 case BHND_PORT_DEVICE: 203 return ("device"); 204 case BHND_PORT_BRIDGE: 205 return ("bridge"); 206 case BHND_PORT_AGENT: 207 return ("agent"); 208 default: 209 return "unknown"; 210 } 211 } 212 213 /** 214 * Return the name of an NVRAM source. 215 */ 216 const char * 217 bhnd_nvram_src_name(bhnd_nvram_src nvram_src) 218 { 219 switch (nvram_src) { 220 case BHND_NVRAM_SRC_FLASH: 221 return ("flash"); 222 case BHND_NVRAM_SRC_OTP: 223 return ("OTP"); 224 case BHND_NVRAM_SRC_SPROM: 225 return ("SPROM"); 226 case BHND_NVRAM_SRC_UNKNOWN: 227 return ("none"); 228 default: 229 return ("unknown"); 230 } 231 } 232 233 static const struct bhnd_core_desc * 234 bhnd_find_core_desc(uint16_t vendor, uint16_t device) 235 { 236 for (u_int i = 0; bhnd_core_descs[i].desc != NULL; i++) { 237 if (bhnd_core_descs[i].vendor != vendor) 238 continue; 239 240 if (bhnd_core_descs[i].device != device) 241 continue; 242 243 return (&bhnd_core_descs[i]); 244 } 245 246 return (NULL); 247 } 248 249 /** 250 * Return a human-readable name for a BHND core. 251 * 252 * @param vendor The core designer's JEDEC-106 Manufacturer ID 253 * @param device The core identifier. 254 */ 255 const char * 256 bhnd_find_core_name(uint16_t vendor, uint16_t device) 257 { 258 const struct bhnd_core_desc *desc; 259 260 if ((desc = bhnd_find_core_desc(vendor, device)) == NULL) 261 return ("unknown"); 262 263 return desc->desc; 264 } 265 266 /** 267 * Return the device class for a BHND core. 268 * 269 * @param vendor The core designer's JEDEC-106 Manufacturer ID 270 * @param device The core identifier. 271 */ 272 bhnd_devclass_t 273 bhnd_find_core_class(uint16_t vendor, uint16_t device) 274 { 275 const struct bhnd_core_desc *desc; 276 277 if ((desc = bhnd_find_core_desc(vendor, device)) == NULL) 278 return (BHND_DEVCLASS_OTHER); 279 280 return desc->class; 281 } 282 283 /** 284 * Return a human-readable name for a BHND core. 285 * 286 * @param ci The core's info record. 287 */ 288 const char * 289 bhnd_core_name(const struct bhnd_core_info *ci) 290 { 291 return bhnd_find_core_name(ci->vendor, ci->device); 292 } 293 294 /** 295 * Return the device class for a BHND core. 296 * 297 * @param ci The core's info record. 298 */ 299 bhnd_devclass_t 300 bhnd_core_class(const struct bhnd_core_info *ci) 301 { 302 return bhnd_find_core_class(ci->vendor, ci->device); 303 } 304 305 /** 306 * Write a human readable name representation of the given 307 * BHND_CHIPID_* constant to @p buffer. 308 * 309 * @param buffer Output buffer, or NULL to compute the required size. 310 * @param size Capacity of @p buffer, in bytes. 311 * @param chip_id Chip ID to be formatted. 312 * 313 * @return Returns the required number of bytes on success, or a negative 314 * integer on failure. No more than @p size-1 characters be written, with 315 * the @p size'th set to '\0'. 316 * 317 * @sa BHND_CHIPID_MAX_NAMELEN 318 */ 319 int 320 bhnd_format_chip_id(char *buffer, size_t size, uint16_t chip_id) 321 { 322 /* All hex formatted IDs are within the range of 0x4000-0x9C3F (40000-1) */ 323 if (chip_id >= 0x4000 && chip_id <= 0x9C3F) 324 return (snprintf(buffer, size, "BCM%hX", chip_id)); 325 else 326 return (snprintf(buffer, size, "BCM%hu", chip_id)); 327 } 328 329 /** 330 * Initialize a core info record with data from from a bhnd-attached @p dev. 331 * 332 * @param dev A bhnd device. 333 * @param core The record to be initialized. 334 */ 335 struct bhnd_core_info 336 bhnd_get_core_info(device_t dev) { 337 return (struct bhnd_core_info) { 338 .vendor = bhnd_get_vendor(dev), 339 .device = bhnd_get_device(dev), 340 .hwrev = bhnd_get_hwrev(dev), 341 .core_idx = bhnd_get_core_index(dev), 342 .unit = bhnd_get_core_unit(dev) 343 }; 344 } 345 346 /** 347 * Find a @p class child device with @p unit on @p bus. 348 * 349 * @param bus The bhnd-compatible bus to be searched. 350 * @param class The device class to match on. 351 * @param unit The core unit number; specify -1 to return the first match 352 * regardless of unit number. 353 * 354 * @retval device_t if a matching child device is found. 355 * @retval NULL if no matching child device is found. 356 */ 357 device_t 358 bhnd_bus_find_child(device_t bus, bhnd_devclass_t class, int unit) 359 { 360 struct bhnd_core_match md = { 361 BHND_MATCH_CORE_CLASS(class), 362 BHND_MATCH_CORE_UNIT(unit) 363 }; 364 365 if (unit == -1) 366 md.m.match.core_unit = 0; 367 368 return bhnd_bus_match_child(bus, &md); 369 } 370 371 /** 372 * Find the first child device on @p bus that matches @p desc. 373 * 374 * @param bus The bhnd-compatible bus to be searched. 375 * @param desc A match descriptor. 376 * 377 * @retval device_t if a matching child device is found. 378 * @retval NULL if no matching child device is found. 379 */ 380 device_t 381 bhnd_bus_match_child(device_t bus, const struct bhnd_core_match *desc) 382 { 383 device_t *devlistp; 384 device_t match; 385 int devcnt; 386 int error; 387 388 error = device_get_children(bus, &devlistp, &devcnt); 389 if (error != 0) 390 return (NULL); 391 392 match = NULL; 393 for (int i = 0; i < devcnt; i++) { 394 struct bhnd_core_info ci = bhnd_get_core_info(devlistp[i]); 395 396 if (bhnd_core_matches(&ci, desc)) { 397 match = devlistp[i]; 398 goto done; 399 } 400 } 401 402 done: 403 free(devlistp, M_TEMP); 404 return match; 405 } 406 407 /** 408 * Retrieve an ordered list of all device instances currently connected to 409 * @p bus, returning a pointer to the array in @p devlistp and the count 410 * in @p ndevs. 411 * 412 * The memory allocated for the table must be freed via 413 * bhnd_bus_free_children(). 414 * 415 * @param bus The bhnd-compatible bus to be queried. 416 * @param[out] devlist The array of devices. 417 * @param[out] devcount The number of devices in @p devlistp 418 * @param order The order in which devices will be returned 419 * in @p devlist. 420 * 421 * @retval 0 success 422 * @retval non-zero if an error occurs, a regular unix error code will 423 * be returned. 424 */ 425 int 426 bhnd_bus_get_children(device_t bus, device_t **devlist, int *devcount, 427 bhnd_device_order order) 428 { 429 int error; 430 431 /* Fetch device array */ 432 if ((error = device_get_children(bus, devlist, devcount))) 433 return (error); 434 435 /* Perform requested sorting */ 436 if ((error = bhnd_sort_devices(*devlist, *devcount, order))) { 437 bhnd_bus_free_children(*devlist); 438 return (error); 439 } 440 441 return (0); 442 } 443 444 /** 445 * Free any memory allocated in a previous call to bhnd_bus_get_children(). 446 * 447 * @param devlist The device array returned by bhnd_bus_get_children(). 448 */ 449 void 450 bhnd_bus_free_children(device_t *devlist) 451 { 452 free(devlist, M_TEMP); 453 } 454 455 /** 456 * Perform in-place sorting of an array of bhnd device instances. 457 * 458 * @param devlist An array of bhnd devices. 459 * @param devcount The number of devices in @p devs. 460 * @param order The sort order to be used. 461 */ 462 int 463 bhnd_sort_devices(device_t *devlist, size_t devcount, bhnd_device_order order) 464 { 465 int (*compare)(const void *, const void *); 466 467 switch (order) { 468 case BHND_DEVICE_ORDER_ATTACH: 469 compare = compare_ascending_probe_order; 470 break; 471 case BHND_DEVICE_ORDER_DETACH: 472 compare = compare_descending_probe_order; 473 break; 474 default: 475 printf("unknown sort order: %d\n", order); 476 return (EINVAL); 477 } 478 479 qsort(devlist, devcount, sizeof(*devlist), compare); 480 return (0); 481 } 482 483 /* 484 * Ascending comparison of bhnd device's probe order. 485 */ 486 static int 487 compare_ascending_probe_order(const void *lhs, const void *rhs) 488 { 489 device_t ldev, rdev; 490 int lorder, rorder; 491 492 ldev = (*(const device_t *) lhs); 493 rdev = (*(const device_t *) rhs); 494 495 lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev); 496 rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev); 497 498 if (lorder < rorder) { 499 return (-1); 500 } else if (lorder > rorder) { 501 return (1); 502 } else { 503 return (0); 504 } 505 } 506 507 /* 508 * Descending comparison of bhnd device's probe order. 509 */ 510 static int 511 compare_descending_probe_order(const void *lhs, const void *rhs) 512 { 513 return (compare_ascending_probe_order(rhs, lhs)); 514 } 515 516 /** 517 * Call device_probe_and_attach() for each of the bhnd bus device's 518 * children, in bhnd attach order. 519 * 520 * @param bus The bhnd-compatible bus for which all children should be probed 521 * and attached. 522 */ 523 int 524 bhnd_bus_probe_children(device_t bus) 525 { 526 device_t *devs; 527 int ndevs; 528 int error; 529 530 /* Fetch children in attach order */ 531 error = bhnd_bus_get_children(bus, &devs, &ndevs, 532 BHND_DEVICE_ORDER_ATTACH); 533 if (error) 534 return (error); 535 536 /* Probe and attach all children */ 537 for (int i = 0; i < ndevs; i++) { 538 device_t child = devs[i]; 539 device_probe_and_attach(child); 540 } 541 542 bhnd_bus_free_children(devs); 543 544 return (0); 545 } 546 547 /** 548 * Walk up the bhnd device hierarchy to locate the root device 549 * to which the bhndb bridge is attached. 550 * 551 * This can be used from within bhnd host bridge drivers to locate the 552 * actual upstream host device. 553 * 554 * @param dev A bhnd device. 555 * @param bus_class The expected bus (e.g. "pci") to which the bridge root 556 * should be attached. 557 * 558 * @retval device_t if a matching parent device is found. 559 * @retval NULL @p dev is not attached via a bhndb bus 560 * @retval NULL no parent device is attached via @p bus_class. 561 */ 562 device_t 563 bhnd_find_bridge_root(device_t dev, devclass_t bus_class) 564 { 565 devclass_t bhndb_class; 566 device_t parent; 567 568 KASSERT(device_get_devclass(device_get_parent(dev)) == bhnd_devclass, 569 ("%s not a bhnd device", device_get_nameunit(dev))); 570 571 bhndb_class = devclass_find("bhndb"); 572 573 /* Walk the device tree until we hit a bridge */ 574 parent = dev; 575 while ((parent = device_get_parent(parent)) != NULL) { 576 if (device_get_devclass(parent) == bhndb_class) 577 break; 578 } 579 580 /* No bridge? */ 581 if (parent == NULL) 582 return (NULL); 583 584 /* Search for a parent attached to the expected bus class */ 585 while ((parent = device_get_parent(parent)) != NULL) { 586 device_t bus; 587 588 bus = device_get_parent(parent); 589 if (bus != NULL && device_get_devclass(bus) == bus_class) 590 return (parent); 591 } 592 593 /* Not found */ 594 return (NULL); 595 } 596 597 /** 598 * Find the first core in @p cores that matches @p desc. 599 * 600 * @param cores The table to search. 601 * @param num_cores The length of @p cores. 602 * @param desc A match descriptor. 603 * 604 * @retval bhnd_core_info if a matching core is found. 605 * @retval NULL if no matching core is found. 606 */ 607 const struct bhnd_core_info * 608 bhnd_match_core(const struct bhnd_core_info *cores, u_int num_cores, 609 const struct bhnd_core_match *desc) 610 { 611 for (u_int i = 0; i < num_cores; i++) { 612 if (bhnd_core_matches(&cores[i], desc)) 613 return &cores[i]; 614 } 615 616 return (NULL); 617 } 618 619 620 /** 621 * Find the first core in @p cores with the given @p class. 622 * 623 * @param cores The table to search. 624 * @param num_cores The length of @p cores. 625 * @param desc A match descriptor. 626 * 627 * @retval bhnd_core_info if a matching core is found. 628 * @retval NULL if no matching core is found. 629 */ 630 const struct bhnd_core_info * 631 bhnd_find_core(const struct bhnd_core_info *cores, u_int num_cores, 632 bhnd_devclass_t class) 633 { 634 struct bhnd_core_match md = { 635 BHND_MATCH_CORE_CLASS(class) 636 }; 637 638 return bhnd_match_core(cores, num_cores, &md); 639 } 640 641 642 /** 643 * Create an equality match descriptor for @p core. 644 * 645 * @param core The core info to be matched on. 646 * @param desc On return, will be populated with a match descriptor for @p core. 647 */ 648 struct bhnd_core_match 649 bhnd_core_get_match_desc(const struct bhnd_core_info *core) 650 { 651 return ((struct bhnd_core_match) { 652 BHND_MATCH_CORE_VENDOR(core->vendor), 653 BHND_MATCH_CORE_ID(core->device), 654 BHND_MATCH_CORE_REV(HWREV_EQ(core->hwrev)), 655 BHND_MATCH_CORE_CLASS(bhnd_core_class(core)), 656 BHND_MATCH_CORE_IDX(core->core_idx), 657 BHND_MATCH_CORE_UNIT(core->unit) 658 }); 659 } 660 661 662 /** 663 * Return true if the @p lhs is equal to @p rhs 664 * 665 * @param lhs The first bhnd core descriptor to compare. 666 * @param rhs The second bhnd core descriptor to compare. 667 * 668 * @retval true if @p lhs is equal to @p rhs 669 * @retval false if @p lhs is not equal to @p rhs 670 */ 671 bool 672 bhnd_cores_equal(const struct bhnd_core_info *lhs, 673 const struct bhnd_core_info *rhs) 674 { 675 struct bhnd_core_match md; 676 677 /* Use an equality match descriptor to perform the comparison */ 678 md = bhnd_core_get_match_desc(rhs); 679 return (bhnd_core_matches(lhs, &md)); 680 } 681 682 /** 683 * Return true if the @p core matches @p desc. 684 * 685 * @param core A bhnd core descriptor. 686 * @param desc A match descriptor to compare against @p core. 687 * 688 * @retval true if @p core matches @p match 689 * @retval false if @p core does not match @p match. 690 */ 691 bool 692 bhnd_core_matches(const struct bhnd_core_info *core, 693 const struct bhnd_core_match *desc) 694 { 695 if (desc->m.match.core_vendor && desc->core_vendor != core->vendor) 696 return (false); 697 698 if (desc->m.match.core_id && desc->core_id != core->device) 699 return (false); 700 701 if (desc->m.match.core_unit && desc->core_unit != core->unit) 702 return (false); 703 704 if (desc->m.match.core_rev && 705 !bhnd_hwrev_matches(core->hwrev, &desc->core_rev)) 706 return (false); 707 708 if (desc->m.match.core_idx && desc->core_idx != core->core_idx) 709 return (false); 710 711 if (desc->m.match.core_class && 712 desc->core_class != bhnd_core_class(core)) 713 return (false); 714 715 return true; 716 } 717 718 /** 719 * Return true if the @p chip matches @p desc. 720 * 721 * @param chip A bhnd chip identifier. 722 * @param desc A match descriptor to compare against @p chip. 723 * 724 * @retval true if @p chip matches @p match 725 * @retval false if @p chip does not match @p match. 726 */ 727 bool 728 bhnd_chip_matches(const struct bhnd_chipid *chip, 729 const struct bhnd_chip_match *desc) 730 { 731 if (desc->m.match.chip_id && chip->chip_id != desc->chip_id) 732 return (false); 733 734 if (desc->m.match.chip_pkg && chip->chip_pkg != desc->chip_pkg) 735 return (false); 736 737 if (desc->m.match.chip_rev && 738 !bhnd_hwrev_matches(chip->chip_rev, &desc->chip_rev)) 739 return (false); 740 741 return (true); 742 } 743 744 /** 745 * Return true if the @p board matches @p desc. 746 * 747 * @param board The bhnd board info. 748 * @param desc A match descriptor to compare against @p board. 749 * 750 * @retval true if @p chip matches @p match 751 * @retval false if @p chip does not match @p match. 752 */ 753 bool 754 bhnd_board_matches(const struct bhnd_board_info *board, 755 const struct bhnd_board_match *desc) 756 { 757 if (desc->m.match.board_srom_rev && 758 !bhnd_hwrev_matches(board->board_srom_rev, &desc->board_srom_rev)) 759 return (false); 760 761 if (desc->m.match.board_vendor && 762 board->board_vendor != desc->board_vendor) 763 return (false); 764 765 if (desc->m.match.board_type && board->board_type != desc->board_type) 766 return (false); 767 768 if (desc->m.match.board_rev && 769 !bhnd_hwrev_matches(board->board_rev, &desc->board_rev)) 770 return (false); 771 772 return (true); 773 } 774 775 /** 776 * Return true if the @p hwrev matches @p desc. 777 * 778 * @param hwrev A bhnd hardware revision. 779 * @param desc A match descriptor to compare against @p core. 780 * 781 * @retval true if @p hwrev matches @p match 782 * @retval false if @p hwrev does not match @p match. 783 */ 784 bool 785 bhnd_hwrev_matches(uint16_t hwrev, const struct bhnd_hwrev_match *desc) 786 { 787 if (desc->start != BHND_HWREV_INVALID && 788 desc->start > hwrev) 789 return false; 790 791 if (desc->end != BHND_HWREV_INVALID && 792 desc->end < hwrev) 793 return false; 794 795 return true; 796 } 797 798 /** 799 * Return true if the @p dev matches @p desc. 800 * 801 * @param dev A bhnd device. 802 * @param desc A match descriptor to compare against @p dev. 803 * 804 * @retval true if @p dev matches @p match 805 * @retval false if @p dev does not match @p match. 806 */ 807 bool 808 bhnd_device_matches(device_t dev, const struct bhnd_device_match *desc) 809 { 810 struct bhnd_core_info core; 811 const struct bhnd_chipid *chip; 812 struct bhnd_board_info board; 813 device_t parent; 814 int error; 815 816 /* Construct individual match descriptors */ 817 struct bhnd_core_match m_core = { _BHND_CORE_MATCH_COPY(desc) }; 818 struct bhnd_chip_match m_chip = { _BHND_CHIP_MATCH_COPY(desc) }; 819 struct bhnd_board_match m_board = { _BHND_BOARD_MATCH_COPY(desc) }; 820 821 /* Fetch and match core info */ 822 if (m_core.m.match_flags) { 823 /* Only applicable to bhnd-attached cores */ 824 parent = device_get_parent(dev); 825 if (device_get_devclass(parent) != bhnd_devclass) { 826 device_printf(dev, "attempting to match core " 827 "attributes against non-core device\n"); 828 return (false); 829 } 830 831 core = bhnd_get_core_info(dev); 832 if (!bhnd_core_matches(&core, &m_core)) 833 return (false); 834 } 835 836 /* Fetch and match chip info */ 837 if (m_chip.m.match_flags) { 838 chip = bhnd_get_chipid(dev); 839 840 if (!bhnd_chip_matches(chip, &m_chip)) 841 return (false); 842 } 843 844 /* Fetch and match board info. 845 * 846 * This is not available until after NVRAM is up; earlier device 847 * matches should not include board requirements */ 848 if (m_board.m.match_flags) { 849 if ((error = bhnd_read_board_info(dev, &board))) { 850 device_printf(dev, "failed to read required board info " 851 "during device matching: %d\n", error); 852 return (false); 853 } 854 855 if (!bhnd_board_matches(&board, &m_board)) 856 return (false); 857 } 858 859 /* All matched */ 860 return (true); 861 } 862 863 /** 864 * Search @p table for an entry matching @p dev. 865 * 866 * @param dev A bhnd device to match against @p table. 867 * @param table The device table to search. 868 * @param entry_size The @p table entry size, in bytes. 869 * 870 * @retval bhnd_device the first matching device, if any. 871 * @retval NULL if no matching device is found in @p table. 872 */ 873 const struct bhnd_device * 874 bhnd_device_lookup(device_t dev, const struct bhnd_device *table, 875 size_t entry_size) 876 { 877 const struct bhnd_device *entry; 878 device_t hostb, parent; 879 bhnd_attach_type attach_type; 880 uint32_t dflags; 881 882 parent = device_get_parent(dev); 883 hostb = bhnd_bus_find_hostb_device(parent); 884 attach_type = bhnd_get_attach_type(dev); 885 886 for (entry = table; !BHND_DEVICE_IS_END(entry); entry = 887 (const struct bhnd_device *) ((const char *) entry + entry_size)) 888 { 889 /* match core info */ 890 if (!bhnd_device_matches(dev, &entry->core)) 891 continue; 892 893 /* match device flags */ 894 dflags = entry->device_flags; 895 896 /* hostb implies BHND_ATTACH_ADAPTER requirement */ 897 if (dflags & BHND_DF_HOSTB) 898 dflags |= BHND_DF_ADAPTER; 899 900 if (dflags & BHND_DF_ADAPTER) 901 if (attach_type != BHND_ATTACH_ADAPTER) 902 continue; 903 904 if (dflags & BHND_DF_HOSTB) 905 if (dev != hostb) 906 continue; 907 908 if (dflags & BHND_DF_SOC) 909 if (attach_type != BHND_ATTACH_NATIVE) 910 continue; 911 912 /* device found */ 913 return (entry); 914 } 915 916 /* not found */ 917 return (NULL); 918 } 919 920 /** 921 * Scan the device @p table for all quirk flags applicable to @p dev. 922 * 923 * @param dev A bhnd device to match against @p table. 924 * @param table The device table to search. 925 * 926 * @return returns all matching quirk flags. 927 */ 928 uint32_t 929 bhnd_device_quirks(device_t dev, const struct bhnd_device *table, 930 size_t entry_size) 931 { 932 const struct bhnd_device *dent; 933 const struct bhnd_device_quirk *qent, *qtable; 934 uint32_t quirks; 935 936 /* Locate the device entry */ 937 if ((dent = bhnd_device_lookup(dev, table, entry_size)) == NULL) 938 return (0); 939 940 /* Quirks table is optional */ 941 qtable = dent->quirks_table; 942 if (qtable == NULL) 943 return (0); 944 945 /* Collect matching device quirk entries */ 946 quirks = 0; 947 for (qent = qtable; !BHND_DEVICE_QUIRK_IS_END(qent); qent++) { 948 if (bhnd_device_matches(dev, &qent->desc)) 949 quirks |= qent->quirks; 950 } 951 952 return (quirks); 953 } 954 955 956 /** 957 * Allocate bhnd(4) resources defined in @p rs from a parent bus. 958 * 959 * @param dev The device requesting ownership of the resources. 960 * @param rs A standard bus resource specification. This will be updated 961 * with the allocated resource's RIDs. 962 * @param res On success, the allocated bhnd resources. 963 * 964 * @retval 0 success 965 * @retval non-zero if allocation of any non-RF_OPTIONAL resource fails, 966 * all allocated resources will be released and a regular 967 * unix error code will be returned. 968 */ 969 int 970 bhnd_alloc_resources(device_t dev, struct resource_spec *rs, 971 struct bhnd_resource **res) 972 { 973 /* Initialize output array */ 974 for (u_int i = 0; rs[i].type != -1; i++) 975 res[i] = NULL; 976 977 for (u_int i = 0; rs[i].type != -1; i++) { 978 res[i] = bhnd_alloc_resource_any(dev, rs[i].type, &rs[i].rid, 979 rs[i].flags); 980 981 /* Clean up all allocations on failure */ 982 if (res[i] == NULL && !(rs[i].flags & RF_OPTIONAL)) { 983 bhnd_release_resources(dev, rs, res); 984 return (ENXIO); 985 } 986 } 987 988 return (0); 989 } 990 991 /** 992 * Release bhnd(4) resources defined in @p rs from a parent bus. 993 * 994 * @param dev The device that owns the resources. 995 * @param rs A standard bus resource specification previously initialized 996 * by @p bhnd_alloc_resources. 997 * @param res The bhnd resources to be released. 998 */ 999 void 1000 bhnd_release_resources(device_t dev, const struct resource_spec *rs, 1001 struct bhnd_resource **res) 1002 { 1003 for (u_int i = 0; rs[i].type != -1; i++) { 1004 if (res[i] == NULL) 1005 continue; 1006 1007 bhnd_release_resource(dev, rs[i].type, rs[i].rid, res[i]); 1008 res[i] = NULL; 1009 } 1010 } 1011 1012 /** 1013 * Parse the CHIPC_ID_* fields from the ChipCommon CHIPC_ID 1014 * register, returning its bhnd_chipid representation. 1015 * 1016 * @param idreg The CHIPC_ID register value. 1017 * @param enum_addr The enumeration address to include in the result. 1018 * 1019 * @warning 1020 * On early siba(4) devices, the ChipCommon core does not provide 1021 * a valid CHIPC_ID_NUMCORE field. On these ChipCommon revisions 1022 * (see CHIPC_NCORES_MIN_HWREV()), this function will parse and return 1023 * an invalid `ncores` value. 1024 */ 1025 struct bhnd_chipid 1026 bhnd_parse_chipid(uint32_t idreg, bhnd_addr_t enum_addr) 1027 { 1028 struct bhnd_chipid result; 1029 1030 /* Fetch the basic chip info */ 1031 result.chip_id = CHIPC_GET_BITS(idreg, CHIPC_ID_CHIP); 1032 result.chip_pkg = CHIPC_GET_BITS(idreg, CHIPC_ID_PKG); 1033 result.chip_rev = CHIPC_GET_BITS(idreg, CHIPC_ID_REV); 1034 result.chip_type = CHIPC_GET_BITS(idreg, CHIPC_ID_BUS); 1035 result.ncores = CHIPC_GET_BITS(idreg, CHIPC_ID_NUMCORE); 1036 1037 result.enum_addr = enum_addr; 1038 1039 return (result); 1040 } 1041 1042 1043 /** 1044 * Determine the correct core count for a chip identification value that 1045 * may contain an invalid core count. 1046 * 1047 * On some early siba(4) devices (see CHIPC_NCORES_MIN_HWREV()), the ChipCommon 1048 * core does not provide a valid CHIPC_ID_NUMCORE field. 1049 * 1050 * @param cid The chip identification to be queried. 1051 * @param chipc_hwrev The hardware revision of the ChipCommon core from which 1052 * @p cid was parsed. 1053 * @param[out] ncores On success, will be set to the correct core count. 1054 * 1055 * @retval 0 If the core count is already correct, or was mapped to a 1056 * a correct value. 1057 * @retval EINVAL If the core count is incorrect, but the chip was not 1058 * recognized. 1059 */ 1060 int 1061 bhnd_chipid_fixed_ncores(const struct bhnd_chipid *cid, uint16_t chipc_hwrev, 1062 uint8_t *ncores) 1063 { 1064 /* bcma(4), and most siba(4) devices */ 1065 if (CHIPC_NCORES_MIN_HWREV(chipc_hwrev)) { 1066 *ncores = cid->ncores; 1067 return (0); 1068 } 1069 1070 /* broken siba(4) chipsets */ 1071 switch (cid->chip_id) { 1072 case BHND_CHIPID_BCM4306: 1073 *ncores = 6; 1074 break; 1075 case BHND_CHIPID_BCM4704: 1076 *ncores = 9; 1077 break; 1078 case BHND_CHIPID_BCM5365: 1079 /* 1080 * BCM5365 does support ID_NUMCORE in at least 1081 * some of its revisions, but for unknown 1082 * reasons, Broadcom's drivers always exclude 1083 * the ChipCommon revision (0x5) used by BCM5365 1084 * from the set of revisions supporting 1085 * ID_NUMCORE, and instead supply a fixed value. 1086 * 1087 * Presumably, at least some of these devices 1088 * shipped with a broken ID_NUMCORE value. 1089 */ 1090 *ncores = 7; 1091 break; 1092 default: 1093 return (EINVAL); 1094 } 1095 1096 return (0); 1097 } 1098 1099 /** 1100 * Allocate the resource defined by @p rs via @p dev, use it 1101 * to read the ChipCommon ID register relative to @p chipc_offset, 1102 * then release the resource. 1103 * 1104 * @param dev The device owning @p rs. 1105 * @param rs A resource spec that encompasses the ChipCommon register block. 1106 * @param chipc_offset The offset of the ChipCommon registers within @p rs. 1107 * @param[out] result the chip identification data. 1108 * 1109 * @retval 0 success 1110 * @retval non-zero if the ChipCommon identification data could not be read. 1111 */ 1112 int 1113 bhnd_read_chipid(device_t dev, struct resource_spec *rs, 1114 bus_size_t chipc_offset, struct bhnd_chipid *result) 1115 { 1116 struct resource *res; 1117 bhnd_addr_t enum_addr; 1118 uint32_t reg; 1119 uint8_t chip_type; 1120 int error, rid, rtype; 1121 1122 rid = rs->rid; 1123 rtype = rs->type; 1124 error = 0; 1125 1126 /* Allocate the ChipCommon window resource and fetch the chipid data */ 1127 res = bus_alloc_resource_any(dev, rtype, &rid, RF_ACTIVE); 1128 if (res == NULL) { 1129 device_printf(dev, 1130 "failed to allocate bhnd chipc resource\n"); 1131 return (ENXIO); 1132 } 1133 1134 /* Fetch the basic chip info */ 1135 reg = bus_read_4(res, chipc_offset + CHIPC_ID); 1136 chip_type = CHIPC_GET_BITS(reg, CHIPC_ID_BUS); 1137 1138 /* Fetch the EROMPTR */ 1139 if (BHND_CHIPTYPE_HAS_EROM(chip_type)) { 1140 enum_addr = bus_read_4(res, chipc_offset + CHIPC_EROMPTR); 1141 } else if (chip_type == BHND_CHIPTYPE_SIBA) { 1142 /* siba(4) uses the ChipCommon base address as the enumeration 1143 * address */ 1144 enum_addr = BHND_DEFAULT_CHIPC_ADDR; 1145 } else { 1146 device_printf(dev, "unknown chip type %hhu\n", chip_type); 1147 error = ENODEV; 1148 goto cleanup; 1149 } 1150 1151 *result = bhnd_parse_chipid(reg, enum_addr); 1152 1153 /* Fix the core count on early siba(4) devices */ 1154 if (chip_type == BHND_CHIPTYPE_SIBA) { 1155 uint32_t idh; 1156 uint16_t chipc_hwrev; 1157 1158 /* 1159 * We need the ChipCommon revision to determine whether 1160 * the ncore field is valid. 1161 * 1162 * We can safely assume the siba IDHIGH register is mapped 1163 * within the chipc register block. 1164 */ 1165 idh = bus_read_4(res, SB0_REG_ABS(SIBA_CFG0_IDHIGH)); 1166 chipc_hwrev = SIBA_IDH_CORE_REV(idh); 1167 1168 error = bhnd_chipid_fixed_ncores(result, chipc_hwrev, 1169 &result->ncores); 1170 if (error) 1171 goto cleanup; 1172 } 1173 1174 cleanup: 1175 /* Clean up */ 1176 bus_release_resource(dev, rtype, rid, res); 1177 return (error); 1178 } 1179 1180 /** 1181 * Read an NVRAM variable's NUL-terminated string value. 1182 * 1183 * @param dev A bhnd bus child device. 1184 * @param name The NVRAM variable name. 1185 * @param[out] buf A buffer large enough to hold @p len bytes. On 1186 * success, the NUL-terminated string value will be 1187 * written to this buffer. This argment may be NULL if 1188 * the value is not desired. 1189 * @param len The maximum capacity of @p buf. 1190 * @param[out] rlen On success, will be set to the actual size of 1191 * the requested value (including NUL termination). This 1192 * argment may be NULL if the size is not desired. 1193 * 1194 * @retval 0 success 1195 * @retval ENOENT The requested variable was not found. 1196 * @retval ENODEV No valid NVRAM source could be found. 1197 * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too 1198 * small to hold the requested value. 1199 * @retval EFTYPE If the variable data cannot be coerced to a valid 1200 * string representation. 1201 * @retval ERANGE If value coercion would overflow @p type. 1202 * @retval non-zero If reading @p name otherwise fails, a regular unix 1203 * error code will be returned. 1204 */ 1205 int 1206 bhnd_nvram_getvar_str(device_t dev, const char *name, char *buf, size_t len, 1207 size_t *rlen) 1208 { 1209 size_t larg; 1210 int error; 1211 1212 larg = len; 1213 error = bhnd_nvram_getvar(dev, name, buf, &larg, 1214 BHND_NVRAM_TYPE_STRING); 1215 if (rlen != NULL) 1216 *rlen = larg; 1217 1218 return (error); 1219 } 1220 1221 /** 1222 * Read an NVRAM variable's unsigned integer value. 1223 * 1224 * @param dev A bhnd bus child device. 1225 * @param name The NVRAM variable name. 1226 * @param[out] value On success, the requested value will be written 1227 * to this pointer. 1228 * @param width The output integer type width (1, 2, or 1229 * 4 bytes). 1230 * 1231 * @retval 0 success 1232 * @retval ENOENT The requested variable was not found. 1233 * @retval ENODEV No valid NVRAM source could be found. 1234 * @retval EFTYPE If the variable data cannot be coerced to a 1235 * a valid unsigned integer representation. 1236 * @retval ERANGE If value coercion would overflow (or underflow) an 1237 * unsigned representation of the given @p width. 1238 * @retval non-zero If reading @p name otherwise fails, a regular unix 1239 * error code will be returned. 1240 */ 1241 int 1242 bhnd_nvram_getvar_uint(device_t dev, const char *name, void *value, int width) 1243 { 1244 bhnd_nvram_type type; 1245 size_t len; 1246 1247 switch (width) { 1248 case 1: 1249 type = BHND_NVRAM_TYPE_UINT8; 1250 break; 1251 case 2: 1252 type = BHND_NVRAM_TYPE_UINT16; 1253 break; 1254 case 4: 1255 type = BHND_NVRAM_TYPE_UINT32; 1256 break; 1257 default: 1258 device_printf(dev, "unsupported NVRAM integer width: %d\n", 1259 width); 1260 return (EINVAL); 1261 } 1262 1263 len = width; 1264 return (bhnd_nvram_getvar(dev, name, value, &len, type)); 1265 } 1266 1267 /** 1268 * Read an NVRAM variable's unsigned 8-bit integer value. 1269 * 1270 * @param dev A bhnd bus child device. 1271 * @param name The NVRAM variable name. 1272 * @param[out] value On success, the requested value will be written 1273 * to this pointer. 1274 * 1275 * @retval 0 success 1276 * @retval ENOENT The requested variable was not found. 1277 * @retval ENODEV No valid NVRAM source could be found. 1278 * @retval EFTYPE If the variable data cannot be coerced to a 1279 * a valid unsigned integer representation. 1280 * @retval ERANGE If value coercion would overflow (or underflow) uint8_t. 1281 * @retval non-zero If reading @p name otherwise fails, a regular unix 1282 * error code will be returned. 1283 */ 1284 int 1285 bhnd_nvram_getvar_uint8(device_t dev, const char *name, uint8_t *value) 1286 { 1287 return (bhnd_nvram_getvar_uint(dev, name, value, sizeof(*value))); 1288 } 1289 1290 /** 1291 * Read an NVRAM variable's unsigned 16-bit integer value. 1292 * 1293 * @param dev A bhnd bus child device. 1294 * @param name The NVRAM variable name. 1295 * @param[out] value On success, the requested value will be written 1296 * to this pointer. 1297 * 1298 * @retval 0 success 1299 * @retval ENOENT The requested variable was not found. 1300 * @retval ENODEV No valid NVRAM source could be found. 1301 * @retval EFTYPE If the variable data cannot be coerced to a 1302 * a valid unsigned integer representation. 1303 * @retval ERANGE If value coercion would overflow (or underflow) 1304 * uint16_t. 1305 * @retval non-zero If reading @p name otherwise fails, a regular unix 1306 * error code will be returned. 1307 */ 1308 int 1309 bhnd_nvram_getvar_uint16(device_t dev, const char *name, uint16_t *value) 1310 { 1311 return (bhnd_nvram_getvar_uint(dev, name, value, sizeof(*value))); 1312 } 1313 1314 /** 1315 * Read an NVRAM variable's unsigned 32-bit integer value. 1316 * 1317 * @param dev A bhnd bus child device. 1318 * @param name The NVRAM variable name. 1319 * @param[out] value On success, the requested value will be written 1320 * to this pointer. 1321 * 1322 * @retval 0 success 1323 * @retval ENOENT The requested variable was not found. 1324 * @retval ENODEV No valid NVRAM source could be found. 1325 * @retval EFTYPE If the variable data cannot be coerced to a 1326 * a valid unsigned integer representation. 1327 * @retval ERANGE If value coercion would overflow (or underflow) 1328 * uint32_t. 1329 * @retval non-zero If reading @p name otherwise fails, a regular unix 1330 * error code will be returned. 1331 */ 1332 int 1333 bhnd_nvram_getvar_uint32(device_t dev, const char *name, uint32_t *value) 1334 { 1335 return (bhnd_nvram_getvar_uint(dev, name, value, sizeof(*value))); 1336 } 1337 1338 /** 1339 * Read an NVRAM variable's signed integer value. 1340 * 1341 * @param dev A bhnd bus child device. 1342 * @param name The NVRAM variable name. 1343 * @param[out] value On success, the requested value will be written 1344 * to this pointer. 1345 * @param width The output integer type width (1, 2, or 1346 * 4 bytes). 1347 * 1348 * @retval 0 success 1349 * @retval ENOENT The requested variable was not found. 1350 * @retval ENODEV No valid NVRAM source could be found. 1351 * @retval EFTYPE If the variable data cannot be coerced to a 1352 * a valid integer representation. 1353 * @retval ERANGE If value coercion would overflow (or underflow) an 1354 * signed representation of the given @p width. 1355 * @retval non-zero If reading @p name otherwise fails, a regular unix 1356 * error code will be returned. 1357 */ 1358 int 1359 bhnd_nvram_getvar_int(device_t dev, const char *name, void *value, int width) 1360 { 1361 bhnd_nvram_type type; 1362 size_t len; 1363 1364 switch (width) { 1365 case 1: 1366 type = BHND_NVRAM_TYPE_INT8; 1367 break; 1368 case 2: 1369 type = BHND_NVRAM_TYPE_INT16; 1370 break; 1371 case 4: 1372 type = BHND_NVRAM_TYPE_INT32; 1373 break; 1374 default: 1375 device_printf(dev, "unsupported NVRAM integer width: %d\n", 1376 width); 1377 return (EINVAL); 1378 } 1379 1380 len = width; 1381 return (bhnd_nvram_getvar(dev, name, value, &len, type)); 1382 } 1383 1384 /** 1385 * Read an NVRAM variable's signed 8-bit integer value. 1386 * 1387 * @param dev A bhnd bus child device. 1388 * @param name The NVRAM variable name. 1389 * @param[out] value On success, the requested value will be written 1390 * to this pointer. 1391 * 1392 * @retval 0 success 1393 * @retval ENOENT The requested variable was not found. 1394 * @retval ENODEV No valid NVRAM source could be found. 1395 * @retval EFTYPE If the variable data cannot be coerced to a 1396 * a valid integer representation. 1397 * @retval ERANGE If value coercion would overflow (or underflow) int8_t. 1398 * @retval non-zero If reading @p name otherwise fails, a regular unix 1399 * error code will be returned. 1400 */ 1401 int 1402 bhnd_nvram_getvar_int8(device_t dev, const char *name, int8_t *value) 1403 { 1404 return (bhnd_nvram_getvar_int(dev, name, value, sizeof(*value))); 1405 } 1406 1407 /** 1408 * Read an NVRAM variable's signed 16-bit integer value. 1409 * 1410 * @param dev A bhnd bus child device. 1411 * @param name The NVRAM variable name. 1412 * @param[out] value On success, the requested value will be written 1413 * to this pointer. 1414 * 1415 * @retval 0 success 1416 * @retval ENOENT The requested variable was not found. 1417 * @retval ENODEV No valid NVRAM source could be found. 1418 * @retval EFTYPE If the variable data cannot be coerced to a 1419 * a valid integer representation. 1420 * @retval ERANGE If value coercion would overflow (or underflow) 1421 * int16_t. 1422 * @retval non-zero If reading @p name otherwise fails, a regular unix 1423 * error code will be returned. 1424 */ 1425 int 1426 bhnd_nvram_getvar_int16(device_t dev, const char *name, int16_t *value) 1427 { 1428 return (bhnd_nvram_getvar_int(dev, name, value, sizeof(*value))); 1429 } 1430 1431 /** 1432 * Read an NVRAM variable's signed 32-bit integer value. 1433 * 1434 * @param dev A bhnd bus child device. 1435 * @param name The NVRAM variable name. 1436 * @param[out] value On success, the requested value will be written 1437 * to this pointer. 1438 * 1439 * @retval 0 success 1440 * @retval ENOENT The requested variable was not found. 1441 * @retval ENODEV No valid NVRAM source could be found. 1442 * @retval EFTYPE If the variable data cannot be coerced to a 1443 * a valid integer representation. 1444 * @retval ERANGE If value coercion would overflow (or underflow) 1445 * int32_t. 1446 * @retval non-zero If reading @p name otherwise fails, a regular unix 1447 * error code will be returned. 1448 */ 1449 int 1450 bhnd_nvram_getvar_int32(device_t dev, const char *name, int32_t *value) 1451 { 1452 return (bhnd_nvram_getvar_int(dev, name, value, sizeof(*value))); 1453 } 1454 1455 1456 /** 1457 * Read an NVRAM variable's array value. 1458 * 1459 * @param dev A bhnd bus child device. 1460 * @param name The NVRAM variable name. 1461 * @param[out] buf A buffer large enough to hold @p size bytes. 1462 * On success, the requested value will be written 1463 * to this buffer. 1464 * @param[in,out] size The required number of bytes to write to 1465 * @p buf. 1466 * @param type The desired array element data representation. 1467 * 1468 * @retval 0 success 1469 * @retval ENOENT The requested variable was not found. 1470 * @retval ENODEV No valid NVRAM source could be found. 1471 * @retval ENXIO If less than @p size bytes are available. 1472 * @retval ENOMEM If a buffer of @p size is too small to hold the 1473 * requested value. 1474 * @retval EFTYPE If the variable data cannot be coerced to a 1475 * a valid instance of @p type. 1476 * @retval ERANGE If value coercion would overflow (or underflow) a 1477 * representation of @p type. 1478 * @retval non-zero If reading @p name otherwise fails, a regular unix 1479 * error code will be returned. 1480 */ 1481 int 1482 bhnd_nvram_getvar_array(device_t dev, const char *name, void *buf, size_t size, 1483 bhnd_nvram_type type) 1484 { 1485 size_t nbytes; 1486 int error; 1487 1488 /* Attempt read */ 1489 nbytes = size; 1490 if ((error = bhnd_nvram_getvar(dev, name, buf, &nbytes, type))) 1491 return (error); 1492 1493 /* Verify that the expected number of bytes were fetched */ 1494 if (nbytes < size) 1495 return (ENXIO); 1496 1497 return (0); 1498 } 1499 1500 /** 1501 * Initialize a service provider registry. 1502 * 1503 * @param bsr The service registry to initialize. 1504 * 1505 * @retval 0 success 1506 * @retval non-zero if an error occurs initializing the service registry, 1507 * a regular unix error code will be returned. 1508 1509 */ 1510 int 1511 bhnd_service_registry_init(struct bhnd_service_registry *bsr) 1512 { 1513 STAILQ_INIT(&bsr->entries); 1514 mtx_init(&bsr->lock, "bhnd_service_registry lock", NULL, MTX_DEF); 1515 1516 return (0); 1517 } 1518 1519 /** 1520 * Release all resources held by @p bsr. 1521 * 1522 * @param bsr A service registry instance previously successfully 1523 * initialized via bhnd_service_registry_init(). 1524 * 1525 * @retval 0 success 1526 * @retval EBUSY if active references to service providers registered 1527 * with @p bsr exist. 1528 */ 1529 int 1530 bhnd_service_registry_fini(struct bhnd_service_registry *bsr) 1531 { 1532 struct bhnd_service_entry *entry, *enext; 1533 1534 /* Remove everthing we can */ 1535 mtx_lock(&bsr->lock); 1536 STAILQ_FOREACH_SAFE(entry, &bsr->entries, link, enext) { 1537 if (entry->refs > 0) 1538 continue; 1539 1540 STAILQ_REMOVE(&bsr->entries, entry, bhnd_service_entry, link); 1541 free(entry, M_BHND); 1542 } 1543 1544 if (!STAILQ_EMPTY(&bsr->entries)) { 1545 mtx_unlock(&bsr->lock); 1546 return (EBUSY); 1547 } 1548 mtx_unlock(&bsr->lock); 1549 1550 mtx_destroy(&bsr->lock); 1551 return (0); 1552 } 1553 1554 /** 1555 * Register a @p provider for the given @p service. 1556 * 1557 * @param bsr Service registry to be modified. 1558 * @param provider Service provider to register. 1559 * @param service Service for which @p provider will be registered. 1560 * @param flags Service provider flags (see BHND_SPF_*). 1561 * 1562 * @retval 0 success 1563 * @retval EEXIST if an entry for @p service already exists. 1564 * @retval EINVAL if @p service is BHND_SERVICE_ANY. 1565 * @retval non-zero if registering @p provider otherwise fails, a regular 1566 * unix error code will be returned. 1567 */ 1568 int 1569 bhnd_service_registry_add(struct bhnd_service_registry *bsr, device_t provider, 1570 bhnd_service_t service, uint32_t flags) 1571 { 1572 struct bhnd_service_entry *entry; 1573 1574 if (service == BHND_SERVICE_ANY) 1575 return (EINVAL); 1576 1577 mtx_lock(&bsr->lock); 1578 1579 /* Is a service provider already registered? */ 1580 STAILQ_FOREACH(entry, &bsr->entries, link) { 1581 if (entry->service == service) { 1582 mtx_unlock(&bsr->lock); 1583 return (EEXIST); 1584 } 1585 } 1586 1587 /* Initialize and insert our new entry */ 1588 entry = malloc(sizeof(*entry), M_BHND, M_NOWAIT); 1589 if (entry == NULL) { 1590 mtx_unlock(&bsr->lock); 1591 return (ENOMEM); 1592 } 1593 1594 entry->provider = provider; 1595 entry->service = service; 1596 entry->flags = flags; 1597 refcount_init(&entry->refs, 0); 1598 1599 STAILQ_INSERT_HEAD(&bsr->entries, entry, link); 1600 1601 mtx_unlock(&bsr->lock); 1602 return (0); 1603 } 1604 1605 /** 1606 * Free an unreferenced registry entry. 1607 * 1608 * @param entry The entry to be deallocated. 1609 */ 1610 static void 1611 bhnd_service_registry_free_entry(struct bhnd_service_entry *entry) 1612 { 1613 KASSERT(entry->refs == 0, ("provider has active references")); 1614 free(entry, M_BHND); 1615 } 1616 1617 /** 1618 * Attempt to remove the @p service provider registration for @p provider. 1619 * 1620 * @param bsr The service registry to be modified. 1621 * @param provider The service provider to be deregistered. 1622 * @param service The service for which @p provider will be deregistered, 1623 * or BHND_SERVICE_ANY to remove all service 1624 * registrations for @p provider. 1625 * 1626 * @retval 0 success 1627 * @retval EBUSY if active references to @p provider exist; @see 1628 * bhnd_service_registry_retain() and 1629 * bhnd_service_registry_release(). 1630 */ 1631 int 1632 bhnd_service_registry_remove(struct bhnd_service_registry *bsr, 1633 device_t provider, bhnd_service_t service) 1634 { 1635 struct bhnd_service_entry *entry, *enext; 1636 1637 mtx_lock(&bsr->lock); 1638 1639 #define BHND_PROV_MATCH(_e) \ 1640 ((_e)->provider == provider && \ 1641 (service == BHND_SERVICE_ANY || (_e)->service == service)) 1642 1643 /* Validate matching provider entries before making any 1644 * modifications */ 1645 STAILQ_FOREACH(entry, &bsr->entries, link) { 1646 /* Skip non-matching entries */ 1647 if (!BHND_PROV_MATCH(entry)) 1648 continue; 1649 1650 /* Entry is in use? */ 1651 if (entry->refs > 0) { 1652 mtx_unlock(&bsr->lock); 1653 return (EBUSY); 1654 } 1655 } 1656 1657 /* We can now safely remove matching entries */ 1658 STAILQ_FOREACH_SAFE(entry, &bsr->entries, link, enext) { 1659 /* Skip non-matching entries */ 1660 if (!BHND_PROV_MATCH(entry)) 1661 continue; 1662 1663 /* Remove from list */ 1664 STAILQ_REMOVE(&bsr->entries, entry, bhnd_service_entry, link); 1665 1666 /* Free provider entry */ 1667 bhnd_service_registry_free_entry(entry); 1668 } 1669 #undef BHND_PROV_MATCH 1670 1671 mtx_unlock(&bsr->lock); 1672 return (0); 1673 } 1674 1675 /** 1676 * Retain and return a reference to a registered @p service provider, if any. 1677 * 1678 * @param bsr The service registry to be queried. 1679 * @param service The service for which a provider should be returned. 1680 * 1681 * On success, the caller assumes ownership the returned provider, and 1682 * is responsible for releasing this reference via 1683 * bhnd_service_registry_release(). 1684 * 1685 * @retval device_t success 1686 * @retval NULL if no provider is registered for @p service. 1687 */ 1688 device_t 1689 bhnd_service_registry_retain(struct bhnd_service_registry *bsr, 1690 bhnd_service_t service) 1691 { 1692 struct bhnd_service_entry *entry; 1693 1694 mtx_lock(&bsr->lock); 1695 STAILQ_FOREACH(entry, &bsr->entries, link) { 1696 if (entry->service != service) 1697 continue; 1698 1699 /* With a live refcount, entry is gauranteed to remain alive 1700 * after we release our lock */ 1701 refcount_acquire(&entry->refs); 1702 1703 mtx_unlock(&bsr->lock); 1704 return (entry->provider); 1705 } 1706 mtx_unlock(&bsr->lock); 1707 1708 /* Not found */ 1709 return (NULL); 1710 } 1711 1712 /** 1713 * Release a reference to a service provider previously returned by 1714 * bhnd_service_registry_retain(). 1715 * 1716 * If this is the last reference to an inherited service provider registration 1717 * (@see BHND_SPF_INHERITED), the registration will also be removed, and 1718 * true will be returned. 1719 * 1720 * @param bsr The service registry from which @p provider 1721 * was returned. 1722 * @param provider The provider to be released. 1723 * @param service The service for which @p provider was previously 1724 * retained. 1725 * @retval true The inherited service provider registration was removed; 1726 * the caller should release its own reference to the 1727 * provider. 1728 * @retval false The service provider was not inherited, or active 1729 * references to the provider remain. 1730 */ 1731 bool 1732 bhnd_service_registry_release(struct bhnd_service_registry *bsr, 1733 device_t provider, bhnd_service_t service) 1734 { 1735 struct bhnd_service_entry *entry; 1736 1737 /* Exclusive lock, as we need to prevent any new references to the 1738 * entry from being taken if it's to be removed */ 1739 mtx_lock(&bsr->lock); 1740 STAILQ_FOREACH(entry, &bsr->entries, link) { 1741 bool removed; 1742 1743 if (entry->provider != provider) 1744 continue; 1745 1746 if (entry->service != service) 1747 continue; 1748 1749 if (refcount_release(&entry->refs) && 1750 (entry->flags & BHND_SPF_INHERITED)) 1751 { 1752 /* If an inherited entry is no longer actively 1753 * referenced, remove the local registration and inform 1754 * the caller. */ 1755 STAILQ_REMOVE(&bsr->entries, entry, bhnd_service_entry, 1756 link); 1757 bhnd_service_registry_free_entry(entry); 1758 removed = true; 1759 } else { 1760 removed = false; 1761 } 1762 1763 mtx_unlock(&bsr->lock); 1764 return (removed); 1765 } 1766 1767 /* Caller owns a reference, but no such provider is registered? */ 1768 panic("invalid service provider reference"); 1769 } 1770 1771 /** 1772 * Using the bhnd(4) bus-level core information and a custom core name, 1773 * populate @p dev's device description. 1774 * 1775 * @param dev A bhnd-bus attached device. 1776 * @param dev_name The core's name (e.g. "SDIO Device Core") 1777 */ 1778 void 1779 bhnd_set_custom_core_desc(device_t dev, const char *dev_name) 1780 { 1781 const char *vendor_name; 1782 char *desc; 1783 1784 vendor_name = bhnd_get_vendor_name(dev); 1785 asprintf(&desc, M_BHND, "%s %s, rev %hhu", vendor_name, dev_name, 1786 bhnd_get_hwrev(dev)); 1787 1788 if (desc != NULL) { 1789 device_set_desc_copy(dev, desc); 1790 free(desc, M_BHND); 1791 } else { 1792 device_set_desc(dev, dev_name); 1793 } 1794 } 1795 1796 /** 1797 * Using the bhnd(4) bus-level core information, populate @p dev's device 1798 * description. 1799 * 1800 * @param dev A bhnd-bus attached device. 1801 */ 1802 void 1803 bhnd_set_default_core_desc(device_t dev) 1804 { 1805 bhnd_set_custom_core_desc(dev, bhnd_get_device_name(dev)); 1806 } 1807 1808 1809 /** 1810 * Using the bhnd @p chip_id, populate the bhnd(4) bus @p dev's device 1811 * description. 1812 * 1813 * @param dev A bhnd-bus attached device. 1814 */ 1815 void 1816 bhnd_set_default_bus_desc(device_t dev, const struct bhnd_chipid *chip_id) 1817 { 1818 const char *bus_name; 1819 char *desc; 1820 char chip_name[BHND_CHIPID_MAX_NAMELEN]; 1821 1822 /* Determine chip type's bus name */ 1823 switch (chip_id->chip_type) { 1824 case BHND_CHIPTYPE_SIBA: 1825 bus_name = "SIBA bus"; 1826 break; 1827 case BHND_CHIPTYPE_BCMA: 1828 case BHND_CHIPTYPE_BCMA_ALT: 1829 bus_name = "BCMA bus"; 1830 break; 1831 case BHND_CHIPTYPE_UBUS: 1832 bus_name = "UBUS bus"; 1833 break; 1834 default: 1835 bus_name = "Unknown Type"; 1836 break; 1837 } 1838 1839 /* Format chip name */ 1840 bhnd_format_chip_id(chip_name, sizeof(chip_name), 1841 chip_id->chip_id); 1842 1843 /* Format and set device description */ 1844 asprintf(&desc, M_BHND, "%s %s", chip_name, bus_name); 1845 if (desc != NULL) { 1846 device_set_desc_copy(dev, desc); 1847 free(desc, M_BHND); 1848 } else { 1849 device_set_desc(dev, bus_name); 1850 } 1851 1852 } 1853 1854 /** 1855 * Helper function for implementing BHND_BUS_REGISTER_PROVIDER(). 1856 * 1857 * This implementation delegates the request to the BHND_BUS_REGISTER_PROVIDER() 1858 * method on the parent of @p dev. If no parent exists, the implementation 1859 * will return an error. 1860 */ 1861 int 1862 bhnd_bus_generic_register_provider(device_t dev, device_t child, 1863 device_t provider, bhnd_service_t service) 1864 { 1865 device_t parent = device_get_parent(dev); 1866 1867 if (parent != NULL) { 1868 return (BHND_BUS_REGISTER_PROVIDER(parent, child, 1869 provider, service)); 1870 } 1871 1872 return (ENXIO); 1873 } 1874 1875 /** 1876 * Helper function for implementing BHND_BUS_DEREGISTER_PROVIDER(). 1877 * 1878 * This implementation delegates the request to the 1879 * BHND_BUS_DEREGISTER_PROVIDER() method on the parent of @p dev. If no parent 1880 * exists, the implementation will panic. 1881 */ 1882 int 1883 bhnd_bus_generic_deregister_provider(device_t dev, device_t child, 1884 device_t provider, bhnd_service_t service) 1885 { 1886 device_t parent = device_get_parent(dev); 1887 1888 if (parent != NULL) { 1889 return (BHND_BUS_DEREGISTER_PROVIDER(parent, child, 1890 provider, service)); 1891 } 1892 1893 panic("missing BHND_BUS_DEREGISTER_PROVIDER()"); 1894 } 1895 1896 /** 1897 * Helper function for implementing BHND_BUS_RETAIN_PROVIDER(). 1898 * 1899 * This implementation delegates the request to the 1900 * BHND_BUS_DEREGISTER_PROVIDER() method on the parent of @p dev. If no parent 1901 * exists, the implementation will return NULL. 1902 */ 1903 device_t 1904 bhnd_bus_generic_retain_provider(device_t dev, device_t child, 1905 bhnd_service_t service) 1906 { 1907 device_t parent = device_get_parent(dev); 1908 1909 if (parent != NULL) { 1910 return (BHND_BUS_RETAIN_PROVIDER(parent, child, 1911 service)); 1912 } 1913 1914 return (NULL); 1915 } 1916 1917 /** 1918 * Helper function for implementing BHND_BUS_RELEASE_PROVIDER(). 1919 * 1920 * This implementation delegates the request to the 1921 * BHND_BUS_DEREGISTER_PROVIDER() method on the parent of @p dev. If no parent 1922 * exists, the implementation will panic. 1923 */ 1924 void 1925 bhnd_bus_generic_release_provider(device_t dev, device_t child, 1926 device_t provider, bhnd_service_t service) 1927 { 1928 device_t parent = device_get_parent(dev); 1929 1930 if (parent != NULL) { 1931 return (BHND_BUS_RELEASE_PROVIDER(parent, child, 1932 provider, service)); 1933 } 1934 1935 panic("missing BHND_BUS_RELEASE_PROVIDER()"); 1936 } 1937 1938 /** 1939 * Helper function for implementing BHND_BUS_REGISTER_PROVIDER(). 1940 * 1941 * This implementation uses the bhnd_service_registry_add() function to 1942 * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find 1943 * a suitable service registry to edit. 1944 */ 1945 int 1946 bhnd_bus_generic_sr_register_provider(device_t dev, device_t child, 1947 device_t provider, bhnd_service_t service) 1948 { 1949 struct bhnd_service_registry *bsr; 1950 1951 bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); 1952 1953 KASSERT(bsr != NULL, ("NULL service registry")); 1954 1955 return (bhnd_service_registry_add(bsr, provider, service, 0)); 1956 } 1957 1958 /** 1959 * Helper function for implementing BHND_BUS_DEREGISTER_PROVIDER(). 1960 * 1961 * This implementation uses the bhnd_service_registry_remove() function to 1962 * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find 1963 * a suitable service registry to edit. 1964 */ 1965 int 1966 bhnd_bus_generic_sr_deregister_provider(device_t dev, device_t child, 1967 device_t provider, bhnd_service_t service) 1968 { 1969 struct bhnd_service_registry *bsr; 1970 1971 bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); 1972 1973 KASSERT(bsr != NULL, ("NULL service registry")); 1974 1975 return (bhnd_service_registry_remove(bsr, provider, service)); 1976 } 1977 1978 /** 1979 * Helper function for implementing BHND_BUS_RETAIN_PROVIDER(). 1980 * 1981 * This implementation uses the bhnd_service_registry_retain() function to 1982 * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find 1983 * a suitable service registry. 1984 * 1985 * If a local provider for the service is not available, and a parent device is 1986 * available, this implementation will attempt to fetch and locally register 1987 * a service provider reference from the parent of @p dev. 1988 */ 1989 device_t 1990 bhnd_bus_generic_sr_retain_provider(device_t dev, device_t child, 1991 bhnd_service_t service) 1992 { 1993 struct bhnd_service_registry *bsr; 1994 device_t parent, provider; 1995 int error; 1996 1997 bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); 1998 KASSERT(bsr != NULL, ("NULL service registry")); 1999 2000 /* 2001 * Attempt to fetch a service provider reference from either the local 2002 * service registry, or if not found, from our parent. 2003 * 2004 * If we fetch a provider from our parent, we register the provider 2005 * with the local service registry to prevent conflicting local 2006 * registrations from being added. 2007 */ 2008 while (1) { 2009 /* Check the local service registry first */ 2010 provider = bhnd_service_registry_retain(bsr, service); 2011 if (provider != NULL) 2012 return (provider); 2013 2014 /* Otherwise, try to delegate to our parent (if any) */ 2015 if ((parent = device_get_parent(dev)) == NULL) 2016 return (NULL); 2017 2018 provider = BHND_BUS_RETAIN_PROVIDER(parent, dev, service); 2019 if (provider == NULL) 2020 return (NULL); 2021 2022 /* Register the inherited service registration with the local 2023 * registry */ 2024 error = bhnd_service_registry_add(bsr, provider, service, 2025 BHND_SPF_INHERITED); 2026 if (error) { 2027 BHND_BUS_RELEASE_PROVIDER(parent, dev, provider, 2028 service); 2029 if (error == EEXIST) { 2030 /* A valid service provider was registered 2031 * concurrently; retry fetching from the local 2032 * registry */ 2033 continue; 2034 } 2035 2036 device_printf(dev, "failed to register service " 2037 "provider: %d\n", error); 2038 return (NULL); 2039 } 2040 } 2041 } 2042 2043 /** 2044 * Helper function for implementing BHND_BUS_RELEASE_PROVIDER(). 2045 * 2046 * This implementation uses the bhnd_service_registry_release() function to 2047 * do most of the work. It calls BHND_BUS_GET_SERVICE_REGISTRY() to find 2048 * a suitable service registry. 2049 */ 2050 void 2051 bhnd_bus_generic_sr_release_provider(device_t dev, device_t child, 2052 device_t provider, bhnd_service_t service) 2053 { 2054 struct bhnd_service_registry *bsr; 2055 2056 bsr = BHND_BUS_GET_SERVICE_REGISTRY(dev, child); 2057 KASSERT(bsr != NULL, ("NULL service registry")); 2058 2059 /* Release the provider reference; if the refcount hits zero on an 2060 * inherited reference, true will be returned, and we need to drop 2061 * our own bus reference to the provider */ 2062 if (!bhnd_service_registry_release(bsr, provider, service)) 2063 return; 2064 2065 /* Drop our reference to the borrowed provider */ 2066 BHND_BUS_RELEASE_PROVIDER(device_get_parent(dev), dev, provider, 2067 service); 2068 } 2069 2070 /** 2071 * Helper function for implementing BHND_BUS_IS_HW_DISABLED(). 2072 * 2073 * If a parent device is available, this implementation delegates the 2074 * request to the BHND_BUS_IS_HW_DISABLED() method on the parent of @p dev. 2075 * 2076 * If no parent device is available (i.e. on a the bus root), the hardware 2077 * is assumed to be usable and false is returned. 2078 */ 2079 bool 2080 bhnd_bus_generic_is_hw_disabled(device_t dev, device_t child) 2081 { 2082 if (device_get_parent(dev) != NULL) 2083 return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), child)); 2084 2085 return (false); 2086 } 2087 2088 /** 2089 * Helper function for implementing BHND_BUS_GET_CHIPID(). 2090 * 2091 * This implementation delegates the request to the BHND_BUS_GET_CHIPID() 2092 * method on the parent of @p dev. If no parent exists, the implementation 2093 * will panic. 2094 */ 2095 const struct bhnd_chipid * 2096 bhnd_bus_generic_get_chipid(device_t dev, device_t child) 2097 { 2098 if (device_get_parent(dev) != NULL) 2099 return (BHND_BUS_GET_CHIPID(device_get_parent(dev), child)); 2100 2101 panic("missing BHND_BUS_GET_CHIPID()"); 2102 } 2103 2104 /* nvram board_info population macros for bhnd_bus_generic_read_board_info() */ 2105 #define BHND_GV(_dest, _name) \ 2106 bhnd_nvram_getvar_uint(child, BHND_NVAR_ ## _name, &_dest, \ 2107 sizeof(_dest)) 2108 2109 #define REQ_BHND_GV(_dest, _name) do { \ 2110 if ((error = BHND_GV(_dest, _name))) { \ 2111 device_printf(dev, \ 2112 "error reading " __STRING(_name) ": %d\n", error); \ 2113 return (error); \ 2114 } \ 2115 } while(0) 2116 2117 #define OPT_BHND_GV(_dest, _name, _default) do { \ 2118 if ((error = BHND_GV(_dest, _name))) { \ 2119 if (error != ENOENT) { \ 2120 device_printf(dev, \ 2121 "error reading " \ 2122 __STRING(_name) ": %d\n", error); \ 2123 return (error); \ 2124 } \ 2125 _dest = _default; \ 2126 } \ 2127 } while(0) 2128 2129 /** 2130 * Helper function for implementing BHND_BUS_READ_BOARDINFO(). 2131 * 2132 * This implementation populates @p info with information from NVRAM, 2133 * defaulting board_vendor and board_type fields to 0 if the 2134 * requested variables cannot be found. 2135 * 2136 * This behavior is correct for most SoCs, but must be overridden on 2137 * bridged (PCI, PCMCIA, etc) devices to produce a complete bhnd_board_info 2138 * result. 2139 */ 2140 int 2141 bhnd_bus_generic_read_board_info(device_t dev, device_t child, 2142 struct bhnd_board_info *info) 2143 { 2144 int error; 2145 2146 OPT_BHND_GV(info->board_vendor, BOARDVENDOR, 0); 2147 OPT_BHND_GV(info->board_type, BOARDTYPE, 0); /* srom >= 2 */ 2148 REQ_BHND_GV(info->board_rev, BOARDREV); 2149 OPT_BHND_GV(info->board_srom_rev,SROMREV, 0); /* missing in 2150 some SoC 2151 NVRAM */ 2152 REQ_BHND_GV(info->board_flags, BOARDFLAGS); 2153 OPT_BHND_GV(info->board_flags2, BOARDFLAGS2, 0); /* srom >= 4 */ 2154 OPT_BHND_GV(info->board_flags3, BOARDFLAGS3, 0); /* srom >= 11 */ 2155 2156 return (0); 2157 } 2158 2159 #undef BHND_GV 2160 #undef BHND_GV_REQ 2161 #undef BHND_GV_OPT 2162 2163 /** 2164 * Helper function for implementing BHND_BUS_GET_NVRAM_VAR(). 2165 * 2166 * This implementation searches @p dev for a usable NVRAM child device. 2167 * 2168 * If no usable child device is found on @p dev, the request is delegated to 2169 * the BHND_BUS_GET_NVRAM_VAR() method on the parent of @p dev. 2170 */ 2171 int 2172 bhnd_bus_generic_get_nvram_var(device_t dev, device_t child, const char *name, 2173 void *buf, size_t *size, bhnd_nvram_type type) 2174 { 2175 device_t nvram; 2176 device_t parent; 2177 2178 /* Make sure we're holding Giant for newbus */ 2179 GIANT_REQUIRED; 2180 2181 /* Look for a directly-attached NVRAM child */ 2182 if ((nvram = device_find_child(dev, "bhnd_nvram", -1)) != NULL) 2183 return BHND_NVRAM_GETVAR(nvram, name, buf, size, type); 2184 2185 /* Try to delegate to parent */ 2186 if ((parent = device_get_parent(dev)) == NULL) 2187 return (ENODEV); 2188 2189 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), child, 2190 name, buf, size, type)); 2191 } 2192 2193 /** 2194 * Helper function for implementing BHND_BUS_ALLOC_RESOURCE(). 2195 * 2196 * This implementation of BHND_BUS_ALLOC_RESOURCE() delegates allocation 2197 * of the underlying resource to BUS_ALLOC_RESOURCE(), and activation 2198 * to @p dev's BHND_BUS_ACTIVATE_RESOURCE(). 2199 */ 2200 struct bhnd_resource * 2201 bhnd_bus_generic_alloc_resource(device_t dev, device_t child, int type, 2202 int *rid, rman_res_t start, rman_res_t end, rman_res_t count, 2203 u_int flags) 2204 { 2205 struct bhnd_resource *br; 2206 struct resource *res; 2207 int error; 2208 2209 br = NULL; 2210 res = NULL; 2211 2212 /* Allocate the real bus resource (without activating it) */ 2213 res = BUS_ALLOC_RESOURCE(dev, child, type, rid, start, end, count, 2214 (flags & ~RF_ACTIVE)); 2215 if (res == NULL) 2216 return (NULL); 2217 2218 /* Allocate our bhnd resource wrapper. */ 2219 br = malloc(sizeof(struct bhnd_resource), M_BHND, M_NOWAIT); 2220 if (br == NULL) 2221 goto failed; 2222 2223 br->direct = false; 2224 br->res = res; 2225 2226 /* Attempt activation */ 2227 if (flags & RF_ACTIVE) { 2228 error = BHND_BUS_ACTIVATE_RESOURCE(dev, child, type, *rid, br); 2229 if (error) 2230 goto failed; 2231 } 2232 2233 return (br); 2234 2235 failed: 2236 if (res != NULL) 2237 BUS_RELEASE_RESOURCE(dev, child, type, *rid, res); 2238 2239 free(br, M_BHND); 2240 return (NULL); 2241 } 2242 2243 /** 2244 * Helper function for implementing BHND_BUS_RELEASE_RESOURCE(). 2245 * 2246 * This implementation of BHND_BUS_RELEASE_RESOURCE() delegates release of 2247 * the backing resource to BUS_RELEASE_RESOURCE(). 2248 */ 2249 int 2250 bhnd_bus_generic_release_resource(device_t dev, device_t child, int type, 2251 int rid, struct bhnd_resource *r) 2252 { 2253 int error; 2254 2255 if ((error = BUS_RELEASE_RESOURCE(dev, child, type, rid, r->res))) 2256 return (error); 2257 2258 free(r, M_BHND); 2259 return (0); 2260 } 2261 2262 2263 /** 2264 * Helper function for implementing BHND_BUS_ACTIVATE_RESOURCE(). 2265 * 2266 * This implementation of BHND_BUS_ACTIVATE_RESOURCE() first calls the 2267 * BHND_BUS_ACTIVATE_RESOURCE() method of the parent of @p dev. 2268 * 2269 * If this fails, and if @p dev is the direct parent of @p child, standard 2270 * resource activation is attempted via bus_activate_resource(). This enables 2271 * direct use of the bhnd(4) resource APIs on devices that may not be attached 2272 * to a parent bhnd bus or bridge. 2273 */ 2274 int 2275 bhnd_bus_generic_activate_resource(device_t dev, device_t child, int type, 2276 int rid, struct bhnd_resource *r) 2277 { 2278 int error; 2279 bool passthrough; 2280 2281 passthrough = (device_get_parent(child) != dev); 2282 2283 /* Try to delegate to the parent */ 2284 if (device_get_parent(dev) != NULL) { 2285 error = BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev), 2286 child, type, rid, r); 2287 } else { 2288 error = ENODEV; 2289 } 2290 2291 /* If bhnd(4) activation has failed and we're the child's direct 2292 * parent, try falling back on standard resource activation. 2293 */ 2294 if (error && !passthrough) { 2295 error = bus_activate_resource(child, type, rid, r->res); 2296 if (!error) 2297 r->direct = true; 2298 } 2299 2300 return (error); 2301 } 2302 2303 /** 2304 * Helper function for implementing BHND_BUS_DEACTIVATE_RESOURCE(). 2305 * 2306 * This implementation of BHND_BUS_ACTIVATE_RESOURCE() simply calls the 2307 * BHND_BUS_ACTIVATE_RESOURCE() method of the parent of @p dev. 2308 */ 2309 int 2310 bhnd_bus_generic_deactivate_resource(device_t dev, device_t child, 2311 int type, int rid, struct bhnd_resource *r) 2312 { 2313 if (device_get_parent(dev) != NULL) 2314 return (BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), 2315 child, type, rid, r)); 2316 2317 return (EINVAL); 2318 } 2319 2320