verbs.c revision d41fcc6705eddd04f7218c985b6da35435ed73cc
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>
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <ib_verbs.h>
45513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock#include <ib_cache.h>
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Protection domains */
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_pd *ib_alloc_pd(struct ib_device *device)
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
53b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier	pd = device->alloc_pd(device, NULL, NULL);
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(pd)) {
56b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		pd->device  = device;
57b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		pd->uobject = NULL;
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&pd->usecnt, 0);
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pd;
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_pd);
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_pd(struct ib_pd *pd)
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&pd->usecnt))
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pd->device->dealloc_pd(pd);
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_pd);
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Address handles */
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_ah *ah;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ah = pd->device->create_ah(pd, ah_attr);
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(ah)) {
83b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->device  = pd->device;
84b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->pd      = pd;
85b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->uobject = NULL;
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah;
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_ah);
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
93513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstockstruct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc,
94513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock				   struct ib_grh *grh, u8 port_num)
95513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock{
96513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	struct ib_ah_attr ah_attr;
97513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	u32 flow_class;
98513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	u16 gid_index;
99513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	int ret;
100513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
101513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	memset(&ah_attr, 0, sizeof ah_attr);
102513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	ah_attr.dlid = wc->slid;
103513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	ah_attr.sl = wc->sl;
104513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	ah_attr.src_path_bits = wc->dlid_path_bits;
105513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	ah_attr.port_num = port_num;
106513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
107513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	if (wc->wc_flags & IB_WC_GRH) {
108513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		ah_attr.ah_flags = IB_AH_GRH;
109513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		ah_attr.grh.dgid = grh->dgid;
110513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
111513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		ret = ib_find_cached_gid(pd->device, &grh->sgid, &port_num,
112513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock					 &gid_index);
113513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		if (ret)
114513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock			return ERR_PTR(ret);
115513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
116513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		ah_attr.grh.sgid_index = (u8) gid_index;
117497677ab940e637a41351dca6610bc4320abc8f1Hal Rosenstock		flow_class = be32_to_cpu(grh->version_tclass_flow);
118513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		ah_attr.grh.flow_label = flow_class & 0xFFFFF;
119513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		ah_attr.grh.traffic_class = (flow_class >> 20) & 0xFF;
120513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		ah_attr.grh.hop_limit = grh->hop_limit;
121513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	}
122513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
123513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	return ib_create_ah(pd, &ah_attr);
124513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock}
125513789ed995fb2ba72ba2a5bee53ea11d1170580Hal RosenstockEXPORT_SYMBOL(ib_create_ah_from_wc);
126513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah->device->modify_ah ?
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ah->device->modify_ah(ah, ah_attr) :
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_modify_ah);
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah->device->query_ah ?
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ah->device->query_ah(ah, ah_attr) :
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_ah);
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_ah(struct ib_ah *ah)
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = ah->pd;
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = ah->device->destroy_ah(ah);
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_ah);
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
157d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier/* Shared receive queues */
158d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
159d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierstruct ib_srq *ib_create_srq(struct ib_pd *pd,
160d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier			     struct ib_srq_init_attr *srq_init_attr)
161d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
162d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	struct ib_srq *srq;
163d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
164d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (!pd->device->create_srq)
165d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		return ERR_PTR(-ENOSYS);
166d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
167d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	srq = pd->device->create_srq(pd, srq_init_attr, NULL);
168d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
169d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (!IS_ERR(srq)) {
170d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->device    	   = pd->device;
171d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->pd        	   = pd;
172d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->uobject       = NULL;
173d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->event_handler = srq_init_attr->event_handler;
174d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->srq_context   = srq_init_attr->srq_context;
175d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_inc(&pd->usecnt);
176d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_set(&srq->usecnt, 0);
177d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	}
178d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
179d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return srq;
180d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
181d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_create_srq);
182d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
183d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_modify_srq(struct ib_srq *srq,
184d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		  struct ib_srq_attr *srq_attr,
185d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		  enum ib_srq_attr_mask srq_attr_mask)
186d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
187d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return srq->device->modify_srq(srq, srq_attr, srq_attr_mask);
188d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
189d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_modify_srq);
190d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
191d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_query_srq(struct ib_srq *srq,
192d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		 struct ib_srq_attr *srq_attr)
193d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
194d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return srq->device->query_srq ?
195d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->device->query_srq(srq, srq_attr) : -ENOSYS;
196d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
197d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_query_srq);
198d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
199d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_destroy_srq(struct ib_srq *srq)
200d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
201d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	struct ib_pd *pd;
202d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	int ret;
203d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
204d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (atomic_read(&srq->usecnt))
205d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		return -EBUSY;
206d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
207d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	pd = srq->pd;
208d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
209d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	ret = srq->device->destroy_srq(srq);
210d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (!ret)
211d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_dec(&pd->usecnt);
212d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
213d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return ret;
214d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
215d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_destroy_srq);
216d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Queue pairs */
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_qp *ib_create_qp(struct ib_pd *pd,
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct ib_qp_init_attr *qp_init_attr)
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_qp *qp;
2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
224b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier	qp = pd->device->create_qp(pd, qp_init_attr, NULL);
2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(qp)) {
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->device     	  = pd->device;
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->pd         	  = pd;
2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->send_cq    	  = qp_init_attr->send_cq;
2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->recv_cq    	  = qp_init_attr->recv_cq;
2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->srq	       	  = qp_init_attr->srq;
232b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		qp->uobject       = NULL;
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->event_handler = qp_init_attr->event_handler;
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->qp_context    = qp_init_attr->qp_context;
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->qp_type	  = qp_init_attr->qp_type;
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&qp_init_attr->send_cq->usecnt);
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&qp_init_attr->recv_cq->usecnt);
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (qp_init_attr->srq)
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			atomic_inc(&qp_init_attr->srq->usecnt);
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp;
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_qp);
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_modify_qp(struct ib_qp *qp,
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 struct ib_qp_attr *qp_attr,
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 int qp_attr_mask)
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp->device->modify_qp(qp, qp_attr, qp_attr_mask);
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_modify_qp);
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_qp(struct ib_qp *qp,
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ib_qp_attr *qp_attr,
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int qp_attr_mask,
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ib_qp_init_attr *qp_init_attr)
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp->device->query_qp ?
2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->device->query_qp(qp, qp_attr, qp_attr_mask, qp_init_attr) :
2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_qp);
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_qp(struct ib_qp *qp)
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_cq *scq, *rcq;
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_srq *srq;
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd  = qp->pd;
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scq = qp->send_cq;
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	rcq = qp->recv_cq;
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	srq = qp->srq;
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = qp->device->destroy_qp(qp);
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret) {
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&scq->usecnt);
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&rcq->usecnt);
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (srq)
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			atomic_dec(&srq->usecnt);
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_qp);
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Completion queues */
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_cq *ib_create_cq(struct ib_device *device,
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   ib_comp_handler comp_handler,
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   void (*event_handler)(struct ib_event *, void *),
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   void *cq_context, int cqe)
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_cq *cq;
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
300b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier	cq = device->create_cq(device, cqe, NULL, NULL);
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(cq)) {
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->device        = device;
304b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		cq->uobject       = NULL;
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->comp_handler  = comp_handler;
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->event_handler = event_handler;
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->cq_context    = cq_context;
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&cq->usecnt, 0);
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return cq;
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_cq);
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_cq(struct ib_cq *cq)
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&cq->usecnt))
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return cq->device->destroy_cq(cq);
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_cq);
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_resize_cq(struct ib_cq *cq,
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds                 int           cqe)
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!cq->device->resize_cq)
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOSYS;
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = cq->device->resize_cq(cq, &cqe);
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->cqe = cqe;
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_resize_cq);
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Memory regions */
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mr *mr;
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mr = pd->device->get_dma_mr(pd, mr_access_flags);
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mr)) {
349b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->device  = pd->device;
350b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->pd      = pd;
351b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->uobject = NULL;
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&mr->usecnt, 0);
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr;
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_get_dma_mr);
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     struct ib_phys_buf *phys_buf_array,
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int num_phys_buf,
3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int mr_access_flags,
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     u64 *iova_start)
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mr *mr;
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mr = pd->device->reg_phys_mr(pd, phys_buf_array, num_phys_buf,
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				     mr_access_flags, iova_start);
3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mr)) {
372b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->device  = pd->device;
373b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->pd      = pd;
374b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->uobject = NULL;
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&mr->usecnt, 0);
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr;
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_reg_phys_mr);
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_rereg_phys_mr(struct ib_mr *mr,
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int mr_rereg_mask,
3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     struct ib_pd *pd,
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     struct ib_phys_buf *phys_buf_array,
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int num_phys_buf,
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int mr_access_flags,
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     u64 *iova_start)
3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *old_pd;
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!mr->device->rereg_phys_mr)
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOSYS;
3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&mr->usecnt))
3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	old_pd = mr->pd;
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mr->device->rereg_phys_mr(mr, mr_rereg_mask, pd,
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					phys_buf_array, num_phys_buf,
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mr_access_flags, iova_start);
4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret && (mr_rereg_mask & IB_MR_REREG_PD)) {
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&old_pd->usecnt);
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_rereg_phys_mr);
4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr->device->query_mr ?
4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mr->device->query_mr(mr, mr_attr) : -ENOSYS;
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_mr);
4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dereg_mr(struct ib_mr *mr)
4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&mr->usecnt))
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = mr->pd;
4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mr->device->dereg_mr(mr);
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dereg_mr);
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Memory windows */
4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mw *ib_alloc_mw(struct ib_pd *pd)
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mw *mw;
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!pd->device->alloc_mw)
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOSYS);
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mw = pd->device->alloc_mw(pd);
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mw)) {
450b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->device  = pd->device;
451b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->pd      = pd;
452b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->uobject = NULL;
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mw;
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_mw);
4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_mw(struct ib_mw *mw)
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = mw->pd;
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mw->device->dealloc_mw(mw);
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_mw);
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* "Fast" memory regions */
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    int mr_access_flags,
4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    struct ib_fmr_attr *fmr_attr)
4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_fmr *fmr;
4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!pd->device->alloc_fmr)
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOSYS);
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr);
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(fmr)) {
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fmr->device = pd->device;
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fmr->pd     = pd;
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return fmr;
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_fmr);
4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_unmap_fmr(struct list_head *fmr_list)
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_fmr *fmr;
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (list_empty(fmr_list))
5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fmr = list_entry(fmr_list->next, struct ib_fmr, list);
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return fmr->device->unmap_fmr(fmr_list);
5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_unmap_fmr);
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_fmr(struct ib_fmr *fmr)
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = fmr->pd;
5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = fmr->device->dealloc_fmr(fmr);
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_fmr);
5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Multicast groups */
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp->device->attach_mcast ?
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->device->attach_mcast(qp, gid, lid) :
5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_attach_mcast);
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp->device->detach_mcast ?
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->device->detach_mcast(qp, gid, lid) :
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_detach_mcast);
539