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