On 16/11/2020 22:23, Jason Gunthorpe wrote: > This implements all the query_device command flows under a single call. > > Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx> > --- > libibverbs/cmd_device.c | 155 +++++++++++++++++++++++++++++++++++ > libibverbs/driver.h | 5 ++ > libibverbs/libibverbs.map.in | 1 + > 3 files changed, 161 insertions(+) > > diff --git a/libibverbs/cmd_device.c b/libibverbs/cmd_device.c > index 6c8e01ec9866a9..0019784ee779c1 100644 > --- a/libibverbs/cmd_device.c > +++ b/libibverbs/cmd_device.c > @@ -35,6 +35,7 @@ > #include <stdlib.h> > #include <dirent.h> > #include <infiniband/cmd_write.h> > +#include <util/util.h> > > #include <net/if.h> > > @@ -516,3 +517,157 @@ ssize_t _ibv_query_gid_table(struct ibv_context *context, > > return num_entries; > } > + > +int ibv_cmd_query_device_any(struct ibv_context *context, > + const struct ibv_query_device_ex_input *input, > + struct ibv_device_attr_ex *attr, size_t attr_size, > + struct ib_uverbs_ex_query_device_resp *resp, > + size_t *resp_size) > +{ > + struct ib_uverbs_ex_query_device_resp internal_resp; > + size_t internal_resp_size; > + int err; > + > + if (input && input->comp_mask) > + return EINVAL; > + if (attr_size < sizeof(attr->orig_attr)) > + return EINVAL; > + > + if (!resp) { > + resp = &internal_resp; > + internal_resp_size = sizeof(internal_resp); > + resp_size = &internal_resp_size; > + } > + memset(attr, 0, attr_size); > + memset(resp, 0, *resp_size); > + > + if (attr_size > sizeof(attr->orig_attr)) { > + struct ibv_query_device_ex cmd = {}; > + > + err = execute_cmd_write_ex(context, > + IB_USER_VERBS_EX_CMD_QUERY_DEVICE, > + &cmd, sizeof(cmd), resp, *resp_size); > + if (err) { > + if (err != EOPNOTSUPP) Are you sure about that? I think older kernels return ENOSYS.