35 #include <linux/module.h>
38 #include <linux/random.h>
40 #include <linux/slab.h>
114 .add = ib_sa_add_one,
115 .remove = ib_sa_remove_one
124 #define PATH_REC_FIELD(field) \
125 .struct_offset_bytes = offsetof(struct ib_sa_path_rec, field), \
126 .struct_size_bytes = sizeof ((struct ib_sa_path_rec *) 0)->field, \
127 .field_name = "sa_path_rec:" #field
129 static const struct ib_field path_rec_table[] = {
224 #define MCMEMBER_REC_FIELD(field) \
225 .struct_offset_bytes = offsetof(struct ib_sa_mcmember_rec, field), \
226 .struct_size_bytes = sizeof ((struct ib_sa_mcmember_rec *) 0)->field, \
227 .field_name = "sa_mcmember_rec:" #field
229 static const struct ib_field mcmember_rec_table[] = {
308 #define SERVICE_REC_FIELD(field) \
309 .struct_offset_bytes = offsetof(struct ib_sa_service_rec, field), \
310 .struct_size_bytes = sizeof ((struct ib_sa_service_rec *) 0)->field, \
311 .field_name = "sa_service_rec:" #field
313 static const struct ib_field service_rec_table[] = {
356 #define GUIDINFO_REC_FIELD(field) \
357 .struct_offset_bytes = offsetof(struct ib_sa_guidinfo_rec, field), \
358 .struct_size_bytes = sizeof((struct ib_sa_guidinfo_rec *) 0)->field, \
359 .field_name = "sa_guidinfo_rec:" #field
361 static const struct ib_field guidinfo_rec_table[] = {
384 static void free_sm_ah(
struct kref *
kref)
411 kref_init(&new_ah->
ref);
419 memset(&ah_attr, 0,
sizeof ah_attr);
420 ah_attr.dlid = port_attr.sm_lid;
421 ah_attr.sl = port_attr.sm_sl;
425 if (IS_ERR(new_ah->
ah)) {
433 kref_put(&port->
sm_ah->ref, free_sm_ah);
434 port->
sm_ah = new_ah;
435 spin_unlock_irq(&port->
ah_lock);
458 kref_put(&port->
sm_ah->ref, free_sm_ah);
460 spin_unlock_irqrestore(&port->
ah_lock, flags);
470 init_completion(&client->
comp);
476 ib_sa_client_put(client);
497 if (
idr_find(&query_idr,
id) != query) {
498 spin_unlock_irqrestore(&idr_lock, flags);
501 agent = query->
port->agent;
503 spin_unlock_irqrestore(&idr_lock, flags);
522 src_path_mask = port->
sm_ah ? port->
sm_ah->src_path_mask : 0x7f;
523 spin_unlock_irqrestore(&port->
ah_lock, flags);
525 return src_path_mask;
535 memset(ah_attr, 0,
sizeof *ah_attr);
537 ah_attr->
sl = rec->
sl;
539 get_src_path_mask(device, port_num);
554 ah_attr->
grh.sgid_index = gid_index;
568 if (!query->
port->sm_ah) {
569 spin_unlock_irqrestore(&query->
port->ah_lock, flags);
572 kref_get(&query->
port->sm_ah->ref);
574 spin_unlock_irqrestore(&query->
port->ah_lock, flags);
577 query->
sm_ah->pkey_index,
581 kref_put(&query->
sm_ah->ref, free_sm_ah);
593 kref_put(&query->
sm_ah->ref, free_sm_ah);
600 memset(mad, 0,
sizeof *mad);
609 spin_unlock_irqrestore(&tid_lock, flags);
622 spin_unlock_irqrestore(&idr_lock, flags);
636 spin_unlock_irqrestore(&idr_lock, flags);
644 return ret ? ret :
id;
653 static void ib_sa_path_rec_callback(
struct ib_sa_query *sa_query,
670 static void ib_sa_path_rec_release(
struct ib_sa_query *sa_query)
704 int timeout_ms,
gfp_t gfp_mask,
724 query =
kmalloc(
sizeof *query, gfp_mask);
729 ret = alloc_mad(&query->
sa_query, gfp_mask);
733 ib_sa_client_get(client);
739 init_mad(mad, agent);
742 query->
sa_query.release = ib_sa_path_rec_release;
751 ret = send_mad(&query->
sa_query, timeout_ms, gfp_mask);
759 ib_sa_client_put(query->
sa_query.client);
768 static void ib_sa_service_rec_callback(
struct ib_sa_query *sa_query,
785 static void ib_sa_service_rec_release(
struct ib_sa_query *sa_query)
821 int timeout_ms,
gfp_t gfp_mask,
846 query =
kmalloc(
sizeof *query, gfp_mask);
851 ret = alloc_mad(&query->
sa_query, gfp_mask);
855 ib_sa_client_get(client);
861 init_mad(mad, agent);
864 query->
sa_query.release = ib_sa_service_rec_release;
874 ret = send_mad(&query->
sa_query, timeout_ms, gfp_mask);
882 ib_sa_client_put(query->
sa_query.client);
891 static void ib_sa_mcmember_rec_callback(
struct ib_sa_query *sa_query,
908 static void ib_sa_mcmember_rec_release(
struct ib_sa_query *sa_query)
918 int timeout_ms,
gfp_t gfp_mask,
938 query =
kmalloc(
sizeof *query, gfp_mask);
943 ret = alloc_mad(&query->
sa_query, gfp_mask);
947 ib_sa_client_get(client);
953 init_mad(mad, agent);
956 query->
sa_query.release = ib_sa_mcmember_rec_release;
966 ret = send_mad(&query->
sa_query, timeout_ms, gfp_mask);
974 ib_sa_client_put(query->
sa_query.client);
983 static void ib_sa_guidinfo_rec_callback(
struct ib_sa_query *sa_query,
1000 static void ib_sa_guidinfo_rec_release(
struct ib_sa_query *sa_query)
1009 int timeout_ms,
gfp_t gfp_mask,
1033 agent = port->
agent;
1035 query =
kmalloc(
sizeof *query, gfp_mask);
1040 ret = alloc_mad(&query->
sa_query, gfp_mask);
1044 ib_sa_client_get(client);
1049 mad = query->
sa_query.mad_buf->mad;
1050 init_mad(mad, agent);
1053 query->
sa_query.release = ib_sa_guidinfo_rec_release;
1064 ret = send_mad(&query->
sa_query, timeout_ms, gfp_mask);
1072 ib_sa_client_put(query->
sa_query.client);
1085 unsigned long flags;
1088 switch (mad_send_wc->
status) {
1105 spin_unlock_irqrestore(&idr_lock, flags);
1108 ib_sa_client_put(query->
client);
1112 static void recv_handler(
struct ib_mad_agent *mad_agent,
1118 mad_buf = (
void *) (
unsigned long) mad_recv_wc->
wc->wr_id;
1124 mad_recv_wc->
recv_buf.mad->mad_hdr.status ?
1134 static void ib_sa_add_one(
struct ib_device *device)
1149 sa_dev = kzalloc(
sizeof *sa_dev +
1158 for (i = 0; i <= e -
s; ++
i) {
1164 sa_dev->
port[
i].port_num = i +
s;
1166 sa_dev->
port[
i].agent =
1168 NULL, 0, send_handler,
1169 recv_handler, sa_dev);
1170 if (IS_ERR(sa_dev->
port[i].agent))
1189 for (i = 0; i <= e -
s; ++
i)
1191 update_sm_ah(&sa_dev->
port[i].update_task);
1205 static void ib_sa_remove_one(
struct ib_device *device)
1220 if (sa_dev->
port[i].sm_ah)
1221 kref_put(&sa_dev->
port[i].sm_ah->ref, free_sm_ah);
1229 static int __init ib_sa_init(
void)
1254 static void __exit ib_sa_cleanup(
void)