コード例 #1
0
ファイル: ofw_pcibus.c プロジェクト: fengsi/freebsd
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));
}
コード例 #2
0
ファイル: acpi_pci.c プロジェクト: MattDooner/freebsd-west
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));
}
コード例 #3
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;
	int error;

	error = pci_attach_common(dev);
	if (error)
		return (error);
	pcib = device_get_parent(dev);
	domain = pcib_get_domain(dev);
	busno = pcib_get_bus(dev);
	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, dev,
	    domain, busno, 0, 0)) != 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, dev,
		    domain, busno, slot, func);
		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);
		OFW_PCI_SETUP_DEVICE(pcib, dinfo->opd_dinfo.cfg.dev);
	}

	return (bus_generic_attach(dev));
}