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