xref: /freebsd/sys/dev/bhnd/siba/siba.c (revision 8ef24a0d4b28fe230e20637f56869cc4148cd2ca)
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 #include <sys/param.h>
34 #include <sys/bus.h>
35 #include <sys/kernel.h>
36 #include <sys/malloc.h>
37 #include <sys/module.h>
38 #include <sys/systm.h>
39 
40 #include <machine/bus.h>
41 
42 #include <dev/bhnd/cores/chipc/chipcreg.h>
43 
44 #include "sibareg.h"
45 #include "sibavar.h"
46 
47 int
48 siba_probe(device_t dev)
49 {
50 	device_set_desc(dev, "SIBA BHND bus");
51 	return (BUS_PROBE_DEFAULT);
52 }
53 
54 int
55 siba_attach(device_t dev)
56 {
57 	struct siba_devinfo	*dinfo;
58 	struct siba_softc	*sc;
59 	device_t		*devs;
60 	int			 ndevs;
61 	int			 error;
62 
63 	sc = device_get_softc(dev);
64 	sc->dev = dev;
65 
66 	/* Fetch references to the siba SIBA_CFG* blocks for all
67 	 * registered devices */
68 	if ((error = device_get_children(dev, &devs, &ndevs)))
69 		return (error);
70 
71 	for (int i = 0; i < ndevs; i++) {
72 		struct siba_addrspace	*addrspace;
73 		struct siba_port	*port;
74 
75 		dinfo = device_get_ivars(devs[i]);
76 
77 		KASSERT(!device_is_suspended(devs[i]),
78 		    ("siba(4) stateful suspend handling requires that devices "
79 		        "not be suspended before siba_attach()"));
80 
81 		/* Fetch the core register address space */
82 		port = siba_dinfo_get_port(dinfo, BHND_PORT_DEVICE, 0);
83 		if (port == NULL) {
84 			error = ENXIO;
85 			goto cleanup;
86 		}
87 
88 		addrspace = siba_find_port_addrspace(port, SIBA_ADDRSPACE_CORE);
89 		if (addrspace == NULL) {
90 			error = ENXIO;
91 			goto cleanup;
92 		}
93 
94 		/*
95 		 * Map the per-core configuration blocks
96 		 */
97 		KASSERT(dinfo->core_id.num_cfg_blocks <= SIBA_CFG_NUM_MAX,
98 		    ("config block count %u out of range",
99 		        dinfo->core_id.num_cfg_blocks));
100 
101 		for (u_int cfgidx = 0; cfgidx < dinfo->core_id.num_cfg_blocks;
102 		    cfgidx++)
103 		{
104 			rman_res_t	r_start, r_count, r_end;
105 
106 			/* Determine the config block's address range; configuration
107 			 * blocks are allocated starting at SIBA_CFG0_OFFSET,
108 			 * growing downwards. */
109 			r_start = addrspace->sa_base + SIBA_CFG0_OFFSET;
110 			r_start -= cfgidx * SIBA_CFG_SIZE;
111 
112 			r_count = SIBA_CFG_SIZE;
113 			r_end = r_start + r_count - 1;
114 
115 			/* Allocate the config resource */
116 			dinfo->cfg_rid[cfgidx] = 0;
117 			dinfo->cfg[cfgidx] = bhnd_alloc_resource(dev,
118 			    SYS_RES_MEMORY, &dinfo->cfg_rid[cfgidx], r_start,
119 			    r_end, r_count, RF_ACTIVE);
120 
121 			if (dinfo->cfg[cfgidx] == NULL) {
122 			     device_printf(dev, "failed allocating CFG_%u for "
123 			     "core %d\n", cfgidx, i);
124 			     error = ENXIO;
125 			     goto cleanup;
126 			}
127 		}
128 	}
129 
130 cleanup:
131 	free(devs, M_BHND);
132 	if (error)
133 		return (error);
134 
135 	/* Delegate remainder to standard bhnd method implementation */
136 	return (bhnd_generic_attach(dev));
137 }
138 
139 int
140 siba_detach(device_t dev)
141 {
142 	return (bhnd_generic_detach(dev));
143 }
144 
145 int
146 siba_resume(device_t dev)
147 {
148 	return (bhnd_generic_resume(dev));
149 }
150 
151 int
152 siba_suspend(device_t dev)
153 {
154 	return (bhnd_generic_suspend(dev));
155 }
156 
157 static int
158 siba_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
159 {
160 	const struct siba_devinfo *dinfo;
161 	const struct bhnd_core_info *cfg;
162 
163 	dinfo = device_get_ivars(child);
164 	cfg = &dinfo->core_id.core_info;
165 
166 	switch (index) {
167 	case BHND_IVAR_VENDOR:
168 		*result = cfg->vendor;
169 		return (0);
170 	case BHND_IVAR_DEVICE:
171 		*result = cfg->device;
172 		return (0);
173 	case BHND_IVAR_HWREV:
174 		*result = cfg->hwrev;
175 		return (0);
176 	case BHND_IVAR_DEVICE_CLASS:
177 		*result = bhnd_core_class(cfg);
178 		return (0);
179 	case BHND_IVAR_VENDOR_NAME:
180 		*result = (uintptr_t) bhnd_vendor_name(cfg->vendor);
181 		return (0);
182 	case BHND_IVAR_DEVICE_NAME:
183 		*result = (uintptr_t) bhnd_core_name(cfg);
184 		return (0);
185 	case BHND_IVAR_CORE_INDEX:
186 		*result = cfg->core_idx;
187 		return (0);
188 	case BHND_IVAR_CORE_UNIT:
189 		*result = cfg->unit;
190 		return (0);
191 	default:
192 		return (ENOENT);
193 	}
194 }
195 
196 static int
197 siba_write_ivar(device_t dev, device_t child, int index, uintptr_t value)
198 {
199 	switch (index) {
200 	case BHND_IVAR_VENDOR:
201 	case BHND_IVAR_DEVICE:
202 	case BHND_IVAR_HWREV:
203 	case BHND_IVAR_DEVICE_CLASS:
204 	case BHND_IVAR_VENDOR_NAME:
205 	case BHND_IVAR_DEVICE_NAME:
206 	case BHND_IVAR_CORE_INDEX:
207 	case BHND_IVAR_CORE_UNIT:
208 		return (EINVAL);
209 	default:
210 		return (ENOENT);
211 	}
212 }
213 
214 static void
215 siba_child_deleted(device_t dev, device_t child)
216 {
217 	struct siba_devinfo *dinfo = device_get_ivars(child);
218 	if (dinfo != NULL)
219 		siba_free_dinfo(dev, dinfo);
220 }
221 
222 static struct resource_list *
223 siba_get_resource_list(device_t dev, device_t child)
224 {
225 	struct siba_devinfo *dinfo = device_get_ivars(child);
226 	return (&dinfo->resources);
227 }
228 
229 static device_t
230 siba_find_hostb_device(device_t dev)
231 {
232 	struct siba_softc *sc = device_get_softc(dev);
233 
234 	/* This is set (or not) by the concrete siba driver subclass. */
235 	return (sc->hostb_dev);
236 }
237 
238 static int
239 siba_reset_core(device_t dev, device_t child, uint16_t flags)
240 {
241 	struct siba_devinfo *dinfo;
242 
243 	if (device_get_parent(child) != dev)
244 		BHND_BUS_RESET_CORE(device_get_parent(dev), child, flags);
245 
246 	dinfo = device_get_ivars(child);
247 
248 	/* Can't reset the core without access to the CFG0 registers */
249 	if (dinfo->cfg[0] == NULL)
250 		return (ENODEV);
251 
252 	// TODO - perform reset
253 
254 	return (ENXIO);
255 }
256 
257 static int
258 siba_suspend_core(device_t dev, device_t child)
259 {
260 	struct siba_devinfo *dinfo;
261 
262 	if (device_get_parent(child) != dev)
263 		BHND_BUS_SUSPEND_CORE(device_get_parent(dev), child);
264 
265 	dinfo = device_get_ivars(child);
266 
267 	/* Can't suspend the core without access to the CFG0 registers */
268 	if (dinfo->cfg[0] == NULL)
269 		return (ENODEV);
270 
271 	// TODO - perform suspend
272 
273 	return (ENXIO);
274 }
275 
276 
277 static u_int
278 siba_get_port_count(device_t dev, device_t child, bhnd_port_type type)
279 {
280 	struct siba_devinfo *dinfo;
281 
282 	/* delegate non-bus-attached devices to our parent */
283 	if (device_get_parent(child) != dev)
284 		return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), child,
285 		    type));
286 
287 	dinfo = device_get_ivars(child);
288 
289 	/* We advertise exactly one port of any type */
290 	if (siba_dinfo_get_port(dinfo, type, 0) != NULL)
291 		return (1);
292 
293 	return (0);
294 }
295 
296 static u_int
297 siba_get_region_count(device_t dev, device_t child, bhnd_port_type type,
298     u_int port_num)
299 {
300 	struct siba_devinfo	*dinfo;
301 	struct siba_port	*port;
302 
303 	/* delegate non-bus-attached devices to our parent */
304 	if (device_get_parent(child) != dev)
305 		return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), child,
306 		    type, port_num));
307 
308 	dinfo = device_get_ivars(child);
309 	port = siba_dinfo_get_port(dinfo, type, port_num);
310 	if (port == NULL)
311 		return (0);
312 
313 	return (port->sp_num_addrs);
314 }
315 
316 static int
317 siba_get_port_rid(device_t dev, device_t child, bhnd_port_type port_type,
318     u_int port_num, u_int region_num)
319 {
320 	struct siba_devinfo	*dinfo;
321 	struct siba_port	*port;
322 	struct siba_addrspace	*addrspace;
323 
324 	/* delegate non-bus-attached devices to our parent */
325 	if (device_get_parent(child) != dev)
326 		return (BHND_BUS_GET_PORT_RID(device_get_parent(dev), child,
327 		    port_type, port_num, region_num));
328 
329 	dinfo = device_get_ivars(child);
330 	port = siba_dinfo_get_port(dinfo, port_type, port_num);
331 	if (port == NULL)
332 		return (-1);
333 
334 	STAILQ_FOREACH(addrspace, &port->sp_addrs, sa_link) {
335 		if (addrspace->sa_region_num == region_num)
336 			return (addrspace->sa_rid);
337 	}
338 
339 	/* not found */
340 	return (-1);
341 }
342 
343 static int
344 siba_decode_port_rid(device_t dev, device_t child, int type, int rid,
345     bhnd_port_type *port_type, u_int *port_num, u_int *region_num)
346 {
347 	struct siba_devinfo	*dinfo;
348 	struct siba_port	*port;
349 	struct siba_addrspace	*addrspace;
350 
351 	/* delegate non-bus-attached devices to our parent */
352 	if (device_get_parent(child) != dev)
353 		return (BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), child,
354 		    type, rid, port_type, port_num, region_num));
355 
356 	dinfo = device_get_ivars(child);
357 
358 	/* Ports are always memory mapped */
359 	if (type != SYS_RES_MEMORY)
360 		return (EINVAL);
361 
362 	/* Starting with the most likely device list, search all three port
363 	 * lists */
364 	bhnd_port_type types[] = {
365 	    BHND_PORT_DEVICE,
366 	    BHND_PORT_AGENT,
367 	    BHND_PORT_BRIDGE
368 	};
369 
370 	for (int i = 0; i < nitems(types); i++) {
371 		port = siba_dinfo_get_port(dinfo, types[i], 0);
372 		if (port == NULL)
373 			continue;
374 
375 		STAILQ_FOREACH(addrspace, &port->sp_addrs, sa_link) {
376 			if (addrspace->sa_rid != rid)
377 				continue;
378 
379 			*port_type = port->sp_type;
380 			*port_num = port->sp_num;
381 			*region_num = addrspace->sa_region_num;
382 		}
383 	}
384 
385 	return (ENOENT);
386 }
387 
388 static int
389 siba_get_region_addr(device_t dev, device_t child, bhnd_port_type port_type,
390     u_int port_num, u_int region_num, bhnd_addr_t *addr, bhnd_size_t *size)
391 {
392 	struct siba_devinfo	*dinfo;
393 	struct siba_port	*port;
394 	struct siba_addrspace	*addrspace;
395 
396 	/* delegate non-bus-attached devices to our parent */
397 	if (device_get_parent(child) != dev) {
398 		return (BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), child,
399 		    port_type, port_num, region_num, addr, size));
400 	}
401 
402 	dinfo = device_get_ivars(child);
403 	port = siba_dinfo_get_port(dinfo, port_type, port_num);
404 	if (port == NULL)
405 		return (ENOENT);
406 
407 	STAILQ_FOREACH(addrspace, &port->sp_addrs, sa_link) {
408 		if (addrspace->sa_region_num != region_num)
409 			continue;
410 
411 		*addr = addrspace->sa_base;
412 		*size = addrspace->sa_size;
413 		return (0);
414 	}
415 
416 	return (ENOENT);
417 }
418 
419 
420 /**
421  * Register all address space mappings for @p di.
422  *
423  * @param dev The siba bus device.
424  * @param di The device info instance on which to register all address
425  * space entries.
426  * @param r A resource mapping the enumeration table block for @p di.
427  */
428 static int
429 siba_register_addrspaces(device_t dev, struct siba_devinfo *di,
430     struct resource *r)
431 {
432 	struct siba_core_id	*cid;
433 	uint32_t		 addr;
434 	uint32_t		 size;
435 	u_int			 region_num;
436 	int			 error;
437 
438 	cid = &di->core_id;
439 
440 	/* Region numbers must be assigned in order, but our siba address
441 	 * space IDs may be sparsely allocated; thus, we track
442 	 * the region index separately. */
443 	region_num = 0;
444 
445 	/* Register the device address space entries */
446 	for (uint8_t sid = 0; sid < di->core_id.num_addrspace; sid++) {
447 		uint32_t	adm;
448 		u_int		adm_offset;
449 		uint32_t	bus_reserved;
450 
451 		/* Determine the register offset */
452 		adm_offset = siba_admatch_offset(sid);
453 		if (adm_offset == 0) {
454 		    device_printf(dev, "addrspace %hhu is unsupported", sid);
455 		    return (ENODEV);
456 		}
457 
458 		/* Fetch the address match register value */
459 		adm = bus_read_4(r, adm_offset);
460 
461 		/* Skip disabled entries */
462 		if (adm & SIBA_AM_ADEN)
463 			continue;
464 
465 		/* Parse the value */
466 		if ((error = siba_parse_admatch(adm, &addr, &size))) {
467 			device_printf(dev, "failed to decode address "
468 			    " match register value 0x%x\n", adm);
469 			return (error);
470 		}
471 
472 		/* If this is the device's core/enumeration addrespace,
473 		 * reserve the Sonics configuration register blocks for the
474 		 * use of our bus. */
475 		bus_reserved = 0;
476 		if (sid == SIBA_ADDRSPACE_CORE)
477 			bus_reserved = cid->num_cfg_blocks * SIBA_CFG_SIZE;
478 
479 		/* Append the region info */
480 		error = siba_append_dinfo_region(di, BHND_PORT_DEVICE, 0,
481 		    region_num, sid, addr, size, bus_reserved);
482 		if (error)
483 			return (error);
484 
485 
486 		region_num++;
487 	}
488 
489 	return (0);
490 }
491 
492 /**
493  * Scan the core table and add all valid discovered cores to
494  * the bus.
495  *
496  * @param dev The siba bus device.
497  * @param chipid The chip identifier, if the device does not provide a
498  * ChipCommon core. Should o NULL otherwise.
499  */
500 int
501 siba_add_children(device_t dev, const struct bhnd_chipid *chipid)
502 {
503 	struct bhnd_chipid	 ccid;
504 	struct bhnd_core_info	*cores;
505 	struct siba_devinfo	*dinfo;
506 	struct resource		*r;
507 	int			 rid;
508 	int			 error;
509 
510 	dinfo = NULL;
511 	cores = NULL;
512 	r = NULL;
513 
514 	/*
515 	 * Try to determine the number of device cores via the ChipCommon
516 	 * identification registers.
517 	 *
518 	 * A small number of very early devices do not include a ChipCommon
519 	 * core, in which case our caller must supply the chip identification
520 	 * information via a non-NULL chipid parameter.
521 	 */
522 	if (chipid == NULL) {
523 		uint32_t	idhigh, ccreg;
524 		uint16_t	vendor, device;
525 		uint8_t		ccrev;
526 
527 		/* Map the first core's register block. If the ChipCommon core
528 		 * exists, it will always be the first core. */
529 		rid = 0;
530 		r = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
531 		    SIBA_CORE_ADDR(0), SIBA_CORE_SIZE,
532 		    SIBA_CORE_ADDR(0) + SIBA_CORE_SIZE - 1,
533 		    RF_ACTIVE);
534 
535 		/* Identify the core */
536 		idhigh = bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDHIGH));
537 		vendor = SIBA_REG_GET(idhigh, IDH_VENDOR);
538 		device = SIBA_REG_GET(idhigh, IDH_DEVICE);
539 		ccrev = SIBA_IDH_CORE_REV(idhigh);
540 
541 		if (vendor != OCP_VENDOR_BCM || device != BHND_COREID_CC) {
542 			device_printf(dev,
543 			    "cannot identify device: no chipcommon core "
544 			    "found\n");
545 			error = ENXIO;
546 			goto cleanup;
547 		}
548 
549 		/* Identify the chipset */
550 		ccreg = bus_read_4(r, CHIPC_ID);
551 		ccid = bhnd_parse_chipid(ccreg, SIBA_ENUM_ADDR);
552 
553 		if (!CHIPC_NCORES_MIN_HWREV(ccrev)) {
554 			switch (device) {
555 			case BHND_CHIPID_BCM4306:
556 				ccid.ncores = 6;
557 				break;
558 			case BHND_CHIPID_BCM4704:
559 				ccid.ncores = 9;
560 				break;
561 			case BHND_CHIPID_BCM5365:
562 				/*
563 				* BCM5365 does support ID_NUMCORE in at least
564 				* some of its revisions, but for unknown
565 				* reasons, Broadcom's drivers always exclude
566 				* the ChipCommon revision (0x5) used by BCM5365
567 				* from the set of revisions supporting
568 				* ID_NUMCORE, and instead supply a fixed value.
569 				*
570 				* Presumably, at least some of these devices
571 				* shipped with a broken ID_NUMCORE value.
572 				*/
573 				ccid.ncores = 7;
574 				break;
575 			default:
576 				device_printf(dev, "unable to determine core "
577 				    "count for unrecognized chipset 0x%hx\n",
578 				    ccid.chip_id);
579 				error = ENXIO;
580 				goto cleanup;
581 			}
582 		}
583 
584 		chipid = &ccid;
585 		bus_release_resource(dev, SYS_RES_MEMORY, rid, r);
586 	}
587 
588 	/* Allocate our temporary core table and enumerate all cores */
589 	cores = malloc(sizeof(*cores) * chipid->ncores, M_BHND, M_NOWAIT);
590 	if (cores == NULL)
591 		return (ENOMEM);
592 
593 	/* Add all cores. */
594 	for (u_int i = 0; i < chipid->ncores; i++) {
595 		struct siba_core_id	 cid;
596 		device_t		 child;
597 		uint32_t		 idhigh, idlow;
598 		rman_res_t		 r_count, r_end, r_start;
599 
600 		/* Map the core's register block */
601 		rid = 0;
602 		r_start = SIBA_CORE_ADDR(i);
603 		r_count = SIBA_CORE_SIZE;
604 		r_end = r_start + SIBA_CORE_SIZE - 1;
605 		r = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, r_start,
606 		    r_end, r_count, RF_ACTIVE);
607 		if (r == NULL) {
608 			error = ENXIO;
609 			goto cleanup;
610 		}
611 
612 		/* Read the core info */
613 		idhigh = bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDHIGH));
614 		idlow = bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDLOW));
615 
616 		cid = siba_parse_core_id(idhigh, idlow, i, 0);
617 		cores[i] = cid.core_info;
618 
619 		/* Determine unit number */
620 		for (u_int j = 0; j < i; j++) {
621 			if (cores[j].vendor == cores[i].vendor &&
622 			    cores[j].device == cores[i].device)
623 				cores[i].unit++;
624 		}
625 
626 		/* Allocate per-device bus info */
627 		dinfo = siba_alloc_dinfo(dev, &cid);
628 		if (dinfo == NULL) {
629 			error = ENXIO;
630 			goto cleanup;
631 		}
632 
633 		/* Register the core's address space(s). */
634 		if ((error = siba_register_addrspaces(dev, dinfo, r)))
635 			goto cleanup;
636 
637 		/* Add the child device */
638 		child = device_add_child(dev, NULL, -1);
639 		if (child == NULL) {
640 			error = ENXIO;
641 			goto cleanup;
642 		}
643 
644 		/* The child device now owns the dinfo pointer */
645 		device_set_ivars(child, dinfo);
646 		dinfo = NULL;
647 
648 		/* If pins are floating or the hardware is otherwise
649 		 * unpopulated, the device shouldn't be used. */
650 		if (bhnd_is_hw_disabled(child))
651 			device_disable(child);
652 
653 		/* Release our resource */
654 		bus_release_resource(dev, SYS_RES_MEMORY, rid, r);
655 		r = NULL;
656 	}
657 
658 cleanup:
659 	if (cores != NULL)
660 		free(cores, M_BHND);
661 
662 	if (dinfo != NULL)
663 		siba_free_dinfo(dev, dinfo);
664 
665 	if (r != NULL)
666 		bus_release_resource(dev, SYS_RES_MEMORY, rid, r);
667 
668 	return (error);
669 }
670 
671 static device_method_t siba_methods[] = {
672 	/* Device interface */
673 	DEVMETHOD(device_probe,			siba_probe),
674 	DEVMETHOD(device_attach,		siba_attach),
675 	DEVMETHOD(device_detach,		siba_detach),
676 	DEVMETHOD(device_resume,		siba_resume),
677 	DEVMETHOD(device_suspend,		siba_suspend),
678 
679 	/* Bus interface */
680 	DEVMETHOD(bus_child_deleted,		siba_child_deleted),
681 	DEVMETHOD(bus_read_ivar,		siba_read_ivar),
682 	DEVMETHOD(bus_write_ivar,		siba_write_ivar),
683 	DEVMETHOD(bus_get_resource_list,	siba_get_resource_list),
684 
685 	/* BHND interface */
686 	DEVMETHOD(bhnd_bus_find_hostb_device,	siba_find_hostb_device),
687 	DEVMETHOD(bhnd_bus_reset_core,		siba_reset_core),
688 	DEVMETHOD(bhnd_bus_suspend_core,	siba_suspend_core),
689 	DEVMETHOD(bhnd_bus_get_port_count,	siba_get_port_count),
690 	DEVMETHOD(bhnd_bus_get_region_count,	siba_get_region_count),
691 	DEVMETHOD(bhnd_bus_get_port_rid,	siba_get_port_rid),
692 	DEVMETHOD(bhnd_bus_decode_port_rid,	siba_decode_port_rid),
693 	DEVMETHOD(bhnd_bus_get_region_addr,	siba_get_region_addr),
694 
695 	DEVMETHOD_END
696 };
697 
698 DEFINE_CLASS_1(bhnd, siba_driver, siba_methods, sizeof(struct siba_softc), bhnd_driver);
699 
700 MODULE_VERSION(siba, 1);
701 MODULE_DEPEND(siba, bhnd, 1, 1, 1);
702