]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/bhnd/bhnd.h
[bhnd] Add logging macros to BHND.
[FreeBSD/FreeBSD.git] / sys / dev / bhnd / bhnd.h
1 /*-
2  * Copyright (c) 2015 Landon Fuller <landon@landonf.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13  *    redistribution must be conditioned upon including a substantially
14  *    similar Disclaimer requirement for further binary redistribution.
15  *
16  * NO WARRANTY
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21  * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27  * THE POSSIBILITY OF SUCH DAMAGES.
28  * 
29  * $FreeBSD$
30  */
31
32 #ifndef _BHND_BHND_H_
33 #define _BHND_BHND_H_
34
35 #include <sys/types.h>
36 #include <sys/bus.h>
37
38 #include <machine/bus.h>
39
40 #include "bhnd_ids.h"
41 #include "bhnd_types.h"
42 #include "bhnd_debug.h"
43 #include "bhnd_bus_if.h"
44
45 extern devclass_t bhnd_devclass;
46 extern devclass_t bhnd_hostb_devclass;
47 extern devclass_t bhnd_nvram_devclass;
48
49 /**
50  * bhnd child instance variables
51  */
52 enum bhnd_device_vars {
53         BHND_IVAR_VENDOR,       /**< Designer's JEP-106 manufacturer ID. */
54         BHND_IVAR_DEVICE,       /**< Part number */
55         BHND_IVAR_HWREV,        /**< Core revision */
56         BHND_IVAR_DEVICE_CLASS, /**< Core class (@sa bhnd_devclass_t) */
57         BHND_IVAR_VENDOR_NAME,  /**< Core vendor name */
58         BHND_IVAR_DEVICE_NAME,  /**< Core name */
59         BHND_IVAR_CORE_INDEX,   /**< Bus-assigned core number */
60         BHND_IVAR_CORE_UNIT,    /**< Bus-assigned core unit number,
61                                      assigned sequentially (starting at 0) for
62                                      each vendor/device pair. */
63 };
64
65 /**
66  * bhnd device probe priority bands.
67  */
68 enum {
69         BHND_PROBE_ROOT         = 0,    /**< Nexus or host bridge */
70         BHND_PROBE_BUS          = 1000, /**< Busses and bridges */
71         BHND_PROBE_CPU          = 2000, /**< CPU devices */
72         BHND_PROBE_INTERRUPT    = 3000, /**< Interrupt controllers. */
73         BHND_PROBE_TIMER        = 4000, /**< Timers and clocks. */
74         BHND_PROBE_RESOURCE     = 5000, /**< Resource discovery (including NVRAM/SPROM) */
75         BHND_PROBE_DEFAULT      = 6000, /**< Default device priority */
76 };
77
78 /**
79  * Constants defining fine grained ordering within a BHND_PROBE_* priority band.
80  * 
81  * Example:
82  * @code
83  * BHND_PROBE_BUS + BHND_PROBE_ORDER_FIRST
84  * @endcode
85  */
86 enum {
87         BHND_PROBE_ORDER_FIRST          = 0,
88         BHND_PROBE_ORDER_EARLY          = 25,
89         BHND_PROBE_ORDER_MIDDLE         = 50,
90         BHND_PROBE_ORDER_LATE           = 75,
91         BHND_PROBE_ORDER_LAST           = 100
92
93 };
94
95 /*
96  * Simplified accessors for bhnd device ivars
97  */
98 #define BHND_ACCESSOR(var, ivar, type) \
99         __BUS_ACCESSOR(bhnd, var, BHND, ivar, type)
100
101 BHND_ACCESSOR(vendor,           VENDOR,         uint16_t);
102 BHND_ACCESSOR(device,           DEVICE,         uint16_t);
103 BHND_ACCESSOR(hwrev,            HWREV,          uint8_t);
104 BHND_ACCESSOR(class,            DEVICE_CLASS,   bhnd_devclass_t);
105 BHND_ACCESSOR(vendor_name,      VENDOR_NAME,    const char *);
106 BHND_ACCESSOR(device_name,      DEVICE_NAME,    const char *);
107 BHND_ACCESSOR(core_index,       CORE_INDEX,     u_int);
108 BHND_ACCESSOR(core_unit,        CORE_UNIT,      int);
109
110 #undef  BHND_ACCESSOR
111
112 /**
113  * Chip Identification
114  * 
115  * This is read from the ChipCommon ID register; on earlier bhnd(4) devices
116  * where ChipCommon is unavailable, known values must be supplied.
117  */
118 struct bhnd_chipid {
119         uint16_t        chip_id;        /**< chip id (BHND_CHIPID_*) */
120         uint8_t         chip_rev;       /**< chip revision */
121         uint8_t         chip_pkg;       /**< chip package (BHND_PKGID_*) */
122         uint8_t         chip_type;      /**< chip type (BHND_CHIPTYPE_*) */
123
124         bhnd_addr_t     enum_addr;      /**< chip_type-specific enumeration
125                                           *  address; either the siba(4) base
126                                           *  core register block, or the bcma(4)
127                                           *  EROM core address. */
128
129         uint8_t         ncores;         /**< number of cores, if known. 0 if
130                                           *  not available. */
131 };
132
133 /**
134 * A bhnd(4) bus resource.
135
136 * This provides an abstract interface to per-core resources that may require
137 * bus-level remapping of address windows prior to access.
138 */
139 struct bhnd_resource {
140         struct resource *res;           /**< the system resource. */
141         bool             direct;        /**< false if the resource requires
142                                          *   bus window remapping before it
143                                          *   is MMIO accessible. */
144 };
145
146 /**
147  * A bhnd(4) core descriptor.
148  */
149 struct bhnd_core_info {
150         uint16_t        vendor;         /**< vendor */
151         uint16_t        device;         /**< device */
152         uint16_t        hwrev;          /**< hardware revision */
153         u_int           core_idx;       /**< bus-assigned core index */
154         int             unit;           /**< bus-assigned core unit */
155 };
156
157
158 /**
159  * A hardware revision match descriptor.
160  */
161 struct bhnd_hwrev_match {
162         uint16_t        start;  /**< first revision, or BHND_HWREV_INVALID
163                                              to match on any revision. */
164         uint16_t        end;    /**< last revision, or BHND_HWREV_INVALID
165                                              to match on any revision. */
166 };
167
168 /** 
169  * Wildcard hardware revision match descriptor.
170  */
171 #define BHND_HWREV_ANY          { BHND_HWREV_INVALID, BHND_HWREV_INVALID }
172 #define BHND_HWREV_IS_ANY(_m)   \
173         ((_m)->start == BHND_HWREV_INVALID && (_m)->end == BHND_HWREV_INVALID)
174
175 /**
176  * Hardware revision match descriptor for an inclusive range.
177  * 
178  * @param _start The first applicable hardware revision.
179  * @param _end The last applicable hardware revision, or BHND_HWREV_INVALID
180  * to match on any revision.
181  */
182 #define BHND_HWREV_RANGE(_start, _end)  { _start, _end }
183
184 /**
185  * Hardware revision match descriptor for a single revision.
186  * 
187  * @param _hwrev The hardware revision to match on.
188  */
189 #define BHND_HWREV_EQ(_hwrev)   BHND_HWREV_RANGE(_hwrev, _hwrev)
190
191 /**
192  * Hardware revision match descriptor for any revision equal to or greater
193  * than @p _start.
194  * 
195  * @param _start The first hardware revision to match on.
196  */
197 #define BHND_HWREV_GTE(_start)  BHND_HWREV_RANGE(_start, BHND_HWREV_INVALID)
198
199 /**
200  * Hardware revision match descriptor for any revision equal to or less
201  * than @p _end.
202  * 
203  * @param _end The last hardware revision to match on.
204  */
205 #define BHND_HWREV_LTE(_end)    BHND_HWREV_RANGE(0, _end)
206
207
208 /** A core match descriptor. */
209 struct bhnd_core_match {
210         uint16_t                vendor; /**< required JEP106 device vendor or BHND_MFGID_INVALID. */
211         uint16_t                device; /**< required core ID or BHND_COREID_INVALID */
212         struct bhnd_hwrev_match hwrev;  /**< matching revisions. */
213         bhnd_devclass_t         class;  /**< required class or BHND_DEVCLASS_INVALID */
214         int                     unit;   /**< required core unit, or -1 */
215 };
216
217 /**
218  * Core match descriptor matching against the given @p _vendor, @p _device,
219  * and @p _hwrev match descriptors.
220  */
221 #define BHND_CORE_MATCH(_vendor, _device, _hwrev)       \
222         { _vendor, _device, _hwrev, BHND_DEVCLASS_INVALID, -1 }
223
224 /** 
225  * Wildcard core match descriptor.
226  */
227 #define BHND_CORE_MATCH_ANY                     \
228         {                                       \
229                 .vendor = BHND_MFGID_INVALID,   \
230                 .device = BHND_COREID_INVALID,  \
231                 .hwrev = BHND_HWREV_ANY,        \
232                 .class = BHND_DEVCLASS_INVALID, \
233                 .unit = -1                      \
234         }
235
236 /** A chipset match descriptor. */
237 struct bhnd_chip_match {
238         /** Select fields to be matched */
239         uint8_t
240                 match_id:1,
241                 match_rev:1,
242                 match_pkg:1,
243                 match_flags_unused:5;
244
245         uint16_t                chip_id;        /**< required chip id */
246         struct bhnd_hwrev_match chip_rev;       /**< matching chip revisions */
247         uint8_t                 chip_pkg;       /**< required package */
248 };
249
250 #define BHND_CHIP_MATCH_ANY             \
251         { .match_id = 0, .match_rev = 0, .match_pkg = 0 }
252
253 #define BHND_CHIP_MATCH_IS_ANY(_m)      \
254         ((_m)->match_id == 0 && (_m)->match_rev == 0 && (_m)->match_pkg == 0)
255
256 /** Set the required chip ID within a bhnd_chip_match instance */
257 #define BHND_CHIP_ID(_cid)              \
258         .match_id = 1, .chip_id = BHND_CHIPID_BCM ## _cid
259
260 /** Set the required revision range within a bhnd_chip_match instance */
261 #define BHND_CHIP_REV(_rev)             \
262         .match_rev = 1, .chip_rev = BHND_ ## _rev
263
264 /** Set the required package ID within a bhnd_chip_match instance */
265 #define BHND_CHIP_PKG(_pkg)             \
266         .match_pkg = 1, .chip_pkg = BHND_PKGID_BCM ## _pkg
267
268 /** Set the required chip and package ID within a bhnd_chip_match instance */
269 #define BHND_CHIP_IP(_cid, _pkg)        \
270         BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg)
271
272 /** Set the required chip ID, package ID, and revision within a bhnd_chip_match
273  *  instance */
274 #define BHND_CHIP_IPR(_cid, _pkg, _rev) \
275         BHND_CHIP_ID(_cid), BHND_CHIP_PKG(_pkg), BHND_CHIP_REV(_rev)
276
277 /** Set the required chip ID and revision within a bhnd_chip_match
278  *  instance */
279 #define BHND_CHIP_IR(_cid, _rev)        \
280         BHND_CHIP_ID(_cid), BHND_CHIP_REV(_rev)
281
282 /**
283  * Chipset quirk table descriptor.
284  */
285 struct bhnd_chip_quirk {
286         const struct bhnd_chip_match     chip;          /**< chip match descriptor */ 
287         uint32_t                         quirks;        /**< quirk flags */
288 };
289
290 #define BHND_CHIP_QUIRK_END     { BHND_CHIP_MATCH_ANY, 0 }
291
292 #define BHND_CHIP_QUIRK_IS_END(_q)      \
293         (BHND_CHIP_MATCH_IS_ANY(&(_q)->chip) && (_q)->quirks == 0)
294
295 /**
296  * Device quirk table descriptor.
297  */
298 struct bhnd_device_quirk {
299         struct bhnd_hwrev_match  hwrev;         /**< applicable hardware revisions */
300         uint32_t                 quirks;        /**< quirk flags */
301 };
302 #define BHND_DEVICE_QUIRK_END           { BHND_HWREV_ANY, 0 }
303 #define BHND_DEVICE_QUIRK_IS_END(_q)    \
304         (BHND_HWREV_IS_ANY(&(_q)->hwrev) && (_q)->quirks == 0)
305
306 enum {
307         BHND_DF_ANY     = 0,
308         BHND_DF_HOSTB   = (1<<0)        /**< core is serving as the bus'
309                                           *  host bridge */
310 };
311
312 /** Device probe table descriptor */
313 struct bhnd_device {
314         const struct bhnd_core_match     core;                  /**< core match descriptor */ 
315         const char                      *desc;                  /**< device description, or NULL. */
316         const struct bhnd_device_quirk  *quirks_table;          /**< quirks table for this device, or NULL */
317         uint32_t                         device_flags;          /**< required BHND_DF_* flags */
318 };
319
320 #define _BHND_DEVICE(_vendor, _device, _desc, _quirks, _flags, ...)     \
321         { BHND_CORE_MATCH(BHND_MFGID_ ## _vendor, BHND_COREID_ ## _device, \
322             BHND_HWREV_ANY), _desc, _quirks, _flags }
323
324 #define BHND_MIPS_DEVICE(_device, _desc, _quirks, ...)  \
325         _BHND_DEVICE(MIPS, _device, _desc, _quirks, ## __VA_ARGS__, 0)
326
327 #define BHND_ARM_DEVICE(_device, _desc, _quirks, ...)   \
328         _BHND_DEVICE(ARM, _device, _desc, _quirks, ## __VA_ARGS__, 0)
329
330 #define BHND_DEVICE(_device, _desc, _quirks, ...)       \
331         _BHND_DEVICE(BCM, _device, _desc, _quirks, ## __VA_ARGS__, 0)
332
333 #define BHND_DEVICE_END                 { BHND_CORE_MATCH_ANY, NULL, NULL, 0 }
334
335 const char                      *bhnd_vendor_name(uint16_t vendor);
336 const char                      *bhnd_port_type_name(bhnd_port_type port_type);
337
338 const char                      *bhnd_find_core_name(uint16_t vendor,
339                                      uint16_t device);
340 bhnd_devclass_t                  bhnd_find_core_class(uint16_t vendor,
341                                      uint16_t device);
342
343 const char                      *bhnd_core_name(const struct bhnd_core_info *ci);
344 bhnd_devclass_t                  bhnd_core_class(const struct bhnd_core_info *ci);
345
346
347 device_t                         bhnd_match_child(device_t dev,
348                                      const struct bhnd_core_match *desc);
349
350 device_t                         bhnd_find_child(device_t dev,
351                                      bhnd_devclass_t class, int unit);
352
353 const struct bhnd_core_info     *bhnd_match_core(
354                                      const struct bhnd_core_info *cores,
355                                      u_int num_cores,
356                                      const struct bhnd_core_match *desc);
357
358 const struct bhnd_core_info     *bhnd_find_core(
359                                      const struct bhnd_core_info *cores,
360                                      u_int num_cores, bhnd_devclass_t class);
361
362 bool                             bhnd_core_matches(
363                                      const struct bhnd_core_info *core,
364                                      const struct bhnd_core_match *desc);
365
366 bool                             bhnd_chip_matches(
367                                      const struct bhnd_chipid *chipid,
368                                      const struct bhnd_chip_match *desc);
369
370 bool                             bhnd_hwrev_matches(uint16_t hwrev,
371                                      const struct bhnd_hwrev_match *desc);
372
373 uint32_t                         bhnd_chip_quirks(device_t dev,
374                                      const struct bhnd_chip_quirk *table);
375
376 bool                             bhnd_device_matches(device_t dev,
377                                      const struct bhnd_core_match *desc);
378
379 const struct bhnd_device        *bhnd_device_lookup(device_t dev,
380                                      const struct bhnd_device *table,
381                                      size_t entry_size);
382
383 uint32_t                         bhnd_device_quirks(device_t dev,
384                                      const struct bhnd_device *table,
385                                      size_t entry_size);
386
387 struct bhnd_core_info            bhnd_get_core_info(device_t dev);
388
389
390 int                              bhnd_alloc_resources(device_t dev,
391                                      struct resource_spec *rs,
392                                      struct bhnd_resource **res);
393
394 void                             bhnd_release_resources(device_t dev,
395                                      const struct resource_spec *rs,
396                                      struct bhnd_resource **res);
397
398 struct bhnd_chipid               bhnd_parse_chipid(uint32_t idreg,
399                                      bhnd_addr_t enum_addr);
400
401 int                              bhnd_read_chipid(device_t dev,
402                                      struct resource_spec *rs,
403                                      bus_size_t chipc_offset,
404                                      struct bhnd_chipid *result);
405
406 void                             bhnd_set_custom_core_desc(device_t dev,
407                                      const char *name);
408 void                             bhnd_set_default_core_desc(device_t dev);
409
410
411 bool                             bhnd_bus_generic_is_hw_disabled(device_t dev,
412                                      device_t child);
413 bool                             bhnd_bus_generic_is_region_valid(device_t dev,
414                                      device_t child, bhnd_port_type type,
415                                      u_int port, u_int region);
416 int                              bhnd_bus_generic_read_nvram_var(device_t dev,
417                                      device_t child, const char *name,
418                                      void *buf, size_t *size);
419 const struct bhnd_chipid        *bhnd_bus_generic_get_chipid(device_t dev,
420                                      device_t child);
421 struct bhnd_resource            *bhnd_bus_generic_alloc_resource (device_t dev,
422                                      device_t child, int type, int *rid,
423                                      rman_res_t start, rman_res_t end,
424                                      rman_res_t count, u_int flags);
425 int                              bhnd_bus_generic_release_resource (device_t dev,
426                                      device_t child, int type, int rid,
427                                      struct bhnd_resource *r);
428 int                              bhnd_bus_generic_activate_resource (device_t dev,
429                                      device_t child, int type, int rid,
430                                      struct bhnd_resource *r);
431 int                              bhnd_bus_generic_deactivate_resource (device_t dev,
432                                      device_t child, int type, int rid,
433                                      struct bhnd_resource *r);
434
435
436
437 /**
438  * Return the active host bridge core for the bhnd bus, if any, or NULL if
439  * not found.
440  *
441  * @param dev A bhnd bus device.
442  */
443 static inline device_t
444 bhnd_find_hostb_device(device_t dev) {
445         return (BHND_BUS_FIND_HOSTB_DEVICE(dev));
446 }
447
448 /**
449  * Return true if the hardware components required by @p dev are known to be
450  * unpopulated or otherwise unusable.
451  *
452  * In some cases, enumerated devices may have pins that are left floating, or
453  * the hardware may otherwise be non-functional; this method allows a parent
454  * device to explicitly specify if a successfully enumerated @p dev should
455  * be disabled.
456  *
457  * @param dev A bhnd bus child device.
458  */
459 static inline bool
460 bhnd_is_hw_disabled(device_t dev) {
461         return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), dev));
462 }
463
464 /**
465  * Return the BHND chip identification info for the bhnd bus.
466  *
467  * @param dev A bhnd bus child device.
468  */
469 static inline const struct bhnd_chipid *
470 bhnd_get_chipid(device_t dev) {
471         return (BHND_BUS_GET_CHIPID(device_get_parent(dev), dev));
472 };
473
474 /**
475  * Determine an NVRAM variable's expected size.
476  *
477  * @param       dev     A bhnd bus child device.
478  * @param       name    The variable name.
479  * @param[out]  len     On success, the variable's size, in bytes.
480  *
481  * @retval 0            success
482  * @retval ENOENT       The requested variable was not found.
483  * @retval non-zero     If reading @p name otherwise fails, a regular unix
484  *                      error code will be returned.
485  */
486 static inline int
487 bhnd_nvram_getvarlen(device_t dev, const char *name, size_t *len)
488 {
489         return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, NULL,
490             len));
491 }
492
493 /**
494  * Read an NVRAM variable.
495  *
496  * @param       dev     A bhnd bus child device.
497  * @param       name    The NVRAM variable name.
498  * @param       buf     A buffer large enough to hold @p len bytes. On success,
499  *                      the requested value will be written to this buffer.
500  * @param       len     The required variable length.
501  *
502  * @retval 0            success
503  * @retval ENOENT       The requested variable was not found.
504  * @retval EINVAL       If @p len does not match the actual variable size.
505  * @retval non-zero     If reading @p name otherwise fails, a regular unix
506  *                      error code will be returned.
507  */
508 static inline int
509 bhnd_nvram_getvar(device_t dev, const char *name, void *buf, size_t len)
510 {
511         size_t  var_len;
512         int     error;
513
514         if ((error = bhnd_nvram_getvarlen(dev, name, &var_len)))
515                 return (error);
516
517         if (len != var_len)
518                 return (EINVAL);
519
520         return (BHND_BUS_GET_NVRAM_VAR(device_get_parent(dev), dev, name, buf,
521             &len));
522 }
523
524 /**
525  * Allocate a resource from a device's parent bhnd(4) bus.
526  * 
527  * @param dev The device requesting resource ownership.
528  * @param type The type of resource to allocate. This may be any type supported
529  * by the standard bus APIs.
530  * @param rid The bus-specific handle identifying the resource being allocated.
531  * @param start The start address of the resource.
532  * @param end The end address of the resource.
533  * @param count The size of the resource.
534  * @param flags The flags for the resource to be allocated. These may be any
535  * values supported by the standard bus APIs.
536  * 
537  * To request the resource's default addresses, pass @p start and
538  * @p end values of @c 0 and @c ~0, respectively, and
539  * a @p count of @c 1.
540  * 
541  * @retval NULL The resource could not be allocated.
542  * @retval resource The allocated resource.
543  */
544 static inline struct bhnd_resource *
545 bhnd_alloc_resource(device_t dev, int type, int *rid, rman_res_t start,
546     rman_res_t end, rman_res_t count, u_int flags)
547 {
548         return BHND_BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, type, rid,
549             start, end, count, flags);
550 }
551
552
553 /**
554  * Allocate a resource from a device's parent bhnd(4) bus, using the
555  * resource's default start, end, and count values.
556  * 
557  * @param dev The device requesting resource ownership.
558  * @param type The type of resource to allocate. This may be any type supported
559  * by the standard bus APIs.
560  * @param rid The bus-specific handle identifying the resource being allocated.
561  * @param flags The flags for the resource to be allocated. These may be any
562  * values supported by the standard bus APIs.
563  * 
564  * @retval NULL The resource could not be allocated.
565  * @retval resource The allocated resource.
566  */
567 static inline struct bhnd_resource *
568 bhnd_alloc_resource_any(device_t dev, int type, int *rid, u_int flags)
569 {
570         return bhnd_alloc_resource(dev, type, rid, 0, ~0, 1, flags);
571 }
572
573 /**
574  * Activate a previously allocated bhnd resource.
575  *
576  * @param dev The device holding ownership of the allocated resource.
577  * @param type The type of the resource. 
578  * @param rid The bus-specific handle identifying the resource.
579  * @param r A pointer to the resource returned by bhnd_alloc_resource or
580  * BHND_BUS_ALLOC_RESOURCE.
581  * 
582  * @retval 0 success
583  * @retval non-zero an error occurred while activating the resource.
584  */
585 static inline int
586 bhnd_activate_resource(device_t dev, int type, int rid,
587    struct bhnd_resource *r)
588 {
589         return BHND_BUS_ACTIVATE_RESOURCE(device_get_parent(dev), dev, type,
590             rid, r);
591 }
592
593 /**
594  * Deactivate a previously activated bhnd resource.
595  *
596  * @param dev The device holding ownership of the activated resource.
597  * @param type The type of the resource. 
598  * @param rid The bus-specific handle identifying the resource.
599  * @param r A pointer to the resource returned by bhnd_alloc_resource or
600  * BHND_BUS_ALLOC_RESOURCE.
601  * 
602  * @retval 0 success
603  * @retval non-zero an error occurred while activating the resource.
604  */
605 static inline int
606 bhnd_deactivate_resource(device_t dev, int type, int rid,
607    struct bhnd_resource *r)
608 {
609         return BHND_BUS_DEACTIVATE_RESOURCE(device_get_parent(dev), dev, type,
610             rid, r);
611 }
612
613 /**
614  * Free a resource allocated by bhnd_alloc_resource().
615  *
616  * @param dev The device holding ownership of the resource.
617  * @param type The type of the resource. 
618  * @param rid The bus-specific handle identifying the resource.
619  * @param r A pointer to the resource returned by bhnd_alloc_resource or
620  * BHND_ALLOC_RESOURCE.
621  * 
622  * @retval 0 success
623  * @retval non-zero an error occurred while activating the resource.
624  */
625 static inline int
626 bhnd_release_resource(device_t dev, int type, int rid,
627    struct bhnd_resource *r)
628 {
629         return BHND_BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, type,
630             rid, r);
631 }
632
633 /**
634  * Return true if @p region_num is a valid region on @p port_num of
635  * @p type attached to @p dev.
636  *
637  * @param dev A bhnd bus child device.
638  * @param type The port type being queried.
639  * @param port_num The port number being queried.
640  * @param region_num The region number being queried.
641  */
642 static inline bool
643 bhnd_is_region_valid(device_t dev, bhnd_port_type type, u_int port_num,
644     u_int region_num)
645 {
646         return (BHND_BUS_IS_REGION_VALID(device_get_parent(dev), dev, type,
647             port_num, region_num));
648 }
649
650 /**
651  * Return the number of ports of type @p type attached to @p def.
652  *
653  * @param dev A bhnd bus child device.
654  * @param type The port type being queried.
655  */
656 static inline u_int
657 bhnd_get_port_count(device_t dev, bhnd_port_type type) {
658         return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), dev, type));
659 }
660
661 /**
662  * Return the number of memory regions mapped to @p child @p port of
663  * type @p type.
664  *
665  * @param dev A bhnd bus child device.
666  * @param port The port number being queried.
667  * @param type The port type being queried.
668  */
669 static inline u_int
670 bhnd_get_region_count(device_t dev, bhnd_port_type type, u_int port) {
671         return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), dev, type,
672             port));
673 }
674
675 /**
676  * Return the resource-ID for a memory region on the given device port.
677  *
678  * @param dev A bhnd bus child device.
679  * @param type The port type.
680  * @param port The port identifier.
681  * @param region The identifier of the memory region on @p port.
682  * 
683  * @retval int The RID for the given @p port and @p region on @p device.
684  * @retval -1 No such port/region found.
685  */
686 static inline int
687 bhnd_get_port_rid(device_t dev, bhnd_port_type type, u_int port, u_int region)
688 {
689         return BHND_BUS_GET_PORT_RID(device_get_parent(dev), dev, type, port,
690             region);
691 }
692
693 /**
694  * Decode a port / region pair on @p dev defined by @p rid.
695  *
696  * @param dev A bhnd bus child device.
697  * @param type The resource type.
698  * @param rid The resource identifier.
699  * @param[out] port_type The decoded port type.
700  * @param[out] port The decoded port identifier.
701  * @param[out] region The decoded region identifier.
702  *
703  * @retval 0 success
704  * @retval non-zero No matching port/region found.
705  */
706 static inline int
707 bhnd_decode_port_rid(device_t dev, int type, int rid, bhnd_port_type *port_type,
708     u_int *port, u_int *region)
709 {
710         return BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), dev, type, rid,
711             port_type, port, region);
712 }
713
714 /**
715  * Get the address and size of @p region on @p port.
716  *
717  * @param dev A bhnd bus child device.
718  * @param port_type The port type.
719  * @param port The port identifier.
720  * @param region The identifier of the memory region on @p port.
721  * @param[out] region_addr The region's base address.
722  * @param[out] region_size The region's size.
723  *
724  * @retval 0 success
725  * @retval non-zero No matching port/region found.
726  */
727 static inline int
728 bhnd_get_region_addr(device_t dev, bhnd_port_type port_type, u_int port,
729     u_int region, bhnd_addr_t *region_addr, bhnd_size_t *region_size)
730 {
731         return BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), dev, port_type,
732             port, region, region_addr, region_size);
733 }
734
735 /*
736  * bhnd bus-level equivalents of the bus_(read|write|set|barrier|...)
737  * macros (compatible with bhnd_resource).
738  *
739  * Generated with bhnd/tools/bus_macro.sh
740  */
741 #define bhnd_bus_barrier(r, o, l, f) \
742     ((r)->direct) ? \
743         bus_barrier((r)->res, (o), (l), (f)) : \
744         BHND_BUS_BARRIER( \
745             device_get_parent(rman_get_device((r)->res)),       \
746             rman_get_device((r)->res), (r), (o), (l), (f))
747 #define bhnd_bus_read_1(r, o) \
748     ((r)->direct) ? \
749         bus_read_1((r)->res, (o)) : \
750         BHND_BUS_READ_1( \
751             device_get_parent(rman_get_device((r)->res)),       \
752             rman_get_device((r)->res), (r), (o))
753 #define bhnd_bus_read_multi_1(r, o, d, c) \
754     ((r)->direct) ? \
755         bus_read_multi_1((r)->res, (o), (d), (c)) : \
756         BHND_BUS_READ_MULTI_1( \
757             device_get_parent(rman_get_device((r)->res)),       \
758             rman_get_device((r)->res), (r), (o), (d), (c))
759 #define bhnd_bus_write_1(r, o, v) \
760     ((r)->direct) ? \
761         bus_write_1((r)->res, (o), (v)) : \
762         BHND_BUS_WRITE_1( \
763             device_get_parent(rman_get_device((r)->res)),       \
764             rman_get_device((r)->res), (r), (o), (v))
765 #define bhnd_bus_write_multi_1(r, o, d, c) \
766     ((r)->direct) ? \
767         bus_write_multi_1((r)->res, (o), (d), (c)) : \
768         BHND_BUS_WRITE_MULTI_1( \
769             device_get_parent(rman_get_device((r)->res)),       \
770             rman_get_device((r)->res), (r), (o), (d), (c))
771 #define bhnd_bus_read_stream_1(r, o) \
772     ((r)->direct) ? \
773         bus_read_stream_1((r)->res, (o)) : \
774         BHND_BUS_READ_STREAM_1( \
775             device_get_parent(rman_get_device((r)->res)),       \
776             rman_get_device((r)->res), (r), (o))
777 #define bhnd_bus_read_multi_stream_1(r, o, d, c) \
778     ((r)->direct) ? \
779         bus_read_multi_stream_1((r)->res, (o), (d), (c)) : \
780         BHND_BUS_READ_MULTI_STREAM_1( \
781             device_get_parent(rman_get_device((r)->res)),       \
782             rman_get_device((r)->res), (r), (o), (d), (c))
783 #define bhnd_bus_write_stream_1(r, o, v) \
784     ((r)->direct) ? \
785         bus_write_stream_1((r)->res, (o), (v)) : \
786         BHND_BUS_WRITE_STREAM_1( \
787             device_get_parent(rman_get_device((r)->res)),       \
788             rman_get_device((r)->res), (r), (o), (v))
789 #define bhnd_bus_write_multi_stream_1(r, o, d, c) \
790     ((r)->direct) ? \
791         bus_write_multi_stream_1((r)->res, (o), (d), (c)) : \
792         BHND_BUS_WRITE_MULTI_STREAM_1( \
793             device_get_parent(rman_get_device((r)->res)),       \
794             rman_get_device((r)->res), (r), (o), (d), (c))
795 #define bhnd_bus_read_2(r, o) \
796     ((r)->direct) ? \
797         bus_read_2((r)->res, (o)) : \
798         BHND_BUS_READ_2( \
799             device_get_parent(rman_get_device((r)->res)),       \
800             rman_get_device((r)->res), (r), (o))
801 #define bhnd_bus_read_multi_2(r, o, d, c) \
802     ((r)->direct) ? \
803         bus_read_multi_2((r)->res, (o), (d), (c)) : \
804         BHND_BUS_READ_MULTI_2( \
805             device_get_parent(rman_get_device((r)->res)),       \
806             rman_get_device((r)->res), (r), (o), (d), (c))
807 #define bhnd_bus_write_2(r, o, v) \
808     ((r)->direct) ? \
809         bus_write_2((r)->res, (o), (v)) : \
810         BHND_BUS_WRITE_2( \
811             device_get_parent(rman_get_device((r)->res)),       \
812             rman_get_device((r)->res), (r), (o), (v))
813 #define bhnd_bus_write_multi_2(r, o, d, c) \
814     ((r)->direct) ? \
815         bus_write_multi_2((r)->res, (o), (d), (c)) : \
816         BHND_BUS_WRITE_MULTI_2( \
817             device_get_parent(rman_get_device((r)->res)),       \
818             rman_get_device((r)->res), (r), (o), (d), (c))
819 #define bhnd_bus_read_stream_2(r, o) \
820     ((r)->direct) ? \
821         bus_read_stream_2((r)->res, (o)) : \
822         BHND_BUS_READ_STREAM_2( \
823             device_get_parent(rman_get_device((r)->res)),       \
824             rman_get_device((r)->res), (r), (o))
825 #define bhnd_bus_read_multi_stream_2(r, o, d, c) \
826     ((r)->direct) ? \
827         bus_read_multi_stream_2((r)->res, (o), (d), (c)) : \
828         BHND_BUS_READ_MULTI_STREAM_2( \
829             device_get_parent(rman_get_device((r)->res)),       \
830             rman_get_device((r)->res), (r), (o), (d), (c))
831 #define bhnd_bus_write_stream_2(r, o, v) \
832     ((r)->direct) ? \
833         bus_write_stream_2((r)->res, (o), (v)) : \
834         BHND_BUS_WRITE_STREAM_2( \
835             device_get_parent(rman_get_device((r)->res)),       \
836             rman_get_device((r)->res), (r), (o), (v))
837 #define bhnd_bus_write_multi_stream_2(r, o, d, c) \
838     ((r)->direct) ? \
839         bus_write_multi_stream_2((r)->res, (o), (d), (c)) : \
840         BHND_BUS_WRITE_MULTI_STREAM_2( \
841             device_get_parent(rman_get_device((r)->res)),       \
842             rman_get_device((r)->res), (r), (o), (d), (c))
843 #define bhnd_bus_read_4(r, o) \
844     ((r)->direct) ? \
845         bus_read_4((r)->res, (o)) : \
846         BHND_BUS_READ_4( \
847             device_get_parent(rman_get_device((r)->res)),       \
848             rman_get_device((r)->res), (r), (o))
849 #define bhnd_bus_read_multi_4(r, o, d, c) \
850     ((r)->direct) ? \
851         bus_read_multi_4((r)->res, (o), (d), (c)) : \
852         BHND_BUS_READ_MULTI_4( \
853             device_get_parent(rman_get_device((r)->res)),       \
854             rman_get_device((r)->res), (r), (o), (d), (c))
855 #define bhnd_bus_write_4(r, o, v) \
856     ((r)->direct) ? \
857         bus_write_4((r)->res, (o), (v)) : \
858         BHND_BUS_WRITE_4( \
859             device_get_parent(rman_get_device((r)->res)),       \
860             rman_get_device((r)->res), (r), (o), (v))
861 #define bhnd_bus_write_multi_4(r, o, d, c) \
862     ((r)->direct) ? \
863         bus_write_multi_4((r)->res, (o), (d), (c)) : \
864         BHND_BUS_WRITE_MULTI_4( \
865             device_get_parent(rman_get_device((r)->res)),       \
866             rman_get_device((r)->res), (r), (o), (d), (c))
867 #define bhnd_bus_read_stream_4(r, o) \
868     ((r)->direct) ? \
869         bus_read_stream_4((r)->res, (o)) : \
870         BHND_BUS_READ_STREAM_4( \
871             device_get_parent(rman_get_device((r)->res)),       \
872             rman_get_device((r)->res), (r), (o))
873 #define bhnd_bus_read_multi_stream_4(r, o, d, c) \
874     ((r)->direct) ? \
875         bus_read_multi_stream_4((r)->res, (o), (d), (c)) : \
876         BHND_BUS_READ_MULTI_STREAM_4( \
877             device_get_parent(rman_get_device((r)->res)),       \
878             rman_get_device((r)->res), (r), (o), (d), (c))
879 #define bhnd_bus_write_stream_4(r, o, v) \
880     ((r)->direct) ? \
881         bus_write_stream_4((r)->res, (o), (v)) : \
882         BHND_BUS_WRITE_STREAM_4( \
883             device_get_parent(rman_get_device((r)->res)),       \
884             rman_get_device((r)->res), (r), (o), (v))
885 #define bhnd_bus_write_multi_stream_4(r, o, d, c) \
886     ((r)->direct) ? \
887         bus_write_multi_stream_4((r)->res, (o), (d), (c)) : \
888         BHND_BUS_WRITE_MULTI_STREAM_4( \
889             device_get_parent(rman_get_device((r)->res)),       \
890             rman_get_device((r)->res), (r), (o), (d), (c))
891
892 #endif /* _BHND_BHND_H_ */