In preparation for the kernel switching from ACPI0016 devices as the dport
identifier to the corresponding host-bridge as the identifier, add support
for listing the dport firmware_node as an alias, and determining when the
dev_path is the phys_path for a dport or a target.

The code paths that depend on phys_path like cxl_target_maps_memdev() and
cxl_dport_maps_memdev() already have appropriate fallbacks to dev_path.

Signed-off-by: Dan Williams <[email protected]>
---
 cxl/json.c         |   20 +++++++++++++++++---
 cxl/lib/libcxl.c   |   31 +++++++++++++++++++++++++++++++
 cxl/lib/libcxl.sym |    6 ++++++
 cxl/lib/private.h  |    2 ++
 cxl/libcxl.h       |    2 ++
 5 files changed, 58 insertions(+), 3 deletions(-)

diff --git a/cxl/json.c b/cxl/json.c
index 63c17519aba1..5cff532acb13 100644
--- a/cxl/json.c
+++ b/cxl/json.c
@@ -384,7 +384,7 @@ void util_cxl_dports_append_json(struct json_object *jport,
 
        cxl_dport_foreach(port, dport) {
                struct json_object *jdport;
-               const char *phys_node;
+               const char *phys_node, *fw_node;
 
                if (!util_cxl_dport_filter_by_memdev(dport, ident, serial))
                        continue;
@@ -404,6 +404,13 @@ void util_cxl_dports_append_json(struct json_object *jport,
                                json_object_object_add(jdport, "alias", jobj);
                }
 
+               fw_node = cxl_dport_get_firmware_node(dport);
+               if (fw_node) {
+                       jobj = json_object_new_string(fw_node);
+                       if (jobj)
+                               json_object_object_add(jdport, "alias", jobj);
+               }
+
                val = cxl_dport_get_id(dport);
                jobj = util_json_object_hex(val, flags);
                if (jobj)
@@ -711,9 +718,9 @@ void util_cxl_targets_append_json(struct json_object 
*jdecoder,
                return;
 
        cxl_target_foreach(decoder, target) {
-               struct json_object *jtarget;
-               const char *phys_node;
                const char *devname;
+               struct json_object *jtarget;
+               const char *phys_node, *fw_node;
 
                if (!util_cxl_target_filter_by_memdev(target, ident, serial))
                        continue;
@@ -734,6 +741,13 @@ void util_cxl_targets_append_json(struct json_object 
*jdecoder,
                                json_object_object_add(jtarget, "alias", jobj);
                }
 
+               fw_node = cxl_target_get_firmware_node(target);
+               if (fw_node) {
+                       jobj = json_object_new_string(fw_node);
+                       if (jobj)
+                               json_object_object_add(jtarget, "alias", jobj);
+               }
+
                val = cxl_target_get_position(target);
                jobj = json_object_new_int(val);
                if (jobj)
diff --git a/cxl/lib/libcxl.c b/cxl/lib/libcxl.c
index e8c5d4444dd0..a69e31bc8a6e 100644
--- a/cxl/lib/libcxl.c
+++ b/cxl/lib/libcxl.c
@@ -77,6 +77,7 @@ static void free_target(struct cxl_target *target, struct 
list_head *head)
                list_del_from(head, &target->list);
        free(target->dev_path);
        free(target->phys_path);
+       free(target->fw_path);
        free(target);
 }
 
@@ -134,6 +135,7 @@ static void free_dport(struct cxl_dport *dport, struct 
list_head *head)
        free(dport->dev_buf);
        free(dport->dev_path);
        free(dport->phys_path);
+       free(dport->fw_path);
        free(dport);
 }
 
@@ -1856,6 +1858,15 @@ static void *add_cxl_decoder(void *parent, int id, const 
char *cxldecoder_base)
                dbg(ctx, "%s: target%ld %s phys_path: %s\n", devname, i,
                    target->dev_path,
                    target->phys_path ? target->phys_path : "none");
+
+               sprintf(port->dev_buf, "%s/dport%d/firmware_node", 
port->dev_path, did);
+               target->fw_path = realpath(port->dev_buf, NULL);
+               dbg(ctx, "%s: target%ld %s fw_path: %s\n", devname, i,
+                   target->dev_path,
+                   target->fw_path ? target->fw_path : "none");
+
+               if (!target->phys_path && target->fw_path)
+                       target->phys_path = strdup(target->dev_path);
                list_add(&decoder->targets, &target->list);
        }
 
@@ -2288,6 +2299,13 @@ CXL_EXPORT const char 
*cxl_target_get_physical_node(struct cxl_target *target)
        return devpath_to_devname(target->phys_path);
 }
 
+CXL_EXPORT const char *cxl_target_get_firmware_node(struct cxl_target *target)
+{
+       if (!target->fw_path)
+               return NULL;
+       return devpath_to_devname(target->fw_path);
+}
+
 CXL_EXPORT struct cxl_target *
 cxl_decoder_get_target_by_memdev(struct cxl_decoder *decoder,
                                 struct cxl_memdev *memdev)
@@ -2569,6 +2587,12 @@ static void *add_cxl_dport(void *parent, int id, const 
char *cxldport_base)
        sprintf(dport->dev_buf, "%s/physical_node", cxldport_base);
        dport->phys_path = realpath(dport->dev_buf, NULL);
 
+       sprintf(dport->dev_buf, "%s/firmware_node", cxldport_base);
+       dport->fw_path = realpath(dport->dev_buf, NULL);
+
+       if (!dport->phys_path && dport->fw_path)
+               dport->phys_path = strdup(dport->dev_path);
+
        cxl_dport_foreach(port, dport_dup)
                if (dport_dup->id == dport->id) {
                        free_dport(dport, NULL);
@@ -2629,6 +2653,13 @@ CXL_EXPORT const char 
*cxl_dport_get_physical_node(struct cxl_dport *dport)
        return devpath_to_devname(dport->phys_path);
 }
 
+CXL_EXPORT const char *cxl_dport_get_firmware_node(struct cxl_dport *dport)
+{
+       if (!dport->fw_path)
+               return NULL;
+       return devpath_to_devname(dport->fw_path);
+}
+
 CXL_EXPORT int cxl_dport_get_id(struct cxl_dport *dport)
 {
        return dport->id;
diff --git a/cxl/lib/libcxl.sym b/cxl/lib/libcxl.sym
index 8bb91e05638b..490ed1fda5d3 100644
--- a/cxl/lib/libcxl.sym
+++ b/cxl/lib/libcxl.sym
@@ -217,3 +217,9 @@ global:
        cxl_decoder_get_max_available_extent;
        cxl_decoder_get_region;
 } LIBCXL_2;
+
+LIBCXL_4 {
+global:
+       cxl_target_get_firmware_node;
+       cxl_dport_get_firmware_node;
+} LIBCXL_3;
diff --git a/cxl/lib/private.h b/cxl/lib/private.h
index 437eadeb670a..e378339ec353 100644
--- a/cxl/lib/private.h
+++ b/cxl/lib/private.h
@@ -45,6 +45,7 @@ struct cxl_dport {
        size_t buf_len;
        char *dev_path;
        char *phys_path;
+       char *fw_path;
        struct cxl_port *port;
        struct list_node list;
 };
@@ -93,6 +94,7 @@ struct cxl_target {
        struct cxl_decoder *decoder;
        char *dev_path;
        char *phys_path;
+       char *fw_path;
        int id, position;
 };
 
diff --git a/cxl/libcxl.h b/cxl/libcxl.h
index 9fe4e99263dd..1e0076908901 100644
--- a/cxl/libcxl.h
+++ b/cxl/libcxl.h
@@ -116,6 +116,7 @@ struct cxl_dport *cxl_dport_get_first(struct cxl_port 
*port);
 struct cxl_dport *cxl_dport_get_next(struct cxl_dport *dport);
 const char *cxl_dport_get_devname(struct cxl_dport *dport);
 const char *cxl_dport_get_physical_node(struct cxl_dport *dport);
+const char *cxl_dport_get_firmware_node(struct cxl_dport *dport);
 struct cxl_port *cxl_dport_get_port(struct cxl_dport *dport);
 int cxl_dport_get_id(struct cxl_dport *dport);
 bool cxl_dport_maps_memdev(struct cxl_dport *dport, struct cxl_memdev *memdev);
@@ -225,6 +226,7 @@ const char *cxl_target_get_devname(struct cxl_target 
*target);
 bool cxl_target_maps_memdev(struct cxl_target *target,
                            struct cxl_memdev *memdev);
 const char *cxl_target_get_physical_node(struct cxl_target *target);
+const char *cxl_target_get_firmware_node(struct cxl_target *target);
 
 #define cxl_target_foreach(decoder, target)                                    
\
        for (target = cxl_target_get_first(decoder); target != NULL;           \


Reply via email to