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