示例#1
0
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);
}
示例#2
0
文件: chipc.c 项目: wulf7/freebsd
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);
}
示例#3
0
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);
}