aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/cm.c
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2005-10-17 18:37:43 -0400
committerRoland Dreier <rolandd@cisco.com>2005-10-17 18:37:43 -0400
commit07d357d0cbf89d9980b1769d5444a3c70f000e00 (patch)
treecc7bcdee52b4e79e2115295e763f2e3d49c68a86 /drivers/infiniband/core/cm.c
parent595e726a1f28420c5fc7970b1a87cbce77a1cd45 (diff)
[IB] CM: bind IDs to a specific device
Bind communication identifiers to a device to support device removal. Export per HCA CM devices to userspace. Signed-off-by: Sean Hefty <sean.hefty@intel.com>
Diffstat (limited to 'drivers/infiniband/core/cm.c')
-rw-r--r--drivers/infiniband/core/cm.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 54db6d4831f..6f747debca9 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -366,9 +366,15 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv)
366 cur_cm_id_priv = rb_entry(parent, struct cm_id_private, 366 cur_cm_id_priv = rb_entry(parent, struct cm_id_private,
367 service_node); 367 service_node);
368 if ((cur_cm_id_priv->id.service_mask & service_id) == 368 if ((cur_cm_id_priv->id.service_mask & service_id) ==
369 (service_mask & cur_cm_id_priv->id.service_id)) 369 (service_mask & cur_cm_id_priv->id.service_id) &&
370 return cm_id_priv; 370 (cm_id_priv->id.device == cur_cm_id_priv->id.device))
371 if (service_id < cur_cm_id_priv->id.service_id) 371 return cur_cm_id_priv;
372
373 if (cm_id_priv->id.device < cur_cm_id_priv->id.device)
374 link = &(*link)->rb_left;
375 else if (cm_id_priv->id.device > cur_cm_id_priv->id.device)
376 link = &(*link)->rb_right;
377 else if (service_id < cur_cm_id_priv->id.service_id)
372 link = &(*link)->rb_left; 378 link = &(*link)->rb_left;
373 else 379 else
374 link = &(*link)->rb_right; 380 link = &(*link)->rb_right;
@@ -378,7 +384,8 @@ static struct cm_id_private * cm_insert_listen(struct cm_id_private *cm_id_priv)
378 return NULL; 384 return NULL;
379} 385}
380 386
381static struct cm_id_private * cm_find_listen(__be64 service_id) 387static struct cm_id_private * cm_find_listen(struct ib_device *device,
388 __be64 service_id)
382{ 389{
383 struct rb_node *node = cm.listen_service_table.rb_node; 390 struct rb_node *node = cm.listen_service_table.rb_node;
384 struct cm_id_private *cm_id_priv; 391 struct cm_id_private *cm_id_priv;
@@ -386,9 +393,15 @@ static struct cm_id_private * cm_find_listen(__be64 service_id)
386 while (node) { 393 while (node) {
387 cm_id_priv = rb_entry(node, struct cm_id_private, service_node); 394 cm_id_priv = rb_entry(node, struct cm_id_private, service_node);
388 if ((cm_id_priv->id.service_mask & service_id) == 395 if ((cm_id_priv->id.service_mask & service_id) ==
389 (cm_id_priv->id.service_mask & cm_id_priv->id.service_id)) 396 cm_id_priv->id.service_id &&
397 (cm_id_priv->id.device == device))
390 return cm_id_priv; 398 return cm_id_priv;
391 if (service_id < cm_id_priv->id.service_id) 399
400 if (device < cm_id_priv->id.device)
401 node = node->rb_left;
402 else if (device > cm_id_priv->id.device)
403 node = node->rb_right;
404 else if (service_id < cm_id_priv->id.service_id)
392 node = node->rb_left; 405 node = node->rb_left;
393 else 406 else
394 node = node->rb_right; 407 node = node->rb_right;
@@ -523,7 +536,8 @@ static void cm_reject_sidr_req(struct cm_id_private *cm_id_priv,
523 ib_send_cm_sidr_rep(&cm_id_priv->id, &param); 536 ib_send_cm_sidr_rep(&cm_id_priv->id, &param);
524} 537}
525 538
526struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler, 539struct ib_cm_id *ib_create_cm_id(struct ib_device *device,
540 ib_cm_handler cm_handler,
527 void *context) 541 void *context)
528{ 542{
529 struct cm_id_private *cm_id_priv; 543 struct cm_id_private *cm_id_priv;
@@ -535,6 +549,7 @@ struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler,
535 549
536 memset(cm_id_priv, 0, sizeof *cm_id_priv); 550 memset(cm_id_priv, 0, sizeof *cm_id_priv);
537 cm_id_priv->id.state = IB_CM_IDLE; 551 cm_id_priv->id.state = IB_CM_IDLE;
552 cm_id_priv->id.device = device;
538 cm_id_priv->id.cm_handler = cm_handler; 553 cm_id_priv->id.cm_handler = cm_handler;
539 cm_id_priv->id.context = context; 554 cm_id_priv->id.context = context;
540 cm_id_priv->id.remote_cm_qpn = 1; 555 cm_id_priv->id.remote_cm_qpn = 1;
@@ -1047,7 +1062,6 @@ static void cm_format_req_event(struct cm_work *work,
1047 req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad; 1062 req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
1048 param = &work->cm_event.param.req_rcvd; 1063 param = &work->cm_event.param.req_rcvd;
1049 param->listen_id = listen_id; 1064 param->listen_id = listen_id;
1050 param->device = cm_id_priv->av.port->mad_agent->device;
1051 param->port = cm_id_priv->av.port->port_num; 1065 param->port = cm_id_priv->av.port->port_num;
1052 param->primary_path = &work->path[0]; 1066 param->primary_path = &work->path[0];
1053 if (req_msg->alt_local_lid) 1067 if (req_msg->alt_local_lid)
@@ -1226,7 +1240,8 @@ static struct cm_id_private * cm_match_req(struct cm_work *work,
1226 } 1240 }
1227 1241
1228 /* Find matching listen request. */ 1242 /* Find matching listen request. */
1229 listen_cm_id_priv = cm_find_listen(req_msg->service_id); 1243 listen_cm_id_priv = cm_find_listen(cm_id_priv->id.device,
1244 req_msg->service_id);
1230 if (!listen_cm_id_priv) { 1245 if (!listen_cm_id_priv) {
1231 spin_unlock_irqrestore(&cm.lock, flags); 1246 spin_unlock_irqrestore(&cm.lock, flags);
1232 cm_issue_rej(work->port, work->mad_recv_wc, 1247 cm_issue_rej(work->port, work->mad_recv_wc,
@@ -1254,7 +1269,7 @@ static int cm_req_handler(struct cm_work *work)
1254 1269
1255 req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad; 1270 req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
1256 1271
1257 cm_id = ib_create_cm_id(NULL, NULL); 1272 cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
1258 if (IS_ERR(cm_id)) 1273 if (IS_ERR(cm_id))
1259 return PTR_ERR(cm_id); 1274 return PTR_ERR(cm_id);
1260 1275
@@ -2629,7 +2644,6 @@ static void cm_format_sidr_req_event(struct cm_work *work,
2629 param = &work->cm_event.param.sidr_req_rcvd; 2644 param = &work->cm_event.param.sidr_req_rcvd;
2630 param->pkey = __be16_to_cpu(sidr_req_msg->pkey); 2645 param->pkey = __be16_to_cpu(sidr_req_msg->pkey);
2631 param->listen_id = listen_id; 2646 param->listen_id = listen_id;
2632 param->device = work->port->mad_agent->device;
2633 param->port = work->port->port_num; 2647 param->port = work->port->port_num;
2634 work->cm_event.private_data = &sidr_req_msg->private_data; 2648 work->cm_event.private_data = &sidr_req_msg->private_data;
2635} 2649}
@@ -2642,7 +2656,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
2642 struct ib_wc *wc; 2656 struct ib_wc *wc;
2643 unsigned long flags; 2657 unsigned long flags;
2644 2658
2645 cm_id = ib_create_cm_id(NULL, NULL); 2659 cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
2646 if (IS_ERR(cm_id)) 2660 if (IS_ERR(cm_id))
2647 return PTR_ERR(cm_id); 2661 return PTR_ERR(cm_id);
2648 cm_id_priv = container_of(cm_id, struct cm_id_private, id); 2662 cm_id_priv = container_of(cm_id, struct cm_id_private, id);
@@ -2666,7 +2680,8 @@ static int cm_sidr_req_handler(struct cm_work *work)
2666 spin_unlock_irqrestore(&cm.lock, flags); 2680 spin_unlock_irqrestore(&cm.lock, flags);
2667 goto out; /* Duplicate message. */ 2681 goto out; /* Duplicate message. */
2668 } 2682 }
2669 cur_cm_id_priv = cm_find_listen(sidr_req_msg->service_id); 2683 cur_cm_id_priv = cm_find_listen(cm_id->device,
2684 sidr_req_msg->service_id);
2670 if (!cur_cm_id_priv) { 2685 if (!cur_cm_id_priv) {
2671 rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table); 2686 rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
2672 spin_unlock_irqrestore(&cm.lock, flags); 2687 spin_unlock_irqrestore(&cm.lock, flags);