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 * $FreeBSD$ 34 */ 35 36 #ifndef _BHND_BHND_H_ 37 #define _BHND_BHND_H_ 38 39 #include <sys/param.h> 40 #include <sys/bus.h> 41 #include <sys/lock.h> 42 #include <sys/mutex.h> 43 44 #include <machine/bus.h> 45 46 #include "bhnd_ids.h" 47 #include "bhnd_types.h" 48 #include "bhnd_erom_types.h" 49 #include "bhnd_debug.h" 50 #include "bhnd_bus_if.h" 51 #include "bhnd_match.h" 52 53 #include "nvram/bhnd_nvram.h" 54 55 struct bhnd_core_pmu_info; 56 57 extern devclass_t bhnd_devclass; 58 extern devclass_t bhnd_hostb_devclass; 59 extern devclass_t bhnd_nvram_devclass; 60 61 #define BHND_CHIPID_MAX_NAMELEN 32 /**< maximum buffer required for a 62 bhnd_format_chip_id() */ 63 64 /** 65 * bhnd child instance variables 66 */ 67 enum bhnd_device_vars { 68 BHND_IVAR_VENDOR, /**< Designer's JEP-106 manufacturer ID. */ 69 BHND_IVAR_DEVICE, /**< Part number */ 70 BHND_IVAR_HWREV, /**< Core revision */ 71 BHND_IVAR_DEVICE_CLASS, /**< Core class (@sa bhnd_devclass_t) */ 72 BHND_IVAR_VENDOR_NAME, /**< Core vendor name */ 73 BHND_IVAR_DEVICE_NAME, /**< Core name */ 74 BHND_IVAR_CORE_INDEX, /**< Bus-assigned core number */ 75 BHND_IVAR_CORE_UNIT, /**< Bus-assigned core unit number, 76 assigned sequentially (starting at 0) for 77 each vendor/device pair. */ 78 BHND_IVAR_PMU_INFO, /**< Internal bus-managed PMU state */ 79 }; 80 81 /** 82 * bhnd device probe priority bands. 83 */ 84 enum { 85 BHND_PROBE_ROOT = 0, /**< Nexus or host bridge */ 86 BHND_PROBE_BUS = 1000, /**< Buses and bridges */ 87 BHND_PROBE_CPU = 2000, /**< CPU devices */ 88 BHND_PROBE_INTERRUPT = 3000, /**< Interrupt controllers. */ 89 BHND_PROBE_TIMER = 4000, /**< Timers and clocks. */ 90 BHND_PROBE_RESOURCE = 5000, /**< Resource discovery (including NVRAM/SPROM) */ 91 BHND_PROBE_DEFAULT = 6000, /**< Default device priority */ 92 }; 93 94 /** 95 * Constants defining fine grained ordering within a BHND_PROBE_* priority band. 96 * 97 * Example: 98 * @code 99 * BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST 100 * @endcode 101 */ 102 enum { 103 BHND_PROBE_ORDER_FIRST = 0, 104 BHND_PROBE_ORDER_EARLY = 25, 105 BHND_PROBE_ORDER_MIDDLE = 50, 106 BHND_PROBE_ORDER_LATE = 75, 107 BHND_PROBE_ORDER_LAST = 100 108 109 }; 110 111 112 /** 113 * Per-core IOCTL flags common to all bhnd(4) cores. 114 */ 115 enum { 116 BHND_IOCTL_BIST = 0x8000, /**< Initiate a built-in self-test (BIST). Must be cleared 117 after BIST results are read via BHND_IOST_BIST_* */ 118 BHND_IOCTL_PME = 0x4000, /**< Enable posting of power management events by the core. */ 119 BHND_IOCTL_CFLAGS = 0x3FFC, /**< Reserved for core-specific ioctl flags. */ 120 BHND_IOCTL_CLK_FORCE = 0x0002, /**< Force disable of clock gating, resulting in all clocks 121 being distributed within the core. Should be set when 122 asserting/deasserting reset to ensure the reset signal 123 fully propagates to the entire core. */ 124 BHND_IOCTL_CLK_EN = 0x0001, /**< If cleared, the core clock will be disabled. Should be 125 set during normal operation, and cleared when the core is 126 held in reset. */ 127 }; 128 129 /** 130 * Per-core IOST flags common to all bhnd(4) cores. 131 */ 132 enum { 133 BHND_IOST_BIST_DONE = 0x8000, /**< Set upon BIST completion (see BHND_IOCTL_BIST), and cleared 134 if 0 is written to BHND_IOCTL_BIST. */ 135 BHND_IOST_BIST_FAIL = 0x4000, /**< Set upon detection of a BIST error; the value is unspecified 136 if BIST has not completed and BHND_IOST_BIST_DONE is not set. */ 137 BHND_IOST_CLK = 0x2000, /**< Set if the core has requested that gated clocks be enabled, or 138 cleared otherwise. The value is undefined if a core does not 139 support clock gating. */ 140 BHND_IOST_DMA64 = 0x1000, /**< Set if this core supports 64-bit DMA */ 141 BHND_IOST_CFLAGS = 0x0FFC, /**< Reserved for core-specific status flags. */ 142 }; 143 144 /* 145 * Simplified accessors for bhnd device ivars 146 */ 147 #define BHND_ACCESSOR(var, ivar, type) \ 148 __BUS_ACCESSOR(bhnd, var, BHND, ivar, type) 149 150 BHND_ACCESSOR(vendor, VENDOR, uint16_t); 151 BHND_ACCESSOR(device, DEVICE, uint16_t); 152 BHND_ACCESSOR(hwrev, HWREV, uint8_t); 153 BHND_ACCESSOR(class, DEVICE_CLASS, bhnd_devclass_t); 154 BHND_ACCESSOR(vendor_name, VENDOR_NAME, const char *); 155 BHND_ACCESSOR(device_name, DEVICE_NAME, const char *); 156 BHND_ACCESSOR(core_index, CORE_INDEX, u_int); 157 BHND_ACCESSOR(core_unit, CORE_UNIT, int); 158 BHND_ACCESSOR(pmu_info, PMU_INFO, struct bhnd_core_pmu_info *); 159 160 #undef BHND_ACCESSOR 161 162 /** 163 * A bhnd(4) board descriptor. 164 */ 165 struct bhnd_board_info { 166 uint16_t board_vendor; /**< PCI-SIG vendor ID (even on non-PCI 167 * devices). 168 * 169 * On PCI devices, this will generally 170 * be the subsystem vendor ID, but the 171 * value may be overridden in device 172 * NVRAM. 173 */ 174 uint16_t board_type; /**< Board type (See BHND_BOARD_*) 175 * 176 * On PCI devices, this will generally 177 * be the subsystem device ID, but the 178 * value may be overridden in device 179 * NVRAM. 180 */ 181 uint16_t board_rev; /**< Board revision. */ 182 uint8_t board_srom_rev; /**< Board SROM format revision */ 183 184 uint32_t board_flags; /**< Board flags (see BHND_BFL_*) */ 185 uint32_t board_flags2; /**< Board flags 2 (see BHND_BFL2_*) */ 186 uint32_t board_flags3; /**< Board flags 3 (see BHND_BFL3_*) */ 187 }; 188 189 190 /** 191 * Chip Identification 192 * 193 * This is read from the ChipCommon ID register; on earlier bhnd(4) devices 194 * where ChipCommon is unavailable, known values must be supplied. 195 */ 196 struct bhnd_chipid { 197 uint16_t chip_id; /**< chip id (BHND_CHIPID_*) */ 198 uint8_t chip_rev; /**< chip revision */ 199 uint8_t chip_pkg; /**< chip package (BHND_PKGID_*) */ 200 uint8_t chip_type; /**< chip type (BHND_CHIPTYPE_*) */ 201 202 bhnd_addr_t enum_addr; /**< chip_type-specific enumeration 203 * address; either the siba(4) base 204 * core register block, or the bcma(4) 205 * EROM core address. */ 206 207 uint8_t ncores; /**< number of cores, if known. 0 if 208 * not available. */ 209 }; 210 211 /** 212 * A bhnd(4) core descriptor. 213 */ 214 struct bhnd_core_info { 215 uint16_t vendor; /**< JEP-106 vendor (BHND_MFGID_*) */ 216 uint16_t device; /**< device */ 217 uint16_t hwrev; /**< hardware revision */ 218 u_int core_idx; /**< bus-assigned core index */ 219 int unit; /**< bus-assigned core unit */ 220 }; 221 222 /** 223 * A bhnd(4) bus resource. 224 * 225 * This provides an abstract interface to per-core resources that may require 226 * bus-level remapping of address windows prior to access. 227 */ 228 struct bhnd_resource { 229 struct resource *res; /**< the system resource. */ 230 bool direct; /**< false if the resource requires 231 * bus window remapping before it 232 * is MMIO accessible. */ 233 }; 234 235 /** Wrap the active resource @p _r in a bhnd_resource structure */ 236 #define BHND_DIRECT_RESOURCE(_r) ((struct bhnd_resource) { \ 237 .res = (_r), \ 238 .direct = true, \ 239 }) 240 241 /** 242 * Device quirk table descriptor. 243 */ 244 struct bhnd_device_quirk { 245 struct bhnd_device_match desc; /**< device match descriptor */ 246 uint32_t quirks; /**< quirk flags */ 247 }; 248 249 #define BHND_CORE_QUIRK(_rev, _flags) \ 250 {{ BHND_MATCH_CORE_REV(_rev) }, (_flags) } 251 252 #define BHND_CHIP_QUIRK(_chip, _rev, _flags) \ 253 {{ BHND_CHIP_IR(BCM ## _chip, _rev) }, (_flags) } 254 255 #define BHND_PKG_QUIRK(_chip, _pkg, _flags) \ 256 {{ BHND_CHIP_IP(BCM ## _chip, BCM ## _chip ## _pkg) }, (_flags) } 257 258 #define BHND_BOARD_QUIRK(_board, _flags) \ 259 {{ BHND_MATCH_BOARD_TYPE(_board) }, \ 260 (_flags) } 261 262 #define BHND_DEVICE_QUIRK_END { { BHND_MATCH_ANY }, 0 } 263 #define BHND_DEVICE_QUIRK_IS_END(_q) \ 264 (((_q)->desc.m.match_flags == 0) && (_q)->quirks == 0) 265 266 enum { 267 BHND_DF_ANY = 0, 268 BHND_DF_HOSTB = (1<<0), /**< core is serving as the bus' host 269 * bridge. implies BHND_DF_ADAPTER */ 270 BHND_DF_SOC = (1<<1), /**< core is attached to a native 271 bus (BHND_ATTACH_NATIVE) */ 272 BHND_DF_ADAPTER = (1<<2), /**< core is attached to a bridged 273 * adapter (BHND_ATTACH_ADAPTER) */ 274 }; 275 276 /** Device probe table descriptor */ 277 struct bhnd_device { 278 const struct bhnd_device_match core; /**< core match descriptor */ 279 const char *desc; /**< device description, or NULL. */ 280 const struct bhnd_device_quirk *quirks_table; /**< quirks table for this device, or NULL */ 281 uint32_t device_flags; /**< required BHND_DF_* flags */ 282 }; 283 284 #define _BHND_DEVICE(_vendor, _device, _desc, _quirks, \ 285 _flags, ...) \ 286 { { BHND_MATCH_CORE(BHND_MFGID_ ## _vendor, \ 287 BHND_COREID_ ## _device) }, _desc, _quirks, \ 288 _flags } 289 290 #define BHND_DEVICE(_vendor, _device, _desc, _quirks, ...) \ 291 _BHND_DEVICE(_vendor, _device, _desc, _quirks, \ 292 ## __VA_ARGS__, 0) 293 294 #define BHND_DEVICE_END { { BHND_MATCH_ANY }, NULL, NULL, 0 } 295 #define BHND_DEVICE_IS_END(_d) \ 296 (BHND_MATCH_IS_ANY(&(_d)->core) && (_d)->desc == NULL) 297 298 /** 299 * bhnd device sort order. 300 */ 301 typedef enum { 302 BHND_DEVICE_ORDER_ATTACH, /**< sort by bhnd(4) device attach order; 303 child devices should be probed/attached 304 in this order */ 305 BHND_DEVICE_ORDER_DETACH, /**< sort by bhnd(4) device detach order; 306 child devices should be detached, suspended, 307 and shutdown in this order */ 308 } bhnd_device_order; 309 310 /** 311 * A registry of bhnd service providers. 312 */ 313 struct bhnd_service_registry { 314 STAILQ_HEAD(,bhnd_service_entry) entries; /**< registered services */ 315 struct mtx lock; /**< state lock */ 316 }; 317 318 /** 319 * bhnd service provider flags. 320 */ 321 enum { 322 BHND_SPF_INHERITED = (1<<0), /**< service provider reference was inherited from 323 a parent bus, and should be deregistered when the 324 last active reference is released */ 325 }; 326 327 const char *bhnd_vendor_name(uint16_t vendor); 328 const char *bhnd_port_type_name(bhnd_port_type port_type); 329 const char *bhnd_nvram_src_name(bhnd_nvram_src nvram_src); 330 331 const char *bhnd_find_core_name(uint16_t vendor, 332 uint16_t device); 333 bhnd_devclass_t bhnd_find_core_class(uint16_t vendor, 334 uint16_t device); 335 336 const char *bhnd_core_name(const struct bhnd_core_info *ci); 337 bhnd_devclass_t bhnd_core_class(const struct bhnd_core_info *ci); 338 339 int bhnd_format_chip_id(char *buffer, size_t size, 340 uint16_t chip_id); 341 342 device_t bhnd_bus_match_child(device_t bus, 343 const struct bhnd_core_match *desc); 344 345 device_t bhnd_bus_find_child(device_t bus, 346 bhnd_devclass_t class, int unit); 347 348 int bhnd_bus_get_children(device_t bus, 349 device_t **devlistp, int *devcountp, 350 bhnd_device_order order); 351 352 void bhnd_bus_free_children(device_t *devlist); 353 354 int bhnd_bus_probe_children(device_t bus); 355 356 int bhnd_sort_devices(device_t *devlist, 357 size_t devcount, bhnd_device_order order); 358 359 device_t bhnd_find_bridge_root(device_t dev, 360 devclass_t bus_class); 361 362 const struct bhnd_core_info *bhnd_match_core( 363 const struct bhnd_core_info *cores, 364 u_int num_cores, 365 const struct bhnd_core_match *desc); 366 367 const struct bhnd_core_info *bhnd_find_core( 368 const struct bhnd_core_info *cores, 369 u_int num_cores, bhnd_devclass_t class); 370 371 struct bhnd_core_match bhnd_core_get_match_desc( 372 const struct bhnd_core_info *core); 373 374 bool bhnd_cores_equal( 375 const struct bhnd_core_info *lhs, 376 const struct bhnd_core_info *rhs); 377 378 bool bhnd_core_matches( 379 const struct bhnd_core_info *core, 380 const struct bhnd_core_match *desc); 381 382 bool bhnd_chip_matches( 383 const struct bhnd_chipid *chipid, 384 const struct bhnd_chip_match *desc); 385 386 bool bhnd_board_matches( 387 const struct bhnd_board_info *info, 388 const struct bhnd_board_match *desc); 389 390 bool bhnd_hwrev_matches(uint16_t hwrev, 391 const struct bhnd_hwrev_match *desc); 392 393 bool bhnd_device_matches(device_t dev, 394 const struct bhnd_device_match *desc); 395 396 const struct bhnd_device *bhnd_device_lookup(device_t dev, 397 const struct bhnd_device *table, 398 size_t entry_size); 399 400 uint32_t bhnd_device_quirks(device_t dev, 401 const struct bhnd_device *table, 402 size_t entry_size); 403 404 struct bhnd_core_info bhnd_get_core_info(device_t dev); 405 406 int bhnd_alloc_resources(device_t dev, 407 struct resource_spec *rs, 408 struct bhnd_resource **res); 409 410 void bhnd_release_resources(device_t dev, 411 const struct resource_spec *rs, 412 struct bhnd_resource **res); 413 414 struct bhnd_chipid bhnd_parse_chipid(uint32_t idreg, 415 bhnd_addr_t enum_addr); 416 417 int bhnd_chipid_fixed_ncores( 418 const struct bhnd_chipid *cid, 419 uint16_t chipc_hwrev, uint8_t *ncores); 420 421 int bhnd_read_chipid(device_t dev, 422 struct resource_spec *rs, 423 bus_size_t chipc_offset, 424 struct bhnd_chipid *result); 425 426 void bhnd_set_custom_core_desc(device_t dev, 427 const char *name); 428 void bhnd_set_default_core_desc(device_t dev); 429 430 void bhnd_set_default_bus_desc(device_t dev, 431 const struct bhnd_chipid *chip_id); 432 433 int bhnd_nvram_getvar_str(device_t dev, 434 const char *name, char *buf, size_t len, 435 size_t *rlen); 436 437 int bhnd_nvram_getvar_uint(device_t dev, 438 const char *name, void *value, int width); 439 int bhnd_nvram_getvar_uint8(device_t dev, 440 const char *name, uint8_t *value); 441 int bhnd_nvram_getvar_uint16(device_t dev, 442 const char *name, uint16_t *value); 443 int bhnd_nvram_getvar_uint32(device_t dev, 444 const char *name, uint32_t *value); 445 446 int bhnd_nvram_getvar_int(device_t dev, 447 const char *name, void *value, int width); 448 int bhnd_nvram_getvar_int8(device_t dev, 449 const char *name, int8_t *value); 450 int bhnd_nvram_getvar_int16(device_t dev, 451 const char *name, int16_t *value); 452 int bhnd_nvram_getvar_int32(device_t dev, 453 const char *name, int32_t *value); 454 455 int bhnd_nvram_getvar_array(device_t dev, 456 const char *name, void *buf, size_t count, 457 bhnd_nvram_type type); 458 459 int bhnd_service_registry_init( 460 struct bhnd_service_registry *bsr); 461 int bhnd_service_registry_fini( 462 struct bhnd_service_registry *bsr); 463 int bhnd_service_registry_add( 464 struct bhnd_service_registry *bsr, 465 device_t provider, 466 bhnd_service_t service, 467 uint32_t flags); 468 int bhnd_service_registry_remove( 469 struct bhnd_service_registry *bsr, 470 device_t provider, 471 bhnd_service_t service); 472 device_t bhnd_service_registry_retain( 473 struct bhnd_service_registry *bsr, 474 bhnd_service_t service); 475 bool bhnd_service_registry_release( 476 struct bhnd_service_registry *bsr, 477 device_t provider, 478 bhnd_service_t service); 479 480 int bhnd_bus_generic_register_provider( 481 device_t dev, device_t child, 482 device_t provider, bhnd_service_t service); 483 int bhnd_bus_generic_deregister_provider( 484 device_t dev, device_t child, 485 device_t provider, bhnd_service_t service); 486 device_t bhnd_bus_generic_retain_provider(device_t dev, 487 device_t child, bhnd_service_t service); 488 void bhnd_bus_generic_release_provider(device_t dev, 489 device_t child, device_t provider, 490 bhnd_service_t service); 491 492 int bhnd_bus_generic_sr_register_provider( 493 device_t dev, device_t child, 494 device_t provider, bhnd_service_t service); 495 int bhnd_bus_generic_sr_deregister_provider( 496 device_t dev, device_t child, 497 device_t provider, bhnd_service_t service); 498 device_t bhnd_bus_generic_sr_retain_provider(device_t dev, 499 device_t child, bhnd_service_t service); 500 void bhnd_bus_generic_sr_release_provider(device_t dev, 501 device_t child, device_t provider, 502 bhnd_service_t service); 503 504 bool bhnd_bus_generic_is_hw_disabled(device_t dev, 505 device_t child); 506 bool bhnd_bus_generic_is_region_valid(device_t dev, 507 device_t child, bhnd_port_type type, 508 u_int port, u_int region); 509 int bhnd_bus_generic_get_nvram_var(device_t dev, 510 device_t child, const char *name, 511 void *buf, size_t *size, 512 bhnd_nvram_type type); 513 const struct bhnd_chipid *bhnd_bus_generic_get_chipid(device_t dev, 514 device_t child); 515 int bhnd_bus_generic_read_board_info(device_t dev, 516 device_t child, 517 struct bhnd_board_info *info); 518 struct bhnd_resource *bhnd_bus_generic_alloc_resource (device_t dev, 519 device_t child, int type, int *rid, 520 rman_res_t start, rman_res_t end, 521 rman_res_t count, u_int flags); 522 int bhnd_bus_generic_release_resource (device_t dev, 523 device_t child, int type, int rid, 524 struct bhnd_resource *r); 525 int bhnd_bus_generic_activate_resource (device_t dev, 526 device_t child, int type, int rid, 527 struct bhnd_resource *r); 528 int bhnd_bus_generic_deactivate_resource (device_t dev, 529 device_t child, int type, int rid, 530 struct bhnd_resource *r); 531 bhnd_attach_type bhnd_bus_generic_get_attach_type(device_t dev, 532 device_t child); 533 534 /** 535 * Return the bhnd(4) bus driver's device enumeration parser class 536 * 537 * @param driver A bhnd bus driver instance. 538 */ 539 static inline bhnd_erom_class_t * 540 bhnd_driver_get_erom_class(driver_t *driver) 541 { 542 return (BHND_BUS_GET_EROM_CLASS(driver)); 543 } 544 545 /** 546 * Return the active host bridge core for the bhnd bus, if any, or NULL if 547 * not found. 548 * 549 * @param dev A bhnd bus device. 550 */ 551 static inline device_t 552 bhnd_bus_find_hostb_device(device_t dev) { 553 return (BHND_BUS_FIND_HOSTB_DEVICE(dev)); 554 } 555 556 /** 557 * Register a provider for a given @p service. 558 * 559 * @param dev The device to register as a service provider 560 * with its parent bus. 561 * @param service The service for which @p dev will be registered. 562 * 563 * @retval 0 success 564 * @retval EEXIST if an entry for @p service already exists. 565 * @retval non-zero if registering @p dev otherwise fails, a regular 566 * unix error code will be returned. 567 */ 568 static inline int 569 bhnd_register_provider(device_t dev, bhnd_service_t service) 570 { 571 return (BHND_BUS_REGISTER_PROVIDER(device_get_parent(dev), dev, dev, 572 service)); 573 } 574 575 /** 576 * Attempt to remove a service provider registration for @p dev. 577 * 578 * @param dev The device to be deregistered as a service provider. 579 * @param service The service for which @p dev will be deregistered, or 580 * BHND_SERVICE_INVALID to remove all service registrations 581 * for @p dev. 582 * 583 * @retval 0 success 584 * @retval EBUSY if active references to @p dev exist; @see 585 * bhnd_retain_provider() and bhnd_release_provider(). 586 */ 587 static inline int 588 bhnd_deregister_provider(device_t dev, bhnd_service_t service) 589 { 590 return (BHND_BUS_DEREGISTER_PROVIDER(device_get_parent(dev), dev, dev, 591 service)); 592 } 593 594 /** 595 * Retain and return a reference to the registered @p service provider, if any. 596 * 597 * @param dev The requesting device. 598 * @param service The service for which a provider should be returned. 599 * 600 * On success, the caller assumes ownership the returned provider, and 601 * is responsible for releasing this reference via 602 * BHND_BUS_RELEASE_PROVIDER(). 603 * 604 * @retval device_t success 605 * @retval NULL if no provider is registered for @p service. 606 */ 607 static inline device_t 608 bhnd_retain_provider(device_t dev, bhnd_service_t service) 609 { 610 return (BHND_BUS_RETAIN_PROVIDER(device_get_parent(dev), dev, 611 service)); 612 } 613 614 /** 615 * Release a reference to a provider device previously returned by 616 * bhnd_retain_provider(). 617 * 618 * @param dev The requesting device. 619 * @param provider The provider to be released. 620 * @param service The service for which @p provider was previously retained. 621 */ 622 static inline void 623 bhnd_release_provider(device_t dev, device_t provider, 624 bhnd_service_t service) 625 { 626 return (BHND_BUS_RELEASE_PROVIDER(device_get_parent(dev), dev, 627 provider, service)); 628 } 629 630 /** 631 * Return true if the hardware components required by @p dev are known to be 632 * unpopulated or otherwise unusable. 633 * 634 * In some cases, enumerated devices may have pins that are left floating, or 635 * the hardware may otherwise be non-functional; this method allows a parent 636 * device to explicitly specify if a successfully enumerated @p dev should 637 * be disabled. 638 * 639 * @param dev A bhnd bus child device. 640 */ 641 static inline bool 642 bhnd_is_hw_disabled(device_t dev) { 643 return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), dev)); 644 } 645 646 /** 647 * Return the BHND chip identification info for the bhnd bus. 648 * 649 * @param dev A bhnd bus child device. 650 */ 651 static inline const struct bhnd_chipid * 652 bhnd_get_chipid(device_t dev) { 653 return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev)); 654 }; 655 656 657 /** 658 * Read the current value of a bhnd(4) device's per-core I/O control register. 659 * 660 * @param dev The bhnd bus child device to be queried. 661 * @param[out] ioctl On success, the I/O control register value. 662 * 663 * @retval 0 success 664 * @retval EINVAL If @p child is not a direct child of @p dev. 665 * @retval ENODEV If agent/config space for @p child is unavailable. 666 * @retval non-zero If reading the IOCTL register otherwise fails, a regular 667 * unix error code will be returned. 668 */ 669 static inline int 670 bhnd_read_ioctl(device_t dev, uint16_t *ioctl) 671 { 672 return (BHND_BUS_READ_IOCTL(device_get_parent(dev), dev, ioctl)); 673 } 674 675 /** 676 * Write @p value and @p mask to a bhnd(4) device's per-core I/O control 677 * register. 678 * 679 * @param dev The bhnd bus child device for which the IOCTL register will be 680 * written. 681 * @param value The value to be written (see BHND_IOCTL_*). 682 * @param mask Only the bits defined by @p mask will be updated from @p value. 683 * 684 * @retval 0 success 685 * @retval EINVAL If @p child is not a direct child of @p dev. 686 * @retval ENODEV If agent/config space for @p child is unavailable. 687 * @retval non-zero If writing the IOCTL register otherwise fails, a regular 688 * unix error code will be returned. 689 */ 690 static inline int 691 bhnd_write_ioctl(device_t dev, uint16_t value, uint16_t mask) 692 { 693 return (BHND_BUS_WRITE_IOCTL(device_get_parent(dev), dev, value, mask)); 694 } 695 696 /** 697 * Read the current value of a bhnd(4) device's per-core I/O status register. 698 * 699 * @param dev The bhnd bus child device to be queried. 700 * @param[out] iost On success, the I/O status register value. 701 * 702 * @retval 0 success 703 * @retval EINVAL If @p child is not a direct child of @p dev. 704 * @retval ENODEV If agent/config space for @p child is unavailable. 705 * @retval non-zero If reading the IOST register otherwise fails, a regular 706 * unix error code will be returned. 707 */ 708 static inline int 709 bhnd_read_iost(device_t dev, uint16_t *iost) 710 { 711 return (BHND_BUS_READ_IOST(device_get_parent(dev), dev, iost)); 712 } 713 714 /** 715 * Return true if the given bhnd device's hardware is currently held 716 * in a RESET state or otherwise not clocked (BHND_IOCTL_CLK_EN). 717 * 718 * @param dev The device to query. 719 * 720 * @retval true If @p dev is held in RESET or not clocked (BHND_IOCTL_CLK_EN), 721 * or an error occured determining @p dev's hardware state. 722 * @retval false If @p dev is clocked and is not held in RESET. 723 */ 724 static inline bool 725 bhnd_is_hw_suspended(device_t dev) 726 { 727 return (BHND_BUS_IS_HW_SUSPENDED(device_get_parent(dev), dev)); 728 } 729 730 /** 731 * Place the bhnd(4) device's hardware into a reset state, and then bring the 732 * hardware out of reset with BHND_IOCTL_CLK_EN and @p ioctl flags set. 733 * 734 * Any clock or resource PMU requests previously made by @p dev will be 735 * invalidated. 736 * 737 * @param dev The device to be reset. 738 * @param ioctl Device-specific core ioctl flags to be supplied on reset 739 * (see BHND_IOCTL_*). 740 * 741 * @retval 0 success 742 * @retval non-zero error 743 */ 744 static inline int 745 bhnd_reset_hw(device_t dev, uint16_t ioctl) 746 { 747 return (BHND_BUS_RESET_HW(device_get_parent(dev), dev, ioctl)); 748 } 749 750 /** 751 * Suspend @p child's hardware in a low-power reset state. 752 * 753 * Any clock or resource PMU requests previously made by @p dev will be 754 * invalidated. 755 * 756 * The hardware may be brought out of reset via bhnd_reset_hw(). 757 * 758 * @param dev The device to be suspended. 759 * 760 * @retval 0 success 761 * @retval non-zero error 762 */ 763 static inline int 764 bhnd_suspend_hw(device_t dev) 765 { 766 return (BHND_BUS_SUSPEND_HW(device_get_parent(dev), dev)); 767 } 768 769 /** 770 * If supported by the chipset, return the clock source for the given clock. 771 * 772 * This function is only supported on early PWRCTL-equipped chipsets 773 * that expose clock management via their host bridge interface. Currently, 774 * this includes PCI (not PCIe) devices, with ChipCommon core revisions 0-9. 775 * 776 * @param dev A bhnd bus child device. 777 * @param clock The clock for which a clock source will be returned. 778 * 779 * @retval bhnd_clksrc The clock source for @p clock. 780 * @retval BHND_CLKSRC_UNKNOWN If @p clock is unsupported, or its 781 * clock source is not known to the bus. 782 */ 783 static inline bhnd_clksrc 784 bhnd_pwrctl_get_clksrc(device_t dev, bhnd_clock clock) 785 { 786 return (BHND_BUS_PWRCTL_GET_CLKSRC(device_get_parent(dev), dev, clock)); 787 } 788 789 /** 790 * If supported by the chipset, gate @p clock 791 * 792 * This function is only supported on early PWRCTL-equipped chipsets 793 * that expose clock management via their host bridge interface. Currently, 794 * this includes PCI (not PCIe) devices, with ChipCommon core revisions 0-9. 795 * 796 * @param dev A bhnd bus child device. 797 * @param clock The clock to be disabled. 798 * 799 * @retval 0 success 800 * @retval ENODEV If bus-level clock source management is not supported. 801 * @retval ENXIO If bus-level management of @p clock is not supported. 802 */ 803 static inline int 804 bhnd_pwrctl_gate_clock(device_t dev, bhnd_clock clock) 805 { 806 return (BHND_BUS_PWRCTL_GATE_CLOCK(device_get_parent(dev), dev, clock)); 807 } 808 809 /** 810 * If supported by the chipset, ungate @p clock 811 * 812 * This function is only supported on early PWRCTL-equipped chipsets 813 * that expose clock management via their host bridge interface. Currently, 814 * this includes PCI (not PCIe) devices, with ChipCommon core revisions 0-9. 815 * 816 * @param dev A bhnd bus child device. 817 * @param clock The clock to be enabled. 818 * 819 * @retval 0 success 820 * @retval ENODEV If bus-level clock source management is not supported. 821 * @retval ENXIO If bus-level management of @p clock is not supported. 822 */ 823 static inline int 824 bhnd_pwrctl_ungate_clock(device_t dev, bhnd_clock clock) 825 { 826 return (BHND_BUS_PWRCTL_UNGATE_CLOCK(device_get_parent(dev), dev, 827 clock)); 828 } 829 830 /** 831 * Return the BHND attachment type of the parent bhnd bus. 832 * 833 * @param dev A bhnd bus child device. 834 * 835 * @retval BHND_ATTACH_ADAPTER if the bus is resident on a bridged adapter, 836 * such as a WiFi chipset. 837 * @retval BHND_ATTACH_NATIVE if the bus provides hardware services (clock, 838 * CPU, etc) to a directly attached native host. 839 */ 840 static inline bhnd_attach_type 841 bhnd_get_attach_type (device_t dev) { 842 return (BHND_BUS_GET_ATTACH_TYPE(device_get_parent(dev), dev)); 843 } 844 845 /** 846 * Attempt to read the BHND board identification from the bhnd bus. 847 * 848 * This relies on NVRAM access, and will fail if a valid NVRAM device cannot 849 * be found, or is not yet attached. 850 * 851 * @param dev The parent of @p child. 852 * @param child The bhnd device requesting board info. 853 * @param[out] info On success, will be populated with the bhnd(4) device's 854 * board information. 855 * 856 * @retval 0 success 857 * @retval ENODEV No valid NVRAM source could be found. 858 * @retval non-zero If reading @p name otherwise fails, a regular unix 859 * error code will be returned. 860 */ 861 static inline int 862 bhnd_read_board_info(device_t dev, struct bhnd_board_info *info) 863 { 864 return (BHND_BUS_READ_BOARD_INFO(device_get_parent(dev), dev, info)); 865 } 866 867 /** 868 * Return the number of interrupts to be assigned to @p child via 869 * BHND_BUS_ASSIGN_INTR(). 870 * 871 * @param dev A bhnd bus child device. 872 */ 873 static inline int 874 bhnd_get_intr_count(device_t dev) 875 { 876 return (BHND_BUS_GET_INTR_COUNT(device_get_parent(dev), dev)); 877 } 878 879 /** 880 * Return the backplane interrupt vector corresponding to @p dev's given 881 * @p intr number. 882 * 883 * @param dev A bhnd bus child device. 884 * @param intr The interrupt number being queried. This is equivalent to the 885 * bus resource ID for the interrupt. 886 * @param[out] ivec On success, the assigned hardware interrupt vector be 887 * written to this pointer. 888 * 889 * On bcma(4) devices, this returns the OOB bus line assigned to the 890 * interrupt. 891 * 892 * On siba(4) devices, this returns the target OCP slave flag number assigned 893 * to the interrupt. 894 * 895 * @retval 0 success 896 * @retval ENXIO If @p intr exceeds the number of interrupts available 897 * to @p child. 898 */ 899 static inline int 900 bhnd_get_core_ivec(device_t dev, u_int intr, uint32_t *ivec) 901 { 902 return (BHND_BUS_GET_CORE_IVEC(device_get_parent(dev), dev, intr, 903 ivec)); 904 } 905 906 /** 907 * Allocate and enable per-core PMU request handling for @p child. 908 * 909 * The region containing the core's PMU register block (if any) must be 910 * allocated via bus_alloc_resource(9) (or bhnd_alloc_resource) before 911 * calling bhnd_alloc_pmu(), and must not be released until after 912 * calling bhnd_release_pmu(). 913 * 914 * @param dev The parent of @p child. 915 * @param child The requesting bhnd device. 916 * 917 * @retval 0 success 918 * @retval non-zero If allocating PMU request state otherwise fails, a 919 * regular unix error code will be returned. 920 */ 921 static inline int 922 bhnd_alloc_pmu(device_t dev) 923 { 924 return (BHND_BUS_ALLOC_PMU(device_get_parent(dev), dev)); 925 } 926 927 /** 928 * Release any per-core PMU resources allocated for @p child. Any outstanding 929 * PMU requests are are discarded. 930 * 931 * @param dev The parent of @p child. 932 * @param child The requesting bhnd device. 933 * 934 * @retval 0 success 935 * @retval non-zero If releasing PMU request state otherwise fails, a 936 * regular unix error code will be returned, and 937 * the core state will be left unmodified. 938 */ 939 static inline int 940 bhnd_release_pmu(device_t dev) 941 { 942 return (BHND_BUS_RELEASE_PMU(device_get_parent(dev), dev)); 943 } 944 945 /** 946 * Request that @p clock (or faster) be routed to @p dev. 947 * 948 * @note A driver must ask the bhnd bus to allocate clock request state 949 * via bhnd_alloc_pmu() before it can request clock resources. 950 * 951 * @note Any outstanding PMU clock requests will be discarded upon calling 952 * BHND_BUS_RESET_HW() or BHND_BUS_SUSPEND_HW(). 953 * 954 * @param dev The bhnd(4) device to which @p clock should be routed. 955 * @param clock The requested clock source. 956 * 957 * @retval 0 success 958 * @retval ENODEV If an unsupported clock was requested. 959 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable, 960 */ 961 static inline int 962 bhnd_request_clock(device_t dev, bhnd_clock clock) 963 { 964 return (BHND_BUS_REQUEST_CLOCK(device_get_parent(dev), dev, clock)); 965 } 966 967 /** 968 * Request that @p clocks be powered on behalf of @p dev. 969 * 970 * This will power any clock sources (e.g. XTAL, PLL, etc) required for 971 * @p clocks and wait until they are ready, discarding any previous 972 * requests by @p dev. 973 * 974 * @note A driver must ask the bhnd bus to allocate clock request state 975 * via bhnd_alloc_pmu() before it can request clock resources. 976 * 977 * @note Any outstanding PMU clock requests will be discarded upon calling 978 * BHND_BUS_RESET_HW() or BHND_BUS_SUSPEND_HW(). 979 * 980 * @param dev The requesting bhnd(4) device. 981 * @param clocks The clock(s) to be enabled. 982 * 983 * @retval 0 success 984 * @retval ENODEV If an unsupported clock was requested. 985 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable. 986 */ 987 static inline int 988 bhnd_enable_clocks(device_t dev, uint32_t clocks) 989 { 990 return (BHND_BUS_ENABLE_CLOCKS(device_get_parent(dev), dev, clocks)); 991 } 992 993 /** 994 * Power up an external PMU-managed resource assigned to @p dev. 995 * 996 * @note A driver must ask the bhnd bus to allocate PMU request state 997 * via bhnd_alloc_pmu() before it can request PMU resources. 998 * 999 * @note Any outstanding PMU resource requests will be released upon calling 1000 * bhnd_reset_hw() or bhnd_suspend_hw(). 1001 * 1002 * @param dev The requesting bhnd(4) device. 1003 * @param rsrc The core-specific external resource identifier. 1004 * 1005 * @retval 0 success 1006 * @retval ENODEV If the PMU does not support @p rsrc. 1007 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable. 1008 */ 1009 static inline int 1010 bhnd_request_ext_rsrc(device_t dev, u_int rsrc) 1011 { 1012 return (BHND_BUS_REQUEST_EXT_RSRC(device_get_parent(dev), dev, rsrc)); 1013 } 1014 1015 /** 1016 * Power down an external PMU-managed resource assigned to @p dev. 1017 * 1018 * A driver must ask the bhnd bus to allocate PMU request state 1019 * via bhnd_alloc_pmu() before it can request PMU resources. 1020 * 1021 * @param dev The requesting bhnd(4) device. 1022 * @param rsrc The core-specific external resource identifier. 1023 * 1024 * @retval 0 success 1025 * @retval ENODEV If the PMU does not support @p rsrc. 1026 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable. 1027 */ 1028 static inline int 1029 bhnd_release_ext_rsrc(device_t dev, u_int rsrc) 1030 { 1031 return (BHND_BUS_RELEASE_EXT_RSRC(device_get_parent(dev), dev, rsrc)); 1032 } 1033 1034 /** 1035 * Read @p width bytes at @p offset from the bus-specific agent/config 1036 * space of @p dev. 1037 * 1038 * @param dev The bhnd device for which @p offset should be read. 1039 * @param offset The offset to be read. 1040 * @param[out] value On success, the will be set to the @p width value read 1041 * at @p offset. 1042 * @param width The size of the access. Must be 1, 2 or 4 bytes. 1043 * 1044 * The exact behavior of this method is bus-specific. In the case of 1045 * bcma(4), this method provides access to the first agent port of @p child. 1046 * 1047 * @note Device drivers should only use this API for functionality 1048 * that is not available via another bhnd(4) function. 1049 * 1050 * @retval 0 success 1051 * @retval EINVAL If @p child is not a direct child of @p dev. 1052 * @retval EINVAL If @p width is not one of 1, 2, or 4 bytes. 1053 * @retval ENODEV If accessing agent/config space for @p child is unsupported. 1054 * @retval EFAULT If reading @p width at @p offset exceeds the bounds of 1055 * the mapped agent/config space for @p child. 1056 */ 1057 static inline uint32_t 1058 bhnd_read_config(device_t dev, bus_size_t offset, void *value, u_int width) 1059 { 1060 return (BHND_BUS_READ_CONFIG(device_get_parent(dev), dev, offset, 1061 value, width)); 1062 } 1063 1064 /** 1065 * Write @p width bytes at @p offset to the bus-specific agent/config 1066 * space of @p dev. 1067 * 1068 * @param dev The bhnd device for which @p offset should be read. 1069 * @param offset The offset to be written. 1070 * @param value A pointer to the value to be written. 1071 * @param width The size of @p value. Must be 1, 2 or 4 bytes. 1072 * 1073 * The exact behavior of this method is bus-specific. In the case of 1074 * bcma(4), this method provides access to the first agent port of @p child. 1075 * 1076 * @note Device drivers should only use this API for functionality 1077 * that is not available via another bhnd(4) function. 1078 * 1079 * @retval 0 success 1080 * @retval EINVAL If @p child is not a direct child of @p dev. 1081 * @retval EINVAL If @p width is not one of 1, 2, or 4 bytes. 1082 * @retval ENODEV If accessing agent/config space for @p child is unsupported. 1083 * @retval EFAULT If reading @p width at @p offset exceeds the bounds of 1084 * the mapped agent/config space for @p child. 1085 */ 1086 static inline int 1087 bhnd_write_config(device_t dev, bus_size_t offset, const void *value, 1088 u_int width) 1089 { 1090 return (BHND_BUS_WRITE_CONFIG(device_get_parent(dev), dev, offset, 1091 value, width)); 1092 } 1093 1094 /** 1095 * Read an NVRAM variable, coerced to the requested @p type. 1096 * 1097 * @param dev A bhnd bus child device. 1098 * @param name The NVRAM variable name. 1099 * @param[out] buf A buffer large enough to hold @p len bytes. On 1100 * success, the requested value will be written to 1101 * this buffer. This argment may be NULL if 1102 * the value is not desired. 1103 * @param[in,out] len The maximum capacity of @p buf. On success, 1104 * will be set to the actual size of the requested 1105 * value. 1106 * @param type The desired data representation to be written 1107 * to @p buf. 1108 * 1109 * @retval 0 success 1110 * @retval ENOENT The requested variable was not found. 1111 * @retval ENODEV No valid NVRAM source could be found. 1112 * @retval ENOMEM If a buffer of @p size is too small to hold the 1113 * requested value. 1114 * @retval EOPNOTSUPP If the value cannot be coerced to @p type. 1115 * @retval ERANGE If value coercion would overflow @p type. 1116 * @retval non-zero If reading @p name otherwise fails, a regular unix 1117 * error code will be returned. 1118 */ 1119 static inline int 1120 bhnd_nvram_getvar(device_t dev, const char *name, void *buf, size_t *len, 1121 bhnd_nvram_type type) 1122 { 1123 return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, buf, 1124 len, type)); 1125 } 1126 1127 /** 1128 * Allocate a resource from a device's parent bhnd(4) bus. 1129 * 1130 * @param dev The device requesting resource ownership. 1131 * @param type The type of resource to allocate. This may be any type supported 1132 * by the standard bus APIs. 1133 * @param rid The bus-specific handle identifying the resource being allocated. 1134 * @param start The start address of the resource. 1135 * @param end The end address of the resource. 1136 * @param count The size of the resource. 1137 * @param flags The flags for the resource to be allocated. These may be any 1138 * values supported by the standard bus APIs. 1139 * 1140 * To request the resource's default addresses, pass @p start and 1141 * @p end values of @c 0 and @c ~0, respectively, and 1142 * a @p count of @c 1. 1143 * 1144 * @retval NULL The resource could not be allocated. 1145 * @retval resource The allocated resource. 1146 */ 1147 static inline struct bhnd_resource * 1148 bhnd_alloc_resource(device_t dev, int type, int *rid, rman_res_t start, 1149 rman_res_t end, rman_res_t count, u_int flags) 1150 { 1151 return BHND_BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, rid, 1152 start, end, count, flags); 1153 } 1154 1155 1156 /** 1157 * Allocate a resource from a device's parent bhnd(4) bus, using the 1158 * resource's default start, end, and count values. 1159 * 1160 * @param dev The device requesting resource ownership. 1161 * @param type The type of resource to allocate. This may be any type supported 1162 * by the standard bus APIs. 1163 * @param rid The bus-specific handle identifying the resource being allocated. 1164 * @param flags The flags for the resource to be allocated. These may be any 1165 * values supported by the standard bus APIs. 1166 * 1167 * @retval NULL The resource could not be allocated. 1168 * @retval resource The allocated resource. 1169 */ 1170 static inline struct bhnd_resource * 1171 bhnd_alloc_resource_any(device_t dev, int type, int *rid, u_int flags) 1172 { 1173 return bhnd_alloc_resource(dev, type, rid, 0, ~0, 1, flags); 1174 } 1175 1176 /** 1177 * Activate a previously allocated bhnd resource. 1178 * 1179 * @param dev The device holding ownership of the allocated resource. 1180 * @param type The type of the resource. 1181 * @param rid The bus-specific handle identifying the resource. 1182 * @param r A pointer to the resource returned by bhnd_alloc_resource or 1183 * BHND_BUS_ALLOC_RESOURCE. 1184 * 1185 * @retval 0 success 1186 * @retval non-zero an error occurred while activating the resource. 1187 */ 1188 static inline int 1189 bhnd_activate_resource(device_t dev, int type, int rid, 1190 struct bhnd_resource *r) 1191 { 1192 return BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev), dev, type, 1193 rid, r); 1194 } 1195 1196 /** 1197 * Deactivate a previously activated bhnd resource. 1198 * 1199 * @param dev The device holding ownership of the activated resource. 1200 * @param type The type of the resource. 1201 * @param rid The bus-specific handle identifying the resource. 1202 * @param r A pointer to the resource returned by bhnd_alloc_resource or 1203 * BHND_BUS_ALLOC_RESOURCE. 1204 * 1205 * @retval 0 success 1206 * @retval non-zero an error occurred while activating the resource. 1207 */ 1208 static inline int 1209 bhnd_deactivate_resource(device_t dev, int type, int rid, 1210 struct bhnd_resource *r) 1211 { 1212 return BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), dev, type, 1213 rid, r); 1214 } 1215 1216 /** 1217 * Free a resource allocated by bhnd_alloc_resource(). 1218 * 1219 * @param dev The device holding ownership of the resource. 1220 * @param type The type of the resource. 1221 * @param rid The bus-specific handle identifying the resource. 1222 * @param r A pointer to the resource returned by bhnd_alloc_resource or 1223 * BHND_ALLOC_RESOURCE. 1224 * 1225 * @retval 0 success 1226 * @retval non-zero an error occurred while activating the resource. 1227 */ 1228 static inline int 1229 bhnd_release_resource(device_t dev, int type, int rid, 1230 struct bhnd_resource *r) 1231 { 1232 return BHND_BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, type, 1233 rid, r); 1234 } 1235 1236 /** 1237 * Return true if @p region_num is a valid region on @p port_num of 1238 * @p type attached to @p dev. 1239 * 1240 * @param dev A bhnd bus child device. 1241 * @param type The port type being queried. 1242 * @param port_num The port number being queried. 1243 * @param region_num The region number being queried. 1244 */ 1245 static inline bool 1246 bhnd_is_region_valid(device_t dev, bhnd_port_type type, u_int port_num, 1247 u_int region_num) 1248 { 1249 return (BHND_BUS_IS_REGION_VALID(device_get_parent(dev), dev, type, 1250 port_num, region_num)); 1251 } 1252 1253 /** 1254 * Return the number of ports of type @p type attached to @p def. 1255 * 1256 * @param dev A bhnd bus child device. 1257 * @param type The port type being queried. 1258 */ 1259 static inline u_int 1260 bhnd_get_port_count(device_t dev, bhnd_port_type type) { 1261 return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), dev, type)); 1262 } 1263 1264 /** 1265 * Return the number of memory regions mapped to @p child @p port of 1266 * type @p type. 1267 * 1268 * @param dev A bhnd bus child device. 1269 * @param port The port number being queried. 1270 * @param type The port type being queried. 1271 */ 1272 static inline u_int 1273 bhnd_get_region_count(device_t dev, bhnd_port_type type, u_int port) { 1274 return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), dev, type, 1275 port)); 1276 } 1277 1278 /** 1279 * Return the resource-ID for a memory region on the given device port. 1280 * 1281 * @param dev A bhnd bus child device. 1282 * @param type The port type. 1283 * @param port The port identifier. 1284 * @param region The identifier of the memory region on @p port. 1285 * 1286 * @retval int The RID for the given @p port and @p region on @p device. 1287 * @retval -1 No such port/region found. 1288 */ 1289 static inline int 1290 bhnd_get_port_rid(device_t dev, bhnd_port_type type, u_int port, u_int region) 1291 { 1292 return BHND_BUS_GET_PORT_RID(device_get_parent(dev), dev, type, port, 1293 region); 1294 } 1295 1296 /** 1297 * Decode a port / region pair on @p dev defined by @p rid. 1298 * 1299 * @param dev A bhnd bus child device. 1300 * @param type The resource type. 1301 * @param rid The resource identifier. 1302 * @param[out] port_type The decoded port type. 1303 * @param[out] port The decoded port identifier. 1304 * @param[out] region The decoded region identifier. 1305 * 1306 * @retval 0 success 1307 * @retval non-zero No matching port/region found. 1308 */ 1309 static inline int 1310 bhnd_decode_port_rid(device_t dev, int type, int rid, bhnd_port_type *port_type, 1311 u_int *port, u_int *region) 1312 { 1313 return BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), dev, type, rid, 1314 port_type, port, region); 1315 } 1316 1317 /** 1318 * Get the address and size of @p region on @p port. 1319 * 1320 * @param dev A bhnd bus child device. 1321 * @param port_type The port type. 1322 * @param port The port identifier. 1323 * @param region The identifier of the memory region on @p port. 1324 * @param[out] region_addr The region's base address. 1325 * @param[out] region_size The region's size. 1326 * 1327 * @retval 0 success 1328 * @retval non-zero No matching port/region found. 1329 */ 1330 static inline int 1331 bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port, 1332 u_int region, bhnd_addr_t *region_addr, bhnd_size_t *region_size) 1333 { 1334 return BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), dev, port_type, 1335 port, region, region_addr, region_size); 1336 } 1337 1338 /* 1339 * bhnd bus-level equivalents of the bus_(read|write|set|barrier|...) 1340 * macros (compatible with bhnd_resource). 1341 * 1342 * Generated with bhnd/tools/bus_macro.sh 1343 */ 1344 #define bhnd_bus_barrier(r, o, l, f) \ 1345 ((r)->direct) ? \ 1346 bus_barrier((r)->res, (o), (l), (f)) : \ 1347 BHND_BUS_BARRIER( \ 1348 device_get_parent(rman_get_device((r)->res)), \ 1349 rman_get_device((r)->res), (r), (o), (l), (f)) 1350 #define bhnd_bus_read_1(r, o) \ 1351 ((r)->direct) ? \ 1352 bus_read_1((r)->res, (o)) : \ 1353 BHND_BUS_READ_1( \ 1354 device_get_parent(rman_get_device((r)->res)), \ 1355 rman_get_device((r)->res), (r), (o)) 1356 #define bhnd_bus_read_multi_1(r, o, d, c) \ 1357 ((r)->direct) ? \ 1358 bus_read_multi_1((r)->res, (o), (d), (c)) : \ 1359 BHND_BUS_READ_MULTI_1( \ 1360 device_get_parent(rman_get_device((r)->res)), \ 1361 rman_get_device((r)->res), (r), (o), (d), (c)) 1362 #define bhnd_bus_read_region_1(r, o, d, c) \ 1363 ((r)->direct) ? \ 1364 bus_read_region_1((r)->res, (o), (d), (c)) : \ 1365 BHND_BUS_READ_REGION_1( \ 1366 device_get_parent(rman_get_device((r)->res)), \ 1367 rman_get_device((r)->res), (r), (o), (d), (c)) 1368 #define bhnd_bus_write_1(r, o, v) \ 1369 ((r)->direct) ? \ 1370 bus_write_1((r)->res, (o), (v)) : \ 1371 BHND_BUS_WRITE_1( \ 1372 device_get_parent(rman_get_device((r)->res)), \ 1373 rman_get_device((r)->res), (r), (o), (v)) 1374 #define bhnd_bus_write_multi_1(r, o, d, c) \ 1375 ((r)->direct) ? \ 1376 bus_write_multi_1((r)->res, (o), (d), (c)) : \ 1377 BHND_BUS_WRITE_MULTI_1( \ 1378 device_get_parent(rman_get_device((r)->res)), \ 1379 rman_get_device((r)->res), (r), (o), (d), (c)) 1380 #define bhnd_bus_write_region_1(r, o, d, c) \ 1381 ((r)->direct) ? \ 1382 bus_write_region_1((r)->res, (o), (d), (c)) : \ 1383 BHND_BUS_WRITE_REGION_1( \ 1384 device_get_parent(rman_get_device((r)->res)), \ 1385 rman_get_device((r)->res), (r), (o), (d), (c)) 1386 #define bhnd_bus_read_stream_1(r, o) \ 1387 ((r)->direct) ? \ 1388 bus_read_stream_1((r)->res, (o)) : \ 1389 BHND_BUS_READ_STREAM_1( \ 1390 device_get_parent(rman_get_device((r)->res)), \ 1391 rman_get_device((r)->res), (r), (o)) 1392 #define bhnd_bus_read_multi_stream_1(r, o, d, c) \ 1393 ((r)->direct) ? \ 1394 bus_read_multi_stream_1((r)->res, (o), (d), (c)) : \ 1395 BHND_BUS_READ_MULTI_STREAM_1( \ 1396 device_get_parent(rman_get_device((r)->res)), \ 1397 rman_get_device((r)->res), (r), (o), (d), (c)) 1398 #define bhnd_bus_read_region_stream_1(r, o, d, c) \ 1399 ((r)->direct) ? \ 1400 bus_read_region_stream_1((r)->res, (o), (d), (c)) : \ 1401 BHND_BUS_READ_REGION_STREAM_1( \ 1402 device_get_parent(rman_get_device((r)->res)), \ 1403 rman_get_device((r)->res), (r), (o), (d), (c)) 1404 #define bhnd_bus_write_stream_1(r, o, v) \ 1405 ((r)->direct) ? \ 1406 bus_write_stream_1((r)->res, (o), (v)) : \ 1407 BHND_BUS_WRITE_STREAM_1( \ 1408 device_get_parent(rman_get_device((r)->res)), \ 1409 rman_get_device((r)->res), (r), (o), (v)) 1410 #define bhnd_bus_write_multi_stream_1(r, o, d, c) \ 1411 ((r)->direct) ? \ 1412 bus_write_multi_stream_1((r)->res, (o), (d), (c)) : \ 1413 BHND_BUS_WRITE_MULTI_STREAM_1( \ 1414 device_get_parent(rman_get_device((r)->res)), \ 1415 rman_get_device((r)->res), (r), (o), (d), (c)) 1416 #define bhnd_bus_write_region_stream_1(r, o, d, c) \ 1417 ((r)->direct) ? \ 1418 bus_write_region_stream_1((r)->res, (o), (d), (c)) : \ 1419 BHND_BUS_WRITE_REGION_STREAM_1( \ 1420 device_get_parent(rman_get_device((r)->res)), \ 1421 rman_get_device((r)->res), (r), (o), (d), (c)) 1422 #define bhnd_bus_set_multi_1(r, o, v, c) \ 1423 ((r)->direct) ? \ 1424 bus_set_multi_1((r)->res, (o), (v), (c)) : \ 1425 BHND_BUS_SET_MULTI_1( \ 1426 device_get_parent(rman_get_device((r)->res)), \ 1427 rman_get_device((r)->res), (r), (o), (v), (c)) 1428 #define bhnd_bus_set_region_1(r, o, v, c) \ 1429 ((r)->direct) ? \ 1430 bus_set_region_1((r)->res, (o), (v), (c)) : \ 1431 BHND_BUS_SET_REGION_1( \ 1432 device_get_parent(rman_get_device((r)->res)), \ 1433 rman_get_device((r)->res), (r), (o), (v), (c)) 1434 #define bhnd_bus_read_2(r, o) \ 1435 ((r)->direct) ? \ 1436 bus_read_2((r)->res, (o)) : \ 1437 BHND_BUS_READ_2( \ 1438 device_get_parent(rman_get_device((r)->res)), \ 1439 rman_get_device((r)->res), (r), (o)) 1440 #define bhnd_bus_read_multi_2(r, o, d, c) \ 1441 ((r)->direct) ? \ 1442 bus_read_multi_2((r)->res, (o), (d), (c)) : \ 1443 BHND_BUS_READ_MULTI_2( \ 1444 device_get_parent(rman_get_device((r)->res)), \ 1445 rman_get_device((r)->res), (r), (o), (d), (c)) 1446 #define bhnd_bus_read_region_2(r, o, d, c) \ 1447 ((r)->direct) ? \ 1448 bus_read_region_2((r)->res, (o), (d), (c)) : \ 1449 BHND_BUS_READ_REGION_2( \ 1450 device_get_parent(rman_get_device((r)->res)), \ 1451 rman_get_device((r)->res), (r), (o), (d), (c)) 1452 #define bhnd_bus_write_2(r, o, v) \ 1453 ((r)->direct) ? \ 1454 bus_write_2((r)->res, (o), (v)) : \ 1455 BHND_BUS_WRITE_2( \ 1456 device_get_parent(rman_get_device((r)->res)), \ 1457 rman_get_device((r)->res), (r), (o), (v)) 1458 #define bhnd_bus_write_multi_2(r, o, d, c) \ 1459 ((r)->direct) ? \ 1460 bus_write_multi_2((r)->res, (o), (d), (c)) : \ 1461 BHND_BUS_WRITE_MULTI_2( \ 1462 device_get_parent(rman_get_device((r)->res)), \ 1463 rman_get_device((r)->res), (r), (o), (d), (c)) 1464 #define bhnd_bus_write_region_2(r, o, d, c) \ 1465 ((r)->direct) ? \ 1466 bus_write_region_2((r)->res, (o), (d), (c)) : \ 1467 BHND_BUS_WRITE_REGION_2( \ 1468 device_get_parent(rman_get_device((r)->res)), \ 1469 rman_get_device((r)->res), (r), (o), (d), (c)) 1470 #define bhnd_bus_read_stream_2(r, o) \ 1471 ((r)->direct) ? \ 1472 bus_read_stream_2((r)->res, (o)) : \ 1473 BHND_BUS_READ_STREAM_2( \ 1474 device_get_parent(rman_get_device((r)->res)), \ 1475 rman_get_device((r)->res), (r), (o)) 1476 #define bhnd_bus_read_multi_stream_2(r, o, d, c) \ 1477 ((r)->direct) ? \ 1478 bus_read_multi_stream_2((r)->res, (o), (d), (c)) : \ 1479 BHND_BUS_READ_MULTI_STREAM_2( \ 1480 device_get_parent(rman_get_device((r)->res)), \ 1481 rman_get_device((r)->res), (r), (o), (d), (c)) 1482 #define bhnd_bus_read_region_stream_2(r, o, d, c) \ 1483 ((r)->direct) ? \ 1484 bus_read_region_stream_2((r)->res, (o), (d), (c)) : \ 1485 BHND_BUS_READ_REGION_STREAM_2( \ 1486 device_get_parent(rman_get_device((r)->res)), \ 1487 rman_get_device((r)->res), (r), (o), (d), (c)) 1488 #define bhnd_bus_write_stream_2(r, o, v) \ 1489 ((r)->direct) ? \ 1490 bus_write_stream_2((r)->res, (o), (v)) : \ 1491 BHND_BUS_WRITE_STREAM_2( \ 1492 device_get_parent(rman_get_device((r)->res)), \ 1493 rman_get_device((r)->res), (r), (o), (v)) 1494 #define bhnd_bus_write_multi_stream_2(r, o, d, c) \ 1495 ((r)->direct) ? \ 1496 bus_write_multi_stream_2((r)->res, (o), (d), (c)) : \ 1497 BHND_BUS_WRITE_MULTI_STREAM_2( \ 1498 device_get_parent(rman_get_device((r)->res)), \ 1499 rman_get_device((r)->res), (r), (o), (d), (c)) 1500 #define bhnd_bus_write_region_stream_2(r, o, d, c) \ 1501 ((r)->direct) ? \ 1502 bus_write_region_stream_2((r)->res, (o), (d), (c)) : \ 1503 BHND_BUS_WRITE_REGION_STREAM_2( \ 1504 device_get_parent(rman_get_device((r)->res)), \ 1505 rman_get_device((r)->res), (r), (o), (d), (c)) 1506 #define bhnd_bus_set_multi_2(r, o, v, c) \ 1507 ((r)->direct) ? \ 1508 bus_set_multi_2((r)->res, (o), (v), (c)) : \ 1509 BHND_BUS_SET_MULTI_2( \ 1510 device_get_parent(rman_get_device((r)->res)), \ 1511 rman_get_device((r)->res), (r), (o), (v), (c)) 1512 #define bhnd_bus_set_region_2(r, o, v, c) \ 1513 ((r)->direct) ? \ 1514 bus_set_region_2((r)->res, (o), (v), (c)) : \ 1515 BHND_BUS_SET_REGION_2( \ 1516 device_get_parent(rman_get_device((r)->res)), \ 1517 rman_get_device((r)->res), (r), (o), (v), (c)) 1518 #define bhnd_bus_read_4(r, o) \ 1519 ((r)->direct) ? \ 1520 bus_read_4((r)->res, (o)) : \ 1521 BHND_BUS_READ_4( \ 1522 device_get_parent(rman_get_device((r)->res)), \ 1523 rman_get_device((r)->res), (r), (o)) 1524 #define bhnd_bus_read_multi_4(r, o, d, c) \ 1525 ((r)->direct) ? \ 1526 bus_read_multi_4((r)->res, (o), (d), (c)) : \ 1527 BHND_BUS_READ_MULTI_4( \ 1528 device_get_parent(rman_get_device((r)->res)), \ 1529 rman_get_device((r)->res), (r), (o), (d), (c)) 1530 #define bhnd_bus_read_region_4(r, o, d, c) \ 1531 ((r)->direct) ? \ 1532 bus_read_region_4((r)->res, (o), (d), (c)) : \ 1533 BHND_BUS_READ_REGION_4( \ 1534 device_get_parent(rman_get_device((r)->res)), \ 1535 rman_get_device((r)->res), (r), (o), (d), (c)) 1536 #define bhnd_bus_write_4(r, o, v) \ 1537 ((r)->direct) ? \ 1538 bus_write_4((r)->res, (o), (v)) : \ 1539 BHND_BUS_WRITE_4( \ 1540 device_get_parent(rman_get_device((r)->res)), \ 1541 rman_get_device((r)->res), (r), (o), (v)) 1542 #define bhnd_bus_write_multi_4(r, o, d, c) \ 1543 ((r)->direct) ? \ 1544 bus_write_multi_4((r)->res, (o), (d), (c)) : \ 1545 BHND_BUS_WRITE_MULTI_4( \ 1546 device_get_parent(rman_get_device((r)->res)), \ 1547 rman_get_device((r)->res), (r), (o), (d), (c)) 1548 #define bhnd_bus_write_region_4(r, o, d, c) \ 1549 ((r)->direct) ? \ 1550 bus_write_region_4((r)->res, (o), (d), (c)) : \ 1551 BHND_BUS_WRITE_REGION_4( \ 1552 device_get_parent(rman_get_device((r)->res)), \ 1553 rman_get_device((r)->res), (r), (o), (d), (c)) 1554 #define bhnd_bus_read_stream_4(r, o) \ 1555 ((r)->direct) ? \ 1556 bus_read_stream_4((r)->res, (o)) : \ 1557 BHND_BUS_READ_STREAM_4( \ 1558 device_get_parent(rman_get_device((r)->res)), \ 1559 rman_get_device((r)->res), (r), (o)) 1560 #define bhnd_bus_read_multi_stream_4(r, o, d, c) \ 1561 ((r)->direct) ? \ 1562 bus_read_multi_stream_4((r)->res, (o), (d), (c)) : \ 1563 BHND_BUS_READ_MULTI_STREAM_4( \ 1564 device_get_parent(rman_get_device((r)->res)), \ 1565 rman_get_device((r)->res), (r), (o), (d), (c)) 1566 #define bhnd_bus_read_region_stream_4(r, o, d, c) \ 1567 ((r)->direct) ? \ 1568 bus_read_region_stream_4((r)->res, (o), (d), (c)) : \ 1569 BHND_BUS_READ_REGION_STREAM_4( \ 1570 device_get_parent(rman_get_device((r)->res)), \ 1571 rman_get_device((r)->res), (r), (o), (d), (c)) 1572 #define bhnd_bus_write_stream_4(r, o, v) \ 1573 ((r)->direct) ? \ 1574 bus_write_stream_4((r)->res, (o), (v)) : \ 1575 BHND_BUS_WRITE_STREAM_4( \ 1576 device_get_parent(rman_get_device((r)->res)), \ 1577 rman_get_device((r)->res), (r), (o), (v)) 1578 #define bhnd_bus_write_multi_stream_4(r, o, d, c) \ 1579 ((r)->direct) ? \ 1580 bus_write_multi_stream_4((r)->res, (o), (d), (c)) : \ 1581 BHND_BUS_WRITE_MULTI_STREAM_4( \ 1582 device_get_parent(rman_get_device((r)->res)), \ 1583 rman_get_device((r)->res), (r), (o), (d), (c)) 1584 #define bhnd_bus_write_region_stream_4(r, o, d, c) \ 1585 ((r)->direct) ? \ 1586 bus_write_region_stream_4((r)->res, (o), (d), (c)) : \ 1587 BHND_BUS_WRITE_REGION_STREAM_4( \ 1588 device_get_parent(rman_get_device((r)->res)), \ 1589 rman_get_device((r)->res), (r), (o), (d), (c)) 1590 #define bhnd_bus_set_multi_4(r, o, v, c) \ 1591 ((r)->direct) ? \ 1592 bus_set_multi_4((r)->res, (o), (v), (c)) : \ 1593 BHND_BUS_SET_MULTI_4( \ 1594 device_get_parent(rman_get_device((r)->res)), \ 1595 rman_get_device((r)->res), (r), (o), (v), (c)) 1596 #define bhnd_bus_set_region_4(r, o, v, c) \ 1597 ((r)->direct) ? \ 1598 bus_set_region_4((r)->res, (o), (v), (c)) : \ 1599 BHND_BUS_SET_REGION_4( \ 1600 device_get_parent(rman_get_device((r)->res)), \ 1601 rman_get_device((r)->res), (r), (o), (v), (c)) 1602 1603 #endif /* _BHND_BHND_H_ */ 1604