xref: /freebsd/sys/dev/bhnd/bhndb/bhndb.c (revision d96700a6da2afa88607fbd7405ade439424d10d9)
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 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 /*
34  * Abstract BHND Bridge Device Driver
35  *
36  * Provides generic support for bridging from a parent bus (such as PCI) to
37  * a BHND-compatible bus (e.g. bcma or siba).
38  */
39 
40 #include <sys/param.h>
41 #include <sys/kernel.h>
42 #include <sys/bus.h>
43 #include <sys/module.h>
44 #include <sys/systm.h>
45 
46 #include <machine/bus.h>
47 #include <sys/rman.h>
48 #include <machine/resource.h>
49 
50 #include <dev/bhnd/bhndvar.h>
51 #include <dev/bhnd/bhndreg.h>
52 
53 #include <dev/bhnd/cores/chipc/chipcreg.h>
54 #include <dev/bhnd/nvram/bhnd_nvram.h>
55 
56 #include "bhnd_chipc_if.h"
57 #include "bhnd_nvram_if.h"
58 
59 #include "bhndbvar.h"
60 #include "bhndb_bus_if.h"
61 #include "bhndb_hwdata.h"
62 #include "bhndb_private.h"
63 
64 /* Debugging flags */
65 static u_long bhndb_debug = 0;
66 TUNABLE_ULONG("hw.bhndb.debug", &bhndb_debug);
67 
68 enum {
69 	BHNDB_DEBUG_PRIO = 1 << 0,
70 };
71 
72 #define	BHNDB_DEBUG(_type)	(BHNDB_DEBUG_ ## _type & bhndb_debug)
73 
74 static bool			 bhndb_hw_matches(device_t *devlist,
75 				     int num_devs,
76 				     const struct bhndb_hw *hw);
77 
78 static int			 bhndb_initialize_region_cfg(
79 				     struct bhndb_softc *sc, device_t *devs,
80 				     int ndevs,
81 				     const struct bhndb_hw_priority *table,
82 				     struct bhndb_resources *r);
83 
84 static int			 bhndb_find_hwspec(struct bhndb_softc *sc,
85 				     device_t *devs, int ndevs,
86 				     const struct bhndb_hw **hw);
87 
88 static int			 bhndb_read_chipid(struct bhndb_softc *sc,
89 				     const struct bhndb_hwcfg *cfg,
90 				     struct bhnd_chipid *result);
91 
92 bhndb_addrspace			 bhndb_get_addrspace(struct bhndb_softc *sc,
93 				     device_t child);
94 
95 static struct rman		*bhndb_get_rman(struct bhndb_softc *sc,
96 				     device_t child, int type);
97 
98 static int			 bhndb_init_child_resource(struct resource *r,
99 				     struct resource *parent,
100 				     bhnd_size_t offset,
101 				     bhnd_size_t size);
102 
103 static int			 bhndb_activate_static_region(
104 				     struct bhndb_softc *sc,
105 				     struct bhndb_region *region,
106 				     device_t child, int type, int rid,
107 				     struct resource *r);
108 
109 static int			 bhndb_try_activate_resource(
110 				     struct bhndb_softc *sc, device_t child,
111 				     int type, int rid, struct resource *r,
112 				     bool *indirect);
113 
114 
115 /**
116  * Default bhndb(4) implementation of DEVICE_PROBE().
117  *
118  * This function provides the default bhndb implementation of DEVICE_PROBE(),
119  * and is compatible with bhndb(4) bridges attached via bhndb_attach_bridge().
120  */
121 int
122 bhndb_generic_probe(device_t dev)
123 {
124 	return (BUS_PROBE_NOWILDCARD);
125 }
126 
127 static void
128 bhndb_probe_nomatch(device_t dev, device_t child)
129 {
130 	const char *name;
131 
132 	name = device_get_name(child);
133 	if (name == NULL)
134 		name = "unknown device";
135 
136 	device_printf(dev, "<%s> (no driver attached)\n", name);
137 }
138 
139 static int
140 bhndb_print_child(device_t dev, device_t child)
141 {
142 	struct bhndb_softc	*sc;
143 	struct resource_list	*rl;
144 	int			 retval = 0;
145 
146 	sc = device_get_softc(dev);
147 
148 	retval += bus_print_child_header(dev, child);
149 
150 	rl = BUS_GET_RESOURCE_LIST(dev, child);
151 	if (rl != NULL) {
152 		retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY,
153 		    "%#jx");
154 		retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ,
155 		    "%jd");
156 	}
157 
158 	retval += bus_print_child_domain(dev, child);
159 	retval += bus_print_child_footer(dev, child);
160 
161 	return (retval);
162 }
163 
164 static int
165 bhndb_child_pnpinfo_str(device_t bus, device_t child, char *buf,
166     size_t buflen)
167 {
168 	*buf = '\0';
169 	return (0);
170 }
171 
172 static int
173 bhndb_child_location_str(device_t dev, device_t child, char *buf,
174     size_t buflen)
175 {
176 	struct bhndb_softc *sc;
177 
178 	sc = device_get_softc(dev);
179 
180 	snprintf(buf, buflen, "base=0x%llx",
181 	    (unsigned long long) sc->chipid.enum_addr);
182 	return (0);
183 }
184 
185 /**
186  * Return true if @p devlist matches the @p hw specification.
187  *
188  * @param devlist A device table to match against.
189  * @param num_devs The number of devices in @p devlist.
190  * @param hw The hardware description to be matched against.
191  */
192 static bool
193 bhndb_hw_matches(device_t *devlist, int num_devs, const struct bhndb_hw *hw)
194 {
195 	for (u_int i = 0; i < hw->num_hw_reqs; i++) {
196 		const struct bhnd_core_match	*match;
197 		struct bhnd_core_info		 ci;
198 		bool				 found;
199 
200 		match =  &hw->hw_reqs[i];
201 		found = false;
202 
203 		for (int d = 0; d < num_devs; d++) {
204 			ci = bhnd_get_core_info(devlist[d]);
205 			if (!bhnd_core_matches(&ci, match))
206 				continue;
207 
208 			found = true;
209 			break;
210 		}
211 
212 		if (!found)
213 			return (false);
214 	}
215 
216 	return (true);
217 }
218 
219 /**
220  * Initialize the region maps and priority configuration in @p r using
221  * the provided priority @p table and the set of devices attached to
222  * the bridged @p bus_dev .
223  *
224  * @param sc The bhndb device state.
225  * @param devs All devices enumerated on the bridged bhnd bus.
226  * @param ndevs The length of @p devs.
227  * @param table Hardware priority table to be used to determine the relative
228  * priorities of per-core port resources.
229  * @param r The resource state to be configured.
230  */
231 static int
232 bhndb_initialize_region_cfg(struct bhndb_softc *sc, device_t *devs, int ndevs,
233     const struct bhndb_hw_priority *table, struct bhndb_resources *r)
234 {
235 	const struct bhndb_hw_priority	*hp;
236 	bhnd_addr_t			 addr;
237 	bhnd_size_t			 size;
238 	size_t				 prio_low, prio_default, prio_high;
239 	int				 error;
240 
241 	/* The number of port regions per priority band that must be accessible
242 	 * via dynamic register windows */
243 	prio_low = 0;
244 	prio_default = 0;
245 	prio_high = 0;
246 
247 	/*
248 	 * Register bridge regions covering all statically mapped ports.
249 	 */
250 	for (int i = 0; i < ndevs; i++) {
251 		const struct bhndb_regwin	*regw;
252 		device_t			 child;
253 
254 		child = devs[i];
255 
256 		for (regw = r->cfg->register_windows;
257 		    regw->win_type != BHNDB_REGWIN_T_INVALID; regw++)
258 		{
259 			/* Only core windows are supported */
260 			if (regw->win_type != BHNDB_REGWIN_T_CORE)
261 				continue;
262 
263 			/* Skip non-applicable register windows. */
264 			if (!bhndb_regwin_matches_device(regw, child))
265 				continue;
266 
267 			/* Fetch the base address of the mapped port. */
268 			error = bhnd_get_region_addr(child,
269 			    regw->d.core.port_type, regw->d.core.port,
270 			    regw->d.core.region, &addr, &size);
271 			if (error)
272 			    return (error);
273 
274 			/*
275 			 * Always defer to the register window's size.
276 			 *
277 			 * If the port size is smaller than the window size,
278 			 * this ensures that we fully utilize register windows
279 			 * larger than the referenced port.
280 			 *
281 			 * If the port size is larger than the window size, this
282 			 * ensures that we do not directly map the allocations
283 			 * within the region to a too-small window.
284 			 */
285 			size = regw->win_size;
286 
287 			/*
288 			 * Add to the bus region list.
289 			 *
290 			 * The window priority for a statically mapped
291 			 * region is always HIGH.
292 			 */
293 			error = bhndb_add_resource_region(r, addr, size,
294 			    BHNDB_PRIORITY_HIGH, regw);
295 			if (error)
296 				return (error);
297 		}
298 	}
299 
300 	/*
301 	 * Perform priority accounting and register bridge regions for all
302 	 * ports defined in the priority table
303 	 */
304 	for (int i = 0; i < ndevs; i++) {
305 		struct bhndb_region	*region;
306 		device_t		 child;
307 
308 		child = devs[i];
309 
310 		/*
311 		 * Skip priority accounting for cores that ...
312 		 */
313 
314 		/* ... do not require bridge resources */
315 		if (bhnd_is_hw_disabled(child) || !device_is_enabled(child))
316 			continue;
317 
318 		/* ... do not have a priority table entry */
319 		hp = bhndb_hw_priority_find_device(table, child);
320 		if (hp == NULL)
321 			continue;
322 
323 		/* ... are explicitly disabled in the priority table. */
324 		if (hp->priority == BHNDB_PRIORITY_NONE)
325 			continue;
326 
327 		/* Determine the number of dynamic windows required and
328 		 * register their bus_region entries. */
329 		for (u_int i = 0; i < hp->num_ports; i++) {
330 			const struct bhndb_port_priority *pp;
331 
332 			pp = &hp->ports[i];
333 
334 			/* Skip ports not defined on this device */
335 			if (!bhnd_is_region_valid(child, pp->type, pp->port,
336 			    pp->region))
337 			{
338 				continue;
339 			}
340 
341 			/* Fetch the address+size of the mapped port. */
342 			error = bhnd_get_region_addr(child, pp->type, pp->port,
343 			    pp->region, &addr, &size);
344 			if (error)
345 			    return (error);
346 
347 			/* Skip ports with an existing static mapping */
348 			region = bhndb_find_resource_region(r, addr, size);
349 			if (region != NULL && region->static_regwin != NULL)
350 				continue;
351 
352 			/* Define a dynamic region for this port */
353 			error = bhndb_add_resource_region(r, addr, size,
354 			    pp->priority, NULL);
355 			if (error)
356 				return (error);
357 
358 			/* Update port mapping counts */
359 			switch (pp->priority) {
360 			case BHNDB_PRIORITY_NONE:
361 				break;
362 			case BHNDB_PRIORITY_LOW:
363 				prio_low++;
364 				break;
365 			case BHNDB_PRIORITY_DEFAULT:
366 				prio_default++;
367 				break;
368 			case BHNDB_PRIORITY_HIGH:
369 				prio_high++;
370 				break;
371 			}
372 		}
373 	}
374 
375 	/* Determine the minimum priority at which we'll allocate direct
376 	 * register windows from our dynamic pool */
377 	size_t prio_total = prio_low + prio_default + prio_high;
378 	if (prio_total <= r->dwa_count) {
379 		/* low+default+high priority regions get windows */
380 		r->min_prio = BHNDB_PRIORITY_LOW;
381 
382 	} else if (prio_default + prio_high <= r->dwa_count) {
383 		/* default+high priority regions get windows */
384 		r->min_prio = BHNDB_PRIORITY_DEFAULT;
385 
386 	} else {
387 		/* high priority regions get windows */
388 		r->min_prio = BHNDB_PRIORITY_HIGH;
389 	}
390 
391 	if (BHNDB_DEBUG(PRIO)) {
392 		struct bhndb_region	*region;
393 		const char		*direct_msg, *type_msg;
394 		bhndb_priority_t	 prio, prio_min;
395 
396 		prio_min = r->min_prio;
397 		device_printf(sc->dev, "min_prio: %d\n", prio_min);
398 
399 		STAILQ_FOREACH(region, &r->bus_regions, link) {
400 			prio = region->priority;
401 
402 			direct_msg = prio >= prio_min ? "direct" : "indirect";
403 			type_msg = region->static_regwin ? "static" : "dynamic";
404 
405 			device_printf(sc->dev, "region 0x%llx+0x%llx priority "
406 			    "%u %s/%s\n",
407 			    (unsigned long long) region->addr,
408 			    (unsigned long long) region->size,
409 			    region->priority,
410 			    direct_msg, type_msg);
411 		}
412 	}
413 
414 	return (0);
415 }
416 
417 /**
418  * Find a hardware specification for @p dev.
419  *
420  * @param sc The bhndb device state.
421  * @param devs All devices enumerated on the bridged bhnd bus.
422  * @param ndevs The length of @p devs.
423  * @param[out] hw On success, the matched hardware specification.
424  * with @p dev.
425  *
426  * @retval 0 success
427  * @retval non-zero if an error occurs fetching device info for comparison.
428  */
429 static int
430 bhndb_find_hwspec(struct bhndb_softc *sc, device_t *devs, int ndevs,
431     const struct bhndb_hw **hw)
432 {
433 	const struct bhndb_hw	*next, *hw_table;
434 
435 	/* Search for the first matching hardware config. */
436 	hw_table = BHNDB_BUS_GET_HARDWARE_TABLE(sc->parent_dev, sc->dev);
437 	for (next = hw_table; next->hw_reqs != NULL; next++) {
438 		if (!bhndb_hw_matches(devs, ndevs, next))
439 			continue;
440 
441 		/* Found */
442 		*hw = next;
443 		return (0);
444 	}
445 
446 	return (ENOENT);
447 }
448 
449 /**
450  * Read the ChipCommon identification data for this device.
451  *
452  * @param sc bhndb device state.
453  * @param cfg The hardware configuration to use when mapping the ChipCommon
454  * registers.
455  * @param[out] result the chip identification data.
456  *
457  * @retval 0 success
458  * @retval non-zero if the ChipCommon identification data could not be read.
459  */
460 static int
461 bhndb_read_chipid(struct bhndb_softc *sc, const struct bhndb_hwcfg *cfg,
462     struct bhnd_chipid *result)
463 {
464 	const struct bhnd_chipid	*parent_cid;
465 	const struct bhndb_regwin	*cc_win;
466 	struct resource_spec		 rs;
467 	int				 error;
468 
469 	/* Let our parent device override the discovery process */
470 	parent_cid = BHNDB_BUS_GET_CHIPID(sc->parent_dev, sc->dev);
471 	if (parent_cid != NULL) {
472 		*result = *parent_cid;
473 		return (0);
474 	}
475 
476 	/* Find a register window we can use to map the first CHIPC_CHIPID_SIZE
477 	 * of ChipCommon registers. */
478 	cc_win = bhndb_regwin_find_best(cfg->register_windows,
479 	    BHND_DEVCLASS_CC, 0, BHND_PORT_DEVICE, 0, 0, CHIPC_CHIPID_SIZE);
480 	if (cc_win == NULL) {
481 		device_printf(sc->dev, "no chipcommon register window\n");
482 		return (0);
483 	}
484 
485 	/* We can assume a device without a static ChipCommon window uses the
486 	 * default ChipCommon address. */
487 	if (cc_win->win_type == BHNDB_REGWIN_T_DYN) {
488 		error = BHNDB_SET_WINDOW_ADDR(sc->dev, cc_win,
489 		    BHND_DEFAULT_CHIPC_ADDR);
490 
491 		if (error) {
492 			device_printf(sc->dev, "failed to set chipcommon "
493 			    "register window\n");
494 			return (error);
495 		}
496 	}
497 
498 	/* Let the default bhnd implemenation alloc/release the resource and
499 	 * perform the read */
500 	rs.type = cc_win->res.type;
501 	rs.rid = cc_win->res.rid;
502 	rs.flags = RF_ACTIVE;
503 
504 	return (bhnd_read_chipid(sc->parent_dev, &rs, cc_win->win_offset,
505 	    result));
506 }
507 
508 /**
509  * Helper function that must be called by subclass bhndb(4) drivers
510  * when implementing DEVICE_ATTACH() before calling any bhnd(4) or bhndb(4)
511  * APIs on the bridge device.
512  *
513  * @param dev The bridge device to attach.
514  * @param bridge_devclass The device class of the bridging core. This is used
515  * to automatically detect the bridge core, and to disable additional bridge
516  * cores (e.g. PCMCIA on a PCIe device).
517  */
518 int
519 bhndb_attach(device_t dev, bhnd_devclass_t bridge_devclass)
520 {
521 	struct bhndb_devinfo		*dinfo;
522 	struct bhndb_softc		*sc;
523 	const struct bhndb_hwcfg	*cfg;
524 	int				 error;
525 
526 	sc = device_get_softc(dev);
527 	sc->dev = dev;
528 	sc->parent_dev = device_get_parent(dev);
529 	sc->bridge_class = bridge_devclass;
530 
531 	BHNDB_LOCK_INIT(sc);
532 
533 	/* Read our chip identification data */
534 	cfg = BHNDB_BUS_GET_GENERIC_HWCFG(sc->parent_dev, sc->dev);
535 	if ((error = bhndb_read_chipid(sc, cfg, &sc->chipid)))
536 		return (error);
537 
538 	/* Populate generic resource allocation state. */
539 	sc->bus_res = bhndb_alloc_resources(dev, sc->parent_dev, cfg);
540 	if (sc->bus_res == NULL) {
541 		return (ENXIO);
542 	}
543 
544 	/* Attach our bridged bus device */
545 	sc->bus_dev = BUS_ADD_CHILD(dev, 0, "bhnd", -1);
546 	if (sc->bus_dev == NULL) {
547 		error = ENXIO;
548 		goto failed;
549 	}
550 
551 	/* Configure address space */
552 	dinfo = device_get_ivars(sc->bus_dev);
553 	dinfo->addrspace = BHNDB_ADDRSPACE_BRIDGED;
554 
555 	/* Finish attach */
556 	return (bus_generic_attach(dev));
557 
558 failed:
559 	BHNDB_LOCK_DESTROY(sc);
560 
561 	if (sc->bus_res != NULL)
562 		bhndb_free_resources(sc->bus_res);
563 
564 	return (error);
565 }
566 
567 /**
568  * Default bhndb(4) implementation of BHNDB_INIT_FULL_CONFIG().
569  *
570  * This function provides the default bhndb implementation of
571  * BHNDB_INIT_FULL_CONFIG(), and must be called by any subclass driver
572  * overriding BHNDB_INIT_FULL_CONFIG().
573  *
574  * As documented by BHNDB_INIT_FULL_CONFIG, this function performs final
575  * bridge configuration based on the hardware information enumerated by the
576  * child bus, and will reset all resource allocation state on the bridge.
577  *
578  * When calling this method:
579  * - Any bus resources previously allocated by @p child must be deallocated.
580  * - The @p child bus must have performed initial enumeration -- but not
581  *   probe or attachment -- of its children.
582  */
583 int
584 bhndb_generic_init_full_config(device_t dev, device_t child,
585     const struct bhndb_hw_priority *hw_prio_table)
586 {
587 	struct bhndb_softc		*sc;
588 	const struct bhndb_hw		*hw;
589 	struct bhndb_resources		*r;
590 	device_t			*devs;
591 	device_t			 hostb;
592 	int				 ndevs;
593 	int				 error;
594 
595 	sc = device_get_softc(dev);
596 	hostb = NULL;
597 
598 	/* Fetch the full set of bhnd-attached cores */
599 	if ((error = device_get_children(sc->bus_dev, &devs, &ndevs))) {
600 		device_printf(sc->dev, "unable to get children\n");
601 		return (error);
602 	}
603 
604 	/* Find our host bridge device */
605 	hostb = BHNDB_FIND_HOSTB_DEVICE(dev, child);
606 	if (hostb == NULL) {
607 		device_printf(sc->dev, "no host bridge core found\n");
608 		error = ENODEV;
609 		goto cleanup;
610 	}
611 
612 	/* Find our full register window configuration */
613 	if ((error = bhndb_find_hwspec(sc, devs, ndevs, &hw))) {
614 		device_printf(sc->dev, "unable to identify device, "
615 			" using generic bridge resource definitions\n");
616 		error = 0;
617 		goto cleanup;
618 	}
619 
620 	if (bootverbose || BHNDB_DEBUG(PRIO))
621 		device_printf(sc->dev, "%s resource configuration\n", hw->name);
622 
623 	/* Release existing resource state */
624 	BHNDB_LOCK(sc);
625 	bhndb_free_resources(sc->bus_res);
626 	sc->bus_res = NULL;
627 	BHNDB_UNLOCK(sc);
628 
629 	/* Allocate new resource state */
630 	r = bhndb_alloc_resources(dev, sc->parent_dev, hw->cfg);
631 	if (r == NULL) {
632 		error = ENXIO;
633 		goto cleanup;
634 	}
635 
636 	/* Initialize our resource priority configuration */
637 	error = bhndb_initialize_region_cfg(sc, devs, ndevs, hw_prio_table, r);
638 	if (error) {
639 		bhndb_free_resources(r);
640 		goto cleanup;
641 	}
642 
643 	/* Update our bridge state */
644 	BHNDB_LOCK(sc);
645 	sc->bus_res = r;
646 	sc->hostb_dev = hostb;
647 	BHNDB_UNLOCK(sc);
648 
649 cleanup:
650 	free(devs, M_TEMP);
651 	return (error);
652 }
653 
654 /**
655  * Default bhndb(4) implementation of DEVICE_DETACH().
656  *
657  * This function detaches any child devices, and if successful, releases all
658  * resources held by the bridge device.
659  */
660 int
661 bhndb_generic_detach(device_t dev)
662 {
663 	struct bhndb_softc	*sc;
664 	int			 error;
665 
666 	sc = device_get_softc(dev);
667 
668 	/* Detach children */
669 	if ((error = bus_generic_detach(dev)))
670 		return (error);
671 
672 	/* Clean up our driver state. */
673 	bhndb_free_resources(sc->bus_res);
674 
675 	BHNDB_LOCK_DESTROY(sc);
676 
677 	return (0);
678 }
679 
680 /**
681  * Default bhndb(4) implementation of DEVICE_SUSPEND().
682  *
683  * This function calls bus_generic_suspend() (or implements equivalent
684  * behavior).
685  */
686 int
687 bhndb_generic_suspend(device_t dev)
688 {
689 	return (bus_generic_suspend(dev));
690 }
691 
692 /**
693  * Default bhndb(4) implementation of DEVICE_RESUME().
694  *
695  * This function calls bus_generic_resume() (or implements equivalent
696  * behavior).
697  */
698 int
699 bhndb_generic_resume(device_t dev)
700 {
701 	struct bhndb_softc	*sc;
702 	struct bhndb_resources	*bus_res;
703 	struct bhndb_dw_alloc	*dwa;
704 	int			 error;
705 
706 	sc = device_get_softc(dev);
707 	bus_res = sc->bus_res;
708 
709 	/* Guarantee that all in-use dynamic register windows are mapped to
710 	 * their previously configured target address. */
711 	BHNDB_LOCK(sc);
712 	for (size_t i = 0; i < bus_res->dwa_count; i++) {
713 		dwa = &bus_res->dw_alloc[i];
714 
715 		/* Skip regions that were not previously used */
716 		if (bhndb_dw_is_free(bus_res, dwa) && dwa->target == 0x0)
717 			continue;
718 
719 		/* Otherwise, ensure the register window is correct before
720 		 * any children attempt MMIO */
721 		error = BHNDB_SET_WINDOW_ADDR(dev, dwa->win, dwa->target);
722 		if (error)
723 			break;
724 	}
725 	BHNDB_UNLOCK(sc);
726 
727 	/* Error restoring hardware state; children cannot be safely resumed */
728 	if (error) {
729 		device_printf(dev, "Unable to restore hardware configuration; "
730 		    "cannot resume: %d\n", error);
731 		return (error);
732 	}
733 
734 	return (bus_generic_resume(dev));
735 }
736 
737 /**
738  * Default implementation of BHNDB_SUSPEND_RESOURCE.
739  */
740 static void
741 bhndb_suspend_resource(device_t dev, device_t child, int type,
742     struct resource *r)
743 {
744 	struct bhndb_softc	*sc;
745 	struct bhndb_dw_alloc	*dwa;
746 
747 	sc = device_get_softc(dev);
748 
749 	// TODO: IRQs?
750 	if (type != SYS_RES_MEMORY)
751 		return;
752 
753 	BHNDB_LOCK(sc);
754 	dwa = bhndb_dw_find_resource(sc->bus_res, r);
755 	if (dwa == NULL) {
756 		BHNDB_UNLOCK(sc);
757 		return;
758 	}
759 
760 	if (BHNDB_DEBUG(PRIO))
761 		device_printf(child, "suspend resource type=%d 0x%jx+0x%jx\n",
762 		    type, rman_get_start(r), rman_get_size(r));
763 
764 	/* Release the resource's window reference */
765 	bhndb_dw_release(sc->bus_res, dwa, r);
766 	BHNDB_UNLOCK(sc);
767 }
768 
769 /**
770  * Default implementation of BHNDB_RESUME_RESOURCE.
771  */
772 static int
773 bhndb_resume_resource(device_t dev, device_t child, int type,
774     struct resource *r)
775 {
776 	struct bhndb_softc	*sc;
777 
778 	sc = device_get_softc(dev);
779 
780 	// TODO: IRQs?
781 	if (type != SYS_RES_MEMORY)
782 		return (0);
783 
784 	/* Inactive resources don't require reallocation of bridge resources */
785 	if (!(rman_get_flags(r) & RF_ACTIVE))
786 		return (0);
787 
788 	if (BHNDB_DEBUG(PRIO))
789 		device_printf(child, "resume resource type=%d 0x%jx+0x%jx\n",
790 		    type, rman_get_start(r), rman_get_size(r));
791 
792 	return (bhndb_try_activate_resource(sc, rman_get_device(r), type,
793 	    rman_get_rid(r), r, NULL));
794 }
795 
796 
797 /**
798  * Default bhndb(4) implementation of BUS_READ_IVAR().
799  */
800 static int
801 bhndb_read_ivar(device_t dev, device_t child, int index,
802     uintptr_t *result)
803 {
804 	return (ENOENT);
805 }
806 
807 /**
808  * Default bhndb(4) implementation of BUS_WRITE_IVAR().
809  */
810 static int
811 bhndb_write_ivar(device_t dev, device_t child, int index,
812     uintptr_t value)
813 {
814 	return (ENOENT);
815 }
816 
817 /**
818  * Return the address space for the given @p child device.
819  */
820 bhndb_addrspace
821 bhndb_get_addrspace(struct bhndb_softc *sc, device_t child)
822 {
823 	struct bhndb_devinfo	*dinfo;
824 	device_t		 imd_dev;
825 
826 	/* Find the directly attached parent of the requesting device */
827 	imd_dev = child;
828 	while (imd_dev != NULL && device_get_parent(imd_dev) != sc->dev)
829 		imd_dev = device_get_parent(imd_dev);
830 
831 	if (imd_dev == NULL)
832 		panic("bhndb address space request for non-child device %s\n",
833 		     device_get_nameunit(child));
834 
835 	dinfo = device_get_ivars(imd_dev);
836 	return (dinfo->addrspace);
837 }
838 
839 /**
840  * Return the rman instance for a given resource @p type, if any.
841  *
842  * @param sc The bhndb device state.
843  * @param child The requesting child.
844  * @param type The resource type (e.g. SYS_RES_MEMORY, SYS_RES_IRQ, ...)
845  */
846 static struct rman *
847 bhndb_get_rman(struct bhndb_softc *sc, device_t child, int type)
848 {
849 	switch (bhndb_get_addrspace(sc, child)) {
850 	case BHNDB_ADDRSPACE_NATIVE:
851 		switch (type) {
852 		case SYS_RES_MEMORY:
853 			return (&sc->bus_res->ht_mem_rman);
854 		case SYS_RES_IRQ:
855 			return (NULL);
856 		default:
857 			return (NULL);
858 		};
859 
860 	case BHNDB_ADDRSPACE_BRIDGED:
861 		switch (type) {
862 		case SYS_RES_MEMORY:
863 			return (&sc->bus_res->br_mem_rman);
864 		case SYS_RES_IRQ:
865 			// TODO
866 			// return &sc->irq_rman;
867 			return (NULL);
868 		default:
869 			return (NULL);
870 		};
871 	}
872 
873 	/* Quieten gcc */
874 	return (NULL);
875 }
876 
877 /**
878  * Default implementation of BUS_ADD_CHILD()
879  */
880 static device_t
881 bhndb_add_child(device_t dev, u_int order, const char *name, int unit)
882 {
883 	struct bhndb_devinfo	*dinfo;
884 	device_t		 child;
885 
886 	child = device_add_child_ordered(dev, order, name, unit);
887 	if (child == NULL)
888 		return (NULL);
889 
890 	dinfo = malloc(sizeof(struct bhndb_devinfo), M_BHND, M_NOWAIT);
891 	if (dinfo == NULL) {
892 		device_delete_child(dev, child);
893 		return (NULL);
894 	}
895 
896 	dinfo->addrspace = BHNDB_ADDRSPACE_NATIVE;
897 	resource_list_init(&dinfo->resources);
898 
899 	device_set_ivars(child, dinfo);
900 
901 	return (child);
902 }
903 
904 /**
905  * Default implementation of BUS_CHILD_DELETED().
906  */
907 static void
908 bhndb_child_deleted(device_t dev, device_t child)
909 {
910 	struct bhndb_devinfo *dinfo = device_get_ivars(child);
911 	if (dinfo != NULL) {
912 		resource_list_free(&dinfo->resources);
913 		free(dinfo, M_BHND);
914 	}
915 
916 	device_set_ivars(child, NULL);
917 }
918 
919 /**
920  * Default implementation of BHNDB_GET_CHIPID().
921  */
922 static const struct bhnd_chipid *
923 bhndb_get_chipid(device_t dev, device_t child)
924 {
925 	struct bhndb_softc *sc = device_get_softc(dev);
926 	return (&sc->chipid);
927 }
928 
929 
930 /**
931  * Default implementation of BHNDB_IS_HW_DISABLED().
932  */
933 static bool
934 bhndb_is_hw_disabled(device_t dev, device_t child) {
935 	struct bhndb_softc	*sc;
936 	struct bhnd_core_info	 core;
937 
938 	sc = device_get_softc(dev);
939 
940 	/* Requestor must be attached to the bhnd bus */
941 	if (device_get_parent(child) != sc->bus_dev) {
942 		return (BHND_BUS_IS_HW_DISABLED(device_get_parent(dev), child));
943 	}
944 
945 	/* Fetch core info */
946 	core = bhnd_get_core_info(child);
947 
948 	/* Try to defer to the bhndb bus parent */
949 	if (BHNDB_BUS_IS_CORE_DISABLED(sc->parent_dev, dev, &core))
950 		return (true);
951 
952 	/* Otherwise, we treat bridge-capable cores as unpopulated if they're
953 	 * not the configured host bridge */
954 	if (BHND_DEVCLASS_SUPPORTS_HOSTB(bhnd_core_class(&core)))
955 		return (BHNDB_FIND_HOSTB_DEVICE(dev, sc->bus_dev) != child);
956 
957 	/* Otherwise, assume the core is populated */
958 	return (false);
959 }
960 
961 /* ascending core index comparison used by bhndb_find_hostb_device() */
962 static int
963 compare_core_index(const void *lhs, const void *rhs)
964 {
965 	u_int left = bhnd_get_core_index(*(const device_t *) lhs);
966 	u_int right = bhnd_get_core_index(*(const device_t *) rhs);
967 
968 	if (left < right)
969 		return (-1);
970 	else if (left > right)
971 		return (1);
972 	else
973 		return (0);
974 }
975 
976 /**
977  * Default bhndb(4) implementation of BHND_BUS_FIND_HOSTB_DEVICE().
978  *
979  * This function uses a heuristic valid on all known PCI/PCIe/PCMCIA-bridged
980  * bhnd(4) devices to determine the hostb core:
981  *
982  * - The core must have a Broadcom vendor ID.
983  * - The core devclass must match the bridge type.
984  * - The core must be the first device on the bus with the bridged device
985  *   class.
986  *
987  * @param dev The bhndb device
988  * @param child The requesting bhnd bus.
989  */
990 static device_t
991 bhndb_find_hostb_device(device_t dev, device_t child)
992 {
993 	struct bhndb_softc		*sc;
994 	struct bhnd_device_match	 md;
995 	device_t			 hostb_dev, *devlist;
996 	int				 devcnt, error;
997 
998 	sc = device_get_softc(dev);
999 
1000 	/* Set up a match descriptor for the required device class. */
1001 	md = (struct bhnd_device_match) {
1002 		BHND_MATCH_CORE_CLASS(sc->bridge_class),
1003 		BHND_MATCH_CORE_UNIT(0)
1004 	};
1005 
1006 	/* Must be the absolute first matching device on the bus. */
1007 	if ((error = device_get_children(child, &devlist, &devcnt)))
1008 		return (false);
1009 
1010 	/* Sort by core index value, ascending */
1011 	qsort(devlist, devcnt, sizeof(*devlist), compare_core_index);
1012 
1013 	/* Find the hostb device */
1014 	hostb_dev = NULL;
1015 	for (int i = 0; i < devcnt; i++) {
1016 		if (bhnd_device_matches(devlist[i], &md)) {
1017 			hostb_dev = devlist[i];
1018 			break;
1019 		}
1020 	}
1021 
1022 	/* Clean up */
1023 	free(devlist, M_TEMP);
1024 
1025 	return (hostb_dev);
1026 }
1027 
1028 /**
1029  * Default bhndb(4) implementation of BUS_ALLOC_RESOURCE().
1030  */
1031 static struct resource *
1032 bhndb_alloc_resource(device_t dev, device_t child, int type,
1033     int *rid, rman_res_t start, rman_res_t end, rman_res_t count, u_int flags)
1034 {
1035 	struct bhndb_softc		*sc;
1036 	struct resource_list_entry	*rle;
1037 	struct resource			*rv;
1038 	struct rman			*rm;
1039 	int				 error;
1040 	bool				 passthrough, isdefault;
1041 
1042 	sc = device_get_softc(dev);
1043 	passthrough = (device_get_parent(child) != dev);
1044 	isdefault = RMAN_IS_DEFAULT_RANGE(start, end);
1045 	rle = NULL;
1046 
1047 	/* Populate defaults */
1048 	if (!passthrough && isdefault) {
1049 		/* Fetch the resource list entry. */
1050 		rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child),
1051 		    type, *rid);
1052 		if (rle == NULL) {
1053 			device_printf(dev,
1054 			    "default resource %#x type %d for child %s "
1055 			    "not found\n", *rid, type,
1056 			    device_get_nameunit(child));
1057 
1058 			return (NULL);
1059 		}
1060 
1061 		if (rle->res != NULL) {
1062 			device_printf(dev,
1063 			    "resource entry %#x type %d for child %s is busy\n",
1064 			    *rid, type, device_get_nameunit(child));
1065 
1066 			return (NULL);
1067 		}
1068 
1069 		start = rle->start;
1070 		end = rle->end;
1071 		count = ulmax(count, rle->count);
1072 	}
1073 
1074 	/* Validate resource addresses */
1075 	if (start > end || count > ((end - start) + 1))
1076 		return (NULL);
1077 
1078 	/* Fetch the resource manager */
1079 	rm = bhndb_get_rman(sc, child, type);
1080 	if (rm == NULL)
1081 		return (NULL);
1082 
1083 	/* Make our reservation */
1084 	rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE,
1085 	    child);
1086 	if (rv == NULL)
1087 		return (NULL);
1088 
1089 	rman_set_rid(rv, *rid);
1090 
1091 	/* Activate */
1092 	if (flags & RF_ACTIVE) {
1093 		error = bus_activate_resource(child, type, *rid, rv);
1094 		if (error) {
1095 			device_printf(dev,
1096 			    "failed to activate entry %#x type %d for "
1097 				"child %s: %d\n",
1098 			     *rid, type, device_get_nameunit(child), error);
1099 
1100 			rman_release_resource(rv);
1101 
1102 			return (NULL);
1103 		}
1104 	}
1105 
1106 	/* Update child's resource list entry */
1107 	if (rle != NULL) {
1108 		rle->res = rv;
1109 		rle->start = rman_get_start(rv);
1110 		rle->end = rman_get_end(rv);
1111 		rle->count = rman_get_size(rv);
1112 	}
1113 
1114 	return (rv);
1115 }
1116 
1117 /**
1118  * Default bhndb(4) implementation of BUS_RELEASE_RESOURCE().
1119  */
1120 static int
1121 bhndb_release_resource(device_t dev, device_t child, int type, int rid,
1122     struct resource *r)
1123 {
1124 	struct resource_list_entry	*rle;
1125 	bool				 passthrough;
1126 	int				 error;
1127 
1128 	passthrough = (device_get_parent(child) != dev);
1129 
1130 	/* Deactivate resources */
1131 	if (rman_get_flags(r) & RF_ACTIVE) {
1132 		error = BUS_DEACTIVATE_RESOURCE(dev, child, type, rid, r);
1133 		if (error)
1134 			return (error);
1135 	}
1136 
1137 	if ((error = rman_release_resource(r)))
1138 		return (error);
1139 
1140 	if (!passthrough) {
1141 		/* Clean resource list entry */
1142 		rle = resource_list_find(BUS_GET_RESOURCE_LIST(dev, child),
1143 		    type, rid);
1144 		if (rle != NULL)
1145 			rle->res = NULL;
1146 	}
1147 
1148 	return (0);
1149 }
1150 
1151 /**
1152  * Default bhndb(4) implementation of BUS_ADJUST_RESOURCE().
1153  */
1154 static int
1155 bhndb_adjust_resource(device_t dev, device_t child, int type,
1156     struct resource *r, rman_res_t start, rman_res_t end)
1157 {
1158 	struct bhndb_softc		*sc;
1159 	struct rman			*rm;
1160 	rman_res_t			 mstart, mend;
1161 	int				 error;
1162 
1163 	sc = device_get_softc(dev);
1164 	error = 0;
1165 
1166 	/* Verify basic constraints */
1167 	if (end <= start)
1168 		return (EINVAL);
1169 
1170 	/* Fetch resource manager */
1171 	rm = bhndb_get_rman(sc, child, type);
1172 	if (rm == NULL)
1173 		return (ENXIO);
1174 
1175 	if (!rman_is_region_manager(r, rm))
1176 		return (ENXIO);
1177 
1178 	BHNDB_LOCK(sc);
1179 
1180 	/* If not active, allow any range permitted by the resource manager */
1181 	if (!(rman_get_flags(r) & RF_ACTIVE))
1182 		goto done;
1183 
1184 	/* Otherwise, the range is limited to the existing register window
1185 	 * mapping */
1186 	error = bhndb_find_resource_limits(sc->bus_res, r, &mstart, &mend);
1187 	if (error)
1188 		goto done;
1189 
1190 	if (start < mstart || end > mend) {
1191 		error = EINVAL;
1192 		goto done;
1193 	}
1194 
1195 	/* Fall through */
1196 done:
1197 	if (!error)
1198 		error = rman_adjust_resource(r, start, end);
1199 
1200 	BHNDB_UNLOCK(sc);
1201 	return (error);
1202 }
1203 
1204 /**
1205  * Initialize child resource @p r with a virtual address, tag, and handle
1206  * copied from @p parent, adjusted to contain only the range defined by
1207  * @p offsize and @p size.
1208  *
1209  * @param r The register to be initialized.
1210  * @param parent The parent bus resource that fully contains the subregion.
1211  * @param offset The subregion offset within @p parent.
1212  * @param size The subregion size.
1213  * @p r.
1214  */
1215 static int
1216 bhndb_init_child_resource(struct resource *r,
1217     struct resource *parent, bhnd_size_t offset, bhnd_size_t size)
1218 {
1219 	bus_space_handle_t	bh, child_bh;
1220 	bus_space_tag_t		bt;
1221 	uintptr_t		vaddr;
1222 	int			error;
1223 
1224 	/* Fetch the parent resource's real bus values */
1225 	vaddr = (uintptr_t) rman_get_virtual(parent);
1226 	bt = rman_get_bustag(parent);
1227 	bh = rman_get_bushandle(parent);
1228 
1229 	/* Configure child resource with window-adjusted real bus values */
1230 	vaddr += offset;
1231 	error = bus_space_subregion(bt, bh, offset, size, &child_bh);
1232 	if (error)
1233 		return (error);
1234 
1235 	rman_set_virtual(r, (void *) vaddr);
1236 	rman_set_bustag(r, bt);
1237 	rman_set_bushandle(r, child_bh);
1238 
1239 	return (0);
1240 }
1241 
1242 /**
1243  * Attempt activation of a fixed register window mapping for @p child.
1244  *
1245  * @param sc BHNDB device state.
1246  * @param region The static region definition capable of mapping @p r.
1247  * @param child A child requesting resource activation.
1248  * @param type Resource type.
1249  * @param rid Resource identifier.
1250  * @param r Resource to be activated.
1251  *
1252  * @retval 0 if @p r was activated successfully
1253  * @retval ENOENT if no fixed register window was found.
1254  * @retval non-zero if @p r could not be activated.
1255  */
1256 static int
1257 bhndb_activate_static_region(struct bhndb_softc *sc,
1258     struct bhndb_region *region, device_t child, int type, int rid,
1259     struct resource *r)
1260 {
1261 	struct resource			*bridge_res;
1262 	const struct bhndb_regwin	*win;
1263 	bhnd_size_t			 parent_offset;
1264 	rman_res_t			 r_start, r_size;
1265 	int				 error;
1266 
1267 	win = region->static_regwin;
1268 
1269 	KASSERT(win != NULL && BHNDB_REGWIN_T_IS_STATIC(win->win_type),
1270 	    ("can't activate non-static region"));
1271 
1272 	r_start = rman_get_start(r);
1273 	r_size = rman_get_size(r);
1274 
1275 	/* Find the corresponding bridge resource */
1276 	bridge_res = bhndb_find_regwin_resource(sc->bus_res, win);
1277 	if (bridge_res == NULL)
1278 		return (ENXIO);
1279 
1280 	/* Calculate subregion offset within the parent resource */
1281 	parent_offset = r_start - region->addr;
1282 	parent_offset += win->win_offset;
1283 
1284 	/* Configure resource with its real bus values. */
1285 	error = bhndb_init_child_resource(r, bridge_res, parent_offset, r_size);
1286 	if (error)
1287 		return (error);
1288 
1289 	/* Mark active */
1290 	if ((error = rman_activate_resource(r)))
1291 		return (error);
1292 
1293 	return (0);
1294 }
1295 
1296 /**
1297  * Attempt to allocate/retain a dynamic register window for @p r, returning
1298  * the retained window.
1299  *
1300  * @param sc The bhndb driver state.
1301  * @param r The resource for which a window will be retained.
1302  */
1303 static struct bhndb_dw_alloc *
1304 bhndb_retain_dynamic_window(struct bhndb_softc *sc, struct resource *r)
1305 {
1306 	struct bhndb_dw_alloc	*dwa;
1307 	rman_res_t		 r_start, r_size;
1308 	int			 error;
1309 
1310 	BHNDB_LOCK_ASSERT(sc, MA_OWNED);
1311 
1312 	r_start = rman_get_start(r);
1313 	r_size = rman_get_size(r);
1314 
1315 	/* Look for an existing dynamic window we can reference */
1316 	dwa = bhndb_dw_find_mapping(sc->bus_res, r_start, r_size);
1317 	if (dwa != NULL) {
1318 		if (bhndb_dw_retain(sc->bus_res, dwa, r) == 0)
1319 			return (dwa);
1320 
1321 		return (NULL);
1322 	}
1323 
1324 	/* Otherwise, try to reserve a free window */
1325 	dwa = bhndb_dw_next_free(sc->bus_res);
1326 	if (dwa == NULL) {
1327 		/* No free windows */
1328 		return (NULL);
1329 	}
1330 
1331 	/* Set the window target */
1332 	error = bhndb_dw_set_addr(sc->dev, sc->bus_res, dwa, rman_get_start(r),
1333 	    rman_get_size(r));
1334 	if (error) {
1335 		device_printf(sc->dev, "dynamic window initialization "
1336 			"for 0x%llx-0x%llx failed: %d\n",
1337 			(unsigned long long) r_start,
1338 			(unsigned long long) r_start + r_size - 1,
1339 			error);
1340 		return (NULL);
1341 	}
1342 
1343 	/* Add our reservation */
1344 	if (bhndb_dw_retain(sc->bus_res, dwa, r))
1345 		return (NULL);
1346 
1347 	return (dwa);
1348 }
1349 
1350 /**
1351  * Activate a resource using any viable static or dynamic register window.
1352  *
1353  * @param sc The bhndb driver state.
1354  * @param child The child holding ownership of @p r.
1355  * @param type The type of the resource to be activated.
1356  * @param rid The resource ID of @p r.
1357  * @param r The resource to be activated
1358  * @param[out] indirect On error and if not NULL, will be set to 'true' if
1359  * the caller should instead use an indirect resource mapping.
1360  *
1361  * @retval 0 success
1362  * @retval non-zero activation failed.
1363  */
1364 static int
1365 bhndb_try_activate_resource(struct bhndb_softc *sc, device_t child, int type,
1366     int rid, struct resource *r, bool *indirect)
1367 {
1368 	struct bhndb_region	*region;
1369 	struct bhndb_dw_alloc	*dwa;
1370 	bhndb_priority_t	 dw_priority;
1371 	rman_res_t		 r_start, r_size;
1372 	rman_res_t		 parent_offset;
1373 	int			 error;
1374 
1375 	BHNDB_LOCK_ASSERT(sc, MA_NOTOWNED);
1376 
1377 	// TODO - IRQs
1378 	if (type != SYS_RES_MEMORY)
1379 		return (ENXIO);
1380 
1381 	if (indirect)
1382 		*indirect = false;
1383 
1384 	r_start = rman_get_start(r);
1385 	r_size = rman_get_size(r);
1386 
1387 	/* Activate native addrspace resources using the host address space */
1388 	if (bhndb_get_addrspace(sc, child) == BHNDB_ADDRSPACE_NATIVE) {
1389 		struct resource *parent;
1390 
1391 		/* Find the bridge resource referenced by the child */
1392 		parent = bhndb_find_resource_range(sc->bus_res, r_start,
1393 		    r_size);
1394 		if (parent == NULL) {
1395 			device_printf(sc->dev, "host resource not found "
1396 			     "for 0x%llx-0x%llx\n",
1397 			     (unsigned long long) r_start,
1398 			     (unsigned long long) r_start + r_size - 1);
1399 			return (ENOENT);
1400 		}
1401 
1402 		/* Initialize child resource with the real bus values */
1403 		error = bhndb_init_child_resource(r, parent,
1404 		    r_start - rman_get_start(parent), r_size);
1405 		if (error)
1406 			return (error);
1407 
1408 		/* Try to activate child resource */
1409 		return (rman_activate_resource(r));
1410 	}
1411 
1412 	/* Default to low priority */
1413 	dw_priority = BHNDB_PRIORITY_LOW;
1414 
1415 	/* Look for a bus region matching the resource's address range */
1416 	region = bhndb_find_resource_region(sc->bus_res, r_start, r_size);
1417 	if (region != NULL)
1418 		dw_priority = region->priority;
1419 
1420 	/* Prefer static mappings over consuming a dynamic windows. */
1421 	if (region && region->static_regwin) {
1422 		error = bhndb_activate_static_region(sc, region, child, type,
1423 		    rid, r);
1424 		if (error)
1425 			device_printf(sc->dev, "static window allocation "
1426 			     "for 0x%llx-0x%llx failed\n",
1427 			     (unsigned long long) r_start,
1428 			     (unsigned long long) r_start + r_size - 1);
1429 		return (error);
1430 	}
1431 
1432 	/* A dynamic window will be required; is this resource high enough
1433 	 * priority to be reserved a dynamic window? */
1434 	if (dw_priority < sc->bus_res->min_prio) {
1435 		if (indirect)
1436 			*indirect = true;
1437 
1438 		return (ENOMEM);
1439 	}
1440 
1441 	/* Find and retain a usable window */
1442 	BHNDB_LOCK(sc); {
1443 		dwa = bhndb_retain_dynamic_window(sc, r);
1444 	} BHNDB_UNLOCK(sc);
1445 
1446 	if (dwa == NULL) {
1447 		if (indirect)
1448 			*indirect = true;
1449 		return (ENOMEM);
1450 	}
1451 
1452 	/* Configure resource with its real bus values. */
1453 	parent_offset = dwa->win->win_offset;
1454 	parent_offset += r_start - dwa->target;
1455 
1456 	error = bhndb_init_child_resource(r, dwa->parent_res, parent_offset,
1457 	    dwa->win->win_size);
1458 	if (error)
1459 		goto failed;
1460 
1461 	/* Mark active */
1462 	if ((error = rman_activate_resource(r)))
1463 		goto failed;
1464 
1465 	return (0);
1466 
1467 failed:
1468 	/* Release our region allocation. */
1469 	BHNDB_LOCK(sc);
1470 	bhndb_dw_release(sc->bus_res, dwa, r);
1471 	BHNDB_UNLOCK(sc);
1472 
1473 	return (error);
1474 }
1475 
1476 /**
1477  * Default bhndb(4) implementation of BUS_ACTIVATE_RESOURCE().
1478  *
1479  * Maps resource activation requests to a viable static or dynamic
1480  * register window, if any.
1481  */
1482 static int
1483 bhndb_activate_resource(device_t dev, device_t child, int type, int rid,
1484     struct resource *r)
1485 {
1486 	struct bhndb_softc *sc = device_get_softc(dev);
1487 
1488 	return (bhndb_try_activate_resource(sc, child, type, rid, r, NULL));
1489 }
1490 
1491 /**
1492  * Default bhndb(4) implementation of BUS_DEACTIVATE_RESOURCE().
1493  */
1494 static int
1495 bhndb_deactivate_resource(device_t dev, device_t child, int type,
1496     int rid, struct resource *r)
1497 {
1498 	struct bhndb_dw_alloc	*dwa;
1499 	struct bhndb_softc	*sc;
1500 	struct rman		*rm;
1501 	int			 error;
1502 
1503 	sc = device_get_softc(dev);
1504 
1505 	if ((rm = bhndb_get_rman(sc, child, type)) == NULL)
1506 		return (EINVAL);
1507 
1508 	/* Mark inactive */
1509 	if ((error = rman_deactivate_resource(r)))
1510 		return (error);
1511 
1512 	/* Free any dynamic window allocation. */
1513 	if (bhndb_get_addrspace(sc, child) == BHNDB_ADDRSPACE_BRIDGED) {
1514 		BHNDB_LOCK(sc);
1515 		dwa = bhndb_dw_find_resource(sc->bus_res, r);
1516 		if (dwa != NULL)
1517 			bhndb_dw_release(sc->bus_res, dwa, r);
1518 		BHNDB_UNLOCK(sc);
1519 	}
1520 
1521 	return (0);
1522 }
1523 
1524 /**
1525  * Default bhndb(4) implementation of BUS_GET_RESOURCE_LIST().
1526  */
1527 static struct resource_list *
1528 bhndb_get_resource_list(device_t dev, device_t child)
1529 {
1530 	struct bhndb_devinfo *dinfo = device_get_ivars(child);
1531 	return (&dinfo->resources);
1532 }
1533 
1534 /**
1535  * Default bhndb(4) implementation of BHND_BUS_ACTIVATE_RESOURCE().
1536  *
1537  * For BHNDB_ADDRSPACE_NATIVE children, all resources may be assumed to
1538  * be activated by the bridge.
1539  *
1540  * For BHNDB_ADDRSPACE_BRIDGED children, attempts to activate a static register
1541  * window, a dynamic register window, or configures @p r as an indirect
1542  * resource -- in that order.
1543  */
1544 static int
1545 bhndb_activate_bhnd_resource(device_t dev, device_t child,
1546     int type, int rid, struct bhnd_resource *r)
1547 {
1548 	struct bhndb_softc	*sc;
1549 	struct bhndb_region	*region;
1550 	rman_res_t		 r_start, r_size;
1551 	int 			 error;
1552 	bool			 indirect;
1553 
1554 	KASSERT(!r->direct,
1555 	    ("direct flag set on inactive resource"));
1556 
1557 	KASSERT(!(rman_get_flags(r->res) & RF_ACTIVE),
1558 	    ("RF_ACTIVE set on inactive resource"));
1559 
1560 	sc = device_get_softc(dev);
1561 
1562 	r_start = rman_get_start(r->res);
1563 	r_size = rman_get_size(r->res);
1564 
1565 	/* Verify bridged address range's resource priority, and skip direct
1566 	 * allocation if the priority is too low. */
1567 	if (bhndb_get_addrspace(sc, child) == BHNDB_ADDRSPACE_BRIDGED) {
1568 		bhndb_priority_t r_prio;
1569 
1570 		region = bhndb_find_resource_region(sc->bus_res, r_start,
1571 		    r_size);
1572 		if (region != NULL)
1573 			r_prio = region->priority;
1574 		else
1575 			r_prio = BHNDB_PRIORITY_NONE;
1576 
1577 		/* If less than the minimum dynamic window priority, this
1578 		 * resource should always be indirect. */
1579 		if (r_prio < sc->bus_res->min_prio)
1580 			return (0);
1581 	}
1582 
1583 	/* Attempt direct activation */
1584 	error = bhndb_try_activate_resource(sc, child, type, rid, r->res,
1585 	    &indirect);
1586 	if (!error) {
1587 		r->direct = true;
1588 	} else if (indirect) {
1589 		/* The request was valid, but no viable register window is
1590 		 * available; indirection must be employed. */
1591 		error = 0;
1592 		r->direct = false;
1593 	}
1594 
1595 	if (BHNDB_DEBUG(PRIO) &&
1596 	    bhndb_get_addrspace(sc, child) == BHNDB_ADDRSPACE_BRIDGED)
1597 	{
1598 		device_printf(child, "activated 0x%llx-0x%llx as %s "
1599 		    "resource\n",
1600 		    (unsigned long long) r_start,
1601 		    (unsigned long long) r_start + r_size - 1,
1602 		    r->direct ? "direct" : "indirect");
1603 	}
1604 
1605 	return (error);
1606 };
1607 
1608 /**
1609  * Default bhndb(4) implementation of BHND_BUS_DEACTIVATE_RESOURCE().
1610  */
1611 static int
1612 bhndb_deactivate_bhnd_resource(device_t dev, device_t child,
1613     int type, int rid, struct bhnd_resource *r)
1614 {
1615 	int error;
1616 
1617 	/* Indirect resources don't require activation */
1618 	if (!r->direct)
1619 		return (0);
1620 
1621 	KASSERT(rman_get_flags(r->res) & RF_ACTIVE,
1622 	    ("RF_ACTIVE not set on direct resource"));
1623 
1624 	/* Perform deactivation */
1625 	error = bus_deactivate_resource(child, type, rid, r->res);
1626 	if (!error)
1627 		r->direct = false;
1628 
1629 	return (error);
1630 };
1631 
1632 /**
1633  * Slow path for bhndb_io_resource().
1634  *
1635  * Iterates over the existing allocated dynamic windows looking for a viable
1636  * in-use region; the first matching region is returned.
1637  */
1638 static struct bhndb_dw_alloc *
1639 bhndb_io_resource_slow(struct bhndb_softc *sc, bus_addr_t addr,
1640     bus_size_t size, bus_size_t *offset)
1641 {
1642 	struct bhndb_resources	*br;
1643 	struct bhndb_dw_alloc	*dwa;
1644 
1645 	BHNDB_LOCK_ASSERT(sc, MA_OWNED);
1646 
1647 	br = sc->bus_res;
1648 
1649 	/* Search for an existing dynamic mapping of this address range.
1650 	 * Static regions are not searched, as a statically mapped
1651 	 * region would never be allocated as an indirect resource. */
1652 	for (size_t i = 0; i < br->dwa_count; i++) {
1653 		const struct bhndb_regwin *win;
1654 
1655 		dwa = &br->dw_alloc[i];
1656 		win = dwa->win;
1657 
1658 		KASSERT(win->win_type == BHNDB_REGWIN_T_DYN,
1659 			("invalid register window type"));
1660 
1661 		/* Verify the range */
1662 		if (addr < dwa->target)
1663 			continue;
1664 
1665 		if (addr + size > dwa->target + win->win_size)
1666 			continue;
1667 
1668 		/* Found */
1669 		*offset = dwa->win->win_offset;
1670 		*offset += addr - dwa->target;
1671 
1672 		return (dwa);
1673 	}
1674 
1675 	/* not found */
1676 	return (NULL);
1677 }
1678 
1679 /**
1680  * Find the bridge resource to be used for I/O requests.
1681  *
1682  * @param sc Bridge driver state.
1683  * @param addr The I/O target address.
1684  * @param size The size of the I/O operation to be performed at @p addr.
1685  * @param[out] offset The offset within the returned resource at which
1686  * to perform the I/O request.
1687  */
1688 static inline struct bhndb_dw_alloc *
1689 bhndb_io_resource(struct bhndb_softc *sc, bus_addr_t addr, bus_size_t size,
1690     bus_size_t *offset)
1691 {
1692 	struct bhndb_resources	*br;
1693 	struct bhndb_dw_alloc	*dwa;
1694 	int			 error;
1695 
1696 	BHNDB_LOCK_ASSERT(sc, MA_OWNED);
1697 
1698 	br = sc->bus_res;
1699 
1700 	/* Try to fetch a free window */
1701 	dwa = bhndb_dw_next_free(br);
1702 
1703 	/*
1704 	 * If no dynamic windows are available, look for an existing
1705 	 * region that maps the target range.
1706 	 *
1707 	 * If none are found, this is a child driver bug -- our window
1708 	 * over-commit should only fail in the case where a child driver leaks
1709 	 * resources, or perform operations out-of-order.
1710 	 *
1711 	 * Broadcom HND chipsets are designed to not require register window
1712 	 * swapping during execution; as long as the child devices are
1713 	 * attached/detached correctly, using the hardware's required order
1714 	 * of operations, there should always be a window available for the
1715 	 * current operation.
1716 	 */
1717 	if (dwa == NULL) {
1718 		dwa = bhndb_io_resource_slow(sc, addr, size, offset);
1719 		if (dwa == NULL) {
1720 			panic("register windows exhausted attempting to map "
1721 			    "0x%llx-0x%llx\n",
1722 			    (unsigned long long) addr,
1723 			    (unsigned long long) addr+size-1);
1724 		}
1725 
1726 		return (dwa);
1727 	}
1728 
1729 	/* Adjust the window if the I/O request won't fit in the current
1730 	 * target range. */
1731 	if (addr < dwa->target ||
1732 	    addr > dwa->target + dwa->win->win_size ||
1733 	    (dwa->target + dwa->win->win_size) - addr < size)
1734 	{
1735 		error = bhndb_dw_set_addr(sc->dev, sc->bus_res, dwa, addr,
1736 		    size);
1737 		if (error) {
1738 		    panic("failed to set register window target mapping "
1739 			    "0x%llx-0x%llx\n",
1740 			    (unsigned long long) addr,
1741 			    (unsigned long long) addr+size-1);
1742 		}
1743 	}
1744 
1745 	/* Calculate the offset and return */
1746 	*offset = (addr - dwa->target) + dwa->win->win_offset;
1747 	return (dwa);
1748 }
1749 
1750 /*
1751  * BHND_BUS_(READ|WRITE_* implementations
1752  */
1753 
1754 /* bhndb_bus_(read|write) common implementation */
1755 #define	BHNDB_IO_COMMON_SETUP(_io_size)				\
1756 	struct bhndb_softc	*sc;				\
1757 	struct bhndb_dw_alloc	*dwa;				\
1758 	struct resource		*io_res;			\
1759 	bus_size_t		 io_offset;			\
1760 								\
1761 	sc = device_get_softc(dev);				\
1762 								\
1763 	BHNDB_LOCK(sc);						\
1764 	dwa = bhndb_io_resource(sc, rman_get_start(r->res) +	\
1765 	    offset, _io_size, &io_offset);			\
1766 	io_res = dwa->parent_res;				\
1767 								\
1768 	KASSERT(!r->direct,					\
1769 	    ("bhnd_bus slow path used for direct resource"));	\
1770 								\
1771 	KASSERT(rman_get_flags(io_res) & RF_ACTIVE,		\
1772 	    ("i/o resource is not active"));
1773 
1774 #define	BHNDB_IO_COMMON_TEARDOWN()				\
1775 	BHNDB_UNLOCK(sc);
1776 
1777 /* Defines a bhndb_bus_read_* method implementation */
1778 #define	BHNDB_IO_READ(_type, _name)				\
1779 static _type							\
1780 bhndb_bus_read_ ## _name (device_t dev, device_t child,		\
1781     struct bhnd_resource *r, bus_size_t offset)			\
1782 {								\
1783 	_type v;						\
1784 	BHNDB_IO_COMMON_SETUP(sizeof(_type));			\
1785 	v = bus_read_ ## _name (io_res, io_offset);		\
1786 	BHNDB_IO_COMMON_TEARDOWN();				\
1787 								\
1788 	return (v);						\
1789 }
1790 
1791 /* Defines a bhndb_bus_write_* method implementation */
1792 #define	BHNDB_IO_WRITE(_type, _name)				\
1793 static void							\
1794 bhndb_bus_write_ ## _name (device_t dev, device_t child,	\
1795     struct bhnd_resource *r, bus_size_t offset, _type value)	\
1796 {								\
1797 	BHNDB_IO_COMMON_SETUP(sizeof(_type));			\
1798 	bus_write_ ## _name (io_res, io_offset, value);		\
1799 	BHNDB_IO_COMMON_TEARDOWN();				\
1800 }
1801 
1802 /* Defines a bhndb_bus_(read|write|set)_(multi|region)_* method */
1803 #define	BHNDB_IO_MISC(_type, _ptr, _op, _size)			\
1804 static void							\
1805 bhndb_bus_ ## _op ## _ ## _size (device_t dev,			\
1806     device_t child, struct bhnd_resource *r, bus_size_t offset,	\
1807     _type _ptr datap, bus_size_t count)				\
1808 {								\
1809 	BHNDB_IO_COMMON_SETUP(sizeof(_type) * count);		\
1810 	bus_ ## _op ## _ ## _size (io_res, io_offset,		\
1811 	    datap, count);					\
1812 	BHNDB_IO_COMMON_TEARDOWN();				\
1813 }
1814 
1815 /* Defines a complete set of read/write methods */
1816 #define	BHNDB_IO_METHODS(_type, _size)				\
1817 	BHNDB_IO_READ(_type, _size)				\
1818 	BHNDB_IO_WRITE(_type, _size)				\
1819 								\
1820 	BHNDB_IO_READ(_type, stream_ ## _size)			\
1821 	BHNDB_IO_WRITE(_type, stream_ ## _size)			\
1822 								\
1823 	BHNDB_IO_MISC(_type, *, read_multi, _size)		\
1824 	BHNDB_IO_MISC(_type, *, write_multi, _size)		\
1825 								\
1826 	BHNDB_IO_MISC(_type, *, read_multi_stream, _size)	\
1827 	BHNDB_IO_MISC(_type, *, write_multi_stream, _size)	\
1828 								\
1829 	BHNDB_IO_MISC(_type,  , set_multi, _size)		\
1830 	BHNDB_IO_MISC(_type,  , set_region, _size)		\
1831 	BHNDB_IO_MISC(_type, *, read_region, _size)		\
1832 	BHNDB_IO_MISC(_type, *, write_region, _size)		\
1833 								\
1834 	BHNDB_IO_MISC(_type, *, read_region_stream, _size)	\
1835 	BHNDB_IO_MISC(_type, *, write_region_stream, _size)
1836 
1837 BHNDB_IO_METHODS(uint8_t, 1);
1838 BHNDB_IO_METHODS(uint16_t, 2);
1839 BHNDB_IO_METHODS(uint32_t, 4);
1840 
1841 /**
1842  * Default bhndb(4) implementation of BHND_BUS_BARRIER().
1843  */
1844 static void
1845 bhndb_bus_barrier(device_t dev, device_t child, struct bhnd_resource *r,
1846     bus_size_t offset, bus_size_t length, int flags)
1847 {
1848 	BHNDB_IO_COMMON_SETUP(length);
1849 
1850 	bus_barrier(io_res, io_offset + offset, length, flags);
1851 
1852 	BHNDB_IO_COMMON_TEARDOWN();
1853 }
1854 
1855 /**
1856  * Default bhndb(4) implementation of BUS_SETUP_INTR().
1857  */
1858 static int
1859 bhndb_setup_intr(device_t dev, device_t child, struct resource *r,
1860     int flags, driver_filter_t filter, driver_intr_t handler, void *arg,
1861     void **cookiep)
1862 {
1863 	// TODO
1864 	return (EOPNOTSUPP);
1865 }
1866 
1867 /**
1868  * Default bhndb(4) implementation of BUS_TEARDOWN_INTR().
1869  */
1870 static int
1871 bhndb_teardown_intr(device_t dev, device_t child, struct resource *r,
1872     void *cookie)
1873 {
1874 	// TODO
1875 	return (EOPNOTSUPP);
1876 }
1877 
1878 /**
1879  * Default bhndb(4) implementation of BUS_CONFIG_INTR().
1880  */
1881 static int
1882 bhndb_config_intr(device_t dev, int irq, enum intr_trigger trig,
1883     enum intr_polarity pol)
1884 {
1885 	// TODO
1886 	return (EOPNOTSUPP);
1887 }
1888 
1889 /**
1890  * Default bhndb(4) implementation of BUS_BIND_INTR().
1891  */
1892 static int
1893 bhndb_bind_intr(device_t dev, device_t child, struct resource *r, int cpu)
1894 {
1895 	// TODO
1896 	return (EOPNOTSUPP);
1897 }
1898 
1899 /**
1900  * Default bhndb(4) implementation of BUS_DESCRIBE_INTR().
1901  */
1902 static int
1903 bhndb_describe_intr(device_t dev, device_t child, struct resource *irq, void *cookie,
1904     const char *descr)
1905 {
1906 	// TODO
1907 	return (EOPNOTSUPP);
1908 }
1909 
1910 /**
1911  * Default bhndb(4) implementation of BUS_GET_DMA_TAG().
1912  */
1913 static bus_dma_tag_t
1914 bhndb_get_dma_tag(device_t dev, device_t child)
1915 {
1916 	// TODO
1917 	return (NULL);
1918 }
1919 
1920 static device_method_t bhndb_methods[] = {
1921 	/* Device interface */ \
1922 	DEVMETHOD(device_probe,			bhndb_generic_probe),
1923 	DEVMETHOD(device_detach,		bhndb_generic_detach),
1924 	DEVMETHOD(device_shutdown,		bus_generic_shutdown),
1925 	DEVMETHOD(device_suspend,		bhndb_generic_suspend),
1926 	DEVMETHOD(device_resume,		bhndb_generic_resume),
1927 
1928 	/* Bus interface */
1929 	DEVMETHOD(bus_probe_nomatch,		bhndb_probe_nomatch),
1930 	DEVMETHOD(bus_print_child,		bhndb_print_child),
1931 	DEVMETHOD(bus_child_pnpinfo_str,	bhndb_child_pnpinfo_str),
1932 	DEVMETHOD(bus_child_location_str,	bhndb_child_location_str),
1933 	DEVMETHOD(bus_add_child,		bhndb_add_child),
1934 	DEVMETHOD(bus_child_deleted,		bhndb_child_deleted),
1935 
1936 	DEVMETHOD(bus_alloc_resource,		bhndb_alloc_resource),
1937 	DEVMETHOD(bus_release_resource,		bhndb_release_resource),
1938 	DEVMETHOD(bus_activate_resource,	bhndb_activate_resource),
1939 	DEVMETHOD(bus_deactivate_resource,	bhndb_deactivate_resource),
1940 
1941 	DEVMETHOD(bus_setup_intr,		bhndb_setup_intr),
1942 	DEVMETHOD(bus_teardown_intr,		bhndb_teardown_intr),
1943 	DEVMETHOD(bus_config_intr,		bhndb_config_intr),
1944 	DEVMETHOD(bus_bind_intr,		bhndb_bind_intr),
1945 	DEVMETHOD(bus_describe_intr,		bhndb_describe_intr),
1946 
1947 	DEVMETHOD(bus_get_dma_tag,		bhndb_get_dma_tag),
1948 
1949 	DEVMETHOD(bus_adjust_resource,		bhndb_adjust_resource),
1950 	DEVMETHOD(bus_set_resource,		bus_generic_rl_set_resource),
1951 	DEVMETHOD(bus_get_resource,		bus_generic_rl_get_resource),
1952 	DEVMETHOD(bus_delete_resource,		bus_generic_rl_delete_resource),
1953 	DEVMETHOD(bus_get_resource_list,	bhndb_get_resource_list),
1954 
1955 	DEVMETHOD(bus_read_ivar,		bhndb_read_ivar),
1956 	DEVMETHOD(bus_write_ivar,		bhndb_write_ivar),
1957 
1958 	/* BHNDB interface */
1959 	DEVMETHOD(bhndb_get_chipid,		bhndb_get_chipid),
1960 	DEVMETHOD(bhndb_init_full_config,	bhndb_generic_init_full_config),
1961 	DEVMETHOD(bhndb_find_hostb_device,	bhndb_find_hostb_device),
1962 	DEVMETHOD(bhndb_suspend_resource,	bhndb_suspend_resource),
1963 	DEVMETHOD(bhndb_resume_resource,	bhndb_resume_resource),
1964 
1965 	/* BHND interface */
1966 	DEVMETHOD(bhnd_bus_is_hw_disabled,	bhndb_is_hw_disabled),
1967 	DEVMETHOD(bhnd_bus_get_chipid,		bhndb_get_chipid),
1968 	DEVMETHOD(bhnd_bus_activate_resource,	bhndb_activate_bhnd_resource),
1969 	DEVMETHOD(bhnd_bus_deactivate_resource,	bhndb_deactivate_bhnd_resource),
1970 	DEVMETHOD(bhnd_bus_get_nvram_var,	bhnd_bus_generic_get_nvram_var),
1971 	DEVMETHOD(bhnd_bus_read_1,		bhndb_bus_read_1),
1972 	DEVMETHOD(bhnd_bus_read_2,		bhndb_bus_read_2),
1973 	DEVMETHOD(bhnd_bus_read_4,		bhndb_bus_read_4),
1974 	DEVMETHOD(bhnd_bus_write_1,		bhndb_bus_write_1),
1975 	DEVMETHOD(bhnd_bus_write_2,		bhndb_bus_write_2),
1976 	DEVMETHOD(bhnd_bus_write_4,		bhndb_bus_write_4),
1977 
1978 	DEVMETHOD(bhnd_bus_read_stream_1,	bhndb_bus_read_stream_1),
1979 	DEVMETHOD(bhnd_bus_read_stream_2,	bhndb_bus_read_stream_2),
1980 	DEVMETHOD(bhnd_bus_read_stream_4,	bhndb_bus_read_stream_4),
1981 	DEVMETHOD(bhnd_bus_write_stream_1,	bhndb_bus_write_stream_1),
1982 	DEVMETHOD(bhnd_bus_write_stream_2,	bhndb_bus_write_stream_2),
1983 	DEVMETHOD(bhnd_bus_write_stream_4,	bhndb_bus_write_stream_4),
1984 
1985 	DEVMETHOD(bhnd_bus_read_multi_1,	bhndb_bus_read_multi_1),
1986 	DEVMETHOD(bhnd_bus_read_multi_2,	bhndb_bus_read_multi_2),
1987 	DEVMETHOD(bhnd_bus_read_multi_4,	bhndb_bus_read_multi_4),
1988 	DEVMETHOD(bhnd_bus_write_multi_1,	bhndb_bus_write_multi_1),
1989 	DEVMETHOD(bhnd_bus_write_multi_2,	bhndb_bus_write_multi_2),
1990 	DEVMETHOD(bhnd_bus_write_multi_4,	bhndb_bus_write_multi_4),
1991 
1992 	DEVMETHOD(bhnd_bus_read_multi_stream_1,	bhndb_bus_read_multi_stream_1),
1993 	DEVMETHOD(bhnd_bus_read_multi_stream_2,	bhndb_bus_read_multi_stream_2),
1994 	DEVMETHOD(bhnd_bus_read_multi_stream_4,	bhndb_bus_read_multi_stream_4),
1995 	DEVMETHOD(bhnd_bus_write_multi_stream_1,bhndb_bus_write_multi_stream_1),
1996 	DEVMETHOD(bhnd_bus_write_multi_stream_2,bhndb_bus_write_multi_stream_2),
1997 	DEVMETHOD(bhnd_bus_write_multi_stream_4,bhndb_bus_write_multi_stream_4),
1998 
1999 	DEVMETHOD(bhnd_bus_set_multi_1,		bhndb_bus_set_multi_1),
2000 	DEVMETHOD(bhnd_bus_set_multi_2,		bhndb_bus_set_multi_2),
2001 	DEVMETHOD(bhnd_bus_set_multi_4,		bhndb_bus_set_multi_4),
2002 	DEVMETHOD(bhnd_bus_set_region_1,	bhndb_bus_set_region_1),
2003 	DEVMETHOD(bhnd_bus_set_region_2,	bhndb_bus_set_region_2),
2004 	DEVMETHOD(bhnd_bus_set_region_4,	bhndb_bus_set_region_4),
2005 
2006 	DEVMETHOD(bhnd_bus_read_region_1,	bhndb_bus_read_region_1),
2007 	DEVMETHOD(bhnd_bus_read_region_2,	bhndb_bus_read_region_2),
2008 	DEVMETHOD(bhnd_bus_read_region_4,	bhndb_bus_read_region_4),
2009 	DEVMETHOD(bhnd_bus_write_region_1,	bhndb_bus_write_region_1),
2010 	DEVMETHOD(bhnd_bus_write_region_2,	bhndb_bus_write_region_2),
2011 	DEVMETHOD(bhnd_bus_write_region_4,	bhndb_bus_write_region_4),
2012 
2013 	DEVMETHOD(bhnd_bus_read_region_stream_1,bhndb_bus_read_region_stream_1),
2014 	DEVMETHOD(bhnd_bus_read_region_stream_2,bhndb_bus_read_region_stream_2),
2015 	DEVMETHOD(bhnd_bus_read_region_stream_4,bhndb_bus_read_region_stream_4),
2016 	DEVMETHOD(bhnd_bus_write_region_stream_1,bhndb_bus_write_region_stream_1),
2017 	DEVMETHOD(bhnd_bus_write_region_stream_2,bhndb_bus_write_region_stream_2),
2018 	DEVMETHOD(bhnd_bus_write_region_stream_4,bhndb_bus_write_region_stream_4),
2019 
2020 	DEVMETHOD(bhnd_bus_barrier,		bhndb_bus_barrier),
2021 
2022 	DEVMETHOD_END
2023 };
2024 
2025 devclass_t bhndb_devclass;
2026 
2027 DEFINE_CLASS_0(bhndb, bhndb_driver, bhndb_methods, sizeof(struct bhndb_softc));
2028 
2029 MODULE_VERSION(bhndb, 1);
2030 MODULE_DEPEND(bhndb, bhnd, 1, 1, 1);
2031