bhnd.h revision 299990
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: head/sys/dev/bhnd/bhnd.h 299990 2016-05-16 23:40:32Z adrian $
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
45extern devclass_t bhnd_devclass;
46extern devclass_t bhnd_hostb_devclass;
47extern devclass_t bhnd_nvram_devclass;
48
49/**
50 * bhnd child instance variables
51 */
52enum 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 */
68enum {
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 */
86enum {
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
101BHND_ACCESSOR(vendor,		VENDOR,		uint16_t);
102BHND_ACCESSOR(device,		DEVICE,		uint16_t);
103BHND_ACCESSOR(hwrev,		HWREV,		uint8_t);
104BHND_ACCESSOR(class,		DEVICE_CLASS,	bhnd_devclass_t);
105BHND_ACCESSOR(vendor_name,	VENDOR_NAME,	const char *);
106BHND_ACCESSOR(device_name,	DEVICE_NAME,	const char *);
107BHND_ACCESSOR(core_index,	CORE_INDEX,	u_int);
108BHND_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 */
118struct 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*/
139struct 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 */
149struct 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 */
161struct 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. */
209struct 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. */
237struct 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 */
285struct 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 */
298struct 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
306enum {
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 */
313struct 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
335const char			*bhnd_vendor_name(uint16_t vendor);
336const char			*bhnd_port_type_name(bhnd_port_type port_type);
337
338const char 			*bhnd_find_core_name(uint16_t vendor,
339				     uint16_t device);
340bhnd_devclass_t			 bhnd_find_core_class(uint16_t vendor,
341				     uint16_t device);
342
343const char			*bhnd_core_name(const struct bhnd_core_info *ci);
344bhnd_devclass_t			 bhnd_core_class(const struct bhnd_core_info *ci);
345
346
347device_t			 bhnd_match_child(device_t dev,
348				     const struct bhnd_core_match *desc);
349
350device_t			 bhnd_find_child(device_t dev,
351				     bhnd_devclass_t class, int unit);
352
353const 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
358const struct bhnd_core_info	*bhnd_find_core(
359				     const struct bhnd_core_info *cores,
360				     u_int num_cores, bhnd_devclass_t class);
361
362bool				 bhnd_core_matches(
363				     const struct bhnd_core_info *core,
364				     const struct bhnd_core_match *desc);
365
366bool				 bhnd_chip_matches(
367				     const struct bhnd_chipid *chipid,
368				     const struct bhnd_chip_match *desc);
369
370bool				 bhnd_hwrev_matches(uint16_t hwrev,
371				     const struct bhnd_hwrev_match *desc);
372
373uint32_t			 bhnd_chip_quirks(device_t dev,
374				     const struct bhnd_chip_quirk *table);
375
376bool				 bhnd_device_matches(device_t dev,
377				     const struct bhnd_core_match *desc);
378
379const struct bhnd_device	*bhnd_device_lookup(device_t dev,
380				     const struct bhnd_device *table,
381				     size_t entry_size);
382
383uint32_t			 bhnd_device_quirks(device_t dev,
384				     const struct bhnd_device *table,
385				     size_t entry_size);
386
387struct bhnd_core_info		 bhnd_get_core_info(device_t dev);
388
389
390int				 bhnd_alloc_resources(device_t dev,
391				     struct resource_spec *rs,
392				     struct bhnd_resource **res);
393
394void				 bhnd_release_resources(device_t dev,
395				     const struct resource_spec *rs,
396				     struct bhnd_resource **res);
397
398struct bhnd_chipid		 bhnd_parse_chipid(uint32_t idreg,
399				     bhnd_addr_t enum_addr);
400
401int				 bhnd_read_chipid(device_t dev,
402				     struct resource_spec *rs,
403				     bus_size_t chipc_offset,
404				     struct bhnd_chipid *result);
405
406void				 bhnd_set_custom_core_desc(device_t dev,
407				     const char *name);
408void				 bhnd_set_default_core_desc(device_t dev);
409
410
411bool				 bhnd_bus_generic_is_hw_disabled(device_t dev,
412				     device_t child);
413bool				 bhnd_bus_generic_is_region_valid(device_t dev,
414				     device_t child, bhnd_port_type type,
415				     u_int port, u_int region);
416int				 bhnd_bus_generic_read_nvram_var(device_t dev,
417				     device_t child, const char *name,
418				     void *buf, size_t *size);
419const struct bhnd_chipid	*bhnd_bus_generic_get_chipid(device_t dev,
420				     device_t child);
421struct 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);
425int				 bhnd_bus_generic_release_resource (device_t dev,
426				     device_t child, int type, int rid,
427				     struct bhnd_resource *r);
428int				 bhnd_bus_generic_activate_resource (device_t dev,
429				     device_t child, int type, int rid,
430				     struct bhnd_resource *r);
431int				 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 */
443static inline device_t
444bhnd_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 */
459static inline bool
460bhnd_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 */
469static inline const struct bhnd_chipid *
470bhnd_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 */
486static inline int
487bhnd_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 */
508static inline int
509bhnd_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 */
544static inline struct bhnd_resource *
545bhnd_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 */
567static inline struct bhnd_resource *
568bhnd_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 */
585static inline int
586bhnd_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 */
605static inline int
606bhnd_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 */
625static inline int
626bhnd_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 */
642static inline bool
643bhnd_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 */
656static inline u_int
657bhnd_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 */
669static inline u_int
670bhnd_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 */
686static inline int
687bhnd_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 */
706static inline int
707bhnd_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 */
727static inline int
728bhnd_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_ */
893