return 0;
}
+static void ucma_convert_path(struct ibv_path_data *path_data,
+ struct ibv_sa_path_rec *sa_path)
+{
+ uint32_t fl_hop;
+
+ sa_path->dgid = path_data->path.dgid;
+ sa_path->sgid = path_data->path.sgid;
+ sa_path->dlid = path_data->path.dlid;
+ sa_path->slid = path_data->path.slid;
+ sa_path->raw_traffic = 0;
+
+ fl_hop = ntohl(path_data->path.flowlabel_hoplimit);
+ sa_path->flow_label = htonl(fl_hop >> 8);
+ sa_path->hop_limit = (uint8_t) fl_hop;
+
+ sa_path->traffic_class = path_data->path.tclass;
+ sa_path->reversible = path_data->path.reversible_numpath >> 7;
+ sa_path->numb_path = 1;
+ sa_path->pkey = path_data->path.pkey;
+ sa_path->sl = ntohs(path_data->path.qosclass_sl) & 0xF;
+ sa_path->mtu_selector = 1;
+ sa_path->mtu = path_data->path.mtu & 0x1F;
+ sa_path->rate_selector = 1;
+ sa_path->rate = path_data->path.rate & 0x1F;
+ sa_path->packet_life_time_selector = 1;
+ sa_path->packet_life_time = path_data->path.packetlifetime & 0x1F;
+
+ sa_path->preference = (uint8_t) path_data->flags;
+}
+
+static int ucma_query_path(struct rdma_cm_id *id)
+{
+ struct ucma_abi_query_path_resp *resp;
+ struct ucma_abi_query *cmd;
+ struct ucma_abi_cmd_hdr *hdr;
+ struct cma_id_private *id_priv;
+ void *msg;
+ int ret, size, i;
+
+ size = sizeof(*hdr) + sizeof(*cmd);
+ msg = alloca(size);
+ if (!msg)
+ return ERR(ENOMEM);
+
+ hdr = msg;
+ cmd = msg + sizeof(*hdr);
+
+ hdr->cmd = UCMA_CMD_QUERY;
+ hdr->in = sizeof(*cmd);
+ hdr->out = sizeof(*resp) + sizeof(struct ibv_path_data) * 6;
+
+ memset(cmd, 0, sizeof(*cmd));
+
+ resp = alloca(hdr->out);
+ if (!resp)
+ return ERR(ENOMEM);
+
+ id_priv = container_of(id, struct cma_id_private, id);
+ cmd->response = (uintptr_t) resp;
+ cmd->id = id_priv->handle;
+ cmd->option = UCMA_QUERY_PATH;
+
+ ret = write(id->channel->fd, msg, size);
+ if (ret != size)
+ return (ret >= 0) ? ERR(ENODATA) : -1;
+
+ VALGRIND_MAKE_MEM_DEFINED(resp, hdr->out);
+
+ if (resp->num_paths) {
+ id->route.path_rec = malloc(sizeof(*id->route.path_rec) *
+ resp->num_paths);
+ if (!id->route.path_rec)
+ return ERR(ENOMEM);
+
+ id->route.num_paths = resp->num_paths;
+ for (i = 0; i < resp->num_paths; i++)
+ ucma_convert_path(&resp->path_data[i], &id->route.path_rec[i]);
+ }
+
+ return 0;
+}
+
static int ucma_query_route(struct rdma_cm_id *id)
{
struct ucma_abi_query_route_resp *resp;