summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@fingolfin.org>2020-05-16 09:24:29 -0700
committerRobert Mustacchi <rm@fingolfin.org>2020-06-12 09:43:33 -0700
commita377495feb6d6c6a51d6cca4065a74f320f29a07 (patch)
treec8dba57f5b72b248c7f0a528b547dfad9cae8936
parent44b0ba916e529fad7fa22597911db69ae8f24994 (diff)
downloadillumos-joyent-a377495feb6d6c6a51d6cca4065a74f320f29a07.tar.gz
12762 topo should create per-device UFM entries by default
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Approved by: Joshua Clulow <josh@sysmgr.org>
-rw-r--r--usr/src/lib/fm/topo/modules/common/pcibus/pcibus.c34
1 files 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);
}