From a377495feb6d6c6a51d6cca4065a74f320f29a07 Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Sat, 16 May 2020 09:24:29 -0700 Subject: 12762 topo should create per-device UFM entries by default Reviewed by: Patrick Mooney Approved by: Joshua Clulow --- usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c | 34 +++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c index 8927188c12..12459510dc 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c @@ -165,7 +165,7 @@ hostbridge_asdevice(topo_mod_t *mod, tnode_t *bus) } static int -pciexfn_add_ufm(topo_mod_t *mod, tnode_t *node) +pciexfn_add_ufm(topo_mod_t *mod, tnode_t *parent, tnode_t *node) { char *devpath = NULL; ufm_ioc_getcaps_t ugc = { 0 }; @@ -174,6 +174,7 @@ pciexfn_add_ufm(topo_mod_t *mod, tnode_t *node) nvlist_t *ufminfo = NULL, **images; uint_t nimages; int err, fd, ret = -1; + tnode_t *create; if (topo_prop_get_string(node, TOPO_PGROUP_IO, TOPO_IO_DEV, &devpath, &err) != 0) { @@ -269,7 +270,31 @@ pciexfn_add_ufm(topo_mod_t *mod, tnode_t *node) (void) topo_mod_seterrno(mod, EMOD_UNKNOWN); goto err; } - if (topo_node_range_create(mod, node, UFM, 0, (nimages - 1)) != 0) { + + /* + * There's nothing for us to do if there are no images. + */ + if (nimages == 0) { + ret = 0; + goto err; + } + + /* + * In general, almost all UFMs are device-wide. That is, in a + * multi-function device, there is still a single global firmware image. + * At this time, we default to putting the UFM data always on the device + * node. However, if someone creates a UFM on something that's not the + * first function, we'll create a UFM under that function for now. If we + * add support for hardware that has per-function UFMs, then we should + * update the UFM API to convey that scope. + */ + if (topo_node_instance(node) != 0) { + create = node; + } else { + create = parent; + } + + if (topo_node_range_create(mod, create, UFM, 0, (nimages - 1)) != 0) { topo_mod_dprintf(mod, "failed to create %s range", UFM); /* errno set */ goto err; @@ -287,7 +312,8 @@ pciexfn_add_ufm(topo_mod_t *mod, tnode_t *node) (void) topo_mod_seterrno(mod, EMOD_UNKNOWN); goto err; } - if ((ufmnode = topo_mod_create_ufm(mod, node, descr, NULL)) == + + if ((ufmnode = topo_mod_create_ufm(mod, create, descr, NULL)) == NULL) { topo_mod_dprintf(mod, "failed to create ufm nodes for " "%s", descr); @@ -429,7 +455,7 @@ pciexfn_declare(topo_mod_t *mod, tnode_t *parent, di_node_t dn, * information via the DDI UFM subsystem and, if so, create the * corresponding ufm topo nodes. */ - if (pciexfn_add_ufm(mod, ntn) != 0) { + if (pciexfn_add_ufm(mod, parent, ntn) != 0) { topo_node_unbind(ntn); return (NULL); } -- cgit v1.2.3