Page MenuHomeFreeBSD

D30180.diff
No OneTemporary

D30180.diff

diff --git a/sys/dev/pci/pci_host_generic_fdt.h b/sys/dev/pci/pci_host_generic_fdt.h
--- a/sys/dev/pci/pci_host_generic_fdt.h
+++ b/sys/dev/pci/pci_host_generic_fdt.h
@@ -34,9 +34,13 @@
#ifndef __PCI_HOST_GENERIC_FDT_H_
#define __PCI_HOST_GENERIC_FDT_H_
+struct pci_ofw_devinfo;
+
struct generic_pcie_fdt_softc {
struct generic_pcie_core_softc base;
struct ofw_bus_iinfo pci_iinfo;
+
+ STAILQ_HEAD(, pci_ofw_devinfo) pci_ofw_devlist;
};
DECLARE_CLASS(generic_pcie_fdt_driver);
diff --git a/sys/dev/pci/pci_host_generic_fdt.c b/sys/dev/pci/pci_host_generic_fdt.c
--- a/sys/dev/pci/pci_host_generic_fdt.c
+++ b/sys/dev/pci/pci_host_generic_fdt.c
@@ -71,10 +71,21 @@
#define PROPS_CELL_SIZE 1
#define PCI_ADDR_CELL_SIZE 2
+struct pci_ofw_devinfo {
+ STAILQ_ENTRY(pci_ofw_devinfo) pci_ofw_link;
+ struct ofw_bus_devinfo di_dinfo;
+ uint8_t slot;
+ uint8_t func;
+ uint8_t bus;
+};
+
/* Forward prototypes */
static int generic_pcie_fdt_probe(device_t dev);
static int parse_pci_mem_ranges(device_t, struct generic_pcie_core_softc *);
+static int generic_pcie_ofw_bus_attach(device_t);
+static const struct ofw_bus_devinfo *generic_pcie_ofw_get_devinfo(device_t,
+ device_t);
static int
generic_pcie_fdt_probe(device_t dev)
@@ -104,12 +115,18 @@
sc = device_get_softc(dev);
+ STAILQ_INIT(&sc->pci_ofw_devlist);
+
/* Retrieve 'ranges' property from FDT */
if (bootverbose)
device_printf(dev, "parsing FDT for ECAM%d:\n", sc->base.ecam);
if (parse_pci_mem_ranges(dev, &sc->base))
return (ENXIO);
+ /* Attach OFW bus */
+ if (generic_pcie_ofw_bus_attach(dev) != 0)
+ return (ENXIO);
+
node = ofw_bus_get_node(dev);
if (sc->base.coherent == 0) {
sc->base.coherent = OF_hasprop(node, "dma-coherent");
@@ -367,8 +384,62 @@
return (0);
}
+static const struct ofw_bus_devinfo *
+generic_pcie_ofw_get_devinfo(device_t bus, device_t child)
+{
+ struct generic_pcie_fdt_softc *sc;
+ struct pci_ofw_devinfo *di;
+ uint8_t slot, func, busno;
+
+ sc = device_get_softc(bus);
+ slot = pci_get_slot(child);
+ func = pci_get_function(child);
+ busno = pci_get_bus(child);
+
+ STAILQ_FOREACH(di, &sc->pci_ofw_devlist, pci_ofw_link)
+ if (slot == di->slot && func == di->func && busno == di->bus)
+ return (&di->di_dinfo);
+
+ return (NULL);
+}
+
/* Helper functions */
+static int
+generic_pcie_ofw_bus_attach(device_t dev)
+{
+ struct generic_pcie_fdt_softc *sc;
+ struct pci_ofw_devinfo *di;
+ phandle_t parent, node;
+ pcell_t reg[5];
+ ssize_t len;
+
+ sc = device_get_softc(dev);
+ parent = ofw_bus_get_node(dev);
+ if (parent == 0)
+ return (0);
+
+ /* Iterate through all bus subordinates */
+ for (node = OF_child(parent); node > 0; node = OF_peer(node)) {
+ len = OF_getencprop(node, "reg", reg, sizeof(reg));
+ if (len != 5 * sizeof(pcell_t))
+ continue;
+
+ /* Allocate and populate devinfo. */
+ di = malloc(sizeof(*di), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (ofw_bus_gen_setup_devinfo(&di->di_dinfo, node) != 0) {
+ free(di, M_DEVBUF);
+ continue;
+ }
+ di->func = OFW_PCI_PHYS_HI_FUNCTION(reg[0]);
+ di->slot = OFW_PCI_PHYS_HI_DEVICE(reg[0]);
+ di->bus = OFW_PCI_PHYS_HI_BUS(reg[0]);
+ STAILQ_INSERT_TAIL(&sc->pci_ofw_devlist, di, pci_ofw_link);
+ }
+
+ return (0);
+}
+
static device_method_t generic_pcie_fdt_methods[] = {
DEVMETHOD(device_probe, generic_pcie_fdt_probe),
DEVMETHOD(device_attach, pci_host_generic_attach),
@@ -385,6 +456,13 @@
DEVMETHOD(pcib_get_id, generic_pcie_get_id),
DEVMETHOD(pcib_request_feature, pcib_request_feature_allow),
+ DEVMETHOD(ofw_bus_get_devinfo, generic_pcie_ofw_get_devinfo),
+ DEVMETHOD(ofw_bus_get_compat, ofw_bus_gen_get_compat),
+ DEVMETHOD(ofw_bus_get_model, ofw_bus_gen_get_model),
+ DEVMETHOD(ofw_bus_get_name, ofw_bus_gen_get_name),
+ DEVMETHOD(ofw_bus_get_node, ofw_bus_gen_get_node),
+ DEVMETHOD(ofw_bus_get_type, ofw_bus_gen_get_type),
+
DEVMETHOD_END
};

File Metadata

Mime Type
text/plain
Expires
Sun, Jan 12, 12:43 PM (20 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15769429
Default Alt Text
D30180.diff (3 KB)

Event Timeline