1 /* 2 * Copyright (c) 2004 Topspin Communications. All rights reserved. 3 * Copyright (c) 2005 Voltaire, Inc. All rights reserved. 4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 5 * 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: 11 * 12 * Redistribution and use in source and binary forms, with or 13 * without modification, are permitted provided that the following 14 * conditions are met: 15 * 16 * - Redistributions of source code must retain the above 17 * copyright notice, this list of conditions and the following 18 * disclaimer. 19 * 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. 24 * 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 32 * SOFTWARE. 33 * 34 * $Id: user_mad.c 2814 2005-07-06 19:14:09Z halr $ 35 */ 36 37 #include <linux/module.h> 38 #include <linux/init.h> 39 #include <linux/device.h> 40 #include <linux/err.h> 41 #include <linux/fs.h> 42 #include <linux/cdev.h> 43 #include <linux/pci.h> 44 #include <linux/dma-mapping.h> 45 #include <linux/poll.h> 46 #include <linux/rwsem.h> 47 #include <linux/kref.h> 48 49 #include <asm/uaccess.h> 50 #include <asm/semaphore.h> 51 52 #include <rdma/ib_mad.h> 53 #include <rdma/ib_user_mad.h> 54 55 MODULE_AUTHOR("Roland Dreier"); 56 MODULE_DESCRIPTION("InfiniBand userspace MAD packet access"); 57 MODULE_LICENSE("Dual BSD/GPL"); 58 59 enum { 60 IB_UMAD_MAX_PORTS = 64, 61 IB_UMAD_MAX_AGENTS = 32, 62 63 IB_UMAD_MAJOR = 231, 64 IB_UMAD_MINOR_BASE = 0 65 }; 66 67 struct ib_umad_port { 68 int devnum; 69 struct cdev dev; 70 struct class_device class_dev; 71 72 int sm_devnum; 73 struct cdev sm_dev; 74 struct class_device sm_class_dev; 75 struct semaphore sm_sem; 76 77 struct ib_device *ib_dev; 78 struct ib_umad_device *umad_dev; 79 u8 port_num; 80 }; 81 82 struct ib_umad_device { 83 int start_port, end_port; 84 struct kref ref; 85 struct ib_umad_port port[0]; 86 }; 87 88 struct ib_umad_file { 89 struct ib_umad_port *port; 90 spinlock_t recv_lock; 91 struct list_head recv_list; 92 wait_queue_head_t recv_wait; 93 struct rw_semaphore agent_mutex; 94 struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; 95 struct ib_mr *mr[IB_UMAD_MAX_AGENTS]; 96 }; 97 98 struct ib_umad_packet { 99 struct ib_ah *ah; 100 struct ib_mad_send_buf *msg; 101 struct list_head list; 102 int length; 103 DECLARE_PCI_UNMAP_ADDR(mapping) 104 struct ib_user_mad mad; 105 }; 106 107 static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE); 108 static spinlock_t map_lock; 109 static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS * 2); 110 111 static void ib_umad_add_one(struct ib_device *device); 112 static void ib_umad_remove_one(struct ib_device *device); 113 114 static int queue_packet(struct ib_umad_file *file, 115 struct ib_mad_agent *agent, 116 struct ib_umad_packet *packet) 117 { 118 int ret = 1; 119 120 down_read(&file->agent_mutex); 121 for (packet->mad.hdr.id = 0; 122 packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; 123 packet->mad.hdr.id++) 124 if (agent == file->agent[packet->mad.hdr.id]) { 125 spin_lock_irq(&file->recv_lock); 126 list_add_tail(&packet->list, &file->recv_list); 127 spin_unlock_irq(&file->recv_lock); 128 wake_up_interruptible(&file->recv_wait); 129 ret = 0; 130 break; 131 } 132 133 up_read(&file->agent_mutex); 134 135 return ret; 136 } 137 138 static void send_handler(struct ib_mad_agent *agent, 139 struct ib_mad_send_wc *send_wc) 140 { 141 struct ib_umad_file *file = agent->context; 142 struct ib_umad_packet *timeout, *packet = 143 (void *) (unsigned long) send_wc->wr_id; 144 145 ib_destroy_ah(packet->msg->send_wr.wr.ud.ah); 146 ib_free_send_mad(packet->msg); 147 148 if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) { 149 timeout = kmalloc(sizeof *timeout + sizeof (struct ib_mad_hdr), 150 GFP_KERNEL); 151 if (!timeout) 152 goto out; 153 154 memset(timeout, 0, sizeof *timeout + sizeof (struct ib_mad_hdr)); 155 156 timeout->length = sizeof (struct ib_mad_hdr); 157 timeout->mad.hdr.id = packet->mad.hdr.id; 158 timeout->mad.hdr.status = ETIMEDOUT; 159 memcpy(timeout->mad.data, packet->mad.data, 160 sizeof (struct ib_mad_hdr)); 161 162 if (!queue_packet(file, agent, timeout)) 163 return; 164 } 165 out: 166 kfree(packet); 167 } 168 169 static void recv_handler(struct ib_mad_agent *agent, 170 struct ib_mad_recv_wc *mad_recv_wc) 171 { 172 struct ib_umad_file *file = agent->context; 173 struct ib_umad_packet *packet; 174 int length; 175 176 if (mad_recv_wc->wc->status != IB_WC_SUCCESS) 177 goto out; 178 179 length = mad_recv_wc->mad_len; 180 packet = kmalloc(sizeof *packet + length, GFP_KERNEL); 181 if (!packet) 182 goto out; 183 184 memset(packet, 0, sizeof *packet + length); 185 packet->length = length; 186 187 ib_coalesce_recv_mad(mad_recv_wc, packet->mad.data); 188 189 packet->mad.hdr.status = 0; 190 packet->mad.hdr.length = length + sizeof (struct ib_user_mad); 191 packet->mad.hdr.qpn = cpu_to_be32(mad_recv_wc->wc->src_qp); 192 packet->mad.hdr.lid = cpu_to_be16(mad_recv_wc->wc->slid); 193 packet->mad.hdr.sl = mad_recv_wc->wc->sl; 194 packet->mad.hdr.path_bits = mad_recv_wc->wc->dlid_path_bits; 195 packet->mad.hdr.grh_present = !!(mad_recv_wc->wc->wc_flags & IB_WC_GRH); 196 if (packet->mad.hdr.grh_present) { 197 /* XXX parse GRH */ 198 packet->mad.hdr.gid_index = 0; 199 packet->mad.hdr.hop_limit = 0; 200 packet->mad.hdr.traffic_class = 0; 201 memset(packet->mad.hdr.gid, 0, 16); 202 packet->mad.hdr.flow_label = 0; 203 } 204 205 if (queue_packet(file, agent, packet)) 206 kfree(packet); 207 208 out: 209 ib_free_recv_mad(mad_recv_wc); 210 } 211 212 static ssize_t ib_umad_read(struct file *filp, char __user *buf, 213 size_t count, loff_t *pos) 214 { 215 struct ib_umad_file *file = filp->private_data; 216 struct ib_umad_packet *packet; 217 ssize_t ret; 218 219 if (count < sizeof (struct ib_user_mad) + sizeof (struct ib_mad)) 220 return -EINVAL; 221 222 spin_lock_irq(&file->recv_lock); 223 224 while (list_empty(&file->recv_list)) { 225 spin_unlock_irq(&file->recv_lock); 226 227 if (filp->f_flags & O_NONBLOCK) 228 return -EAGAIN; 229 230 if (wait_event_interruptible(file->recv_wait, 231 !list_empty(&file->recv_list))) 232 return -ERESTARTSYS; 233 234 spin_lock_irq(&file->recv_lock); 235 } 236 237 packet = list_entry(file->recv_list.next, struct ib_umad_packet, list); 238 list_del(&packet->list); 239 240 spin_unlock_irq(&file->recv_lock); 241 242 if (count < packet->length + sizeof (struct ib_user_mad)) { 243 /* Return length needed (and first RMPP segment) if too small */ 244 if (copy_to_user(buf, &packet->mad, 245 sizeof (struct ib_user_mad) + sizeof (struct ib_mad))) 246 ret = -EFAULT; 247 else 248 ret = -ENOSPC; 249 } else if (copy_to_user(buf, &packet->mad, 250 packet->length + sizeof (struct ib_user_mad))) 251 ret = -EFAULT; 252 else 253 ret = packet->length + sizeof (struct ib_user_mad); 254 if (ret < 0) { 255 /* Requeue packet */ 256 spin_lock_irq(&file->recv_lock); 257 list_add(&packet->list, &file->recv_list); 258 spin_unlock_irq(&file->recv_lock); 259 } else 260 kfree(packet); 261 return ret; 262 } 263 264 static ssize_t ib_umad_write(struct file *filp, const char __user *buf, 265 size_t count, loff_t *pos) 266 { 267 struct ib_umad_file *file = filp->private_data; 268 struct ib_umad_packet *packet; 269 struct ib_mad_agent *agent; 270 struct ib_ah_attr ah_attr; 271 struct ib_send_wr *bad_wr; 272 struct ib_rmpp_mad *rmpp_mad; 273 u8 method; 274 __be64 *tid; 275 int ret, length, hdr_len, data_len, rmpp_hdr_size; 276 int rmpp_active = 0; 277 278 if (count < sizeof (struct ib_user_mad)) 279 return -EINVAL; 280 281 length = count - sizeof (struct ib_user_mad); 282 packet = kmalloc(sizeof *packet + sizeof(struct ib_mad_hdr) + 283 sizeof(struct ib_rmpp_hdr), GFP_KERNEL); 284 if (!packet) 285 return -ENOMEM; 286 287 if (copy_from_user(&packet->mad, buf, 288 sizeof (struct ib_user_mad) + 289 sizeof(struct ib_mad_hdr) + 290 sizeof(struct ib_rmpp_hdr))) { 291 ret = -EFAULT; 292 goto err; 293 } 294 295 if (packet->mad.hdr.id < 0 || 296 packet->mad.hdr.id >= IB_UMAD_MAX_AGENTS) { 297 ret = -EINVAL; 298 goto err; 299 } 300 301 packet->length = length; 302 303 down_read(&file->agent_mutex); 304 305 agent = file->agent[packet->mad.hdr.id]; 306 if (!agent) { 307 ret = -EINVAL; 308 goto err_up; 309 } 310 311 memset(&ah_attr, 0, sizeof ah_attr); 312 ah_attr.dlid = be16_to_cpu(packet->mad.hdr.lid); 313 ah_attr.sl = packet->mad.hdr.sl; 314 ah_attr.src_path_bits = packet->mad.hdr.path_bits; 315 ah_attr.port_num = file->port->port_num; 316 if (packet->mad.hdr.grh_present) { 317 ah_attr.ah_flags = IB_AH_GRH; 318 memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16); 319 ah_attr.grh.flow_label = be32_to_cpu(packet->mad.hdr.flow_label); 320 ah_attr.grh.hop_limit = packet->mad.hdr.hop_limit; 321 ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class; 322 } 323 324 packet->ah = ib_create_ah(agent->qp->pd, &ah_attr); 325 if (IS_ERR(packet->ah)) { 326 ret = PTR_ERR(packet->ah); 327 goto err_up; 328 } 329 330 rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; 331 if (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE) { 332 /* RMPP active */ 333 if (!agent->rmpp_version) { 334 ret = -EINVAL; 335 goto err_ah; 336 } 337 338 /* Validate that the management class can support RMPP */ 339 if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { 340 hdr_len = offsetof(struct ib_sa_mad, data); 341 data_len = length - hdr_len; 342 } else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && 343 (rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) { 344 hdr_len = offsetof(struct ib_vendor_mad, data); 345 data_len = length - hdr_len; 346 } else { 347 ret = -EINVAL; 348 goto err_ah; 349 } 350 rmpp_active = 1; 351 } else { 352 if (length > sizeof(struct ib_mad)) { 353 ret = -EINVAL; 354 goto err_ah; 355 } 356 hdr_len = offsetof(struct ib_mad, data); 357 data_len = length - hdr_len; 358 } 359 360 packet->msg = ib_create_send_mad(agent, 361 be32_to_cpu(packet->mad.hdr.qpn), 362 0, packet->ah, rmpp_active, 363 hdr_len, data_len, 364 GFP_KERNEL); 365 if (IS_ERR(packet->msg)) { 366 ret = PTR_ERR(packet->msg); 367 goto err_ah; 368 } 369 370 packet->msg->send_wr.wr.ud.timeout_ms = packet->mad.hdr.timeout_ms; 371 packet->msg->send_wr.wr.ud.retries = packet->mad.hdr.retries; 372 373 /* Override send WR WRID initialized in ib_create_send_mad */ 374 packet->msg->send_wr.wr_id = (unsigned long) packet; 375 376 if (!rmpp_active) { 377 /* Copy message from user into send buffer */ 378 if (copy_from_user(packet->msg->mad, 379 buf + sizeof(struct ib_user_mad), length)) { 380 ret = -EFAULT; 381 goto err_msg; 382 } 383 } else { 384 rmpp_hdr_size = sizeof(struct ib_mad_hdr) + 385 sizeof(struct ib_rmpp_hdr); 386 387 /* Only copy MAD headers (RMPP header in place) */ 388 memcpy(packet->msg->mad, packet->mad.data, 389 sizeof(struct ib_mad_hdr)); 390 391 /* Now, copy rest of message from user into send buffer */ 392 if (copy_from_user(((struct ib_rmpp_mad *) packet->msg->mad)->data, 393 buf + sizeof (struct ib_user_mad) + rmpp_hdr_size, 394 length - rmpp_hdr_size)) { 395 ret = -EFAULT; 396 goto err_msg; 397 } 398 } 399 400 /* 401 * If userspace is generating a request that will generate a 402 * response, we need to make sure the high-order part of the 403 * transaction ID matches the agent being used to send the 404 * MAD. 405 */ 406 method = packet->msg->mad->mad_hdr.method; 407 408 if (!(method & IB_MGMT_METHOD_RESP) && 409 method != IB_MGMT_METHOD_TRAP_REPRESS && 410 method != IB_MGMT_METHOD_SEND) { 411 tid = &packet->msg->mad->mad_hdr.tid; 412 *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 | 413 (be64_to_cpup(tid) & 0xffffffff)); 414 } 415 416 ret = ib_post_send_mad(agent, &packet->msg->send_wr, &bad_wr); 417 if (ret) 418 goto err_msg; 419 420 up_read(&file->agent_mutex); 421 422 return sizeof (struct ib_user_mad_hdr) + packet->length; 423 424 err_msg: 425 ib_free_send_mad(packet->msg); 426 427 err_ah: 428 ib_destroy_ah(packet->ah); 429 430 err_up: 431 up_read(&file->agent_mutex); 432 433 err: 434 kfree(packet); 435 return ret; 436 } 437 438 static unsigned int ib_umad_poll(struct file *filp, struct poll_table_struct *wait) 439 { 440 struct ib_umad_file *file = filp->private_data; 441 442 /* we will always be able to post a MAD send */ 443 unsigned int mask = POLLOUT | POLLWRNORM; 444 445 poll_wait(filp, &file->recv_wait, wait); 446 447 if (!list_empty(&file->recv_list)) 448 mask |= POLLIN | POLLRDNORM; 449 450 return mask; 451 } 452 453 static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg) 454 { 455 struct ib_user_mad_reg_req ureq; 456 struct ib_mad_reg_req req; 457 struct ib_mad_agent *agent; 458 int agent_id; 459 int ret; 460 461 down_write(&file->agent_mutex); 462 463 if (copy_from_user(&ureq, (void __user *) arg, sizeof ureq)) { 464 ret = -EFAULT; 465 goto out; 466 } 467 468 if (ureq.qpn != 0 && ureq.qpn != 1) { 469 ret = -EINVAL; 470 goto out; 471 } 472 473 for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id) 474 if (!file->agent[agent_id]) 475 goto found; 476 477 ret = -ENOMEM; 478 goto out; 479 480 found: 481 if (ureq.mgmt_class) { 482 req.mgmt_class = ureq.mgmt_class; 483 req.mgmt_class_version = ureq.mgmt_class_version; 484 memcpy(req.method_mask, ureq.method_mask, sizeof req.method_mask); 485 memcpy(req.oui, ureq.oui, sizeof req.oui); 486 } 487 488 agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num, 489 ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI, 490 ureq.mgmt_class ? &req : NULL, 491 ureq.rmpp_version, 492 send_handler, recv_handler, file); 493 if (IS_ERR(agent)) { 494 ret = PTR_ERR(agent); 495 goto out; 496 } 497 498 file->agent[agent_id] = agent; 499 500 file->mr[agent_id] = ib_get_dma_mr(agent->qp->pd, IB_ACCESS_LOCAL_WRITE); 501 if (IS_ERR(file->mr[agent_id])) { 502 ret = -ENOMEM; 503 goto err; 504 } 505 506 if (put_user(agent_id, 507 (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) { 508 ret = -EFAULT; 509 goto err_mr; 510 } 511 512 ret = 0; 513 goto out; 514 515 err_mr: 516 ib_dereg_mr(file->mr[agent_id]); 517 518 err: 519 file->agent[agent_id] = NULL; 520 ib_unregister_mad_agent(agent); 521 522 out: 523 up_write(&file->agent_mutex); 524 return ret; 525 } 526 527 static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg) 528 { 529 u32 id; 530 int ret = 0; 531 532 down_write(&file->agent_mutex); 533 534 if (get_user(id, (u32 __user *) arg)) { 535 ret = -EFAULT; 536 goto out; 537 } 538 539 if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !file->agent[id]) { 540 ret = -EINVAL; 541 goto out; 542 } 543 544 ib_dereg_mr(file->mr[id]); 545 ib_unregister_mad_agent(file->agent[id]); 546 file->agent[id] = NULL; 547 548 out: 549 up_write(&file->agent_mutex); 550 return ret; 551 } 552 553 static long ib_umad_ioctl(struct file *filp, unsigned int cmd, 554 unsigned long arg) 555 { 556 switch (cmd) { 557 case IB_USER_MAD_REGISTER_AGENT: 558 return ib_umad_reg_agent(filp->private_data, arg); 559 case IB_USER_MAD_UNREGISTER_AGENT: 560 return ib_umad_unreg_agent(filp->private_data, arg); 561 default: 562 return -ENOIOCTLCMD; 563 } 564 } 565 566 static int ib_umad_open(struct inode *inode, struct file *filp) 567 { 568 struct ib_umad_port *port = 569 container_of(inode->i_cdev, struct ib_umad_port, dev); 570 struct ib_umad_file *file; 571 572 file = kmalloc(sizeof *file, GFP_KERNEL); 573 if (!file) 574 return -ENOMEM; 575 576 memset(file, 0, sizeof *file); 577 578 spin_lock_init(&file->recv_lock); 579 init_rwsem(&file->agent_mutex); 580 INIT_LIST_HEAD(&file->recv_list); 581 init_waitqueue_head(&file->recv_wait); 582 583 file->port = port; 584 filp->private_data = file; 585 586 return 0; 587 } 588 589 static int ib_umad_close(struct inode *inode, struct file *filp) 590 { 591 struct ib_umad_file *file = filp->private_data; 592 struct ib_umad_packet *packet, *tmp; 593 int i; 594 595 for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) 596 if (file->agent[i]) { 597 ib_dereg_mr(file->mr[i]); 598 ib_unregister_mad_agent(file->agent[i]); 599 } 600 601 list_for_each_entry_safe(packet, tmp, &file->recv_list, list) 602 kfree(packet); 603 604 kfree(file); 605 606 return 0; 607 } 608 609 static struct file_operations umad_fops = { 610 .owner = THIS_MODULE, 611 .read = ib_umad_read, 612 .write = ib_umad_write, 613 .poll = ib_umad_poll, 614 .unlocked_ioctl = ib_umad_ioctl, 615 .compat_ioctl = ib_umad_ioctl, 616 .open = ib_umad_open, 617 .release = ib_umad_close 618 }; 619 620 static int ib_umad_sm_open(struct inode *inode, struct file *filp) 621 { 622 struct ib_umad_port *port = 623 container_of(inode->i_cdev, struct ib_umad_port, sm_dev); 624 struct ib_port_modify props = { 625 .set_port_cap_mask = IB_PORT_SM 626 }; 627 int ret; 628 629 if (filp->f_flags & O_NONBLOCK) { 630 if (down_trylock(&port->sm_sem)) 631 return -EAGAIN; 632 } else { 633 if (down_interruptible(&port->sm_sem)) 634 return -ERESTARTSYS; 635 } 636 637 ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props); 638 if (ret) { 639 up(&port->sm_sem); 640 return ret; 641 } 642 643 filp->private_data = port; 644 645 return 0; 646 } 647 648 static int ib_umad_sm_close(struct inode *inode, struct file *filp) 649 { 650 struct ib_umad_port *port = filp->private_data; 651 struct ib_port_modify props = { 652 .clr_port_cap_mask = IB_PORT_SM 653 }; 654 int ret; 655 656 ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props); 657 up(&port->sm_sem); 658 659 return ret; 660 } 661 662 static struct file_operations umad_sm_fops = { 663 .owner = THIS_MODULE, 664 .open = ib_umad_sm_open, 665 .release = ib_umad_sm_close 666 }; 667 668 static struct ib_client umad_client = { 669 .name = "umad", 670 .add = ib_umad_add_one, 671 .remove = ib_umad_remove_one 672 }; 673 674 static ssize_t show_dev(struct class_device *class_dev, char *buf) 675 { 676 struct ib_umad_port *port = class_get_devdata(class_dev); 677 678 if (class_dev == &port->class_dev) 679 return print_dev_t(buf, port->dev.dev); 680 else 681 return print_dev_t(buf, port->sm_dev.dev); 682 } 683 static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_dev, NULL); 684 685 static ssize_t show_ibdev(struct class_device *class_dev, char *buf) 686 { 687 struct ib_umad_port *port = class_get_devdata(class_dev); 688 689 return sprintf(buf, "%s\n", port->ib_dev->name); 690 } 691 static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); 692 693 static ssize_t show_port(struct class_device *class_dev, char *buf) 694 { 695 struct ib_umad_port *port = class_get_devdata(class_dev); 696 697 return sprintf(buf, "%d\n", port->port_num); 698 } 699 static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL); 700 701 static void ib_umad_release_dev(struct kref *ref) 702 { 703 struct ib_umad_device *dev = 704 container_of(ref, struct ib_umad_device, ref); 705 706 kfree(dev); 707 } 708 709 static void ib_umad_release_port(struct class_device *class_dev) 710 { 711 struct ib_umad_port *port = class_get_devdata(class_dev); 712 713 if (class_dev == &port->class_dev) { 714 cdev_del(&port->dev); 715 clear_bit(port->devnum, dev_map); 716 } else { 717 cdev_del(&port->sm_dev); 718 clear_bit(port->sm_devnum, dev_map); 719 } 720 721 kref_put(&port->umad_dev->ref, ib_umad_release_dev); 722 } 723 724 static struct class umad_class = { 725 .name = "infiniband_mad", 726 .release = ib_umad_release_port 727 }; 728 729 static ssize_t show_abi_version(struct class *class, char *buf) 730 { 731 return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION); 732 } 733 static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); 734 735 static int ib_umad_init_port(struct ib_device *device, int port_num, 736 struct ib_umad_port *port) 737 { 738 spin_lock(&map_lock); 739 port->devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS); 740 if (port->devnum >= IB_UMAD_MAX_PORTS) { 741 spin_unlock(&map_lock); 742 return -1; 743 } 744 port->sm_devnum = find_next_zero_bit(dev_map, IB_UMAD_MAX_PORTS * 2, IB_UMAD_MAX_PORTS); 745 if (port->sm_devnum >= IB_UMAD_MAX_PORTS * 2) { 746 spin_unlock(&map_lock); 747 return -1; 748 } 749 set_bit(port->devnum, dev_map); 750 set_bit(port->sm_devnum, dev_map); 751 spin_unlock(&map_lock); 752 753 port->ib_dev = device; 754 port->port_num = port_num; 755 init_MUTEX(&port->sm_sem); 756 757 cdev_init(&port->dev, &umad_fops); 758 port->dev.owner = THIS_MODULE; 759 kobject_set_name(&port->dev.kobj, "umad%d", port->devnum); 760 if (cdev_add(&port->dev, base_dev + port->devnum, 1)) 761 return -1; 762 763 port->class_dev.class = &umad_class; 764 port->class_dev.dev = device->dma_device; 765 766 snprintf(port->class_dev.class_id, BUS_ID_SIZE, "umad%d", port->devnum); 767 768 if (class_device_register(&port->class_dev)) 769 goto err_cdev; 770 771 class_set_devdata(&port->class_dev, port); 772 kref_get(&port->umad_dev->ref); 773 774 if (class_device_create_file(&port->class_dev, &class_device_attr_dev)) 775 goto err_class; 776 if (class_device_create_file(&port->class_dev, &class_device_attr_ibdev)) 777 goto err_class; 778 if (class_device_create_file(&port->class_dev, &class_device_attr_port)) 779 goto err_class; 780 781 cdev_init(&port->sm_dev, &umad_sm_fops); 782 port->sm_dev.owner = THIS_MODULE; 783 kobject_set_name(&port->dev.kobj, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS); 784 if (cdev_add(&port->sm_dev, base_dev + port->sm_devnum, 1)) 785 return -1; 786 787 port->sm_class_dev.class = &umad_class; 788 port->sm_class_dev.dev = device->dma_device; 789 790 snprintf(port->sm_class_dev.class_id, BUS_ID_SIZE, "issm%d", port->sm_devnum - IB_UMAD_MAX_PORTS); 791 792 if (class_device_register(&port->sm_class_dev)) 793 goto err_sm_cdev; 794 795 class_set_devdata(&port->sm_class_dev, port); 796 kref_get(&port->umad_dev->ref); 797 798 if (class_device_create_file(&port->sm_class_dev, &class_device_attr_dev)) 799 goto err_sm_class; 800 if (class_device_create_file(&port->sm_class_dev, &class_device_attr_ibdev)) 801 goto err_sm_class; 802 if (class_device_create_file(&port->sm_class_dev, &class_device_attr_port)) 803 goto err_sm_class; 804 805 return 0; 806 807 err_sm_class: 808 class_device_unregister(&port->sm_class_dev); 809 810 err_sm_cdev: 811 cdev_del(&port->sm_dev); 812 813 err_class: 814 class_device_unregister(&port->class_dev); 815 816 err_cdev: 817 cdev_del(&port->dev); 818 clear_bit(port->devnum, dev_map); 819 820 return -1; 821 } 822 823 static void ib_umad_add_one(struct ib_device *device) 824 { 825 struct ib_umad_device *umad_dev; 826 int s, e, i; 827 828 if (device->node_type == IB_NODE_SWITCH) 829 s = e = 0; 830 else { 831 s = 1; 832 e = device->phys_port_cnt; 833 } 834 835 umad_dev = kmalloc(sizeof *umad_dev + 836 (e - s + 1) * sizeof (struct ib_umad_port), 837 GFP_KERNEL); 838 if (!umad_dev) 839 return; 840 841 memset(umad_dev, 0, sizeof *umad_dev + 842 (e - s + 1) * sizeof (struct ib_umad_port)); 843 844 kref_init(&umad_dev->ref); 845 846 umad_dev->start_port = s; 847 umad_dev->end_port = e; 848 849 for (i = s; i <= e; ++i) { 850 umad_dev->port[i - s].umad_dev = umad_dev; 851 852 if (ib_umad_init_port(device, i, &umad_dev->port[i - s])) 853 goto err; 854 } 855 856 ib_set_client_data(device, &umad_client, umad_dev); 857 858 return; 859 860 err: 861 while (--i >= s) { 862 class_device_unregister(&umad_dev->port[i - s].class_dev); 863 class_device_unregister(&umad_dev->port[i - s].sm_class_dev); 864 } 865 866 kref_put(&umad_dev->ref, ib_umad_release_dev); 867 } 868 869 static void ib_umad_remove_one(struct ib_device *device) 870 { 871 struct ib_umad_device *umad_dev = ib_get_client_data(device, &umad_client); 872 int i; 873 874 if (!umad_dev) 875 return; 876 877 for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i) { 878 class_device_unregister(&umad_dev->port[i].class_dev); 879 class_device_unregister(&umad_dev->port[i].sm_class_dev); 880 } 881 882 kref_put(&umad_dev->ref, ib_umad_release_dev); 883 } 884 885 static int __init ib_umad_init(void) 886 { 887 int ret; 888 889 spin_lock_init(&map_lock); 890 891 ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2, 892 "infiniband_mad"); 893 if (ret) { 894 printk(KERN_ERR "user_mad: couldn't register device number\n"); 895 goto out; 896 } 897 898 ret = class_register(&umad_class); 899 if (ret) { 900 printk(KERN_ERR "user_mad: couldn't create class infiniband_mad\n"); 901 goto out_chrdev; 902 } 903 904 ret = class_create_file(&umad_class, &class_attr_abi_version); 905 if (ret) { 906 printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n"); 907 goto out_class; 908 } 909 910 ret = ib_register_client(&umad_client); 911 if (ret) { 912 printk(KERN_ERR "user_mad: couldn't register ib_umad client\n"); 913 goto out_class; 914 } 915 916 return 0; 917 918 out_class: 919 class_unregister(&umad_class); 920 921 out_chrdev: 922 unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2); 923 924 out: 925 return ret; 926 } 927 928 static void __exit ib_umad_cleanup(void) 929 { 930 ib_unregister_client(&umad_client); 931 class_unregister(&umad_class); 932 unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2); 933 } 934 935 module_init(ib_umad_init); 936 module_exit(ib_umad_cleanup); 937