Add helper function to detect that the bus is cxl based.
Signed-off-by: Dave Jiang <[email protected]>
---
ndctl/lib/libndctl.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
ndctl/lib/libndctl.sym | 1 +
ndctl/lib/private.h | 1 +
ndctl/libndctl.h | 1 +
4 files changed, 56 insertions(+)
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index ad54f0626510..10422e24d38b 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -12,6 +12,7 @@
#include <ctype.h>
#include <fcntl.h>
#include <dirent.h>
+#include <libgen.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>
@@ -876,6 +877,48 @@ static enum ndctl_fwa_method fwa_method_to_method(const
char *fwa_method)
return NDCTL_FWA_METHOD_RESET;
}
+static int is_ndbus_cxl(const char *ctl_base)
+{
+ char *path, *ppath, *subsys;
+ char tmp_path[PATH_MAX];
+ int rc;
+
+ /* get the real path of ctl_base */
+ path = realpath(ctl_base, NULL);
+ if (!path)
+ return -errno;
+
+ /* setup to get the nd bridge device backing the ctl */
+ sprintf(tmp_path, "%s/device", path);
+ free(path);
+
+ path = realpath(tmp_path, NULL);
+ if (!path)
+ return -errno;
+
+ /* get the parent dir of the ndbus, which should be the nvdimm-bridge */
+ ppath = dirname(path);
+
+ /* setup to get the subsystem of the nvdimm-bridge */
+ sprintf(tmp_path, "%s/%s", ppath, "subsystem");
+ free(path);
+
+ path = realpath(tmp_path, NULL);
+ if (!path)
+ return -errno;
+
+ subsys = basename(path);
+
+ /* check if subsystem is cxl */
+ if (!strcmp(subsys, "cxl"))
+ rc = 1;
+ else
+ rc = 0;
+
+ free(path);
+ return rc;
+}
+
static void *add_bus(void *parent, int id, const char *ctl_base)
{
char buf[SYSFS_ATTR_SIZE];
@@ -919,6 +962,11 @@ static void *add_bus(void *parent, int id, const char
*ctl_base)
else
bus->has_of_node = 1;
+ if (is_ndbus_cxl(ctl_base))
+ bus->has_cxl = 1;
+ else
+ bus->has_cxl = 0;
+
sprintf(path, "%s/device/nfit/dsm_mask", ctl_base);
if (sysfs_read_attr(ctx, path, buf) < 0)
bus->nfit_dsm_mask = 0;
@@ -1050,6 +1098,11 @@ NDCTL_EXPORT int ndctl_bus_has_of_node(struct ndctl_bus
*bus)
return bus->has_of_node;
}
+NDCTL_EXPORT int ndctl_bus_has_cxl(struct ndctl_bus *bus)
+{
+ return bus->has_cxl;
+}
+
NDCTL_EXPORT int ndctl_bus_is_papr_scm(struct ndctl_bus *bus)
{
char buf[SYSFS_ATTR_SIZE];
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index c933163c0380..3a3e8bbd63ef 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -465,4 +465,5 @@ LIBNDCTL_27 {
LIBNDCTL_28 {
ndctl_dimm_disable_master_passphrase;
+ ndctl_bus_has_cxl;
} LIBNDCTL_27;
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index e5c56295556d..46bc8908bd90 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -163,6 +163,7 @@ struct ndctl_bus {
int regions_init;
int has_nfit;
int has_of_node;
+ int has_cxl;
char *bus_path;
char *bus_buf;
size_t buf_len;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index c52e82a6f826..91ef0f42f654 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -133,6 +133,7 @@ struct ndctl_bus *ndctl_bus_get_next(struct ndctl_bus *bus);
struct ndctl_ctx *ndctl_bus_get_ctx(struct ndctl_bus *bus);
int ndctl_bus_has_nfit(struct ndctl_bus *bus);
int ndctl_bus_has_of_node(struct ndctl_bus *bus);
+int ndctl_bus_has_cxl(struct ndctl_bus *bus);
int ndctl_bus_is_papr_scm(struct ndctl_bus *bus);
unsigned int ndctl_bus_get_major(struct ndctl_bus *bus);
unsigned int ndctl_bus_get_minor(struct ndctl_bus *bus);