OpenSolaris_b135/lib/udapl/udapl_tavor/tavor/dapl_tavor_ibtf_mrsync.c

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */

/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#include "dapl.h"
#include "dapl_mr_util.h"
#include <dapl_tavor_ibtf_impl.h>

DAT_RETURN
dapls_ib_lmr_sync_rdma_common(
	IN	DAT_IA_HANDLE ia_handle,
	IN 	const DAT_LMR_TRIPLET *lmr_triplet,
	IN	DAT_VLEN num_segments,
	IN	uint32_t op_type)
{
	DAPL_IA		*ia_ptr;
	DAPL_LMR	*lmr;
	DAT_RETURN	dat_status;
	dapl_mr_sync_t	args;
	int		i, j;
	int		retval;

	if (DAPL_BAD_HANDLE(ia_handle, DAPL_MAGIC_IA)) {
		return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_IA));
	}

	ia_ptr = (DAPL_IA *)ia_handle;
	args.mrs_flags = op_type;

	for (i = 0, j = 0; i < num_segments; i++) {
		dat_status = dapls_hash_search(
		    ia_ptr->hca_ptr->lmr_hash_table,
		    lmr_triplet[i].lmr_context, (DAPL_HASH_DATA *)&lmr);

		if (dat_status != DAT_SUCCESS) {
			return (DAT_ERROR(DAT_INVALID_PARAMETER,
			    DAT_INVALID_ARG2));
		}

		dat_status = dapl_mr_bounds_check(
		    dapl_mr_get_address(lmr->param.region_desc,
		    lmr->param.mem_type),
		    lmr->param.length,
		    lmr_triplet[i].virtual_address,
		    lmr_triplet[i].segment_length);
		if (dat_status != DAT_TRUE) {
			return (DAT_ERROR(DAT_INVALID_PARAMETER,
			    DAT_INVALID_ARG2));
		}
		args.mrs_vec[j].mrsv_hkey = lmr->mr_handle->mr_hkey;
		args.mrs_vec[j].mrsv_va = lmr_triplet[i].virtual_address;
		args.mrs_vec[j].mrsv_len = lmr_triplet[i].segment_length;
		j = j + 1;
		args.mrs_numseg = j;
		if (j == DAPL_MR_PER_SYNC) {
			j = 0;
			retval = ioctl(ia_ptr->hca_ptr->ib_hca_handle->ia_fd,
			    DAPL_MR_SYNC, &args);

			if (retval != 0) {
				dapl_dbg_log(DAPL_DBG_TYPE_ERR,
				    "dapls_ib_lmr_sync: failed %s, retval %d\n",
				    strerror(errno), retval);
				return (dapls_convert_error(errno, retval));
			}
		}
	}

	if (j != 0) {
		retval = ioctl(ia_ptr->hca_ptr->ib_hca_handle->ia_fd,
		    DAPL_MR_SYNC, &args);
		if (retval != 0) {
			dapl_dbg_log(DAPL_DBG_TYPE_ERR,
			    "dapls_ib_lmr_sync: failed %s, retval %d\n",
			    strerror(errno), retval);
			return (dapls_convert_error(errno, retval));
		}
	}
	return (DAT_SUCCESS);
}