xref: /freebsd/sys/dev/bhnd/bhnd_bus_if.m (revision d3de06238379fc0e692927ebf74fcc41860c726f)
1#-
2# Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.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# 2. Redistributions in binary form must reproduce the above copyright
11#    notice, this list of conditions and the following disclaimer in the
12#    documentation and/or other materials provided with the distribution.
13#
14# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17# IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
18# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
23# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24#
25# $FreeBSD$
26
27#include <sys/types.h>
28#include <sys/bus.h>
29#include <sys/rman.h>
30
31#include <dev/bhnd/bhnd_types.h>
32#include <dev/bhnd/bhnd_erom_types.h>
33
34INTERFACE bhnd_bus;
35
36#
37# bhnd(4) bus interface
38#
39
40HEADER {
41	/* forward declarations */
42	struct bhnd_board_info;
43	struct bhnd_core_info;
44	struct bhnd_chipid;
45	struct bhnd_devinfo;
46	struct bhnd_resource;
47}
48
49CODE {
50	#include <sys/systm.h>
51
52	#include <dev/bhnd/bhndvar.h>
53
54	static bhnd_erom_class_t *
55	bhnd_bus_null_get_erom_class(driver_t *driver)
56	{
57		return (NULL);
58	}
59
60	static struct bhnd_chipid *
61	bhnd_bus_null_get_chipid(device_t dev, device_t child)
62	{
63		panic("bhnd_bus_get_chipid unimplemented");
64	}
65
66	static bhnd_attach_type
67	bhnd_bus_null_get_attach_type(device_t dev, device_t child)
68	{
69		panic("bhnd_bus_get_attach_type unimplemented");
70	}
71
72	static bhnd_clksrc
73	bhnd_bus_null_pwrctl_get_clksrc(device_t dev, device_t child,
74	    bhnd_clock clock)
75	{
76		return (BHND_CLKSRC_UNKNOWN);
77	}
78
79	static int
80	bhnd_bus_null_pwrctl_gate_clock(device_t dev, device_t child,
81	    bhnd_clock clock)
82	{
83		return (ENODEV);
84	}
85
86	static int
87	bhnd_bus_null_pwrctl_ungate_clock(device_t dev, device_t child,
88	    bhnd_clock clock)
89	{
90		return (ENODEV);
91	}
92
93	static int
94	bhnd_bus_null_read_board_info(device_t dev, device_t child,
95	    struct bhnd_board_info *info)
96	{
97		panic("bhnd_bus_read_boardinfo unimplemented");
98	}
99
100	static int
101	bhnd_bus_null_get_intr_count(device_t dev, device_t child)
102	{
103		panic("bhnd_bus_get_intr_count unimplemented");
104	}
105
106	static int
107	bhnd_bus_null_assign_intr(device_t dev, device_t child, int rid)
108	{
109		panic("bhnd_bus_assign_intr unimplemented");
110	}
111
112	static int
113	bhnd_bus_null_get_core_ivec(device_t dev, device_t child, u_int intr,
114	    uint32_t *ivec)
115	{
116		panic("bhnd_bus_get_core_ivec unimplemented");
117	}
118
119	static void
120	bhnd_bus_null_child_added(device_t dev, device_t child)
121	{
122	}
123
124	static int
125	bhnd_bus_null_alloc_pmu(device_t dev, device_t child)
126	{
127		panic("bhnd_bus_alloc_pmu unimplemented");
128	}
129
130	static int
131	bhnd_bus_null_release_pmu(device_t dev, device_t child)
132	{
133		panic("bhnd_bus_release_pmu unimplemented");
134	}
135
136	static int
137	bhnd_bus_null_request_clock(device_t dev, device_t child,
138	    bhnd_clock clock)
139	{
140		panic("bhnd_bus_request_clock unimplemented");
141	}
142
143	static int
144	bhnd_bus_null_enable_clocks(device_t dev, device_t child,
145	    uint32_t clocks)
146	{
147		panic("bhnd_bus_enable_clocks unimplemented");
148	}
149
150	static int
151	bhnd_bus_null_request_ext_rsrc(device_t dev, device_t child,
152	    u_int rsrc)
153	{
154		panic("bhnd_bus_request_ext_rsrc unimplemented");
155	}
156
157	static int
158	bhnd_bus_null_release_ext_rsrc(device_t dev, device_t child,
159	    u_int rsrc)
160	{
161		panic("bhnd_bus_release_ext_rsrc unimplemented");
162	}
163
164	static uint32_t
165	bhnd_bus_null_read_config(device_t dev, device_t child,
166	    bus_size_t offset, u_int width)
167	{
168		panic("bhnd_bus_null_read_config unimplemented");
169	}
170
171	static void
172	bhnd_bus_null_write_config(device_t dev, device_t child,
173	    bus_size_t offset, uint32_t val, u_int width)
174	{
175		panic("bhnd_bus_null_write_config unimplemented");
176	}
177
178	static device_t
179	bhnd_bus_null_find_hostb_device(device_t dev)
180	{
181		return (NULL);
182	}
183
184	static bool
185	bhnd_bus_null_is_hw_disabled(device_t dev, device_t child)
186	{
187		panic("bhnd_bus_is_hw_disabled unimplemented");
188	}
189
190	static int
191	bhnd_bus_null_get_probe_order(device_t dev, device_t child)
192	{
193		panic("bhnd_bus_get_probe_order unimplemented");
194	}
195
196	static int
197	bhnd_bus_null_get_port_rid(device_t dev, device_t child,
198	    bhnd_port_type port_type, u_int port, u_int region)
199	{
200		return (-1);
201	}
202
203	static int
204	bhnd_bus_null_decode_port_rid(device_t dev, device_t child, int type,
205	    int rid, bhnd_port_type *port_type, u_int *port, u_int *region)
206	{
207		return (ENOENT);
208	}
209
210	static int
211	bhnd_bus_null_get_region_addr(device_t dev, device_t child,
212	    bhnd_port_type type, u_int port, u_int region, bhnd_addr_t *addr,
213	    bhnd_size_t *size)
214	{
215		return (ENOENT);
216	}
217
218	static int
219	bhnd_bus_null_get_nvram_var(device_t dev, device_t child,
220	    const char *name, void *buf, size_t *size, bhnd_nvram_type type)
221	{
222		return (ENODEV);
223	}
224
225}
226
227/**
228 * Return the bhnd(4) bus driver's device enumeration parser class.
229 *
230 * @param driver	The bhnd bus driver instance.
231 */
232STATICMETHOD bhnd_erom_class_t * get_erom_class {
233	driver_t			*driver;
234} DEFAULT bhnd_bus_null_get_erom_class;
235
236/**
237 * Return the active host bridge core for the bhnd bus, if any.
238 *
239 * @param dev The bhnd bus device.
240 *
241 * @retval device_t if a hostb device exists
242 * @retval NULL if no hostb device is found.
243 */
244METHOD device_t find_hostb_device {
245	device_t dev;
246} DEFAULT bhnd_bus_null_find_hostb_device;
247
248/**
249 * Return true if the hardware components required by @p child are unpopulated
250 * or otherwise unusable.
251 *
252 * In some cases, enumerated devices may have pins that are left floating, or
253 * the hardware may otherwise be non-functional; this method allows a parent
254 * device to explicitly specify if a successfully enumerated @p child should
255 * be disabled.
256 *
257 * @param dev The device whose child is being examined.
258 * @param child The child device.
259 */
260METHOD bool is_hw_disabled {
261	device_t dev;
262	device_t child;
263} DEFAULT bhnd_bus_null_is_hw_disabled;
264
265/**
266 * Return the probe (and attach) order for @p child.
267 *
268 * All devices on the bhnd(4) bus will be probed, attached, or resumed in
269 * ascending order; they will be suspended, shutdown, and detached in
270 * descending order.
271 *
272 * The following device methods will be dispatched in ascending probe order
273 * by the bus:
274 *
275 * - DEVICE_PROBE()
276 * - DEVICE_ATTACH()
277 * - DEVICE_RESUME()
278 *
279 * The following device methods will be dispatched in descending probe order
280 * by the bus:
281 *
282 * - DEVICE_SHUTDOWN()
283 * - DEVICE_DETACH()
284 * - DEVICE_SUSPEND()
285 *
286 * @param dev The device whose child is being examined.
287 * @param child The child device.
288 *
289 * Refer to BHND_PROBE_* and BHND_PROBE_ORDER_* for the standard set of
290 * priorities.
291 */
292METHOD int get_probe_order {
293	device_t dev;
294	device_t child;
295} DEFAULT bhnd_bus_null_get_probe_order;
296
297/**
298 * Return the BHND chip identification for the parent bus.
299 *
300 * @param dev The device whose child is being examined.
301 * @param child The child device.
302 */
303METHOD const struct bhnd_chipid * get_chipid {
304	device_t dev;
305	device_t child;
306} DEFAULT bhnd_bus_null_get_chipid;
307
308/**
309 * Return the BHND attachment type of the parent bus.
310 *
311 * @param dev The device whose child is being examined.
312 * @param child The child device.
313 *
314 * @retval BHND_ATTACH_ADAPTER if the bus is resident on a bridged adapter,
315 * such as a WiFi chipset.
316 * @retval BHND_ATTACH_NATIVE if the bus provides hardware services (clock,
317 * CPU, etc) to a directly attached native host.
318 */
319METHOD bhnd_attach_type get_attach_type {
320	device_t dev;
321	device_t child;
322} DEFAULT bhnd_bus_null_get_attach_type;
323
324/**
325 * Attempt to read the BHND board identification from the parent bus.
326 *
327 * This relies on NVRAM access, and will fail if a valid NVRAM device cannot
328 * be found, or is not yet attached.
329 *
330 * @param dev The parent of @p child.
331 * @param child The bhnd device requesting board info.
332 * @param[out] info On success, will be populated with the bhnd(4) device's
333 * board information.
334 *
335 * @retval 0 success
336 * @retval ENODEV	No valid NVRAM source could be found.
337 * @retval non-zero	If reading @p name otherwise fails, a regular unix
338 *			error code will be returned.
339 */
340METHOD int read_board_info {
341	device_t dev;
342	device_t child;
343	struct bhnd_board_info *info;
344} DEFAULT bhnd_bus_null_read_board_info;
345
346/**
347 * Allocate and zero-initialize a buffer suitably sized and aligned for a
348 * bhnd_devinfo structure.
349 *
350 * @param dev The bhnd bus device.
351 *
352 * @retval non-NULL	success
353 * @retval NULL		allocation failed
354 */
355METHOD struct bhnd_devinfo * alloc_devinfo {
356	device_t dev;
357};
358
359/**
360 * Release memory previously allocated for @p devinfo.
361 *
362 * @param dev The bhnd bus device.
363 * @param dinfo A devinfo buffer previously allocated via
364 * BHND_BUS_ALLOC_DEVINFO().
365 */
366METHOD void free_devinfo {
367	device_t dev;
368	struct bhnd_devinfo *dinfo;
369};
370
371
372/**
373 * Return the number of interrupts to be assigned to @p child via
374 * BHND_BUS_ASSIGN_INTR().
375 *
376 * @param dev The bhnd bus parent of @p child.
377 * @param child The bhnd device for which a count should be returned.
378 *
379 * @retval 0		If no interrupts should be assigned.
380 * @retval non-zero	The count of interrupt resource IDs to be
381 *			assigned, starting at rid 0.
382 */
383METHOD int get_intr_count {
384	device_t dev;
385	device_t child;
386} DEFAULT bhnd_bus_null_get_intr_count;
387
388/**
389 * Assign an interrupt to @p child via bus_set_resource().
390 *
391 * The default bus implementation of this method should assign backplane
392 * interrupt values to @p child.
393 *
394 * Bridge-attached bus implementations may instead override standard
395 * interconnect IRQ assignment, providing IRQs inherited from the parent bus.
396 *
397 * TODO: Once we can depend on INTRNG, investigate replacing this with a
398 * bridge-level interrupt controller.
399 *
400 * @param dev The bhnd bus parent of @p child.
401 * @param child The bhnd device to which an interrupt should be assigned.
402 * @param rid The interrupt resource ID to be assigned.
403 *
404 * @retval 0		If an interrupt was assigned.
405 * @retval non-zero	If assigning an interrupt otherwise fails, a regular
406 *			unix error code will be returned.
407 */
408METHOD int assign_intr {
409	device_t dev;
410	device_t child;
411	int rid;
412} DEFAULT bhnd_bus_null_assign_intr;
413
414/**
415 * Return the backplane interrupt vector corresponding to @p child's given
416 * @p intr number.
417 *
418 * @param dev The bhnd bus parent of @p child.
419 * @param child The bhnd device for which the assigned interrupt vector should
420 * be queried.
421 * @param intr The interrupt number being queried. This is equivalent to the
422 * bus resource ID for the interrupt.
423 * @param[out] ivec On success, the assigned hardware interrupt vector be
424 * written to this pointer.
425 *
426 * On bcma(4) devices, this returns the OOB bus line assigned to the
427 * interrupt.
428 *
429 * On siba(4) devices, this returns the target OCP slave flag number assigned
430 * to the interrupt.
431 *
432 * @retval 0		success
433 * @retval ENXIO	If @p intr exceeds the number of interrupts available
434 *			to @p child.
435 */
436METHOD int get_core_ivec {
437	device_t dev;
438	device_t child;
439	u_int intr;
440	uint32_t *ivec;
441} DEFAULT bhnd_bus_null_get_core_ivec;
442
443/**
444 * Notify a bhnd bus that a child was added.
445 *
446 * This method must be called by concrete bhnd(4) driver impementations
447 * after @p child's bus state is fully initialized.
448 *
449 * @param dev The bhnd bus whose child is being added.
450 * @param child The child added to @p dev.
451 */
452METHOD void child_added {
453	device_t dev;
454	device_t child;
455} DEFAULT bhnd_bus_null_child_added;
456
457/**
458 * Reset the device's hardware core.
459 *
460 * @param dev The parent of @p child.
461 * @param child The device to be reset.
462 * @param flags Device-specific core flags to be supplied on reset.
463 *
464 * @retval 0 success
465 * @retval non-zero error
466 */
467METHOD int reset_core {
468	device_t dev;
469	device_t child;
470	uint16_t flags;
471}
472
473/**
474 * Suspend a device hardware core.
475 *
476 * @param dev The parent of @p child.
477 * @param child The device to be reset.
478 *
479 * @retval 0 success
480 * @retval non-zero error
481 */
482METHOD int suspend_core {
483	device_t dev;
484	device_t child;
485}
486
487/**
488 * If supported by the chipset, return the clock source for the given clock.
489 *
490 * This function is only supported on early PWRCTL-equipped chipsets
491 * that expose clock management via their host bridge interface. Currently,
492 * this includes PCI (not PCIe) devices, with ChipCommon core revisions 0-9.
493 *
494 * @param dev The parent of @p child.
495 * @param child The bhnd device requesting a clock source.
496 * @param clock The clock for which a clock source will be returned.
497 *
498 * @retval	bhnd_clksrc		The clock source for @p clock.
499 * @retval	BHND_CLKSRC_UNKNOWN	If @p clock is unsupported, or its
500 *					clock source is not known to the bus.
501 */
502METHOD bhnd_clksrc pwrctl_get_clksrc {
503	device_t dev;
504	device_t child;
505	bhnd_clock clock;
506} DEFAULT bhnd_bus_null_pwrctl_get_clksrc;
507
508/**
509 * If supported by the chipset, gate the clock source for @p clock
510 *
511 * This function is only supported on early PWRCTL-equipped chipsets
512 * that expose clock management via their host bridge interface. Currently,
513 * this includes PCI (not PCIe) devices, with ChipCommon core revisions 0-9.
514 *
515 * @param dev The parent of @p child.
516 * @param child The bhnd device requesting clock gating.
517 * @param clock The clock to be disabled.
518 *
519 * @retval 0 success
520 * @retval ENODEV If bus-level clock source management is not supported.
521 * @retval ENXIO If bus-level management of @p clock is not supported.
522 */
523METHOD int pwrctl_gate_clock {
524	device_t dev;
525	device_t child;
526	bhnd_clock clock;
527} DEFAULT bhnd_bus_null_pwrctl_gate_clock;
528
529/**
530 * If supported by the chipset, ungate the clock source for @p clock
531 *
532 * This function is only supported on early PWRCTL-equipped chipsets
533 * that expose clock management via their host bridge interface. Currently,
534 * this includes PCI (not PCIe) devices, with ChipCommon core revisions 0-9.
535 *
536 * @param dev The parent of @p child.
537 * @param child The bhnd device requesting clock gating.
538 * @param clock The clock to be enabled.
539 *
540 * @retval 0 success
541 * @retval ENODEV If bus-level clock source management is not supported.
542 * @retval ENXIO If bus-level management of @p clock is not supported.
543 */
544METHOD int pwrctl_ungate_clock {
545	device_t dev;
546	device_t child;
547	bhnd_clock clock;
548} DEFAULT bhnd_bus_null_pwrctl_ungate_clock;
549
550/**
551 * Allocate and enable per-core PMU request handling for @p child.
552 *
553 * The region containing the core's PMU register block (if any) must be
554 * allocated via bus_alloc_resource(9) (or bhnd_alloc_resource) before
555 * calling BHND_BUS_ALLOC_PMU(), and must not be released until after
556 * calling BHND_BUS_RELEASE_PMU().
557 *
558 * @param dev The parent of @p child.
559 * @param child The requesting bhnd device.
560 */
561METHOD int alloc_pmu {
562	device_t dev;
563	device_t child;
564} DEFAULT bhnd_bus_null_alloc_pmu;
565
566/**
567 * Release per-core PMU resources allocated for @p child. Any
568 * outstanding PMU requests are discarded.
569 *
570 * @param dev The parent of @p child.
571 * @param child The requesting bhnd device.
572 */
573METHOD int release_pmu {
574	device_t dev;
575	device_t child;
576} DEFAULT bhnd_bus_null_release_pmu;
577
578/**
579 * Request that @p clock (or faster) be routed to @p child.
580 *
581 * A driver must ask the bhnd bus to allocate PMU request state
582 * via BHND_BUS_ALLOC_PMU() before it can request clock resources.
583 *
584 * Request multiplexing is managed by the bus.
585 *
586 * @param dev The parent of @p child.
587 * @param child The bhnd device requesting @p clock.
588 * @param clock The requested clock source.
589 *
590 * @retval 0 success
591 * @retval ENODEV If an unsupported clock was requested.
592 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.
593 */
594METHOD int request_clock {
595	device_t dev;
596	device_t child;
597	bhnd_clock clock;
598} DEFAULT bhnd_bus_null_request_clock;
599
600/**
601 * Request that @p clocks be powered on behalf of @p child.
602 *
603 * This will power on clock sources (e.g. XTAL, PLL, etc) required for
604 * @p clocks and wait until they are ready, discarding any previous
605 * requests by @p child.
606 *
607 * Request multiplexing is managed by the bus.
608 *
609 * A driver must ask the bhnd bus to allocate PMU request state
610 * via BHND_BUS_ALLOC_PMU() before it can request clock resources.
611 *
612 * @param dev The parent of @p child.
613 * @param child The bhnd device requesting @p clock.
614 * @param clock The requested clock source.
615 *
616 * @retval 0 success
617 * @retval ENODEV If an unsupported clock was requested.
618 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.
619 */
620METHOD int enable_clocks {
621	device_t dev;
622	device_t child;
623	uint32_t clocks;
624} DEFAULT bhnd_bus_null_enable_clocks;
625
626/**
627 * Power up an external PMU-managed resource assigned to @p child.
628 *
629 * A driver must ask the bhnd bus to allocate PMU request state
630 * via BHND_BUS_ALLOC_PMU() before it can request PMU resources.
631 *
632 * @param dev The parent of @p child.
633 * @param child The bhnd device requesting @p rsrc.
634 * @param rsrc The core-specific external resource identifier.
635 *
636 * @retval 0 success
637 * @retval ENODEV If the PMU does not support @p rsrc.
638 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.
639 */
640METHOD int request_ext_rsrc {
641	device_t dev;
642	device_t child;
643	u_int rsrc;
644} DEFAULT bhnd_bus_null_request_ext_rsrc;
645
646/**
647 * Power down an external PMU-managed resource assigned to @p child.
648 *
649 * A driver must ask the bhnd bus to allocate PMU request state
650 * via BHND_BUS_ALLOC_PMU() before it can request PMU resources.
651 *
652 * @param dev The parent of @p child.
653 * @param child The bhnd device requesting @p rsrc.
654 * @param rsrc The core-specific external resource number.
655 *
656 * @retval 0 success
657 * @retval ENODEV If the PMU does not support @p rsrc.
658 * @retval ENXIO If the PMU has not been initialized or is otherwise unvailable.
659 */
660METHOD int release_ext_rsrc {
661	device_t dev;
662	device_t child;
663	u_int rsrc;
664} DEFAULT bhnd_bus_null_release_ext_rsrc;
665
666/**
667 * Read @p width bytes at @p offset from the bus-specific agent/config
668 * space of @p child.
669 *
670 * @param dev The parent of @p child.
671 * @param child The bhnd device for which @p offset should be read.
672 * @param offset The offset to be read.
673 * @param width The size of the access. Must be 1, 2 or 4 bytes.
674 *
675 * The exact behavior of this method is bus-specific. On a bcma(4) bus, this
676 * method provides access to the first agent port of @p child; on a siba(4) bus,
677 * this method provides access to the core's CFG0 register block.
678 *
679 * @note Device drivers should only use this API for functionality
680 * that is not available via another bhnd(4) function.
681 */
682METHOD uint32_t read_config {
683	device_t dev;
684	device_t child;
685	bus_size_t offset;
686	u_int width;
687} DEFAULT bhnd_bus_null_read_config;
688
689/**
690 * Read @p width bytes at @p offset from the bus-specific agent/config
691 * space of @p child.
692 *
693 * @param dev The parent of @p child.
694 * @param child The bhnd device for which @p offset should be read.
695 * @param offset The offset to be written.
696 * @param width The size of the access. Must be 1, 2 or 4 bytes.
697 *
698 * The exact behavior of this method is bus-specific. In the case of
699 * bcma(4), this method provides access to the first agent port of @p child.
700 *
701 * @note Device drivers should only use this API for functionality
702 * that is not available via another bhnd(4) function.
703 */
704METHOD void write_config {
705	device_t dev;
706	device_t child;
707	bus_size_t offset;
708	uint32_t val;
709	u_int width;
710} DEFAULT bhnd_bus_null_write_config;
711
712/**
713 * Allocate a bhnd resource.
714 *
715 * This method's semantics are functionally identical to the bus API of the same
716 * name; refer to BUS_ALLOC_RESOURCE for complete documentation.
717 */
718METHOD struct bhnd_resource * alloc_resource {
719	device_t dev;
720	device_t child;
721	int type;
722	int *rid;
723	rman_res_t start;
724	rman_res_t end;
725	rman_res_t count;
726	u_int flags;
727} DEFAULT bhnd_bus_generic_alloc_resource;
728
729/**
730 * Release a bhnd resource.
731 *
732 * This method's semantics are functionally identical to the bus API of the same
733 * name; refer to BUS_RELEASE_RESOURCE for complete documentation.
734 */
735METHOD int release_resource {
736	device_t dev;
737	device_t child;
738	int type;
739	int rid;
740	struct bhnd_resource *res;
741} DEFAULT bhnd_bus_generic_release_resource;
742
743/**
744 * Activate a bhnd resource.
745 *
746 * This method's semantics are functionally identical to the bus API of the same
747 * name; refer to BUS_ACTIVATE_RESOURCE for complete documentation.
748 */
749METHOD int activate_resource {
750	device_t dev;
751        device_t child;
752	int type;
753        int rid;
754        struct bhnd_resource *r;
755} DEFAULT bhnd_bus_generic_activate_resource;
756
757/**
758 * Deactivate a bhnd resource.
759 *
760 * This method's semantics are functionally identical to the bus API of the same
761 * name; refer to BUS_DEACTIVATE_RESOURCE for complete documentation.
762 */
763METHOD int deactivate_resource {
764        device_t dev;
765        device_t child;
766        int type;
767	int rid;
768        struct bhnd_resource *r;
769} DEFAULT bhnd_bus_generic_deactivate_resource;
770
771/**
772 * Return true if @p region_num is a valid region on @p port_num of
773 * @p type attached to @p child.
774 *
775 * @param dev The device whose child is being examined.
776 * @param child The child device.
777 * @param type The port type being queried.
778 * @param port_num The port number being queried.
779 * @param region_num The region number being queried.
780 */
781METHOD bool is_region_valid {
782	device_t dev;
783	device_t child;
784	bhnd_port_type type;
785	u_int port_num;
786	u_int region_num;
787};
788
789/**
790 * Return the number of ports of type @p type attached to @p child.
791 *
792 * @param dev The device whose child is being examined.
793 * @param child The child device.
794 * @param type The port type being queried.
795 */
796METHOD u_int get_port_count {
797	device_t dev;
798	device_t child;
799	bhnd_port_type type;
800};
801
802/**
803 * Return the number of memory regions mapped to @p child @p port of
804 * type @p type.
805 *
806 * @param dev The device whose child is being examined.
807 * @param child The child device.
808 * @param port The port number being queried.
809 * @param type The port type being queried.
810 */
811METHOD u_int get_region_count {
812	device_t dev;
813	device_t child;
814	bhnd_port_type type;
815	u_int port;
816};
817
818/**
819 * Return the SYS_RES_MEMORY resource-ID for a port/region pair attached to
820 * @p child.
821 *
822 * @param dev The bus device.
823 * @param child The bhnd child.
824 * @param port_type The port type.
825 * @param port_num The index of the child interconnect port.
826 * @param region_num The index of the port-mapped address region.
827 *
828 * @retval -1 No such port/region found.
829 */
830METHOD int get_port_rid {
831	device_t dev;
832	device_t child;
833	bhnd_port_type port_type;
834	u_int port_num;
835	u_int region_num;
836} DEFAULT bhnd_bus_null_get_port_rid;
837
838
839/**
840 * Decode a port / region pair on @p child defined by @p type and @p rid.
841 *
842 * @param dev The bus device.
843 * @param child The bhnd child.
844 * @param type The resource type.
845 * @param rid The resource ID.
846 * @param[out] port_type The port's type.
847 * @param[out] port The port identifier.
848 * @param[out] region The identifier of the memory region on @p port.
849 *
850 * @retval 0 success
851 * @retval non-zero No matching type/rid found.
852 */
853METHOD int decode_port_rid {
854	device_t dev;
855	device_t child;
856	int type;
857	int rid;
858	bhnd_port_type *port_type;
859	u_int *port;
860	u_int *region;
861} DEFAULT bhnd_bus_null_decode_port_rid;
862
863/**
864 * Get the address and size of @p region on @p port.
865 *
866 * @param dev The bus device.
867 * @param child The bhnd child.
868 * @param port_type The port type.
869 * @param port The port identifier.
870 * @param region The identifier of the memory region on @p port.
871 * @param[out] region_addr The region's base address.
872 * @param[out] region_size The region's size.
873 *
874 * @retval 0 success
875 * @retval non-zero No matching port/region found.
876 */
877METHOD int get_region_addr {
878	device_t dev;
879	device_t child;
880	bhnd_port_type port_type;
881	u_int port;
882	u_int region;
883	bhnd_addr_t *region_addr;
884	bhnd_size_t *region_size;
885} DEFAULT bhnd_bus_null_get_region_addr;
886
887/**
888 * Read an NVRAM variable.
889 *
890 * It is the responsibility of the bus to delegate this request to
891 * the appropriate NVRAM child device, or to a parent bus implementation.
892 *
893 * @param		dev	The bus device.
894 * @param		child	The requesting device.
895 * @param		name	The NVRAM variable name.
896 * @param[out]		buf	On success, the requested value will be written
897 *				to this buffer. This argment may be NULL if
898 *				the value is not desired.
899 * @param[in,out]	size	The capacity of @p buf. On success, will be set
900 *				to the actual size of the requested value.
901 * @param		type	The data type to be written to @p buf.
902 *
903 * @retval 0		success
904 * @retval ENOENT	The requested variable was not found.
905 * @retval ENOMEM	If @p buf is non-NULL and a buffer of @p size is too
906 *			small to hold the requested value.
907 * @retval ENODEV	No valid NVRAM source could be found.
908 * @retval EFTYPE	If the @p name's data type cannot be coerced to @p type.
909 * @retval ERANGE	If value coercion would overflow @p type.
910 * @retval non-zero	If reading @p name otherwise fails, a regular unix
911 *			error code will be returned.
912 */
913METHOD int get_nvram_var {
914	device_t	 dev;
915	device_t	 child;
916	const char	*name;
917	void		*buf;
918	size_t		*size;
919	bhnd_nvram_type	 type;
920} DEFAULT bhnd_bus_null_get_nvram_var;
921
922
923/** An implementation of bus_read_1() compatible with bhnd_resource */
924METHOD uint8_t read_1 {
925	device_t dev;
926	device_t child;
927	struct bhnd_resource *r;
928	bus_size_t offset;
929}
930
931/** An implementation of bus_read_2() compatible with bhnd_resource */
932METHOD uint16_t read_2 {
933	device_t dev;
934	device_t child;
935	struct bhnd_resource *r;
936	bus_size_t offset;
937}
938
939/** An implementation of bus_read_4() compatible with bhnd_resource */
940METHOD uint32_t read_4 {
941	device_t dev;
942	device_t child;
943	struct bhnd_resource *r;
944	bus_size_t offset;
945}
946
947/** An implementation of bus_write_1() compatible with bhnd_resource */
948METHOD void write_1 {
949	device_t dev;
950	device_t child;
951	struct bhnd_resource *r;
952	bus_size_t offset;
953	uint8_t value;
954}
955
956/** An implementation of bus_write_2() compatible with bhnd_resource */
957METHOD void write_2 {
958	device_t dev;
959	device_t child;
960	struct bhnd_resource *r;
961	bus_size_t offset;
962	uint16_t value;
963}
964
965/** An implementation of bus_write_4() compatible with bhnd_resource */
966METHOD void write_4 {
967	device_t dev;
968	device_t child;
969	struct bhnd_resource *r;
970	bus_size_t offset;
971	uint32_t value;
972}
973
974/** An implementation of bus_read_stream_1() compatible with bhnd_resource */
975METHOD uint8_t read_stream_1 {
976	device_t dev;
977	device_t child;
978	struct bhnd_resource *r;
979	bus_size_t offset;
980}
981
982/** An implementation of bus_read_stream_2() compatible with bhnd_resource */
983METHOD uint16_t read_stream_2 {
984	device_t dev;
985	device_t child;
986	struct bhnd_resource *r;
987	bus_size_t offset;
988}
989
990/** An implementation of bus_read_stream_4() compatible with bhnd_resource */
991METHOD uint32_t read_stream_4 {
992	device_t dev;
993	device_t child;
994	struct bhnd_resource *r;
995	bus_size_t offset;
996}
997
998/** An implementation of bus_write_stream_1() compatible with bhnd_resource */
999METHOD void write_stream_1 {
1000	device_t dev;
1001	device_t child;
1002	struct bhnd_resource *r;
1003	bus_size_t offset;
1004	uint8_t value;
1005}
1006
1007/** An implementation of bus_write_stream_2() compatible with bhnd_resource */
1008METHOD void write_stream_2 {
1009	device_t dev;
1010	device_t child;
1011	struct bhnd_resource *r;
1012	bus_size_t offset;
1013	uint16_t value;
1014}
1015
1016/** An implementation of bus_write_stream_4() compatible with bhnd_resource */
1017METHOD void write_stream_4 {
1018	device_t dev;
1019	device_t child;
1020	struct bhnd_resource *r;
1021	bus_size_t offset;
1022	uint32_t value;
1023}
1024
1025/** An implementation of bus_read_multi_1() compatible with bhnd_resource */
1026METHOD void read_multi_1 {
1027	device_t dev;
1028	device_t child;
1029	struct bhnd_resource *r;
1030	bus_size_t offset;
1031	uint8_t *datap;
1032	bus_size_t count;
1033}
1034
1035/** An implementation of bus_read_multi_2() compatible with bhnd_resource */
1036METHOD void read_multi_2 {
1037	device_t dev;
1038	device_t child;
1039	struct bhnd_resource *r;
1040	bus_size_t offset;
1041	uint16_t *datap;
1042	bus_size_t count;
1043}
1044
1045/** An implementation of bus_read_multi_4() compatible with bhnd_resource */
1046METHOD void read_multi_4 {
1047	device_t dev;
1048	device_t child;
1049	struct bhnd_resource *r;
1050	bus_size_t offset;
1051	uint32_t *datap;
1052	bus_size_t count;
1053}
1054
1055/** An implementation of bus_write_multi_1() compatible with bhnd_resource */
1056METHOD void write_multi_1 {
1057	device_t dev;
1058	device_t child;
1059	struct bhnd_resource *r;
1060	bus_size_t offset;
1061	uint8_t *datap;
1062	bus_size_t count;
1063}
1064
1065/** An implementation of bus_write_multi_2() compatible with bhnd_resource */
1066METHOD void write_multi_2 {
1067	device_t dev;
1068	device_t child;
1069	struct bhnd_resource *r;
1070	bus_size_t offset;
1071	uint16_t *datap;
1072	bus_size_t count;
1073}
1074
1075/** An implementation of bus_write_multi_4() compatible with bhnd_resource */
1076METHOD void write_multi_4 {
1077	device_t dev;
1078	device_t child;
1079	struct bhnd_resource *r;
1080	bus_size_t offset;
1081	uint32_t *datap;
1082	bus_size_t count;
1083}
1084
1085/** An implementation of bus_read_multi_stream_1() compatible
1086 *  bhnd_resource */
1087METHOD void read_multi_stream_1 {
1088	device_t dev;
1089	device_t child;
1090	struct bhnd_resource *r;
1091	bus_size_t offset;
1092	uint8_t *datap;
1093	bus_size_t count;
1094}
1095
1096/** An implementation of bus_read_multi_stream_2() compatible
1097 *  bhnd_resource */
1098METHOD void read_multi_stream_2 {
1099	device_t dev;
1100	device_t child;
1101	struct bhnd_resource *r;
1102	bus_size_t offset;
1103	uint16_t *datap;
1104	bus_size_t count;
1105}
1106
1107/** An implementation of bus_read_multi_stream_4() compatible
1108 *  bhnd_resource */
1109METHOD void read_multi_stream_4 {
1110	device_t dev;
1111	device_t child;
1112	struct bhnd_resource *r;
1113	bus_size_t offset;
1114	uint32_t *datap;
1115	bus_size_t count;
1116}
1117
1118/** An implementation of bus_write_multi_stream_1() compatible
1119 *  bhnd_resource */
1120METHOD void write_multi_stream_1 {
1121	device_t dev;
1122	device_t child;
1123	struct bhnd_resource *r;
1124	bus_size_t offset;
1125	uint8_t *datap;
1126	bus_size_t count;
1127}
1128
1129/** An implementation of bus_write_multi_stream_2() compatible with
1130 *  bhnd_resource */
1131METHOD void write_multi_stream_2 {
1132	device_t dev;
1133	device_t child;
1134	struct bhnd_resource *r;
1135	bus_size_t offset;
1136	uint16_t *datap;
1137	bus_size_t count;
1138}
1139
1140/** An implementation of bus_write_multi_stream_4() compatible with
1141 *  bhnd_resource */
1142METHOD void write_multi_stream_4 {
1143	device_t dev;
1144	device_t child;
1145	struct bhnd_resource *r;
1146	bus_size_t offset;
1147	uint32_t *datap;
1148	bus_size_t count;
1149}
1150
1151/** An implementation of bus_set_multi_1() compatible with bhnd_resource */
1152METHOD void set_multi_1 {
1153	device_t dev;
1154	device_t child;
1155	struct bhnd_resource *r;
1156	bus_size_t offset;
1157	uint8_t value;
1158	bus_size_t count;
1159}
1160
1161/** An implementation of bus_set_multi_2() compatible with bhnd_resource */
1162METHOD void set_multi_2 {
1163	device_t dev;
1164	device_t child;
1165	struct bhnd_resource *r;
1166	bus_size_t offset;
1167	uint16_t value;
1168	bus_size_t count;
1169}
1170
1171/** An implementation of bus_set_multi_4() compatible with bhnd_resource */
1172METHOD void set_multi_4 {
1173	device_t dev;
1174	device_t child;
1175	struct bhnd_resource *r;
1176	bus_size_t offset;
1177	uint32_t value;
1178	bus_size_t count;
1179}
1180
1181/** An implementation of bus_set_region_1() compatible with bhnd_resource */
1182METHOD void set_region_1 {
1183	device_t dev;
1184	device_t child;
1185	struct bhnd_resource *r;
1186	bus_size_t offset;
1187	uint8_t value;
1188	bus_size_t count;
1189}
1190
1191/** An implementation of bus_set_region_2() compatible with bhnd_resource */
1192METHOD void set_region_2 {
1193	device_t dev;
1194	device_t child;
1195	struct bhnd_resource *r;
1196	bus_size_t offset;
1197	uint16_t value;
1198	bus_size_t count;
1199}
1200
1201/** An implementation of bus_set_region_4() compatible with bhnd_resource */
1202METHOD void set_region_4 {
1203	device_t dev;
1204	device_t child;
1205	struct bhnd_resource *r;
1206	bus_size_t offset;
1207	uint32_t value;
1208	bus_size_t count;
1209}
1210
1211/** An implementation of bus_read_region_1() compatible with bhnd_resource */
1212METHOD void read_region_1 {
1213	device_t dev;
1214	device_t child;
1215	struct bhnd_resource *r;
1216	bus_size_t offset;
1217	uint8_t *datap;
1218	bus_size_t count;
1219}
1220
1221/** An implementation of bus_read_region_2() compatible with bhnd_resource */
1222METHOD void read_region_2 {
1223	device_t dev;
1224	device_t child;
1225	struct bhnd_resource *r;
1226	bus_size_t offset;
1227	uint16_t *datap;
1228	bus_size_t count;
1229}
1230
1231/** An implementation of bus_read_region_4() compatible with bhnd_resource */
1232METHOD void read_region_4 {
1233	device_t dev;
1234	device_t child;
1235	struct bhnd_resource *r;
1236	bus_size_t offset;
1237	uint32_t *datap;
1238	bus_size_t count;
1239}
1240
1241/** An implementation of bus_read_region_stream_1() compatible with
1242  * bhnd_resource */
1243METHOD void read_region_stream_1 {
1244	device_t dev;
1245	device_t child;
1246	struct bhnd_resource *r;
1247	bus_size_t offset;
1248	uint8_t *datap;
1249	bus_size_t count;
1250}
1251
1252/** An implementation of bus_read_region_stream_2() compatible with
1253  * bhnd_resource */
1254METHOD void read_region_stream_2 {
1255	device_t dev;
1256	device_t child;
1257	struct bhnd_resource *r;
1258	bus_size_t offset;
1259	uint16_t *datap;
1260	bus_size_t count;
1261}
1262
1263/** An implementation of bus_read_region_stream_4() compatible with
1264  * bhnd_resource */
1265METHOD void read_region_stream_4 {
1266	device_t dev;
1267	device_t child;
1268	struct bhnd_resource *r;
1269	bus_size_t offset;
1270	uint32_t *datap;
1271	bus_size_t count;
1272}
1273
1274/** An implementation of bus_write_region_1() compatible with bhnd_resource */
1275METHOD void write_region_1 {
1276	device_t dev;
1277	device_t child;
1278	struct bhnd_resource *r;
1279	bus_size_t offset;
1280	uint8_t *datap;
1281	bus_size_t count;
1282}
1283
1284/** An implementation of bus_write_region_2() compatible with bhnd_resource */
1285METHOD void write_region_2 {
1286	device_t dev;
1287	device_t child;
1288	struct bhnd_resource *r;
1289	bus_size_t offset;
1290	uint16_t *datap;
1291	bus_size_t count;
1292}
1293
1294/** An implementation of bus_write_region_4() compatible with bhnd_resource */
1295METHOD void write_region_4 {
1296	device_t dev;
1297	device_t child;
1298	struct bhnd_resource *r;
1299	bus_size_t offset;
1300	uint32_t *datap;
1301	bus_size_t count;
1302}
1303
1304/** An implementation of bus_write_region_stream_1() compatible with
1305  * bhnd_resource */
1306METHOD void write_region_stream_1 {
1307	device_t dev;
1308	device_t child;
1309	struct bhnd_resource *r;
1310	bus_size_t offset;
1311	uint8_t *datap;
1312	bus_size_t count;
1313}
1314
1315/** An implementation of bus_write_region_stream_2() compatible with
1316  * bhnd_resource */
1317METHOD void write_region_stream_2 {
1318	device_t dev;
1319	device_t child;
1320	struct bhnd_resource *r;
1321	bus_size_t offset;
1322	uint16_t *datap;
1323	bus_size_t count;
1324}
1325
1326/** An implementation of bus_write_region_stream_4() compatible with
1327  * bhnd_resource */
1328METHOD void write_region_stream_4 {
1329	device_t dev;
1330	device_t child;
1331	struct bhnd_resource *r;
1332	bus_size_t offset;
1333	uint32_t *datap;
1334	bus_size_t count;
1335}
1336
1337/** An implementation of bus_barrier() compatible with bhnd_resource */
1338METHOD void barrier {
1339	device_t dev;
1340	device_t child;
1341	struct bhnd_resource *r;
1342	bus_size_t offset;
1343	bus_size_t length;
1344	int flags;
1345}
1346