11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved. 31da177e4SLinus Torvalds * Copyright (c) 2004 Infinicon Corporation. All rights reserved. 41da177e4SLinus Torvalds * Copyright (c) 2004 Intel Corporation. All rights reserved. 51da177e4SLinus Torvalds * Copyright (c) 2004 Topspin Corporation. All rights reserved. 61da177e4SLinus Torvalds * Copyright (c) 2004 Voltaire Corporation. All rights reserved. 72a1d9b7fSRoland Dreier * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 8b5e81bf5SRoland Dreier * Copyright (c) 2005 Cisco Systems. All rights reserved. 91da177e4SLinus Torvalds * 101da177e4SLinus Torvalds * This software is available to you under a choice of one of two 111da177e4SLinus Torvalds * licenses. You may choose to be licensed under the terms of the GNU 121da177e4SLinus Torvalds * General Public License (GPL) Version 2, available from the file 131da177e4SLinus Torvalds * COPYING in the main directory of this source tree, or the 141da177e4SLinus Torvalds * OpenIB.org BSD license below: 151da177e4SLinus Torvalds * 161da177e4SLinus Torvalds * Redistribution and use in source and binary forms, with or 171da177e4SLinus Torvalds * without modification, are permitted provided that the following 181da177e4SLinus Torvalds * conditions are met: 191da177e4SLinus Torvalds * 201da177e4SLinus Torvalds * - Redistributions of source code must retain the above 211da177e4SLinus Torvalds * copyright notice, this list of conditions and the following 221da177e4SLinus Torvalds * disclaimer. 231da177e4SLinus Torvalds * 241da177e4SLinus Torvalds * - Redistributions in binary form must reproduce the above 251da177e4SLinus Torvalds * copyright notice, this list of conditions and the following 261da177e4SLinus Torvalds * disclaimer in the documentation and/or other materials 271da177e4SLinus Torvalds * provided with the distribution. 281da177e4SLinus Torvalds * 291da177e4SLinus Torvalds * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 301da177e4SLinus Torvalds * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 311da177e4SLinus Torvalds * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 321da177e4SLinus Torvalds * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 331da177e4SLinus Torvalds * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 341da177e4SLinus Torvalds * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 351da177e4SLinus Torvalds * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 361da177e4SLinus Torvalds * SOFTWARE. 371da177e4SLinus Torvalds * 381da177e4SLinus Torvalds * $Id: verbs.c 1349 2004-12-16 21:09:43Z roland $ 391da177e4SLinus Torvalds */ 401da177e4SLinus Torvalds 411da177e4SLinus Torvalds #include <linux/errno.h> 421da177e4SLinus Torvalds #include <linux/err.h> 431da177e4SLinus Torvalds 44a4d61e84SRoland Dreier #include <rdma/ib_verbs.h> 45a4d61e84SRoland Dreier #include <rdma/ib_cache.h> 461da177e4SLinus Torvalds 471da177e4SLinus Torvalds /* Protection domains */ 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds struct ib_pd *ib_alloc_pd(struct ib_device *device) 501da177e4SLinus Torvalds { 511da177e4SLinus Torvalds struct ib_pd *pd; 521da177e4SLinus Torvalds 53b5e81bf5SRoland Dreier pd = device->alloc_pd(device, NULL, NULL); 541da177e4SLinus Torvalds 551da177e4SLinus Torvalds if (!IS_ERR(pd)) { 561da177e4SLinus Torvalds pd->device = device; 57b5e81bf5SRoland Dreier pd->uobject = NULL; 581da177e4SLinus Torvalds atomic_set(&pd->usecnt, 0); 591da177e4SLinus Torvalds } 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds return pd; 621da177e4SLinus Torvalds } 631da177e4SLinus Torvalds EXPORT_SYMBOL(ib_alloc_pd); 641da177e4SLinus Torvalds 651da177e4SLinus Torvalds int ib_dealloc_pd(struct ib_pd *pd) 661da177e4SLinus Torvalds { 671da177e4SLinus Torvalds if (atomic_read(&pd->usecnt)) 681da177e4SLinus Torvalds return -EBUSY; 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds return pd->device->dealloc_pd(pd); 711da177e4SLinus Torvalds } 721da177e4SLinus Torvalds EXPORT_SYMBOL(ib_dealloc_pd); 731da177e4SLinus Torvalds 741da177e4SLinus Torvalds /* Address handles */ 751da177e4SLinus Torvalds 761da177e4SLinus Torvalds struct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr) 771da177e4SLinus Torvalds { 781da177e4SLinus Torvalds struct ib_ah *ah; 791da177e4SLinus Torvalds 801da177e4SLinus Torvalds ah = pd->device->create_ah(pd, ah_attr); 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds if (!IS_ERR(ah)) { 831da177e4SLinus Torvalds ah->device = pd->device; 841da177e4SLinus Torvalds ah->pd = pd; 85b5e81bf5SRoland Dreier ah->uobject = NULL; 861da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 871da177e4SLinus Torvalds } 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds return ah; 901da177e4SLinus Torvalds } 911da177e4SLinus Torvalds EXPORT_SYMBOL(ib_create_ah); 921da177e4SLinus Torvalds 93513789edSHal Rosenstock struct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc, 94513789edSHal Rosenstock struct ib_grh *grh, u8 port_num) 95513789edSHal Rosenstock { 96513789edSHal Rosenstock struct ib_ah_attr ah_attr; 97513789edSHal Rosenstock u32 flow_class; 98513789edSHal Rosenstock u16 gid_index; 99513789edSHal Rosenstock int ret; 100513789edSHal Rosenstock 101513789edSHal Rosenstock memset(&ah_attr, 0, sizeof ah_attr); 102513789edSHal Rosenstock ah_attr.dlid = wc->slid; 103513789edSHal Rosenstock ah_attr.sl = wc->sl; 104513789edSHal Rosenstock ah_attr.src_path_bits = wc->dlid_path_bits; 105513789edSHal Rosenstock ah_attr.port_num = port_num; 106513789edSHal Rosenstock 107513789edSHal Rosenstock if (wc->wc_flags & IB_WC_GRH) { 108513789edSHal Rosenstock ah_attr.ah_flags = IB_AH_GRH; 109513789edSHal Rosenstock ah_attr.grh.dgid = grh->dgid; 110513789edSHal Rosenstock 111513789edSHal Rosenstock ret = ib_find_cached_gid(pd->device, &grh->sgid, &port_num, 112513789edSHal Rosenstock &gid_index); 113513789edSHal Rosenstock if (ret) 114513789edSHal Rosenstock return ERR_PTR(ret); 115513789edSHal Rosenstock 116513789edSHal Rosenstock ah_attr.grh.sgid_index = (u8) gid_index; 117497677abSHal Rosenstock flow_class = be32_to_cpu(grh->version_tclass_flow); 118513789edSHal Rosenstock ah_attr.grh.flow_label = flow_class & 0xFFFFF; 119513789edSHal Rosenstock ah_attr.grh.traffic_class = (flow_class >> 20) & 0xFF; 120513789edSHal Rosenstock ah_attr.grh.hop_limit = grh->hop_limit; 121513789edSHal Rosenstock } 122513789edSHal Rosenstock 123513789edSHal Rosenstock return ib_create_ah(pd, &ah_attr); 124513789edSHal Rosenstock } 125513789edSHal Rosenstock EXPORT_SYMBOL(ib_create_ah_from_wc); 126513789edSHal Rosenstock 1271da177e4SLinus Torvalds int ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr) 1281da177e4SLinus Torvalds { 1291da177e4SLinus Torvalds return ah->device->modify_ah ? 1301da177e4SLinus Torvalds ah->device->modify_ah(ah, ah_attr) : 1311da177e4SLinus Torvalds -ENOSYS; 1321da177e4SLinus Torvalds } 1331da177e4SLinus Torvalds EXPORT_SYMBOL(ib_modify_ah); 1341da177e4SLinus Torvalds 1351da177e4SLinus Torvalds int ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr) 1361da177e4SLinus Torvalds { 1371da177e4SLinus Torvalds return ah->device->query_ah ? 1381da177e4SLinus Torvalds ah->device->query_ah(ah, ah_attr) : 1391da177e4SLinus Torvalds -ENOSYS; 1401da177e4SLinus Torvalds } 1411da177e4SLinus Torvalds EXPORT_SYMBOL(ib_query_ah); 1421da177e4SLinus Torvalds 1431da177e4SLinus Torvalds int ib_destroy_ah(struct ib_ah *ah) 1441da177e4SLinus Torvalds { 1451da177e4SLinus Torvalds struct ib_pd *pd; 1461da177e4SLinus Torvalds int ret; 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds pd = ah->pd; 1491da177e4SLinus Torvalds ret = ah->device->destroy_ah(ah); 1501da177e4SLinus Torvalds if (!ret) 1511da177e4SLinus Torvalds atomic_dec(&pd->usecnt); 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds return ret; 1541da177e4SLinus Torvalds } 1551da177e4SLinus Torvalds EXPORT_SYMBOL(ib_destroy_ah); 1561da177e4SLinus Torvalds 157d41fcc67SRoland Dreier /* Shared receive queues */ 158d41fcc67SRoland Dreier 159d41fcc67SRoland Dreier struct ib_srq *ib_create_srq(struct ib_pd *pd, 160d41fcc67SRoland Dreier struct ib_srq_init_attr *srq_init_attr) 161d41fcc67SRoland Dreier { 162d41fcc67SRoland Dreier struct ib_srq *srq; 163d41fcc67SRoland Dreier 164d41fcc67SRoland Dreier if (!pd->device->create_srq) 165d41fcc67SRoland Dreier return ERR_PTR(-ENOSYS); 166d41fcc67SRoland Dreier 167d41fcc67SRoland Dreier srq = pd->device->create_srq(pd, srq_init_attr, NULL); 168d41fcc67SRoland Dreier 169d41fcc67SRoland Dreier if (!IS_ERR(srq)) { 170d41fcc67SRoland Dreier srq->device = pd->device; 171d41fcc67SRoland Dreier srq->pd = pd; 172d41fcc67SRoland Dreier srq->uobject = NULL; 173d41fcc67SRoland Dreier srq->event_handler = srq_init_attr->event_handler; 174d41fcc67SRoland Dreier srq->srq_context = srq_init_attr->srq_context; 175d41fcc67SRoland Dreier atomic_inc(&pd->usecnt); 176d41fcc67SRoland Dreier atomic_set(&srq->usecnt, 0); 177d41fcc67SRoland Dreier } 178d41fcc67SRoland Dreier 179d41fcc67SRoland Dreier return srq; 180d41fcc67SRoland Dreier } 181d41fcc67SRoland Dreier EXPORT_SYMBOL(ib_create_srq); 182d41fcc67SRoland Dreier 183d41fcc67SRoland Dreier int ib_modify_srq(struct ib_srq *srq, 184d41fcc67SRoland Dreier struct ib_srq_attr *srq_attr, 185d41fcc67SRoland Dreier enum ib_srq_attr_mask srq_attr_mask) 186d41fcc67SRoland Dreier { 187d41fcc67SRoland Dreier return srq->device->modify_srq(srq, srq_attr, srq_attr_mask); 188d41fcc67SRoland Dreier } 189d41fcc67SRoland Dreier EXPORT_SYMBOL(ib_modify_srq); 190d41fcc67SRoland Dreier 191d41fcc67SRoland Dreier int ib_query_srq(struct ib_srq *srq, 192d41fcc67SRoland Dreier struct ib_srq_attr *srq_attr) 193d41fcc67SRoland Dreier { 194d41fcc67SRoland Dreier return srq->device->query_srq ? 195d41fcc67SRoland Dreier srq->device->query_srq(srq, srq_attr) : -ENOSYS; 196d41fcc67SRoland Dreier } 197d41fcc67SRoland Dreier EXPORT_SYMBOL(ib_query_srq); 198d41fcc67SRoland Dreier 199d41fcc67SRoland Dreier int ib_destroy_srq(struct ib_srq *srq) 200d41fcc67SRoland Dreier { 201d41fcc67SRoland Dreier struct ib_pd *pd; 202d41fcc67SRoland Dreier int ret; 203d41fcc67SRoland Dreier 204d41fcc67SRoland Dreier if (atomic_read(&srq->usecnt)) 205d41fcc67SRoland Dreier return -EBUSY; 206d41fcc67SRoland Dreier 207d41fcc67SRoland Dreier pd = srq->pd; 208d41fcc67SRoland Dreier 209d41fcc67SRoland Dreier ret = srq->device->destroy_srq(srq); 210d41fcc67SRoland Dreier if (!ret) 211d41fcc67SRoland Dreier atomic_dec(&pd->usecnt); 212d41fcc67SRoland Dreier 213d41fcc67SRoland Dreier return ret; 214d41fcc67SRoland Dreier } 215d41fcc67SRoland Dreier EXPORT_SYMBOL(ib_destroy_srq); 216d41fcc67SRoland Dreier 2171da177e4SLinus Torvalds /* Queue pairs */ 2181da177e4SLinus Torvalds 2191da177e4SLinus Torvalds struct ib_qp *ib_create_qp(struct ib_pd *pd, 2201da177e4SLinus Torvalds struct ib_qp_init_attr *qp_init_attr) 2211da177e4SLinus Torvalds { 2221da177e4SLinus Torvalds struct ib_qp *qp; 2231da177e4SLinus Torvalds 224b5e81bf5SRoland Dreier qp = pd->device->create_qp(pd, qp_init_attr, NULL); 2251da177e4SLinus Torvalds 2261da177e4SLinus Torvalds if (!IS_ERR(qp)) { 2271da177e4SLinus Torvalds qp->device = pd->device; 2281da177e4SLinus Torvalds qp->pd = pd; 2291da177e4SLinus Torvalds qp->send_cq = qp_init_attr->send_cq; 2301da177e4SLinus Torvalds qp->recv_cq = qp_init_attr->recv_cq; 2311da177e4SLinus Torvalds qp->srq = qp_init_attr->srq; 232b5e81bf5SRoland Dreier qp->uobject = NULL; 2331da177e4SLinus Torvalds qp->event_handler = qp_init_attr->event_handler; 2341da177e4SLinus Torvalds qp->qp_context = qp_init_attr->qp_context; 2351da177e4SLinus Torvalds qp->qp_type = qp_init_attr->qp_type; 2361da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 2371da177e4SLinus Torvalds atomic_inc(&qp_init_attr->send_cq->usecnt); 2381da177e4SLinus Torvalds atomic_inc(&qp_init_attr->recv_cq->usecnt); 2391da177e4SLinus Torvalds if (qp_init_attr->srq) 2401da177e4SLinus Torvalds atomic_inc(&qp_init_attr->srq->usecnt); 2411da177e4SLinus Torvalds } 2421da177e4SLinus Torvalds 2431da177e4SLinus Torvalds return qp; 2441da177e4SLinus Torvalds } 2451da177e4SLinus Torvalds EXPORT_SYMBOL(ib_create_qp); 2461da177e4SLinus Torvalds 2471da177e4SLinus Torvalds int ib_modify_qp(struct ib_qp *qp, 2481da177e4SLinus Torvalds struct ib_qp_attr *qp_attr, 2491da177e4SLinus Torvalds int qp_attr_mask) 2501da177e4SLinus Torvalds { 2511da177e4SLinus Torvalds return qp->device->modify_qp(qp, qp_attr, qp_attr_mask); 2521da177e4SLinus Torvalds } 2531da177e4SLinus Torvalds EXPORT_SYMBOL(ib_modify_qp); 2541da177e4SLinus Torvalds 2551da177e4SLinus Torvalds int ib_query_qp(struct ib_qp *qp, 2561da177e4SLinus Torvalds struct ib_qp_attr *qp_attr, 2571da177e4SLinus Torvalds int qp_attr_mask, 2581da177e4SLinus Torvalds struct ib_qp_init_attr *qp_init_attr) 2591da177e4SLinus Torvalds { 2601da177e4SLinus Torvalds return qp->device->query_qp ? 2611da177e4SLinus Torvalds qp->device->query_qp(qp, qp_attr, qp_attr_mask, qp_init_attr) : 2621da177e4SLinus Torvalds -ENOSYS; 2631da177e4SLinus Torvalds } 2641da177e4SLinus Torvalds EXPORT_SYMBOL(ib_query_qp); 2651da177e4SLinus Torvalds 2661da177e4SLinus Torvalds int ib_destroy_qp(struct ib_qp *qp) 2671da177e4SLinus Torvalds { 2681da177e4SLinus Torvalds struct ib_pd *pd; 2691da177e4SLinus Torvalds struct ib_cq *scq, *rcq; 2701da177e4SLinus Torvalds struct ib_srq *srq; 2711da177e4SLinus Torvalds int ret; 2721da177e4SLinus Torvalds 2731da177e4SLinus Torvalds pd = qp->pd; 2741da177e4SLinus Torvalds scq = qp->send_cq; 2751da177e4SLinus Torvalds rcq = qp->recv_cq; 2761da177e4SLinus Torvalds srq = qp->srq; 2771da177e4SLinus Torvalds 2781da177e4SLinus Torvalds ret = qp->device->destroy_qp(qp); 2791da177e4SLinus Torvalds if (!ret) { 2801da177e4SLinus Torvalds atomic_dec(&pd->usecnt); 2811da177e4SLinus Torvalds atomic_dec(&scq->usecnt); 2821da177e4SLinus Torvalds atomic_dec(&rcq->usecnt); 2831da177e4SLinus Torvalds if (srq) 2841da177e4SLinus Torvalds atomic_dec(&srq->usecnt); 2851da177e4SLinus Torvalds } 2861da177e4SLinus Torvalds 2871da177e4SLinus Torvalds return ret; 2881da177e4SLinus Torvalds } 2891da177e4SLinus Torvalds EXPORT_SYMBOL(ib_destroy_qp); 2901da177e4SLinus Torvalds 2911da177e4SLinus Torvalds /* Completion queues */ 2921da177e4SLinus Torvalds 2931da177e4SLinus Torvalds struct ib_cq *ib_create_cq(struct ib_device *device, 2941da177e4SLinus Torvalds ib_comp_handler comp_handler, 2951da177e4SLinus Torvalds void (*event_handler)(struct ib_event *, void *), 2961da177e4SLinus Torvalds void *cq_context, int cqe) 2971da177e4SLinus Torvalds { 2981da177e4SLinus Torvalds struct ib_cq *cq; 2991da177e4SLinus Torvalds 300b5e81bf5SRoland Dreier cq = device->create_cq(device, cqe, NULL, NULL); 3011da177e4SLinus Torvalds 3021da177e4SLinus Torvalds if (!IS_ERR(cq)) { 3031da177e4SLinus Torvalds cq->device = device; 304b5e81bf5SRoland Dreier cq->uobject = NULL; 3051da177e4SLinus Torvalds cq->comp_handler = comp_handler; 3061da177e4SLinus Torvalds cq->event_handler = event_handler; 3071da177e4SLinus Torvalds cq->cq_context = cq_context; 3081da177e4SLinus Torvalds atomic_set(&cq->usecnt, 0); 3091da177e4SLinus Torvalds } 3101da177e4SLinus Torvalds 3111da177e4SLinus Torvalds return cq; 3121da177e4SLinus Torvalds } 3131da177e4SLinus Torvalds EXPORT_SYMBOL(ib_create_cq); 3141da177e4SLinus Torvalds 3151da177e4SLinus Torvalds int ib_destroy_cq(struct ib_cq *cq) 3161da177e4SLinus Torvalds { 3171da177e4SLinus Torvalds if (atomic_read(&cq->usecnt)) 3181da177e4SLinus Torvalds return -EBUSY; 3191da177e4SLinus Torvalds 3201da177e4SLinus Torvalds return cq->device->destroy_cq(cq); 3211da177e4SLinus Torvalds } 3221da177e4SLinus Torvalds EXPORT_SYMBOL(ib_destroy_cq); 3231da177e4SLinus Torvalds 3241da177e4SLinus Torvalds int ib_resize_cq(struct ib_cq *cq, 3251da177e4SLinus Torvalds int cqe) 3261da177e4SLinus Torvalds { 32740de2e54SRoland Dreier return cq->device->resize_cq ? 32840de2e54SRoland Dreier cq->device->resize_cq(cq, cqe) : -ENOSYS; 3291da177e4SLinus Torvalds } 3301da177e4SLinus Torvalds EXPORT_SYMBOL(ib_resize_cq); 3311da177e4SLinus Torvalds 3321da177e4SLinus Torvalds /* Memory regions */ 3331da177e4SLinus Torvalds 3341da177e4SLinus Torvalds struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags) 3351da177e4SLinus Torvalds { 3361da177e4SLinus Torvalds struct ib_mr *mr; 3371da177e4SLinus Torvalds 3381da177e4SLinus Torvalds mr = pd->device->get_dma_mr(pd, mr_access_flags); 3391da177e4SLinus Torvalds 3401da177e4SLinus Torvalds if (!IS_ERR(mr)) { 3411da177e4SLinus Torvalds mr->device = pd->device; 3421da177e4SLinus Torvalds mr->pd = pd; 343b5e81bf5SRoland Dreier mr->uobject = NULL; 3441da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 3451da177e4SLinus Torvalds atomic_set(&mr->usecnt, 0); 3461da177e4SLinus Torvalds } 3471da177e4SLinus Torvalds 3481da177e4SLinus Torvalds return mr; 3491da177e4SLinus Torvalds } 3501da177e4SLinus Torvalds EXPORT_SYMBOL(ib_get_dma_mr); 3511da177e4SLinus Torvalds 3521da177e4SLinus Torvalds struct ib_mr *ib_reg_phys_mr(struct ib_pd *pd, 3531da177e4SLinus Torvalds struct ib_phys_buf *phys_buf_array, 3541da177e4SLinus Torvalds int num_phys_buf, 3551da177e4SLinus Torvalds int mr_access_flags, 3561da177e4SLinus Torvalds u64 *iova_start) 3571da177e4SLinus Torvalds { 3581da177e4SLinus Torvalds struct ib_mr *mr; 3591da177e4SLinus Torvalds 3601da177e4SLinus Torvalds mr = pd->device->reg_phys_mr(pd, phys_buf_array, num_phys_buf, 3611da177e4SLinus Torvalds mr_access_flags, iova_start); 3621da177e4SLinus Torvalds 3631da177e4SLinus Torvalds if (!IS_ERR(mr)) { 3641da177e4SLinus Torvalds mr->device = pd->device; 3651da177e4SLinus Torvalds mr->pd = pd; 366b5e81bf5SRoland Dreier mr->uobject = NULL; 3671da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 3681da177e4SLinus Torvalds atomic_set(&mr->usecnt, 0); 3691da177e4SLinus Torvalds } 3701da177e4SLinus Torvalds 3711da177e4SLinus Torvalds return mr; 3721da177e4SLinus Torvalds } 3731da177e4SLinus Torvalds EXPORT_SYMBOL(ib_reg_phys_mr); 3741da177e4SLinus Torvalds 3751da177e4SLinus Torvalds int ib_rereg_phys_mr(struct ib_mr *mr, 3761da177e4SLinus Torvalds int mr_rereg_mask, 3771da177e4SLinus Torvalds struct ib_pd *pd, 3781da177e4SLinus Torvalds struct ib_phys_buf *phys_buf_array, 3791da177e4SLinus Torvalds int num_phys_buf, 3801da177e4SLinus Torvalds int mr_access_flags, 3811da177e4SLinus Torvalds u64 *iova_start) 3821da177e4SLinus Torvalds { 3831da177e4SLinus Torvalds struct ib_pd *old_pd; 3841da177e4SLinus Torvalds int ret; 3851da177e4SLinus Torvalds 3861da177e4SLinus Torvalds if (!mr->device->rereg_phys_mr) 3871da177e4SLinus Torvalds return -ENOSYS; 3881da177e4SLinus Torvalds 3891da177e4SLinus Torvalds if (atomic_read(&mr->usecnt)) 3901da177e4SLinus Torvalds return -EBUSY; 3911da177e4SLinus Torvalds 3921da177e4SLinus Torvalds old_pd = mr->pd; 3931da177e4SLinus Torvalds 3941da177e4SLinus Torvalds ret = mr->device->rereg_phys_mr(mr, mr_rereg_mask, pd, 3951da177e4SLinus Torvalds phys_buf_array, num_phys_buf, 3961da177e4SLinus Torvalds mr_access_flags, iova_start); 3971da177e4SLinus Torvalds 3981da177e4SLinus Torvalds if (!ret && (mr_rereg_mask & IB_MR_REREG_PD)) { 3991da177e4SLinus Torvalds atomic_dec(&old_pd->usecnt); 4001da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 4011da177e4SLinus Torvalds } 4021da177e4SLinus Torvalds 4031da177e4SLinus Torvalds return ret; 4041da177e4SLinus Torvalds } 4051da177e4SLinus Torvalds EXPORT_SYMBOL(ib_rereg_phys_mr); 4061da177e4SLinus Torvalds 4071da177e4SLinus Torvalds int ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr) 4081da177e4SLinus Torvalds { 4091da177e4SLinus Torvalds return mr->device->query_mr ? 4101da177e4SLinus Torvalds mr->device->query_mr(mr, mr_attr) : -ENOSYS; 4111da177e4SLinus Torvalds } 4121da177e4SLinus Torvalds EXPORT_SYMBOL(ib_query_mr); 4131da177e4SLinus Torvalds 4141da177e4SLinus Torvalds int ib_dereg_mr(struct ib_mr *mr) 4151da177e4SLinus Torvalds { 4161da177e4SLinus Torvalds struct ib_pd *pd; 4171da177e4SLinus Torvalds int ret; 4181da177e4SLinus Torvalds 4191da177e4SLinus Torvalds if (atomic_read(&mr->usecnt)) 4201da177e4SLinus Torvalds return -EBUSY; 4211da177e4SLinus Torvalds 4221da177e4SLinus Torvalds pd = mr->pd; 4231da177e4SLinus Torvalds ret = mr->device->dereg_mr(mr); 4241da177e4SLinus Torvalds if (!ret) 4251da177e4SLinus Torvalds atomic_dec(&pd->usecnt); 4261da177e4SLinus Torvalds 4271da177e4SLinus Torvalds return ret; 4281da177e4SLinus Torvalds } 4291da177e4SLinus Torvalds EXPORT_SYMBOL(ib_dereg_mr); 4301da177e4SLinus Torvalds 4311da177e4SLinus Torvalds /* Memory windows */ 4321da177e4SLinus Torvalds 4331da177e4SLinus Torvalds struct ib_mw *ib_alloc_mw(struct ib_pd *pd) 4341da177e4SLinus Torvalds { 4351da177e4SLinus Torvalds struct ib_mw *mw; 4361da177e4SLinus Torvalds 4371da177e4SLinus Torvalds if (!pd->device->alloc_mw) 4381da177e4SLinus Torvalds return ERR_PTR(-ENOSYS); 4391da177e4SLinus Torvalds 4401da177e4SLinus Torvalds mw = pd->device->alloc_mw(pd); 4411da177e4SLinus Torvalds if (!IS_ERR(mw)) { 4421da177e4SLinus Torvalds mw->device = pd->device; 4431da177e4SLinus Torvalds mw->pd = pd; 444b5e81bf5SRoland Dreier mw->uobject = NULL; 4451da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 4461da177e4SLinus Torvalds } 4471da177e4SLinus Torvalds 4481da177e4SLinus Torvalds return mw; 4491da177e4SLinus Torvalds } 4501da177e4SLinus Torvalds EXPORT_SYMBOL(ib_alloc_mw); 4511da177e4SLinus Torvalds 4521da177e4SLinus Torvalds int ib_dealloc_mw(struct ib_mw *mw) 4531da177e4SLinus Torvalds { 4541da177e4SLinus Torvalds struct ib_pd *pd; 4551da177e4SLinus Torvalds int ret; 4561da177e4SLinus Torvalds 4571da177e4SLinus Torvalds pd = mw->pd; 4581da177e4SLinus Torvalds ret = mw->device->dealloc_mw(mw); 4591da177e4SLinus Torvalds if (!ret) 4601da177e4SLinus Torvalds atomic_dec(&pd->usecnt); 4611da177e4SLinus Torvalds 4621da177e4SLinus Torvalds return ret; 4631da177e4SLinus Torvalds } 4641da177e4SLinus Torvalds EXPORT_SYMBOL(ib_dealloc_mw); 4651da177e4SLinus Torvalds 4661da177e4SLinus Torvalds /* "Fast" memory regions */ 4671da177e4SLinus Torvalds 4681da177e4SLinus Torvalds struct ib_fmr *ib_alloc_fmr(struct ib_pd *pd, 4691da177e4SLinus Torvalds int mr_access_flags, 4701da177e4SLinus Torvalds struct ib_fmr_attr *fmr_attr) 4711da177e4SLinus Torvalds { 4721da177e4SLinus Torvalds struct ib_fmr *fmr; 4731da177e4SLinus Torvalds 4741da177e4SLinus Torvalds if (!pd->device->alloc_fmr) 4751da177e4SLinus Torvalds return ERR_PTR(-ENOSYS); 4761da177e4SLinus Torvalds 4771da177e4SLinus Torvalds fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr); 4781da177e4SLinus Torvalds if (!IS_ERR(fmr)) { 4791da177e4SLinus Torvalds fmr->device = pd->device; 4801da177e4SLinus Torvalds fmr->pd = pd; 4811da177e4SLinus Torvalds atomic_inc(&pd->usecnt); 4821da177e4SLinus Torvalds } 4831da177e4SLinus Torvalds 4841da177e4SLinus Torvalds return fmr; 4851da177e4SLinus Torvalds } 4861da177e4SLinus Torvalds EXPORT_SYMBOL(ib_alloc_fmr); 4871da177e4SLinus Torvalds 4881da177e4SLinus Torvalds int ib_unmap_fmr(struct list_head *fmr_list) 4891da177e4SLinus Torvalds { 4901da177e4SLinus Torvalds struct ib_fmr *fmr; 4911da177e4SLinus Torvalds 4921da177e4SLinus Torvalds if (list_empty(fmr_list)) 4931da177e4SLinus Torvalds return 0; 4941da177e4SLinus Torvalds 4951da177e4SLinus Torvalds fmr = list_entry(fmr_list->next, struct ib_fmr, list); 4961da177e4SLinus Torvalds return fmr->device->unmap_fmr(fmr_list); 4971da177e4SLinus Torvalds } 4981da177e4SLinus Torvalds EXPORT_SYMBOL(ib_unmap_fmr); 4991da177e4SLinus Torvalds 5001da177e4SLinus Torvalds int ib_dealloc_fmr(struct ib_fmr *fmr) 5011da177e4SLinus Torvalds { 5021da177e4SLinus Torvalds struct ib_pd *pd; 5031da177e4SLinus Torvalds int ret; 5041da177e4SLinus Torvalds 5051da177e4SLinus Torvalds pd = fmr->pd; 5061da177e4SLinus Torvalds ret = fmr->device->dealloc_fmr(fmr); 5071da177e4SLinus Torvalds if (!ret) 5081da177e4SLinus Torvalds atomic_dec(&pd->usecnt); 5091da177e4SLinus Torvalds 5101da177e4SLinus Torvalds return ret; 5111da177e4SLinus Torvalds } 5121da177e4SLinus Torvalds EXPORT_SYMBOL(ib_dealloc_fmr); 5131da177e4SLinus Torvalds 5141da177e4SLinus Torvalds /* Multicast groups */ 5151da177e4SLinus Torvalds 5161da177e4SLinus Torvalds int ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) 5171da177e4SLinus Torvalds { 5180c33aeedSJack Morgenstein if (!qp->device->attach_mcast) 5190c33aeedSJack Morgenstein return -ENOSYS; 5200c33aeedSJack Morgenstein if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) 5210c33aeedSJack Morgenstein return -EINVAL; 5220c33aeedSJack Morgenstein 5230c33aeedSJack Morgenstein return qp->device->attach_mcast(qp, gid, lid); 5241da177e4SLinus Torvalds } 5251da177e4SLinus Torvalds EXPORT_SYMBOL(ib_attach_mcast); 5261da177e4SLinus Torvalds 5271da177e4SLinus Torvalds int ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid) 5281da177e4SLinus Torvalds { 5290c33aeedSJack Morgenstein if (!qp->device->detach_mcast) 5300c33aeedSJack Morgenstein return -ENOSYS; 5310c33aeedSJack Morgenstein if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD) 5320c33aeedSJack Morgenstein return -EINVAL; 5330c33aeedSJack Morgenstein 5340c33aeedSJack Morgenstein return qp->device->detach_mcast(qp, gid, lid); 5351da177e4SLinus Torvalds } 5361da177e4SLinus Torvalds EXPORT_SYMBOL(ib_detach_mcast); 537