예제 #1
0
static int __gnix_amo_txd_complete(void *arg, gni_return_t tx_status)
{
	struct gnix_tx_descriptor *txd = (struct gnix_tx_descriptor *)arg;
	struct gnix_fab_req *req = txd->req;
	int rc = FI_SUCCESS;

	_gnix_nic_tx_free(req->vc->ep->nic, txd);

	if (tx_status != GNI_RC_SUCCESS) {
		return __gnix_amo_post_err(req, FI_ECANCELED);
	}

	if (req->vc->peer_caps & FI_RMA_EVENT) {
		/* control message needed for a counter event. */
		req->work_fn = __gnix_amo_send_cntr_req;
		_gnix_vc_queue_work_req(req);
	} else {
		/* complete request */
		rc = __gnix_amo_send_completion(req->vc->ep, req);
		if (rc != FI_SUCCESS)
			GNIX_WARN(FI_LOG_EP_DATA,
				  "__gnix_amo_send_completion() failed: %d\n",
				  rc);

		__gnix_amo_fr_complete(req);
	}

	return FI_SUCCESS;
}
예제 #2
0
static int __gnix_amo_txd_complete(void *arg, gni_return_t tx_status)
{
	struct gnix_tx_descriptor *txd = (struct gnix_tx_descriptor *)arg;
	struct gnix_fab_req *req = txd->req;
	int rc = FI_SUCCESS;
	uint32_t read_data32;
	uint64_t read_data64;

	if (tx_status != GNI_RC_SUCCESS) {
		return __gnix_amo_post_err(txd);
	}

	/* FI_ATOMIC_READ data is delivered to operand buffer in addition to
	 * the results buffer. */
	if (req->amo.op == FI_ATOMIC_READ) {
		switch(fi_datatype_size(req->amo.datatype)) {
		case sizeof(uint32_t):
			read_data32 = *(uint32_t *)req->amo.loc_addr;
			*(uint32_t *)req->amo.read_buf = read_data32;
			break;
		case sizeof(uint64_t):
			read_data64 = *(uint64_t *)req->amo.loc_addr;
			*(uint64_t *)req->amo.read_buf = read_data64;
			break;
		default:
			GNIX_WARN(FI_LOG_EP_DATA, "Invalid datatype: %d\n",
				  req->amo.datatype);
			assert(0);
			break;
		}
	}

	/* complete request */
	rc = __gnix_amo_send_completion(req->vc->ep, req);
	if (rc != FI_SUCCESS)
		GNIX_WARN(FI_LOG_EP_DATA,
			  "__gnix_amo_send_completion() failed: %d\n",
			  rc);

	__gnix_amo_fr_complete(req, txd);

	return FI_SUCCESS;
}
예제 #3
0
static int __gnix_amo_txd_cntr_complete(void *arg, gni_return_t tx_status)
{
	struct gnix_tx_descriptor *txd = (struct gnix_tx_descriptor *)arg;
	struct gnix_fab_req *req = txd->req;
	int rc;

	_gnix_nic_tx_free(req->gnix_ep->nic, txd);

	if (tx_status != GNI_RC_SUCCESS)
		return __gnix_amo_post_err(req, FI_ECANCELED);

	/* Successful data delivery.  Generate local completion. */
	rc = __gnix_amo_send_completion(req->vc->ep, req);
	if (rc != FI_SUCCESS)
		GNIX_WARN(FI_LOG_EP_DATA,
			  "__gnix_amo_send_completion() failed: %d\n",
			  rc);

	__gnix_amo_fr_complete(req);

	return FI_SUCCESS;
}