diff options
Diffstat (limited to 'drivers/infiniband/core/sa_query.c')
-rw-r--r-- | drivers/infiniband/core/sa_query.c | 67 |
1 files changed, 56 insertions, 11 deletions
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index d6b84226bba7..1706d3c7e95e 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c | |||
@@ -1,6 +1,7 @@ | |||
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) 2006 Intel Corporation. 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 |
@@ -75,6 +76,7 @@ struct ib_sa_device { | |||
75 | struct ib_sa_query { | 76 | struct ib_sa_query { |
76 | void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *); | 77 | void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *); |
77 | void (*release)(struct ib_sa_query *); | 78 | void (*release)(struct ib_sa_query *); |
79 | struct ib_sa_client *client; | ||
78 | struct ib_sa_port *port; | 80 | struct ib_sa_port *port; |
79 | struct ib_mad_send_buf *mad_buf; | 81 | struct ib_mad_send_buf *mad_buf; |
80 | struct ib_sa_sm_ah *sm_ah; | 82 | struct ib_sa_sm_ah *sm_ah; |
@@ -415,6 +417,31 @@ static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event | |||
415 | } | 417 | } |
416 | } | 418 | } |
417 | 419 | ||
420 | void ib_sa_register_client(struct ib_sa_client *client) | ||
421 | { | ||
422 | atomic_set(&client->users, 1); | ||
423 | init_completion(&client->comp); | ||
424 | } | ||
425 | EXPORT_SYMBOL(ib_sa_register_client); | ||
426 | |||
427 | static inline void ib_sa_client_get(struct ib_sa_client *client) | ||
428 | { | ||
429 | atomic_inc(&client->users); | ||
430 | } | ||
431 | |||
432 | static inline void ib_sa_client_put(struct ib_sa_client *client) | ||
433 | { | ||
434 | if (atomic_dec_and_test(&client->users)) | ||
435 | complete(&client->comp); | ||
436 | } | ||
437 | |||
438 | void ib_sa_unregister_client(struct ib_sa_client *client) | ||
439 | { | ||
440 | ib_sa_client_put(client); | ||
441 | wait_for_completion(&client->comp); | ||
442 | } | ||
443 | EXPORT_SYMBOL(ib_sa_unregister_client); | ||
444 | |||
418 | /** | 445 | /** |
419 | * ib_sa_cancel_query - try to cancel an SA query | 446 | * ib_sa_cancel_query - try to cancel an SA query |
420 | * @id:ID of query to cancel | 447 | * @id:ID of query to cancel |
@@ -557,6 +584,7 @@ static void ib_sa_path_rec_release(struct ib_sa_query *sa_query) | |||
557 | 584 | ||
558 | /** | 585 | /** |
559 | * ib_sa_path_rec_get - Start a Path get query | 586 | * ib_sa_path_rec_get - Start a Path get query |
587 | * @client:SA client | ||
560 | * @device:device to send query on | 588 | * @device:device to send query on |
561 | * @port_num: port number to send query on | 589 | * @port_num: port number to send query on |
562 | * @rec:Path Record to send in query | 590 | * @rec:Path Record to send in query |
@@ -579,7 +607,8 @@ static void ib_sa_path_rec_release(struct ib_sa_query *sa_query) | |||
579 | * error code. Otherwise it is a query ID that can be used to cancel | 607 | * error code. Otherwise it is a query ID that can be used to cancel |
580 | * the query. | 608 | * the query. |
581 | */ | 609 | */ |
582 | int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, | 610 | int ib_sa_path_rec_get(struct ib_sa_client *client, |
611 | struct ib_device *device, u8 port_num, | ||
583 | struct ib_sa_path_rec *rec, | 612 | struct ib_sa_path_rec *rec, |
584 | ib_sa_comp_mask comp_mask, | 613 | ib_sa_comp_mask comp_mask, |
585 | int timeout_ms, gfp_t gfp_mask, | 614 | int timeout_ms, gfp_t gfp_mask, |
@@ -614,8 +643,10 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, | |||
614 | goto err1; | 643 | goto err1; |
615 | } | 644 | } |
616 | 645 | ||
617 | query->callback = callback; | 646 | ib_sa_client_get(client); |
618 | query->context = context; | 647 | query->sa_query.client = client; |
648 | query->callback = callback; | ||
649 | query->context = context; | ||
619 | 650 | ||
620 | mad = query->sa_query.mad_buf->mad; | 651 | mad = query->sa_query.mad_buf->mad; |
621 | init_mad(mad, agent); | 652 | init_mad(mad, agent); |
@@ -639,6 +670,7 @@ int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, | |||
639 | 670 | ||
640 | err2: | 671 | err2: |
641 | *sa_query = NULL; | 672 | *sa_query = NULL; |
673 | ib_sa_client_put(query->sa_query.client); | ||
642 | ib_free_send_mad(query->sa_query.mad_buf); | 674 | ib_free_send_mad(query->sa_query.mad_buf); |
643 | 675 | ||
644 | err1: | 676 | err1: |
@@ -671,6 +703,7 @@ static void ib_sa_service_rec_release(struct ib_sa_query *sa_query) | |||
671 | 703 | ||
672 | /** | 704 | /** |
673 | * ib_sa_service_rec_query - Start Service Record operation | 705 | * ib_sa_service_rec_query - Start Service Record operation |
706 | * @client:SA client | ||
674 | * @device:device to send request on | 707 | * @device:device to send request on |
675 | * @port_num: port number to send request on | 708 | * @port_num: port number to send request on |
676 | * @method:SA method - should be get, set, or delete | 709 | * @method:SA method - should be get, set, or delete |
@@ -695,7 +728,8 @@ static void ib_sa_service_rec_release(struct ib_sa_query *sa_query) | |||
695 | * error code. Otherwise it is a request ID that can be used to cancel | 728 | * error code. Otherwise it is a request ID that can be used to cancel |
696 | * the query. | 729 | * the query. |
697 | */ | 730 | */ |
698 | int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method, | 731 | int ib_sa_service_rec_query(struct ib_sa_client *client, |
732 | struct ib_device *device, u8 port_num, u8 method, | ||
699 | struct ib_sa_service_rec *rec, | 733 | struct ib_sa_service_rec *rec, |
700 | ib_sa_comp_mask comp_mask, | 734 | ib_sa_comp_mask comp_mask, |
701 | int timeout_ms, gfp_t gfp_mask, | 735 | int timeout_ms, gfp_t gfp_mask, |
@@ -735,8 +769,10 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method, | |||
735 | goto err1; | 769 | goto err1; |
736 | } | 770 | } |
737 | 771 | ||
738 | query->callback = callback; | 772 | ib_sa_client_get(client); |
739 | query->context = context; | 773 | query->sa_query.client = client; |
774 | query->callback = callback; | ||
775 | query->context = context; | ||
740 | 776 | ||
741 | mad = query->sa_query.mad_buf->mad; | 777 | mad = query->sa_query.mad_buf->mad; |
742 | init_mad(mad, agent); | 778 | init_mad(mad, agent); |
@@ -761,6 +797,7 @@ int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method, | |||
761 | 797 | ||
762 | err2: | 798 | err2: |
763 | *sa_query = NULL; | 799 | *sa_query = NULL; |
800 | ib_sa_client_put(query->sa_query.client); | ||
764 | ib_free_send_mad(query->sa_query.mad_buf); | 801 | ib_free_send_mad(query->sa_query.mad_buf); |
765 | 802 | ||
766 | err1: | 803 | err1: |
@@ -791,7 +828,8 @@ static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query) | |||
791 | kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query)); | 828 | kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query)); |
792 | } | 829 | } |
793 | 830 | ||
794 | int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, | 831 | int ib_sa_mcmember_rec_query(struct ib_sa_client *client, |
832 | struct ib_device *device, u8 port_num, | ||
795 | u8 method, | 833 | u8 method, |
796 | struct ib_sa_mcmember_rec *rec, | 834 | struct ib_sa_mcmember_rec *rec, |
797 | ib_sa_comp_mask comp_mask, | 835 | ib_sa_comp_mask comp_mask, |
@@ -827,8 +865,10 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, | |||
827 | goto err1; | 865 | goto err1; |
828 | } | 866 | } |
829 | 867 | ||
830 | query->callback = callback; | 868 | ib_sa_client_get(client); |
831 | query->context = context; | 869 | query->sa_query.client = client; |
870 | query->callback = callback; | ||
871 | query->context = context; | ||
832 | 872 | ||
833 | mad = query->sa_query.mad_buf->mad; | 873 | mad = query->sa_query.mad_buf->mad; |
834 | init_mad(mad, agent); | 874 | init_mad(mad, agent); |
@@ -853,6 +893,7 @@ int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, | |||
853 | 893 | ||
854 | err2: | 894 | err2: |
855 | *sa_query = NULL; | 895 | *sa_query = NULL; |
896 | ib_sa_client_put(query->sa_query.client); | ||
856 | ib_free_send_mad(query->sa_query.mad_buf); | 897 | ib_free_send_mad(query->sa_query.mad_buf); |
857 | 898 | ||
858 | err1: | 899 | err1: |
@@ -887,8 +928,9 @@ static void send_handler(struct ib_mad_agent *agent, | |||
887 | idr_remove(&query_idr, query->id); | 928 | idr_remove(&query_idr, query->id); |
888 | spin_unlock_irqrestore(&idr_lock, flags); | 929 | spin_unlock_irqrestore(&idr_lock, flags); |
889 | 930 | ||
890 | ib_free_send_mad(mad_send_wc->send_buf); | 931 | ib_free_send_mad(mad_send_wc->send_buf); |
891 | kref_put(&query->sm_ah->ref, free_sm_ah); | 932 | kref_put(&query->sm_ah->ref, free_sm_ah); |
933 | ib_sa_client_put(query->client); | ||
892 | query->release(query); | 934 | query->release(query); |
893 | } | 935 | } |
894 | 936 | ||
@@ -919,7 +961,10 @@ static void ib_sa_add_one(struct ib_device *device) | |||
919 | struct ib_sa_device *sa_dev; | 961 | struct ib_sa_device *sa_dev; |
920 | int s, e, i; | 962 | int s, e, i; |
921 | 963 | ||
922 | if (device->node_type == IB_NODE_SWITCH) | 964 | if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB) |
965 | return; | ||
966 | |||
967 | if (device->node_type == RDMA_NODE_IB_SWITCH) | ||
923 | s = e = 0; | 968 | s = e = 0; |
924 | else { | 969 | else { |
925 | s = 1; | 970 | s = 1; |