static int verify;
static int nodelay;
static int repetitions = 1;
+static int ep_index;
+static int enum_ep;
enum perf_query_output {
PERF_QUERY_NONE,
{
printf("usage 1: %s\n", program);
printf("Query specified ibacm service for data\n");
+ printf(" [-e [N]] - display one or all endpoints:\n");
+ printf(" No index: all endpoints\n");
+ printf(" N: endpoint N (N = 1, 2, ...)\n");
printf(" [-f addr_format] - i(p), n(ame), l(id), g(gid), or u(nspecified)\n");
printf(" address format for -s and -d options, default: 'u'\n");
printf(" [-s src_addr] - source address for path queries\n");
ib_acm_free_perf(counters);
}
+static int enumerate_ep(char *svc, int index)
+{
+ static int labels;
+ int ret, i;
+ struct acm_ep_config_data *ep_data;
+
+ ret = ib_acm_enum_ep(index, &ep_data);
+ if (ret)
+ return ret;
+
+ if (!labels) {
+ printf("svc,guid,port,pkey,ep_index,prov,addr_0,addresses\n");
+ labels = 1;
+ }
+
+ printf("%s,0x%016lx,%d,0x%04x,%d,%s", svc, ep_data->dev_guid,
+ ep_data->port_num, ep_data->pkey, index, ep_data->prov_name);
+ for (i = 0; i < ep_data->addr_cnt; i++)
+ printf(",%s", ep_data->addrs[i].name);
+ printf("\n");
+ ib_acm_free_ep_data(ep_data);
+
+ return 0;
+}
+
+static void enumerate_eps(char *svc)
+{
+ int index = 1;
+
+ if (ep_index > 0) {
+ if (enumerate_ep(svc, ep_index))
+ printf(" Endpoint %d is not available\n", ep_index);
+ } else {
+ while (!enumerate_ep(svc, index++));
+ }
+}
+
static int query_svcs(void)
{
char **svc_list;
if (perf_query)
query_perf(svc_list[i]);
+ if (enum_ep)
+ enumerate_eps(svc_list[i]);
+
ib_acm_disconnect();
}
if (ret)
goto out;
- while ((op = getopt(argc, argv, "f:s:d:vcA::O::D:P::S:C:V")) != -1) {
+ while ((op = getopt(argc, argv, "e::f:s:d:vcA::O::D:P::S:C:V")) != -1) {
switch (op) {
+ case 'e':
+ enum_ep = 1;
+ if (opt_arg(argc, argv))
+ ep_index = atoi(opt_arg(argc, argv));
+ break;
case 'f':
addr_type = optarg[0];
if (addr_type != 'i' && addr_type != 'n' &&
}
if ((src_arg && !dest_arg) ||
- (!src_arg && !dest_arg && !perf_query && !make_addr && !make_opts))
+ (!src_arg && !dest_arg && !perf_query && !make_addr && !make_opts &&
+ !enum_ep))
goto show_use;
- if (dest_arg || perf_query)
+ if (dest_arg || perf_query || enum_ep)
ret = query_svcs();
if (!ret && make_addr)
return ret;
}
+int ib_acm_enum_ep(int index, struct acm_ep_config_data **data)
+{
+ struct acm_msg msg;
+ int ret;
+ int len;
+ int cnt;
+ struct acm_ep_config_data *edata;
+
+ lock_acquire(&lock);
+ memset(&msg, 0, sizeof msg);
+ msg.hdr.version = ACM_VERSION;
+ msg.hdr.opcode = ACM_OP_EP_QUERY;
+ msg.hdr.data[0] = index;
+ msg.hdr.length = htons(ACM_MSG_HDR_LENGTH);
+
+ ret = send(sock, (char *) &msg, ACM_MSG_HDR_LENGTH, 0);
+ if (ret != ACM_MSG_HDR_LENGTH)
+ goto out;
+
+ ret = recv(sock, (char *) &msg, sizeof msg, 0);
+ if (ret < ACM_MSG_HDR_LENGTH || ret != ntohs(msg.hdr.length)) {
+ ret = ACM_STATUS_EINVAL;
+ goto out;
+ }
+
+ if (msg.hdr.status) {
+ ret = acm_error(msg.hdr.status);
+ goto out;
+ }
+
+ cnt = ntohs(msg.ep_data[0].addr_cnt);
+ len = sizeof(struct acm_ep_config_data) +
+ ACM_MAX_ADDRESS * cnt;
+ edata = malloc(len);
+ if (!edata) {
+ ret = ACM_STATUS_ENOMEM;
+ goto out;
+ }
+
+ memcpy(edata, &msg.ep_data[0], len);
+ edata->dev_guid = ntohll(msg.ep_data[0].dev_guid);
+ edata->pkey = ntohs(msg.ep_data[0].pkey);
+ edata->addr_cnt = cnt;
+ *data = edata;
+ ret = 0;
+out:
+ lock_release(&lock);
+ return ret;
+}
+
const char *ib_acm_cntr_name(int index)
{
static const char *const cntr_name[] = {