19e39c5baSBill Taylor /*
29e39c5baSBill Taylor  * CDDL HEADER START
39e39c5baSBill Taylor  *
49e39c5baSBill Taylor  * The contents of this file are subject to the terms of the
59e39c5baSBill Taylor  * Common Development and Distribution License (the "License").
69e39c5baSBill Taylor  * You may not use this file except in compliance with the License.
79e39c5baSBill Taylor  *
89e39c5baSBill Taylor  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e39c5baSBill Taylor  * or http://www.opensolaris.org/os/licensing.
109e39c5baSBill Taylor  * See the License for the specific language governing permissions
119e39c5baSBill Taylor  * and limitations under the License.
129e39c5baSBill Taylor  *
139e39c5baSBill Taylor  * When distributing Covered Code, include this CDDL HEADER in each
149e39c5baSBill Taylor  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e39c5baSBill Taylor  * If applicable, add the following below this CDDL HEADER, with the
169e39c5baSBill Taylor  * fields enclosed by brackets "[]" replaced with your own identifying
179e39c5baSBill Taylor  * information: Portions Copyright [yyyy] [name of copyright owner]
189e39c5baSBill Taylor  *
199e39c5baSBill Taylor  * CDDL HEADER END
209e39c5baSBill Taylor  */
219e39c5baSBill Taylor 
229e39c5baSBill Taylor /*
239e39c5baSBill Taylor  * Copyright (c) 2002-2003, Network Appliance, Inc. All rights reserved.
249e39c5baSBill Taylor  */
259e39c5baSBill Taylor 
269e39c5baSBill Taylor /*
279e39c5baSBill Taylor  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
289e39c5baSBill Taylor  * Use is subject to license terms.
299e39c5baSBill Taylor  */
309e39c5baSBill Taylor 
319e39c5baSBill Taylor /*
329e39c5baSBill Taylor  *
339e39c5baSBill Taylor  * MODULE: dapl_rmr_bind.c
349e39c5baSBill Taylor  *
359e39c5baSBill Taylor  * PURPOSE: Memory management
369e39c5baSBill Taylor  * Description: Interfaces in this file are completely described in
379e39c5baSBill Taylor  *		the DAPL 1.1 API, Chapter 6, section 6
389e39c5baSBill Taylor  *
399e39c5baSBill Taylor  * $Id: dapl_rmr_bind.c,v 1.14 2003/07/11 18:23:31 jlentini Exp $
409e39c5baSBill Taylor  */
419e39c5baSBill Taylor 
429e39c5baSBill Taylor #include "dapl.h"
439e39c5baSBill Taylor #include "dapl_rmr_util.h"
449e39c5baSBill Taylor #include "dapl_ep_util.h"
459e39c5baSBill Taylor #include "dapl_cookie.h"
469e39c5baSBill Taylor #include "dapl_adapter_util.h"
479e39c5baSBill Taylor 
489e39c5baSBill Taylor /*
499e39c5baSBill Taylor  *
509e39c5baSBill Taylor  * Function Prototypes
519e39c5baSBill Taylor  *
529e39c5baSBill Taylor  */
539e39c5baSBill Taylor 
549e39c5baSBill Taylor static DAT_RETURN
559e39c5baSBill Taylor dapli_rmr_bind_fuse(
569e39c5baSBill Taylor     IN  DAPL_RMR		*rmr,
579e39c5baSBill Taylor     IN  const DAT_LMR_TRIPLET 	*lmr_triplet,
589e39c5baSBill Taylor     IN  DAT_MEM_PRIV_FLAGS 	mem_priv,
599e39c5baSBill Taylor     IN  DAPL_EP 		*ep,
609e39c5baSBill Taylor     IN  DAT_RMR_COOKIE 		user_cookie,
619e39c5baSBill Taylor     IN  DAT_COMPLETION_FLAGS	completion_flags,
629e39c5baSBill Taylor     OUT DAT_RMR_CONTEXT 	*rmr_context);
639e39c5baSBill Taylor 
649e39c5baSBill Taylor static DAT_RETURN
659e39c5baSBill Taylor dapli_rmr_bind_unfuse(
669e39c5baSBill Taylor     IN  DAPL_RMR		*rmr,
679e39c5baSBill Taylor     IN  const DAT_LMR_TRIPLET 	*lmr_triplet,
689e39c5baSBill Taylor     IN  DAPL_EP 		*ep,
699e39c5baSBill Taylor     IN  DAT_RMR_COOKIE 		user_cookie,
709e39c5baSBill Taylor     IN  DAT_COMPLETION_FLAGS 	completion_flags);
719e39c5baSBill Taylor 
729e39c5baSBill Taylor 
739e39c5baSBill Taylor /*
749e39c5baSBill Taylor  *
759e39c5baSBill Taylor  * Function Definitions
769e39c5baSBill Taylor  *
779e39c5baSBill Taylor  */
789e39c5baSBill Taylor 
799e39c5baSBill Taylor static DAT_RETURN
dapli_rmr_bind_fuse(IN DAPL_RMR * rmr,IN const DAT_LMR_TRIPLET * lmr_triplet,IN DAT_MEM_PRIV_FLAGS mem_priv,IN DAPL_EP * ep_ptr,IN DAT_RMR_COOKIE user_cookie,IN DAT_COMPLETION_FLAGS completion_flags,OUT DAT_RMR_CONTEXT * rmr_context)809e39c5baSBill Taylor dapli_rmr_bind_fuse(
819e39c5baSBill Taylor     IN  DAPL_RMR		*rmr,
829e39c5baSBill Taylor     IN  const DAT_LMR_TRIPLET* 	lmr_triplet,
839e39c5baSBill Taylor     IN  DAT_MEM_PRIV_FLAGS 	mem_priv,
849e39c5baSBill Taylor     IN  DAPL_EP 		*ep_ptr,
859e39c5baSBill Taylor     IN  DAT_RMR_COOKIE 		user_cookie,
869e39c5baSBill Taylor     IN  DAT_COMPLETION_FLAGS	completion_flags,
879e39c5baSBill Taylor     OUT DAT_RMR_CONTEXT 	*rmr_context)
889e39c5baSBill Taylor {
899e39c5baSBill Taylor 	DAPL_LMR 			*lmr;
909e39c5baSBill Taylor 	DAPL_COOKIE			*cookie;
919e39c5baSBill Taylor 	DAT_RETURN 			dat_status;
929e39c5baSBill Taylor 
939e39c5baSBill Taylor 	dat_status = dapls_hash_search(
949e39c5baSBill Taylor 	    rmr->header.owner_ia->hca_ptr->lmr_hash_table,
959e39c5baSBill Taylor 	    lmr_triplet->lmr_context,
969e39c5baSBill Taylor 	    (DAPL_HASH_DATA *) &lmr);
979e39c5baSBill Taylor 	if (DAT_SUCCESS != dat_status) {
989e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
999e39c5baSBill Taylor 		goto bail;
1009e39c5baSBill Taylor 	}
1019e39c5baSBill Taylor 
1029e39c5baSBill Taylor 	/*
1039e39c5baSBill Taylor 	 * if the ep in unconnected return an error. IB requires that the
1049e39c5baSBill Taylor 	 * QP be connected to change a memory window binding since:
1059e39c5baSBill Taylor 	 *
1069e39c5baSBill Taylor 	 * - memory window bind operations are WQEs placed on a QP's
1079e39c5baSBill Taylor 	 *   send queue
1089e39c5baSBill Taylor 	 *
1099e39c5baSBill Taylor 	 * - QP's only process WQEs on the send queue when the QP is in
1109e39c5baSBill Taylor 	 *   the RTS state
1119e39c5baSBill Taylor 	 */
1129e39c5baSBill Taylor 	if (DAT_EP_STATE_CONNECTED != ep_ptr->param.ep_state) {
1139e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_STATE,
1149e39c5baSBill Taylor 		    dapls_ep_state_subtype(ep_ptr));
1159e39c5baSBill Taylor 		goto bail;
1169e39c5baSBill Taylor 	}
1179e39c5baSBill Taylor 
1189e39c5baSBill Taylor 	if (DAT_FALSE == dapl_mr_bounds_check(
1199e39c5baSBill Taylor 	    dapl_mr_get_address(lmr->param.region_desc, lmr->param.mem_type),
1209e39c5baSBill Taylor 	    lmr->param.length,
1219e39c5baSBill Taylor 	    lmr_triplet->virtual_address,
1229e39c5baSBill Taylor 	    lmr_triplet->segment_length)) {
1239e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER,
1249e39c5baSBill Taylor 		    DAT_INVALID_ARG2);
1259e39c5baSBill Taylor 		goto bail;
1269e39c5baSBill Taylor 	}
1279e39c5baSBill Taylor 
1289e39c5baSBill Taylor 	/* If the LMR, RMR, and EP are not in the same PZ, there is an error */
1299e39c5baSBill Taylor 	if ((ep_ptr->param.pz_handle != lmr->param.pz_handle) ||
1309e39c5baSBill Taylor 	    (ep_ptr->param.pz_handle != rmr->param.pz_handle)) {
1319e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
1329e39c5baSBill Taylor 		goto bail;
1339e39c5baSBill Taylor 	}
1349e39c5baSBill Taylor 
1359e39c5baSBill Taylor 	if (!dapl_rmr_validate_completion_flag(DAT_COMPLETION_SUPPRESS_FLAG,
1369e39c5baSBill Taylor 	    ep_ptr->param.ep_attr.request_completion_flags, completion_flags) ||
1379e39c5baSBill Taylor 	    !dapl_rmr_validate_completion_flag(DAT_COMPLETION_UNSIGNALLED_FLAG,
1389e39c5baSBill Taylor 	    ep_ptr->param.ep_attr.request_completion_flags, completion_flags) ||
1399e39c5baSBill Taylor 	    !dapl_rmr_validate_completion_flag(
1409e39c5baSBill Taylor 	    DAT_COMPLETION_BARRIER_FENCE_FLAG,
1419e39c5baSBill Taylor 	    ep_ptr->param.ep_attr.request_completion_flags, completion_flags)) {
1429e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG4);
1439e39c5baSBill Taylor 		goto bail;
1449e39c5baSBill Taylor 	}
1459e39c5baSBill Taylor 
1469e39c5baSBill Taylor 	dat_status = dapls_rmr_cookie_alloc(&ep_ptr->req_buffer,
1479e39c5baSBill Taylor 	    rmr, user_cookie, &cookie);
1489e39c5baSBill Taylor 	if (DAT_SUCCESS != dat_status) {
1499e39c5baSBill Taylor 		goto bail;
1509e39c5baSBill Taylor 	}
1519e39c5baSBill Taylor 
1529e39c5baSBill Taylor 	dat_status = dapls_ib_mw_bind(rmr,
1539e39c5baSBill Taylor 	    lmr_triplet->lmr_context,
1549e39c5baSBill Taylor 	    ep_ptr,
1559e39c5baSBill Taylor 	    cookie,
1569e39c5baSBill Taylor 	    lmr_triplet->virtual_address,
1579e39c5baSBill Taylor 	    lmr_triplet->segment_length,
1589e39c5baSBill Taylor 	    mem_priv,
1599e39c5baSBill Taylor 	    completion_flags);
1609e39c5baSBill Taylor 	if (DAT_SUCCESS != dat_status) {
1619e39c5baSBill Taylor 		dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
1629e39c5baSBill Taylor 		goto bail;
1639e39c5baSBill Taylor 	}
1649e39c5baSBill Taylor 
165*fb4cdc19SToomas Soome 	dapl_os_atomic_inc(&lmr->lmr_ref_count);
1669e39c5baSBill Taylor 
1679e39c5baSBill Taylor 	/* if the RMR was previously bound */
1689e39c5baSBill Taylor 	if (NULL != rmr->lmr) {
169*fb4cdc19SToomas Soome 		dapl_os_atomic_dec(&rmr->lmr->lmr_ref_count);
1709e39c5baSBill Taylor 	}
1719e39c5baSBill Taylor 
1729e39c5baSBill Taylor 	rmr->param.mem_priv = mem_priv;
1739e39c5baSBill Taylor 	rmr->param.lmr_triplet = *lmr_triplet;
1749e39c5baSBill Taylor 	rmr->ep = ep_ptr;
1759e39c5baSBill Taylor 	rmr->lmr = lmr;
1769e39c5baSBill Taylor 
1779e39c5baSBill Taylor 	dapl_os_atomic_inc(&ep_ptr->req_count);
1789e39c5baSBill Taylor 
1799e39c5baSBill Taylor 	if (NULL != rmr_context) { *rmr_context = rmr->param.rmr_context; }
1809e39c5baSBill Taylor bail:
1819e39c5baSBill Taylor 	return (dat_status);
1829e39c5baSBill Taylor }
1839e39c5baSBill Taylor 
1849e39c5baSBill Taylor 
1859e39c5baSBill Taylor static DAT_RETURN
dapli_rmr_bind_unfuse(IN DAPL_RMR * rmr,IN const DAT_LMR_TRIPLET * lmr_triplet,IN DAPL_EP * ep_ptr,IN DAT_RMR_COOKIE user_cookie,IN DAT_COMPLETION_FLAGS completion_flags)1869e39c5baSBill Taylor dapli_rmr_bind_unfuse(
1879e39c5baSBill Taylor     IN  DAPL_RMR		*rmr,
1889e39c5baSBill Taylor     IN  const DAT_LMR_TRIPLET 	*lmr_triplet,
1899e39c5baSBill Taylor     IN  DAPL_EP 		*ep_ptr,
1909e39c5baSBill Taylor     IN  DAT_RMR_COOKIE 		user_cookie,
1919e39c5baSBill Taylor     IN  DAT_COMPLETION_FLAGS 	completion_flags)
1929e39c5baSBill Taylor {
1939e39c5baSBill Taylor 	DAPL_COOKIE			*cookie;
1949e39c5baSBill Taylor 	DAT_RETURN 			dat_status;
1959e39c5baSBill Taylor 
1969e39c5baSBill Taylor 	dat_status = DAT_SUCCESS;
1979e39c5baSBill Taylor 	/*
1989e39c5baSBill Taylor 	 * if the ep in unconnected return an error. IB requires that the
1999e39c5baSBill Taylor 	 * QP be connected to change a memory window binding since:
2009e39c5baSBill Taylor 	 *
2019e39c5baSBill Taylor 	 * - memory window bind operations are WQEs placed on a QP's
2029e39c5baSBill Taylor 	 *   send queue
2039e39c5baSBill Taylor 	 *
2049e39c5baSBill Taylor 	 * - QP's only process WQEs on the send queue when the QP is in
2059e39c5baSBill Taylor 	 *   the RTS state
2069e39c5baSBill Taylor 	 */
2079e39c5baSBill Taylor 	if (DAT_EP_STATE_CONNECTED != ep_ptr->param.ep_state) {
2089e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_STATE,
2099e39c5baSBill Taylor 		    dapls_ep_state_subtype(ep_ptr));
2109e39c5baSBill Taylor 		goto bail1;
2119e39c5baSBill Taylor 	}
2129e39c5baSBill Taylor 
2139e39c5baSBill Taylor 	/* If the RMR and EP are not in the same PZ, there is an error */
2149e39c5baSBill Taylor 	if (ep_ptr->param.pz_handle != rmr->param.pz_handle) {
2159e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
2169e39c5baSBill Taylor 		goto bail1;
2179e39c5baSBill Taylor 	}
2189e39c5baSBill Taylor 
2199e39c5baSBill Taylor 	if (!dapl_rmr_validate_completion_flag(DAT_COMPLETION_SUPPRESS_FLAG,
2209e39c5baSBill Taylor 	    ep_ptr->param.ep_attr.request_completion_flags, completion_flags) ||
2219e39c5baSBill Taylor 	    !dapl_rmr_validate_completion_flag(DAT_COMPLETION_UNSIGNALLED_FLAG,
2229e39c5baSBill Taylor 	    ep_ptr->param.ep_attr.request_completion_flags, completion_flags) ||
2239e39c5baSBill Taylor 	    !dapl_rmr_validate_completion_flag(
2249e39c5baSBill Taylor 	    DAT_COMPLETION_BARRIER_FENCE_FLAG,
2259e39c5baSBill Taylor 	    ep_ptr->param.ep_attr.request_completion_flags, completion_flags)) {
2269e39c5baSBill Taylor 		dat_status = DAT_ERROR(DAT_INVALID_PARAMETER, DAT_INVALID_ARG2);
2279e39c5baSBill Taylor 		goto bail1;
2289e39c5baSBill Taylor 	}
2299e39c5baSBill Taylor 
2309e39c5baSBill Taylor 	dat_status = dapls_rmr_cookie_alloc(&ep_ptr->req_buffer, rmr,
2319e39c5baSBill Taylor 	    user_cookie, &cookie);
2329e39c5baSBill Taylor 	if (DAT_SUCCESS != dat_status) {
2339e39c5baSBill Taylor 		goto bail1;
2349e39c5baSBill Taylor 	}
2359e39c5baSBill Taylor 
2369e39c5baSBill Taylor 
2379e39c5baSBill Taylor 	dat_status = dapls_ib_mw_unbind(rmr, lmr_triplet->lmr_context,
2389e39c5baSBill Taylor 	    ep_ptr, cookie, completion_flags);
2399e39c5baSBill Taylor 
2409e39c5baSBill Taylor 	if (DAT_SUCCESS != dat_status) {
2419e39c5baSBill Taylor 		dapls_cookie_dealloc(&ep_ptr->req_buffer, cookie);
2429e39c5baSBill Taylor 		goto bail1;
2439e39c5baSBill Taylor 	}
2449e39c5baSBill Taylor 
2459e39c5baSBill Taylor 	/* if the RMR was previously bound */
2469e39c5baSBill Taylor 	if (NULL != rmr->lmr) {
247*fb4cdc19SToomas Soome 		dapl_os_atomic_dec(&rmr->lmr->lmr_ref_count);
2489e39c5baSBill Taylor 	}
2499e39c5baSBill Taylor 
2509e39c5baSBill Taylor 	rmr->param.mem_priv = DAT_MEM_PRIV_NONE_FLAG;
2519e39c5baSBill Taylor 	rmr->param.lmr_triplet.lmr_context = 0;
2529e39c5baSBill Taylor 	rmr->param.lmr_triplet.virtual_address = 0;
2539e39c5baSBill Taylor 	rmr->param.lmr_triplet.segment_length = 0;
2549e39c5baSBill Taylor 	rmr->ep = ep_ptr;
2559e39c5baSBill Taylor 	rmr->lmr = NULL;
2569e39c5baSBill Taylor 
2579e39c5baSBill Taylor 	dapl_os_atomic_inc(&ep_ptr->req_count);
2589e39c5baSBill Taylor 
2599e39c5baSBill Taylor bail1:
2609e39c5baSBill Taylor 	return (dat_status);
2619e39c5baSBill Taylor }
2629e39c5baSBill Taylor 
2639e39c5baSBill Taylor 
2649e39c5baSBill Taylor /*
2659e39c5baSBill Taylor  * dapl_rmr_bind
2669e39c5baSBill Taylor  *
2679e39c5baSBill Taylor  * DAPL Requirements Version xxx, 6.6.4.4
2689e39c5baSBill Taylor  *
2699e39c5baSBill Taylor  * Bind the RMR to the specified memory region within the LMR and
2709e39c5baSBill Taylor  * provide a new rmr_context value.
2719e39c5baSBill Taylor  *
2729e39c5baSBill Taylor  * Input:
2739e39c5baSBill Taylor  * Output:
2749e39c5baSBill Taylor  */
2759e39c5baSBill Taylor DAT_RETURN
dapl_rmr_bind(IN DAT_RMR_HANDLE rmr_handle,IN const DAT_LMR_TRIPLET * lmr_triplet,IN DAT_MEM_PRIV_FLAGS mem_priv,IN DAT_EP_HANDLE ep_handle,IN DAT_RMR_COOKIE user_cookie,IN DAT_COMPLETION_FLAGS completion_flags,OUT DAT_RMR_CONTEXT * rmr_context)2769e39c5baSBill Taylor dapl_rmr_bind(
2779e39c5baSBill Taylor 	IN	DAT_RMR_HANDLE		rmr_handle,
2789e39c5baSBill Taylor 	IN	const DAT_LMR_TRIPLET	*lmr_triplet,
2799e39c5baSBill Taylor 	IN	DAT_MEM_PRIV_FLAGS	mem_priv,
2809e39c5baSBill Taylor 	IN	DAT_EP_HANDLE		ep_handle,
2819e39c5baSBill Taylor 	IN	DAT_RMR_COOKIE		user_cookie,
2829e39c5baSBill Taylor 	IN	DAT_COMPLETION_FLAGS 	completion_flags,
2839e39c5baSBill Taylor 	OUT	DAT_RMR_CONTEXT		*rmr_context)
2849e39c5baSBill Taylor {
2859e39c5baSBill Taylor 	DAPL_RMR				*rmr;
2869e39c5baSBill Taylor 	DAPL_EP 				*ep_ptr;
2879e39c5baSBill Taylor 
2889e39c5baSBill Taylor 	if (DAPL_BAD_HANDLE(rmr_handle, DAPL_MAGIC_RMR)) {
2899e39c5baSBill Taylor 		return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_RMR));
2909e39c5baSBill Taylor 	}
2919e39c5baSBill Taylor 	if (DAPL_BAD_HANDLE(ep_handle, DAPL_MAGIC_EP)) {
2929e39c5baSBill Taylor 		return (DAT_ERROR(DAT_INVALID_HANDLE, DAT_INVALID_HANDLE_EP));
2939e39c5baSBill Taylor 	}
2949e39c5baSBill Taylor 
2959e39c5baSBill Taylor 	rmr = (DAPL_RMR *) rmr_handle;
2969e39c5baSBill Taylor 	ep_ptr = (DAPL_EP *) ep_handle;
2979e39c5baSBill Taylor 
2989e39c5baSBill Taylor 	/* if the rmr should be bound */
2999e39c5baSBill Taylor 	if (0 != lmr_triplet->segment_length) {
3009e39c5baSBill Taylor 		return (dapli_rmr_bind_fuse(rmr,
3019e39c5baSBill Taylor 		    lmr_triplet,
3029e39c5baSBill Taylor 		    mem_priv,
3039e39c5baSBill Taylor 		    ep_ptr,
3049e39c5baSBill Taylor 		    user_cookie,
3059e39c5baSBill Taylor 		    completion_flags,
3069e39c5baSBill Taylor 		    rmr_context));
3079e39c5baSBill Taylor 	} else { /* the rmr should be unbound */
3089e39c5baSBill Taylor 		return (dapli_rmr_bind_unfuse(rmr,
3099e39c5baSBill Taylor 		    lmr_triplet,
3109e39c5baSBill Taylor 		    ep_ptr,
3119e39c5baSBill Taylor 		    user_cookie,
3129e39c5baSBill Taylor 		    completion_flags));
3139e39c5baSBill Taylor 	}
3149e39c5baSBill Taylor }
315