2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved.
4 * Copyright (c) 2006 Intel Corporation. All rights reserved.
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
35 #include <linux/module.h>
36 #include <linux/init.h>
37 #include <linux/err.h>
38 #include <linux/random.h>
39 #include <linux/spinlock.h>
40 #include <linux/slab.h>
41 #include <linux/dma-mapping.h>
42 #include <linux/kref.h>
43 #include <linux/idr.h>
44 #include <linux/workqueue.h>
46 #include <rdma/ib_pack.h>
47 #include <rdma/ib_cache.h>
50 MODULE_AUTHOR("Roland Dreier");
51 MODULE_DESCRIPTION("InfiniBand subnet administration query support");
52 MODULE_LICENSE("Dual BSD/GPL");
62 struct ib_mad_agent *agent;
63 struct ib_mad_agent *notice_agent;
64 struct ib_sa_sm_ah *sm_ah;
65 struct work_struct update_task;
68 struct ib_device *device;
72 int start_port, end_port;
73 struct ib_event_handler event_handler;
74 struct ib_sa_port port[0];
78 void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *);
79 void (*release)(struct ib_sa_query *);
80 struct ib_sa_client *client;
81 struct ib_sa_port *port;
82 struct ib_mad_send_buf *mad_buf;
83 struct ib_sa_sm_ah *sm_ah;
87 struct ib_sa_service_query {
88 void (*callback)(int, struct ib_sa_service_rec *, void *);
90 struct ib_sa_query sa_query;
93 struct ib_sa_path_query {
94 void (*callback)(int, struct ib_sa_path_rec *, void *);
96 struct ib_sa_query sa_query;
99 struct ib_sa_mcmember_query {
100 void (*callback)(int, struct ib_sa_mcmember_rec *, void *);
102 struct ib_sa_query sa_query;
105 struct ib_sa_inform_query {
106 void (*callback)(int, struct ib_sa_inform *, void *);
108 struct ib_sa_query sa_query;
111 static void ib_sa_add_one(struct ib_device *device);
112 static void ib_sa_remove_one(struct ib_device *device);
114 static struct ib_client sa_client = {
116 .add = ib_sa_add_one,
117 .remove = ib_sa_remove_one
120 static spinlock_t idr_lock;
121 static DEFINE_IDR(query_idr);
123 static spinlock_t tid_lock;
126 #define PATH_REC_FIELD(field) \
127 .struct_offset_bytes = offsetof(struct ib_sa_path_rec, field), \
128 .struct_size_bytes = sizeof ((struct ib_sa_path_rec *) 0)->field, \
129 .field_name = "sa_path_rec:" #field
131 static const struct ib_field path_rec_table[] = {
132 { PATH_REC_FIELD(service_id),
136 { PATH_REC_FIELD(dgid),
140 { PATH_REC_FIELD(sgid),
144 { PATH_REC_FIELD(dlid),
148 { PATH_REC_FIELD(slid),
152 { PATH_REC_FIELD(raw_traffic),
160 { PATH_REC_FIELD(flow_label),
164 { PATH_REC_FIELD(hop_limit),
168 { PATH_REC_FIELD(traffic_class),
172 { PATH_REC_FIELD(reversible),
176 { PATH_REC_FIELD(numb_path),
180 { PATH_REC_FIELD(pkey),
184 { PATH_REC_FIELD(qos_class),
188 { PATH_REC_FIELD(sl),
192 { PATH_REC_FIELD(mtu_selector),
196 { PATH_REC_FIELD(mtu),
200 { PATH_REC_FIELD(rate_selector),
204 { PATH_REC_FIELD(rate),
208 { PATH_REC_FIELD(packet_life_time_selector),
212 { PATH_REC_FIELD(packet_life_time),
216 { PATH_REC_FIELD(preference),
226 #define MCMEMBER_REC_FIELD(field) \
227 .struct_offset_bytes = offsetof(struct ib_sa_mcmember_rec, field), \
228 .struct_size_bytes = sizeof ((struct ib_sa_mcmember_rec *) 0)->field, \
229 .field_name = "sa_mcmember_rec:" #field
231 static const struct ib_field mcmember_rec_table[] = {
232 { MCMEMBER_REC_FIELD(mgid),
236 { MCMEMBER_REC_FIELD(port_gid),
240 { MCMEMBER_REC_FIELD(qkey),
244 { MCMEMBER_REC_FIELD(mlid),
248 { MCMEMBER_REC_FIELD(mtu_selector),
252 { MCMEMBER_REC_FIELD(mtu),
256 { MCMEMBER_REC_FIELD(traffic_class),
260 { MCMEMBER_REC_FIELD(pkey),
264 { MCMEMBER_REC_FIELD(rate_selector),
268 { MCMEMBER_REC_FIELD(rate),
272 { MCMEMBER_REC_FIELD(packet_life_time_selector),
276 { MCMEMBER_REC_FIELD(packet_life_time),
280 { MCMEMBER_REC_FIELD(sl),
284 { MCMEMBER_REC_FIELD(flow_label),
288 { MCMEMBER_REC_FIELD(hop_limit),
292 { MCMEMBER_REC_FIELD(scope),
296 { MCMEMBER_REC_FIELD(join_state),
300 { MCMEMBER_REC_FIELD(proxy_join),
310 #define SERVICE_REC_FIELD(field) \
311 .struct_offset_bytes = offsetof(struct ib_sa_service_rec, field), \
312 .struct_size_bytes = sizeof ((struct ib_sa_service_rec *) 0)->field, \
313 .field_name = "sa_service_rec:" #field
315 static const struct ib_field service_rec_table[] = {
316 { SERVICE_REC_FIELD(id),
320 { SERVICE_REC_FIELD(gid),
324 { SERVICE_REC_FIELD(pkey),
328 { SERVICE_REC_FIELD(lease),
332 { SERVICE_REC_FIELD(key),
336 { SERVICE_REC_FIELD(name),
340 { SERVICE_REC_FIELD(data8),
344 { SERVICE_REC_FIELD(data16),
348 { SERVICE_REC_FIELD(data32),
352 { SERVICE_REC_FIELD(data64),
358 #define INFORM_FIELD(field) \
359 .struct_offset_bytes = offsetof(struct ib_sa_inform, field), \
360 .struct_size_bytes = sizeof ((struct ib_sa_inform *) 0)->field, \
361 .field_name = "sa_inform:" #field
363 static const struct ib_field inform_table[] = {
368 { INFORM_FIELD(lid_range_begin),
372 { INFORM_FIELD(lid_range_end),
380 { INFORM_FIELD(is_generic),
384 { INFORM_FIELD(subscribe),
388 { INFORM_FIELD(type),
392 { INFORM_FIELD(trap.generic.trap_num),
396 { INFORM_FIELD(trap.generic.qpn),
404 { INFORM_FIELD(trap.generic.resp_time),
412 { INFORM_FIELD(trap.generic.producer_type),
418 #define NOTICE_FIELD(field) \
419 .struct_offset_bytes = offsetof(struct ib_sa_notice, field), \
420 .struct_size_bytes = sizeof ((struct ib_sa_notice *) 0)->field, \
421 .field_name = "sa_notice:" #field
423 static const struct ib_field notice_table[] = {
424 { NOTICE_FIELD(is_generic),
428 { NOTICE_FIELD(type),
432 { NOTICE_FIELD(trap.generic.producer_type),
436 { NOTICE_FIELD(trap.generic.trap_num),
440 { NOTICE_FIELD(issuer_lid),
444 { NOTICE_FIELD(notice_toggle),
448 { NOTICE_FIELD(notice_count),
452 { NOTICE_FIELD(data_details),
456 { NOTICE_FIELD(issuer_gid),
462 int ib_sa_check_selector(ib_sa_comp_mask comp_mask,
463 ib_sa_comp_mask selector_mask,
464 ib_sa_comp_mask value_mask,
465 u8 selector, u8 src_value, u8 dst_value)
469 if (!(comp_mask & selector_mask) || !(comp_mask & value_mask))
474 err = (src_value <= dst_value);
477 err = (src_value >= dst_value);
480 err = (src_value != dst_value);
490 int ib_sa_pack_attr(void *dst, void *src, int attr_id)
493 case IB_SA_ATTR_PATH_REC:
494 ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), src, dst);
502 int ib_sa_unpack_attr(void *dst, void *src, int attr_id)
505 case IB_SA_ATTR_PATH_REC:
506 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), src, dst);
514 static void free_sm_ah(struct kref *kref)
516 struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref);
518 ib_destroy_ah(sm_ah->ah);
522 static void update_sm_ah(struct work_struct *work)
524 struct ib_sa_port *port =
525 container_of(work, struct ib_sa_port, update_task);
526 struct ib_sa_sm_ah *new_ah;
527 struct ib_port_attr port_attr;
528 struct ib_ah_attr ah_attr;
530 if (ib_query_port(port->agent->device, port->port_num, &port_attr)) {
531 printk(KERN_WARNING "Couldn't query port\n");
535 new_ah = kmalloc(sizeof *new_ah, GFP_KERNEL);
537 printk(KERN_WARNING "Couldn't allocate new SM AH\n");
541 kref_init(&new_ah->ref);
542 new_ah->src_path_mask = (1 << port_attr.lmc) - 1;
544 new_ah->pkey_index = 0;
545 if (ib_find_pkey(port->agent->device, port->port_num,
546 IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index))
547 printk(KERN_ERR "Couldn't find index for default PKey\n");
549 memset(&ah_attr, 0, sizeof ah_attr);
550 ah_attr.dlid = port_attr.sm_lid;
551 ah_attr.sl = port_attr.sm_sl;
552 ah_attr.port_num = port->port_num;
554 new_ah->ah = ib_create_ah(port->agent->qp->pd, &ah_attr);
555 if (IS_ERR(new_ah->ah)) {
556 printk(KERN_WARNING "Couldn't create new SM AH\n");
561 spin_lock_irq(&port->ah_lock);
563 kref_put(&port->sm_ah->ref, free_sm_ah);
564 port->sm_ah = new_ah;
565 spin_unlock_irq(&port->ah_lock);
569 static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event)
571 if (event->event == IB_EVENT_PORT_ERR ||
572 event->event == IB_EVENT_PORT_ACTIVE ||
573 event->event == IB_EVENT_LID_CHANGE ||
574 event->event == IB_EVENT_PKEY_CHANGE ||
575 event->event == IB_EVENT_SM_CHANGE ||
576 event->event == IB_EVENT_CLIENT_REREGISTER) {
578 struct ib_sa_device *sa_dev =
579 container_of(handler, typeof(*sa_dev), event_handler);
580 struct ib_sa_port *port =
581 &sa_dev->port[event->element.port_num - sa_dev->start_port];
583 if (rdma_port_get_link_layer(handler->device, port->port_num) != IB_LINK_LAYER_INFINIBAND)
586 spin_lock_irqsave(&port->ah_lock, flags);
588 kref_put(&port->sm_ah->ref, free_sm_ah);
590 spin_unlock_irqrestore(&port->ah_lock, flags);
592 schedule_work(&sa_dev->port[event->element.port_num -
593 sa_dev->start_port].update_task);
597 void ib_sa_register_client(struct ib_sa_client *client)
599 atomic_set(&client->users, 1);
600 init_completion(&client->comp);
602 EXPORT_SYMBOL(ib_sa_register_client);
604 void ib_sa_unregister_client(struct ib_sa_client *client)
606 ib_sa_client_put(client);
607 wait_for_completion(&client->comp);
609 EXPORT_SYMBOL(ib_sa_unregister_client);
612 * ib_sa_cancel_query - try to cancel an SA query
613 * @id:ID of query to cancel
614 * @query:query pointer to cancel
616 * Try to cancel an SA query. If the id and query don't match up or
617 * the query has already completed, nothing is done. Otherwise the
618 * query is canceled and will complete with a status of -EINTR.
620 void ib_sa_cancel_query(int id, struct ib_sa_query *query)
623 struct ib_mad_agent *agent;
624 struct ib_mad_send_buf *mad_buf;
626 spin_lock_irqsave(&idr_lock, flags);
627 if (idr_find(&query_idr, id) != query) {
628 spin_unlock_irqrestore(&idr_lock, flags);
631 agent = query->port->agent;
632 mad_buf = query->mad_buf;
633 spin_unlock_irqrestore(&idr_lock, flags);
635 ib_cancel_mad(agent, mad_buf);
637 EXPORT_SYMBOL(ib_sa_cancel_query);
639 static u8 get_src_path_mask(struct ib_device *device, u8 port_num)
641 struct ib_sa_device *sa_dev;
642 struct ib_sa_port *port;
646 sa_dev = ib_get_client_data(device, &sa_client);
650 port = &sa_dev->port[port_num - sa_dev->start_port];
651 spin_lock_irqsave(&port->ah_lock, flags);
652 src_path_mask = port->sm_ah ? port->sm_ah->src_path_mask : 0x7f;
653 spin_unlock_irqrestore(&port->ah_lock, flags);
655 return src_path_mask;
658 int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
659 struct ib_sa_path_rec *rec, struct ib_ah_attr *ah_attr)
665 memset(ah_attr, 0, sizeof *ah_attr);
666 ah_attr->dlid = be16_to_cpu(rec->dlid);
667 ah_attr->sl = rec->sl;
668 ah_attr->src_path_bits = be16_to_cpu(rec->slid) &
669 get_src_path_mask(device, port_num);
670 ah_attr->port_num = port_num;
671 ah_attr->static_rate = rec->rate;
673 force_grh = rdma_port_get_link_layer(device, port_num) == IB_LINK_LAYER_ETHERNET;
675 if (rec->hop_limit > 1 || force_grh) {
676 ah_attr->ah_flags = IB_AH_GRH;
677 ah_attr->grh.dgid = rec->dgid;
679 ret = ib_find_cached_gid(device, &rec->sgid, &port_num,
684 ah_attr->grh.sgid_index = gid_index;
685 ah_attr->grh.flow_label = be32_to_cpu(rec->flow_label);
686 ah_attr->grh.hop_limit = rec->hop_limit;
687 ah_attr->grh.traffic_class = rec->traffic_class;
691 EXPORT_SYMBOL(ib_init_ah_from_path);
693 static int alloc_mad(struct ib_sa_query *query, gfp_t gfp_mask)
697 spin_lock_irqsave(&query->port->ah_lock, flags);
698 if (!query->port->sm_ah) {
699 spin_unlock_irqrestore(&query->port->ah_lock, flags);
702 kref_get(&query->port->sm_ah->ref);
703 query->sm_ah = query->port->sm_ah;
704 spin_unlock_irqrestore(&query->port->ah_lock, flags);
706 query->mad_buf = ib_create_send_mad(query->port->agent, 1,
707 query->sm_ah->pkey_index,
708 0, IB_MGMT_SA_HDR, IB_MGMT_SA_DATA,
710 if (IS_ERR(query->mad_buf)) {
711 kref_put(&query->sm_ah->ref, free_sm_ah);
715 query->mad_buf->ah = query->sm_ah->ah;
720 static void free_mad(struct ib_sa_query *query)
722 ib_free_send_mad(query->mad_buf);
723 kref_put(&query->sm_ah->ref, free_sm_ah);
726 static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent)
730 memset(mad, 0, sizeof *mad);
732 mad->mad_hdr.base_version = IB_MGMT_BASE_VERSION;
733 mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM;
734 mad->mad_hdr.class_version = IB_SA_CLASS_VERSION;
736 spin_lock_irqsave(&tid_lock, flags);
738 cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++);
739 spin_unlock_irqrestore(&tid_lock, flags);
742 static int send_mad(struct ib_sa_query *query, int timeout_ms, gfp_t gfp_mask)
748 if (!idr_pre_get(&query_idr, gfp_mask))
750 spin_lock_irqsave(&idr_lock, flags);
751 ret = idr_get_new(&query_idr, query, &id);
752 spin_unlock_irqrestore(&idr_lock, flags);
758 query->mad_buf->timeout_ms = timeout_ms;
759 query->mad_buf->context[0] = query;
762 ret = ib_post_send_mad(query->mad_buf, NULL);
764 spin_lock_irqsave(&idr_lock, flags);
765 idr_remove(&query_idr, id);
766 spin_unlock_irqrestore(&idr_lock, flags);
770 * It's not safe to dereference query any more, because the
771 * send may already have completed and freed the query in
774 return ret ? ret : id;
777 void ib_sa_unpack_path(void *attribute, struct ib_sa_path_rec *rec)
779 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), attribute, rec);
781 EXPORT_SYMBOL(ib_sa_unpack_path);
783 static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query,
785 struct ib_sa_mad *mad)
787 struct ib_sa_path_query *query =
788 container_of(sa_query, struct ib_sa_path_query, sa_query);
791 struct ib_sa_path_rec rec;
793 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table),
795 query->callback(status, &rec, query->context);
797 query->callback(status, NULL, query->context);
800 static void ib_sa_path_rec_release(struct ib_sa_query *sa_query)
802 kfree(container_of(sa_query, struct ib_sa_path_query, sa_query));
805 int ib_sa_path_rec_query(struct ib_sa_client *client,
806 struct ib_device *device, u8 port_num,
807 struct ib_sa_path_rec *rec,
808 ib_sa_comp_mask comp_mask,
809 int timeout_ms, gfp_t gfp_mask,
810 void (*callback)(int status,
811 struct ib_sa_path_rec *resp,
814 struct ib_sa_query **sa_query)
816 struct ib_sa_path_query *query;
817 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
818 struct ib_sa_port *port;
819 struct ib_mad_agent *agent;
820 struct ib_sa_mad *mad;
826 port = &sa_dev->port[port_num - sa_dev->start_port];
829 query = kmalloc(sizeof *query, gfp_mask);
833 query->sa_query.port = port;
834 ret = alloc_mad(&query->sa_query, gfp_mask);
838 ib_sa_client_get(client);
839 query->sa_query.client = client;
840 query->callback = callback;
841 query->context = context;
843 mad = query->sa_query.mad_buf->mad;
844 init_mad(mad, agent);
846 query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL;
847 query->sa_query.release = ib_sa_path_rec_release;
848 mad->mad_hdr.method = IB_MGMT_METHOD_GET;
849 mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_PATH_REC);
850 mad->sa_hdr.comp_mask = comp_mask;
852 ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), rec, mad->data);
854 *sa_query = &query->sa_query;
856 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
864 ib_sa_client_put(query->sa_query.client);
865 free_mad(&query->sa_query);
872 static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query,
874 struct ib_sa_mad *mad)
876 struct ib_sa_service_query *query =
877 container_of(sa_query, struct ib_sa_service_query, sa_query);
880 struct ib_sa_service_rec rec;
882 ib_unpack(service_rec_table, ARRAY_SIZE(service_rec_table),
884 query->callback(status, &rec, query->context);
886 query->callback(status, NULL, query->context);
889 static void ib_sa_service_rec_release(struct ib_sa_query *sa_query)
891 kfree(container_of(sa_query, struct ib_sa_service_query, sa_query));
895 * ib_sa_service_rec_query - Start Service Record operation
897 * @device:device to send request on
898 * @port_num: port number to send request on
899 * @method:SA method - should be get, set, or delete
900 * @rec:Service Record to send in request
901 * @comp_mask:component mask to send in request
902 * @timeout_ms:time to wait for response
903 * @gfp_mask:GFP mask to use for internal allocations
904 * @callback:function called when request completes, times out or is
906 * @context:opaque user context passed to callback
907 * @sa_query:request context, used to cancel request
909 * Send a Service Record set/get/delete to the SA to register,
910 * unregister or query a service record.
911 * The callback function will be called when the request completes (or
912 * fails); status is 0 for a successful response, -EINTR if the query
913 * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
914 * occurred sending the query. The resp parameter of the callback is
915 * only valid if status is 0.
917 * If the return value of ib_sa_service_rec_query() is negative, it is an
918 * error code. Otherwise it is a request ID that can be used to cancel
921 int ib_sa_service_rec_query(struct ib_sa_client *client,
922 struct ib_device *device, u8 port_num, u8 method,
923 struct ib_sa_service_rec *rec,
924 ib_sa_comp_mask comp_mask,
925 int timeout_ms, gfp_t gfp_mask,
926 void (*callback)(int status,
927 struct ib_sa_service_rec *resp,
930 struct ib_sa_query **sa_query)
932 struct ib_sa_service_query *query;
933 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
934 struct ib_sa_port *port;
935 struct ib_mad_agent *agent;
936 struct ib_sa_mad *mad;
942 port = &sa_dev->port[port_num - sa_dev->start_port];
945 if (method != IB_MGMT_METHOD_GET &&
946 method != IB_MGMT_METHOD_SET &&
947 method != IB_SA_METHOD_DELETE)
950 query = kmalloc(sizeof *query, gfp_mask);
954 query->sa_query.port = port;
955 ret = alloc_mad(&query->sa_query, gfp_mask);
959 ib_sa_client_get(client);
960 query->sa_query.client = client;
961 query->callback = callback;
962 query->context = context;
964 mad = query->sa_query.mad_buf->mad;
965 init_mad(mad, agent);
967 query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL;
968 query->sa_query.release = ib_sa_service_rec_release;
969 mad->mad_hdr.method = method;
970 mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_SERVICE_REC);
971 mad->sa_hdr.comp_mask = comp_mask;
973 ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table),
976 *sa_query = &query->sa_query;
978 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
986 ib_sa_client_put(query->sa_query.client);
987 free_mad(&query->sa_query);
993 EXPORT_SYMBOL(ib_sa_service_rec_query);
995 static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query,
997 struct ib_sa_mad *mad)
999 struct ib_sa_mcmember_query *query =
1000 container_of(sa_query, struct ib_sa_mcmember_query, sa_query);
1003 struct ib_sa_mcmember_rec rec;
1005 ib_unpack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
1007 query->callback(status, &rec, query->context);
1009 query->callback(status, NULL, query->context);
1012 static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query)
1014 kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query));
1017 int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
1018 struct ib_device *device, u8 port_num,
1020 struct ib_sa_mcmember_rec *rec,
1021 ib_sa_comp_mask comp_mask,
1022 int timeout_ms, gfp_t gfp_mask,
1023 void (*callback)(int status,
1024 struct ib_sa_mcmember_rec *resp,
1027 struct ib_sa_query **sa_query)
1029 struct ib_sa_mcmember_query *query;
1030 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1031 struct ib_sa_port *port;
1032 struct ib_mad_agent *agent;
1033 struct ib_sa_mad *mad;
1039 port = &sa_dev->port[port_num - sa_dev->start_port];
1040 agent = port->agent;
1042 query = kmalloc(sizeof *query, gfp_mask);
1046 query->sa_query.port = port;
1047 ret = alloc_mad(&query->sa_query, gfp_mask);
1051 ib_sa_client_get(client);
1052 query->sa_query.client = client;
1053 query->callback = callback;
1054 query->context = context;
1056 mad = query->sa_query.mad_buf->mad;
1057 init_mad(mad, agent);
1059 query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL;
1060 query->sa_query.release = ib_sa_mcmember_rec_release;
1061 mad->mad_hdr.method = method;
1062 mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC);
1063 mad->sa_hdr.comp_mask = comp_mask;
1065 ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table),
1068 *sa_query = &query->sa_query;
1070 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
1078 ib_sa_client_put(query->sa_query.client);
1079 free_mad(&query->sa_query);
1086 static void ib_sa_inform_callback(struct ib_sa_query *sa_query,
1088 struct ib_sa_mad *mad)
1090 struct ib_sa_inform_query *query =
1091 container_of(sa_query, struct ib_sa_inform_query, sa_query);
1094 struct ib_sa_inform rec;
1096 ib_unpack(inform_table, ARRAY_SIZE(inform_table),
1098 query->callback(status, &rec, query->context);
1100 query->callback(status, NULL, query->context);
1103 static void ib_sa_inform_release(struct ib_sa_query *sa_query)
1105 kfree(container_of(sa_query, struct ib_sa_inform_query, sa_query));
1109 * ib_sa_informinfo_query - Start an InformInfo registration.
1111 * @device:device to send query on
1112 * @port_num: port number to send query on
1113 * @rec:Inform record to send in query
1114 * @timeout_ms:time to wait for response
1115 * @gfp_mask:GFP mask to use for internal allocations
1116 * @callback:function called when notice handler registration completes,
1117 * times out or is canceled
1118 * @context:opaque user context passed to callback
1119 * @sa_query:query context, used to cancel query
1121 * This function sends inform info to register with SA to receive
1122 * in-service notice.
1123 * The callback function will be called when the query completes (or
1124 * fails); status is 0 for a successful response, -EINTR if the query
1125 * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error
1126 * occurred sending the query. The resp parameter of the callback is
1127 * only valid if status is 0.
1129 * If the return value of ib_sa_inform_query() is negative, it is an
1130 * error code. Otherwise it is a query ID that can be used to cancel
1133 int ib_sa_informinfo_query(struct ib_sa_client *client,
1134 struct ib_device *device, u8 port_num,
1135 struct ib_sa_inform *rec,
1136 int timeout_ms, gfp_t gfp_mask,
1137 void (*callback)(int status,
1138 struct ib_sa_inform *resp,
1141 struct ib_sa_query **sa_query)
1143 struct ib_sa_inform_query *query;
1144 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1145 struct ib_sa_port *port;
1146 struct ib_mad_agent *agent;
1147 struct ib_sa_mad *mad;
1153 port = &sa_dev->port[port_num - sa_dev->start_port];
1154 agent = port->agent;
1156 query = kmalloc(sizeof *query, gfp_mask);
1160 query->sa_query.port = port;
1161 ret = alloc_mad(&query->sa_query, gfp_mask);
1165 ib_sa_client_get(client);
1166 query->sa_query.client = client;
1167 query->callback = callback;
1168 query->context = context;
1170 mad = query->sa_query.mad_buf->mad;
1171 init_mad(mad, agent);
1173 query->sa_query.callback = callback ? ib_sa_inform_callback : NULL;
1174 query->sa_query.release = ib_sa_inform_release;
1175 query->sa_query.port = port;
1176 mad->mad_hdr.method = IB_MGMT_METHOD_SET;
1177 mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_INFORM_INFO);
1179 ib_pack(inform_table, ARRAY_SIZE(inform_table), rec, mad->data);
1181 *sa_query = &query->sa_query;
1182 ret = send_mad(&query->sa_query, timeout_ms, gfp_mask);
1190 ib_sa_client_put(query->sa_query.client);
1191 free_mad(&query->sa_query);
1197 static void ib_sa_notice_resp(struct ib_sa_port *port,
1198 struct ib_mad_recv_wc *mad_recv_wc)
1200 struct ib_mad_send_buf *mad_buf;
1201 struct ib_sa_mad *mad;
1203 unsigned long flags;
1205 mad_buf = ib_create_send_mad(port->notice_agent, 1, 0, 0,
1206 IB_MGMT_SA_HDR, IB_MGMT_SA_DATA,
1208 if (IS_ERR(mad_buf))
1212 memcpy(mad, mad_recv_wc->recv_buf.mad, sizeof *mad);
1213 mad->mad_hdr.method = IB_MGMT_METHOD_REPORT_RESP;
1215 spin_lock_irqsave(&port->ah_lock, flags);
1217 spin_unlock_irqrestore(&port->ah_lock, flags);
1218 ib_free_send_mad(mad_buf);
1221 kref_get(&port->sm_ah->ref);
1222 mad_buf->context[0] = &port->sm_ah->ref;
1223 mad_buf->ah = port->sm_ah->ah;
1224 spin_unlock_irqrestore(&port->ah_lock, flags);
1226 ret = ib_post_send_mad(mad_buf, NULL);
1232 kref_put(mad_buf->context[0], free_sm_ah);
1233 ib_free_send_mad(mad_buf);
1236 static void send_handler(struct ib_mad_agent *agent,
1237 struct ib_mad_send_wc *mad_send_wc)
1239 struct ib_sa_query *query = mad_send_wc->send_buf->context[0];
1240 unsigned long flags;
1242 if (query->callback)
1243 switch (mad_send_wc->status) {
1245 /* No callback -- already got recv */
1247 case IB_WC_RESP_TIMEOUT_ERR:
1248 query->callback(query, -ETIMEDOUT, NULL);
1250 case IB_WC_WR_FLUSH_ERR:
1251 query->callback(query, -EINTR, NULL);
1254 query->callback(query, -EIO, NULL);
1258 spin_lock_irqsave(&idr_lock, flags);
1259 idr_remove(&query_idr, query->id);
1260 spin_unlock_irqrestore(&idr_lock, flags);
1263 ib_sa_client_put(query->client);
1264 query->release(query);
1267 static void recv_handler(struct ib_mad_agent *mad_agent,
1268 struct ib_mad_recv_wc *mad_recv_wc)
1270 struct ib_sa_query *query;
1271 struct ib_mad_send_buf *mad_buf;
1273 mad_buf = (void *) (unsigned long) mad_recv_wc->wc->wr_id;
1274 query = mad_buf->context[0];
1276 if (query->callback) {
1277 if (mad_recv_wc->wc->status == IB_WC_SUCCESS)
1278 query->callback(query,
1279 mad_recv_wc->recv_buf.mad->mad_hdr.status ?
1281 (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad);
1283 query->callback(query, -EIO, NULL);
1286 ib_free_recv_mad(mad_recv_wc);
1289 static void notice_resp_handler(struct ib_mad_agent *agent,
1290 struct ib_mad_send_wc *mad_send_wc)
1292 kref_put(mad_send_wc->send_buf->context[0], free_sm_ah);
1293 ib_free_send_mad(mad_send_wc->send_buf);
1296 static void notice_handler(struct ib_mad_agent *mad_agent,
1297 struct ib_mad_recv_wc *mad_recv_wc)
1299 struct ib_sa_port *port;
1300 struct ib_sa_mad *mad;
1301 struct ib_sa_notice notice;
1303 port = mad_agent->context;
1304 mad = (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad;
1305 ib_unpack(notice_table, ARRAY_SIZE(notice_table), mad->data, ¬ice);
1307 if (!notice_dispatch(port->device, port->port_num, ¬ice))
1308 ib_sa_notice_resp(port, mad_recv_wc);
1309 ib_free_recv_mad(mad_recv_wc);
1312 static void ib_sa_add_one(struct ib_device *device)
1314 struct ib_sa_device *sa_dev;
1315 struct ib_mad_reg_req reg_req = {
1316 .mgmt_class = IB_MGMT_CLASS_SUBN_ADM,
1317 .mgmt_class_version = 2
1321 if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
1324 if (device->node_type == RDMA_NODE_IB_SWITCH)
1328 e = device->phys_port_cnt;
1331 sa_dev = kzalloc(sizeof *sa_dev +
1332 (e - s + 1) * sizeof (struct ib_sa_port),
1337 sa_dev->start_port = s;
1338 sa_dev->end_port = e;
1340 for (i = 0; i <= e - s; ++i) {
1341 spin_lock_init(&sa_dev->port[i].ah_lock);
1342 if (rdma_port_get_link_layer(device, i + 1) != IB_LINK_LAYER_INFINIBAND)
1345 sa_dev->port[i].sm_ah = NULL;
1346 sa_dev->port[i].port_num = i + s;
1348 sa_dev->port[i].agent =
1349 ib_register_mad_agent(device, i + s, IB_QPT_GSI,
1350 NULL, 0, send_handler,
1351 recv_handler, sa_dev);
1352 if (IS_ERR(sa_dev->port[i].agent))
1355 sa_dev->port[i].device = device;
1356 set_bit(IB_MGMT_METHOD_REPORT, reg_req.method_mask);
1357 sa_dev->port[i].notice_agent =
1358 ib_register_mad_agent(device, i + s, IB_QPT_GSI,
1359 ®_req, 0, notice_resp_handler,
1360 notice_handler, &sa_dev->port[i]);
1362 if (IS_ERR(sa_dev->port[i].notice_agent))
1365 INIT_WORK(&sa_dev->port[i].update_task, update_sm_ah);
1368 ib_set_client_data(device, &sa_client, sa_dev);
1371 * We register our event handler after everything is set up,
1372 * and then update our cached info after the event handler is
1373 * registered to avoid any problems if a port changes state
1374 * during our initialization.
1377 INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event);
1378 if (ib_register_event_handler(&sa_dev->event_handler))
1381 for (i = 0; i <= e - s; ++i)
1382 if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND)
1383 update_sm_ah(&sa_dev->port[i].update_task);
1389 if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND) {
1390 if (!IS_ERR(sa_dev->port[i].notice_agent))
1391 ib_unregister_mad_agent(sa_dev->port[i].notice_agent);
1392 if (!IS_ERR(sa_dev->port[i].agent))
1393 ib_unregister_mad_agent(sa_dev->port[i].agent);
1401 static void ib_sa_remove_one(struct ib_device *device)
1403 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client);
1409 ib_unregister_event_handler(&sa_dev->event_handler);
1411 flush_scheduled_work();
1413 for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) {
1414 if (rdma_port_get_link_layer(device, i + 1) == IB_LINK_LAYER_INFINIBAND) {
1415 ib_unregister_mad_agent(sa_dev->port[i].notice_agent);
1416 ib_unregister_mad_agent(sa_dev->port[i].agent);
1417 if (sa_dev->port[i].sm_ah)
1418 kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah);
1426 static int __init ib_sa_init(void)
1430 spin_lock_init(&idr_lock);
1431 spin_lock_init(&tid_lock);
1433 get_random_bytes(&tid, sizeof tid);
1435 ret = ib_register_client(&sa_client);
1437 printk(KERN_ERR "Couldn't register ib_sa client\n");
1443 printk(KERN_ERR "Couldn't initialize multicast handling\n");
1447 ret = notice_init();
1449 printk(KERN_ERR "Couldn't initialize notice handling\n");
1455 printk(KERN_ERR "Couldn't initialize local SA\n");
1465 ib_unregister_client(&sa_client);
1470 static void __exit ib_sa_cleanup(void)
1475 ib_unregister_client(&sa_client);
1476 idr_destroy(&query_idr);
1479 module_init_order(ib_sa_init, SI_ORDER_SECOND);
1480 module_exit(ib_sa_cleanup);