1 /* 2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 4 * 5 * 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 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the 9 * OpenIB.org BSD license below: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * - Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 * 33 * $Id: sa_query.c 2811 2005-07-06 18:11:43Z halr $ 34 */ 35 36 #include <linux/module.h> 37 #include <linux/init.h> 38 #include <linux/err.h> 39 #include <linux/random.h> 40 #include <linux/spinlock.h> 41 #include <linux/slab.h> 42 #include <linux/pci.h> 43 #include <linux/dma-mapping.h> 44 #include <linux/kref.h> 45 #include <linux/idr.h> 46 47 #include <rdma/ib_pack.h> 48 #include <rdma/ib_sa.h> 49 50 MODULE_AUTHOR("Roland Dreier"); 51 MODULE_DESCRIPTION("InfiniBand subnet administration query support"); 52 MODULE_LICENSE("Dual BSD/GPL"); 53 54 struct ib_sa_sm_ah { 55 struct ib_ah *ah; 56 struct kref ref; 57 }; 58 59 struct ib_sa_port { 60 struct ib_mad_agent *agent; 61 struct ib_sa_sm_ah *sm_ah; 62 struct work_struct update_task; 63 spinlock_t ah_lock; 64 u8 port_num; 65 }; 66 67 struct ib_sa_device { 68 int start_port, end_port; 69 struct ib_event_handler event_handler; 70 struct ib_sa_port port[0]; 71 }; 72 73 struct ib_sa_query { 74 void (*callback)(struct ib_sa_query *, int, struct ib_sa_mad *); 75 void (*release)(struct ib_sa_query *); 76 struct ib_sa_port *port; 77 struct ib_sa_mad *mad; 78 struct ib_sa_sm_ah *sm_ah; 79 DECLARE_PCI_UNMAP_ADDR(mapping) 80 int id; 81 }; 82 83 struct ib_sa_service_query { 84 void (*callback)(int, struct ib_sa_service_rec *, void *); 85 void *context; 86 struct ib_sa_query sa_query; 87 }; 88 89 struct ib_sa_path_query { 90 void (*callback)(int, struct ib_sa_path_rec *, void *); 91 void *context; 92 struct ib_sa_query sa_query; 93 }; 94 95 struct ib_sa_mcmember_query { 96 void (*callback)(int, struct ib_sa_mcmember_rec *, void *); 97 void *context; 98 struct ib_sa_query sa_query; 99 }; 100 101 static void ib_sa_add_one(struct ib_device *device); 102 static void ib_sa_remove_one(struct ib_device *device); 103 104 static struct ib_client sa_client = { 105 .name = "sa", 106 .add = ib_sa_add_one, 107 .remove = ib_sa_remove_one 108 }; 109 110 static spinlock_t idr_lock; 111 static DEFINE_IDR(query_idr); 112 113 static spinlock_t tid_lock; 114 static u32 tid; 115 116 enum { 117 IB_SA_ATTR_CLASS_PORTINFO = 0x01, 118 IB_SA_ATTR_NOTICE = 0x02, 119 IB_SA_ATTR_INFORM_INFO = 0x03, 120 IB_SA_ATTR_NODE_REC = 0x11, 121 IB_SA_ATTR_PORT_INFO_REC = 0x12, 122 IB_SA_ATTR_SL2VL_REC = 0x13, 123 IB_SA_ATTR_SWITCH_REC = 0x14, 124 IB_SA_ATTR_LINEAR_FDB_REC = 0x15, 125 IB_SA_ATTR_RANDOM_FDB_REC = 0x16, 126 IB_SA_ATTR_MCAST_FDB_REC = 0x17, 127 IB_SA_ATTR_SM_INFO_REC = 0x18, 128 IB_SA_ATTR_LINK_REC = 0x20, 129 IB_SA_ATTR_GUID_INFO_REC = 0x30, 130 IB_SA_ATTR_SERVICE_REC = 0x31, 131 IB_SA_ATTR_PARTITION_REC = 0x33, 132 IB_SA_ATTR_RANGE_REC = 0x34, 133 IB_SA_ATTR_PATH_REC = 0x35, 134 IB_SA_ATTR_VL_ARB_REC = 0x36, 135 IB_SA_ATTR_MC_GROUP_REC = 0x37, 136 IB_SA_ATTR_MC_MEMBER_REC = 0x38, 137 IB_SA_ATTR_TRACE_REC = 0x39, 138 IB_SA_ATTR_MULTI_PATH_REC = 0x3a, 139 IB_SA_ATTR_SERVICE_ASSOC_REC = 0x3b 140 }; 141 142 #define PATH_REC_FIELD(field) \ 143 .struct_offset_bytes = offsetof(struct ib_sa_path_rec, field), \ 144 .struct_size_bytes = sizeof ((struct ib_sa_path_rec *) 0)->field, \ 145 .field_name = "sa_path_rec:" #field 146 147 static const struct ib_field path_rec_table[] = { 148 { RESERVED, 149 .offset_words = 0, 150 .offset_bits = 0, 151 .size_bits = 32 }, 152 { RESERVED, 153 .offset_words = 1, 154 .offset_bits = 0, 155 .size_bits = 32 }, 156 { PATH_REC_FIELD(dgid), 157 .offset_words = 2, 158 .offset_bits = 0, 159 .size_bits = 128 }, 160 { PATH_REC_FIELD(sgid), 161 .offset_words = 6, 162 .offset_bits = 0, 163 .size_bits = 128 }, 164 { PATH_REC_FIELD(dlid), 165 .offset_words = 10, 166 .offset_bits = 0, 167 .size_bits = 16 }, 168 { PATH_REC_FIELD(slid), 169 .offset_words = 10, 170 .offset_bits = 16, 171 .size_bits = 16 }, 172 { PATH_REC_FIELD(raw_traffic), 173 .offset_words = 11, 174 .offset_bits = 0, 175 .size_bits = 1 }, 176 { RESERVED, 177 .offset_words = 11, 178 .offset_bits = 1, 179 .size_bits = 3 }, 180 { PATH_REC_FIELD(flow_label), 181 .offset_words = 11, 182 .offset_bits = 4, 183 .size_bits = 20 }, 184 { PATH_REC_FIELD(hop_limit), 185 .offset_words = 11, 186 .offset_bits = 24, 187 .size_bits = 8 }, 188 { PATH_REC_FIELD(traffic_class), 189 .offset_words = 12, 190 .offset_bits = 0, 191 .size_bits = 8 }, 192 { PATH_REC_FIELD(reversible), 193 .offset_words = 12, 194 .offset_bits = 8, 195 .size_bits = 1 }, 196 { PATH_REC_FIELD(numb_path), 197 .offset_words = 12, 198 .offset_bits = 9, 199 .size_bits = 7 }, 200 { PATH_REC_FIELD(pkey), 201 .offset_words = 12, 202 .offset_bits = 16, 203 .size_bits = 16 }, 204 { RESERVED, 205 .offset_words = 13, 206 .offset_bits = 0, 207 .size_bits = 12 }, 208 { PATH_REC_FIELD(sl), 209 .offset_words = 13, 210 .offset_bits = 12, 211 .size_bits = 4 }, 212 { PATH_REC_FIELD(mtu_selector), 213 .offset_words = 13, 214 .offset_bits = 16, 215 .size_bits = 2 }, 216 { PATH_REC_FIELD(mtu), 217 .offset_words = 13, 218 .offset_bits = 18, 219 .size_bits = 6 }, 220 { PATH_REC_FIELD(rate_selector), 221 .offset_words = 13, 222 .offset_bits = 24, 223 .size_bits = 2 }, 224 { PATH_REC_FIELD(rate), 225 .offset_words = 13, 226 .offset_bits = 26, 227 .size_bits = 6 }, 228 { PATH_REC_FIELD(packet_life_time_selector), 229 .offset_words = 14, 230 .offset_bits = 0, 231 .size_bits = 2 }, 232 { PATH_REC_FIELD(packet_life_time), 233 .offset_words = 14, 234 .offset_bits = 2, 235 .size_bits = 6 }, 236 { PATH_REC_FIELD(preference), 237 .offset_words = 14, 238 .offset_bits = 8, 239 .size_bits = 8 }, 240 { RESERVED, 241 .offset_words = 14, 242 .offset_bits = 16, 243 .size_bits = 48 }, 244 }; 245 246 #define MCMEMBER_REC_FIELD(field) \ 247 .struct_offset_bytes = offsetof(struct ib_sa_mcmember_rec, field), \ 248 .struct_size_bytes = sizeof ((struct ib_sa_mcmember_rec *) 0)->field, \ 249 .field_name = "sa_mcmember_rec:" #field 250 251 static const struct ib_field mcmember_rec_table[] = { 252 { MCMEMBER_REC_FIELD(mgid), 253 .offset_words = 0, 254 .offset_bits = 0, 255 .size_bits = 128 }, 256 { MCMEMBER_REC_FIELD(port_gid), 257 .offset_words = 4, 258 .offset_bits = 0, 259 .size_bits = 128 }, 260 { MCMEMBER_REC_FIELD(qkey), 261 .offset_words = 8, 262 .offset_bits = 0, 263 .size_bits = 32 }, 264 { MCMEMBER_REC_FIELD(mlid), 265 .offset_words = 9, 266 .offset_bits = 0, 267 .size_bits = 16 }, 268 { MCMEMBER_REC_FIELD(mtu_selector), 269 .offset_words = 9, 270 .offset_bits = 16, 271 .size_bits = 2 }, 272 { MCMEMBER_REC_FIELD(mtu), 273 .offset_words = 9, 274 .offset_bits = 18, 275 .size_bits = 6 }, 276 { MCMEMBER_REC_FIELD(traffic_class), 277 .offset_words = 9, 278 .offset_bits = 24, 279 .size_bits = 8 }, 280 { MCMEMBER_REC_FIELD(pkey), 281 .offset_words = 10, 282 .offset_bits = 0, 283 .size_bits = 16 }, 284 { MCMEMBER_REC_FIELD(rate_selector), 285 .offset_words = 10, 286 .offset_bits = 16, 287 .size_bits = 2 }, 288 { MCMEMBER_REC_FIELD(rate), 289 .offset_words = 10, 290 .offset_bits = 18, 291 .size_bits = 6 }, 292 { MCMEMBER_REC_FIELD(packet_life_time_selector), 293 .offset_words = 10, 294 .offset_bits = 24, 295 .size_bits = 2 }, 296 { MCMEMBER_REC_FIELD(packet_life_time), 297 .offset_words = 10, 298 .offset_bits = 26, 299 .size_bits = 6 }, 300 { MCMEMBER_REC_FIELD(sl), 301 .offset_words = 11, 302 .offset_bits = 0, 303 .size_bits = 4 }, 304 { MCMEMBER_REC_FIELD(flow_label), 305 .offset_words = 11, 306 .offset_bits = 4, 307 .size_bits = 20 }, 308 { MCMEMBER_REC_FIELD(hop_limit), 309 .offset_words = 11, 310 .offset_bits = 24, 311 .size_bits = 8 }, 312 { MCMEMBER_REC_FIELD(scope), 313 .offset_words = 12, 314 .offset_bits = 0, 315 .size_bits = 4 }, 316 { MCMEMBER_REC_FIELD(join_state), 317 .offset_words = 12, 318 .offset_bits = 4, 319 .size_bits = 4 }, 320 { MCMEMBER_REC_FIELD(proxy_join), 321 .offset_words = 12, 322 .offset_bits = 8, 323 .size_bits = 1 }, 324 { RESERVED, 325 .offset_words = 12, 326 .offset_bits = 9, 327 .size_bits = 23 }, 328 }; 329 330 #define SERVICE_REC_FIELD(field) \ 331 .struct_offset_bytes = offsetof(struct ib_sa_service_rec, field), \ 332 .struct_size_bytes = sizeof ((struct ib_sa_service_rec *) 0)->field, \ 333 .field_name = "sa_service_rec:" #field 334 335 static const struct ib_field service_rec_table[] = { 336 { SERVICE_REC_FIELD(id), 337 .offset_words = 0, 338 .offset_bits = 0, 339 .size_bits = 64 }, 340 { SERVICE_REC_FIELD(gid), 341 .offset_words = 2, 342 .offset_bits = 0, 343 .size_bits = 128 }, 344 { SERVICE_REC_FIELD(pkey), 345 .offset_words = 6, 346 .offset_bits = 0, 347 .size_bits = 16 }, 348 { SERVICE_REC_FIELD(lease), 349 .offset_words = 7, 350 .offset_bits = 0, 351 .size_bits = 32 }, 352 { SERVICE_REC_FIELD(key), 353 .offset_words = 8, 354 .offset_bits = 0, 355 .size_bits = 128 }, 356 { SERVICE_REC_FIELD(name), 357 .offset_words = 12, 358 .offset_bits = 0, 359 .size_bits = 64*8 }, 360 { SERVICE_REC_FIELD(data8), 361 .offset_words = 28, 362 .offset_bits = 0, 363 .size_bits = 16*8 }, 364 { SERVICE_REC_FIELD(data16), 365 .offset_words = 32, 366 .offset_bits = 0, 367 .size_bits = 8*16 }, 368 { SERVICE_REC_FIELD(data32), 369 .offset_words = 36, 370 .offset_bits = 0, 371 .size_bits = 4*32 }, 372 { SERVICE_REC_FIELD(data64), 373 .offset_words = 40, 374 .offset_bits = 0, 375 .size_bits = 2*64 }, 376 }; 377 378 static void free_sm_ah(struct kref *kref) 379 { 380 struct ib_sa_sm_ah *sm_ah = container_of(kref, struct ib_sa_sm_ah, ref); 381 382 ib_destroy_ah(sm_ah->ah); 383 kfree(sm_ah); 384 } 385 386 static void update_sm_ah(void *port_ptr) 387 { 388 struct ib_sa_port *port = port_ptr; 389 struct ib_sa_sm_ah *new_ah, *old_ah; 390 struct ib_port_attr port_attr; 391 struct ib_ah_attr ah_attr; 392 393 if (ib_query_port(port->agent->device, port->port_num, &port_attr)) { 394 printk(KERN_WARNING "Couldn't query port\n"); 395 return; 396 } 397 398 new_ah = kmalloc(sizeof *new_ah, GFP_KERNEL); 399 if (!new_ah) { 400 printk(KERN_WARNING "Couldn't allocate new SM AH\n"); 401 return; 402 } 403 404 kref_init(&new_ah->ref); 405 406 memset(&ah_attr, 0, sizeof ah_attr); 407 ah_attr.dlid = port_attr.sm_lid; 408 ah_attr.sl = port_attr.sm_sl; 409 ah_attr.port_num = port->port_num; 410 411 new_ah->ah = ib_create_ah(port->agent->qp->pd, &ah_attr); 412 if (IS_ERR(new_ah->ah)) { 413 printk(KERN_WARNING "Couldn't create new SM AH\n"); 414 kfree(new_ah); 415 return; 416 } 417 418 spin_lock_irq(&port->ah_lock); 419 old_ah = port->sm_ah; 420 port->sm_ah = new_ah; 421 spin_unlock_irq(&port->ah_lock); 422 423 if (old_ah) 424 kref_put(&old_ah->ref, free_sm_ah); 425 } 426 427 static void ib_sa_event(struct ib_event_handler *handler, struct ib_event *event) 428 { 429 if (event->event == IB_EVENT_PORT_ERR || 430 event->event == IB_EVENT_PORT_ACTIVE || 431 event->event == IB_EVENT_LID_CHANGE || 432 event->event == IB_EVENT_PKEY_CHANGE || 433 event->event == IB_EVENT_SM_CHANGE) { 434 struct ib_sa_device *sa_dev = 435 ib_get_client_data(event->device, &sa_client); 436 437 schedule_work(&sa_dev->port[event->element.port_num - 438 sa_dev->start_port].update_task); 439 } 440 } 441 442 /** 443 * ib_sa_cancel_query - try to cancel an SA query 444 * @id:ID of query to cancel 445 * @query:query pointer to cancel 446 * 447 * Try to cancel an SA query. If the id and query don't match up or 448 * the query has already completed, nothing is done. Otherwise the 449 * query is canceled and will complete with a status of -EINTR. 450 */ 451 void ib_sa_cancel_query(int id, struct ib_sa_query *query) 452 { 453 unsigned long flags; 454 struct ib_mad_agent *agent; 455 456 spin_lock_irqsave(&idr_lock, flags); 457 if (idr_find(&query_idr, id) != query) { 458 spin_unlock_irqrestore(&idr_lock, flags); 459 return; 460 } 461 agent = query->port->agent; 462 spin_unlock_irqrestore(&idr_lock, flags); 463 464 ib_cancel_mad(agent, id); 465 } 466 EXPORT_SYMBOL(ib_sa_cancel_query); 467 468 static void init_mad(struct ib_sa_mad *mad, struct ib_mad_agent *agent) 469 { 470 unsigned long flags; 471 472 memset(mad, 0, sizeof *mad); 473 474 mad->mad_hdr.base_version = IB_MGMT_BASE_VERSION; 475 mad->mad_hdr.mgmt_class = IB_MGMT_CLASS_SUBN_ADM; 476 mad->mad_hdr.class_version = IB_SA_CLASS_VERSION; 477 478 spin_lock_irqsave(&tid_lock, flags); 479 mad->mad_hdr.tid = 480 cpu_to_be64(((u64) agent->hi_tid) << 32 | tid++); 481 spin_unlock_irqrestore(&tid_lock, flags); 482 } 483 484 static int send_mad(struct ib_sa_query *query, int timeout_ms) 485 { 486 struct ib_sa_port *port = query->port; 487 unsigned long flags; 488 int ret; 489 struct ib_sge gather_list; 490 struct ib_send_wr *bad_wr, wr = { 491 .opcode = IB_WR_SEND, 492 .sg_list = &gather_list, 493 .num_sge = 1, 494 .send_flags = IB_SEND_SIGNALED, 495 .wr = { 496 .ud = { 497 .mad_hdr = &query->mad->mad_hdr, 498 .remote_qpn = 1, 499 .remote_qkey = IB_QP1_QKEY, 500 .timeout_ms = timeout_ms, 501 } 502 } 503 }; 504 505 retry: 506 if (!idr_pre_get(&query_idr, GFP_ATOMIC)) 507 return -ENOMEM; 508 spin_lock_irqsave(&idr_lock, flags); 509 ret = idr_get_new(&query_idr, query, &query->id); 510 spin_unlock_irqrestore(&idr_lock, flags); 511 if (ret == -EAGAIN) 512 goto retry; 513 if (ret) 514 return ret; 515 516 wr.wr_id = query->id; 517 518 spin_lock_irqsave(&port->ah_lock, flags); 519 kref_get(&port->sm_ah->ref); 520 query->sm_ah = port->sm_ah; 521 wr.wr.ud.ah = port->sm_ah->ah; 522 spin_unlock_irqrestore(&port->ah_lock, flags); 523 524 gather_list.addr = dma_map_single(port->agent->device->dma_device, 525 query->mad, 526 sizeof (struct ib_sa_mad), 527 DMA_TO_DEVICE); 528 gather_list.length = sizeof (struct ib_sa_mad); 529 gather_list.lkey = port->agent->mr->lkey; 530 pci_unmap_addr_set(query, mapping, gather_list.addr); 531 532 ret = ib_post_send_mad(port->agent, &wr, &bad_wr); 533 if (ret) { 534 dma_unmap_single(port->agent->device->dma_device, 535 pci_unmap_addr(query, mapping), 536 sizeof (struct ib_sa_mad), 537 DMA_TO_DEVICE); 538 kref_put(&query->sm_ah->ref, free_sm_ah); 539 spin_lock_irqsave(&idr_lock, flags); 540 idr_remove(&query_idr, query->id); 541 spin_unlock_irqrestore(&idr_lock, flags); 542 } 543 544 /* 545 * It's not safe to dereference query any more, because the 546 * send may already have completed and freed the query in 547 * another context. So use wr.wr_id, which has a copy of the 548 * query's id. 549 */ 550 return ret ? ret : wr.wr_id; 551 } 552 553 static void ib_sa_path_rec_callback(struct ib_sa_query *sa_query, 554 int status, 555 struct ib_sa_mad *mad) 556 { 557 struct ib_sa_path_query *query = 558 container_of(sa_query, struct ib_sa_path_query, sa_query); 559 560 if (mad) { 561 struct ib_sa_path_rec rec; 562 563 ib_unpack(path_rec_table, ARRAY_SIZE(path_rec_table), 564 mad->data, &rec); 565 query->callback(status, &rec, query->context); 566 } else 567 query->callback(status, NULL, query->context); 568 } 569 570 static void ib_sa_path_rec_release(struct ib_sa_query *sa_query) 571 { 572 kfree(sa_query->mad); 573 kfree(container_of(sa_query, struct ib_sa_path_query, sa_query)); 574 } 575 576 /** 577 * ib_sa_path_rec_get - Start a Path get query 578 * @device:device to send query on 579 * @port_num: port number to send query on 580 * @rec:Path Record to send in query 581 * @comp_mask:component mask to send in query 582 * @timeout_ms:time to wait for response 583 * @gfp_mask:GFP mask to use for internal allocations 584 * @callback:function called when query completes, times out or is 585 * canceled 586 * @context:opaque user context passed to callback 587 * @sa_query:query context, used to cancel query 588 * 589 * Send a Path Record Get query to the SA to look up a path. The 590 * callback function will be called when the query completes (or 591 * fails); status is 0 for a successful response, -EINTR if the query 592 * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error 593 * occurred sending the query. The resp parameter of the callback is 594 * only valid if status is 0. 595 * 596 * If the return value of ib_sa_path_rec_get() is negative, it is an 597 * error code. Otherwise it is a query ID that can be used to cancel 598 * the query. 599 */ 600 int ib_sa_path_rec_get(struct ib_device *device, u8 port_num, 601 struct ib_sa_path_rec *rec, 602 ib_sa_comp_mask comp_mask, 603 int timeout_ms, unsigned int __nocast gfp_mask, 604 void (*callback)(int status, 605 struct ib_sa_path_rec *resp, 606 void *context), 607 void *context, 608 struct ib_sa_query **sa_query) 609 { 610 struct ib_sa_path_query *query; 611 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); 612 struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port]; 613 struct ib_mad_agent *agent = port->agent; 614 int ret; 615 616 query = kmalloc(sizeof *query, gfp_mask); 617 if (!query) 618 return -ENOMEM; 619 query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask); 620 if (!query->sa_query.mad) { 621 kfree(query); 622 return -ENOMEM; 623 } 624 625 query->callback = callback; 626 query->context = context; 627 628 init_mad(query->sa_query.mad, agent); 629 630 query->sa_query.callback = callback ? ib_sa_path_rec_callback : NULL; 631 query->sa_query.release = ib_sa_path_rec_release; 632 query->sa_query.port = port; 633 query->sa_query.mad->mad_hdr.method = IB_MGMT_METHOD_GET; 634 query->sa_query.mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_PATH_REC); 635 query->sa_query.mad->sa_hdr.comp_mask = comp_mask; 636 637 ib_pack(path_rec_table, ARRAY_SIZE(path_rec_table), 638 rec, query->sa_query.mad->data); 639 640 *sa_query = &query->sa_query; 641 642 ret = send_mad(&query->sa_query, timeout_ms); 643 if (ret < 0) { 644 *sa_query = NULL; 645 kfree(query->sa_query.mad); 646 kfree(query); 647 } 648 649 return ret; 650 } 651 EXPORT_SYMBOL(ib_sa_path_rec_get); 652 653 static void ib_sa_service_rec_callback(struct ib_sa_query *sa_query, 654 int status, 655 struct ib_sa_mad *mad) 656 { 657 struct ib_sa_service_query *query = 658 container_of(sa_query, struct ib_sa_service_query, sa_query); 659 660 if (mad) { 661 struct ib_sa_service_rec rec; 662 663 ib_unpack(service_rec_table, ARRAY_SIZE(service_rec_table), 664 mad->data, &rec); 665 query->callback(status, &rec, query->context); 666 } else 667 query->callback(status, NULL, query->context); 668 } 669 670 static void ib_sa_service_rec_release(struct ib_sa_query *sa_query) 671 { 672 kfree(sa_query->mad); 673 kfree(container_of(sa_query, struct ib_sa_service_query, sa_query)); 674 } 675 676 /** 677 * ib_sa_service_rec_query - Start Service Record operation 678 * @device:device to send request on 679 * @port_num: port number to send request on 680 * @method:SA method - should be get, set, or delete 681 * @rec:Service Record to send in request 682 * @comp_mask:component mask to send in request 683 * @timeout_ms:time to wait for response 684 * @gfp_mask:GFP mask to use for internal allocations 685 * @callback:function called when request completes, times out or is 686 * canceled 687 * @context:opaque user context passed to callback 688 * @sa_query:request context, used to cancel request 689 * 690 * Send a Service Record set/get/delete to the SA to register, 691 * unregister or query a service record. 692 * The callback function will be called when the request completes (or 693 * fails); status is 0 for a successful response, -EINTR if the query 694 * is canceled, -ETIMEDOUT is the query timed out, or -EIO if an error 695 * occurred sending the query. The resp parameter of the callback is 696 * only valid if status is 0. 697 * 698 * If the return value of ib_sa_service_rec_query() is negative, it is an 699 * error code. Otherwise it is a request ID that can be used to cancel 700 * the query. 701 */ 702 int ib_sa_service_rec_query(struct ib_device *device, u8 port_num, u8 method, 703 struct ib_sa_service_rec *rec, 704 ib_sa_comp_mask comp_mask, 705 int timeout_ms, unsigned int __nocast gfp_mask, 706 void (*callback)(int status, 707 struct ib_sa_service_rec *resp, 708 void *context), 709 void *context, 710 struct ib_sa_query **sa_query) 711 { 712 struct ib_sa_service_query *query; 713 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); 714 struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port]; 715 struct ib_mad_agent *agent = port->agent; 716 int ret; 717 718 if (method != IB_MGMT_METHOD_GET && 719 method != IB_MGMT_METHOD_SET && 720 method != IB_SA_METHOD_DELETE) 721 return -EINVAL; 722 723 query = kmalloc(sizeof *query, gfp_mask); 724 if (!query) 725 return -ENOMEM; 726 query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask); 727 if (!query->sa_query.mad) { 728 kfree(query); 729 return -ENOMEM; 730 } 731 732 query->callback = callback; 733 query->context = context; 734 735 init_mad(query->sa_query.mad, agent); 736 737 query->sa_query.callback = callback ? ib_sa_service_rec_callback : NULL; 738 query->sa_query.release = ib_sa_service_rec_release; 739 query->sa_query.port = port; 740 query->sa_query.mad->mad_hdr.method = method; 741 query->sa_query.mad->mad_hdr.attr_id = 742 cpu_to_be16(IB_SA_ATTR_SERVICE_REC); 743 query->sa_query.mad->sa_hdr.comp_mask = comp_mask; 744 745 ib_pack(service_rec_table, ARRAY_SIZE(service_rec_table), 746 rec, query->sa_query.mad->data); 747 748 *sa_query = &query->sa_query; 749 750 ret = send_mad(&query->sa_query, timeout_ms); 751 if (ret < 0) { 752 *sa_query = NULL; 753 kfree(query->sa_query.mad); 754 kfree(query); 755 } 756 757 return ret; 758 } 759 EXPORT_SYMBOL(ib_sa_service_rec_query); 760 761 static void ib_sa_mcmember_rec_callback(struct ib_sa_query *sa_query, 762 int status, 763 struct ib_sa_mad *mad) 764 { 765 struct ib_sa_mcmember_query *query = 766 container_of(sa_query, struct ib_sa_mcmember_query, sa_query); 767 768 if (mad) { 769 struct ib_sa_mcmember_rec rec; 770 771 ib_unpack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table), 772 mad->data, &rec); 773 query->callback(status, &rec, query->context); 774 } else 775 query->callback(status, NULL, query->context); 776 } 777 778 static void ib_sa_mcmember_rec_release(struct ib_sa_query *sa_query) 779 { 780 kfree(sa_query->mad); 781 kfree(container_of(sa_query, struct ib_sa_mcmember_query, sa_query)); 782 } 783 784 int ib_sa_mcmember_rec_query(struct ib_device *device, u8 port_num, 785 u8 method, 786 struct ib_sa_mcmember_rec *rec, 787 ib_sa_comp_mask comp_mask, 788 int timeout_ms, unsigned int __nocast gfp_mask, 789 void (*callback)(int status, 790 struct ib_sa_mcmember_rec *resp, 791 void *context), 792 void *context, 793 struct ib_sa_query **sa_query) 794 { 795 struct ib_sa_mcmember_query *query; 796 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); 797 struct ib_sa_port *port = &sa_dev->port[port_num - sa_dev->start_port]; 798 struct ib_mad_agent *agent = port->agent; 799 int ret; 800 801 query = kmalloc(sizeof *query, gfp_mask); 802 if (!query) 803 return -ENOMEM; 804 query->sa_query.mad = kmalloc(sizeof *query->sa_query.mad, gfp_mask); 805 if (!query->sa_query.mad) { 806 kfree(query); 807 return -ENOMEM; 808 } 809 810 query->callback = callback; 811 query->context = context; 812 813 init_mad(query->sa_query.mad, agent); 814 815 query->sa_query.callback = callback ? ib_sa_mcmember_rec_callback : NULL; 816 query->sa_query.release = ib_sa_mcmember_rec_release; 817 query->sa_query.port = port; 818 query->sa_query.mad->mad_hdr.method = method; 819 query->sa_query.mad->mad_hdr.attr_id = cpu_to_be16(IB_SA_ATTR_MC_MEMBER_REC); 820 query->sa_query.mad->sa_hdr.comp_mask = comp_mask; 821 822 ib_pack(mcmember_rec_table, ARRAY_SIZE(mcmember_rec_table), 823 rec, query->sa_query.mad->data); 824 825 *sa_query = &query->sa_query; 826 827 ret = send_mad(&query->sa_query, timeout_ms); 828 if (ret < 0) { 829 *sa_query = NULL; 830 kfree(query->sa_query.mad); 831 kfree(query); 832 } 833 834 return ret; 835 } 836 EXPORT_SYMBOL(ib_sa_mcmember_rec_query); 837 838 static void send_handler(struct ib_mad_agent *agent, 839 struct ib_mad_send_wc *mad_send_wc) 840 { 841 struct ib_sa_query *query; 842 unsigned long flags; 843 844 spin_lock_irqsave(&idr_lock, flags); 845 query = idr_find(&query_idr, mad_send_wc->wr_id); 846 spin_unlock_irqrestore(&idr_lock, flags); 847 848 if (!query) 849 return; 850 851 if (query->callback) 852 switch (mad_send_wc->status) { 853 case IB_WC_SUCCESS: 854 /* No callback -- already got recv */ 855 break; 856 case IB_WC_RESP_TIMEOUT_ERR: 857 query->callback(query, -ETIMEDOUT, NULL); 858 break; 859 case IB_WC_WR_FLUSH_ERR: 860 query->callback(query, -EINTR, NULL); 861 break; 862 default: 863 query->callback(query, -EIO, NULL); 864 break; 865 } 866 867 dma_unmap_single(agent->device->dma_device, 868 pci_unmap_addr(query, mapping), 869 sizeof (struct ib_sa_mad), 870 DMA_TO_DEVICE); 871 kref_put(&query->sm_ah->ref, free_sm_ah); 872 873 query->release(query); 874 875 spin_lock_irqsave(&idr_lock, flags); 876 idr_remove(&query_idr, mad_send_wc->wr_id); 877 spin_unlock_irqrestore(&idr_lock, flags); 878 } 879 880 static void recv_handler(struct ib_mad_agent *mad_agent, 881 struct ib_mad_recv_wc *mad_recv_wc) 882 { 883 struct ib_sa_query *query; 884 unsigned long flags; 885 886 spin_lock_irqsave(&idr_lock, flags); 887 query = idr_find(&query_idr, mad_recv_wc->wc->wr_id); 888 spin_unlock_irqrestore(&idr_lock, flags); 889 890 if (query && query->callback) { 891 if (mad_recv_wc->wc->status == IB_WC_SUCCESS) 892 query->callback(query, 893 mad_recv_wc->recv_buf.mad->mad_hdr.status ? 894 -EINVAL : 0, 895 (struct ib_sa_mad *) mad_recv_wc->recv_buf.mad); 896 else 897 query->callback(query, -EIO, NULL); 898 } 899 900 ib_free_recv_mad(mad_recv_wc); 901 } 902 903 static void ib_sa_add_one(struct ib_device *device) 904 { 905 struct ib_sa_device *sa_dev; 906 int s, e, i; 907 908 if (device->node_type == IB_NODE_SWITCH) 909 s = e = 0; 910 else { 911 s = 1; 912 e = device->phys_port_cnt; 913 } 914 915 sa_dev = kmalloc(sizeof *sa_dev + 916 (e - s + 1) * sizeof (struct ib_sa_port), 917 GFP_KERNEL); 918 if (!sa_dev) 919 return; 920 921 sa_dev->start_port = s; 922 sa_dev->end_port = e; 923 924 for (i = 0; i <= e - s; ++i) { 925 sa_dev->port[i].sm_ah = NULL; 926 sa_dev->port[i].port_num = i + s; 927 spin_lock_init(&sa_dev->port[i].ah_lock); 928 929 sa_dev->port[i].agent = 930 ib_register_mad_agent(device, i + s, IB_QPT_GSI, 931 NULL, 0, send_handler, 932 recv_handler, sa_dev); 933 if (IS_ERR(sa_dev->port[i].agent)) 934 goto err; 935 936 INIT_WORK(&sa_dev->port[i].update_task, 937 update_sm_ah, &sa_dev->port[i]); 938 } 939 940 ib_set_client_data(device, &sa_client, sa_dev); 941 942 /* 943 * We register our event handler after everything is set up, 944 * and then update our cached info after the event handler is 945 * registered to avoid any problems if a port changes state 946 * during our initialization. 947 */ 948 949 INIT_IB_EVENT_HANDLER(&sa_dev->event_handler, device, ib_sa_event); 950 if (ib_register_event_handler(&sa_dev->event_handler)) 951 goto err; 952 953 for (i = 0; i <= e - s; ++i) 954 update_sm_ah(&sa_dev->port[i]); 955 956 return; 957 958 err: 959 while (--i >= 0) 960 ib_unregister_mad_agent(sa_dev->port[i].agent); 961 962 kfree(sa_dev); 963 964 return; 965 } 966 967 static void ib_sa_remove_one(struct ib_device *device) 968 { 969 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); 970 int i; 971 972 if (!sa_dev) 973 return; 974 975 ib_unregister_event_handler(&sa_dev->event_handler); 976 977 for (i = 0; i <= sa_dev->end_port - sa_dev->start_port; ++i) { 978 ib_unregister_mad_agent(sa_dev->port[i].agent); 979 kref_put(&sa_dev->port[i].sm_ah->ref, free_sm_ah); 980 } 981 982 kfree(sa_dev); 983 } 984 985 static int __init ib_sa_init(void) 986 { 987 int ret; 988 989 spin_lock_init(&idr_lock); 990 spin_lock_init(&tid_lock); 991 992 get_random_bytes(&tid, sizeof tid); 993 994 ret = ib_register_client(&sa_client); 995 if (ret) 996 printk(KERN_ERR "Couldn't register ib_sa client\n"); 997 998 return ret; 999 } 1000 1001 static void __exit ib_sa_cleanup(void) 1002 { 1003 ib_unregister_client(&sa_client); 1004 } 1005 1006 module_init(ib_sa_init); 1007 module_exit(ib_sa_cleanup); 1008