diff options
author | Sean Hefty <sean.hefty@intel.com> | 2005-10-17 18:37:43 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2005-10-17 18:37:43 -0400 |
commit | 07d357d0cbf89d9980b1769d5444a3c70f000e00 (patch) | |
tree | cc7bcdee52b4e79e2115295e763f2e3d49c68a86 /drivers/infiniband/core/cm.c | |
parent | 595e726a1f28420c5fc7970b1a87cbce77a1cd45 (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.c | 41 |
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 | ||
381 | static struct cm_id_private * cm_find_listen(__be64 service_id) | 387 | static 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, ¶m); | 536 | ib_send_cm_sidr_rep(&cm_id_priv->id, ¶m); |
524 | } | 537 | } |
525 | 538 | ||
526 | struct ib_cm_id *ib_create_cm_id(ib_cm_handler cm_handler, | 539 | struct 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); |