aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-08-30 14:33:26 -0400
committerSteve French <sfrench@us.ibm.com>2005-08-30 14:33:26 -0400
commit2016ef789a9ded2e169ad1c028ae3deb5302571f (patch)
tree601359f15b42d4d9868b4eadfe909a7bef6435c5 /drivers/infiniband/core
parent7f57356b70dda014ef269135942426e4a852023e (diff)
parent6b39374a27eb4be7e9d82145ae270ba02ea90dc8 (diff)
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers/infiniband/core')
-rw-r--r--drivers/infiniband/core/Makefile2
-rw-r--r--drivers/infiniband/core/agent.c13
-rw-r--r--drivers/infiniband/core/agent_priv.h10
-rw-r--r--drivers/infiniband/core/cache.c6
-rw-r--r--drivers/infiniband/core/cm.c125
-rw-r--r--drivers/infiniband/core/cm_msgs.h194
-rw-r--r--drivers/infiniband/core/core_priv.h2
-rw-r--r--drivers/infiniband/core/device.c1
-rw-r--r--drivers/infiniband/core/fmr_pool.c8
-rw-r--r--drivers/infiniband/core/mad.c15
-rw-r--r--drivers/infiniband/core/mad_priv.h10
-rw-r--r--drivers/infiniband/core/mad_rmpp.c311
-rw-r--r--drivers/infiniband/core/packer.c3
-rw-r--r--drivers/infiniband/core/sa_query.c6
-rw-r--r--drivers/infiniband/core/smi.c13
-rw-r--r--drivers/infiniband/core/sysfs.c40
-rw-r--r--drivers/infiniband/core/ucm.c464
-rw-r--r--drivers/infiniband/core/ucm.h13
-rw-r--r--drivers/infiniband/core/ud_header.c11
-rw-r--r--drivers/infiniband/core/user_mad.c10
-rw-r--r--drivers/infiniband/core/uverbs.h11
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c182
-rw-r--r--drivers/infiniband/core/uverbs_main.c25
-rw-r--r--drivers/infiniband/core/uverbs_mem.c1
-rw-r--r--drivers/infiniband/core/verbs.c65
25 files changed, 925 insertions, 616 deletions
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index 10be36731ed7..678a7e097f32 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -1,5 +1,3 @@
1EXTRA_CFLAGS += -Idrivers/infiniband/include
2
3obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \ 1obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \
4 ib_cm.o ib_umad.o ib_ucm.o 2 ib_cm.o ib_umad.o ib_ucm.o
5obj-$(CONFIG_INFINIBAND_USER_VERBS) += ib_uverbs.o 3obj-$(CONFIG_INFINIBAND_USER_VERBS) += ib_uverbs.o
diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c
index 729f0b0d983a..5ac86f566dc0 100644
--- a/drivers/infiniband/core/agent.c
+++ b/drivers/infiniband/core/agent.c
@@ -1,9 +1,10 @@
1/* 1/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved. 2 * Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved. 3 * Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved. 4 * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 5 * Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved. 6 * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
7 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
7 * 8 *
8 * This software is available to you under a choice of one of two 9 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU 10 * licenses. You may choose to be licensed under the terms of the GNU
@@ -40,7 +41,7 @@
40 41
41#include <asm/bug.h> 42#include <asm/bug.h>
42 43
43#include <ib_smi.h> 44#include <rdma/ib_smi.h>
44 45
45#include "smi.h" 46#include "smi.h"
46#include "agent_priv.h" 47#include "agent_priv.h"
diff --git a/drivers/infiniband/core/agent_priv.h b/drivers/infiniband/core/agent_priv.h
index 17435af1e914..2ec6d7f1b7d0 100644
--- a/drivers/infiniband/core/agent_priv.h
+++ b/drivers/infiniband/core/agent_priv.h
@@ -1,9 +1,9 @@
1/* 1/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved. 2 * Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved. 3 * Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved. 4 * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 5 * Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved. 6 * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
7 * 7 *
8 * This software is available to you under a choice of one of two 8 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU 9 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index 3042360c97e1..f014e639088c 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -1,5 +1,8 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Intel Corporation. All rights reserved.
4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
5 * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
3 * 6 *
4 * This software is available to you under a choice of one of two 7 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 8 * licenses. You may choose to be licensed under the terms of the GNU
@@ -32,12 +35,11 @@
32 * $Id: cache.c 1349 2004-12-16 21:09:43Z roland $ 35 * $Id: cache.c 1349 2004-12-16 21:09:43Z roland $
33 */ 36 */
34 37
35#include <linux/version.h>
36#include <linux/module.h> 38#include <linux/module.h>
37#include <linux/errno.h> 39#include <linux/errno.h>
38#include <linux/slab.h> 40#include <linux/slab.h>
39 41
40#include <ib_cache.h> 42#include <rdma/ib_cache.h>
41 43
42#include "core_priv.h" 44#include "core_priv.h"
43 45
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 403ed125d8f4..4de93ba274a6 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -43,8 +43,8 @@
43#include <linux/spinlock.h> 43#include <linux/spinlock.h>
44#include <linux/workqueue.h> 44#include <linux/workqueue.h>
45 45
46#include <ib_cache.h> 46#include <rdma/ib_cache.h>
47#include <ib_cm.h> 47#include <rdma/ib_cm.h>
48#include "cm_msgs.h" 48#include "cm_msgs.h"
49 49
50MODULE_AUTHOR("Sean Hefty"); 50MODULE_AUTHOR("Sean Hefty");
@@ -83,7 +83,7 @@ struct cm_port {
83struct cm_device { 83struct cm_device {
84 struct list_head list; 84 struct list_head list;
85 struct ib_device *device; 85 struct ib_device *device;
86 u64 ca_guid; 86 __be64 ca_guid;
87 struct cm_port port[0]; 87 struct cm_port port[0];
88}; 88};
89 89
@@ -100,8 +100,8 @@ struct cm_work {
100 struct list_head list; 100 struct list_head list;
101 struct cm_port *port; 101 struct cm_port *port;
102 struct ib_mad_recv_wc *mad_recv_wc; /* Received MADs */ 102 struct ib_mad_recv_wc *mad_recv_wc; /* Received MADs */
103 u32 local_id; /* Established / timewait */ 103 __be32 local_id; /* Established / timewait */
104 u32 remote_id; 104 __be32 remote_id;
105 struct ib_cm_event cm_event; 105 struct ib_cm_event cm_event;
106 struct ib_sa_path_rec path[0]; 106 struct ib_sa_path_rec path[0];
107}; 107};
@@ -110,8 +110,8 @@ struct cm_timewait_info {
110 struct cm_work work; /* Must be first. */ 110 struct cm_work work; /* Must be first. */
111 struct rb_node remote_qp_node; 111 struct rb_node remote_qp_node;
112 struct rb_node remote_id_node; 112 struct rb_node remote_id_node;
113 u64 remote_ca_guid; 113 __be64 remote_ca_guid;
114 u32 remote_qpn; 114 __be32 remote_qpn;
115 u8 inserted_remote_qp; 115 u8 inserted_remote_qp;
116 u8 inserted_remote_id; 116 u8 inserted_remote_id;
117}; 117};
@@ -132,11 +132,11 @@ struct cm_id_private {
132 struct cm_av alt_av; 132 struct cm_av alt_av;
133 133
134 void *private_data; 134 void *private_data;
135 u64 tid; 135 __be64 tid;
136 u32 local_qpn; 136 __be32 local_qpn;
137 u32 remote_qpn; 137 __be32 remote_qpn;
138 u32 sq_psn; 138 __be32 sq_psn;
139 u32 rq_psn; 139 __be32 rq_psn;
140 int timeout_ms; 140 int timeout_ms;
141 enum ib_mtu path_mtu; 141 enum ib_mtu path_mtu;
142 u8 private_data_len; 142 u8 private_data_len;
@@ -253,7 +253,7 @@ static void cm_set_ah_attr(struct ib_ah_attr *ah_attr, u8 port_num,
253 u16 dlid, u8 sl, u16 src_path_bits) 253 u16 dlid, u8 sl, u16 src_path_bits)
254{ 254{
255 memset(ah_attr, 0, sizeof ah_attr); 255 memset(ah_attr, 0, sizeof ah_attr);
256 ah_attr->dlid = be16_to_cpu(dlid); 256 ah_attr->dlid = dlid;
257 ah_attr->sl = sl; 257 ah_attr->sl = sl;
258 ah_attr->src_path_bits = src_path_bits; 258 ah_attr->src_path_bits = src_path_bits;
259 ah_attr->port_num = port_num; 259 ah_attr->port_num = port_num;
@@ -264,7 +264,7 @@ static void cm_init_av_for_response(struct cm_port *port,
264{ 264{
265 av->port = port; 265 av->port = port;
266 av->pkey_index = wc->pkey_index; 266 av->pkey_index = wc->pkey_index;
267 cm_set_ah_attr(&av->ah_attr, port->port_num, cpu_to_be16(wc->slid), 267 cm_set_ah_attr(&av->ah_attr, port->port_num, wc->slid,
268 wc->sl, wc->dlid_path_bits); 268 wc->sl, wc->dlid_path_bits);
269} 269}
270 270
@@ -295,8 +295,9 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
295 return ret; 295 return ret;
296 296
297 av->port = port; 297 av->port = port;
298 cm_set_ah_attr(&av->ah_attr, av->port->port_num, path->dlid, 298 cm_set_ah_attr(&av->ah_attr, av->port->port_num,
299 path->sl, path->slid & 0x7F); 299 be16_to_cpu(path->dlid), path->sl,
300 be16_to_cpu(path->slid) & 0x7F);
300 av->packet_life_time = path->packet_life_time; 301 av->packet_life_time = path->packet_life_time;
301 return 0; 302 return 0;
302} 303}
@@ -309,26 +310,26 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv)
309 do { 310 do {
310 spin_lock_irqsave(&cm.lock, flags); 311 spin_lock_irqsave(&cm.lock, flags);
311 ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, 1, 312 ret = idr_get_new_above(&cm.local_id_table, cm_id_priv, 1,
312 (int *) &cm_id_priv->id.local_id); 313 (__force int *) &cm_id_priv->id.local_id);
313 spin_unlock_irqrestore(&cm.lock, flags); 314 spin_unlock_irqrestore(&cm.lock, flags);
314 } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) ); 315 } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) );
315 return ret; 316 return ret;
316} 317}
317 318
318static void cm_free_id(u32 local_id) 319static void cm_free_id(__be32 local_id)
319{ 320{
320 unsigned long flags; 321 unsigned long flags;
321 322
322 spin_lock_irqsave(&cm.lock, flags); 323 spin_lock_irqsave(&cm.lock, flags);
323 idr_remove(&cm.local_id_table, (int) local_id); 324 idr_remove(&cm.local_id_table, (__force int) local_id);
324 spin_unlock_irqrestore(&cm.lock, flags); 325 spin_unlock_irqrestore(&cm.lock, flags);
325} 326}
326 327
327static struct cm_id_private * cm_get_id(u32 local_id, u32 remote_id) 328static struct cm_id_private * cm_get_id(__be32 local_id, __be32 remote_id)
328{ 329{
329 struct cm_id_private *cm_id_priv; 330 struct cm_id_private *cm_id_priv;
330 331
331 cm_id_priv = idr_find(&cm.local_id_table, (int) local_id); 332 cm_id_priv = idr_find(&cm.local_id_table, (__force int) local_id);
332 if (cm_id_priv) { 333 if (cm_id_priv) {
333 if (cm_id_priv->id.remote_id == remote_id) 334 if (cm_id_priv->id.remote_id == remote_id)
334 atomic_inc(&cm_id_priv->refcount); 335 atomic_inc(&cm_id_priv->refcount);
@@ -339,7 +340,7 @@ static struct cm_id_private * cm_get_id(u32 local_id, u32 remote_id)
339 return cm_id_priv; 340 return cm_id_priv;
340} 341}
341 342
342static struct cm_id_private * cm_acquire_id(u32 local_id, u32 remote_id) 343static struct cm_id_private * cm_acquire_id(__be32 local_id, __be32 remote_id)
343{ 344{
344 struct cm_id_private *cm_id_priv; 345 struct cm_id_private *cm_id_priv;
345 unsigned long flags; 346 unsigned long flags;
@@ -356,8 +357,8 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv)
356 struct rb_node **link = &cm.listen_service_table.rb_node; 357 struct rb_node **link = &cm.listen_service_table.rb_node;
357 struct rb_node *parent = NULL; 358 struct rb_node *parent = NULL;
358 struct cm_id_private *cur_cm_id_priv; 359 struct cm_id_private *cur_cm_id_priv;
359 u64 service_id = cm_id_priv->id.service_id; 360 __be64 service_id = cm_id_priv->id.service_id;
360 u64 service_mask = cm_id_priv->id.service_mask; 361 __be64 service_mask = cm_id_priv->id.service_mask;
361 362
362 while (*link) { 363 while (*link) {
363 parent = *link; 364 parent = *link;
@@ -376,7 +377,7 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv)
376 return NULL; 377 return NULL;
377} 378}
378 379
379static struct cm_id_private * cm_find_listen(u64 service_id) 380static struct cm_id_private * cm_find_listen(__be64 service_id)
380{ 381{
381 struct rb_node *node = cm.listen_service_table.rb_node; 382 struct rb_node *node = cm.listen_service_table.rb_node;
382 struct cm_id_private *cm_id_priv; 383 struct cm_id_private *cm_id_priv;
@@ -400,8 +401,8 @@ static struct cm_timewait_info * cm_insert_remote_id(struct cm_timewait_info
400 struct rb_node **link = &cm.remote_id_table.rb_node; 401 struct rb_node **link = &cm.remote_id_table.rb_node;
401 struct rb_node *parent = NULL; 402 struct rb_node *parent = NULL;
402 struct cm_timewait_info *cur_timewait_info; 403 struct cm_timewait_info *cur_timewait_info;
403 u64 remote_ca_guid = timewait_info->remote_ca_guid; 404 __be64 remote_ca_guid = timewait_info->remote_ca_guid;
404 u32 remote_id = timewait_info->work.remote_id; 405 __be32 remote_id = timewait_info->work.remote_id;
405 406
406 while (*link) { 407 while (*link) {
407 parent = *link; 408 parent = *link;
@@ -424,8 +425,8 @@ static struct cm_timewait_info * cm_insert_remote_id(struct cm_timewait_info
424 return NULL; 425 return NULL;
425} 426}
426 427
427static struct cm_timewait_info * cm_find_remote_id(u64 remote_ca_guid, 428static struct cm_timewait_info * cm_find_remote_id(__be64 remote_ca_guid,
428 u32 remote_id) 429 __be32 remote_id)
429{ 430{
430 struct rb_node *node = cm.remote_id_table.rb_node; 431 struct rb_node *node = cm.remote_id_table.rb_node;
431 struct cm_timewait_info *timewait_info; 432 struct cm_timewait_info *timewait_info;
@@ -453,8 +454,8 @@ static struct cm_timewait_info * cm_insert_remote_qpn(struct cm_timewait_info
453 struct rb_node **link = &cm.remote_qp_table.rb_node; 454 struct rb_node **link = &cm.remote_qp_table.rb_node;
454 struct rb_node *parent = NULL; 455 struct rb_node *parent = NULL;
455 struct cm_timewait_info *cur_timewait_info; 456 struct cm_timewait_info *cur_timewait_info;
456 u64 remote_ca_guid = timewait_info->remote_ca_guid; 457 __be64 remote_ca_guid = timewait_info->remote_ca_guid;
457 u32 remote_qpn = timewait_info->remote_qpn; 458 __be32 remote_qpn = timewait_info->remote_qpn;
458 459
459 while (*link) { 460 while (*link) {
460 parent = *link; 461 parent = *link;
@@ -484,7 +485,7 @@ static struct cm_id_private * cm_insert_remote_sidr(struct cm_id_private
484 struct rb_node *parent = NULL; 485 struct rb_node *parent = NULL;
485 struct cm_id_private *cur_cm_id_priv; 486 struct cm_id_private *cur_cm_id_priv;
486 union ib_gid *port_gid = &cm_id_priv->av.dgid; 487 union ib_gid *port_gid = &cm_id_priv->av.dgid;
487 u32 remote_id = cm_id_priv->id.remote_id; 488 __be32 remote_id = cm_id_priv->id.remote_id;
488 489
489 while (*link) { 490 while (*link) {
490 parent = *link; 491 parent = *link;
@@ -598,7 +599,7 @@ static void cm_cleanup_timewait(struct cm_timewait_info *timewait_info)
598 spin_unlock_irqrestore(&cm.lock, flags); 599 spin_unlock_irqrestore(&cm.lock, flags);
599} 600}
600 601
601static struct cm_timewait_info * cm_create_timewait_info(u32 local_id) 602static struct cm_timewait_info * cm_create_timewait_info(__be32 local_id)
602{ 603{
603 struct cm_timewait_info *timewait_info; 604 struct cm_timewait_info *timewait_info;
604 605
@@ -715,14 +716,15 @@ retest:
715EXPORT_SYMBOL(ib_destroy_cm_id); 716EXPORT_SYMBOL(ib_destroy_cm_id);
716 717
717int ib_cm_listen(struct ib_cm_id *cm_id, 718int ib_cm_listen(struct ib_cm_id *cm_id,
718 u64 service_id, 719 __be64 service_id,
719 u64 service_mask) 720 __be64 service_mask)
720{ 721{
721 struct cm_id_private *cm_id_priv, *cur_cm_id_priv; 722 struct cm_id_private *cm_id_priv, *cur_cm_id_priv;
722 unsigned long flags; 723 unsigned long flags;
723 int ret = 0; 724 int ret = 0;
724 725
725 service_mask = service_mask ? service_mask : ~0ULL; 726 service_mask = service_mask ? service_mask :
727 __constant_cpu_to_be64(~0ULL);
726 service_id &= service_mask; 728 service_id &= service_mask;
727 if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID && 729 if ((service_id & IB_SERVICE_ID_AGN_MASK) == IB_CM_ASSIGN_SERVICE_ID &&
728 (service_id != IB_CM_ASSIGN_SERVICE_ID)) 730 (service_id != IB_CM_ASSIGN_SERVICE_ID))
@@ -735,8 +737,8 @@ int ib_cm_listen(struct ib_cm_id *cm_id,
735 737
736 spin_lock_irqsave(&cm.lock, flags); 738 spin_lock_irqsave(&cm.lock, flags);
737 if (service_id == IB_CM_ASSIGN_SERVICE_ID) { 739 if (service_id == IB_CM_ASSIGN_SERVICE_ID) {
738 cm_id->service_id = __cpu_to_be64(cm.listen_service_id++); 740 cm_id->service_id = cpu_to_be64(cm.listen_service_id++);
739 cm_id->service_mask = ~0ULL; 741 cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
740 } else { 742 } else {
741 cm_id->service_id = service_id; 743 cm_id->service_id = service_id;
742 cm_id->service_mask = service_mask; 744 cm_id->service_mask = service_mask;
@@ -752,18 +754,19 @@ int ib_cm_listen(struct ib_cm_id *cm_id,
752} 754}
753EXPORT_SYMBOL(ib_cm_listen); 755EXPORT_SYMBOL(ib_cm_listen);
754 756
755static u64 cm_form_tid(struct cm_id_private *cm_id_priv, 757static __be64 cm_form_tid(struct cm_id_private *cm_id_priv,
756 enum cm_msg_sequence msg_seq) 758 enum cm_msg_sequence msg_seq)
757{ 759{
758 u64 hi_tid, low_tid; 760 u64 hi_tid, low_tid;
759 761
760 hi_tid = ((u64) cm_id_priv->av.port->mad_agent->hi_tid) << 32; 762 hi_tid = ((u64) cm_id_priv->av.port->mad_agent->hi_tid) << 32;
761 low_tid = (u64) (cm_id_priv->id.local_id | (msg_seq << 30)); 763 low_tid = (u64) ((__force u32)cm_id_priv->id.local_id |
764 (msg_seq << 30));
762 return cpu_to_be64(hi_tid | low_tid); 765 return cpu_to_be64(hi_tid | low_tid);
763} 766}
764 767
765static void cm_format_mad_hdr(struct ib_mad_hdr *hdr, 768static void cm_format_mad_hdr(struct ib_mad_hdr *hdr,
766 enum cm_msg_attr_id attr_id, u64 tid) 769 __be16 attr_id, __be64 tid)
767{ 770{
768 hdr->base_version = IB_MGMT_BASE_VERSION; 771 hdr->base_version = IB_MGMT_BASE_VERSION;
769 hdr->mgmt_class = IB_MGMT_CLASS_CM; 772 hdr->mgmt_class = IB_MGMT_CLASS_CM;
@@ -896,7 +899,7 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
896 goto error1; 899 goto error1;
897 } 900 }
898 cm_id->service_id = param->service_id; 901 cm_id->service_id = param->service_id;
899 cm_id->service_mask = ~0ULL; 902 cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
900 cm_id_priv->timeout_ms = cm_convert_to_ms( 903 cm_id_priv->timeout_ms = cm_convert_to_ms(
901 param->primary_path->packet_life_time) * 2 + 904 param->primary_path->packet_life_time) * 2 +
902 cm_convert_to_ms( 905 cm_convert_to_ms(
@@ -963,7 +966,7 @@ static int cm_issue_rej(struct cm_port *port,
963 rej_msg->remote_comm_id = rcv_msg->local_comm_id; 966 rej_msg->remote_comm_id = rcv_msg->local_comm_id;
964 rej_msg->local_comm_id = rcv_msg->remote_comm_id; 967 rej_msg->local_comm_id = rcv_msg->remote_comm_id;
965 cm_rej_set_msg_rejected(rej_msg, msg_rejected); 968 cm_rej_set_msg_rejected(rej_msg, msg_rejected);
966 rej_msg->reason = reason; 969 rej_msg->reason = cpu_to_be16(reason);
967 970
968 if (ari && ari_length) { 971 if (ari && ari_length) {
969 cm_rej_set_reject_info_len(rej_msg, ari_length); 972 cm_rej_set_reject_info_len(rej_msg, ari_length);
@@ -977,8 +980,8 @@ static int cm_issue_rej(struct cm_port *port,
977 return ret; 980 return ret;
978} 981}
979 982
980static inline int cm_is_active_peer(u64 local_ca_guid, u64 remote_ca_guid, 983static inline int cm_is_active_peer(__be64 local_ca_guid, __be64 remote_ca_guid,
981 u32 local_qpn, u32 remote_qpn) 984 __be32 local_qpn, __be32 remote_qpn)
982{ 985{
983 return (be64_to_cpu(local_ca_guid) > be64_to_cpu(remote_ca_guid) || 986 return (be64_to_cpu(local_ca_guid) > be64_to_cpu(remote_ca_guid) ||
984 ((local_ca_guid == remote_ca_guid) && 987 ((local_ca_guid == remote_ca_guid) &&
@@ -1137,7 +1140,7 @@ static void cm_format_rej(struct cm_rej_msg *rej_msg,
1137 break; 1140 break;
1138 } 1141 }
1139 1142
1140 rej_msg->reason = reason; 1143 rej_msg->reason = cpu_to_be16(reason);
1141 if (ari && ari_length) { 1144 if (ari && ari_length) {
1142 cm_rej_set_reject_info_len(rej_msg, ari_length); 1145 cm_rej_set_reject_info_len(rej_msg, ari_length);
1143 memcpy(rej_msg->ari, ari, ari_length); 1146 memcpy(rej_msg->ari, ari, ari_length);
@@ -1276,7 +1279,7 @@ static int cm_req_handler(struct cm_work *work)
1276 cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler; 1279 cm_id_priv->id.cm_handler = listen_cm_id_priv->id.cm_handler;
1277 cm_id_priv->id.context = listen_cm_id_priv->id.context; 1280 cm_id_priv->id.context = listen_cm_id_priv->id.context;
1278 cm_id_priv->id.service_id = req_msg->service_id; 1281 cm_id_priv->id.service_id = req_msg->service_id;
1279 cm_id_priv->id.service_mask = ~0ULL; 1282 cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL);
1280 1283
1281 cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]); 1284 cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
1282 ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av); 1285 ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
@@ -1969,7 +1972,7 @@ static void cm_format_rej_event(struct cm_work *work)
1969 param = &work->cm_event.param.rej_rcvd; 1972 param = &work->cm_event.param.rej_rcvd;
1970 param->ari = rej_msg->ari; 1973 param->ari = rej_msg->ari;
1971 param->ari_length = cm_rej_get_reject_info_len(rej_msg); 1974 param->ari_length = cm_rej_get_reject_info_len(rej_msg);
1972 param->reason = rej_msg->reason; 1975 param->reason = __be16_to_cpu(rej_msg->reason);
1973 work->cm_event.private_data = &rej_msg->private_data; 1976 work->cm_event.private_data = &rej_msg->private_data;
1974} 1977}
1975 1978
@@ -1978,20 +1981,20 @@ static struct cm_id_private * cm_acquire_rejected_id(struct cm_rej_msg *rej_msg)
1978 struct cm_timewait_info *timewait_info; 1981 struct cm_timewait_info *timewait_info;
1979 struct cm_id_private *cm_id_priv; 1982 struct cm_id_private *cm_id_priv;
1980 unsigned long flags; 1983 unsigned long flags;
1981 u32 remote_id; 1984 __be32 remote_id;
1982 1985
1983 remote_id = rej_msg->local_comm_id; 1986 remote_id = rej_msg->local_comm_id;
1984 1987
1985 if (rej_msg->reason == IB_CM_REJ_TIMEOUT) { 1988 if (__be16_to_cpu(rej_msg->reason) == IB_CM_REJ_TIMEOUT) {
1986 spin_lock_irqsave(&cm.lock, flags); 1989 spin_lock_irqsave(&cm.lock, flags);
1987 timewait_info = cm_find_remote_id( *((u64 *) rej_msg->ari), 1990 timewait_info = cm_find_remote_id( *((__be64 *) rej_msg->ari),
1988 remote_id); 1991 remote_id);
1989 if (!timewait_info) { 1992 if (!timewait_info) {
1990 spin_unlock_irqrestore(&cm.lock, flags); 1993 spin_unlock_irqrestore(&cm.lock, flags);
1991 return NULL; 1994 return NULL;
1992 } 1995 }
1993 cm_id_priv = idr_find(&cm.local_id_table, 1996 cm_id_priv = idr_find(&cm.local_id_table,
1994 (int) timewait_info->work.local_id); 1997 (__force int) timewait_info->work.local_id);
1995 if (cm_id_priv) { 1998 if (cm_id_priv) {
1996 if (cm_id_priv->id.remote_id == remote_id) 1999 if (cm_id_priv->id.remote_id == remote_id)
1997 atomic_inc(&cm_id_priv->refcount); 2000 atomic_inc(&cm_id_priv->refcount);
@@ -2032,7 +2035,7 @@ static int cm_rej_handler(struct cm_work *work)
2032 /* fall through */ 2035 /* fall through */
2033 case IB_CM_REQ_RCVD: 2036 case IB_CM_REQ_RCVD:
2034 case IB_CM_MRA_REQ_SENT: 2037 case IB_CM_MRA_REQ_SENT:
2035 if (rej_msg->reason == IB_CM_REJ_STALE_CONN) 2038 if (__be16_to_cpu(rej_msg->reason) == IB_CM_REJ_STALE_CONN)
2036 cm_enter_timewait(cm_id_priv); 2039 cm_enter_timewait(cm_id_priv);
2037 else 2040 else
2038 cm_reset_to_idle(cm_id_priv); 2041 cm_reset_to_idle(cm_id_priv);
@@ -2553,7 +2556,7 @@ static void cm_format_sidr_req(struct cm_sidr_req_msg *sidr_req_msg,
2553 cm_format_mad_hdr(&sidr_req_msg->hdr, CM_SIDR_REQ_ATTR_ID, 2556 cm_format_mad_hdr(&sidr_req_msg->hdr, CM_SIDR_REQ_ATTR_ID,
2554 cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_SIDR)); 2557 cm_form_tid(cm_id_priv, CM_MSG_SEQUENCE_SIDR));
2555 sidr_req_msg->request_id = cm_id_priv->id.local_id; 2558 sidr_req_msg->request_id = cm_id_priv->id.local_id;
2556 sidr_req_msg->pkey = param->pkey; 2559 sidr_req_msg->pkey = cpu_to_be16(param->pkey);
2557 sidr_req_msg->service_id = param->service_id; 2560 sidr_req_msg->service_id = param->service_id;
2558 2561
2559 if (param->private_data && param->private_data_len) 2562 if (param->private_data && param->private_data_len)
@@ -2580,7 +2583,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
2580 goto out; 2583 goto out;
2581 2584
2582 cm_id->service_id = param->service_id; 2585 cm_id->service_id = param->service_id;
2583 cm_id->service_mask = ~0ULL; 2586 cm_id->service_mask = __constant_cpu_to_be64(~0ULL);
2584 cm_id_priv->timeout_ms = param->timeout_ms; 2587 cm_id_priv->timeout_ms = param->timeout_ms;
2585 cm_id_priv->max_cm_retries = param->max_cm_retries; 2588 cm_id_priv->max_cm_retries = param->max_cm_retries;
2586 ret = cm_alloc_msg(cm_id_priv, &msg); 2589 ret = cm_alloc_msg(cm_id_priv, &msg);
@@ -2621,7 +2624,7 @@ static void cm_format_sidr_req_event(struct cm_work *work,
2621 sidr_req_msg = (struct cm_sidr_req_msg *) 2624 sidr_req_msg = (struct cm_sidr_req_msg *)
2622 work->mad_recv_wc->recv_buf.mad; 2625 work->mad_recv_wc->recv_buf.mad;
2623 param = &work->cm_event.param.sidr_req_rcvd; 2626 param = &work->cm_event.param.sidr_req_rcvd;
2624 param->pkey = sidr_req_msg->pkey; 2627 param->pkey = __be16_to_cpu(sidr_req_msg->pkey);
2625 param->listen_id = listen_id; 2628 param->listen_id = listen_id;
2626 param->device = work->port->mad_agent->device; 2629 param->device = work->port->mad_agent->device;
2627 param->port = work->port->port_num; 2630 param->port = work->port->port_num;
@@ -2645,7 +2648,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
2645 sidr_req_msg = (struct cm_sidr_req_msg *) 2648 sidr_req_msg = (struct cm_sidr_req_msg *)
2646 work->mad_recv_wc->recv_buf.mad; 2649 work->mad_recv_wc->recv_buf.mad;
2647 wc = work->mad_recv_wc->wc; 2650 wc = work->mad_recv_wc->wc;
2648 cm_id_priv->av.dgid.global.subnet_prefix = wc->slid; 2651 cm_id_priv->av.dgid.global.subnet_prefix = cpu_to_be64(wc->slid);
2649 cm_id_priv->av.dgid.global.interface_id = 0; 2652 cm_id_priv->av.dgid.global.interface_id = 0;
2650 cm_init_av_for_response(work->port, work->mad_recv_wc->wc, 2653 cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
2651 &cm_id_priv->av); 2654 &cm_id_priv->av);
@@ -2673,7 +2676,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
2673 cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler; 2676 cm_id_priv->id.cm_handler = cur_cm_id_priv->id.cm_handler;
2674 cm_id_priv->id.context = cur_cm_id_priv->id.context; 2677 cm_id_priv->id.context = cur_cm_id_priv->id.context;
2675 cm_id_priv->id.service_id = sidr_req_msg->service_id; 2678 cm_id_priv->id.service_id = sidr_req_msg->service_id;
2676 cm_id_priv->id.service_mask = ~0ULL; 2679 cm_id_priv->id.service_mask = __constant_cpu_to_be64(~0ULL);
2677 2680
2678 cm_format_sidr_req_event(work, &cur_cm_id_priv->id); 2681 cm_format_sidr_req_event(work, &cur_cm_id_priv->id);
2679 cm_process_work(cm_id_priv, work); 2682 cm_process_work(cm_id_priv, work);
@@ -3175,10 +3178,10 @@ int ib_cm_init_qp_attr(struct ib_cm_id *cm_id,
3175} 3178}
3176EXPORT_SYMBOL(ib_cm_init_qp_attr); 3179EXPORT_SYMBOL(ib_cm_init_qp_attr);
3177 3180
3178static u64 cm_get_ca_guid(struct ib_device *device) 3181static __be64 cm_get_ca_guid(struct ib_device *device)
3179{ 3182{
3180 struct ib_device_attr *device_attr; 3183 struct ib_device_attr *device_attr;
3181 u64 guid; 3184 __be64 guid;
3182 int ret; 3185 int ret;
3183 3186
3184 device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL); 3187 device_attr = kmalloc(sizeof *device_attr, GFP_KERNEL);
diff --git a/drivers/infiniband/core/cm_msgs.h b/drivers/infiniband/core/cm_msgs.h
index 15a309a77b2b..813ab70bf6d5 100644
--- a/drivers/infiniband/core/cm_msgs.h
+++ b/drivers/infiniband/core/cm_msgs.h
@@ -34,7 +34,7 @@
34#if !defined(CM_MSGS_H) 34#if !defined(CM_MSGS_H)
35#define CM_MSGS_H 35#define CM_MSGS_H
36 36
37#include <ib_mad.h> 37#include <rdma/ib_mad.h>
38 38
39/* 39/*
40 * Parameters to routines below should be in network-byte order, and values 40 * Parameters to routines below should be in network-byte order, and values
@@ -43,19 +43,17 @@
43 43
44#define IB_CM_CLASS_VERSION 2 /* IB specification 1.2 */ 44#define IB_CM_CLASS_VERSION 2 /* IB specification 1.2 */
45 45
46enum cm_msg_attr_id { 46#define CM_REQ_ATTR_ID __constant_htons(0x0010)
47 CM_REQ_ATTR_ID = __constant_htons(0x0010), 47#define CM_MRA_ATTR_ID __constant_htons(0x0011)
48 CM_MRA_ATTR_ID = __constant_htons(0x0011), 48#define CM_REJ_ATTR_ID __constant_htons(0x0012)
49 CM_REJ_ATTR_ID = __constant_htons(0x0012), 49#define CM_REP_ATTR_ID __constant_htons(0x0013)
50 CM_REP_ATTR_ID = __constant_htons(0x0013), 50#define CM_RTU_ATTR_ID __constant_htons(0x0014)
51 CM_RTU_ATTR_ID = __constant_htons(0x0014), 51#define CM_DREQ_ATTR_ID __constant_htons(0x0015)
52 CM_DREQ_ATTR_ID = __constant_htons(0x0015), 52#define CM_DREP_ATTR_ID __constant_htons(0x0016)
53 CM_DREP_ATTR_ID = __constant_htons(0x0016), 53#define CM_SIDR_REQ_ATTR_ID __constant_htons(0x0017)
54 CM_SIDR_REQ_ATTR_ID = __constant_htons(0x0017), 54#define CM_SIDR_REP_ATTR_ID __constant_htons(0x0018)
55 CM_SIDR_REP_ATTR_ID = __constant_htons(0x0018), 55#define CM_LAP_ATTR_ID __constant_htons(0x0019)
56 CM_LAP_ATTR_ID = __constant_htons(0x0019), 56#define CM_APR_ATTR_ID __constant_htons(0x001A)
57 CM_APR_ATTR_ID = __constant_htons(0x001A)
58};
59 57
60enum cm_msg_sequence { 58enum cm_msg_sequence {
61 CM_MSG_SEQUENCE_REQ, 59 CM_MSG_SEQUENCE_REQ,
@@ -67,35 +65,35 @@ enum cm_msg_sequence {
67struct cm_req_msg { 65struct cm_req_msg {
68 struct ib_mad_hdr hdr; 66 struct ib_mad_hdr hdr;
69 67
70 u32 local_comm_id; 68 __be32 local_comm_id;
71 u32 rsvd4; 69 __be32 rsvd4;
72 u64 service_id; 70 __be64 service_id;
73 u64 local_ca_guid; 71 __be64 local_ca_guid;
74 u32 rsvd24; 72 __be32 rsvd24;
75 u32 local_qkey; 73 __be32 local_qkey;
76 /* local QPN:24, responder resources:8 */ 74 /* local QPN:24, responder resources:8 */
77 u32 offset32; 75 __be32 offset32;
78 /* local EECN:24, initiator depth:8 */ 76 /* local EECN:24, initiator depth:8 */
79 u32 offset36; 77 __be32 offset36;
80 /* 78 /*
81 * remote EECN:24, remote CM response timeout:5, 79 * remote EECN:24, remote CM response timeout:5,
82 * transport service type:2, end-to-end flow control:1 80 * transport service type:2, end-to-end flow control:1
83 */ 81 */
84 u32 offset40; 82 __be32 offset40;
85 /* starting PSN:24, local CM response timeout:5, retry count:3 */ 83 /* starting PSN:24, local CM response timeout:5, retry count:3 */
86 u32 offset44; 84 __be32 offset44;
87 u16 pkey; 85 __be16 pkey;
88 /* path MTU:4, RDC exists:1, RNR retry count:3. */ 86 /* path MTU:4, RDC exists:1, RNR retry count:3. */
89 u8 offset50; 87 u8 offset50;
90 /* max CM Retries:4, SRQ:1, rsvd:3 */ 88 /* max CM Retries:4, SRQ:1, rsvd:3 */
91 u8 offset51; 89 u8 offset51;
92 90
93 u16 primary_local_lid; 91 __be16 primary_local_lid;
94 u16 primary_remote_lid; 92 __be16 primary_remote_lid;
95 union ib_gid primary_local_gid; 93 union ib_gid primary_local_gid;
96 union ib_gid primary_remote_gid; 94 union ib_gid primary_remote_gid;
97 /* flow label:20, rsvd:6, packet rate:6 */ 95 /* flow label:20, rsvd:6, packet rate:6 */
98 u32 primary_offset88; 96 __be32 primary_offset88;
99 u8 primary_traffic_class; 97 u8 primary_traffic_class;
100 u8 primary_hop_limit; 98 u8 primary_hop_limit;
101 /* SL:4, subnet local:1, rsvd:3 */ 99 /* SL:4, subnet local:1, rsvd:3 */
@@ -103,12 +101,12 @@ struct cm_req_msg {
103 /* local ACK timeout:5, rsvd:3 */ 101 /* local ACK timeout:5, rsvd:3 */
104 u8 primary_offset95; 102 u8 primary_offset95;
105 103
106 u16 alt_local_lid; 104 __be16 alt_local_lid;
107 u16 alt_remote_lid; 105 __be16 alt_remote_lid;
108 union ib_gid alt_local_gid; 106 union ib_gid alt_local_gid;
109 union ib_gid alt_remote_gid; 107 union ib_gid alt_remote_gid;
110 /* flow label:20, rsvd:6, packet rate:6 */ 108 /* flow label:20, rsvd:6, packet rate:6 */
111 u32 alt_offset132; 109 __be32 alt_offset132;
112 u8 alt_traffic_class; 110 u8 alt_traffic_class;
113 u8 alt_hop_limit; 111 u8 alt_hop_limit;
114 /* SL:4, subnet local:1, rsvd:3 */ 112 /* SL:4, subnet local:1, rsvd:3 */
@@ -120,12 +118,12 @@ struct cm_req_msg {
120 118
121} __attribute__ ((packed)); 119} __attribute__ ((packed));
122 120
123static inline u32 cm_req_get_local_qpn(struct cm_req_msg *req_msg) 121static inline __be32 cm_req_get_local_qpn(struct cm_req_msg *req_msg)
124{ 122{
125 return cpu_to_be32(be32_to_cpu(req_msg->offset32) >> 8); 123 return cpu_to_be32(be32_to_cpu(req_msg->offset32) >> 8);
126} 124}
127 125
128static inline void cm_req_set_local_qpn(struct cm_req_msg *req_msg, u32 qpn) 126static inline void cm_req_set_local_qpn(struct cm_req_msg *req_msg, __be32 qpn)
129{ 127{
130 req_msg->offset32 = cpu_to_be32((be32_to_cpu(qpn) << 8) | 128 req_msg->offset32 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
131 (be32_to_cpu(req_msg->offset32) & 129 (be32_to_cpu(req_msg->offset32) &
@@ -208,13 +206,13 @@ static inline void cm_req_set_flow_ctrl(struct cm_req_msg *req_msg,
208 0xFFFFFFFE)); 206 0xFFFFFFFE));
209} 207}
210 208
211static inline u32 cm_req_get_starting_psn(struct cm_req_msg *req_msg) 209static inline __be32 cm_req_get_starting_psn(struct cm_req_msg *req_msg)
212{ 210{
213 return cpu_to_be32(be32_to_cpu(req_msg->offset44) >> 8); 211 return cpu_to_be32(be32_to_cpu(req_msg->offset44) >> 8);
214} 212}
215 213
216static inline void cm_req_set_starting_psn(struct cm_req_msg *req_msg, 214static inline void cm_req_set_starting_psn(struct cm_req_msg *req_msg,
217 u32 starting_psn) 215 __be32 starting_psn)
218{ 216{
219 req_msg->offset44 = cpu_to_be32((be32_to_cpu(starting_psn) << 8) | 217 req_msg->offset44 = cpu_to_be32((be32_to_cpu(starting_psn) << 8) |
220 (be32_to_cpu(req_msg->offset44) & 0x000000FF)); 218 (be32_to_cpu(req_msg->offset44) & 0x000000FF));
@@ -288,13 +286,13 @@ static inline void cm_req_set_srq(struct cm_req_msg *req_msg, u8 srq)
288 ((srq & 0x1) << 3)); 286 ((srq & 0x1) << 3));
289} 287}
290 288
291static inline u32 cm_req_get_primary_flow_label(struct cm_req_msg *req_msg) 289static inline __be32 cm_req_get_primary_flow_label(struct cm_req_msg *req_msg)
292{ 290{
293 return cpu_to_be32((be32_to_cpu(req_msg->primary_offset88) >> 12)); 291 return cpu_to_be32(be32_to_cpu(req_msg->primary_offset88) >> 12);
294} 292}
295 293
296static inline void cm_req_set_primary_flow_label(struct cm_req_msg *req_msg, 294static inline void cm_req_set_primary_flow_label(struct cm_req_msg *req_msg,
297 u32 flow_label) 295 __be32 flow_label)
298{ 296{
299 req_msg->primary_offset88 = cpu_to_be32( 297 req_msg->primary_offset88 = cpu_to_be32(
300 (be32_to_cpu(req_msg->primary_offset88) & 298 (be32_to_cpu(req_msg->primary_offset88) &
@@ -350,13 +348,13 @@ static inline void cm_req_set_primary_local_ack_timeout(struct cm_req_msg *req_m
350 (local_ack_timeout << 3)); 348 (local_ack_timeout << 3));
351} 349}
352 350
353static inline u32 cm_req_get_alt_flow_label(struct cm_req_msg *req_msg) 351static inline __be32 cm_req_get_alt_flow_label(struct cm_req_msg *req_msg)
354{ 352{
355 return cpu_to_be32((be32_to_cpu(req_msg->alt_offset132) >> 12)); 353 return cpu_to_be32(be32_to_cpu(req_msg->alt_offset132) >> 12);
356} 354}
357 355
358static inline void cm_req_set_alt_flow_label(struct cm_req_msg *req_msg, 356static inline void cm_req_set_alt_flow_label(struct cm_req_msg *req_msg,
359 u32 flow_label) 357 __be32 flow_label)
360{ 358{
361 req_msg->alt_offset132 = cpu_to_be32( 359 req_msg->alt_offset132 = cpu_to_be32(
362 (be32_to_cpu(req_msg->alt_offset132) & 360 (be32_to_cpu(req_msg->alt_offset132) &
@@ -422,8 +420,8 @@ enum cm_msg_response {
422 struct cm_mra_msg { 420 struct cm_mra_msg {
423 struct ib_mad_hdr hdr; 421 struct ib_mad_hdr hdr;
424 422
425 u32 local_comm_id; 423 __be32 local_comm_id;
426 u32 remote_comm_id; 424 __be32 remote_comm_id;
427 /* message MRAed:2, rsvd:6 */ 425 /* message MRAed:2, rsvd:6 */
428 u8 offset8; 426 u8 offset8;
429 /* service timeout:5, rsvd:3 */ 427 /* service timeout:5, rsvd:3 */
@@ -458,13 +456,13 @@ static inline void cm_mra_set_service_timeout(struct cm_mra_msg *mra_msg,
458struct cm_rej_msg { 456struct cm_rej_msg {
459 struct ib_mad_hdr hdr; 457 struct ib_mad_hdr hdr;
460 458
461 u32 local_comm_id; 459 __be32 local_comm_id;
462 u32 remote_comm_id; 460 __be32 remote_comm_id;
463 /* message REJected:2, rsvd:6 */ 461 /* message REJected:2, rsvd:6 */
464 u8 offset8; 462 u8 offset8;
465 /* reject info length:7, rsvd:1. */ 463 /* reject info length:7, rsvd:1. */
466 u8 offset9; 464 u8 offset9;
467 u16 reason; 465 __be16 reason;
468 u8 ari[IB_CM_REJ_ARI_LENGTH]; 466 u8 ari[IB_CM_REJ_ARI_LENGTH];
469 467
470 u8 private_data[IB_CM_REJ_PRIVATE_DATA_SIZE]; 468 u8 private_data[IB_CM_REJ_PRIVATE_DATA_SIZE];
@@ -495,45 +493,45 @@ static inline void cm_rej_set_reject_info_len(struct cm_rej_msg *rej_msg,
495struct cm_rep_msg { 493struct cm_rep_msg {
496 struct ib_mad_hdr hdr; 494 struct ib_mad_hdr hdr;
497 495
498 u32 local_comm_id; 496 __be32 local_comm_id;
499 u32 remote_comm_id; 497 __be32 remote_comm_id;
500 u32 local_qkey; 498 __be32 local_qkey;
501 /* local QPN:24, rsvd:8 */ 499 /* local QPN:24, rsvd:8 */
502 u32 offset12; 500 __be32 offset12;
503 /* local EECN:24, rsvd:8 */ 501 /* local EECN:24, rsvd:8 */
504 u32 offset16; 502 __be32 offset16;
505 /* starting PSN:24 rsvd:8 */ 503 /* starting PSN:24 rsvd:8 */
506 u32 offset20; 504 __be32 offset20;
507 u8 resp_resources; 505 u8 resp_resources;
508 u8 initiator_depth; 506 u8 initiator_depth;
509 /* target ACK delay:5, failover accepted:2, end-to-end flow control:1 */ 507 /* target ACK delay:5, failover accepted:2, end-to-end flow control:1 */
510 u8 offset26; 508 u8 offset26;
511 /* RNR retry count:3, SRQ:1, rsvd:5 */ 509 /* RNR retry count:3, SRQ:1, rsvd:5 */
512 u8 offset27; 510 u8 offset27;
513 u64 local_ca_guid; 511 __be64 local_ca_guid;
514 512
515 u8 private_data[IB_CM_REP_PRIVATE_DATA_SIZE]; 513 u8 private_data[IB_CM_REP_PRIVATE_DATA_SIZE];
516 514
517} __attribute__ ((packed)); 515} __attribute__ ((packed));
518 516
519static inline u32 cm_rep_get_local_qpn(struct cm_rep_msg *rep_msg) 517static inline __be32 cm_rep_get_local_qpn(struct cm_rep_msg *rep_msg)
520{ 518{
521 return cpu_to_be32(be32_to_cpu(rep_msg->offset12) >> 8); 519 return cpu_to_be32(be32_to_cpu(rep_msg->offset12) >> 8);
522} 520}
523 521
524static inline void cm_rep_set_local_qpn(struct cm_rep_msg *rep_msg, u32 qpn) 522static inline void cm_rep_set_local_qpn(struct cm_rep_msg *rep_msg, __be32 qpn)
525{ 523{
526 rep_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) | 524 rep_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
527 (be32_to_cpu(rep_msg->offset12) & 0x000000FF)); 525 (be32_to_cpu(rep_msg->offset12) & 0x000000FF));
528} 526}
529 527
530static inline u32 cm_rep_get_starting_psn(struct cm_rep_msg *rep_msg) 528static inline __be32 cm_rep_get_starting_psn(struct cm_rep_msg *rep_msg)
531{ 529{
532 return cpu_to_be32(be32_to_cpu(rep_msg->offset20) >> 8); 530 return cpu_to_be32(be32_to_cpu(rep_msg->offset20) >> 8);
533} 531}
534 532
535static inline void cm_rep_set_starting_psn(struct cm_rep_msg *rep_msg, 533static inline void cm_rep_set_starting_psn(struct cm_rep_msg *rep_msg,
536 u32 starting_psn) 534 __be32 starting_psn)
537{ 535{
538 rep_msg->offset20 = cpu_to_be32((be32_to_cpu(starting_psn) << 8) | 536 rep_msg->offset20 = cpu_to_be32((be32_to_cpu(starting_psn) << 8) |
539 (be32_to_cpu(rep_msg->offset20) & 0x000000FF)); 537 (be32_to_cpu(rep_msg->offset20) & 0x000000FF));
@@ -600,8 +598,8 @@ static inline void cm_rep_set_srq(struct cm_rep_msg *rep_msg, u8 srq)
600struct cm_rtu_msg { 598struct cm_rtu_msg {
601 struct ib_mad_hdr hdr; 599 struct ib_mad_hdr hdr;
602 600
603 u32 local_comm_id; 601 __be32 local_comm_id;
604 u32 remote_comm_id; 602 __be32 remote_comm_id;
605 603
606 u8 private_data[IB_CM_RTU_PRIVATE_DATA_SIZE]; 604 u8 private_data[IB_CM_RTU_PRIVATE_DATA_SIZE];
607 605
@@ -610,21 +608,21 @@ struct cm_rtu_msg {
610struct cm_dreq_msg { 608struct cm_dreq_msg {
611 struct ib_mad_hdr hdr; 609 struct ib_mad_hdr hdr;
612 610
613 u32 local_comm_id; 611 __be32 local_comm_id;
614 u32 remote_comm_id; 612 __be32 remote_comm_id;
615 /* remote QPN/EECN:24, rsvd:8 */ 613 /* remote QPN/EECN:24, rsvd:8 */
616 u32 offset8; 614 __be32 offset8;
617 615
618 u8 private_data[IB_CM_DREQ_PRIVATE_DATA_SIZE]; 616 u8 private_data[IB_CM_DREQ_PRIVATE_DATA_SIZE];
619 617
620} __attribute__ ((packed)); 618} __attribute__ ((packed));
621 619
622static inline u32 cm_dreq_get_remote_qpn(struct cm_dreq_msg *dreq_msg) 620static inline __be32 cm_dreq_get_remote_qpn(struct cm_dreq_msg *dreq_msg)
623{ 621{
624 return cpu_to_be32(be32_to_cpu(dreq_msg->offset8) >> 8); 622 return cpu_to_be32(be32_to_cpu(dreq_msg->offset8) >> 8);
625} 623}
626 624
627static inline void cm_dreq_set_remote_qpn(struct cm_dreq_msg *dreq_msg, u32 qpn) 625static inline void cm_dreq_set_remote_qpn(struct cm_dreq_msg *dreq_msg, __be32 qpn)
628{ 626{
629 dreq_msg->offset8 = cpu_to_be32((be32_to_cpu(qpn) << 8) | 627 dreq_msg->offset8 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
630 (be32_to_cpu(dreq_msg->offset8) & 0x000000FF)); 628 (be32_to_cpu(dreq_msg->offset8) & 0x000000FF));
@@ -633,8 +631,8 @@ static inline void cm_dreq_set_remote_qpn(struct cm_dreq_msg *dreq_msg, u32 qpn)
633struct cm_drep_msg { 631struct cm_drep_msg {
634 struct ib_mad_hdr hdr; 632 struct ib_mad_hdr hdr;
635 633
636 u32 local_comm_id; 634 __be32 local_comm_id;
637 u32 remote_comm_id; 635 __be32 remote_comm_id;
638 636
639 u8 private_data[IB_CM_DREP_PRIVATE_DATA_SIZE]; 637 u8 private_data[IB_CM_DREP_PRIVATE_DATA_SIZE];
640 638
@@ -643,37 +641,37 @@ struct cm_drep_msg {
643struct cm_lap_msg { 641struct cm_lap_msg {
644 struct ib_mad_hdr hdr; 642 struct ib_mad_hdr hdr;
645 643
646 u32 local_comm_id; 644 __be32 local_comm_id;
647 u32 remote_comm_id; 645 __be32 remote_comm_id;
648 646
649 u32 rsvd8; 647 __be32 rsvd8;
650 /* remote QPN/EECN:24, remote CM response timeout:5, rsvd:3 */ 648 /* remote QPN/EECN:24, remote CM response timeout:5, rsvd:3 */
651 u32 offset12; 649 __be32 offset12;
652 u32 rsvd16; 650 __be32 rsvd16;
653 651
654 u16 alt_local_lid; 652 __be16 alt_local_lid;
655 u16 alt_remote_lid; 653 __be16 alt_remote_lid;
656 union ib_gid alt_local_gid; 654 union ib_gid alt_local_gid;
657 union ib_gid alt_remote_gid; 655 union ib_gid alt_remote_gid;
658 /* flow label:20, rsvd:4, traffic class:8 */ 656 /* flow label:20, rsvd:4, traffic class:8 */
659 u32 offset56; 657 __be32 offset56;
660 u8 alt_hop_limit; 658 u8 alt_hop_limit;
661 /* rsvd:2, packet rate:6 */ 659 /* rsvd:2, packet rate:6 */
662 uint8_t offset61; 660 u8 offset61;
663 /* SL:4, subnet local:1, rsvd:3 */ 661 /* SL:4, subnet local:1, rsvd:3 */
664 uint8_t offset62; 662 u8 offset62;
665 /* local ACK timeout:5, rsvd:3 */ 663 /* local ACK timeout:5, rsvd:3 */
666 uint8_t offset63; 664 u8 offset63;
667 665
668 u8 private_data[IB_CM_LAP_PRIVATE_DATA_SIZE]; 666 u8 private_data[IB_CM_LAP_PRIVATE_DATA_SIZE];
669} __attribute__ ((packed)); 667} __attribute__ ((packed));
670 668
671static inline u32 cm_lap_get_remote_qpn(struct cm_lap_msg *lap_msg) 669static inline __be32 cm_lap_get_remote_qpn(struct cm_lap_msg *lap_msg)
672{ 670{
673 return cpu_to_be32(be32_to_cpu(lap_msg->offset12) >> 8); 671 return cpu_to_be32(be32_to_cpu(lap_msg->offset12) >> 8);
674} 672}
675 673
676static inline void cm_lap_set_remote_qpn(struct cm_lap_msg *lap_msg, u32 qpn) 674static inline void cm_lap_set_remote_qpn(struct cm_lap_msg *lap_msg, __be32 qpn)
677{ 675{
678 lap_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) | 676 lap_msg->offset12 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
679 (be32_to_cpu(lap_msg->offset12) & 677 (be32_to_cpu(lap_msg->offset12) &
@@ -693,17 +691,17 @@ static inline void cm_lap_set_remote_resp_timeout(struct cm_lap_msg *lap_msg,
693 0xFFFFFF07)); 691 0xFFFFFF07));
694} 692}
695 693
696static inline u32 cm_lap_get_flow_label(struct cm_lap_msg *lap_msg) 694static inline __be32 cm_lap_get_flow_label(struct cm_lap_msg *lap_msg)
697{ 695{
698 return be32_to_cpu(lap_msg->offset56) >> 12; 696 return cpu_to_be32(be32_to_cpu(lap_msg->offset56) >> 12);
699} 697}
700 698
701static inline void cm_lap_set_flow_label(struct cm_lap_msg *lap_msg, 699static inline void cm_lap_set_flow_label(struct cm_lap_msg *lap_msg,
702 u32 flow_label) 700 __be32 flow_label)
703{ 701{
704 lap_msg->offset56 = cpu_to_be32((flow_label << 12) | 702 lap_msg->offset56 = cpu_to_be32(
705 (be32_to_cpu(lap_msg->offset56) & 703 (be32_to_cpu(lap_msg->offset56) & 0x00000FFF) |
706 0x00000FFF)); 704 (be32_to_cpu(flow_label) << 12));
707} 705}
708 706
709static inline u8 cm_lap_get_traffic_class(struct cm_lap_msg *lap_msg) 707static inline u8 cm_lap_get_traffic_class(struct cm_lap_msg *lap_msg)
@@ -766,8 +764,8 @@ static inline void cm_lap_set_local_ack_timeout(struct cm_lap_msg *lap_msg,
766struct cm_apr_msg { 764struct cm_apr_msg {
767 struct ib_mad_hdr hdr; 765 struct ib_mad_hdr hdr;
768 766
769 u32 local_comm_id; 767 __be32 local_comm_id;
770 u32 remote_comm_id; 768 __be32 remote_comm_id;
771 769
772 u8 info_length; 770 u8 info_length;
773 u8 ap_status; 771 u8 ap_status;
@@ -779,10 +777,10 @@ struct cm_apr_msg {
779struct cm_sidr_req_msg { 777struct cm_sidr_req_msg {
780 struct ib_mad_hdr hdr; 778 struct ib_mad_hdr hdr;
781 779
782 u32 request_id; 780 __be32 request_id;
783 u16 pkey; 781 __be16 pkey;
784 u16 rsvd; 782 __be16 rsvd;
785 u64 service_id; 783 __be64 service_id;
786 784
787 u8 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE]; 785 u8 private_data[IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE];
788} __attribute__ ((packed)); 786} __attribute__ ((packed));
@@ -790,26 +788,26 @@ struct cm_sidr_req_msg {
790struct cm_sidr_rep_msg { 788struct cm_sidr_rep_msg {
791 struct ib_mad_hdr hdr; 789 struct ib_mad_hdr hdr;
792 790
793 u32 request_id; 791 __be32 request_id;
794 u8 status; 792 u8 status;
795 u8 info_length; 793 u8 info_length;
796 u16 rsvd; 794 __be16 rsvd;
797 /* QPN:24, rsvd:8 */ 795 /* QPN:24, rsvd:8 */
798 u32 offset8; 796 __be32 offset8;
799 u64 service_id; 797 __be64 service_id;
800 u32 qkey; 798 __be32 qkey;
801 u8 info[IB_CM_SIDR_REP_INFO_LENGTH]; 799 u8 info[IB_CM_SIDR_REP_INFO_LENGTH];
802 800
803 u8 private_data[IB_CM_SIDR_REP_PRIVATE_DATA_SIZE]; 801 u8 private_data[IB_CM_SIDR_REP_PRIVATE_DATA_SIZE];
804} __attribute__ ((packed)); 802} __attribute__ ((packed));
805 803
806static inline u32 cm_sidr_rep_get_qpn(struct cm_sidr_rep_msg *sidr_rep_msg) 804static inline __be32 cm_sidr_rep_get_qpn(struct cm_sidr_rep_msg *sidr_rep_msg)
807{ 805{
808 return cpu_to_be32(be32_to_cpu(sidr_rep_msg->offset8) >> 8); 806 return cpu_to_be32(be32_to_cpu(sidr_rep_msg->offset8) >> 8);
809} 807}
810 808
811static inline void cm_sidr_rep_set_qpn(struct cm_sidr_rep_msg *sidr_rep_msg, 809static inline void cm_sidr_rep_set_qpn(struct cm_sidr_rep_msg *sidr_rep_msg,
812 u32 qpn) 810 __be32 qpn)
813{ 811{
814 sidr_rep_msg->offset8 = cpu_to_be32((be32_to_cpu(qpn) << 8) | 812 sidr_rep_msg->offset8 = cpu_to_be32((be32_to_cpu(qpn) << 8) |
815 (be32_to_cpu(sidr_rep_msg->offset8) & 813 (be32_to_cpu(sidr_rep_msg->offset8) &
diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h
index 797049626ff6..7ad47a4b166b 100644
--- a/drivers/infiniband/core/core_priv.h
+++ b/drivers/infiniband/core/core_priv.h
@@ -38,7 +38,7 @@
38#include <linux/list.h> 38#include <linux/list.h>
39#include <linux/spinlock.h> 39#include <linux/spinlock.h>
40 40
41#include <ib_verbs.h> 41#include <rdma/ib_verbs.h>
42 42
43int ib_device_register_sysfs(struct ib_device *device); 43int ib_device_register_sysfs(struct ib_device *device);
44void ib_device_unregister_sysfs(struct ib_device *device); 44void ib_device_unregister_sysfs(struct ib_device *device);
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 9197e92d708a..d3cf84e01587 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
index 7763b31abba7..d34a6f1c4f4c 100644
--- a/drivers/infiniband/core/fmr_pool.c
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -39,7 +39,7 @@
39#include <linux/jhash.h> 39#include <linux/jhash.h>
40#include <linux/kthread.h> 40#include <linux/kthread.h>
41 41
42#include <ib_fmr_pool.h> 42#include <rdma/ib_fmr_pool.h>
43 43
44#include "core_priv.h" 44#include "core_priv.h"
45 45
@@ -334,6 +334,7 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
334{ 334{
335 struct ib_pool_fmr *fmr; 335 struct ib_pool_fmr *fmr;
336 struct ib_pool_fmr *tmp; 336 struct ib_pool_fmr *tmp;
337 LIST_HEAD(fmr_list);
337 int i; 338 int i;
338 339
339 kthread_stop(pool->thread); 340 kthread_stop(pool->thread);
@@ -341,6 +342,11 @@ void ib_destroy_fmr_pool(struct ib_fmr_pool *pool)
341 342
342 i = 0; 343 i = 0;
343 list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) { 344 list_for_each_entry_safe(fmr, tmp, &pool->free_list, list) {
345 if (fmr->remap_count) {
346 INIT_LIST_HEAD(&fmr_list);
347 list_add_tail(&fmr->fmr->list, &fmr_list);
348 ib_unmap_fmr(&fmr_list);
349 }
344 ib_dealloc_fmr(fmr->fmr); 350 ib_dealloc_fmr(fmr->fmr);
345 list_del(&fmr->list); 351 list_del(&fmr->list);
346 kfree(fmr); 352 kfree(fmr);
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index b97e210ce9c8..a4a4d9c1eef3 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -693,7 +693,8 @@ static int handle_outgoing_dr_smp(struct ib_mad_agent_private *mad_agent_priv,
693 goto out; 693 goto out;
694 } 694 }
695 695
696 build_smp_wc(send_wr->wr_id, smp->dr_slid, send_wr->wr.ud.pkey_index, 696 build_smp_wc(send_wr->wr_id, be16_to_cpu(smp->dr_slid),
697 send_wr->wr.ud.pkey_index,
697 send_wr->wr.ud.port_num, &mad_wc); 698 send_wr->wr.ud.port_num, &mad_wc);
698 699
699 /* No GRH for DR SMP */ 700 /* No GRH for DR SMP */
@@ -1554,7 +1555,7 @@ static int is_data_mad(struct ib_mad_agent_private *mad_agent_priv,
1554} 1555}
1555 1556
1556struct ib_mad_send_wr_private* 1557struct ib_mad_send_wr_private*
1557ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, u64 tid) 1558ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid)
1558{ 1559{
1559 struct ib_mad_send_wr_private *mad_send_wr; 1560 struct ib_mad_send_wr_private *mad_send_wr;
1560 1561
@@ -1597,7 +1598,7 @@ static void ib_mad_complete_recv(struct ib_mad_agent_private *mad_agent_priv,
1597 struct ib_mad_send_wr_private *mad_send_wr; 1598 struct ib_mad_send_wr_private *mad_send_wr;
1598 struct ib_mad_send_wc mad_send_wc; 1599 struct ib_mad_send_wc mad_send_wc;
1599 unsigned long flags; 1600 unsigned long flags;
1600 u64 tid; 1601 __be64 tid;
1601 1602
1602 INIT_LIST_HEAD(&mad_recv_wc->rmpp_list); 1603 INIT_LIST_HEAD(&mad_recv_wc->rmpp_list);
1603 list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list); 1604 list_add(&mad_recv_wc->recv_buf.list, &mad_recv_wc->rmpp_list);
@@ -2165,7 +2166,8 @@ static void local_completions(void *data)
2165 * Defined behavior is to complete response 2166 * Defined behavior is to complete response
2166 * before request 2167 * before request
2167 */ 2168 */
2168 build_smp_wc(local->wr_id, IB_LID_PERMISSIVE, 2169 build_smp_wc(local->wr_id,
2170 be16_to_cpu(IB_LID_PERMISSIVE),
2169 0 /* pkey index */, 2171 0 /* pkey index */,
2170 recv_mad_agent->agent.port_num, &wc); 2172 recv_mad_agent->agent.port_num, &wc);
2171 2173
@@ -2294,7 +2296,7 @@ static void timeout_sends(void *data)
2294 spin_unlock_irqrestore(&mad_agent_priv->lock, flags); 2296 spin_unlock_irqrestore(&mad_agent_priv->lock, flags);
2295} 2297}
2296 2298
2297static void ib_mad_thread_completion_handler(struct ib_cq *cq) 2299static void ib_mad_thread_completion_handler(struct ib_cq *cq, void *arg)
2298{ 2300{
2299 struct ib_mad_port_private *port_priv = cq->cq_context; 2301 struct ib_mad_port_private *port_priv = cq->cq_context;
2300 2302
@@ -2574,8 +2576,7 @@ static int ib_mad_port_open(struct ib_device *device,
2574 2576
2575 cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2; 2577 cq_size = (IB_MAD_QP_SEND_SIZE + IB_MAD_QP_RECV_SIZE) * 2;
2576 port_priv->cq = ib_create_cq(port_priv->device, 2578 port_priv->cq = ib_create_cq(port_priv->device,
2577 (ib_comp_handler) 2579 ib_mad_thread_completion_handler,
2578 ib_mad_thread_completion_handler,
2579 NULL, port_priv, cq_size); 2580 NULL, port_priv, cq_size);
2580 if (IS_ERR(port_priv->cq)) { 2581 if (IS_ERR(port_priv->cq)) {
2581 printk(KERN_ERR PFX "Couldn't create ib_mad CQ\n"); 2582 printk(KERN_ERR PFX "Couldn't create ib_mad CQ\n");
diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h
index 568da10b05ab..f1ba794e0daa 100644
--- a/drivers/infiniband/core/mad_priv.h
+++ b/drivers/infiniband/core/mad_priv.h
@@ -40,8 +40,8 @@
40#include <linux/pci.h> 40#include <linux/pci.h>
41#include <linux/kthread.h> 41#include <linux/kthread.h>
42#include <linux/workqueue.h> 42#include <linux/workqueue.h>
43#include <ib_mad.h> 43#include <rdma/ib_mad.h>
44#include <ib_smi.h> 44#include <rdma/ib_smi.h>
45 45
46 46
47#define PFX "ib_mad: " 47#define PFX "ib_mad: "
@@ -121,7 +121,7 @@ struct ib_mad_send_wr_private {
121 struct ib_send_wr send_wr; 121 struct ib_send_wr send_wr;
122 struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; 122 struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
123 u64 wr_id; /* client WR ID */ 123 u64 wr_id; /* client WR ID */
124 u64 tid; 124 __be64 tid;
125 unsigned long timeout; 125 unsigned long timeout;
126 int retries; 126 int retries;
127 int retry; 127 int retry;
@@ -144,7 +144,7 @@ struct ib_mad_local_private {
144 struct ib_send_wr send_wr; 144 struct ib_send_wr send_wr;
145 struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG]; 145 struct ib_sge sg_list[IB_MAD_SEND_REQ_MAX_SG];
146 u64 wr_id; /* client WR ID */ 146 u64 wr_id; /* client WR ID */
147 u64 tid; 147 __be64 tid;
148}; 148};
149 149
150struct ib_mad_mgmt_method_table { 150struct ib_mad_mgmt_method_table {
@@ -210,7 +210,7 @@ extern kmem_cache_t *ib_mad_cache;
210int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr); 210int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr);
211 211
212struct ib_mad_send_wr_private * 212struct ib_mad_send_wr_private *
213ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, u64 tid); 213ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid);
214 214
215void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, 215void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr,
216 struct ib_mad_send_wc *mad_send_wc); 216 struct ib_mad_send_wc *mad_send_wc);
diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c
index 8f1eb80e421f..43fd805e0265 100644
--- a/drivers/infiniband/core/mad_rmpp.c
+++ b/drivers/infiniband/core/mad_rmpp.c
@@ -61,7 +61,7 @@ struct mad_rmpp_recv {
61 int seg_num; 61 int seg_num;
62 int newwin; 62 int newwin;
63 63
64 u64 tid; 64 __be64 tid;
65 u32 src_qp; 65 u32 src_qp;
66 u16 slid; 66 u16 slid;
67 u8 mgmt_class; 67 u8 mgmt_class;
@@ -100,6 +100,121 @@ void ib_cancel_rmpp_recvs(struct ib_mad_agent_private *agent)
100 } 100 }
101} 101}
102 102
103static int data_offset(u8 mgmt_class)
104{
105 if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
106 return offsetof(struct ib_sa_mad, data);
107 else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
108 (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
109 return offsetof(struct ib_vendor_mad, data);
110 else
111 return offsetof(struct ib_rmpp_mad, data);
112}
113
114static void format_ack(struct ib_rmpp_mad *ack,
115 struct ib_rmpp_mad *data,
116 struct mad_rmpp_recv *rmpp_recv)
117{
118 unsigned long flags;
119
120 memcpy(&ack->mad_hdr, &data->mad_hdr,
121 data_offset(data->mad_hdr.mgmt_class));
122
123 ack->mad_hdr.method ^= IB_MGMT_METHOD_RESP;
124 ack->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ACK;
125 ib_set_rmpp_flags(&ack->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
126
127 spin_lock_irqsave(&rmpp_recv->lock, flags);
128 rmpp_recv->last_ack = rmpp_recv->seg_num;
129 ack->rmpp_hdr.seg_num = cpu_to_be32(rmpp_recv->seg_num);
130 ack->rmpp_hdr.paylen_newwin = cpu_to_be32(rmpp_recv->newwin);
131 spin_unlock_irqrestore(&rmpp_recv->lock, flags);
132}
133
134static void ack_recv(struct mad_rmpp_recv *rmpp_recv,
135 struct ib_mad_recv_wc *recv_wc)
136{
137 struct ib_mad_send_buf *msg;
138 struct ib_send_wr *bad_send_wr;
139 int hdr_len, ret;
140
141 hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr);
142 msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
143 recv_wc->wc->pkey_index, rmpp_recv->ah, 1,
144 hdr_len, sizeof(struct ib_rmpp_mad) - hdr_len,
145 GFP_KERNEL);
146 if (!msg)
147 return;
148
149 format_ack((struct ib_rmpp_mad *) msg->mad,
150 (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv);
151 ret = ib_post_send_mad(&rmpp_recv->agent->agent, &msg->send_wr,
152 &bad_send_wr);
153 if (ret)
154 ib_free_send_mad(msg);
155}
156
157static int alloc_response_msg(struct ib_mad_agent *agent,
158 struct ib_mad_recv_wc *recv_wc,
159 struct ib_mad_send_buf **msg)
160{
161 struct ib_mad_send_buf *m;
162 struct ib_ah *ah;
163 int hdr_len;
164
165 ah = ib_create_ah_from_wc(agent->qp->pd, recv_wc->wc,
166 recv_wc->recv_buf.grh, agent->port_num);
167 if (IS_ERR(ah))
168 return PTR_ERR(ah);
169
170 hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr);
171 m = ib_create_send_mad(agent, recv_wc->wc->src_qp,
172 recv_wc->wc->pkey_index, ah, 1, hdr_len,
173 sizeof(struct ib_rmpp_mad) - hdr_len,
174 GFP_KERNEL);
175 if (IS_ERR(m)) {
176 ib_destroy_ah(ah);
177 return PTR_ERR(m);
178 }
179 *msg = m;
180 return 0;
181}
182
183static void free_msg(struct ib_mad_send_buf *msg)
184{
185 ib_destroy_ah(msg->send_wr.wr.ud.ah);
186 ib_free_send_mad(msg);
187}
188
189static void nack_recv(struct ib_mad_agent_private *agent,
190 struct ib_mad_recv_wc *recv_wc, u8 rmpp_status)
191{
192 struct ib_mad_send_buf *msg;
193 struct ib_rmpp_mad *rmpp_mad;
194 struct ib_send_wr *bad_send_wr;
195 int ret;
196
197 ret = alloc_response_msg(&agent->agent, recv_wc, &msg);
198 if (ret)
199 return;
200
201 rmpp_mad = (struct ib_rmpp_mad *) msg->mad;
202 memcpy(rmpp_mad, recv_wc->recv_buf.mad,
203 data_offset(recv_wc->recv_buf.mad->mad_hdr.mgmt_class));
204
205 rmpp_mad->mad_hdr.method ^= IB_MGMT_METHOD_RESP;
206 rmpp_mad->rmpp_hdr.rmpp_version = IB_MGMT_RMPP_VERSION;
207 rmpp_mad->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ABORT;
208 ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
209 rmpp_mad->rmpp_hdr.rmpp_status = rmpp_status;
210 rmpp_mad->rmpp_hdr.seg_num = 0;
211 rmpp_mad->rmpp_hdr.paylen_newwin = 0;
212
213 ret = ib_post_send_mad(&agent->agent, &msg->send_wr, &bad_send_wr);
214 if (ret)
215 free_msg(msg);
216}
217
103static void recv_timeout_handler(void *data) 218static void recv_timeout_handler(void *data)
104{ 219{
105 struct mad_rmpp_recv *rmpp_recv = data; 220 struct mad_rmpp_recv *rmpp_recv = data;
@@ -115,8 +230,8 @@ static void recv_timeout_handler(void *data)
115 list_del(&rmpp_recv->list); 230 list_del(&rmpp_recv->list);
116 spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags); 231 spin_unlock_irqrestore(&rmpp_recv->agent->lock, flags);
117 232
118 /* TODO: send abort. */
119 rmpp_wc = rmpp_recv->rmpp_wc; 233 rmpp_wc = rmpp_recv->rmpp_wc;
234 nack_recv(rmpp_recv->agent, rmpp_wc, IB_MGMT_RMPP_STATUS_T2L);
120 destroy_rmpp_recv(rmpp_recv); 235 destroy_rmpp_recv(rmpp_recv);
121 ib_free_recv_mad(rmpp_wc); 236 ib_free_recv_mad(rmpp_wc);
122} 237}
@@ -230,60 +345,6 @@ insert_rmpp_recv(struct ib_mad_agent_private *agent,
230 return cur_rmpp_recv; 345 return cur_rmpp_recv;
231} 346}
232 347
233static int data_offset(u8 mgmt_class)
234{
235 if (mgmt_class == IB_MGMT_CLASS_SUBN_ADM)
236 return offsetof(struct ib_sa_mad, data);
237 else if ((mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&
238 (mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END))
239 return offsetof(struct ib_vendor_mad, data);
240 else
241 return offsetof(struct ib_rmpp_mad, data);
242}
243
244static void format_ack(struct ib_rmpp_mad *ack,
245 struct ib_rmpp_mad *data,
246 struct mad_rmpp_recv *rmpp_recv)
247{
248 unsigned long flags;
249
250 memcpy(&ack->mad_hdr, &data->mad_hdr,
251 data_offset(data->mad_hdr.mgmt_class));
252
253 ack->mad_hdr.method ^= IB_MGMT_METHOD_RESP;
254 ack->rmpp_hdr.rmpp_type = IB_MGMT_RMPP_TYPE_ACK;
255 ib_set_rmpp_flags(&ack->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);
256
257 spin_lock_irqsave(&rmpp_recv->lock, flags);
258 rmpp_recv->last_ack = rmpp_recv->seg_num;
259 ack->rmpp_hdr.seg_num = cpu_to_be32(rmpp_recv->seg_num);
260 ack->rmpp_hdr.paylen_newwin = cpu_to_be32(rmpp_recv->newwin);
261 spin_unlock_irqrestore(&rmpp_recv->lock, flags);
262}
263
264static void ack_recv(struct mad_rmpp_recv *rmpp_recv,
265 struct ib_mad_recv_wc *recv_wc)
266{
267 struct ib_mad_send_buf *msg;
268 struct ib_send_wr *bad_send_wr;
269 int hdr_len, ret;
270
271 hdr_len = sizeof(struct ib_mad_hdr) + sizeof(struct ib_rmpp_hdr);
272 msg = ib_create_send_mad(&rmpp_recv->agent->agent, recv_wc->wc->src_qp,
273 recv_wc->wc->pkey_index, rmpp_recv->ah, 1,
274 hdr_len, sizeof(struct ib_rmpp_mad) - hdr_len,
275 GFP_KERNEL);
276 if (!msg)
277 return;
278
279 format_ack((struct ib_rmpp_mad *) msg->mad,
280 (struct ib_rmpp_mad *) recv_wc->recv_buf.mad, rmpp_recv);
281 ret = ib_post_send_mad(&rmpp_recv->agent->agent, &msg->send_wr,
282 &bad_send_wr);
283 if (ret)
284 ib_free_send_mad(msg);
285}
286
287static inline int get_last_flag(struct ib_mad_recv_buf *seg) 348static inline int get_last_flag(struct ib_mad_recv_buf *seg)
288{ 349{
289 struct ib_rmpp_mad *rmpp_mad; 350 struct ib_rmpp_mad *rmpp_mad;
@@ -559,6 +620,34 @@ static int send_next_seg(struct ib_mad_send_wr_private *mad_send_wr)
559 return ib_send_mad(mad_send_wr); 620 return ib_send_mad(mad_send_wr);
560} 621}
561 622
623static void abort_send(struct ib_mad_agent_private *agent, __be64 tid,
624 u8 rmpp_status)
625{
626 struct ib_mad_send_wr_private *mad_send_wr;
627 struct ib_mad_send_wc wc;
628 unsigned long flags;
629
630 spin_lock_irqsave(&agent->lock, flags);
631 mad_send_wr = ib_find_send_mad(agent, tid);
632 if (!mad_send_wr)
633 goto out; /* Unmatched send */
634
635 if ((mad_send_wr->last_ack == mad_send_wr->total_seg) ||
636 (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS))
637 goto out; /* Send is already done */
638
639 ib_mark_mad_done(mad_send_wr);
640 spin_unlock_irqrestore(&agent->lock, flags);
641
642 wc.status = IB_WC_REM_ABORT_ERR;
643 wc.vendor_err = rmpp_status;
644 wc.wr_id = mad_send_wr->wr_id;
645 ib_mad_complete_send_wr(mad_send_wr, &wc);
646 return;
647out:
648 spin_unlock_irqrestore(&agent->lock, flags);
649}
650
562static void process_rmpp_ack(struct ib_mad_agent_private *agent, 651static void process_rmpp_ack(struct ib_mad_agent_private *agent,
563 struct ib_mad_recv_wc *mad_recv_wc) 652 struct ib_mad_recv_wc *mad_recv_wc)
564{ 653{
@@ -568,11 +657,21 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
568 int seg_num, newwin, ret; 657 int seg_num, newwin, ret;
569 658
570 rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad; 659 rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
571 if (rmpp_mad->rmpp_hdr.rmpp_status) 660 if (rmpp_mad->rmpp_hdr.rmpp_status) {
661 abort_send(agent, rmpp_mad->mad_hdr.tid,
662 IB_MGMT_RMPP_STATUS_BAD_STATUS);
663 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
572 return; 664 return;
665 }
573 666
574 seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num); 667 seg_num = be32_to_cpu(rmpp_mad->rmpp_hdr.seg_num);
575 newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin); 668 newwin = be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);
669 if (newwin < seg_num) {
670 abort_send(agent, rmpp_mad->mad_hdr.tid,
671 IB_MGMT_RMPP_STATUS_W2S);
672 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_W2S);
673 return;
674 }
576 675
577 spin_lock_irqsave(&agent->lock, flags); 676 spin_lock_irqsave(&agent->lock, flags);
578 mad_send_wr = ib_find_send_mad(agent, rmpp_mad->mad_hdr.tid); 677 mad_send_wr = ib_find_send_mad(agent, rmpp_mad->mad_hdr.tid);
@@ -583,8 +682,13 @@ static void process_rmpp_ack(struct ib_mad_agent_private *agent,
583 (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS)) 682 (!mad_send_wr->timeout) || (mad_send_wr->status != IB_WC_SUCCESS))
584 goto out; /* Send is already done */ 683 goto out; /* Send is already done */
585 684
586 if (seg_num > mad_send_wr->total_seg) 685 if (seg_num > mad_send_wr->total_seg || seg_num > mad_send_wr->newwin) {
587 goto out; /* Bad ACK */ 686 spin_unlock_irqrestore(&agent->lock, flags);
687 abort_send(agent, rmpp_mad->mad_hdr.tid,
688 IB_MGMT_RMPP_STATUS_S2B);
689 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_S2B);
690 return;
691 }
588 692
589 if (newwin < mad_send_wr->newwin || seg_num < mad_send_wr->last_ack) 693 if (newwin < mad_send_wr->newwin || seg_num < mad_send_wr->last_ack)
590 goto out; /* Old ACK */ 694 goto out; /* Old ACK */
@@ -628,6 +732,72 @@ out:
628 spin_unlock_irqrestore(&agent->lock, flags); 732 spin_unlock_irqrestore(&agent->lock, flags);
629} 733}
630 734
735static struct ib_mad_recv_wc *
736process_rmpp_data(struct ib_mad_agent_private *agent,
737 struct ib_mad_recv_wc *mad_recv_wc)
738{
739 struct ib_rmpp_hdr *rmpp_hdr;
740 u8 rmpp_status;
741
742 rmpp_hdr = &((struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad)->rmpp_hdr;
743
744 if (rmpp_hdr->rmpp_status) {
745 rmpp_status = IB_MGMT_RMPP_STATUS_BAD_STATUS;
746 goto bad;
747 }
748
749 if (rmpp_hdr->seg_num == __constant_htonl(1)) {
750 if (!(ib_get_rmpp_flags(rmpp_hdr) & IB_MGMT_RMPP_FLAG_FIRST)) {
751 rmpp_status = IB_MGMT_RMPP_STATUS_BAD_SEG;
752 goto bad;
753 }
754 return start_rmpp(agent, mad_recv_wc);
755 } else {
756 if (ib_get_rmpp_flags(rmpp_hdr) & IB_MGMT_RMPP_FLAG_FIRST) {
757 rmpp_status = IB_MGMT_RMPP_STATUS_BAD_SEG;
758 goto bad;
759 }
760 return continue_rmpp(agent, mad_recv_wc);
761 }
762bad:
763 nack_recv(agent, mad_recv_wc, rmpp_status);
764 ib_free_recv_mad(mad_recv_wc);
765 return NULL;
766}
767
768static void process_rmpp_stop(struct ib_mad_agent_private *agent,
769 struct ib_mad_recv_wc *mad_recv_wc)
770{
771 struct ib_rmpp_mad *rmpp_mad;
772
773 rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
774
775 if (rmpp_mad->rmpp_hdr.rmpp_status != IB_MGMT_RMPP_STATUS_RESX) {
776 abort_send(agent, rmpp_mad->mad_hdr.tid,
777 IB_MGMT_RMPP_STATUS_BAD_STATUS);
778 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
779 } else
780 abort_send(agent, rmpp_mad->mad_hdr.tid,
781 rmpp_mad->rmpp_hdr.rmpp_status);
782}
783
784static void process_rmpp_abort(struct ib_mad_agent_private *agent,
785 struct ib_mad_recv_wc *mad_recv_wc)
786{
787 struct ib_rmpp_mad *rmpp_mad;
788
789 rmpp_mad = (struct ib_rmpp_mad *)mad_recv_wc->recv_buf.mad;
790
791 if (rmpp_mad->rmpp_hdr.rmpp_status < IB_MGMT_RMPP_STATUS_ABORT_MIN ||
792 rmpp_mad->rmpp_hdr.rmpp_status > IB_MGMT_RMPP_STATUS_ABORT_MAX) {
793 abort_send(agent, rmpp_mad->mad_hdr.tid,
794 IB_MGMT_RMPP_STATUS_BAD_STATUS);
795 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BAD_STATUS);
796 } else
797 abort_send(agent, rmpp_mad->mad_hdr.tid,
798 rmpp_mad->rmpp_hdr.rmpp_status);
799}
800
631struct ib_mad_recv_wc * 801struct ib_mad_recv_wc *
632ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent, 802ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent,
633 struct ib_mad_recv_wc *mad_recv_wc) 803 struct ib_mad_recv_wc *mad_recv_wc)
@@ -638,23 +808,29 @@ ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent,
638 if (!(rmpp_mad->rmpp_hdr.rmpp_rtime_flags & IB_MGMT_RMPP_FLAG_ACTIVE)) 808 if (!(rmpp_mad->rmpp_hdr.rmpp_rtime_flags & IB_MGMT_RMPP_FLAG_ACTIVE))
639 return mad_recv_wc; 809 return mad_recv_wc;
640 810
641 if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) 811 if (rmpp_mad->rmpp_hdr.rmpp_version != IB_MGMT_RMPP_VERSION) {
812 abort_send(agent, rmpp_mad->mad_hdr.tid,
813 IB_MGMT_RMPP_STATUS_UNV);
814 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_UNV);
642 goto out; 815 goto out;
816 }
643 817
644 switch (rmpp_mad->rmpp_hdr.rmpp_type) { 818 switch (rmpp_mad->rmpp_hdr.rmpp_type) {
645 case IB_MGMT_RMPP_TYPE_DATA: 819 case IB_MGMT_RMPP_TYPE_DATA:
646 if (rmpp_mad->rmpp_hdr.seg_num == __constant_htonl(1)) 820 return process_rmpp_data(agent, mad_recv_wc);
647 return start_rmpp(agent, mad_recv_wc);
648 else
649 return continue_rmpp(agent, mad_recv_wc);
650 case IB_MGMT_RMPP_TYPE_ACK: 821 case IB_MGMT_RMPP_TYPE_ACK:
651 process_rmpp_ack(agent, mad_recv_wc); 822 process_rmpp_ack(agent, mad_recv_wc);
652 break; 823 break;
653 case IB_MGMT_RMPP_TYPE_STOP: 824 case IB_MGMT_RMPP_TYPE_STOP:
825 process_rmpp_stop(agent, mad_recv_wc);
826 break;
654 case IB_MGMT_RMPP_TYPE_ABORT: 827 case IB_MGMT_RMPP_TYPE_ABORT:
655 /* TODO: process_rmpp_nack(agent, mad_recv_wc); */ 828 process_rmpp_abort(agent, mad_recv_wc);
656 break; 829 break;
657 default: 830 default:
831 abort_send(agent, rmpp_mad->mad_hdr.tid,
832 IB_MGMT_RMPP_STATUS_BADT);
833 nack_recv(agent, mad_recv_wc, IB_MGMT_RMPP_STATUS_BADT);
658 break; 834 break;
659 } 835 }
660out: 836out:
@@ -714,7 +890,10 @@ int ib_process_rmpp_send_wc(struct ib_mad_send_wr_private *mad_send_wr,
714 if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) { 890 if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_DATA) {
715 msg = (struct ib_mad_send_buf *) (unsigned long) 891 msg = (struct ib_mad_send_buf *) (unsigned long)
716 mad_send_wc->wr_id; 892 mad_send_wc->wr_id;
717 ib_free_send_mad(msg); 893 if (rmpp_mad->rmpp_hdr.rmpp_type == IB_MGMT_RMPP_TYPE_ACK)
894 ib_free_send_mad(msg);
895 else
896 free_msg(msg);
718 return IB_RMPP_RESULT_INTERNAL; /* ACK, STOP, or ABORT */ 897 return IB_RMPP_RESULT_INTERNAL; /* ACK, STOP, or ABORT */
719 } 898 }
720 899
diff --git a/drivers/infiniband/core/packer.c b/drivers/infiniband/core/packer.c
index eb5ff54c10d7..35df5010e723 100644
--- a/drivers/infiniband/core/packer.c
+++ b/drivers/infiniband/core/packer.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 2 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -32,7 +33,7 @@
32 * $Id: packer.c 1349 2004-12-16 21:09:43Z roland $ 33 * $Id: packer.c 1349 2004-12-16 21:09:43Z roland $
33 */ 34 */
34 35
35#include <ib_pack.h> 36#include <rdma/ib_pack.h>
36 37
37static u64 value_read(int offset, int size, void *structure) 38static u64 value_read(int offset, int size, void *structure)
38{ 39{
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index 795184931c83..126ac80db7b8 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
4 * 4 *
5 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -44,8 +44,8 @@
44#include <linux/kref.h> 44#include <linux/kref.h>
45#include <linux/idr.h> 45#include <linux/idr.h>
46 46
47#include <ib_pack.h> 47#include <rdma/ib_pack.h>
48#include <ib_sa.h> 48#include <rdma/ib_sa.h>
49 49
50MODULE_AUTHOR("Roland Dreier"); 50MODULE_AUTHOR("Roland Dreier");
51MODULE_DESCRIPTION("InfiniBand subnet administration query support"); 51MODULE_DESCRIPTION("InfiniBand subnet administration query support");
diff --git a/drivers/infiniband/core/smi.c b/drivers/infiniband/core/smi.c
index b4b284324a33..35852e794e26 100644
--- a/drivers/infiniband/core/smi.c
+++ b/drivers/infiniband/core/smi.c
@@ -1,9 +1,10 @@
1/* 1/*
2 * Copyright (c) 2004 Mellanox Technologies Ltd. All rights reserved. 2 * Copyright (c) 2004, 2005 Mellanox Technologies Ltd. All rights reserved.
3 * Copyright (c) 2004 Infinicon Corporation. All rights reserved. 3 * Copyright (c) 2004, 2005 Infinicon Corporation. All rights reserved.
4 * Copyright (c) 2004 Intel Corporation. All rights reserved. 4 * Copyright (c) 2004, 2005 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 5 * Copyright (c) 2004, 2005 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved. 6 * Copyright (c) 2004, 2005 Voltaire Corporation. All rights reserved.
7 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
7 * 8 *
8 * This software is available to you under a choice of one of two 9 * This software is available to you under a choice of one of two
9 * licenses. You may choose to be licensed under the terms of the GNU 10 * licenses. You may choose to be licensed under the terms of the GNU
@@ -36,7 +37,7 @@
36 * $Id: smi.c 1389 2004-12-27 22:56:47Z roland $ 37 * $Id: smi.c 1389 2004-12-27 22:56:47Z roland $
37 */ 38 */
38 39
39#include <ib_smi.h> 40#include <rdma/ib_smi.h>
40#include "smi.h" 41#include "smi.h"
41 42
42/* 43/*
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 90d51b179abe..fae1c2dcee51 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -1,5 +1,7 @@
1/* 1/*
2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Mellanox Technologies Ltd. All rights reserved.
4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
3 * 5 *
4 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
@@ -34,7 +36,7 @@
34 36
35#include "core_priv.h" 37#include "core_priv.h"
36 38
37#include <ib_mad.h> 39#include <rdma/ib_mad.h>
38 40
39struct ib_port { 41struct ib_port {
40 struct kobject kobj; 42 struct kobject kobj;
@@ -253,14 +255,14 @@ static ssize_t show_port_gid(struct ib_port *p, struct port_attribute *attr,
253 return ret; 255 return ret;
254 256
255 return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n", 257 return sprintf(buf, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
256 be16_to_cpu(((u16 *) gid.raw)[0]), 258 be16_to_cpu(((__be16 *) gid.raw)[0]),
257 be16_to_cpu(((u16 *) gid.raw)[1]), 259 be16_to_cpu(((__be16 *) gid.raw)[1]),
258 be16_to_cpu(((u16 *) gid.raw)[2]), 260 be16_to_cpu(((__be16 *) gid.raw)[2]),
259 be16_to_cpu(((u16 *) gid.raw)[3]), 261 be16_to_cpu(((__be16 *) gid.raw)[3]),
260 be16_to_cpu(((u16 *) gid.raw)[4]), 262 be16_to_cpu(((__be16 *) gid.raw)[4]),
261 be16_to_cpu(((u16 *) gid.raw)[5]), 263 be16_to_cpu(((__be16 *) gid.raw)[5]),
262 be16_to_cpu(((u16 *) gid.raw)[6]), 264 be16_to_cpu(((__be16 *) gid.raw)[6]),
263 be16_to_cpu(((u16 *) gid.raw)[7])); 265 be16_to_cpu(((__be16 *) gid.raw)[7]));
264} 266}
265 267
266static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr, 268static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr,
@@ -332,11 +334,11 @@ static ssize_t show_pma_counter(struct ib_port *p, struct port_attribute *attr,
332 break; 334 break;
333 case 16: 335 case 16:
334 ret = sprintf(buf, "%u\n", 336 ret = sprintf(buf, "%u\n",
335 be16_to_cpup((u16 *)(out_mad->data + 40 + offset / 8))); 337 be16_to_cpup((__be16 *)(out_mad->data + 40 + offset / 8)));
336 break; 338 break;
337 case 32: 339 case 32:
338 ret = sprintf(buf, "%u\n", 340 ret = sprintf(buf, "%u\n",
339 be32_to_cpup((u32 *)(out_mad->data + 40 + offset / 8))); 341 be32_to_cpup((__be32 *)(out_mad->data + 40 + offset / 8)));
340 break; 342 break;
341 default: 343 default:
342 ret = 0; 344 ret = 0;
@@ -598,10 +600,10 @@ static ssize_t show_sys_image_guid(struct class_device *cdev, char *buf)
598 return ret; 600 return ret;
599 601
600 return sprintf(buf, "%04x:%04x:%04x:%04x\n", 602 return sprintf(buf, "%04x:%04x:%04x:%04x\n",
601 be16_to_cpu(((u16 *) &attr.sys_image_guid)[0]), 603 be16_to_cpu(((__be16 *) &attr.sys_image_guid)[0]),
602 be16_to_cpu(((u16 *) &attr.sys_image_guid)[1]), 604 be16_to_cpu(((__be16 *) &attr.sys_image_guid)[1]),
603 be16_to_cpu(((u16 *) &attr.sys_image_guid)[2]), 605 be16_to_cpu(((__be16 *) &attr.sys_image_guid)[2]),
604 be16_to_cpu(((u16 *) &attr.sys_image_guid)[3])); 606 be16_to_cpu(((__be16 *) &attr.sys_image_guid)[3]));
605} 607}
606 608
607static ssize_t show_node_guid(struct class_device *cdev, char *buf) 609static ssize_t show_node_guid(struct class_device *cdev, char *buf)
@@ -615,10 +617,10 @@ static ssize_t show_node_guid(struct class_device *cdev, char *buf)
615 return ret; 617 return ret;
616 618
617 return sprintf(buf, "%04x:%04x:%04x:%04x\n", 619 return sprintf(buf, "%04x:%04x:%04x:%04x\n",
618 be16_to_cpu(((u16 *) &attr.node_guid)[0]), 620 be16_to_cpu(((__be16 *) &attr.node_guid)[0]),
619 be16_to_cpu(((u16 *) &attr.node_guid)[1]), 621 be16_to_cpu(((__be16 *) &attr.node_guid)[1]),
620 be16_to_cpu(((u16 *) &attr.node_guid)[2]), 622 be16_to_cpu(((__be16 *) &attr.node_guid)[2]),
621 be16_to_cpu(((u16 *) &attr.node_guid)[3])); 623 be16_to_cpu(((__be16 *) &attr.node_guid)[3]));
622} 624}
623 625
624static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); 626static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL);
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index 61d07c732f49..79595826ccc7 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Intel Corporation. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -73,14 +74,18 @@ static struct semaphore ctx_id_mutex;
73static struct idr ctx_id_table; 74static struct idr ctx_id_table;
74static int ctx_id_rover = 0; 75static int ctx_id_rover = 0;
75 76
76static struct ib_ucm_context *ib_ucm_ctx_get(int id) 77static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id)
77{ 78{
78 struct ib_ucm_context *ctx; 79 struct ib_ucm_context *ctx;
79 80
80 down(&ctx_id_mutex); 81 down(&ctx_id_mutex);
81 ctx = idr_find(&ctx_id_table, id); 82 ctx = idr_find(&ctx_id_table, id);
82 if (ctx) 83 if (!ctx)
83 ctx->ref++; 84 ctx = ERR_PTR(-ENOENT);
85 else if (ctx->file != file)
86 ctx = ERR_PTR(-EINVAL);
87 else
88 atomic_inc(&ctx->ref);
84 up(&ctx_id_mutex); 89 up(&ctx_id_mutex);
85 90
86 return ctx; 91 return ctx;
@@ -88,21 +93,37 @@ static struct ib_ucm_context *ib_ucm_ctx_get(int id)
88 93
89static void ib_ucm_ctx_put(struct ib_ucm_context *ctx) 94static void ib_ucm_ctx_put(struct ib_ucm_context *ctx)
90{ 95{
96 if (atomic_dec_and_test(&ctx->ref))
97 wake_up(&ctx->wait);
98}
99
100static ssize_t ib_ucm_destroy_ctx(struct ib_ucm_file *file, int id)
101{
102 struct ib_ucm_context *ctx;
91 struct ib_ucm_event *uevent; 103 struct ib_ucm_event *uevent;
92 104
93 down(&ctx_id_mutex); 105 down(&ctx_id_mutex);
94 106 ctx = idr_find(&ctx_id_table, id);
95 ctx->ref--; 107 if (!ctx)
96 if (!ctx->ref) 108 ctx = ERR_PTR(-ENOENT);
109 else if (ctx->file != file)
110 ctx = ERR_PTR(-EINVAL);
111 else
97 idr_remove(&ctx_id_table, ctx->id); 112 idr_remove(&ctx_id_table, ctx->id);
98
99 up(&ctx_id_mutex); 113 up(&ctx_id_mutex);
100 114
101 if (ctx->ref) 115 if (IS_ERR(ctx))
102 return; 116 return PTR_ERR(ctx);
103 117
104 down(&ctx->file->mutex); 118 atomic_dec(&ctx->ref);
119 wait_event(ctx->wait, !atomic_read(&ctx->ref));
120
121 /* No new events will be generated after destroying the cm_id. */
122 if (!IS_ERR(ctx->cm_id))
123 ib_destroy_cm_id(ctx->cm_id);
105 124
125 /* Cleanup events not yet reported to the user. */
126 down(&file->mutex);
106 list_del(&ctx->file_list); 127 list_del(&ctx->file_list);
107 while (!list_empty(&ctx->events)) { 128 while (!list_empty(&ctx->events)) {
108 129
@@ -117,13 +138,10 @@ static void ib_ucm_ctx_put(struct ib_ucm_context *ctx)
117 138
118 kfree(uevent); 139 kfree(uevent);
119 } 140 }
141 up(&file->mutex);
120 142
121 up(&ctx->file->mutex);
122
123 ucm_dbg("Destroyed CM ID <%d>\n", ctx->id);
124
125 ib_destroy_cm_id(ctx->cm_id);
126 kfree(ctx); 143 kfree(ctx);
144 return 0;
127} 145}
128 146
129static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) 147static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
@@ -135,11 +153,11 @@ static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file)
135 if (!ctx) 153 if (!ctx)
136 return NULL; 154 return NULL;
137 155
138 ctx->ref = 1; /* user reference */ 156 atomic_set(&ctx->ref, 1);
157 init_waitqueue_head(&ctx->wait);
139 ctx->file = file; 158 ctx->file = file;
140 159
141 INIT_LIST_HEAD(&ctx->events); 160 INIT_LIST_HEAD(&ctx->events);
142 init_MUTEX(&ctx->mutex);
143 161
144 list_add_tail(&ctx->file_list, &file->ctxs); 162 list_add_tail(&ctx->file_list, &file->ctxs);
145 163
@@ -177,8 +195,8 @@ static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath,
177 if (!kpath || !upath) 195 if (!kpath || !upath)
178 return; 196 return;
179 197
180 memcpy(upath->dgid, kpath->dgid.raw, sizeof(union ib_gid)); 198 memcpy(upath->dgid, kpath->dgid.raw, sizeof *upath->dgid);
181 memcpy(upath->sgid, kpath->sgid.raw, sizeof(union ib_gid)); 199 memcpy(upath->sgid, kpath->sgid.raw, sizeof *upath->sgid);
182 200
183 upath->dlid = kpath->dlid; 201 upath->dlid = kpath->dlid;
184 upath->slid = kpath->slid; 202 upath->slid = kpath->slid;
@@ -201,10 +219,11 @@ static void ib_ucm_event_path_get(struct ib_ucm_path_rec *upath,
201 kpath->packet_life_time_selector; 219 kpath->packet_life_time_selector;
202} 220}
203 221
204static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, 222static void ib_ucm_event_req_get(struct ib_ucm_context *ctx,
223 struct ib_ucm_req_event_resp *ureq,
205 struct ib_cm_req_event_param *kreq) 224 struct ib_cm_req_event_param *kreq)
206{ 225{
207 ureq->listen_id = (long)kreq->listen_id->context; 226 ureq->listen_id = ctx->id;
208 227
209 ureq->remote_ca_guid = kreq->remote_ca_guid; 228 ureq->remote_ca_guid = kreq->remote_ca_guid;
210 ureq->remote_qkey = kreq->remote_qkey; 229 ureq->remote_qkey = kreq->remote_qkey;
@@ -240,34 +259,11 @@ static void ib_ucm_event_rep_get(struct ib_ucm_rep_event_resp *urep,
240 urep->srq = krep->srq; 259 urep->srq = krep->srq;
241} 260}
242 261
243static void ib_ucm_event_rej_get(struct ib_ucm_rej_event_resp *urej, 262static void ib_ucm_event_sidr_req_get(struct ib_ucm_context *ctx,
244 struct ib_cm_rej_event_param *krej) 263 struct ib_ucm_sidr_req_event_resp *ureq,
245{
246 urej->reason = krej->reason;
247}
248
249static void ib_ucm_event_mra_get(struct ib_ucm_mra_event_resp *umra,
250 struct ib_cm_mra_event_param *kmra)
251{
252 umra->timeout = kmra->service_timeout;
253}
254
255static void ib_ucm_event_lap_get(struct ib_ucm_lap_event_resp *ulap,
256 struct ib_cm_lap_event_param *klap)
257{
258 ib_ucm_event_path_get(&ulap->path, klap->alternate_path);
259}
260
261static void ib_ucm_event_apr_get(struct ib_ucm_apr_event_resp *uapr,
262 struct ib_cm_apr_event_param *kapr)
263{
264 uapr->status = kapr->ap_status;
265}
266
267static void ib_ucm_event_sidr_req_get(struct ib_ucm_sidr_req_event_resp *ureq,
268 struct ib_cm_sidr_req_event_param *kreq) 264 struct ib_cm_sidr_req_event_param *kreq)
269{ 265{
270 ureq->listen_id = (long)kreq->listen_id->context; 266 ureq->listen_id = ctx->id;
271 ureq->pkey = kreq->pkey; 267 ureq->pkey = kreq->pkey;
272} 268}
273 269
@@ -279,19 +275,18 @@ static void ib_ucm_event_sidr_rep_get(struct ib_ucm_sidr_rep_event_resp *urep,
279 urep->qpn = krep->qpn; 275 urep->qpn = krep->qpn;
280}; 276};
281 277
282static int ib_ucm_event_process(struct ib_cm_event *evt, 278static int ib_ucm_event_process(struct ib_ucm_context *ctx,
279 struct ib_cm_event *evt,
283 struct ib_ucm_event *uvt) 280 struct ib_ucm_event *uvt)
284{ 281{
285 void *info = NULL; 282 void *info = NULL;
286 int result;
287 283
288 switch (evt->event) { 284 switch (evt->event) {
289 case IB_CM_REQ_RECEIVED: 285 case IB_CM_REQ_RECEIVED:
290 ib_ucm_event_req_get(&uvt->resp.u.req_resp, 286 ib_ucm_event_req_get(ctx, &uvt->resp.u.req_resp,
291 &evt->param.req_rcvd); 287 &evt->param.req_rcvd);
292 uvt->data_len = IB_CM_REQ_PRIVATE_DATA_SIZE; 288 uvt->data_len = IB_CM_REQ_PRIVATE_DATA_SIZE;
293 uvt->resp.present |= (evt->param.req_rcvd.primary_path ? 289 uvt->resp.present = IB_UCM_PRES_PRIMARY;
294 IB_UCM_PRES_PRIMARY : 0);
295 uvt->resp.present |= (evt->param.req_rcvd.alternate_path ? 290 uvt->resp.present |= (evt->param.req_rcvd.alternate_path ?
296 IB_UCM_PRES_ALTERNATE : 0); 291 IB_UCM_PRES_ALTERNATE : 0);
297 break; 292 break;
@@ -299,57 +294,46 @@ static int ib_ucm_event_process(struct ib_cm_event *evt,
299 ib_ucm_event_rep_get(&uvt->resp.u.rep_resp, 294 ib_ucm_event_rep_get(&uvt->resp.u.rep_resp,
300 &evt->param.rep_rcvd); 295 &evt->param.rep_rcvd);
301 uvt->data_len = IB_CM_REP_PRIVATE_DATA_SIZE; 296 uvt->data_len = IB_CM_REP_PRIVATE_DATA_SIZE;
302
303 break; 297 break;
304 case IB_CM_RTU_RECEIVED: 298 case IB_CM_RTU_RECEIVED:
305 uvt->data_len = IB_CM_RTU_PRIVATE_DATA_SIZE; 299 uvt->data_len = IB_CM_RTU_PRIVATE_DATA_SIZE;
306 uvt->resp.u.send_status = evt->param.send_status; 300 uvt->resp.u.send_status = evt->param.send_status;
307
308 break; 301 break;
309 case IB_CM_DREQ_RECEIVED: 302 case IB_CM_DREQ_RECEIVED:
310 uvt->data_len = IB_CM_DREQ_PRIVATE_DATA_SIZE; 303 uvt->data_len = IB_CM_DREQ_PRIVATE_DATA_SIZE;
311 uvt->resp.u.send_status = evt->param.send_status; 304 uvt->resp.u.send_status = evt->param.send_status;
312
313 break; 305 break;
314 case IB_CM_DREP_RECEIVED: 306 case IB_CM_DREP_RECEIVED:
315 uvt->data_len = IB_CM_DREP_PRIVATE_DATA_SIZE; 307 uvt->data_len = IB_CM_DREP_PRIVATE_DATA_SIZE;
316 uvt->resp.u.send_status = evt->param.send_status; 308 uvt->resp.u.send_status = evt->param.send_status;
317
318 break; 309 break;
319 case IB_CM_MRA_RECEIVED: 310 case IB_CM_MRA_RECEIVED:
320 ib_ucm_event_mra_get(&uvt->resp.u.mra_resp, 311 uvt->resp.u.mra_resp.timeout =
321 &evt->param.mra_rcvd); 312 evt->param.mra_rcvd.service_timeout;
322 uvt->data_len = IB_CM_MRA_PRIVATE_DATA_SIZE; 313 uvt->data_len = IB_CM_MRA_PRIVATE_DATA_SIZE;
323
324 break; 314 break;
325 case IB_CM_REJ_RECEIVED: 315 case IB_CM_REJ_RECEIVED:
326 ib_ucm_event_rej_get(&uvt->resp.u.rej_resp, 316 uvt->resp.u.rej_resp.reason = evt->param.rej_rcvd.reason;
327 &evt->param.rej_rcvd);
328 uvt->data_len = IB_CM_REJ_PRIVATE_DATA_SIZE; 317 uvt->data_len = IB_CM_REJ_PRIVATE_DATA_SIZE;
329 uvt->info_len = evt->param.rej_rcvd.ari_length; 318 uvt->info_len = evt->param.rej_rcvd.ari_length;
330 info = evt->param.rej_rcvd.ari; 319 info = evt->param.rej_rcvd.ari;
331
332 break; 320 break;
333 case IB_CM_LAP_RECEIVED: 321 case IB_CM_LAP_RECEIVED:
334 ib_ucm_event_lap_get(&uvt->resp.u.lap_resp, 322 ib_ucm_event_path_get(&uvt->resp.u.lap_resp.path,
335 &evt->param.lap_rcvd); 323 evt->param.lap_rcvd.alternate_path);
336 uvt->data_len = IB_CM_LAP_PRIVATE_DATA_SIZE; 324 uvt->data_len = IB_CM_LAP_PRIVATE_DATA_SIZE;
337 uvt->resp.present |= (evt->param.lap_rcvd.alternate_path ? 325 uvt->resp.present = IB_UCM_PRES_ALTERNATE;
338 IB_UCM_PRES_ALTERNATE : 0);
339 break; 326 break;
340 case IB_CM_APR_RECEIVED: 327 case IB_CM_APR_RECEIVED:
341 ib_ucm_event_apr_get(&uvt->resp.u.apr_resp, 328 uvt->resp.u.apr_resp.status = evt->param.apr_rcvd.ap_status;
342 &evt->param.apr_rcvd);
343 uvt->data_len = IB_CM_APR_PRIVATE_DATA_SIZE; 329 uvt->data_len = IB_CM_APR_PRIVATE_DATA_SIZE;
344 uvt->info_len = evt->param.apr_rcvd.info_len; 330 uvt->info_len = evt->param.apr_rcvd.info_len;
345 info = evt->param.apr_rcvd.apr_info; 331 info = evt->param.apr_rcvd.apr_info;
346
347 break; 332 break;
348 case IB_CM_SIDR_REQ_RECEIVED: 333 case IB_CM_SIDR_REQ_RECEIVED:
349 ib_ucm_event_sidr_req_get(&uvt->resp.u.sidr_req_resp, 334 ib_ucm_event_sidr_req_get(ctx, &uvt->resp.u.sidr_req_resp,
350 &evt->param.sidr_req_rcvd); 335 &evt->param.sidr_req_rcvd);
351 uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE; 336 uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE;
352
353 break; 337 break;
354 case IB_CM_SIDR_REP_RECEIVED: 338 case IB_CM_SIDR_REP_RECEIVED:
355 ib_ucm_event_sidr_rep_get(&uvt->resp.u.sidr_rep_resp, 339 ib_ucm_event_sidr_rep_get(&uvt->resp.u.sidr_rep_resp,
@@ -357,43 +341,35 @@ static int ib_ucm_event_process(struct ib_cm_event *evt,
357 uvt->data_len = IB_CM_SIDR_REP_PRIVATE_DATA_SIZE; 341 uvt->data_len = IB_CM_SIDR_REP_PRIVATE_DATA_SIZE;
358 uvt->info_len = evt->param.sidr_rep_rcvd.info_len; 342 uvt->info_len = evt->param.sidr_rep_rcvd.info_len;
359 info = evt->param.sidr_rep_rcvd.info; 343 info = evt->param.sidr_rep_rcvd.info;
360
361 break; 344 break;
362 default: 345 default:
363 uvt->resp.u.send_status = evt->param.send_status; 346 uvt->resp.u.send_status = evt->param.send_status;
364
365 break; 347 break;
366 } 348 }
367 349
368 if (uvt->data_len && evt->private_data) { 350 if (uvt->data_len) {
369
370 uvt->data = kmalloc(uvt->data_len, GFP_KERNEL); 351 uvt->data = kmalloc(uvt->data_len, GFP_KERNEL);
371 if (!uvt->data) { 352 if (!uvt->data)
372 result = -ENOMEM; 353 goto err1;
373 goto error;
374 }
375 354
376 memcpy(uvt->data, evt->private_data, uvt->data_len); 355 memcpy(uvt->data, evt->private_data, uvt->data_len);
377 uvt->resp.present |= IB_UCM_PRES_DATA; 356 uvt->resp.present |= IB_UCM_PRES_DATA;
378 } 357 }
379 358
380 if (uvt->info_len && info) { 359 if (uvt->info_len) {
381
382 uvt->info = kmalloc(uvt->info_len, GFP_KERNEL); 360 uvt->info = kmalloc(uvt->info_len, GFP_KERNEL);
383 if (!uvt->info) { 361 if (!uvt->info)
384 result = -ENOMEM; 362 goto err2;
385 goto error;
386 }
387 363
388 memcpy(uvt->info, info, uvt->info_len); 364 memcpy(uvt->info, info, uvt->info_len);
389 uvt->resp.present |= IB_UCM_PRES_INFO; 365 uvt->resp.present |= IB_UCM_PRES_INFO;
390 } 366 }
391
392 return 0; 367 return 0;
393error: 368
394 kfree(uvt->info); 369err2:
395 kfree(uvt->data); 370 kfree(uvt->data);
396 return result; 371err1:
372 return -ENOMEM;
397} 373}
398 374
399static int ib_ucm_event_handler(struct ib_cm_id *cm_id, 375static int ib_ucm_event_handler(struct ib_cm_id *cm_id,
@@ -403,63 +379,42 @@ static int ib_ucm_event_handler(struct ib_cm_id *cm_id,
403 struct ib_ucm_context *ctx; 379 struct ib_ucm_context *ctx;
404 int result = 0; 380 int result = 0;
405 int id; 381 int id;
406 /*
407 * lookup correct context based on event type.
408 */
409 switch (event->event) {
410 case IB_CM_REQ_RECEIVED:
411 id = (long)event->param.req_rcvd.listen_id->context;
412 break;
413 case IB_CM_SIDR_REQ_RECEIVED:
414 id = (long)event->param.sidr_req_rcvd.listen_id->context;
415 break;
416 default:
417 id = (long)cm_id->context;
418 break;
419 }
420 382
421 ucm_dbg("Event. CM ID <%d> event <%d>\n", id, event->event); 383 ctx = cm_id->context;
422
423 ctx = ib_ucm_ctx_get(id);
424 if (!ctx)
425 return -ENOENT;
426 384
427 if (event->event == IB_CM_REQ_RECEIVED || 385 if (event->event == IB_CM_REQ_RECEIVED ||
428 event->event == IB_CM_SIDR_REQ_RECEIVED) 386 event->event == IB_CM_SIDR_REQ_RECEIVED)
429 id = IB_UCM_CM_ID_INVALID; 387 id = IB_UCM_CM_ID_INVALID;
388 else
389 id = ctx->id;
430 390
431 uevent = kmalloc(sizeof(*uevent), GFP_KERNEL); 391 uevent = kmalloc(sizeof(*uevent), GFP_KERNEL);
432 if (!uevent) { 392 if (!uevent)
433 result = -ENOMEM; 393 goto err1;
434 goto done;
435 }
436 394
437 memset(uevent, 0, sizeof(*uevent)); 395 memset(uevent, 0, sizeof(*uevent));
438
439 uevent->resp.id = id; 396 uevent->resp.id = id;
440 uevent->resp.event = event->event; 397 uevent->resp.event = event->event;
441 398
442 result = ib_ucm_event_process(event, uevent); 399 result = ib_ucm_event_process(ctx, event, uevent);
443 if (result) 400 if (result)
444 goto done; 401 goto err2;
445 402
446 uevent->ctx = ctx; 403 uevent->ctx = ctx;
447 uevent->cm_id = ((event->event == IB_CM_REQ_RECEIVED || 404 uevent->cm_id = (id == IB_UCM_CM_ID_INVALID) ? cm_id : NULL;
448 event->event == IB_CM_SIDR_REQ_RECEIVED ) ?
449 cm_id : NULL);
450 405
451 down(&ctx->file->mutex); 406 down(&ctx->file->mutex);
452
453 list_add_tail(&uevent->file_list, &ctx->file->events); 407 list_add_tail(&uevent->file_list, &ctx->file->events);
454 list_add_tail(&uevent->ctx_list, &ctx->events); 408 list_add_tail(&uevent->ctx_list, &ctx->events);
455
456 wake_up_interruptible(&ctx->file->poll_wait); 409 wake_up_interruptible(&ctx->file->poll_wait);
457
458 up(&ctx->file->mutex); 410 up(&ctx->file->mutex);
459done: 411 return 0;
460 ctx->error = result; 412
461 ib_ucm_ctx_put(ctx); /* func reference */ 413err2:
462 return result; 414 kfree(uevent);
415err1:
416 /* Destroy new cm_id's */
417 return (id == IB_UCM_CM_ID_INVALID);
463} 418}
464 419
465static ssize_t ib_ucm_event(struct ib_ucm_file *file, 420static ssize_t ib_ucm_event(struct ib_ucm_file *file,
@@ -517,9 +472,8 @@ static ssize_t ib_ucm_event(struct ib_ucm_file *file,
517 goto done; 472 goto done;
518 } 473 }
519 474
520 ctx->cm_id = uevent->cm_id; 475 ctx->cm_id = uevent->cm_id;
521 ctx->cm_id->cm_handler = ib_ucm_event_handler; 476 ctx->cm_id->context = ctx;
522 ctx->cm_id->context = (void *)(unsigned long)ctx->id;
523 477
524 uevent->resp.id = ctx->id; 478 uevent->resp.id = ctx->id;
525 479
@@ -585,30 +539,29 @@ static ssize_t ib_ucm_create_id(struct ib_ucm_file *file,
585 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 539 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
586 return -EFAULT; 540 return -EFAULT;
587 541
542 down(&file->mutex);
588 ctx = ib_ucm_ctx_alloc(file); 543 ctx = ib_ucm_ctx_alloc(file);
544 up(&file->mutex);
589 if (!ctx) 545 if (!ctx)
590 return -ENOMEM; 546 return -ENOMEM;
591 547
592 ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler, 548 ctx->cm_id = ib_create_cm_id(ib_ucm_event_handler, ctx);
593 (void *)(unsigned long)ctx->id); 549 if (IS_ERR(ctx->cm_id)) {
594 if (!ctx->cm_id) { 550 result = PTR_ERR(ctx->cm_id);
595 result = -ENOMEM; 551 goto err;
596 goto err_cm;
597 } 552 }
598 553
599 resp.id = ctx->id; 554 resp.id = ctx->id;
600 if (copy_to_user((void __user *)(unsigned long)cmd.response, 555 if (copy_to_user((void __user *)(unsigned long)cmd.response,
601 &resp, sizeof(resp))) { 556 &resp, sizeof(resp))) {
602 result = -EFAULT; 557 result = -EFAULT;
603 goto err_ret; 558 goto err;
604 } 559 }
605 560
606 return 0; 561 return 0;
607err_ret:
608 ib_destroy_cm_id(ctx->cm_id);
609err_cm:
610 ib_ucm_ctx_put(ctx); /* user reference */
611 562
563err:
564 ib_ucm_destroy_ctx(file, ctx->id);
612 return result; 565 return result;
613} 566}
614 567
@@ -617,19 +570,11 @@ static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file,
617 int in_len, int out_len) 570 int in_len, int out_len)
618{ 571{
619 struct ib_ucm_destroy_id cmd; 572 struct ib_ucm_destroy_id cmd;
620 struct ib_ucm_context *ctx;
621 573
622 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 574 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
623 return -EFAULT; 575 return -EFAULT;
624 576
625 ctx = ib_ucm_ctx_get(cmd.id); 577 return ib_ucm_destroy_ctx(file, cmd.id);
626 if (!ctx)
627 return -ENOENT;
628
629 ib_ucm_ctx_put(ctx); /* user reference */
630 ib_ucm_ctx_put(ctx); /* func reference */
631
632 return 0;
633} 578}
634 579
635static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file, 580static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,
@@ -647,15 +592,9 @@ static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,
647 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 592 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
648 return -EFAULT; 593 return -EFAULT;
649 594
650 ctx = ib_ucm_ctx_get(cmd.id); 595 ctx = ib_ucm_ctx_get(file, cmd.id);
651 if (!ctx) 596 if (IS_ERR(ctx))
652 return -ENOENT; 597 return PTR_ERR(ctx);
653
654 down(&ctx->file->mutex);
655 if (ctx->file != file) {
656 result = -EINVAL;
657 goto done;
658 }
659 598
660 resp.service_id = ctx->cm_id->service_id; 599 resp.service_id = ctx->cm_id->service_id;
661 resp.service_mask = ctx->cm_id->service_mask; 600 resp.service_mask = ctx->cm_id->service_mask;
@@ -666,9 +605,7 @@ static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file,
666 &resp, sizeof(resp))) 605 &resp, sizeof(resp)))
667 result = -EFAULT; 606 result = -EFAULT;
668 607
669done: 608 ib_ucm_ctx_put(ctx);
670 up(&ctx->file->mutex);
671 ib_ucm_ctx_put(ctx); /* func reference */
672 return result; 609 return result;
673} 610}
674 611
@@ -683,19 +620,12 @@ static ssize_t ib_ucm_listen(struct ib_ucm_file *file,
683 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 620 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
684 return -EFAULT; 621 return -EFAULT;
685 622
686 ctx = ib_ucm_ctx_get(cmd.id); 623 ctx = ib_ucm_ctx_get(file, cmd.id);
687 if (!ctx) 624 if (IS_ERR(ctx))
688 return -ENOENT; 625 return PTR_ERR(ctx);
689 626
690 down(&ctx->file->mutex); 627 result = ib_cm_listen(ctx->cm_id, cmd.service_id, cmd.service_mask);
691 if (ctx->file != file) 628 ib_ucm_ctx_put(ctx);
692 result = -EINVAL;
693 else
694 result = ib_cm_listen(ctx->cm_id, cmd.service_id,
695 cmd.service_mask);
696
697 up(&ctx->file->mutex);
698 ib_ucm_ctx_put(ctx); /* func reference */
699 return result; 629 return result;
700} 630}
701 631
@@ -710,18 +640,12 @@ static ssize_t ib_ucm_establish(struct ib_ucm_file *file,
710 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 640 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
711 return -EFAULT; 641 return -EFAULT;
712 642
713 ctx = ib_ucm_ctx_get(cmd.id); 643 ctx = ib_ucm_ctx_get(file, cmd.id);
714 if (!ctx) 644 if (IS_ERR(ctx))
715 return -ENOENT; 645 return PTR_ERR(ctx);
716
717 down(&ctx->file->mutex);
718 if (ctx->file != file)
719 result = -EINVAL;
720 else
721 result = ib_cm_establish(ctx->cm_id);
722 646
723 up(&ctx->file->mutex); 647 result = ib_cm_establish(ctx->cm_id);
724 ib_ucm_ctx_put(ctx); /* func reference */ 648 ib_ucm_ctx_put(ctx);
725 return result; 649 return result;
726} 650}
727 651
@@ -768,8 +692,8 @@ static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src)
768 return -EFAULT; 692 return -EFAULT;
769 } 693 }
770 694
771 memcpy(sa_path->dgid.raw, ucm_path.dgid, sizeof(union ib_gid)); 695 memcpy(sa_path->dgid.raw, ucm_path.dgid, sizeof sa_path->dgid);
772 memcpy(sa_path->sgid.raw, ucm_path.sgid, sizeof(union ib_gid)); 696 memcpy(sa_path->sgid.raw, ucm_path.sgid, sizeof sa_path->sgid);
773 697
774 sa_path->dlid = ucm_path.dlid; 698 sa_path->dlid = ucm_path.dlid;
775 sa_path->slid = ucm_path.slid; 699 sa_path->slid = ucm_path.slid;
@@ -839,25 +763,17 @@ static ssize_t ib_ucm_send_req(struct ib_ucm_file *file,
839 param.max_cm_retries = cmd.max_cm_retries; 763 param.max_cm_retries = cmd.max_cm_retries;
840 param.srq = cmd.srq; 764 param.srq = cmd.srq;
841 765
842 ctx = ib_ucm_ctx_get(cmd.id); 766 ctx = ib_ucm_ctx_get(file, cmd.id);
843 if (!ctx) { 767 if (!IS_ERR(ctx)) {
844 result = -ENOENT;
845 goto done;
846 }
847
848 down(&ctx->file->mutex);
849 if (ctx->file != file)
850 result = -EINVAL;
851 else
852 result = ib_send_cm_req(ctx->cm_id, &param); 768 result = ib_send_cm_req(ctx->cm_id, &param);
769 ib_ucm_ctx_put(ctx);
770 } else
771 result = PTR_ERR(ctx);
853 772
854 up(&ctx->file->mutex);
855 ib_ucm_ctx_put(ctx); /* func reference */
856done: 773done:
857 kfree(param.private_data); 774 kfree(param.private_data);
858 kfree(param.primary_path); 775 kfree(param.primary_path);
859 kfree(param.alternate_path); 776 kfree(param.alternate_path);
860
861 return result; 777 return result;
862} 778}
863 779
@@ -890,23 +806,14 @@ static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file,
890 param.rnr_retry_count = cmd.rnr_retry_count; 806 param.rnr_retry_count = cmd.rnr_retry_count;
891 param.srq = cmd.srq; 807 param.srq = cmd.srq;
892 808
893 ctx = ib_ucm_ctx_get(cmd.id); 809 ctx = ib_ucm_ctx_get(file, cmd.id);
894 if (!ctx) { 810 if (!IS_ERR(ctx)) {
895 result = -ENOENT;
896 goto done;
897 }
898
899 down(&ctx->file->mutex);
900 if (ctx->file != file)
901 result = -EINVAL;
902 else
903 result = ib_send_cm_rep(ctx->cm_id, &param); 811 result = ib_send_cm_rep(ctx->cm_id, &param);
812 ib_ucm_ctx_put(ctx);
813 } else
814 result = PTR_ERR(ctx);
904 815
905 up(&ctx->file->mutex);
906 ib_ucm_ctx_put(ctx); /* func reference */
907done:
908 kfree(param.private_data); 816 kfree(param.private_data);
909
910 return result; 817 return result;
911} 818}
912 819
@@ -928,23 +835,14 @@ static ssize_t ib_ucm_send_private_data(struct ib_ucm_file *file,
928 if (result) 835 if (result)
929 return result; 836 return result;
930 837
931 ctx = ib_ucm_ctx_get(cmd.id); 838 ctx = ib_ucm_ctx_get(file, cmd.id);
932 if (!ctx) { 839 if (!IS_ERR(ctx)) {
933 result = -ENOENT;
934 goto done;
935 }
936
937 down(&ctx->file->mutex);
938 if (ctx->file != file)
939 result = -EINVAL;
940 else
941 result = func(ctx->cm_id, private_data, cmd.len); 840 result = func(ctx->cm_id, private_data, cmd.len);
841 ib_ucm_ctx_put(ctx);
842 } else
843 result = PTR_ERR(ctx);
942 844
943 up(&ctx->file->mutex);
944 ib_ucm_ctx_put(ctx); /* func reference */
945done:
946 kfree(private_data); 845 kfree(private_data);
947
948 return result; 846 return result;
949} 847}
950 848
@@ -995,26 +893,17 @@ static ssize_t ib_ucm_send_info(struct ib_ucm_file *file,
995 if (result) 893 if (result)
996 goto done; 894 goto done;
997 895
998 ctx = ib_ucm_ctx_get(cmd.id); 896 ctx = ib_ucm_ctx_get(file, cmd.id);
999 if (!ctx) { 897 if (!IS_ERR(ctx)) {
1000 result = -ENOENT; 898 result = func(ctx->cm_id, cmd.status, info, cmd.info_len,
1001 goto done;
1002 }
1003
1004 down(&ctx->file->mutex);
1005 if (ctx->file != file)
1006 result = -EINVAL;
1007 else
1008 result = func(ctx->cm_id, cmd.status,
1009 info, cmd.info_len,
1010 data, cmd.data_len); 899 data, cmd.data_len);
900 ib_ucm_ctx_put(ctx);
901 } else
902 result = PTR_ERR(ctx);
1011 903
1012 up(&ctx->file->mutex);
1013 ib_ucm_ctx_put(ctx); /* func reference */
1014done: 904done:
1015 kfree(data); 905 kfree(data);
1016 kfree(info); 906 kfree(info);
1017
1018 return result; 907 return result;
1019} 908}
1020 909
@@ -1048,24 +937,14 @@ static ssize_t ib_ucm_send_mra(struct ib_ucm_file *file,
1048 if (result) 937 if (result)
1049 return result; 938 return result;
1050 939
1051 ctx = ib_ucm_ctx_get(cmd.id); 940 ctx = ib_ucm_ctx_get(file, cmd.id);
1052 if (!ctx) { 941 if (!IS_ERR(ctx)) {
1053 result = -ENOENT; 942 result = ib_send_cm_mra(ctx->cm_id, cmd.timeout, data, cmd.len);
1054 goto done; 943 ib_ucm_ctx_put(ctx);
1055 } 944 } else
945 result = PTR_ERR(ctx);
1056 946
1057 down(&ctx->file->mutex);
1058 if (ctx->file != file)
1059 result = -EINVAL;
1060 else
1061 result = ib_send_cm_mra(ctx->cm_id, cmd.timeout,
1062 data, cmd.len);
1063
1064 up(&ctx->file->mutex);
1065 ib_ucm_ctx_put(ctx); /* func reference */
1066done:
1067 kfree(data); 947 kfree(data);
1068
1069 return result; 948 return result;
1070} 949}
1071 950
@@ -1090,24 +969,16 @@ static ssize_t ib_ucm_send_lap(struct ib_ucm_file *file,
1090 if (result) 969 if (result)
1091 goto done; 970 goto done;
1092 971
1093 ctx = ib_ucm_ctx_get(cmd.id); 972 ctx = ib_ucm_ctx_get(file, cmd.id);
1094 if (!ctx) { 973 if (!IS_ERR(ctx)) {
1095 result = -ENOENT;
1096 goto done;
1097 }
1098
1099 down(&ctx->file->mutex);
1100 if (ctx->file != file)
1101 result = -EINVAL;
1102 else
1103 result = ib_send_cm_lap(ctx->cm_id, path, data, cmd.len); 974 result = ib_send_cm_lap(ctx->cm_id, path, data, cmd.len);
975 ib_ucm_ctx_put(ctx);
976 } else
977 result = PTR_ERR(ctx);
1104 978
1105 up(&ctx->file->mutex);
1106 ib_ucm_ctx_put(ctx); /* func reference */
1107done: 979done:
1108 kfree(data); 980 kfree(data);
1109 kfree(path); 981 kfree(path);
1110
1111 return result; 982 return result;
1112} 983}
1113 984
@@ -1140,24 +1011,16 @@ static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file,
1140 param.max_cm_retries = cmd.max_cm_retries; 1011 param.max_cm_retries = cmd.max_cm_retries;
1141 param.pkey = cmd.pkey; 1012 param.pkey = cmd.pkey;
1142 1013
1143 ctx = ib_ucm_ctx_get(cmd.id); 1014 ctx = ib_ucm_ctx_get(file, cmd.id);
1144 if (!ctx) { 1015 if (!IS_ERR(ctx)) {
1145 result = -ENOENT;
1146 goto done;
1147 }
1148
1149 down(&ctx->file->mutex);
1150 if (ctx->file != file)
1151 result = -EINVAL;
1152 else
1153 result = ib_send_cm_sidr_req(ctx->cm_id, &param); 1016 result = ib_send_cm_sidr_req(ctx->cm_id, &param);
1017 ib_ucm_ctx_put(ctx);
1018 } else
1019 result = PTR_ERR(ctx);
1154 1020
1155 up(&ctx->file->mutex);
1156 ib_ucm_ctx_put(ctx); /* func reference */
1157done: 1021done:
1158 kfree(param.private_data); 1022 kfree(param.private_data);
1159 kfree(param.path); 1023 kfree(param.path);
1160
1161 return result; 1024 return result;
1162} 1025}
1163 1026
@@ -1184,30 +1047,22 @@ static ssize_t ib_ucm_send_sidr_rep(struct ib_ucm_file *file,
1184 if (result) 1047 if (result)
1185 goto done; 1048 goto done;
1186 1049
1187 param.qp_num = cmd.qpn; 1050 param.qp_num = cmd.qpn;
1188 param.qkey = cmd.qkey; 1051 param.qkey = cmd.qkey;
1189 param.status = cmd.status; 1052 param.status = cmd.status;
1190 param.info_length = cmd.info_len; 1053 param.info_length = cmd.info_len;
1191 param.private_data_len = cmd.data_len; 1054 param.private_data_len = cmd.data_len;
1192
1193 ctx = ib_ucm_ctx_get(cmd.id);
1194 if (!ctx) {
1195 result = -ENOENT;
1196 goto done;
1197 }
1198 1055
1199 down(&ctx->file->mutex); 1056 ctx = ib_ucm_ctx_get(file, cmd.id);
1200 if (ctx->file != file) 1057 if (!IS_ERR(ctx)) {
1201 result = -EINVAL;
1202 else
1203 result = ib_send_cm_sidr_rep(ctx->cm_id, &param); 1058 result = ib_send_cm_sidr_rep(ctx->cm_id, &param);
1059 ib_ucm_ctx_put(ctx);
1060 } else
1061 result = PTR_ERR(ctx);
1204 1062
1205 up(&ctx->file->mutex);
1206 ib_ucm_ctx_put(ctx); /* func reference */
1207done: 1063done:
1208 kfree(param.private_data); 1064 kfree(param.private_data);
1209 kfree(param.info); 1065 kfree(param.info);
1210
1211 return result; 1066 return result;
1212} 1067}
1213 1068
@@ -1305,22 +1160,17 @@ static int ib_ucm_close(struct inode *inode, struct file *filp)
1305 struct ib_ucm_context *ctx; 1160 struct ib_ucm_context *ctx;
1306 1161
1307 down(&file->mutex); 1162 down(&file->mutex);
1308
1309 while (!list_empty(&file->ctxs)) { 1163 while (!list_empty(&file->ctxs)) {
1310 1164
1311 ctx = list_entry(file->ctxs.next, 1165 ctx = list_entry(file->ctxs.next,
1312 struct ib_ucm_context, file_list); 1166 struct ib_ucm_context, file_list);
1313 1167
1314 up(&ctx->file->mutex); 1168 up(&file->mutex);
1315 ib_ucm_ctx_put(ctx); /* user reference */ 1169 ib_ucm_destroy_ctx(file, ctx->id);
1316 down(&file->mutex); 1170 down(&file->mutex);
1317 } 1171 }
1318
1319 up(&file->mutex); 1172 up(&file->mutex);
1320
1321 kfree(file); 1173 kfree(file);
1322
1323 ucm_dbg("Deleted struct\n");
1324 return 0; 1174 return 0;
1325} 1175}
1326 1176
diff --git a/drivers/infiniband/core/ucm.h b/drivers/infiniband/core/ucm.h
index 6d36606151b2..c8819b928a1b 100644
--- a/drivers/infiniband/core/ucm.h
+++ b/drivers/infiniband/core/ucm.h
@@ -40,17 +40,15 @@
40#include <linux/cdev.h> 40#include <linux/cdev.h>
41#include <linux/idr.h> 41#include <linux/idr.h>
42 42
43#include <ib_cm.h> 43#include <rdma/ib_cm.h>
44#include <ib_user_cm.h> 44#include <rdma/ib_user_cm.h>
45 45
46#define IB_UCM_CM_ID_INVALID 0xffffffff 46#define IB_UCM_CM_ID_INVALID 0xffffffff
47 47
48struct ib_ucm_file { 48struct ib_ucm_file {
49 struct semaphore mutex; 49 struct semaphore mutex;
50 struct file *filp; 50 struct file *filp;
51 /* 51
52 * list of pending events
53 */
54 struct list_head ctxs; /* list of active connections */ 52 struct list_head ctxs; /* list of active connections */
55 struct list_head events; /* list of pending events */ 53 struct list_head events; /* list of pending events */
56 wait_queue_head_t poll_wait; 54 wait_queue_head_t poll_wait;
@@ -58,12 +56,11 @@ struct ib_ucm_file {
58 56
59struct ib_ucm_context { 57struct ib_ucm_context {
60 int id; 58 int id;
61 int ref; 59 wait_queue_head_t wait;
62 int error; 60 atomic_t ref;
63 61
64 struct ib_ucm_file *file; 62 struct ib_ucm_file *file;
65 struct ib_cm_id *cm_id; 63 struct ib_cm_id *cm_id;
66 struct semaphore mutex;
67 64
68 struct list_head events; /* list of pending events. */ 65 struct list_head events; /* list of pending events. */
69 struct list_head file_list; /* member in file ctx list */ 66 struct list_head file_list; /* member in file ctx list */
diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c
index dc4eb1db5e96..527b23450ab3 100644
--- a/drivers/infiniband/core/ud_header.c
+++ b/drivers/infiniband/core/ud_header.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 2 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
3 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
3 * 4 *
4 * This software is available to you under a choice of one of two 5 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU 6 * licenses. You may choose to be licensed under the terms of the GNU
@@ -34,7 +35,7 @@
34 35
35#include <linux/errno.h> 36#include <linux/errno.h>
36 37
37#include <ib_pack.h> 38#include <rdma/ib_pack.h>
38 39
39#define STRUCT_FIELD(header, field) \ 40#define STRUCT_FIELD(header, field) \
40 .struct_offset_bytes = offsetof(struct ib_unpacked_ ## header, field), \ 41 .struct_offset_bytes = offsetof(struct ib_unpacked_ ## header, field), \
@@ -194,6 +195,7 @@ void ib_ud_header_init(int payload_bytes,
194 struct ib_ud_header *header) 195 struct ib_ud_header *header)
195{ 196{
196 int header_len; 197 int header_len;
198 u16 packet_length;
197 199
198 memset(header, 0, sizeof *header); 200 memset(header, 0, sizeof *header);
199 201
@@ -208,7 +210,7 @@ void ib_ud_header_init(int payload_bytes,
208 header->lrh.link_version = 0; 210 header->lrh.link_version = 0;
209 header->lrh.link_next_header = 211 header->lrh.link_next_header =
210 grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL; 212 grh_present ? IB_LNH_IBA_GLOBAL : IB_LNH_IBA_LOCAL;
211 header->lrh.packet_length = (IB_LRH_BYTES + 213 packet_length = (IB_LRH_BYTES +
212 IB_BTH_BYTES + 214 IB_BTH_BYTES +
213 IB_DETH_BYTES + 215 IB_DETH_BYTES +
214 payload_bytes + 216 payload_bytes +
@@ -217,8 +219,7 @@ void ib_ud_header_init(int payload_bytes,
217 219
218 header->grh_present = grh_present; 220 header->grh_present = grh_present;
219 if (grh_present) { 221 if (grh_present) {
220 header->lrh.packet_length += IB_GRH_BYTES / 4; 222 packet_length += IB_GRH_BYTES / 4;
221
222 header->grh.ip_version = 6; 223 header->grh.ip_version = 6;
223 header->grh.payload_length = 224 header->grh.payload_length =
224 cpu_to_be16((IB_BTH_BYTES + 225 cpu_to_be16((IB_BTH_BYTES +
@@ -229,7 +230,7 @@ void ib_ud_header_init(int payload_bytes,
229 header->grh.next_header = 0x1b; 230 header->grh.next_header = 0x1b;
230 } 231 }
231 232
232 cpu_to_be16s(&header->lrh.packet_length); 233 header->lrh.packet_length = cpu_to_be16(packet_length);
233 234
234 if (header->immediate_present) 235 if (header->immediate_present)
235 header->bth.opcode = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE; 236 header->bth.opcode = IB_OPCODE_UD_SEND_ONLY_WITH_IMMEDIATE;
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 2e38792df533..7c2f03057ddb 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
5 * 5 *
6 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
@@ -49,8 +49,8 @@
49#include <asm/uaccess.h> 49#include <asm/uaccess.h>
50#include <asm/semaphore.h> 50#include <asm/semaphore.h>
51 51
52#include <ib_mad.h> 52#include <rdma/ib_mad.h>
53#include <ib_user_mad.h> 53#include <rdma/ib_user_mad.h>
54 54
55MODULE_AUTHOR("Roland Dreier"); 55MODULE_AUTHOR("Roland Dreier");
56MODULE_DESCRIPTION("InfiniBand userspace MAD packet access"); 56MODULE_DESCRIPTION("InfiniBand userspace MAD packet access");
@@ -271,7 +271,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
271 struct ib_send_wr *bad_wr; 271 struct ib_send_wr *bad_wr;
272 struct ib_rmpp_mad *rmpp_mad; 272 struct ib_rmpp_mad *rmpp_mad;
273 u8 method; 273 u8 method;
274 u64 *tid; 274 __be64 *tid;
275 int ret, length, hdr_len, data_len, rmpp_hdr_size; 275 int ret, length, hdr_len, data_len, rmpp_hdr_size;
276 int rmpp_active = 0; 276 int rmpp_active = 0;
277 277
@@ -316,7 +316,7 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
316 if (packet->mad.hdr.grh_present) { 316 if (packet->mad.hdr.grh_present) {
317 ah_attr.ah_flags = IB_AH_GRH; 317 ah_attr.ah_flags = IB_AH_GRH;
318 memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16); 318 memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16);
319 ah_attr.grh.flow_label = packet->mad.hdr.flow_label; 319 ah_attr.grh.flow_label = be32_to_cpu(packet->mad.hdr.flow_label);
320 ah_attr.grh.hop_limit = packet->mad.hdr.hop_limit; 320 ah_attr.grh.hop_limit = packet->mad.hdr.hop_limit;
321 ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class; 321 ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class;
322 } 322 }
diff --git a/drivers/infiniband/core/uverbs.h b/drivers/infiniband/core/uverbs.h
index 7696022f9a4e..180b3d4765e4 100644
--- a/drivers/infiniband/core/uverbs.h
+++ b/drivers/infiniband/core/uverbs.h
@@ -1,6 +1,8 @@
1/* 1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
5 * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
4 * 6 *
5 * This software is available to you under a choice of one of two 7 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 8 * licenses. You may choose to be licensed under the terms of the GNU
@@ -43,8 +45,8 @@
43#include <linux/kref.h> 45#include <linux/kref.h>
44#include <linux/idr.h> 46#include <linux/idr.h>
45 47
46#include <ib_verbs.h> 48#include <rdma/ib_verbs.h>
47#include <ib_user_verbs.h> 49#include <rdma/ib_user_verbs.h>
48 50
49struct ib_uverbs_device { 51struct ib_uverbs_device {
50 int devnum; 52 int devnum;
@@ -97,10 +99,12 @@ extern struct idr ib_uverbs_mw_idr;
97extern struct idr ib_uverbs_ah_idr; 99extern struct idr ib_uverbs_ah_idr;
98extern struct idr ib_uverbs_cq_idr; 100extern struct idr ib_uverbs_cq_idr;
99extern struct idr ib_uverbs_qp_idr; 101extern struct idr ib_uverbs_qp_idr;
102extern struct idr ib_uverbs_srq_idr;
100 103
101void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); 104void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context);
102void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); 105void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr);
103void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr); 106void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr);
107void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr);
104 108
105int ib_umem_get(struct ib_device *dev, struct ib_umem *mem, 109int ib_umem_get(struct ib_device *dev, struct ib_umem *mem,
106 void *addr, size_t size, int write); 110 void *addr, size_t size, int write);
@@ -129,5 +133,8 @@ IB_UVERBS_DECLARE_CMD(modify_qp);
129IB_UVERBS_DECLARE_CMD(destroy_qp); 133IB_UVERBS_DECLARE_CMD(destroy_qp);
130IB_UVERBS_DECLARE_CMD(attach_mcast); 134IB_UVERBS_DECLARE_CMD(attach_mcast);
131IB_UVERBS_DECLARE_CMD(detach_mcast); 135IB_UVERBS_DECLARE_CMD(detach_mcast);
136IB_UVERBS_DECLARE_CMD(create_srq);
137IB_UVERBS_DECLARE_CMD(modify_srq);
138IB_UVERBS_DECLARE_CMD(destroy_srq);
132 139
133#endif /* UVERBS_H */ 140#endif /* UVERBS_H */
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 5f2bbcda4c73..ebccf9f38af9 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -724,6 +724,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
724 struct ib_uobject *uobj; 724 struct ib_uobject *uobj;
725 struct ib_pd *pd; 725 struct ib_pd *pd;
726 struct ib_cq *scq, *rcq; 726 struct ib_cq *scq, *rcq;
727 struct ib_srq *srq;
727 struct ib_qp *qp; 728 struct ib_qp *qp;
728 struct ib_qp_init_attr attr; 729 struct ib_qp_init_attr attr;
729 int ret; 730 int ret;
@@ -747,10 +748,12 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
747 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle); 748 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
748 scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle); 749 scq = idr_find(&ib_uverbs_cq_idr, cmd.send_cq_handle);
749 rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle); 750 rcq = idr_find(&ib_uverbs_cq_idr, cmd.recv_cq_handle);
751 srq = cmd.is_srq ? idr_find(&ib_uverbs_srq_idr, cmd.srq_handle) : NULL;
750 752
751 if (!pd || pd->uobject->context != file->ucontext || 753 if (!pd || pd->uobject->context != file->ucontext ||
752 !scq || scq->uobject->context != file->ucontext || 754 !scq || scq->uobject->context != file->ucontext ||
753 !rcq || rcq->uobject->context != file->ucontext) { 755 !rcq || rcq->uobject->context != file->ucontext ||
756 (cmd.is_srq && (!srq || srq->uobject->context != file->ucontext))) {
754 ret = -EINVAL; 757 ret = -EINVAL;
755 goto err_up; 758 goto err_up;
756 } 759 }
@@ -759,7 +762,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
759 attr.qp_context = file; 762 attr.qp_context = file;
760 attr.send_cq = scq; 763 attr.send_cq = scq;
761 attr.recv_cq = rcq; 764 attr.recv_cq = rcq;
762 attr.srq = NULL; 765 attr.srq = srq;
763 attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR; 766 attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR;
764 attr.qp_type = cmd.qp_type; 767 attr.qp_type = cmd.qp_type;
765 768
@@ -1004,3 +1007,178 @@ ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
1004 1007
1005 return ret ? ret : in_len; 1008 return ret ? ret : in_len;
1006} 1009}
1010
1011ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
1012 const char __user *buf, int in_len,
1013 int out_len)
1014{
1015 struct ib_uverbs_create_srq cmd;
1016 struct ib_uverbs_create_srq_resp resp;
1017 struct ib_udata udata;
1018 struct ib_uobject *uobj;
1019 struct ib_pd *pd;
1020 struct ib_srq *srq;
1021 struct ib_srq_init_attr attr;
1022 int ret;
1023
1024 if (out_len < sizeof resp)
1025 return -ENOSPC;
1026
1027 if (copy_from_user(&cmd, buf, sizeof cmd))
1028 return -EFAULT;
1029
1030 INIT_UDATA(&udata, buf + sizeof cmd,
1031 (unsigned long) cmd.response + sizeof resp,
1032 in_len - sizeof cmd, out_len - sizeof resp);
1033
1034 uobj = kmalloc(sizeof *uobj, GFP_KERNEL);
1035 if (!uobj)
1036 return -ENOMEM;
1037
1038 down(&ib_uverbs_idr_mutex);
1039
1040 pd = idr_find(&ib_uverbs_pd_idr, cmd.pd_handle);
1041
1042 if (!pd || pd->uobject->context != file->ucontext) {
1043 ret = -EINVAL;
1044 goto err_up;
1045 }
1046
1047 attr.event_handler = ib_uverbs_srq_event_handler;
1048 attr.srq_context = file;
1049 attr.attr.max_wr = cmd.max_wr;
1050 attr.attr.max_sge = cmd.max_sge;
1051 attr.attr.srq_limit = cmd.srq_limit;
1052
1053 uobj->user_handle = cmd.user_handle;
1054 uobj->context = file->ucontext;
1055
1056 srq = pd->device->create_srq(pd, &attr, &udata);
1057 if (IS_ERR(srq)) {
1058 ret = PTR_ERR(srq);
1059 goto err_up;
1060 }
1061
1062 srq->device = pd->device;
1063 srq->pd = pd;
1064 srq->uobject = uobj;
1065 srq->event_handler = attr.event_handler;
1066 srq->srq_context = attr.srq_context;
1067 atomic_inc(&pd->usecnt);
1068 atomic_set(&srq->usecnt, 0);
1069
1070 memset(&resp, 0, sizeof resp);
1071
1072retry:
1073 if (!idr_pre_get(&ib_uverbs_srq_idr, GFP_KERNEL)) {
1074 ret = -ENOMEM;
1075 goto err_destroy;
1076 }
1077
1078 ret = idr_get_new(&ib_uverbs_srq_idr, srq, &uobj->id);
1079
1080 if (ret == -EAGAIN)
1081 goto retry;
1082 if (ret)
1083 goto err_destroy;
1084
1085 resp.srq_handle = uobj->id;
1086
1087 spin_lock_irq(&file->ucontext->lock);
1088 list_add_tail(&uobj->list, &file->ucontext->srq_list);
1089 spin_unlock_irq(&file->ucontext->lock);
1090
1091 if (copy_to_user((void __user *) (unsigned long) cmd.response,
1092 &resp, sizeof resp)) {
1093 ret = -EFAULT;
1094 goto err_list;
1095 }
1096
1097 up(&ib_uverbs_idr_mutex);
1098
1099 return in_len;
1100
1101err_list:
1102 spin_lock_irq(&file->ucontext->lock);
1103 list_del(&uobj->list);
1104 spin_unlock_irq(&file->ucontext->lock);
1105
1106err_destroy:
1107 ib_destroy_srq(srq);
1108
1109err_up:
1110 up(&ib_uverbs_idr_mutex);
1111
1112 kfree(uobj);
1113 return ret;
1114}
1115
1116ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
1117 const char __user *buf, int in_len,
1118 int out_len)
1119{
1120 struct ib_uverbs_modify_srq cmd;
1121 struct ib_srq *srq;
1122 struct ib_srq_attr attr;
1123 int ret;
1124
1125 if (copy_from_user(&cmd, buf, sizeof cmd))
1126 return -EFAULT;
1127
1128 down(&ib_uverbs_idr_mutex);
1129
1130 srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1131 if (!srq || srq->uobject->context != file->ucontext) {
1132 ret = -EINVAL;
1133 goto out;
1134 }
1135
1136 attr.max_wr = cmd.max_wr;
1137 attr.max_sge = cmd.max_sge;
1138 attr.srq_limit = cmd.srq_limit;
1139
1140 ret = ib_modify_srq(srq, &attr, cmd.attr_mask);
1141
1142out:
1143 up(&ib_uverbs_idr_mutex);
1144
1145 return ret ? ret : in_len;
1146}
1147
1148ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
1149 const char __user *buf, int in_len,
1150 int out_len)
1151{
1152 struct ib_uverbs_destroy_srq cmd;
1153 struct ib_srq *srq;
1154 struct ib_uobject *uobj;
1155 int ret = -EINVAL;
1156
1157 if (copy_from_user(&cmd, buf, sizeof cmd))
1158 return -EFAULT;
1159
1160 down(&ib_uverbs_idr_mutex);
1161
1162 srq = idr_find(&ib_uverbs_srq_idr, cmd.srq_handle);
1163 if (!srq || srq->uobject->context != file->ucontext)
1164 goto out;
1165
1166 uobj = srq->uobject;
1167
1168 ret = ib_destroy_srq(srq);
1169 if (ret)
1170 goto out;
1171
1172 idr_remove(&ib_uverbs_srq_idr, cmd.srq_handle);
1173
1174 spin_lock_irq(&file->ucontext->lock);
1175 list_del(&uobj->list);
1176 spin_unlock_irq(&file->ucontext->lock);
1177
1178 kfree(uobj);
1179
1180out:
1181 up(&ib_uverbs_idr_mutex);
1182
1183 return ret ? ret : in_len;
1184}
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index eb99e693dec2..09caf5b1ef36 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
5 * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
4 * 6 *
5 * This software is available to you under a choice of one of two 7 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 8 * licenses. You may choose to be licensed under the terms of the GNU
@@ -67,6 +69,7 @@ DEFINE_IDR(ib_uverbs_mw_idr);
67DEFINE_IDR(ib_uverbs_ah_idr); 69DEFINE_IDR(ib_uverbs_ah_idr);
68DEFINE_IDR(ib_uverbs_cq_idr); 70DEFINE_IDR(ib_uverbs_cq_idr);
69DEFINE_IDR(ib_uverbs_qp_idr); 71DEFINE_IDR(ib_uverbs_qp_idr);
72DEFINE_IDR(ib_uverbs_srq_idr);
70 73
71static spinlock_t map_lock; 74static spinlock_t map_lock;
72static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); 75static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);
@@ -91,6 +94,9 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
91 [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp, 94 [IB_USER_VERBS_CMD_DESTROY_QP] = ib_uverbs_destroy_qp,
92 [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast, 95 [IB_USER_VERBS_CMD_ATTACH_MCAST] = ib_uverbs_attach_mcast,
93 [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast, 96 [IB_USER_VERBS_CMD_DETACH_MCAST] = ib_uverbs_detach_mcast,
97 [IB_USER_VERBS_CMD_CREATE_SRQ] = ib_uverbs_create_srq,
98 [IB_USER_VERBS_CMD_MODIFY_SRQ] = ib_uverbs_modify_srq,
99 [IB_USER_VERBS_CMD_DESTROY_SRQ] = ib_uverbs_destroy_srq,
94}; 100};
95 101
96static struct vfsmount *uverbs_event_mnt; 102static struct vfsmount *uverbs_event_mnt;
@@ -125,18 +131,26 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context)
125 kfree(uobj); 131 kfree(uobj);
126 } 132 }
127 133
128 /* XXX Free SRQs */ 134 list_for_each_entry_safe(uobj, tmp, &context->srq_list, list) {
135 struct ib_srq *srq = idr_find(&ib_uverbs_srq_idr, uobj->id);
136 idr_remove(&ib_uverbs_srq_idr, uobj->id);
137 ib_destroy_srq(srq);
138 list_del(&uobj->list);
139 kfree(uobj);
140 }
141
129 /* XXX Free MWs */ 142 /* XXX Free MWs */
130 143
131 list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { 144 list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) {
132 struct ib_mr *mr = idr_find(&ib_uverbs_mr_idr, uobj->id); 145 struct ib_mr *mr = idr_find(&ib_uverbs_mr_idr, uobj->id);
146 struct ib_device *mrdev = mr->device;
133 struct ib_umem_object *memobj; 147 struct ib_umem_object *memobj;
134 148
135 idr_remove(&ib_uverbs_mr_idr, uobj->id); 149 idr_remove(&ib_uverbs_mr_idr, uobj->id);
136 ib_dereg_mr(mr); 150 ib_dereg_mr(mr);
137 151
138 memobj = container_of(uobj, struct ib_umem_object, uobject); 152 memobj = container_of(uobj, struct ib_umem_object, uobject);
139 ib_umem_release_on_close(mr->device, &memobj->umem); 153 ib_umem_release_on_close(mrdev, &memobj->umem);
140 154
141 list_del(&uobj->list); 155 list_del(&uobj->list);
142 kfree(memobj); 156 kfree(memobj);
@@ -343,6 +357,13 @@ void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr)
343 event->event); 357 event->event);
344} 358}
345 359
360void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr)
361{
362 ib_uverbs_async_handler(context_ptr,
363 event->element.srq->uobject->user_handle,
364 event->event);
365}
366
346static void ib_uverbs_event_handler(struct ib_event_handler *handler, 367static void ib_uverbs_event_handler(struct ib_event_handler *handler,
347 struct ib_event *event) 368 struct ib_event *event)
348{ 369{
diff --git a/drivers/infiniband/core/uverbs_mem.c b/drivers/infiniband/core/uverbs_mem.c
index ed550f6595bd..36a32c315668 100644
--- a/drivers/infiniband/core/uverbs_mem.c
+++ b/drivers/infiniband/core/uverbs_mem.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright (c) 2005 Topspin Communications. All rights reserved. 2 * Copyright (c) 2005 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Cisco Systems. All rights reserved. 3 * Copyright (c) 2005 Cisco Systems. All rights reserved.
4 * Copyright (c) 2005 Mellanox Technologies. All rights reserved.
4 * 5 *
5 * This software is available to you under a choice of one of two 6 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 7 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 506fdf1f2a26..5081d903e561 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -4,6 +4,7 @@
4 * Copyright (c) 2004 Intel Corporation. All rights reserved. 4 * Copyright (c) 2004 Intel Corporation. All rights reserved.
5 * Copyright (c) 2004 Topspin Corporation. All rights reserved. 5 * Copyright (c) 2004 Topspin Corporation. All rights reserved.
6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved. 6 * Copyright (c) 2004 Voltaire Corporation. All rights reserved.
7 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
7 * Copyright (c) 2005 Cisco Systems. All rights reserved. 8 * Copyright (c) 2005 Cisco Systems. All rights reserved.
8 * 9 *
9 * This software is available to you under a choice of one of two 10 * This software is available to you under a choice of one of two
@@ -40,8 +41,8 @@
40#include <linux/errno.h> 41#include <linux/errno.h>
41#include <linux/err.h> 42#include <linux/err.h>
42 43
43#include <ib_verbs.h> 44#include <rdma/ib_verbs.h>
44#include <ib_cache.h> 45#include <rdma/ib_cache.h>
45 46
46/* Protection domains */ 47/* Protection domains */
47 48
@@ -153,6 +154,66 @@ int ib_destroy_ah(struct ib_ah *ah)
153} 154}
154EXPORT_SYMBOL(ib_destroy_ah); 155EXPORT_SYMBOL(ib_destroy_ah);
155 156
157/* Shared receive queues */
158
159struct ib_srq *ib_create_srq(struct ib_pd *pd,
160 struct ib_srq_init_attr *srq_init_attr)
161{
162 struct ib_srq *srq;
163
164 if (!pd->device->create_srq)
165 return ERR_PTR(-ENOSYS);
166
167 srq = pd->device->create_srq(pd, srq_init_attr, NULL);
168
169 if (!IS_ERR(srq)) {
170 srq->device = pd->device;
171 srq->pd = pd;
172 srq->uobject = NULL;
173 srq->event_handler = srq_init_attr->event_handler;
174 srq->srq_context = srq_init_attr->srq_context;
175 atomic_inc(&pd->usecnt);
176 atomic_set(&srq->usecnt, 0);
177 }
178
179 return srq;
180}
181EXPORT_SYMBOL(ib_create_srq);
182
183int ib_modify_srq(struct ib_srq *srq,
184 struct ib_srq_attr *srq_attr,
185 enum ib_srq_attr_mask srq_attr_mask)
186{
187 return srq->device->modify_srq(srq, srq_attr, srq_attr_mask);
188}
189EXPORT_SYMBOL(ib_modify_srq);
190
191int ib_query_srq(struct ib_srq *srq,
192 struct ib_srq_attr *srq_attr)
193{
194 return srq->device->query_srq ?
195 srq->device->query_srq(srq, srq_attr) : -ENOSYS;
196}
197EXPORT_SYMBOL(ib_query_srq);
198
199int ib_destroy_srq(struct ib_srq *srq)
200{
201 struct ib_pd *pd;
202 int ret;
203
204 if (atomic_read(&srq->usecnt))
205 return -EBUSY;
206
207 pd = srq->pd;
208
209 ret = srq->device->destroy_srq(srq);
210 if (!ret)
211 atomic_dec(&pd->usecnt);
212
213 return ret;
214}
215EXPORT_SYMBOL(ib_destroy_srq);
216
156/* Queue pairs */ 217/* Queue pairs */
157 218
158struct ib_qp *ib_create_qp(struct ib_pd *pd, 219struct ib_qp *ib_create_qp(struct ib_pd *pd,