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 static bhnd_erom_class_t * 48 siba_get_erom_class(driver_t *driver) 49 { 50 return (&siba_erom_parser); 51 } 52 53 int 54 siba_probe(device_t dev) 55 { 56 device_set_desc(dev, "SIBA BHND bus"); 57 return (BUS_PROBE_DEFAULT); 58 } 59 60 /** 61 * Default siba(4) bus driver implementation of DEVICE_ATTACH(). 62 * 63 * This implementation initializes internal siba(4) state and performs 64 * bus enumeration, and must be called by subclassing drivers in 65 * DEVICE_ATTACH() before any other bus methods. 66 */ 67 int 68 siba_attach(device_t dev) 69 { 70 struct siba_softc *sc; 71 int error; 72 73 sc = device_get_softc(dev); 74 sc->dev = dev; 75 76 /* Enumerate children */ 77 if ((error = siba_add_children(dev))) { 78 device_delete_children(dev); 79 return (error); 80 } 81 82 return (0); 83 } 84 85 int 86 siba_detach(device_t dev) 87 { 88 return (bhnd_generic_detach(dev)); 89 } 90 91 int 92 siba_resume(device_t dev) 93 { 94 return (bhnd_generic_resume(dev)); 95 } 96 97 int 98 siba_suspend(device_t dev) 99 { 100 return (bhnd_generic_suspend(dev)); 101 } 102 103 static int 104 siba_read_ivar(device_t dev, device_t child, int index, uintptr_t *result) 105 { 106 const struct siba_devinfo *dinfo; 107 const struct bhnd_core_info *cfg; 108 109 dinfo = device_get_ivars(child); 110 cfg = &dinfo->core_id.core_info; 111 112 switch (index) { 113 case BHND_IVAR_VENDOR: 114 *result = cfg->vendor; 115 return (0); 116 case BHND_IVAR_DEVICE: 117 *result = cfg->device; 118 return (0); 119 case BHND_IVAR_HWREV: 120 *result = cfg->hwrev; 121 return (0); 122 case BHND_IVAR_DEVICE_CLASS: 123 *result = bhnd_core_class(cfg); 124 return (0); 125 case BHND_IVAR_VENDOR_NAME: 126 *result = (uintptr_t) bhnd_vendor_name(cfg->vendor); 127 return (0); 128 case BHND_IVAR_DEVICE_NAME: 129 *result = (uintptr_t) bhnd_core_name(cfg); 130 return (0); 131 case BHND_IVAR_CORE_INDEX: 132 *result = cfg->core_idx; 133 return (0); 134 case BHND_IVAR_CORE_UNIT: 135 *result = cfg->unit; 136 return (0); 137 default: 138 return (ENOENT); 139 } 140 } 141 142 static int 143 siba_write_ivar(device_t dev, device_t child, int index, uintptr_t value) 144 { 145 switch (index) { 146 case BHND_IVAR_VENDOR: 147 case BHND_IVAR_DEVICE: 148 case BHND_IVAR_HWREV: 149 case BHND_IVAR_DEVICE_CLASS: 150 case BHND_IVAR_VENDOR_NAME: 151 case BHND_IVAR_DEVICE_NAME: 152 case BHND_IVAR_CORE_INDEX: 153 case BHND_IVAR_CORE_UNIT: 154 return (EINVAL); 155 default: 156 return (ENOENT); 157 } 158 } 159 160 static struct resource_list * 161 siba_get_resource_list(device_t dev, device_t child) 162 { 163 struct siba_devinfo *dinfo = device_get_ivars(child); 164 return (&dinfo->resources); 165 } 166 167 static int 168 siba_reset_core(device_t dev, device_t child, uint16_t flags) 169 { 170 struct siba_devinfo *dinfo; 171 172 if (device_get_parent(child) != dev) 173 BHND_BUS_RESET_CORE(device_get_parent(dev), child, flags); 174 175 dinfo = device_get_ivars(child); 176 177 /* Can't reset the core without access to the CFG0 registers */ 178 if (dinfo->cfg[0] == NULL) 179 return (ENODEV); 180 181 // TODO - perform reset 182 183 return (ENXIO); 184 } 185 186 static int 187 siba_suspend_core(device_t dev, device_t child) 188 { 189 struct siba_devinfo *dinfo; 190 191 if (device_get_parent(child) != dev) 192 BHND_BUS_SUSPEND_CORE(device_get_parent(dev), child); 193 194 dinfo = device_get_ivars(child); 195 196 /* Can't suspend the core without access to the CFG0 registers */ 197 if (dinfo->cfg[0] == NULL) 198 return (ENODEV); 199 200 // TODO - perform suspend 201 202 return (ENXIO); 203 } 204 205 static uint32_t 206 siba_read_config(device_t dev, device_t child, bus_size_t offset, u_int width) 207 { 208 struct siba_devinfo *dinfo; 209 rman_res_t r_size; 210 211 /* Must be directly attached */ 212 if (device_get_parent(child) != dev) 213 return (UINT32_MAX); 214 215 /* CFG0 registers must be available */ 216 dinfo = device_get_ivars(child); 217 if (dinfo->cfg[0] == NULL) 218 return (UINT32_MAX); 219 220 /* Offset must fall within CFG0 */ 221 r_size = rman_get_size(dinfo->cfg[0]->res); 222 if (r_size < offset || r_size - offset < width) 223 return (UINT32_MAX); 224 225 switch (width) { 226 case 1: 227 return (bhnd_bus_read_1(dinfo->cfg[0], offset)); 228 case 2: 229 return (bhnd_bus_read_2(dinfo->cfg[0], offset)); 230 case 4: 231 return (bhnd_bus_read_4(dinfo->cfg[0], offset)); 232 } 233 234 /* Unsuported */ 235 return (UINT32_MAX); 236 } 237 238 static void 239 siba_write_config(device_t dev, device_t child, bus_size_t offset, uint32_t val, 240 u_int width) 241 { 242 struct siba_devinfo *dinfo; 243 rman_res_t r_size; 244 245 /* Must be directly attached */ 246 if (device_get_parent(child) != dev) 247 return; 248 249 /* CFG0 registers must be available */ 250 dinfo = device_get_ivars(child); 251 if (dinfo->cfg[0] == NULL) 252 return; 253 254 /* Offset must fall within CFG0 */ 255 r_size = rman_get_size(dinfo->cfg[0]->res); 256 if (r_size < offset || r_size - offset < width) 257 return; 258 259 switch (width) { 260 case 1: 261 bhnd_bus_write_1(dinfo->cfg[0], offset, val); 262 case 2: 263 bhnd_bus_write_2(dinfo->cfg[0], offset, val); 264 case 4: 265 bhnd_bus_write_4(dinfo->cfg[0], offset, val); 266 } 267 } 268 269 static u_int 270 siba_get_port_count(device_t dev, device_t child, bhnd_port_type type) 271 { 272 struct siba_devinfo *dinfo; 273 274 /* delegate non-bus-attached devices to our parent */ 275 if (device_get_parent(child) != dev) 276 return (BHND_BUS_GET_PORT_COUNT(device_get_parent(dev), child, 277 type)); 278 279 dinfo = device_get_ivars(child); 280 return (siba_addrspace_port_count(dinfo->core_id.num_addrspace)); 281 } 282 283 static u_int 284 siba_get_region_count(device_t dev, device_t child, bhnd_port_type type, 285 u_int port) 286 { 287 struct siba_devinfo *dinfo; 288 289 /* delegate non-bus-attached devices to our parent */ 290 if (device_get_parent(child) != dev) 291 return (BHND_BUS_GET_REGION_COUNT(device_get_parent(dev), child, 292 type, port)); 293 294 dinfo = device_get_ivars(child); 295 if (!siba_is_port_valid(dinfo->core_id.num_addrspace, type, port)) 296 return (0); 297 298 return (siba_addrspace_region_count(dinfo->core_id.num_addrspace, 299 port)); 300 } 301 302 static int 303 siba_get_port_rid(device_t dev, device_t child, bhnd_port_type port_type, 304 u_int port_num, u_int region_num) 305 { 306 struct siba_devinfo *dinfo; 307 struct siba_addrspace *addrspace; 308 309 /* delegate non-bus-attached devices to our parent */ 310 if (device_get_parent(child) != dev) 311 return (BHND_BUS_GET_PORT_RID(device_get_parent(dev), child, 312 port_type, port_num, region_num)); 313 314 dinfo = device_get_ivars(child); 315 addrspace = siba_find_addrspace(dinfo, port_type, port_num, region_num); 316 if (addrspace == NULL) 317 return (-1); 318 319 return (addrspace->sa_rid); 320 } 321 322 static int 323 siba_decode_port_rid(device_t dev, device_t child, int type, int rid, 324 bhnd_port_type *port_type, u_int *port_num, u_int *region_num) 325 { 326 struct siba_devinfo *dinfo; 327 328 /* delegate non-bus-attached devices to our parent */ 329 if (device_get_parent(child) != dev) 330 return (BHND_BUS_DECODE_PORT_RID(device_get_parent(dev), child, 331 type, rid, port_type, port_num, region_num)); 332 333 dinfo = device_get_ivars(child); 334 335 /* Ports are always memory mapped */ 336 if (type != SYS_RES_MEMORY) 337 return (EINVAL); 338 339 for (int i = 0; i < dinfo->core_id.num_addrspace; i++) { 340 if (dinfo->addrspace[i].sa_rid != rid) 341 continue; 342 343 *port_type = BHND_PORT_DEVICE; 344 *port_num = siba_addrspace_port(i); 345 *region_num = siba_addrspace_region(i); 346 return (0); 347 } 348 349 /* Not found */ 350 return (ENOENT); 351 } 352 353 static int 354 siba_get_region_addr(device_t dev, device_t child, bhnd_port_type port_type, 355 u_int port_num, u_int region_num, bhnd_addr_t *addr, bhnd_size_t *size) 356 { 357 struct siba_devinfo *dinfo; 358 struct siba_addrspace *addrspace; 359 360 /* delegate non-bus-attached devices to our parent */ 361 if (device_get_parent(child) != dev) { 362 return (BHND_BUS_GET_REGION_ADDR(device_get_parent(dev), child, 363 port_type, port_num, region_num, addr, size)); 364 } 365 366 dinfo = device_get_ivars(child); 367 addrspace = siba_find_addrspace(dinfo, port_type, port_num, region_num); 368 if (addrspace == NULL) 369 return (ENOENT); 370 371 *addr = addrspace->sa_base; 372 *size = addrspace->sa_size - addrspace->sa_bus_reserved; 373 return (0); 374 } 375 376 /** 377 * Default siba(4) bus driver implementation of BHND_BUS_GET_INTR_COUNT(). 378 * 379 * This implementation consults @p child's configuration block mapping, 380 * returning SIBA_CORE_NUM_INTR if a valid CFG0 block is mapped. 381 */ 382 int 383 siba_get_intr_count(device_t dev, device_t child) 384 { 385 struct siba_devinfo *dinfo; 386 387 /* delegate non-bus-attached devices to our parent */ 388 if (device_get_parent(child) != dev) 389 return (BHND_BUS_GET_INTR_COUNT(device_get_parent(dev), child)); 390 391 dinfo = device_get_ivars(child); 392 393 /* We can get/set interrupt sbflags on any core with a valid cfg0 394 * block; whether the core actually makes use of it is another matter 395 * entirely */ 396 if (dinfo->cfg[0] == NULL) 397 return (0); 398 399 return (SIBA_CORE_NUM_INTR); 400 } 401 402 /** 403 * Default siba(4) bus driver implementation of BHND_BUS_GET_CORE_IVEC(). 404 * 405 * This implementation consults @p child's CFG0 register block, 406 * returning the interrupt flag assigned to @p child. 407 */ 408 int 409 siba_get_core_ivec(device_t dev, device_t child, u_int intr, uint32_t *ivec) 410 { 411 struct siba_devinfo *dinfo; 412 uint32_t tpsflag; 413 414 /* delegate non-bus-attached devices to our parent */ 415 if (device_get_parent(child) != dev) 416 return (BHND_BUS_GET_CORE_IVEC(device_get_parent(dev), child, 417 intr, ivec)); 418 419 /* Must be a valid interrupt ID */ 420 if (intr >= siba_get_intr_count(dev, child)) 421 return (ENXIO); 422 423 /* Fetch sbflag number */ 424 dinfo = device_get_ivars(child); 425 tpsflag = bhnd_bus_read_4(dinfo->cfg[0], SIBA_CFG0_TPSFLAG); 426 *ivec = SIBA_REG_GET(tpsflag, TPS_NUM0); 427 428 return (0); 429 } 430 431 /** 432 * Register all address space mappings for @p di. 433 * 434 * @param dev The siba bus device. 435 * @param di The device info instance on which to register all address 436 * space entries. 437 * @param r A resource mapping the enumeration table block for @p di. 438 */ 439 static int 440 siba_register_addrspaces(device_t dev, struct siba_devinfo *di, 441 struct bhnd_resource *r) 442 { 443 struct siba_core_id *cid; 444 uint32_t addr; 445 uint32_t size; 446 int error; 447 448 cid = &di->core_id; 449 450 451 /* Register the device address space entries */ 452 for (uint8_t i = 0; i < di->core_id.num_addrspace; i++) { 453 uint32_t adm; 454 u_int adm_offset; 455 uint32_t bus_reserved; 456 457 /* Determine the register offset */ 458 adm_offset = siba_admatch_offset(i); 459 if (adm_offset == 0) { 460 device_printf(dev, "addrspace %hhu is unsupported", i); 461 return (ENODEV); 462 } 463 464 /* Fetch the address match register value */ 465 adm = bhnd_bus_read_4(r, adm_offset); 466 467 /* Parse the value */ 468 if ((error = siba_parse_admatch(adm, &addr, &size))) { 469 device_printf(dev, "failed to decode address " 470 " match register value 0x%x\n", adm); 471 return (error); 472 } 473 474 /* If this is the device's core/enumeration addrespace, 475 * reserve the Sonics configuration register blocks for the 476 * use of our bus. */ 477 bus_reserved = 0; 478 if (i == SIBA_CORE_ADDRSPACE) 479 bus_reserved = cid->num_cfg_blocks * SIBA_CFG_SIZE; 480 481 /* Append the region info */ 482 error = siba_append_dinfo_region(di, i, addr, size, 483 bus_reserved); 484 if (error) 485 return (error); 486 } 487 488 return (0); 489 } 490 491 /** 492 * Map per-core configuration blocks for @p dinfo. 493 * 494 * @param dev The siba bus device. 495 * @param dinfo The device info instance on which to map all per-core 496 * configuration blocks. 497 */ 498 static int 499 siba_map_cfg_resources(device_t dev, struct siba_devinfo *dinfo) 500 { 501 struct siba_addrspace *addrspace; 502 rman_res_t r_start, r_count, r_end; 503 uint8_t num_cfg; 504 505 num_cfg = dinfo->core_id.num_cfg_blocks; 506 if (num_cfg > SIBA_MAX_CFG) { 507 device_printf(dev, "config block count %hhu out of range\n", 508 num_cfg); 509 return (ENXIO); 510 } 511 512 /* Fetch the core register address space */ 513 addrspace = siba_find_addrspace(dinfo, BHND_PORT_DEVICE, 0, 0); 514 if (addrspace == NULL) { 515 device_printf(dev, "missing device registers\n"); 516 return (ENXIO); 517 } 518 519 /* 520 * Map the per-core configuration blocks 521 */ 522 for (uint8_t i = 0; i < num_cfg; i++) { 523 /* Determine the config block's address range; configuration 524 * blocks are allocated starting at SIBA_CFG0_OFFSET, 525 * growing downwards. */ 526 r_start = addrspace->sa_base + SIBA_CFG0_OFFSET; 527 r_start -= i * SIBA_CFG_SIZE; 528 529 r_count = SIBA_CFG_SIZE; 530 r_end = r_start + r_count - 1; 531 532 /* Allocate the config resource */ 533 dinfo->cfg_rid[i] = SIBA_CFG_RID(dinfo, i); 534 dinfo->cfg[i] = BHND_BUS_ALLOC_RESOURCE(dev, dev, 535 SYS_RES_MEMORY, &dinfo->cfg_rid[i], r_start, r_end, 536 r_count, RF_ACTIVE); 537 538 if (dinfo->cfg[i] == NULL) { 539 device_printf(dev, "failed to allocate SIBA_CFG%hhu\n", 540 i); 541 return (ENXIO); 542 } 543 } 544 545 return (0); 546 } 547 548 549 static struct bhnd_devinfo * 550 siba_alloc_bhnd_dinfo(device_t dev) 551 { 552 struct siba_devinfo *dinfo = siba_alloc_dinfo(dev); 553 return ((struct bhnd_devinfo *)dinfo); 554 } 555 556 static void 557 siba_free_bhnd_dinfo(device_t dev, struct bhnd_devinfo *dinfo) 558 { 559 siba_free_dinfo(dev, (struct siba_devinfo *)dinfo); 560 } 561 562 /** 563 * Scan the core table and add all valid discovered cores to 564 * the bus. 565 * 566 * @param dev The siba bus device. 567 */ 568 int 569 siba_add_children(device_t dev) 570 { 571 const struct bhnd_chipid *chipid; 572 struct bhnd_core_info *cores; 573 struct siba_devinfo *dinfo; 574 struct bhnd_resource *r; 575 int rid; 576 int error; 577 578 dinfo = NULL; 579 cores = NULL; 580 r = NULL; 581 582 chipid = BHND_BUS_GET_CHIPID(dev, dev); 583 584 /* Allocate our temporary core table and enumerate all cores */ 585 cores = malloc(sizeof(*cores) * chipid->ncores, M_BHND, M_NOWAIT); 586 if (cores == NULL) 587 return (ENOMEM); 588 589 /* Add all cores. */ 590 for (u_int i = 0; i < chipid->ncores; i++) { 591 struct siba_core_id cid; 592 device_t child; 593 uint32_t idhigh, idlow; 594 rman_res_t r_count, r_end, r_start; 595 int nintr; 596 597 /* Map the core's register block */ 598 rid = 0; 599 r_start = SIBA_CORE_ADDR(i); 600 r_count = SIBA_CORE_SIZE; 601 r_end = r_start + SIBA_CORE_SIZE - 1; 602 r = bhnd_alloc_resource(dev, SYS_RES_MEMORY, &rid, r_start, 603 r_end, r_count, RF_ACTIVE); 604 if (r == NULL) { 605 error = ENXIO; 606 goto cleanup; 607 } 608 609 /* Add the child device */ 610 child = BUS_ADD_CHILD(dev, 0, NULL, -1); 611 if (child == NULL) { 612 error = ENXIO; 613 goto cleanup; 614 } 615 616 /* Read the core info */ 617 idhigh = bhnd_bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDHIGH)); 618 idlow = bhnd_bus_read_4(r, SB0_REG_ABS(SIBA_CFG0_IDLOW)); 619 620 cid = siba_parse_core_id(idhigh, idlow, i, 0); 621 cores[i] = cid.core_info; 622 623 /* Determine unit number */ 624 for (u_int j = 0; j < i; j++) { 625 if (cores[j].vendor == cores[i].vendor && 626 cores[j].device == cores[i].device) 627 cores[i].unit++; 628 } 629 630 /* Initialize per-device bus info */ 631 if ((dinfo = device_get_ivars(child)) == NULL) { 632 error = ENXIO; 633 goto cleanup; 634 } 635 636 if ((error = siba_init_dinfo(dev, dinfo, &cid))) 637 goto cleanup; 638 639 /* Register the core's address space(s). */ 640 if ((error = siba_register_addrspaces(dev, dinfo, r))) 641 goto cleanup; 642 643 /* Release our resource covering the register blocks 644 * we're about to map */ 645 bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r); 646 r = NULL; 647 648 /* Map the core's config blocks */ 649 if ((error = siba_map_cfg_resources(dev, dinfo))) 650 goto cleanup; 651 652 /* Assign interrupts */ 653 nintr = bhnd_get_intr_count(child); 654 for (int rid = 0; rid < nintr; rid++) { 655 error = BHND_BUS_ASSIGN_INTR(dev, child, rid); 656 if (error) { 657 device_printf(dev, "failed to assign interrupt " 658 "%d to core %u: %d\n", rid, i, error); 659 } 660 } 661 662 /* If pins are floating or the hardware is otherwise 663 * unpopulated, the device shouldn't be used. */ 664 if (bhnd_is_hw_disabled(child)) 665 device_disable(child); 666 667 /* Issue bus callback for fully initialized child. */ 668 BHND_BUS_CHILD_ADDED(dev, child); 669 } 670 671 cleanup: 672 if (cores != NULL) 673 free(cores, M_BHND); 674 675 if (r != NULL) 676 bhnd_release_resource(dev, SYS_RES_MEMORY, rid, r); 677 678 return (error); 679 } 680 681 static device_method_t siba_methods[] = { 682 /* Device interface */ 683 DEVMETHOD(device_probe, siba_probe), 684 DEVMETHOD(device_attach, siba_attach), 685 DEVMETHOD(device_detach, siba_detach), 686 DEVMETHOD(device_resume, siba_resume), 687 DEVMETHOD(device_suspend, siba_suspend), 688 689 /* Bus interface */ 690 DEVMETHOD(bus_read_ivar, siba_read_ivar), 691 DEVMETHOD(bus_write_ivar, siba_write_ivar), 692 DEVMETHOD(bus_get_resource_list, siba_get_resource_list), 693 694 /* BHND interface */ 695 DEVMETHOD(bhnd_bus_get_erom_class, siba_get_erom_class), 696 DEVMETHOD(bhnd_bus_alloc_devinfo, siba_alloc_bhnd_dinfo), 697 DEVMETHOD(bhnd_bus_free_devinfo, siba_free_bhnd_dinfo), 698 DEVMETHOD(bhnd_bus_reset_core, siba_reset_core), 699 DEVMETHOD(bhnd_bus_suspend_core, siba_suspend_core), 700 DEVMETHOD(bhnd_bus_read_config, siba_read_config), 701 DEVMETHOD(bhnd_bus_write_config, siba_write_config), 702 DEVMETHOD(bhnd_bus_get_port_count, siba_get_port_count), 703 DEVMETHOD(bhnd_bus_get_region_count, siba_get_region_count), 704 DEVMETHOD(bhnd_bus_get_port_rid, siba_get_port_rid), 705 DEVMETHOD(bhnd_bus_decode_port_rid, siba_decode_port_rid), 706 DEVMETHOD(bhnd_bus_get_region_addr, siba_get_region_addr), 707 DEVMETHOD(bhnd_bus_get_intr_count, siba_get_intr_count), 708 DEVMETHOD(bhnd_bus_get_core_ivec, siba_get_core_ivec), 709 710 DEVMETHOD_END 711 }; 712 713 DEFINE_CLASS_1(bhnd, siba_driver, siba_methods, sizeof(struct siba_softc), bhnd_driver); 714 715 MODULE_VERSION(siba, 1); 716 MODULE_DEPEND(siba, bhnd, 1, 1, 1); 717