static int siba_bhndb_attach(device_t dev) { struct siba_bhndb_softc *sc; device_t hostb; int error; sc = device_get_softc(dev); sc->quirks = 0; /* Perform initial attach and enumerate our children. */ if ((error = siba_attach(dev))) return (error); /* Fetch bus-level quirks required by the host bridge core */ if ((hostb = bhnd_bus_find_hostb_device(dev)) != NULL) { sc->quirks |= bhnd_device_quirks(hostb, bridge_devs, sizeof(bridge_devs[0])); } /* Apply attach/resume workarounds before any child drivers attach */ if ((error = siba_bhndb_wars_hwup(sc))) goto failed; /* Delegate remainder to standard bhnd method implementation */ if ((error = bhnd_generic_attach(dev))) goto failed; return (0); failed: siba_detach(dev); return (error); }
static int chipc_attach(device_t dev) { struct chipc_softc *sc; int error; sc = device_get_softc(dev); sc->dev = dev; sc->quirks = bhnd_device_quirks(dev, chipc_devices, sizeof(chipc_devices[0])); sc->sprom_refcnt = 0; CHIPC_LOCK_INIT(sc); STAILQ_INIT(&sc->mem_regions); /* Set up resource management */ if ((error = chipc_init_rman(sc))) { device_printf(sc->dev, "failed to initialize chipc resource state: %d\n", error); goto failed; } /* Allocate the region containing the chipc register block */ if ((sc->core_region = chipc_find_region_by_rid(sc, 0)) == NULL) { error = ENXIO; goto failed; } error = chipc_retain_region(sc, sc->core_region, RF_ALLOCATED|RF_ACTIVE); if (error) { sc->core_region = NULL; goto failed; } /* Save a direct reference to our chipc registers */ sc->core = sc->core_region->cr_res; /* Fetch and parse capability register(s) */ if ((error = chipc_read_caps(sc, &sc->caps))) goto failed; if (bootverbose) chipc_print_caps(sc->dev, &sc->caps); /* Attach all supported child devices */ if ((error = chipc_add_children(sc))) goto failed; if ((error = bus_generic_attach(dev))) goto failed; return (0); failed: device_delete_children(sc->dev); if (sc->core_region != NULL) { chipc_release_region(sc, sc->core_region, RF_ALLOCATED|RF_ACTIVE); } chipc_free_rman(sc); CHIPC_LOCK_DESTROY(sc); return (error); }
static int chipc_attach(device_t dev) { struct chipc_softc *sc; bhnd_addr_t enum_addr; uint32_t ccid_reg; uint8_t chip_type; int error; sc = device_get_softc(dev); sc->dev = dev; sc->quirks = bhnd_device_quirks(dev, chipc_devices, sizeof(chipc_devices[0])); /* Allocate bus resources */ memcpy(sc->rspec, chipc_rspec, sizeof(sc->rspec)); if ((error = bhnd_alloc_resources(dev, sc->rspec, sc->res))) return (error); sc->core = sc->res[0]; /* Fetch our chipset identification data */ ccid_reg = bhnd_bus_read_4(sc->core, CHIPC_ID); chip_type = CHIPC_GET_ATTR(ccid_reg, ID_BUS); switch (chip_type) { case BHND_CHIPTYPE_SIBA: /* enumeration space starts at the ChipCommon register base. */ enum_addr = rman_get_start(sc->core->res); break; case BHND_CHIPTYPE_BCMA: case BHND_CHIPTYPE_BCMA_ALT: enum_addr = bhnd_bus_read_4(sc->core, CHIPC_EROMPTR); break; default: device_printf(dev, "unsupported chip type %hhu\n", chip_type); error = ENODEV; goto cleanup; } sc->ccid = bhnd_parse_chipid(ccid_reg, enum_addr); /* Fetch capability and status register values */ sc->caps = bhnd_bus_read_4(sc->core, CHIPC_CAPABILITIES); sc->cst = bhnd_bus_read_4(sc->core, CHIPC_CHIPST); // TODO switch (bhnd_chipc_nvram_src(dev)) { case BHND_NVRAM_SRC_CIS: device_printf(dev, "NVRAM source: CIS\n"); break; case BHND_NVRAM_SRC_SPROM: device_printf(dev, "NVRAM source: SPROM\n"); break; case BHND_NVRAM_SRC_OTP: device_printf(dev, "NVRAM source: OTP\n"); break; case BHND_NVRAM_SRC_NFLASH: device_printf(dev, "NVRAM source: NFLASH\n"); break; case BHND_NVRAM_SRC_NONE: device_printf(dev, "NVRAM source: NONE\n"); break; } return (0); cleanup: bhnd_release_resources(dev, sc->rspec, sc->res); return (error); }