@@ -348,6 +348,10 @@ struct json_object *util_cxl_memdev_to_json(struct cxl_memdev *memdev,
if (jobj)
json_object_object_add(jdev, "host", jobj);
+ jobj = json_object_new_string(cxl_memdev_get_parent_dport(memdev));
+ if (jobj)
+ json_object_object_add(jdev, "parent_dport", jobj);
+
if (!cxl_memdev_is_enabled(memdev)) {
jobj = json_object_new_string("disabled");
if (jobj)
@@ -769,6 +773,10 @@ static struct json_object *__util_cxl_port_to_json(struct cxl_port *port,
if (jobj)
json_object_object_add(jport, "host", jobj);
+ jobj = json_object_new_string(cxl_port_get_parent_dport(port));
+ if (jobj)
+ json_object_object_add(jport, "parent_dport", jobj);
+
jobj = json_object_new_int(cxl_port_get_depth(port));
if (jobj)
json_object_object_add(jport, "depth", jobj);
@@ -1267,6 +1267,16 @@ CXL_EXPORT const char *cxl_memdev_get_firmware_verison(struct cxl_memdev *memdev
return memdev->firmware_version;
}
+CXL_EXPORT const char *cxl_memdev_get_parent_dport(struct cxl_memdev *memdev)
+{
+ struct cxl_port *port = cxl_endpoint_get_port(memdev->endpoint);
+
+ if (port)
+ return cxl_port_get_parent_dport(port);
+
+ return NULL;
+}
+
static void bus_invalidate(struct cxl_bus *bus)
{
struct cxl_ctx *ctx = cxl_bus_get_ctx(bus);
@@ -1447,6 +1457,24 @@ CXL_EXPORT int cxl_memdev_nvdimm_bridge_active(struct cxl_memdev *memdev)
return is_enabled(path);
}
+static struct cxl_dport *cxl_port_find_parent_dport(struct cxl_port *port,
+ struct cxl_port *parent_port)
+{
+ struct cxl_dport *dport;
+
+ if (parent_port && parent_port->nr_dports) {
+ cxl_dport_foreach(parent_port, dport) {
+ /* HB ACPI0016 can have only one dport and being itself */
+ if (!strcmp(port->uport, dport->dev_path))
+ return NULL;
+ if (strstr(port->uport, dport->dev_path))
+ return dport;
+ }
+ }
+
+ return NULL;
+}
+
static int cxl_port_init(struct cxl_port *port, struct cxl_port *parent_port,
enum cxl_port_type type, struct cxl_ctx *ctx, int id,
const char *cxlport_base)
@@ -1486,6 +1514,8 @@ static int cxl_port_init(struct cxl_port *port, struct cxl_port *parent_port,
if (!port->uport)
goto err;
+ port->parent_dport = cxl_port_find_parent_dport(port, parent_port);
+
sprintf(path, "%s/modalias", cxlport_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
port->module = util_modalias_to_module(ctx, buf);
@@ -2404,6 +2434,15 @@ CXL_EXPORT struct cxl_port *cxl_port_get_parent(struct cxl_port *port)
return port->parent;
}
+CXL_EXPORT const char *cxl_port_get_parent_dport(struct cxl_port *port)
+{
+ if (port->parent_dport)
+ return devpath_to_devname(port->parent_dport->dev_path);
+ else if (port->parent)
+ return devpath_to_devname(port->parent->uport);
+ return NULL;
+}
+
CXL_EXPORT bool cxl_port_is_root(struct cxl_port *port)
{
return port->type == CXL_PORT_ROOT;
@@ -217,3 +217,9 @@ global:
cxl_decoder_get_max_available_extent;
cxl_decoder_get_region;
} LIBCXL_2;
+
+LIBCXL_4 {
+global:
+ cxl_memdev_get_parent_dport;
+ cxl_port_get_parent_dport;
+}LIBCXL_3;
@@ -71,6 +71,7 @@ struct cxl_port {
struct cxl_bus *bus;
enum cxl_port_type type;
struct cxl_port *parent;
+ struct cxl_dport *parent_dport;
struct kmod_module *module;
struct list_node list;
struct list_head child_ports;
@@ -34,6 +34,7 @@ void cxl_set_private_data(struct cxl_ctx *ctx, void *data);
void *cxl_get_private_data(struct cxl_ctx *ctx);
struct cxl_memdev;
+const char *cxl_memdev_get_parent_dport(struct cxl_memdev *memdev);
struct cxl_memdev *cxl_memdev_get_first(struct cxl_ctx *ctx);
struct cxl_memdev *cxl_memdev_get_next(struct cxl_memdev *memdev);
int cxl_memdev_get_id(struct cxl_memdev *memdev);
@@ -81,6 +82,7 @@ int cxl_bus_disable_invalidate(struct cxl_bus *bus);
bus = cxl_bus_get_next(bus))
struct cxl_port;
+const char *cxl_port_get_parent_dport(struct cxl_port *port);
struct cxl_port *cxl_port_get_first(struct cxl_port *parent);
struct cxl_port *cxl_port_get_next(struct cxl_port *port);
const char *cxl_port_get_devname(struct cxl_port *port);
The parent_dport attribute reprents the downstream port that the current device (cxl_port/cxl_memdev) is attached to. It will help to track the topology when plotting the cxl graph Signed-off-by: Fan Ni <fan.ni@samsung.com> --- cxl/json.c | 8 ++++++++ cxl/lib/libcxl.c | 39 +++++++++++++++++++++++++++++++++++++++ cxl/lib/libcxl.sym | 6 ++++++ cxl/lib/private.h | 1 + cxl/libcxl.h | 2 ++ 5 files changed, 56 insertions(+)