diff options
| -rw-r--r-- | sys/powerpc/ofw/ofw_pcibus.c | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/sys/powerpc/ofw/ofw_pcibus.c b/sys/powerpc/ofw/ofw_pcibus.c index 22a1634a0389..2c759f35cb69 100644 --- a/sys/powerpc/ofw/ofw_pcibus.c +++ b/sys/powerpc/ofw/ofw_pcibus.c @@ -156,6 +156,7 @@ ofw_pcibus_alloc_devinfo(device_t dev) struct ofw_pcibus_devinfo *dinfo; dinfo = malloc(sizeof(*dinfo), M_DEVBUF, M_WAITOK | M_ZERO); + dinfo->opd_obdinfo.obd_node = -1; return (&dinfo->opd_dinfo); } @@ -381,13 +382,31 @@ ofw_pcibus_get_devinfo(device_t bus, device_t dev) return (&dinfo->opd_obdinfo); } +/* Return a VF's owning PF node, or -1 if none is available. */ +static phandle_t +ofw_pcibus_get_pf_node(device_t child) +{ + device_t pf; + + pf = pci_iov_get_pf(child); + if (pf == NULL) + return (-1); + return (ofw_bus_get_node(pf)); +} + int ofw_pcibus_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsize, cpuset_t *cpuset) { + phandle_t node; int d, error; - d = platform_node_numa_domain(ofw_bus_get_node(dev)); + node = ofw_pcibus_get_pf_node(child); + if (node == -1) + node = ofw_bus_get_node(dev); + if (node == -1) + return (bus_generic_get_cpus(dev, child, op, setsize, cpuset)); + d = platform_node_numa_domain(node); switch (op) { case LOCAL_CPUS: @@ -410,17 +429,23 @@ ofw_pcibus_get_cpus(device_t dev, device_t child, enum cpu_sets op, size_t setsi } /* - * Fetch the NUMA domain for the given device 'dev'. + * Fetch the NUMA domain for the given device 'child'. * - * If a device has a _PXM method, map that to a NUMA domain. - * Otherwise, pass the request up to the parent. - * If there's no matching domain or the domain cannot be - * determined, return ENOENT. + * VFs have no firmware node, so use the owning PF's node when available. + * Otherwise, pass the request up to the parent when the device is not + * represented in the firmware tree. */ int ofw_pcibus_get_domain(device_t dev, device_t child, int *domain) { - *domain = platform_node_numa_domain(ofw_bus_get_node(child)); + phandle_t node; + + node = ofw_pcibus_get_pf_node(child); + if (node == -1) + node = ofw_bus_get_node(child); + if (node == -1) + return (bus_generic_get_domain(dev, child, domain)); + *domain = platform_node_numa_domain(node); return (0); } |
