Example #1
0
static int
ofw_pcibus_attach(device_t dev)
{
	u_int busno, domain;
	int error;

	error = pci_attach_common(dev);
	if (error)
		return (error);
	domain = pcib_get_domain(dev);
	busno = pcib_get_bus(dev);

	/*
	 * Attach those children represented in the device tree.
	 */

	ofw_pcibus_enum_devtree(dev, domain, busno);

	/*
	 * We now attach any laggard devices. FDT, for instance, allows
	 * the device tree to enumerate only some PCI devices. Apple's
	 * OF device tree on some Grackle-based hardware can also miss
	 * functions on multi-function cards.
	 */

	if (!ofw_devices_only)
		ofw_pcibus_enum_bus(dev, domain, busno);

	return (bus_generic_attach(dev));
}
Example #2
0
static int
acpi_pci_attach(device_t dev)
{
	int busno, domain, error;

	error = pci_attach_common(dev);
	if (error)
		return (error);

	/*
	 * Since there can be multiple independantly numbered PCI
	 * busses on systems with multiple PCI domains, we can't use
	 * the unit number to decide which bus we are probing. We ask
	 * the parent pcib what our domain and bus numbers are.
	 */
	domain = pcib_get_domain(dev);
	busno = pcib_get_bus(dev);

	/*
	 * First, PCI devices are added as in the normal PCI bus driver.
	 * Afterwards, the ACPI namespace under the bridge driver is
	 * walked to save ACPI handles to all the devices that appear in
	 * the ACPI namespace as immediate descendants of the bridge.
	 *
	 * XXX: Sometimes PCI devices show up in the ACPI namespace that
	 * pci_add_children() doesn't find.  We currently just ignore
	 * these devices.
	 */
	pci_add_children(dev, domain, busno, sizeof(struct acpi_pci_devinfo));
	AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
	    acpi_pci_save_handle, NULL, dev, NULL);

	return (bus_generic_attach(dev));
}
Example #3
0
static int
mptable_hostb_attach(device_t dev)
{

	device_add_child(dev, "pci", pcib_get_bus(dev));
	return (bus_generic_attach(dev));
}
Example #4
0
static int
xlp_pci_attach(device_t dev)
{
	device_t pcib = device_get_parent(dev);
	int maxslots, s, f, pcifunchigh;
	int busno;
	uint8_t hdrtype;

	/*
	 * The on-chip devices are on a bus that is almost, but not
	 * quite, completely like PCI. Add those things by hand.
	 */
	busno = pcib_get_bus(dev);
	maxslots = PCIB_MAXSLOTS(pcib);
	for (s = 0; s <= maxslots; s++) {
		pcifunchigh = 0;
		f = 0;
		hdrtype = PCIB_READ_CONFIG(pcib, busno, s, f, PCIR_HDRTYPE, 1);
		if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
			continue;
		if (hdrtype & PCIM_MFDEV)
			pcifunchigh = PCI_FUNCMAX;
		for (f = 0; f <= pcifunchigh; f++)
			xlp_add_soc_child(pcib, dev, busno, s, f);
	}
	return (bus_generic_attach(dev));
}
Example #5
0
static int
ofw_pcibus_attach(device_t dev)
{
	device_t pcib;
	struct ofw_pci_register pcir;
	struct ofw_pcibus_devinfo *dinfo;
	phandle_t node, child;
	uint32_t clock;
	u_int busno, domain, func, slot;

	pcib = device_get_parent(dev);
	domain = pcib_get_domain(dev);
	busno = pcib_get_bus(dev);
	if (bootverbose)
		device_printf(dev, "domain=%d, physical bus=%d\n",
		    domain, busno);
	node = ofw_bus_get_node(dev);

	/*
	 * Add the PCI side of the host-PCI bridge itself to the bus.
	 * Note that we exclude the host-PCIe bridges here as these
	 * have no configuration space implemented themselves.
	 */
	if (strcmp(device_get_name(device_get_parent(pcib)), "nexus") == 0 &&
	    ofw_bus_get_type(pcib) != NULL &&
	    strcmp(ofw_bus_get_type(pcib), OFW_TYPE_PCIE) != 0 &&
	    (dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
	    domain, busno, 0, 0, sizeof(*dinfo))) != NULL) {
		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, node) != 0)
			pci_freecfg((struct pci_devinfo *)dinfo);
		else
			pci_add_child(dev, (struct pci_devinfo *)dinfo);
	}

	if (OF_getprop(ofw_bus_get_node(pcib), "clock-frequency", &clock,
	    sizeof(clock)) == -1)
		clock = 33000000;
	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
		if (OF_getprop(child, "reg", &pcir, sizeof(pcir)) == -1)
			continue;
		slot = OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi);
		func = OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi);
		/* Some OFW device trees contain dupes. */
		if (pci_find_dbsf(domain, busno, slot, func) != NULL)
			continue;
		ofw_pcibus_setup_device(pcib, clock, busno, slot, func);
		dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
		    domain, busno, slot, func, sizeof(*dinfo));
		if (dinfo == NULL)
			continue;
		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
		    0) {
			pci_freecfg((struct pci_devinfo *)dinfo);
			continue;
		}
		pci_add_child(dev, (struct pci_devinfo *)dinfo);
	}

	return (bus_generic_attach(dev));
}
static int
ofw_pcibus_attach(device_t dev)
{
	u_int busno, domain;

	domain = pcib_get_domain(dev);
	busno = pcib_get_bus(dev);
	if (bootverbose)
		device_printf(dev, "domain=%d, physical bus=%d\n",
		    domain, busno);

	/*
	 * Attach those children represented in the device tree.
	 */

	ofw_pcibus_enum_devtree(dev, domain, busno);

	/*
	 * We now attach any laggard devices. FDT, for instance, allows
	 * the device tree to enumerate only some PCI devices. Apple's
	 * OF device tree on some Grackle-based hardware can also miss
	 * functions on multi-function cards.
	 */

	ofw_pcibus_enum_bus(dev, domain, busno);

	return (bus_generic_attach(dev));
}
Example #7
0
static int
xlp_pci_attach(device_t dev)
{
    struct pci_devinfo *dinfo;
    device_t pcib;
    int maxslots, s, f, pcifunchigh, irq;
    int busno, node, devoffset;
    uint16_t devid;
    uint8_t hdrtype;

    /*
     * The on-chip devices are on a bus that is almost, but not
     * quite, completely like PCI. Add those things by hand.
     */
    pcib = device_get_parent(dev);
    busno = pcib_get_bus(dev);
    maxslots = PCIB_MAXSLOTS(pcib);
    for (s = 0; s <= maxslots; s++) {
        pcifunchigh = 0;
        f = 0;
        hdrtype = PCIB_READ_CONFIG(pcib, busno, s, f, PCIR_HDRTYPE, 1);
        if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE)
            continue;
        if (hdrtype & PCIM_MFDEV)
            pcifunchigh = PCI_FUNCMAX;
        node = s / 8;
        for (f = 0; f <= pcifunchigh; f++) {
            devoffset = XLP_HDR_OFFSET(node, 0, s % 8, f);
            if (!nlm_dev_exists(devoffset))
                continue;

            /* Find if there is a desc for the SoC device */
            devid = PCIB_READ_CONFIG(pcib, busno, s, f, PCIR_DEVICE, 2);

            /* Skip devices that don't have a proper PCI header */
            switch (devid) {
            case PCI_DEVICE_ID_NLM_ICI:
            case PCI_DEVICE_ID_NLM_PIC:
            case PCI_DEVICE_ID_NLM_FMN:
            case PCI_DEVICE_ID_NLM_UART:
            case PCI_DEVICE_ID_NLM_I2C:
            case PCI_DEVICE_ID_NLM_NOR:
            case PCI_DEVICE_ID_NLM_MMC:
                continue;
            case PCI_DEVICE_ID_NLM_EHCI:
                irq = PIC_USB_IRQ(f);
                PCIB_WRITE_CONFIG(pcib, busno, s, f,
                                  XLP_PCI_DEVSCRATCH_REG0 << 2,
                                  (1 << 8) | irq, 4);
            }
            dinfo = pci_read_device(pcib, dev, pcib_get_domain(dev),
                                    busno, s, f);
            pci_add_child(dev, dinfo);
        }
    }
    return (bus_generic_attach(dev));
}
Example #8
0
static int
mptable_hostb_attach(device_t dev)
{

#ifdef NEW_PCIB
	mptable_pci_host_res_init(dev);
#endif
	device_add_child(dev, "pci", pcib_get_bus(dev));
	return (bus_generic_attach(dev));
}
Example #9
0
static int
cardbus_attach_card(device_t cbdev)
{
	device_t brdev = device_get_parent(cbdev);
	device_t child;
	int bus, domain, slot, func;
	int cardattached = 0;
	int cardbusfunchigh = 0;
	struct cardbus_softc *sc;

	sc = device_get_softc(cbdev);
	cardbus_detach_card(cbdev); /* detach existing cards */
	POWER_ENABLE_SOCKET(brdev, cbdev);
	domain = pcib_get_domain(cbdev);
	bus = pcib_get_bus(cbdev);
	slot = 0;
	/* For each function, set it up and try to attach a driver to it */
	for (func = 0; func <= cardbusfunchigh; func++) {
		struct cardbus_devinfo *dinfo;

		dinfo = (struct cardbus_devinfo *)
		    pci_read_device(brdev, domain, bus, slot, func,
			sizeof(struct cardbus_devinfo));
		if (dinfo == NULL)
			continue;
		if (dinfo->pci.cfg.mfdev)
			cardbusfunchigh = PCI_FUNCMAX;

		child = device_add_child(cbdev, NULL, -1);
		if (child == NULL) {
			DEVPRINTF((cbdev, "Cannot add child!\n"));
			pci_freecfg((struct pci_devinfo *)dinfo);
			continue;
		}
		dinfo->pci.cfg.dev = child;
		resource_list_init(&dinfo->pci.resources);
		device_set_ivars(child, dinfo);
		cardbus_device_create(sc, dinfo, cbdev, child);
		if (cardbus_do_cis(cbdev, child) != 0)
			DEVPRINTF((cbdev, "Warning: Bogus CIS ignored\n"));
		pci_cfg_save(dinfo->pci.cfg.dev, &dinfo->pci, 0);
		pci_cfg_restore(dinfo->pci.cfg.dev, &dinfo->pci);
		cardbus_device_setup_regs(&dinfo->pci.cfg);
		pci_add_resources(cbdev, child, 1, dinfo->mprefetchable);
		pci_print_verbose(&dinfo->pci);
		if (device_probe_and_attach(child) == 0)
			cardattached++;
		else
			pci_cfg_save(dinfo->pci.cfg.dev, &dinfo->pci, 1);
	}
	if (cardattached > 0)
		return (0);
/*	POWER_DISABLE_SOCKET(brdev, cbdev); */
	return (ENOENT);
}
Example #10
0
static int
mptable_hostb_probe(device_t dev)
{

	if (pci_cfgregopen() == 0)
		return (ENXIO);
	if (mptable_pci_probe_table(pcib_get_bus(dev)) != 0)
		return (ENXIO);
	device_set_desc(dev, "MPTable Host-PCI bridge");
	return (0);
}
Example #11
0
static int
acpi_pci_probe(device_t dev)
{

    if (pcib_get_bus(dev) < 0)
        return (ENXIO);
    if (acpi_get_handle(dev) == NULL)
        return (ENXIO);
    device_set_desc(dev, "ACPI PCI bus");
    return (0);
}
Example #12
0
static int
cardbus_attach(device_t cbdev)
{
	struct cardbus_softc *sc;
#ifdef PCI_RES_BUS
	int rid;
#endif

	sc = device_get_softc(cbdev);
	sc->sc_dev = cbdev;
#ifdef PCI_RES_BUS
	rid = 0;
	sc->sc_bus = bus_alloc_resource(cbdev, PCI_RES_BUS, &rid,
	    pcib_get_bus(cbdev), pcib_get_bus(cbdev), 1, 0);
	if (sc->sc_bus == NULL) {
		device_printf(cbdev, "failed to allocate bus number\n");
		return (ENXIO);
	}
#else
	device_printf(cbdev, "Your bus numbers may be AFU\n");
#endif
	return (0);
}
Example #13
0
static int
qpi_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{

	switch (which) {
	case PCIB_IVAR_DOMAIN:
		*result = 0;
		return (0);
	case PCIB_IVAR_BUS:
		*result = pcib_get_bus(dev);
		return (0);
	default:
		return (ENOENT);
	}
}
Example #14
0
static int
mptable_hostb_probe(device_t dev)
{
    if (!ioapic_enable)
        return (ENXIO);

    if (pci_cfgregopen() == 0)
        return (ENXIO);
#ifdef notyet
    if (mptable_pci_probe_table(pcib_get_bus(dev)) != 0)
        return (ENXIO);
#endif

    device_set_desc(dev, "MPTABLE Host-PCI bridge");
    return (0);
}
Example #15
0
static int
cbb_pci_attach(device_t brdev)
{
	static int curr_bus_number = 2; /* XXX EVILE BAD (see below) */
	struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(brdev);
	struct sysctl_ctx_list *sctx;
	struct sysctl_oid *soid;
	int rid;
	device_t parent;
	uint32_t pribus;

	parent = device_get_parent(brdev);
	mtx_init(&sc->mtx, device_get_nameunit(brdev), "cbb", MTX_DEF);
	sc->chipset = cbb_chipset(pci_get_devid(brdev), NULL);
	sc->dev = brdev;
	sc->cbdev = NULL;
	sc->exca[0].pccarddev = NULL;
	sc->domain = pci_get_domain(brdev);
	sc->secbus = pci_read_config(brdev, PCIR_SECBUS_2, 1);
	sc->subbus = pci_read_config(brdev, PCIR_SUBBUS_2, 1);
	sc->pribus = pcib_get_bus(parent);
	SLIST_INIT(&sc->rl);
	cbb_powerstate_d0(brdev);

	rid = CBBR_SOCKBASE;
	sc->base_res = bus_alloc_resource_any(brdev, SYS_RES_MEMORY, &rid,
	    RF_ACTIVE);
	if (!sc->base_res) {
		device_printf(brdev, "Could not map register memory\n");
		mtx_destroy(&sc->mtx);
		return (ENOMEM);
	} else {
		DEVPRINTF((brdev, "Found memory at %08lx\n",
		    rman_get_start(sc->base_res)));
	}

	sc->bst = rman_get_bustag(sc->base_res);
	sc->bsh = rman_get_bushandle(sc->base_res);
	exca_init(&sc->exca[0], brdev, sc->bst, sc->bsh, CBB_EXCA_OFFSET);
	sc->exca[0].flags |= EXCA_HAS_MEMREG_WIN;
	sc->exca[0].chipset = EXCA_CARDBUS;
	sc->chipinit = cbb_chipinit;
	sc->chipinit(sc);

	/*Sysctls*/
	sctx = device_get_sysctl_ctx(brdev);
	soid = device_get_sysctl_tree(brdev);
	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "domain",
	    CTLFLAG_RD, &sc->domain, 0, "Domain number");
	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "pribus",
	    CTLFLAG_RD, &sc->pribus, 0, "Primary bus number");
	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "secbus",
	    CTLFLAG_RD, &sc->secbus, 0, "Secondary bus number");
	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "subbus",
	    CTLFLAG_RD, &sc->subbus, 0, "Subordinate bus number");
#if 0
	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "memory",
	    CTLFLAG_RD, &sc->subbus, 0, "Memory window open");
	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "premem",
	    CTLFLAG_RD, &sc->subbus, 0, "Prefetch memroy window open");
	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "io1",
	    CTLFLAG_RD, &sc->subbus, 0, "io range 1 open");
	SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "io2",
	    CTLFLAG_RD, &sc->subbus, 0, "io range 2 open");
#endif

	/*
	 * This is a gross hack.  We should be scanning the entire pci
	 * tree, assigning bus numbers in a way such that we (1) can
	 * reserve 1 extra bus just in case and (2) all sub busses
	 * are in an appropriate range.
	 */
	DEVPRINTF((brdev, "Secondary bus is %d\n", sc->secbus));
	pribus = pci_read_config(brdev, PCIR_PRIBUS_2, 1);
	if (sc->secbus == 0 || sc->pribus != pribus) {
		if (curr_bus_number <= sc->pribus)
			curr_bus_number = sc->pribus + 1;
		if (pribus != sc->pribus) {
			DEVPRINTF((brdev, "Setting primary bus to %d\n",
			    sc->pribus));
			pci_write_config(brdev, PCIR_PRIBUS_2, sc->pribus, 1);
		}
		sc->secbus = curr_bus_number++;
		sc->subbus = curr_bus_number++;
		DEVPRINTF((brdev, "Secondary bus set to %d subbus %d\n",
		    sc->secbus, sc->subbus));
		pci_write_config(brdev, PCIR_SECBUS_2, sc->secbus, 1);
		pci_write_config(brdev, PCIR_SUBBUS_2, sc->subbus, 1);
	}

	/* attach children */
	sc->cbdev = device_add_child(brdev, "cardbus", -1);
	if (sc->cbdev == NULL)
		DEVPRINTF((brdev, "WARNING: cannot add cardbus bus.\n"));
	else if (device_probe_and_attach(sc->cbdev) != 0)
		DEVPRINTF((brdev, "WARNING: cannot attach cardbus bus!\n"));

	sc->exca[0].pccarddev = device_add_child(brdev, "pccard", -1);
	if (sc->exca[0].pccarddev == NULL)
		DEVPRINTF((brdev, "WARNING: cannot add pccard bus.\n"));
	else if (device_probe_and_attach(sc->exca[0].pccarddev) != 0)
		DEVPRINTF((brdev, "WARNING: cannot attach pccard bus.\n"));

	/* Map and establish the interrupt. */
	rid = 0;
	sc->irq_res = bus_alloc_resource_any(brdev, SYS_RES_IRQ, &rid,
	    RF_SHAREABLE | RF_ACTIVE);
	if (sc->irq_res == NULL) {
		device_printf(brdev, "Unable to map IRQ...\n");
		goto err;
	}

	if (bus_setup_intr(brdev, sc->irq_res, INTR_TYPE_AV | INTR_MPSAFE,
	    cbb_pci_filt, NULL, sc, &sc->intrhand)) {
		device_printf(brdev, "couldn't establish interrupt\n");
		goto err;
	}

	/* reset 16-bit pcmcia bus */
	exca_clrb(&sc->exca[0], EXCA_INTR, EXCA_INTR_RESET);

	/* turn off power */
	cbb_power(brdev, CARD_OFF);

	/* CSC Interrupt: Card detect interrupt on */
	cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD);

	/* reset interrupt */
	cbb_set(sc, CBB_SOCKET_EVENT, cbb_get(sc, CBB_SOCKET_EVENT));

	if (bootverbose)
		cbb_print_config(brdev);

	/* Start the thread */
	if (kproc_create(cbb_event_thread, sc, &sc->event_thread, 0, 0,
	    "%s event thread", device_get_nameunit(brdev))) {
		device_printf(brdev, "unable to create event thread.\n");
		panic("cbb_create_event_thread");
	}
	sc->sc_root_token = root_mount_hold(device_get_nameunit(sc->dev));
	return (0);
err:
	if (sc->irq_res)
		bus_release_resource(brdev, SYS_RES_IRQ, 0, sc->irq_res);
	if (sc->base_res) {
		bus_release_resource(brdev, SYS_RES_MEMORY, CBBR_SOCKBASE,
		    sc->base_res);
	}
	mtx_destroy(&sc->mtx);
	return (ENOMEM);
}