static int fi_bgq_fillinfo()

in prov/bgq/src/fi_bgq_init.c [111:264]


static int fi_bgq_fillinfo(struct fi_info *fi, const char *node,
		const char* service, const struct fi_info *hints,
	        uint64_t flags)
{
	int ret;
	uint64_t caps;

	if (!fi)
		goto err;

	if (!hints && !node && !service)
		goto err;

	if (hints->dest_addr) {
		FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_FABRIC,
				"cannot support dest_addr lookups now");
		errno = FI_ENOSYS;
		return -errno;
	}

	fi->next = NULL;
	fi->caps = FI_BGQ_DEFAULT_CAPS;

	/* set the mode that we require */
	fi->mode = FI_ASYNC_IOV;
	fi->mode |= (FI_CONTEXT);

	/* clear modes that we do not require */
	fi->mode &= (~FI_LOCAL_MR);
	fi->mode &= (~FI_MSG_PREFIX);

	fi->addr_format = FI_ADDR_BGQ;
	fi->src_addrlen = 24; // includes null
	fi->dest_addrlen = 24; // includes null
#ifdef TODO
	if (flags & FI_SOURCE) {
		fi->src_addr = strdup(service);
		if (!fi->src_addr) {
			goto err;
		}
	}
#endif
	fi->dest_addr = NULL;

	/*
	 * man/fi_fabric.3
	 *
	 * On input to fi_getinfo, a user may set this (fi_fabric_attr::fabric)
	 * to an opened fabric instance to restrict output to the given fabric.
	 * On output from fi_getinfo, if no fabric was specified, but the user
	 * has an opened instance of the named fabric, this (fi_fabric_attr::fabric)
	 * will reference the first opened instance. If no instance has been
	 * opened, this field will be NULL.
	 */

	fi->fabric_attr->name = strdup(FI_BGQ_FABRIC_NAME);
	if (!fi->fabric_attr->name) {
		FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_FABRIC,
				"memory allocation failed");
		goto err;
	}
	fi->fabric_attr->prov_version = FI_BGQ_PROVIDER_VERSION;

	memcpy(fi->tx_attr, fi_bgq_global.default_tx_attr, sizeof(*fi->tx_attr));

	if (hints->tx_attr) {

		/*
		 * man/fi_endpoint.3
		 *
		 *   fi_tx_attr::caps
		 *
		 *   "... If the caps field is 0 on input to fi_getinfo(3), the
		 *   caps value from the fi_info structure will be used."
		 */
		if (hints->tx_attr->caps) {
			fi->tx_attr->caps = hints->tx_attr->caps;
		}

		/* adjust parameters down from what requested if required */
		fi->tx_attr->op_flags = hints->tx_attr->op_flags;
	} else if (hints->caps) {
		fi->tx_attr->caps = hints->caps;
	}

	memcpy(fi->rx_attr, fi_bgq_global.default_rx_attr, sizeof(*fi->rx_attr));
	if (hints->rx_attr) {

		/*
		 * man/fi_endpoint.3
		 *
		 *   fi_rx_attr::caps
		 *
		 *   "... If the caps field is 0 on input to fi_getinfo(3), the
		 *   caps value from the fi_info structure will be used."
		 */
		if (hints->rx_attr->caps) {
			fi->rx_attr->caps = hints->rx_attr->caps;
		}

		/* adjust parameters down from what requested if required */
		fi->rx_attr->op_flags = hints->rx_attr->op_flags;
		if (hints->rx_attr->total_buffered_recv > 0 &&
			hints->rx_attr->total_buffered_recv < fi_bgq_global.default_rx_attr->total_buffered_recv)
				fi->rx_attr->total_buffered_recv = hints->rx_attr->total_buffered_recv;
	} else if (hints->caps) {
		fi->rx_attr->caps = hints->caps;
	}

	caps = fi->caps | fi->tx_attr->caps | fi->rx_attr->caps;

	/*
	 * man/fi_domain.3
	 *
	 * On input to fi_getinfo, a user may set this (fi_domain_attr::domain)
	 * to an opened domain instance to restrict output to the given domain.
	 * On output from fi_getinfo, if no domain was specified, but the user
	 * has an opened instance of the named domain, this (fi_domain_attr::domain)
	 * will reference the first opened instance. If no instance has been
	 * opened, this field will be NULL.
	 */

	ret = fi_bgq_choose_domain(caps, fi->domain_attr, hints->domain_attr);
	if (ret) {
		FI_LOG(fi_bgq_global.prov, FI_LOG_DEBUG, FI_LOG_FABRIC,
				"cannot find appropriate domain");
		goto err;
	}

	memcpy(fi->ep_attr, fi_bgq_global.default_ep_attr, sizeof(*fi->ep_attr));
	if (hints->ep_attr) {
		/* adjust parameters down from what requested if required */
		fi->ep_attr->type	= hints->ep_attr->type;
		if (hints->ep_attr->max_msg_size > 0 &&
			hints->ep_attr->max_msg_size <= fi_bgq_global.default_ep_attr->max_msg_size)
				fi->ep_attr->max_msg_size = hints->ep_attr->max_msg_size;

		if (0 != hints->ep_attr->tx_ctx_cnt && hints->ep_attr->tx_ctx_cnt <= fi->ep_attr->tx_ctx_cnt)
			fi->ep_attr->tx_ctx_cnt = hints->ep_attr->tx_ctx_cnt;	/* TODO - check */

		if (0 != hints->ep_attr->rx_ctx_cnt && hints->ep_attr->rx_ctx_cnt <= fi->ep_attr->rx_ctx_cnt)
			fi->ep_attr->rx_ctx_cnt = hints->ep_attr->rx_ctx_cnt;	/* TODO - check */
	}



	return 0;
err:
	if (fi->domain_attr->name) free(fi->domain_attr->name);
	if (fi->fabric_attr->name) free(fi->fabric_attr->name);
	if (fi->fabric_attr->prov_name) free(fi->fabric_attr->prov_name);
	errno = FI_ENODATA;
	return -errno;
}