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 * Broadcom Home Networking Division (HND) Bus Driver.
35 *
36 * The Broadcom HND family of devices consists of both SoCs and host-connected
37 * networking chipsets containing a common family of Broadcom IP cores,
38 * including an integrated MIPS and/or ARM cores.
39 *
40 * HND devices expose a nearly identical interface whether accessible over a
41 * native SoC interconnect, or when connected via a host interface such as
42 * PCIe. As a result, the majority of hardware support code should be re-usable
43 * across host drivers for HND networking chipsets, as well as FreeBSD support
44 * for Broadcom MIPS/ARM HND SoCs.
45 *
46 * Earlier HND models used the siba(4) on-chip interconnect, while later models
47 * use bcma(4); the programming model is almost entirely independent
48 * of the actual underlying interconect.
49 */
50
51 #include <sys/param.h>
52 #include <sys/kernel.h>
53 #include <sys/bus.h>
54 #include <sys/module.h>
55 #include <sys/systm.h>
56
57 #include <machine/bus.h>
58 #include <sys/rman.h>
59 #include <machine/resource.h>
60
61 #include "bhnd.h"
62 #include "bhndvar.h"
63
64 MALLOC_DEFINE(M_BHND, "bhnd", "bhnd bus data structures");
65
66 /**
67 * bhnd_generic_probe_nomatch() reporting configuration.
68 */
69 static const struct bhnd_nomatch {
70 uint16_t vendor; /**< core designer */
71 uint16_t device; /**< core id */
72 bool if_verbose; /**< print when bootverbose is set. */
73 } bhnd_nomatch_table[] = {
74 { BHND_MFGID_ARM, BHND_COREID_OOB_ROUTER, true },
75 { BHND_MFGID_ARM, BHND_COREID_EROM, true },
76 { BHND_MFGID_ARM, BHND_COREID_PL301, true },
77 { BHND_MFGID_ARM, BHND_COREID_APB_BRIDGE, true },
78 { BHND_MFGID_ARM, BHND_COREID_AXI_UNMAPPED, false },
79
80 { BHND_MFGID_INVALID, BHND_COREID_INVALID, false }
81 };
82
83 static int compare_ascending_probe_order(const void *lhs,
84 const void *rhs);
85 static int compare_descending_probe_order(const void *lhs,
86 const void *rhs);
87
88 /**
89 * Default bhnd(4) bus driver implementation of DEVICE_ATTACH().
90 *
91 * This implementation calls device_probe_and_attach() for each of the device's
92 * children, in bhnd probe order.
93 */
94 int
bhnd_generic_attach(device_t dev)95 bhnd_generic_attach(device_t dev)
96 {
97 device_t *devs;
98 int ndevs;
99 int error;
100
101 if (device_is_attached(dev))
102 return (EBUSY);
103
104 if ((error = device_get_children(dev, &devs, &ndevs)))
105 return (error);
106
107 qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order);
108 for (int i = 0; i < ndevs; i++) {
109 device_t child = devs[i];
110 device_probe_and_attach(child);
111 }
112
113 free(devs, M_TEMP);
114 return (0);
115 }
116
117 /**
118 * Default bhnd(4) bus driver implementation of DEVICE_DETACH().
119 *
120 * This implementation calls device_detach() for each of the device's
121 * children, in reverse bhnd probe order, terminating if any call to
122 * device_detach() fails.
123 */
124 int
bhnd_generic_detach(device_t dev)125 bhnd_generic_detach(device_t dev)
126 {
127 device_t *devs;
128 int ndevs;
129 int error;
130
131 if (!device_is_attached(dev))
132 return (EBUSY);
133
134 if ((error = device_get_children(dev, &devs, &ndevs)))
135 return (error);
136
137 /* Detach in the reverse of attach order */
138 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order);
139 for (int i = 0; i < ndevs; i++) {
140 device_t child = devs[i];
141
142 /* Terminate on first error */
143 if ((error = device_detach(child)))
144 goto cleanup;
145 }
146
147 cleanup:
148 free(devs, M_TEMP);
149 return (error);
150 }
151
152 /**
153 * Default bhnd(4) bus driver implementation of DEVICE_SHUTDOWN().
154 *
155 * This implementation calls device_shutdown() for each of the device's
156 * children, in reverse bhnd probe order, terminating if any call to
157 * device_shutdown() fails.
158 */
159 int
bhnd_generic_shutdown(device_t dev)160 bhnd_generic_shutdown(device_t dev)
161 {
162 device_t *devs;
163 int ndevs;
164 int error;
165
166 if (!device_is_attached(dev))
167 return (EBUSY);
168
169 if ((error = device_get_children(dev, &devs, &ndevs)))
170 return (error);
171
172 /* Shutdown in the reverse of attach order */
173 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order);
174 for (int i = 0; i < ndevs; i++) {
175 device_t child = devs[i];
176
177 /* Terminate on first error */
178 if ((error = device_shutdown(child)))
179 goto cleanup;
180 }
181
182 cleanup:
183 free(devs, M_TEMP);
184 return (error);
185 }
186
187 /**
188 * Default bhnd(4) bus driver implementation of DEVICE_RESUME().
189 *
190 * This implementation calls BUS_RESUME_CHILD() for each of the device's
191 * children in bhnd probe order, terminating if any call to BUS_RESUME_CHILD()
192 * fails.
193 */
194 int
bhnd_generic_resume(device_t dev)195 bhnd_generic_resume(device_t dev)
196 {
197 device_t *devs;
198 int ndevs;
199 int error;
200
201 if (!device_is_attached(dev))
202 return (EBUSY);
203
204 if ((error = device_get_children(dev, &devs, &ndevs)))
205 return (error);
206
207 qsort(devs, ndevs, sizeof(*devs), compare_ascending_probe_order);
208 for (int i = 0; i < ndevs; i++) {
209 device_t child = devs[i];
210
211 /* Terminate on first error */
212 if ((error = BUS_RESUME_CHILD(device_get_parent(child), child)))
213 goto cleanup;
214 }
215
216 cleanup:
217 free(devs, M_TEMP);
218 return (error);
219 }
220
221 /**
222 * Default bhnd(4) bus driver implementation of DEVICE_SUSPEND().
223 *
224 * This implementation calls BUS_SUSPEND_CHILD() for each of the device's
225 * children in reverse bhnd probe order. If any call to BUS_SUSPEND_CHILD()
226 * fails, the suspend operation is terminated and any devices that were
227 * suspended are resumed immediately by calling their BUS_RESUME_CHILD()
228 * methods.
229 */
230 int
bhnd_generic_suspend(device_t dev)231 bhnd_generic_suspend(device_t dev)
232 {
233 device_t *devs;
234 int ndevs;
235 int error;
236
237 if (!device_is_attached(dev))
238 return (EBUSY);
239
240 if ((error = device_get_children(dev, &devs, &ndevs)))
241 return (error);
242
243 /* Suspend in the reverse of attach order */
244 qsort(devs, ndevs, sizeof(*devs), compare_descending_probe_order);
245 for (int i = 0; i < ndevs; i++) {
246 device_t child = devs[i];
247 error = BUS_SUSPEND_CHILD(device_get_parent(child), child);
248
249 /* On error, resume suspended devices and then terminate */
250 if (error) {
251 for (int j = 0; j < i; j++) {
252 BUS_RESUME_CHILD(device_get_parent(devs[j]),
253 devs[j]);
254 }
255
256 goto cleanup;
257 }
258 }
259
260 cleanup:
261 free(devs, M_TEMP);
262 return (error);
263 }
264
265 /*
266 * Ascending comparison of bhnd device's probe order.
267 */
268 static int
compare_ascending_probe_order(const void * lhs,const void * rhs)269 compare_ascending_probe_order(const void *lhs, const void *rhs)
270 {
271 device_t ldev, rdev;
272 int lorder, rorder;
273
274 ldev = (*(const device_t *) lhs);
275 rdev = (*(const device_t *) rhs);
276
277 lorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(ldev), ldev);
278 rorder = BHND_BUS_GET_PROBE_ORDER(device_get_parent(rdev), rdev);
279
280 if (lorder < rorder) {
281 return (-1);
282 } else if (lorder > rorder) {
283 return (1);
284 } else {
285 return (0);
286 }
287 }
288
289 /*
290 * Descending comparison of bhnd device's probe order.
291 */
292 static int
compare_descending_probe_order(const void * lhs,const void * rhs)293 compare_descending_probe_order(const void *lhs, const void *rhs)
294 {
295 return (compare_ascending_probe_order(rhs, lhs));
296 }
297
298 /**
299 * Default bhnd(4) bus driver implementation of BHND_BUS_GET_PROBE_ORDER().
300 *
301 * This implementation determines probe ordering based on the device's class
302 * and other properties, including whether the device is serving as a host
303 * bridge.
304 */
305 int
bhnd_generic_get_probe_order(device_t dev,device_t child)306 bhnd_generic_get_probe_order(device_t dev, device_t child)
307 {
308 switch (bhnd_get_class(child)) {
309 case BHND_DEVCLASS_CC:
310 /* Must be early enough to provide NVRAM access to the
311 * host bridge */
312 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_FIRST);
313
314 case BHND_DEVCLASS_CC_B:
315 /* fall through */
316 case BHND_DEVCLASS_PMU:
317 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_EARLY);
318
319 case BHND_DEVCLASS_SOC_ROUTER:
320 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LATE);
321
322 case BHND_DEVCLASS_SOC_BRIDGE:
323 return (BHND_PROBE_BUS + BHND_PROBE_ORDER_LAST);
324
325 case BHND_DEVCLASS_CPU:
326 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_FIRST);
327
328 case BHND_DEVCLASS_RAM:
329 /* fall through */
330 case BHND_DEVCLASS_MEMC:
331 return (BHND_PROBE_CPU + BHND_PROBE_ORDER_EARLY);
332
333 case BHND_DEVCLASS_NVRAM:
334 return (BHND_PROBE_RESOURCE + BHND_PROBE_ORDER_EARLY);
335
336 case BHND_DEVCLASS_PCI:
337 case BHND_DEVCLASS_PCIE:
338 case BHND_DEVCLASS_PCCARD:
339 case BHND_DEVCLASS_ENET:
340 case BHND_DEVCLASS_ENET_MAC:
341 case BHND_DEVCLASS_ENET_PHY:
342 case BHND_DEVCLASS_WLAN:
343 case BHND_DEVCLASS_WLAN_MAC:
344 case BHND_DEVCLASS_WLAN_PHY:
345 case BHND_DEVCLASS_EROM:
346 case BHND_DEVCLASS_OTHER:
347 case BHND_DEVCLASS_INVALID:
348 if (bhnd_find_hostb_device(dev) == child)
349 return (BHND_PROBE_ROOT + BHND_PROBE_ORDER_EARLY);
350
351 return (BHND_PROBE_DEFAULT);
352 default:
353 return (BHND_PROBE_DEFAULT);
354 }
355 }
356
357 /**
358 * Default bhnd(4) bus driver implementation of BHND_BUS_IS_REGION_VALID().
359 *
360 * This implementation assumes that port and region numbers are 0-indexed and
361 * are allocated non-sparsely, using BHND_BUS_GET_PORT_COUNT() and
362 * BHND_BUS_GET_REGION_COUNT() to determine if @p port and @p region fall
363 * within the defined range.
364 */
365 static bool
bhnd_generic_is_region_valid(device_t dev,device_t child,bhnd_port_type type,u_int port,u_int region)366 bhnd_generic_is_region_valid(device_t dev, device_t child,
367 bhnd_port_type type, u_int port, u_int region)
368 {
369 if (port >= bhnd_get_port_count(child, type))
370 return (false);
371
372 if (region >= bhnd_get_region_count(child, type, port))
373 return (false);
374
375 return (true);
376 }
377
378 /**
379 * Default bhnd(4) bus driver implementation of BUS_PRINT_CHILD().
380 *
381 * This implementation requests the device's struct resource_list via
382 * BUS_GET_RESOURCE_LIST.
383 */
384 int
bhnd_generic_print_child(device_t dev,device_t child)385 bhnd_generic_print_child(device_t dev, device_t child)
386 {
387 struct resource_list *rl;
388 int retval = 0;
389
390 retval += bus_print_child_header(dev, child);
391
392 rl = BUS_GET_RESOURCE_LIST(dev, child);
393 if (rl != NULL) {
394 retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY,
395 "%#jx");
396 }
397
398 retval += printf(" at core %u", bhnd_get_core_index(child));
399
400 retval += bus_print_child_domain(dev, child);
401 retval += bus_print_child_footer(dev, child);
402
403 return (retval);
404 }
405
406 /**
407 * Default bhnd(4) bus driver implementation of BUS_PROBE_NOMATCH().
408 *
409 * This implementation requests the device's struct resource_list via
410 * BUS_GET_RESOURCE_LIST.
411 */
412 void
bhnd_generic_probe_nomatch(device_t dev,device_t child)413 bhnd_generic_probe_nomatch(device_t dev, device_t child)
414 {
415 struct resource_list *rl;
416 const struct bhnd_nomatch *nm;
417 bool report;
418
419 /* Fetch reporting configuration for this device */
420 report = true;
421 for (nm = bhnd_nomatch_table; nm->device != BHND_COREID_INVALID; nm++) {
422 if (nm->vendor != bhnd_get_vendor(child))
423 continue;
424
425 if (nm->device != bhnd_get_device(child))
426 continue;
427
428 report = false;
429 if (bootverbose && nm->if_verbose)
430 report = true;
431 break;
432 }
433
434 if (!report)
435 return;
436
437 /* Print the non-matched device info */
438 device_printf(dev, "<%s %s>", bhnd_get_vendor_name(child),
439 bhnd_get_device_name(child));
440
441 rl = BUS_GET_RESOURCE_LIST(dev, child);
442 if (rl != NULL)
443 resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#jx");
444
445 printf(" at core %u (no driver attached)\n",
446 bhnd_get_core_index(child));
447 }
448
449 /**
450 * Default implementation of BUS_CHILD_PNPINFO_STR().
451 */
452 static int
bhnd_child_pnpinfo_str(device_t dev,device_t child,char * buf,size_t buflen)453 bhnd_child_pnpinfo_str(device_t dev, device_t child, char *buf,
454 size_t buflen)
455 {
456 if (device_get_parent(child) != dev) {
457 return (BUS_CHILD_PNPINFO_STR(device_get_parent(dev), child,
458 buf, buflen));
459 }
460
461 snprintf(buf, buflen, "vendor=0x%hx device=0x%hx rev=0x%hhx",
462 bhnd_get_vendor(child), bhnd_get_device(child),
463 bhnd_get_hwrev(child));
464
465 return (0);
466 }
467
468 /**
469 * Default implementation of BUS_CHILD_LOCATION_STR().
470 */
471 static int
bhnd_child_location_str(device_t dev,device_t child,char * buf,size_t buflen)472 bhnd_child_location_str(device_t dev, device_t child, char *buf,
473 size_t buflen)
474 {
475 bhnd_addr_t addr;
476 bhnd_size_t size;
477
478 if (device_get_parent(child) != dev) {
479 return (BUS_CHILD_LOCATION_STR(device_get_parent(dev), child,
480 buf, buflen));
481 }
482
483
484 if (bhnd_get_region_addr(child, BHND_PORT_DEVICE, 0, 0, &addr, &size)) {
485 /* No device default port/region */
486 if (buflen > 0)
487 *buf = '\0';
488 return (0);
489 }
490
491 snprintf(buf, buflen, "port0.0=0x%llx", (unsigned long long) addr);
492 return (0);
493 }
494
495 /**
496 * Default bhnd(4) bus driver implementation of BUS_ADD_CHILD().
497 *
498 * This implementation manages internal bhnd(4) state, and must be called
499 * by subclassing drivers.
500 */
501 device_t
bhnd_generic_add_child(device_t dev,u_int order,const char * name,int unit)502 bhnd_generic_add_child(device_t dev, u_int order, const char *name, int unit)
503 {
504 struct bhnd_devinfo *dinfo;
505 device_t child;
506
507 child = device_add_child_ordered(dev, order, name, unit);
508 if (child == NULL)
509 return (NULL);
510
511 if ((dinfo = BHND_BUS_ALLOC_DEVINFO(dev)) == NULL) {
512 device_delete_child(dev, child);
513 return (NULL);
514 }
515
516 device_set_ivars(child, dinfo);
517
518 /* Inform concrete bus driver. */
519 BHND_BUS_CHILD_ADDED(dev, child);
520
521 return (child);
522 }
523
524 /**
525 * Default bhnd(4) bus driver implementation of BUS_CHILD_DELETED().
526 *
527 * This implementation manages internal bhnd(4) state, and must be called
528 * by subclassing drivers.
529 */
530 void
bhnd_generic_child_deleted(device_t dev,device_t child)531 bhnd_generic_child_deleted(device_t dev, device_t child)
532 {
533 struct bhnd_softc *sc;
534 struct bhnd_devinfo *dinfo;
535
536 sc = device_get_softc(dev);
537
538 /* Free device info */
539 if ((dinfo = device_get_ivars(child)) != NULL)
540 BHND_BUS_FREE_DEVINFO(dev, dinfo);
541 }
542
543 /**
544 * Helper function for implementing BUS_SUSPEND_CHILD().
545 *
546 * TODO: Power management
547 *
548 * If @p child is not a direct child of @p dev, suspension is delegated to
549 * the @p dev parent.
550 */
551 int
bhnd_generic_suspend_child(device_t dev,device_t child)552 bhnd_generic_suspend_child(device_t dev, device_t child)
553 {
554 if (device_get_parent(child) != dev)
555 BUS_SUSPEND_CHILD(device_get_parent(dev), child);
556
557 return bus_generic_suspend_child(dev, child);
558 }
559
560 /**
561 * Helper function for implementing BUS_RESUME_CHILD().
562 *
563 * TODO: Power management
564 *
565 * If @p child is not a direct child of @p dev, suspension is delegated to
566 * the @p dev parent.
567 */
568 int
bhnd_generic_resume_child(device_t dev,device_t child)569 bhnd_generic_resume_child(device_t dev, device_t child)
570 {
571 if (device_get_parent(child) != dev)
572 BUS_RESUME_CHILD(device_get_parent(dev), child);
573
574 return bus_generic_resume_child(dev, child);
575 }
576
577 /*
578 * Delegate all indirect I/O to the parent device. When inherited by
579 * non-bridged bus implementations, resources will never be marked as
580 * indirect, and these methods will never be called.
581 */
582 #define BHND_IO_READ(_type, _name, _method) \
583 static _type \
584 bhnd_read_ ## _name (device_t dev, device_t child, \
585 struct bhnd_resource *r, bus_size_t offset) \
586 { \
587 return (BHND_BUS_READ_ ## _method( \
588 device_get_parent(dev), child, r, offset)); \
589 }
590
591 #define BHND_IO_WRITE(_type, _name, _method) \
592 static void \
593 bhnd_write_ ## _name (device_t dev, device_t child, \
594 struct bhnd_resource *r, bus_size_t offset, _type value) \
595 { \
596 return (BHND_BUS_WRITE_ ## _method( \
597 device_get_parent(dev), child, r, offset, \
598 value)); \
599 }
600
601 #define BHND_IO_MISC(_type, _op, _method) \
602 static void \
603 bhnd_ ## _op (device_t dev, device_t child, \
604 struct bhnd_resource *r, bus_size_t offset, _type datap, \
605 bus_size_t count) \
606 { \
607 BHND_BUS_ ## _method(device_get_parent(dev), child, r, \
608 offset, datap, count); \
609 }
610
611 #define BHND_IO_METHODS(_type, _size) \
612 BHND_IO_READ(_type, _size, _size) \
613 BHND_IO_WRITE(_type, _size, _size) \
614 \
615 BHND_IO_READ(_type, stream_ ## _size, STREAM_ ## _size) \
616 BHND_IO_WRITE(_type, stream_ ## _size, STREAM_ ## _size) \
617 \
618 BHND_IO_MISC(_type*, read_multi_ ## _size, \
619 READ_MULTI_ ## _size) \
620 BHND_IO_MISC(_type*, write_multi_ ## _size, \
621 WRITE_MULTI_ ## _size) \
622 \
623 BHND_IO_MISC(_type*, read_multi_stream_ ## _size, \
624 READ_MULTI_STREAM_ ## _size) \
625 BHND_IO_MISC(_type*, write_multi_stream_ ## _size, \
626 WRITE_MULTI_STREAM_ ## _size) \
627 \
628 BHND_IO_MISC(_type, set_multi_ ## _size, SET_MULTI_ ## _size) \
629 BHND_IO_MISC(_type, set_region_ ## _size, SET_REGION_ ## _size) \
630 \
631 BHND_IO_MISC(_type*, read_region_ ## _size, \
632 READ_REGION_ ## _size) \
633 BHND_IO_MISC(_type*, write_region_ ## _size, \
634 WRITE_REGION_ ## _size) \
635 \
636 BHND_IO_MISC(_type*, read_region_stream_ ## _size, \
637 READ_REGION_STREAM_ ## _size) \
638 BHND_IO_MISC(_type*, write_region_stream_ ## _size, \
639 WRITE_REGION_STREAM_ ## _size) \
640
641 BHND_IO_METHODS(uint8_t, 1);
642 BHND_IO_METHODS(uint16_t, 2);
643 BHND_IO_METHODS(uint32_t, 4);
644
645 static void
bhnd_barrier(device_t dev,device_t child,struct bhnd_resource * r,bus_size_t offset,bus_size_t length,int flags)646 bhnd_barrier(device_t dev, device_t child, struct bhnd_resource *r,
647 bus_size_t offset, bus_size_t length, int flags)
648 {
649 BHND_BUS_BARRIER(device_get_parent(dev), child, r, offset, length,
650 flags);
651 }
652
653 static device_method_t bhnd_methods[] = {
654 /* Device interface */ \
655 DEVMETHOD(device_attach, bhnd_generic_attach),
656 DEVMETHOD(device_detach, bhnd_generic_detach),
657 DEVMETHOD(device_shutdown, bhnd_generic_shutdown),
658 DEVMETHOD(device_suspend, bhnd_generic_suspend),
659 DEVMETHOD(device_resume, bhnd_generic_resume),
660
661 /* Bus interface */
662 DEVMETHOD(bus_add_child, bhnd_generic_add_child),
663 DEVMETHOD(bus_child_deleted, bhnd_generic_child_deleted),
664 DEVMETHOD(bus_probe_nomatch, bhnd_generic_probe_nomatch),
665 DEVMETHOD(bus_print_child, bhnd_generic_print_child),
666 DEVMETHOD(bus_child_pnpinfo_str, bhnd_child_pnpinfo_str),
667 DEVMETHOD(bus_child_location_str, bhnd_child_location_str),
668
669 DEVMETHOD(bus_suspend_child, bhnd_generic_suspend_child),
670 DEVMETHOD(bus_resume_child, bhnd_generic_resume_child),
671
672 DEVMETHOD(bus_set_resource, bus_generic_rl_set_resource),
673 DEVMETHOD(bus_get_resource, bus_generic_rl_get_resource),
674 DEVMETHOD(bus_delete_resource, bus_generic_rl_delete_resource),
675 DEVMETHOD(bus_alloc_resource, bus_generic_rl_alloc_resource),
676 DEVMETHOD(bus_adjust_resource, bus_generic_adjust_resource),
677 DEVMETHOD(bus_release_resource, bus_generic_rl_release_resource),
678 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
679 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
680
681 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
682 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
683 DEVMETHOD(bus_config_intr, bus_generic_config_intr),
684 DEVMETHOD(bus_bind_intr, bus_generic_bind_intr),
685 DEVMETHOD(bus_describe_intr, bus_generic_describe_intr),
686
687 DEVMETHOD(bus_get_dma_tag, bus_generic_get_dma_tag),
688
689 /* BHND interface */
690 DEVMETHOD(bhnd_bus_get_chipid, bhnd_bus_generic_get_chipid),
691 DEVMETHOD(bhnd_bus_get_probe_order, bhnd_generic_get_probe_order),
692 DEVMETHOD(bhnd_bus_is_region_valid, bhnd_generic_is_region_valid),
693 DEVMETHOD(bhnd_bus_is_hw_disabled, bhnd_bus_generic_is_hw_disabled),
694 DEVMETHOD(bhnd_bus_get_nvram_var, bhnd_bus_generic_get_nvram_var),
695
696 /* BHND interface (bus I/O) */
697 DEVMETHOD(bhnd_bus_read_1, bhnd_read_1),
698 DEVMETHOD(bhnd_bus_read_2, bhnd_read_2),
699 DEVMETHOD(bhnd_bus_read_4, bhnd_read_4),
700 DEVMETHOD(bhnd_bus_write_1, bhnd_write_1),
701 DEVMETHOD(bhnd_bus_write_2, bhnd_write_2),
702 DEVMETHOD(bhnd_bus_write_4, bhnd_write_4),
703
704 DEVMETHOD(bhnd_bus_read_stream_1, bhnd_read_stream_1),
705 DEVMETHOD(bhnd_bus_read_stream_2, bhnd_read_stream_2),
706 DEVMETHOD(bhnd_bus_read_stream_4, bhnd_read_stream_4),
707 DEVMETHOD(bhnd_bus_write_stream_1, bhnd_write_stream_1),
708 DEVMETHOD(bhnd_bus_write_stream_2, bhnd_write_stream_2),
709 DEVMETHOD(bhnd_bus_write_stream_4, bhnd_write_stream_4),
710
711 DEVMETHOD(bhnd_bus_read_multi_1, bhnd_read_multi_1),
712 DEVMETHOD(bhnd_bus_read_multi_2, bhnd_read_multi_2),
713 DEVMETHOD(bhnd_bus_read_multi_4, bhnd_read_multi_4),
714 DEVMETHOD(bhnd_bus_write_multi_1, bhnd_write_multi_1),
715 DEVMETHOD(bhnd_bus_write_multi_2, bhnd_write_multi_2),
716 DEVMETHOD(bhnd_bus_write_multi_4, bhnd_write_multi_4),
717
718 DEVMETHOD(bhnd_bus_read_multi_stream_1, bhnd_read_multi_stream_1),
719 DEVMETHOD(bhnd_bus_read_multi_stream_2, bhnd_read_multi_stream_2),
720 DEVMETHOD(bhnd_bus_read_multi_stream_4, bhnd_read_multi_stream_4),
721 DEVMETHOD(bhnd_bus_write_multi_stream_1,bhnd_write_multi_stream_1),
722 DEVMETHOD(bhnd_bus_write_multi_stream_2,bhnd_write_multi_stream_2),
723 DEVMETHOD(bhnd_bus_write_multi_stream_4,bhnd_write_multi_stream_4),
724
725 DEVMETHOD(bhnd_bus_set_multi_1, bhnd_set_multi_1),
726 DEVMETHOD(bhnd_bus_set_multi_2, bhnd_set_multi_2),
727 DEVMETHOD(bhnd_bus_set_multi_4, bhnd_set_multi_4),
728
729 DEVMETHOD(bhnd_bus_set_region_1, bhnd_set_region_1),
730 DEVMETHOD(bhnd_bus_set_region_2, bhnd_set_region_2),
731 DEVMETHOD(bhnd_bus_set_region_4, bhnd_set_region_4),
732
733 DEVMETHOD(bhnd_bus_read_region_1, bhnd_read_region_1),
734 DEVMETHOD(bhnd_bus_read_region_2, bhnd_read_region_2),
735 DEVMETHOD(bhnd_bus_read_region_4, bhnd_read_region_4),
736 DEVMETHOD(bhnd_bus_write_region_1, bhnd_write_region_1),
737 DEVMETHOD(bhnd_bus_write_region_2, bhnd_write_region_2),
738 DEVMETHOD(bhnd_bus_write_region_4, bhnd_write_region_4),
739
740 DEVMETHOD(bhnd_bus_read_region_stream_1,bhnd_read_region_stream_1),
741 DEVMETHOD(bhnd_bus_read_region_stream_2,bhnd_read_region_stream_2),
742 DEVMETHOD(bhnd_bus_read_region_stream_4,bhnd_read_region_stream_4),
743 DEVMETHOD(bhnd_bus_write_region_stream_1, bhnd_write_region_stream_1),
744 DEVMETHOD(bhnd_bus_write_region_stream_2, bhnd_write_region_stream_2),
745 DEVMETHOD(bhnd_bus_write_region_stream_4, bhnd_write_region_stream_4),
746
747 DEVMETHOD(bhnd_bus_barrier, bhnd_barrier),
748
749 DEVMETHOD_END
750 };
751
752 devclass_t bhnd_devclass; /**< bhnd bus. */
753 devclass_t bhnd_hostb_devclass; /**< bhnd bus host bridge. */
754 devclass_t bhnd_nvram_devclass; /**< bhnd NVRAM device */
755
756 DEFINE_CLASS_0(bhnd, bhnd_driver, bhnd_methods, sizeof(struct bhnd_softc));
757 MODULE_VERSION(bhnd, 1);
758