diff options
author | Steve French <sfrench@us.ibm.com> | 2005-08-30 14:33:26 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2005-08-30 14:33:26 -0400 |
commit | 2016ef789a9ded2e169ad1c028ae3deb5302571f (patch) | |
tree | 601359f15b42d4d9868b4eadfe909a7bef6435c5 /drivers/infiniband/core | |
parent | 7f57356b70dda014ef269135942426e4a852023e (diff) | |
parent | 6b39374a27eb4be7e9d82145ae270ba02ea90dc8 (diff) |
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers/infiniband/core')
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 @@ | |||
1 | EXTRA_CFLAGS += -Idrivers/infiniband/include | ||
2 | |||
3 | obj-$(CONFIG_INFINIBAND) += ib_core.o ib_mad.o ib_sa.o \ | 1 | obj-$(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 |
5 | obj-$(CONFIG_INFINIBAND_USER_VERBS) += ib_uverbs.o | 3 | obj-$(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 | ||
50 | MODULE_AUTHOR("Sean Hefty"); | 50 | MODULE_AUTHOR("Sean Hefty"); |
@@ -83,7 +83,7 @@ struct cm_port { | |||
83 | struct cm_device { | 83 | struct 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 | ||
318 | static void cm_free_id(u32 local_id) | 319 | static 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 | ||
327 | static struct cm_id_private * cm_get_id(u32 local_id, u32 remote_id) | 328 | static 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 | ||
342 | static struct cm_id_private * cm_acquire_id(u32 local_id, u32 remote_id) | 343 | static 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 | ||
379 | static struct cm_id_private * cm_find_listen(u64 service_id) | 380 | static 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 | ||
427 | static struct cm_timewait_info * cm_find_remote_id(u64 remote_ca_guid, | 428 | static 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 | ||
601 | static struct cm_timewait_info * cm_create_timewait_info(u32 local_id) | 602 | static 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: | |||
715 | EXPORT_SYMBOL(ib_destroy_cm_id); | 716 | EXPORT_SYMBOL(ib_destroy_cm_id); |
716 | 717 | ||
717 | int ib_cm_listen(struct ib_cm_id *cm_id, | 718 | int 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 | } |
753 | EXPORT_SYMBOL(ib_cm_listen); | 755 | EXPORT_SYMBOL(ib_cm_listen); |
754 | 756 | ||
755 | static u64 cm_form_tid(struct cm_id_private *cm_id_priv, | 757 | static __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 | ||
765 | static void cm_format_mad_hdr(struct ib_mad_hdr *hdr, | 768 | static 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 | ||
980 | static inline int cm_is_active_peer(u64 local_ca_guid, u64 remote_ca_guid, | 983 | static 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 | } |
3176 | EXPORT_SYMBOL(ib_cm_init_qp_attr); | 3179 | EXPORT_SYMBOL(ib_cm_init_qp_attr); |
3177 | 3180 | ||
3178 | static u64 cm_get_ca_guid(struct ib_device *device) | 3181 | static __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 | ||
46 | enum 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 | ||
60 | enum cm_msg_sequence { | 58 | enum cm_msg_sequence { |
61 | CM_MSG_SEQUENCE_REQ, | 59 | CM_MSG_SEQUENCE_REQ, |
@@ -67,35 +65,35 @@ enum cm_msg_sequence { | |||
67 | struct cm_req_msg { | 65 | struct 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 | ||
123 | static inline u32 cm_req_get_local_qpn(struct cm_req_msg *req_msg) | 121 | static 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 | ||
128 | static inline void cm_req_set_local_qpn(struct cm_req_msg *req_msg, u32 qpn) | 126 | static 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 | ||
211 | static inline u32 cm_req_get_starting_psn(struct cm_req_msg *req_msg) | 209 | static 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 | ||
216 | static inline void cm_req_set_starting_psn(struct cm_req_msg *req_msg, | 214 | static 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 | ||
291 | static inline u32 cm_req_get_primary_flow_label(struct cm_req_msg *req_msg) | 289 | static 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 | ||
296 | static inline void cm_req_set_primary_flow_label(struct cm_req_msg *req_msg, | 294 | static 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 | ||
353 | static inline u32 cm_req_get_alt_flow_label(struct cm_req_msg *req_msg) | 351 | static 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 | ||
358 | static inline void cm_req_set_alt_flow_label(struct cm_req_msg *req_msg, | 356 | static 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, | |||
458 | struct cm_rej_msg { | 456 | struct 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, | |||
495 | struct cm_rep_msg { | 493 | struct 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 | ||
519 | static inline u32 cm_rep_get_local_qpn(struct cm_rep_msg *rep_msg) | 517 | static 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 | ||
524 | static inline void cm_rep_set_local_qpn(struct cm_rep_msg *rep_msg, u32 qpn) | 522 | static 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 | ||
530 | static inline u32 cm_rep_get_starting_psn(struct cm_rep_msg *rep_msg) | 528 | static 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 | ||
535 | static inline void cm_rep_set_starting_psn(struct cm_rep_msg *rep_msg, | 533 | static 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) | |||
600 | struct cm_rtu_msg { | 598 | struct 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 { | |||
610 | struct cm_dreq_msg { | 608 | struct 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 | ||
622 | static inline u32 cm_dreq_get_remote_qpn(struct cm_dreq_msg *dreq_msg) | 620 | static 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 | ||
627 | static inline void cm_dreq_set_remote_qpn(struct cm_dreq_msg *dreq_msg, u32 qpn) | 625 | static 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) | |||
633 | struct cm_drep_msg { | 631 | struct 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 { | |||
643 | struct cm_lap_msg { | 641 | struct 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 | ||
671 | static inline u32 cm_lap_get_remote_qpn(struct cm_lap_msg *lap_msg) | 669 | static 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 | ||
676 | static inline void cm_lap_set_remote_qpn(struct cm_lap_msg *lap_msg, u32 qpn) | 674 | static 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 | ||
696 | static inline u32 cm_lap_get_flow_label(struct cm_lap_msg *lap_msg) | 694 | static 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 | ||
701 | static inline void cm_lap_set_flow_label(struct cm_lap_msg *lap_msg, | 699 | static 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 | ||
709 | static inline u8 cm_lap_get_traffic_class(struct cm_lap_msg *lap_msg) | 707 | static 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, | |||
766 | struct cm_apr_msg { | 764 | struct 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 { | |||
779 | struct cm_sidr_req_msg { | 777 | struct 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 { | |||
790 | struct cm_sidr_rep_msg { | 788 | struct 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 | ||
806 | static inline u32 cm_sidr_rep_get_qpn(struct cm_sidr_rep_msg *sidr_rep_msg) | 804 | static 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 | ||
811 | static inline void cm_sidr_rep_set_qpn(struct cm_sidr_rep_msg *sidr_rep_msg, | 809 | static 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 | ||
43 | int ib_device_register_sysfs(struct ib_device *device); | 43 | int ib_device_register_sysfs(struct ib_device *device); |
44 | void ib_device_unregister_sysfs(struct ib_device *device); | 44 | void 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 | ||
1556 | struct ib_mad_send_wr_private* | 1557 | struct ib_mad_send_wr_private* |
1557 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, u64 tid) | 1558 | ib_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 | ||
2297 | static void ib_mad_thread_completion_handler(struct ib_cq *cq) | 2299 | static 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 | ||
150 | struct ib_mad_mgmt_method_table { | 150 | struct ib_mad_mgmt_method_table { |
@@ -210,7 +210,7 @@ extern kmem_cache_t *ib_mad_cache; | |||
210 | int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr); | 210 | int ib_send_mad(struct ib_mad_send_wr_private *mad_send_wr); |
211 | 211 | ||
212 | struct ib_mad_send_wr_private * | 212 | struct ib_mad_send_wr_private * |
213 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, u64 tid); | 213 | ib_find_send_mad(struct ib_mad_agent_private *mad_agent_priv, __be64 tid); |
214 | 214 | ||
215 | void ib_mad_complete_send_wr(struct ib_mad_send_wr_private *mad_send_wr, | 215 | void 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 | ||
103 | static 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 | |||
114 | static 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 | |||
134 | static 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 | |||
157 | static 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 | |||
183 | static 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 | |||
189 | static 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 | |||
103 | static void recv_timeout_handler(void *data) | 218 | static 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 | ||
233 | static 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 | |||
244 | static 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 | |||
264 | static 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 | |||
287 | static inline int get_last_flag(struct ib_mad_recv_buf *seg) | 348 | static 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 | ||
623 | static 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; | ||
647 | out: | ||
648 | spin_unlock_irqrestore(&agent->lock, flags); | ||
649 | } | ||
650 | |||
562 | static void process_rmpp_ack(struct ib_mad_agent_private *agent, | 651 | static 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 | ||
735 | static struct ib_mad_recv_wc * | ||
736 | process_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 | } | ||
762 | bad: | ||
763 | nack_recv(agent, mad_recv_wc, rmpp_status); | ||
764 | ib_free_recv_mad(mad_recv_wc); | ||
765 | return NULL; | ||
766 | } | ||
767 | |||
768 | static 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 | |||
784 | static 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 | |||
631 | struct ib_mad_recv_wc * | 801 | struct ib_mad_recv_wc * |
632 | ib_process_rmpp_recv_wc(struct ib_mad_agent_private *agent, | 802 | ib_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 | } |
660 | out: | 836 | out: |
@@ -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 | ||
37 | static u64 value_read(int offset, int size, void *structure) | 38 | static 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 | ||
50 | MODULE_AUTHOR("Roland Dreier"); | 50 | MODULE_AUTHOR("Roland Dreier"); |
51 | MODULE_DESCRIPTION("InfiniBand subnet administration query support"); | 51 | MODULE_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 | ||
39 | struct ib_port { | 41 | struct 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 | ||
266 | static ssize_t show_port_pkey(struct ib_port *p, struct port_attribute *attr, | 268 | static 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 | ||
607 | static ssize_t show_node_guid(struct class_device *cdev, char *buf) | 609 | static 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 | ||
624 | static CLASS_DEVICE_ATTR(node_type, S_IRUGO, show_node_type, NULL); | 626 | static 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; | |||
73 | static struct idr ctx_id_table; | 74 | static struct idr ctx_id_table; |
74 | static int ctx_id_rover = 0; | 75 | static int ctx_id_rover = 0; |
75 | 76 | ||
76 | static struct ib_ucm_context *ib_ucm_ctx_get(int id) | 77 | static 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 | ||
89 | static void ib_ucm_ctx_put(struct ib_ucm_context *ctx) | 94 | static 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 | |||
100 | static 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 | ||
129 | static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) | 147 | static 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 | ||
204 | static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, | 222 | static 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 | ||
243 | static void ib_ucm_event_rej_get(struct ib_ucm_rej_event_resp *urej, | 262 | static 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 | |||
249 | static 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 | |||
255 | static 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 | |||
261 | static 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 | |||
267 | static 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 | ||
282 | static int ib_ucm_event_process(struct ib_cm_event *evt, | 278 | static 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; |
393 | error: | 368 | |
394 | kfree(uvt->info); | 369 | err2: |
395 | kfree(uvt->data); | 370 | kfree(uvt->data); |
396 | return result; | 371 | err1: |
372 | return -ENOMEM; | ||
397 | } | 373 | } |
398 | 374 | ||
399 | static int ib_ucm_event_handler(struct ib_cm_id *cm_id, | 375 | static 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); |
459 | done: | 411 | return 0; |
460 | ctx->error = result; | 412 | |
461 | ib_ucm_ctx_put(ctx); /* func reference */ | 413 | err2: |
462 | return result; | 414 | kfree(uevent); |
415 | err1: | ||
416 | /* Destroy new cm_id's */ | ||
417 | return (id == IB_UCM_CM_ID_INVALID); | ||
463 | } | 418 | } |
464 | 419 | ||
465 | static ssize_t ib_ucm_event(struct ib_ucm_file *file, | 420 | static 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; |
607 | err_ret: | ||
608 | ib_destroy_cm_id(ctx->cm_id); | ||
609 | err_cm: | ||
610 | ib_ucm_ctx_put(ctx); /* user reference */ | ||
611 | 562 | ||
563 | err: | ||
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 | ||
635 | static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file, | 580 | static 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 | ||
669 | done: | 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, ¶m); | 768 | result = ib_send_cm_req(ctx->cm_id, ¶m); |
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 */ | ||
856 | done: | 773 | done: |
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, ¶m); | 811 | result = ib_send_cm_rep(ctx->cm_id, ¶m); |
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 */ | ||
907 | done: | ||
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 */ | ||
945 | done: | ||
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 */ | ||
1014 | done: | 904 | done: |
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 */ | ||
1066 | done: | ||
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 */ | ||
1107 | done: | 979 | done: |
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, ¶m); | 1016 | result = ib_send_cm_sidr_req(ctx->cm_id, ¶m); |
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 */ | ||
1157 | done: | 1021 | done: |
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, ¶m); | 1058 | result = ib_send_cm_sidr_rep(ctx->cm_id, ¶m); |
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 */ | ||
1207 | done: | 1063 | done: |
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 | ||
48 | struct ib_ucm_file { | 48 | struct 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 | ||
59 | struct ib_ucm_context { | 57 | struct 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 | ||
55 | MODULE_AUTHOR("Roland Dreier"); | 55 | MODULE_AUTHOR("Roland Dreier"); |
56 | MODULE_DESCRIPTION("InfiniBand userspace MAD packet access"); | 56 | MODULE_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 | ||
49 | struct ib_uverbs_device { | 51 | struct ib_uverbs_device { |
50 | int devnum; | 52 | int devnum; |
@@ -97,10 +99,12 @@ extern struct idr ib_uverbs_mw_idr; | |||
97 | extern struct idr ib_uverbs_ah_idr; | 99 | extern struct idr ib_uverbs_ah_idr; |
98 | extern struct idr ib_uverbs_cq_idr; | 100 | extern struct idr ib_uverbs_cq_idr; |
99 | extern struct idr ib_uverbs_qp_idr; | 101 | extern struct idr ib_uverbs_qp_idr; |
102 | extern struct idr ib_uverbs_srq_idr; | ||
100 | 103 | ||
101 | void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); | 104 | void ib_uverbs_comp_handler(struct ib_cq *cq, void *cq_context); |
102 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); | 105 | void ib_uverbs_cq_event_handler(struct ib_event *event, void *context_ptr); |
103 | void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr); | 106 | void ib_uverbs_qp_event_handler(struct ib_event *event, void *context_ptr); |
107 | void ib_uverbs_srq_event_handler(struct ib_event *event, void *context_ptr); | ||
104 | 108 | ||
105 | int ib_umem_get(struct ib_device *dev, struct ib_umem *mem, | 109 | int 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); | |||
129 | IB_UVERBS_DECLARE_CMD(destroy_qp); | 133 | IB_UVERBS_DECLARE_CMD(destroy_qp); |
130 | IB_UVERBS_DECLARE_CMD(attach_mcast); | 134 | IB_UVERBS_DECLARE_CMD(attach_mcast); |
131 | IB_UVERBS_DECLARE_CMD(detach_mcast); | 135 | IB_UVERBS_DECLARE_CMD(detach_mcast); |
136 | IB_UVERBS_DECLARE_CMD(create_srq); | ||
137 | IB_UVERBS_DECLARE_CMD(modify_srq); | ||
138 | IB_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 | |||
1011 | ssize_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 | |||
1072 | retry: | ||
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 | |||
1101 | err_list: | ||
1102 | spin_lock_irq(&file->ucontext->lock); | ||
1103 | list_del(&uobj->list); | ||
1104 | spin_unlock_irq(&file->ucontext->lock); | ||
1105 | |||
1106 | err_destroy: | ||
1107 | ib_destroy_srq(srq); | ||
1108 | |||
1109 | err_up: | ||
1110 | up(&ib_uverbs_idr_mutex); | ||
1111 | |||
1112 | kfree(uobj); | ||
1113 | return ret; | ||
1114 | } | ||
1115 | |||
1116 | ssize_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 | |||
1142 | out: | ||
1143 | up(&ib_uverbs_idr_mutex); | ||
1144 | |||
1145 | return ret ? ret : in_len; | ||
1146 | } | ||
1147 | |||
1148 | ssize_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 | |||
1180 | out: | ||
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); | |||
67 | DEFINE_IDR(ib_uverbs_ah_idr); | 69 | DEFINE_IDR(ib_uverbs_ah_idr); |
68 | DEFINE_IDR(ib_uverbs_cq_idr); | 70 | DEFINE_IDR(ib_uverbs_cq_idr); |
69 | DEFINE_IDR(ib_uverbs_qp_idr); | 71 | DEFINE_IDR(ib_uverbs_qp_idr); |
72 | DEFINE_IDR(ib_uverbs_srq_idr); | ||
70 | 73 | ||
71 | static spinlock_t map_lock; | 74 | static spinlock_t map_lock; |
72 | static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES); | 75 | static 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 | ||
96 | static struct vfsmount *uverbs_event_mnt; | 102 | static 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 | ||
360 | void 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 | |||
346 | static void ib_uverbs_event_handler(struct ib_event_handler *handler, | 367 | static 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 | } |
154 | EXPORT_SYMBOL(ib_destroy_ah); | 155 | EXPORT_SYMBOL(ib_destroy_ah); |
155 | 156 | ||
157 | /* Shared receive queues */ | ||
158 | |||
159 | struct 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 | } | ||
181 | EXPORT_SYMBOL(ib_create_srq); | ||
182 | |||
183 | int 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 | } | ||
189 | EXPORT_SYMBOL(ib_modify_srq); | ||
190 | |||
191 | int 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 | } | ||
197 | EXPORT_SYMBOL(ib_query_srq); | ||
198 | |||
199 | int 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 | } | ||
215 | EXPORT_SYMBOL(ib_destroy_srq); | ||
216 | |||
156 | /* Queue pairs */ | 217 | /* Queue pairs */ |
157 | 218 | ||
158 | struct ib_qp *ib_create_qp(struct ib_pd *pd, | 219 | struct ib_qp *ib_create_qp(struct ib_pd *pd, |