@@ -221,6 +221,7 @@ const char *cxl_port_get_host(struct cxl_port *port);
struct cxl_port *cxl_decoder_get_port(struct cxl_decoder *decoder);
struct cxl_port *cxl_port_get_next_all(struct cxl_port *port,
const struct cxl_port *top);
+struct cxl_port *cxl_dport_get_port(struct cxl_dport *dport);
#define cxl_port_foreach(parent, port) \
for (port = cxl_port_get_first(parent); port != NULL; \
@@ -435,6 +435,48 @@ util_cxl_decoder_filter_by_memdev(struct cxl_decoder *decoder,
return NULL;
}
+struct cxl_target *util_cxl_target_filter_by_memdev(struct cxl_target *target,
+ const char *ident,
+ const char *serial)
+{
+ struct cxl_decoder *decoder = cxl_target_get_decoder(target);
+ struct cxl_ctx *ctx = cxl_decoder_get_ctx(decoder);
+ struct cxl_memdev *memdev;
+
+ if (!ident && !serial)
+ return target;
+
+ cxl_memdev_foreach(ctx, memdev) {
+ if (!util_cxl_memdev_filter(memdev, ident, serial))
+ continue;
+ if (cxl_target_maps_memdev(target, memdev))
+ return target;
+ }
+
+ return NULL;
+}
+
+struct cxl_dport *util_cxl_dport_filter_by_memdev(struct cxl_dport *dport,
+ const char *ident,
+ const char *serial)
+{
+ struct cxl_port *port = cxl_dport_get_port(dport);
+ struct cxl_ctx *ctx = cxl_port_get_ctx(port);
+ struct cxl_memdev *memdev;
+
+ if (!ident && !serial)
+ return dport;
+
+ cxl_memdev_foreach (ctx, memdev) {
+ if (!util_cxl_memdev_filter(memdev, ident, serial))
+ continue;
+ if (cxl_dport_maps_memdev(dport, memdev))
+ return dport;
+ }
+
+ return NULL;
+}
+
static bool __memdev_filter_by_decoder(struct cxl_memdev *memdev,
struct cxl_port *port, const char *ident)
{
@@ -639,6 +681,9 @@ static void walk_decoders(struct cxl_port *port, struct cxl_filter_params *p,
dbg(p, "decoder object allocation failure\n");
continue;
}
+ util_cxl_targets_append_json(jdecoder, decoder,
+ p->memdev_filter, p->serial_filter,
+ flags);
json_object_array_add(jdecoders, jdecoder);
}
}
@@ -756,6 +801,9 @@ walk_child_ports(struct cxl_port *parent_port, struct cxl_filter_params *p,
err(p, "%s: failed to list\n", devname);
continue;
}
+ util_cxl_dports_append_json(jport, port,
+ p->memdev_filter,
+ p->serial_filter, flags);
json_object_array_add(jports, jport);
jchildports = json_object_new_array();
if (!jchildports) {
@@ -914,6 +962,9 @@ int cxl_filter_walk(struct cxl_ctx *ctx, struct cxl_filter_params *p)
dbg(p, "bus object allocation failure\n");
continue;
}
+ util_cxl_dports_append_json(jbus, port,
+ p->memdev_filter,
+ p->serial_filter, flags);
json_object_array_add(jbuses, jbus);
if (p->ports) {
jchildports = json_object_new_array();
@@ -42,6 +42,12 @@ struct cxl_port *util_cxl_port_filter(struct cxl_port *port, const char *ident,
enum cxl_port_filter_mode mode);
struct cxl_endpoint *util_cxl_endpoint_filter(struct cxl_endpoint *endpoint,
const char *__ident);
+struct cxl_target *util_cxl_target_filter_by_memdev(struct cxl_target *target,
+ const char *ident,
+ const char *serial);
+struct cxl_dport *util_cxl_dport_filter_by_memdev(struct cxl_dport *dport,
+ const char *ident,
+ const char *serial);
int cxl_filter_walk(struct cxl_ctx *ctx, struct cxl_filter_params *param);
bool cxl_filter_has(const char *needle, const char *__filter);
#endif /* _CXL_UTIL_FILTER_H_ */
@@ -8,6 +8,7 @@
#include <json-c/printbuf.h>
#include <ccan/short_types/short_types.h>
+#include "filter.h"
#include "json.h"
static struct json_object *util_cxl_memdev_health_to_json(
@@ -241,9 +242,9 @@ struct json_object *util_cxl_memdev_to_json(struct cxl_memdev *memdev,
return jdev;
}
-static struct json_object *util_cxl_dports_to_json(struct json_object *jport,
- struct cxl_port *port,
- unsigned long flags)
+void util_cxl_dports_append_json(struct json_object *jport,
+ struct cxl_port *port, const char *ident,
+ const char *serial, unsigned long flags)
{
struct json_object *jobj, *jdports;
struct cxl_dport *dport;
@@ -251,7 +252,7 @@ static struct json_object *util_cxl_dports_to_json(struct json_object *jport,
val = cxl_port_get_nr_dports(port);
if (!val || !(flags & UTIL_JSON_TARGETS))
- return jport;
+ return;
jobj = json_object_new_int(val);
if (jobj)
@@ -259,12 +260,15 @@ static struct json_object *util_cxl_dports_to_json(struct json_object *jport,
jdports = json_object_new_array();
if (!jdports)
- return jport;
+ return;
cxl_dport_foreach(port, dport) {
struct json_object *jdport;
const char *phys_node;
+ if (!util_cxl_dport_filter_by_memdev(dport, ident, serial))
+ continue;
+
jdport = json_object_new_object();
if (!jdport)
continue;
@@ -289,8 +293,6 @@ static struct json_object *util_cxl_dports_to_json(struct json_object *jport,
}
json_object_object_add(jport, "dports", jdports);
-
- return jport;
}
struct json_object *util_cxl_bus_to_json(struct cxl_bus *bus,
@@ -311,7 +313,7 @@ struct json_object *util_cxl_bus_to_json(struct cxl_bus *bus,
if (jobj)
json_object_object_add(jbus, "provider", jobj);
- return util_cxl_dports_to_json(jbus, cxl_bus_get_port(bus), flags);
+ return jbus;
}
struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
@@ -320,8 +322,6 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
const char *devname = cxl_decoder_get_devname(decoder);
struct cxl_port *port = cxl_decoder_get_port(decoder);
struct json_object *jdecoder, *jobj;
- struct json_object *jtargets;
- struct cxl_target *target;
u64 val;
jdecoder = json_object_new_object();
@@ -375,9 +375,22 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
jobj);
}
+ return jdecoder;
+}
+
+void util_cxl_targets_append_json(struct json_object *jdecoder,
+ struct cxl_decoder *decoder,
+ const char *ident, const char *serial,
+ unsigned long flags)
+{
+ struct cxl_port *port = cxl_decoder_get_port(decoder);
+ struct json_object *jobj, *jtargets;
+ struct cxl_target *target;
+ int val;
+
/* Endpoints don't have targets, they *are* targets */
if (cxl_port_is_endpoint(port))
- return jdecoder;
+ return;
val = cxl_decoder_get_nr_targets(decoder);
jobj = json_object_new_int(val);
@@ -386,16 +399,21 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
if (!(flags & UTIL_JSON_TARGETS) ||
!cxl_decoder_get_nr_targets(decoder))
- return jdecoder;
+ return;
jtargets = json_object_new_array();
if (!jtargets)
- return jdecoder;
+ return;
cxl_target_foreach(decoder, target) {
- struct json_object *jtarget = json_object_new_object();
+ struct json_object *jtarget;
const char *phys_node;
+ const char *devname;
+
+ if (!util_cxl_target_filter_by_memdev(target, ident, serial))
+ continue;
+ jtarget = json_object_new_object();
if (!jtarget)
continue;
@@ -425,9 +443,6 @@ struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
}
json_object_object_add(jdecoder, "targets", jtargets);
-
- return jdecoder;
-
}
static struct json_object *__util_cxl_port_to_json(struct cxl_port *port,
@@ -455,7 +470,7 @@ static struct json_object *__util_cxl_port_to_json(struct cxl_port *port,
json_object_object_add(jport, "state", jobj);
}
- return util_cxl_dports_to_json(jport, port, flags);
+ return jport;
}
struct json_object *util_cxl_port_to_json(struct cxl_port *port,
@@ -15,4 +15,11 @@ struct json_object *util_cxl_endpoint_to_json(struct cxl_endpoint *endpoint,
unsigned long flags);
struct json_object *util_cxl_decoder_to_json(struct cxl_decoder *decoder,
unsigned long flags);
+void util_cxl_targets_append_json(struct json_object *jdecoder,
+ struct cxl_decoder *decoder,
+ const char *ident, const char *serial,
+ unsigned long flags);
+void util_cxl_dports_append_json(struct json_object *jport,
+ struct cxl_port *port, const char *ident,
+ const char *serial, unsigned long flags);
#endif /* __CXL_UTIL_JSON_H__ */
@@ -1527,6 +1527,11 @@ CXL_EXPORT int cxl_dport_get_id(struct cxl_dport *dport)
return dport->id;
}
+CXL_EXPORT struct cxl_port *cxl_dport_get_port(struct cxl_dport *dport)
+{
+ return dport->port;
+}
+
CXL_EXPORT bool cxl_dport_maps_memdev(struct cxl_dport *dport,
struct cxl_memdev *memdev)
{
@@ -152,6 +152,7 @@ global:
cxl_dport_get_devname;
cxl_dport_get_physical_node;
cxl_dport_get_id;
+ cxl_dport_get_port;
cxl_port_get_dport_by_memdev;
cxl_dport_maps_memdev;
} LIBCXL_1;
@@ -113,6 +113,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);
+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);
struct cxl_dport *cxl_port_get_dport_by_memdev(struct cxl_port *port,
Trim dport / target information by the memdev filter. This is useful when validating connectivity and decoder programming. Reported-by: Ben Widawsky <ben.widawsky@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> --- Documentation/cxl/lib/libcxl.txt | 1 + cxl/filter.c | 51 ++++++++++++++++++++++++++++++++++++++ cxl/filter.h | 6 ++++ cxl/json.c | 51 +++++++++++++++++++++++++------------- cxl/json.h | 7 +++++ cxl/lib/libcxl.c | 5 ++++ cxl/lib/libcxl.sym | 1 + cxl/libcxl.h | 1 + 8 files changed, 105 insertions(+), 18 deletions(-)