verbs.c revision f4fd0b224d60044d2da5ca02f8f2b5150c1d8731
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.
833b9b3ee9709b19c4f02ab91571d53540d05c3d1Roland Dreier * Copyright (c) 2005, 2006 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
48bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinint ib_rate_to_mult(enum ib_rate rate)
49bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{
50bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	switch (rate) {
51bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_2_5_GBPS: return  1;
52bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_5_GBPS:   return  2;
53bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_10_GBPS:  return  4;
54bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_20_GBPS:  return  8;
55bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_30_GBPS:  return 12;
56bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_40_GBPS:  return 16;
57bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_60_GBPS:  return 24;
58bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_80_GBPS:  return 32;
59bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case IB_RATE_120_GBPS: return 48;
60bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	default:	       return -1;
61bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	}
62bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein}
63bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack MorgensteinEXPORT_SYMBOL(ib_rate_to_mult);
64bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein
65bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgensteinenum ib_rate mult_to_ib_rate(int mult)
66bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein{
67bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	switch (mult) {
68bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 1:  return IB_RATE_2_5_GBPS;
69bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 2:  return IB_RATE_5_GBPS;
70bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 4:  return IB_RATE_10_GBPS;
71bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 8:  return IB_RATE_20_GBPS;
72bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 12: return IB_RATE_30_GBPS;
73bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 16: return IB_RATE_40_GBPS;
74bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 24: return IB_RATE_60_GBPS;
75bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 32: return IB_RATE_80_GBPS;
76bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	case 48: return IB_RATE_120_GBPS;
77bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	default: return IB_RATE_PORT_CURRENT;
78bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein	}
79bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein}
80bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack MorgensteinEXPORT_SYMBOL(mult_to_ib_rate);
81bf6a9e31cfa768ce0a8e18474b3ca808641d9243Jack Morgenstein
8207ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tuckerenum rdma_transport_type
8307ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tuckerrdma_node_get_transport(enum rdma_node_type node_type)
8407ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker{
8507ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	switch (node_type) {
8607ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_IB_CA:
8707ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_IB_SWITCH:
8807ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_IB_ROUTER:
8907ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		return RDMA_TRANSPORT_IB;
9007ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	case RDMA_NODE_RNIC:
9107ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		return RDMA_TRANSPORT_IWARP;
9207ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	default:
9307ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		BUG();
9407ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker		return 0;
9507ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker	}
9607ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker}
9707ebafbaaa72aa6a35472879008f5a1d1d469a0cTom TuckerEXPORT_SYMBOL(rdma_node_get_transport);
9807ebafbaaa72aa6a35472879008f5a1d1d469a0cTom Tucker
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Protection domains */
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_pd *ib_alloc_pd(struct ib_device *device)
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
105b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier	pd = device->alloc_pd(device, NULL, NULL);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(pd)) {
108b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		pd->device  = device;
109b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		pd->uobject = NULL;
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&pd->usecnt, 0);
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pd;
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_pd);
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_pd(struct ib_pd *pd)
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&pd->usecnt))
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return pd->device->dealloc_pd(pd);
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_pd);
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Address handles */
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_ah *ib_create_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr)
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_ah *ah;
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ah = pd->device->create_ah(pd, ah_attr);
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(ah)) {
135b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->device  = pd->device;
136b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->pd      = pd;
137b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		ah->uobject = NULL;
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah;
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_ah);
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1454e00d69454a8747798de11dc4eeef1edeee5ce98Sean Heftyint ib_init_ah_from_wc(struct ib_device *device, u8 port_num, struct ib_wc *wc,
1464e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		       struct ib_grh *grh, struct ib_ah_attr *ah_attr)
147513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock{
148513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	u32 flow_class;
149513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	u16 gid_index;
150513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	int ret;
151513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
1524e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	memset(ah_attr, 0, sizeof *ah_attr);
1534e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->dlid = wc->slid;
1544e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->sl = wc->sl;
1554e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->src_path_bits = wc->dlid_path_bits;
1564e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ah_attr->port_num = port_num;
157513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
158513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	if (wc->wc_flags & IB_WC_GRH) {
1594e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->ah_flags = IB_AH_GRH;
1604e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.dgid = grh->sgid;
161513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
1624e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ret = ib_find_cached_gid(device, &grh->dgid, &port_num,
163513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock					 &gid_index);
164513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock		if (ret)
1654e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty			return ret;
166513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
1674e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.sgid_index = (u8) gid_index;
168497677ab940e637a41351dca6610bc4320abc8f1Hal Rosenstock		flow_class = be32_to_cpu(grh->version_tclass_flow);
1694e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.flow_label = flow_class & 0xFFFFF;
17047645d8d25387c08bb3ccd84e1405c3776f21d24Sean Hefty		ah_attr->grh.hop_limit = 0xFF;
1714e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		ah_attr->grh.traffic_class = (flow_class >> 20) & 0xFF;
172513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	}
1734e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	return 0;
1744e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty}
1754e00d69454a8747798de11dc4eeef1edeee5ce98Sean HeftyEXPORT_SYMBOL(ib_init_ah_from_wc);
1764e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty
1774e00d69454a8747798de11dc4eeef1edeee5ce98Sean Heftystruct ib_ah *ib_create_ah_from_wc(struct ib_pd *pd, struct ib_wc *wc,
1784e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty				   struct ib_grh *grh, u8 port_num)
1794e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty{
1804e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	struct ib_ah_attr ah_attr;
1814e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	int ret;
1824e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty
1834e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	ret = ib_init_ah_from_wc(pd->device, port_num, wc, grh, &ah_attr);
1844e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty	if (ret)
1854e00d69454a8747798de11dc4eeef1edeee5ce98Sean Hefty		return ERR_PTR(ret);
186513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
187513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock	return ib_create_ah(pd, &ah_attr);
188513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock}
189513789ed995fb2ba72ba2a5bee53ea11d1170580Hal RosenstockEXPORT_SYMBOL(ib_create_ah_from_wc);
190513789ed995fb2ba72ba2a5bee53ea11d1170580Hal Rosenstock
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_modify_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah->device->modify_ah ?
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ah->device->modify_ah(ah, ah_attr) :
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_modify_ah);
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_ah(struct ib_ah *ah, struct ib_ah_attr *ah_attr)
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ah->device->query_ah ?
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ah->device->query_ah(ah, ah_attr) :
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_ah);
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_ah(struct ib_ah *ah)
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = ah->pd;
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = ah->device->destroy_ah(ah);
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_ah);
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
221d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier/* Shared receive queues */
222d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
223d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierstruct ib_srq *ib_create_srq(struct ib_pd *pd,
224d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier			     struct ib_srq_init_attr *srq_init_attr)
225d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
226d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	struct ib_srq *srq;
227d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
228d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (!pd->device->create_srq)
229d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		return ERR_PTR(-ENOSYS);
230d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
231d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	srq = pd->device->create_srq(pd, srq_init_attr, NULL);
232d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
233d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (!IS_ERR(srq)) {
234d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->device    	   = pd->device;
235d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->pd        	   = pd;
236d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->uobject       = NULL;
237d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->event_handler = srq_init_attr->event_handler;
238d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->srq_context   = srq_init_attr->srq_context;
239d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_inc(&pd->usecnt);
240d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_set(&srq->usecnt, 0);
241d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	}
242d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
243d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return srq;
244d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
245d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_create_srq);
246d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
247d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_modify_srq(struct ib_srq *srq,
248d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		  struct ib_srq_attr *srq_attr,
249d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		  enum ib_srq_attr_mask srq_attr_mask)
250d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
2519bc57e2d19db4da81c1150120658cc3658a99ed4Ralph Campbell	return srq->device->modify_srq(srq, srq_attr, srq_attr_mask, NULL);
252d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
253d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_modify_srq);
254d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
255d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_query_srq(struct ib_srq *srq,
256d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		 struct ib_srq_attr *srq_attr)
257d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
258d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return srq->device->query_srq ?
259d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		srq->device->query_srq(srq, srq_attr) : -ENOSYS;
260d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
261d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_query_srq);
262d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
263d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreierint ib_destroy_srq(struct ib_srq *srq)
264d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier{
265d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	struct ib_pd *pd;
266d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	int ret;
267d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
268d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (atomic_read(&srq->usecnt))
269d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		return -EBUSY;
270d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
271d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	pd = srq->pd;
272d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
273d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	ret = srq->device->destroy_srq(srq);
274d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	if (!ret)
275d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier		atomic_dec(&pd->usecnt);
276d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
277d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier	return ret;
278d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier}
279d41fcc6705eddd04f7218c985b6da35435ed73ccRoland DreierEXPORT_SYMBOL(ib_destroy_srq);
280d41fcc6705eddd04f7218c985b6da35435ed73ccRoland Dreier
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Queue pairs */
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_qp *ib_create_qp(struct ib_pd *pd,
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   struct ib_qp_init_attr *qp_init_attr)
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_qp *qp;
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
288b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier	qp = pd->device->create_qp(pd, qp_init_attr, NULL);
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(qp)) {
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->device     	  = pd->device;
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->pd         	  = pd;
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->send_cq    	  = qp_init_attr->send_cq;
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->recv_cq    	  = qp_init_attr->recv_cq;
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->srq	       	  = qp_init_attr->srq;
296b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		qp->uobject       = NULL;
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->event_handler = qp_init_attr->event_handler;
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->qp_context    = qp_init_attr->qp_context;
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->qp_type	  = qp_init_attr->qp_type;
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&qp_init_attr->send_cq->usecnt);
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&qp_init_attr->recv_cq->usecnt);
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (qp_init_attr->srq)
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			atomic_inc(&qp_init_attr->srq->usecnt);
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp;
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_qp);
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreierstatic const struct {
3128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	int			valid;
3138a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	enum ib_qp_attr_mask	req_param[IB_QPT_RAW_ETY + 1];
3148a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	enum ib_qp_attr_mask	opt_param[IB_QPT_RAW_ETY + 1];
3158a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
3168a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_RESET] = {
3178a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
3188a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR]   = { .valid = 1 },
3198a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_INIT]  = {
3208a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
3218a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.req_param = {
3228a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
3238a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
3248a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
3258a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_PKEY_INDEX		|
3268a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
3278a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
3288a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_PKEY_INDEX		|
3298a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
3308a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
3318a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
3328a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
3338a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
3348a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
3358a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
3368a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
3378a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
3388a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_INIT]  = {
3398a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
3408a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
3418a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_INIT]  = {
3428a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
3438a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
3448a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
3458a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
3468a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
3478a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_PKEY_INDEX		|
3488a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
3498a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
3508a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_PKEY_INDEX		|
3518a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PORT			|
3528a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
3538a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
3548a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
3558a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
3568a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
3578a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
3588a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
3598a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTR]   = {
3608a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
3618a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.req_param = {
3628a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_AV			|
3638a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MTU			|
3648a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_DEST_QPN			|
3658a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RQ_PSN),
3668a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_AV			|
3678a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MTU			|
3688a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_DEST_QPN			|
3698a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RQ_PSN			|
3708a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_DEST_RD_ATOMIC	|
3718a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER),
3728a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			},
3738a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
3748a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
3758a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
3768a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UC]  = (IB_QP_ALT_PATH			|
3778a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
3788a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PKEY_INDEX),
3798a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_RC]  = (IB_QP_ALT_PATH			|
3808a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
3818a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PKEY_INDEX),
3828a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
3838a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
3848a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
3858a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
3868a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			 }
3878a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
3888a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
3898a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_RTR]   = {
3908a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
3918a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
3928a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
3938a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
3948a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.req_param = {
3958a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = IB_QP_SQ_PSN,
3968a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = IB_QP_SQ_PSN,
3978a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_TIMEOUT			|
3988a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RETRY_CNT			|
3998a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RNR_RETRY			|
4008a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_SQ_PSN			|
4018a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_QP_RD_ATOMIC),
4028a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = IB_QP_SQ_PSN,
4038a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = IB_QP_SQ_PSN,
4048a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			},
4058a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
4068a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UD]  = (IB_QP_CUR_STATE		|
4078a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
4088a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_UC]  = (IB_QP_CUR_STATE		|
4098a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ALT_PATH			|
4108a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
4118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PATH_MIG_STATE),
4128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_RC]  = (IB_QP_CUR_STATE		|
4138a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ALT_PATH			|
4148a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_ACCESS_FLAGS		|
4158a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_MIN_RNR_TIMER		|
4168a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_PATH_MIG_STATE),
4178a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_SMI] = (IB_QP_CUR_STATE		|
4188a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
4198a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				 [IB_QPT_GSI] = (IB_QP_CUR_STATE		|
4208a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						 IB_QP_QKEY),
4218a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			 }
4228a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
4238a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
4248a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_RTS]   = {
4258a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
4268a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
4278a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
4288a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
4298a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
4308a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_CUR_STATE			|
4318a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4324546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak				[IB_QPT_UC]  = (IB_QP_CUR_STATE			|
4334546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak						IB_QP_ACCESS_FLAGS		|
4348a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
4358a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
4364546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak				[IB_QPT_RC]  = (IB_QP_CUR_STATE			|
4374546d31d84beafe74c56651173ac4fe197c7de8bDotan Barak						IB_QP_ACCESS_FLAGS		|
4388a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
4398a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE		|
4408a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER),
4418a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_CUR_STATE			|
4428a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4438a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_CUR_STATE			|
4448a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4458a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
4468a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
4478a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_SQD]   = {
4488a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
4498a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
4508a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
4518a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
4528a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
4538a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
4548a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY
4558a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
4568a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
4578a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
4588a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_SQD]   = {
4598a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
4608a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
4618a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
4628a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
4638a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
4648a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_CUR_STATE			|
4658a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4668a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_CUR_STATE			|
4678a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
4688a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
4698a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
4708a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_CUR_STATE			|
4718a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
4728a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
4738a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER		|
4748a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
4758a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_CUR_STATE			|
4768a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4778a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_CUR_STATE			|
4788a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4798a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
4808a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		},
4818a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_SQD]   = {
4828a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
4838a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
4848a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_PKEY_INDEX		|
4858a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
4868a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_AV			|
4878a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
4888a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
4898a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PKEY_INDEX		|
4908a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
4918a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_RC]  = (IB_QP_PORT			|
4928a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_AV			|
4938a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_TIMEOUT			|
4948a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RETRY_CNT			|
4958a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_RNR_RETRY			|
4968a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_QP_RD_ATOMIC		|
4978a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MAX_DEST_RD_ATOMIC	|
4988a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ALT_PATH			|
4998a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS		|
5008a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PKEY_INDEX		|
5018a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_MIN_RNR_TIMER		|
5028a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_PATH_MIG_STATE),
5038a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_PKEY_INDEX		|
5048a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5058a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_PKEY_INDEX		|
5068a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5078a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
5088a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
5098a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
5108a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_SQE]   = {
5118a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
5128a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 },
5138a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RTS]   = {
5148a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.valid = 1,
5158a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			.opt_param = {
5168a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UD]  = (IB_QP_CUR_STATE			|
5178a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5188a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_UC]  = (IB_QP_CUR_STATE			|
5198a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_ACCESS_FLAGS),
5208a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_SMI] = (IB_QP_CUR_STATE			|
5218a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5228a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier				[IB_QPT_GSI] = (IB_QP_CUR_STATE			|
5238a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier						IB_QP_QKEY),
5248a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier			}
5258a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		}
5268a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	},
5278a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	[IB_QPS_ERR] = {
5288a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_RESET] = { .valid = 1 },
5298a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		[IB_QPS_ERR] =   { .valid = 1 }
5308a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	}
5318a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier};
5328a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
5338a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreierint ib_modify_qp_is_ok(enum ib_qp_state cur_state, enum ib_qp_state next_state,
5348a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		       enum ib_qp_type type, enum ib_qp_attr_mask mask)
5358a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier{
5368a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	enum ib_qp_attr_mask req_param, opt_param;
5378a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
5388a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (cur_state  < 0 || cur_state  > IB_QPS_ERR ||
5398a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	    next_state < 0 || next_state > IB_QPS_ERR)
5408a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
5418a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
5428a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (mask & IB_QP_CUR_STATE  &&
5438a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	    cur_state != IB_QPS_RTR && cur_state != IB_QPS_RTS &&
5448a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	    cur_state != IB_QPS_SQD && cur_state != IB_QPS_SQE)
5458a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
5468a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
5478a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (!qp_state_table[cur_state][next_state].valid)
5488a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
5498a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
5508a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	req_param = qp_state_table[cur_state][next_state].req_param[type];
5518a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	opt_param = qp_state_table[cur_state][next_state].opt_param[type];
5528a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
5538a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if ((mask & req_param) != req_param)
5548a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
5558a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
5568a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	if (mask & ~(req_param | opt_param | IB_QP_STATE))
5578a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier		return 0;
5588a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
5598a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier	return 1;
5608a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier}
5618a51866f08103ba04894ce0f65eef567ddc3ed40Roland DreierEXPORT_SYMBOL(ib_modify_qp_is_ok);
5628a51866f08103ba04894ce0f65eef567ddc3ed40Roland Dreier
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_modify_qp(struct ib_qp *qp,
5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 struct ib_qp_attr *qp_attr,
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 int qp_attr_mask)
5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5679bc57e2d19db4da81c1150120658cc3658a99ed4Ralph Campbell	return qp->device->modify_qp(qp, qp_attr, qp_attr_mask, NULL);
5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_modify_qp);
5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_qp(struct ib_qp *qp,
5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ib_qp_attr *qp_attr,
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		int qp_attr_mask,
5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ib_qp_init_attr *qp_init_attr)
5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return qp->device->query_qp ?
5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		qp->device->query_qp(qp, qp_attr, qp_attr_mask, qp_init_attr) :
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		-ENOSYS;
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_qp);
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_qp(struct ib_qp *qp)
5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_cq *scq, *rcq;
5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_srq *srq;
5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd  = qp->pd;
5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	scq = qp->send_cq;
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	rcq = qp->recv_cq;
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	srq = qp->srq;
5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = qp->device->destroy_qp(qp);
5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret) {
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&scq->usecnt);
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&rcq->usecnt);
5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (srq)
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			atomic_dec(&srq->usecnt);
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_qp);
6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Completion queues */
6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_cq *ib_create_cq(struct ib_device *device,
6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   ib_comp_handler comp_handler,
6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			   void (*event_handler)(struct ib_event *, void *),
612f4fd0b224d60044d2da5ca02f8f2b5150c1d8731Michael S. Tsirkin			   void *cq_context, int cqe, int comp_vector)
6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_cq *cq;
6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
616f4fd0b224d60044d2da5ca02f8f2b5150c1d8731Michael S. Tsirkin	cq = device->create_cq(device, cqe, comp_vector, NULL, NULL);
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(cq)) {
6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->device        = device;
620b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		cq->uobject       = NULL;
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->comp_handler  = comp_handler;
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->event_handler = event_handler;
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cq->cq_context    = cq_context;
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&cq->usecnt, 0);
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return cq;
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_create_cq);
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_destroy_cq(struct ib_cq *cq)
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&cq->usecnt))
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return cq->device->destroy_cq(cq);
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_destroy_cq);
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
640a74cd4af0bfa9578594acbb711a958104c93b772Roland Dreierint ib_resize_cq(struct ib_cq *cq, int cqe)
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
64240de2e548c225e3ef859e3c60de9785e37e1b5b1Roland Dreier	return cq->device->resize_cq ?
64333b9b3ee9709b19c4f02ab91571d53540d05c3d1Roland Dreier		cq->device->resize_cq(cq, cqe, NULL) : -ENOSYS;
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_resize_cq);
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Memory regions */
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags)
6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mr *mr;
6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mr = pd->device->get_dma_mr(pd, mr_access_flags);
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mr)) {
656b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->device  = pd->device;
657b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->pd      = pd;
658b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->uobject = NULL;
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&mr->usecnt, 0);
6611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr;
6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_get_dma_mr);
6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mr *ib_reg_phys_mr(struct ib_pd *pd,
6681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     struct ib_phys_buf *phys_buf_array,
6691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int num_phys_buf,
6701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     int mr_access_flags,
6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			     u64 *iova_start)
6721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mr *mr;
6741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mr = pd->device->reg_phys_mr(pd, phys_buf_array, num_phys_buf,
6761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				     mr_access_flags, iova_start);
6771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mr)) {
679b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->device  = pd->device;
680b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->pd      = pd;
681b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mr->uobject = NULL;
6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
6831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_set(&mr->usecnt, 0);
6841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr;
6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_reg_phys_mr);
6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_rereg_phys_mr(struct ib_mr *mr,
6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int mr_rereg_mask,
6921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     struct ib_pd *pd,
6931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     struct ib_phys_buf *phys_buf_array,
6941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int num_phys_buf,
6951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     int mr_access_flags,
6961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		     u64 *iova_start)
6971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *old_pd;
6991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!mr->device->rereg_phys_mr)
7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOSYS;
7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&mr->usecnt))
7051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	old_pd = mr->pd;
7081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mr->device->rereg_phys_mr(mr, mr_rereg_mask, pd,
7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					phys_buf_array, num_phys_buf,
7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					mr_access_flags, iova_start);
7121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret && (mr_rereg_mask & IB_MR_REREG_PD)) {
7141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&old_pd->usecnt);
7151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
7161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
7191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_rereg_phys_mr);
7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_query_mr(struct ib_mr *mr, struct ib_mr_attr *mr_attr)
7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mr->device->query_mr ?
7251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mr->device->query_mr(mr, mr_attr) : -ENOSYS;
7261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_query_mr);
7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dereg_mr(struct ib_mr *mr)
7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (atomic_read(&mr->usecnt))
7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EBUSY;
7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = mr->pd;
7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mr->device->dereg_mr(mr);
7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
7431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dereg_mr);
7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Memory windows */
7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_mw *ib_alloc_mw(struct ib_pd *pd)
7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_mw *mw;
7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!pd->device->alloc_mw)
7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOSYS);
7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mw = pd->device->alloc_mw(pd);
7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(mw)) {
757b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->device  = pd->device;
758b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->pd      = pd;
759b5e81bf5e7084796d93167f438ec073e59aca9edRoland Dreier		mw->uobject = NULL;
7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return mw;
7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_mw);
7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_mw(struct ib_mw *mw)
7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = mw->pd;
7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = mw->device->dealloc_mw(mw);
7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_mw);
7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* "Fast" memory regions */
7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ib_fmr *ib_alloc_fmr(struct ib_pd *pd,
7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    int mr_access_flags,
7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			    struct ib_fmr_attr *fmr_attr)
7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_fmr *fmr;
7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!pd->device->alloc_fmr)
7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return ERR_PTR(-ENOSYS);
7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fmr = pd->device->alloc_fmr(pd, mr_access_flags, fmr_attr);
7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!IS_ERR(fmr)) {
7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fmr->device = pd->device;
7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		fmr->pd     = pd;
7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_inc(&pd->usecnt);
7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return fmr;
8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_alloc_fmr);
8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_unmap_fmr(struct list_head *fmr_list)
8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_fmr *fmr;
8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (list_empty(fmr_list))
8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return 0;
8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	fmr = list_entry(fmr_list->next, struct ib_fmr, list);
8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return fmr->device->unmap_fmr(fmr_list);
8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_unmap_fmr);
8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_dealloc_fmr(struct ib_fmr *fmr)
8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ib_pd *pd;
8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
8191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pd = fmr->pd;
8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = fmr->device->dealloc_fmr(fmr);
8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!ret)
8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		atomic_dec(&pd->usecnt);
8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_dealloc_fmr);
8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Multicast groups */
8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_attach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8330c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (!qp->device->attach_mcast)
8340c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -ENOSYS;
8350c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
8360c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -EINVAL;
8370c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein
8380c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	return qp->device->attach_mcast(qp, gid, lid);
8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_attach_mcast);
8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint ib_detach_mcast(struct ib_qp *qp, union ib_gid *gid, u16 lid)
8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
8440c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (!qp->device->detach_mcast)
8450c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -ENOSYS;
8460c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	if (gid->raw[0] != 0xff || qp->qp_type != IB_QPT_UD)
8470c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein		return -EINVAL;
8480c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein
8490c33aeedb2cf99d877ad9adc7c3df07870f60293Jack Morgenstein	return qp->device->detach_mcast(qp, gid, lid);
8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(ib_detach_mcast);
852