user_mad.c revision 94382f3562e350ed7c8f7dcd6fc968bdece31328
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 4010 2005-11-09 23:11:56Z roland $ 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 55MODULE_AUTHOR("Roland Dreier"); 56MODULE_DESCRIPTION("InfiniBand userspace MAD packet access"); 57MODULE_LICENSE("Dual BSD/GPL"); 58 59enum { 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/* 68 * Our lifetime rules for these structs are the following: each time a 69 * device special file is opened, we look up the corresponding struct 70 * ib_umad_port by minor in the umad_port[] table while holding the 71 * port_lock. If this lookup succeeds, we take a reference on the 72 * ib_umad_port's struct ib_umad_device while still holding the 73 * port_lock; if the lookup fails, we fail the open(). We drop these 74 * references in the corresponding close(). 75 * 76 * In addition to references coming from open character devices, there 77 * is one more reference to each ib_umad_device representing the 78 * module's reference taken when allocating the ib_umad_device in 79 * ib_umad_add_one(). 80 * 81 * When destroying an ib_umad_device, we clear all of its 82 * ib_umad_ports from umad_port[] while holding port_lock before 83 * dropping the module's reference to the ib_umad_device. This is 84 * always safe because any open() calls will either succeed and obtain 85 * a reference before we clear the umad_port[] entries, or fail after 86 * we clear the umad_port[] entries. 87 */ 88 89struct ib_umad_port { 90 struct cdev *dev; 91 struct class_device *class_dev; 92 93 struct cdev *sm_dev; 94 struct class_device *sm_class_dev; 95 struct semaphore sm_sem; 96 97 struct rw_semaphore mutex; 98 struct list_head file_list; 99 100 struct ib_device *ib_dev; 101 struct ib_umad_device *umad_dev; 102 int dev_num; 103 u8 port_num; 104}; 105 106struct ib_umad_device { 107 int start_port, end_port; 108 struct kref ref; 109 struct ib_umad_port port[0]; 110}; 111 112struct ib_umad_file { 113 struct ib_umad_port *port; 114 struct list_head recv_list; 115 struct list_head port_list; 116 spinlock_t recv_lock; 117 wait_queue_head_t recv_wait; 118 struct ib_mad_agent *agent[IB_UMAD_MAX_AGENTS]; 119 int agents_dead; 120}; 121 122struct ib_umad_packet { 123 struct ib_mad_send_buf *msg; 124 struct list_head list; 125 int length; 126 struct ib_user_mad mad; 127}; 128 129static struct class *umad_class; 130 131static const dev_t base_dev = MKDEV(IB_UMAD_MAJOR, IB_UMAD_MINOR_BASE); 132 133static DEFINE_SPINLOCK(port_lock); 134static struct ib_umad_port *umad_port[IB_UMAD_MAX_PORTS]; 135static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS * 2); 136 137static void ib_umad_add_one(struct ib_device *device); 138static void ib_umad_remove_one(struct ib_device *device); 139 140static void ib_umad_release_dev(struct kref *ref) 141{ 142 struct ib_umad_device *dev = 143 container_of(ref, struct ib_umad_device, ref); 144 145 kfree(dev); 146} 147 148/* caller must hold port->mutex at least for reading */ 149static struct ib_mad_agent *__get_agent(struct ib_umad_file *file, int id) 150{ 151 return file->agents_dead ? NULL : file->agent[id]; 152} 153 154static int queue_packet(struct ib_umad_file *file, 155 struct ib_mad_agent *agent, 156 struct ib_umad_packet *packet) 157{ 158 int ret = 1; 159 160 down_read(&file->port->mutex); 161 162 for (packet->mad.hdr.id = 0; 163 packet->mad.hdr.id < IB_UMAD_MAX_AGENTS; 164 packet->mad.hdr.id++) 165 if (agent == __get_agent(file, packet->mad.hdr.id)) { 166 spin_lock_irq(&file->recv_lock); 167 list_add_tail(&packet->list, &file->recv_list); 168 spin_unlock_irq(&file->recv_lock); 169 wake_up_interruptible(&file->recv_wait); 170 ret = 0; 171 break; 172 } 173 174 up_read(&file->port->mutex); 175 176 return ret; 177} 178 179static void send_handler(struct ib_mad_agent *agent, 180 struct ib_mad_send_wc *send_wc) 181{ 182 struct ib_umad_file *file = agent->context; 183 struct ib_umad_packet *timeout; 184 struct ib_umad_packet *packet = send_wc->send_buf->context[0]; 185 186 ib_destroy_ah(packet->msg->ah); 187 ib_free_send_mad(packet->msg); 188 189 if (send_wc->status == IB_WC_RESP_TIMEOUT_ERR) { 190 timeout = kzalloc(sizeof *timeout + IB_MGMT_MAD_HDR, GFP_KERNEL); 191 if (!timeout) 192 goto out; 193 194 timeout->length = IB_MGMT_MAD_HDR; 195 timeout->mad.hdr.id = packet->mad.hdr.id; 196 timeout->mad.hdr.status = ETIMEDOUT; 197 memcpy(timeout->mad.data, packet->mad.data, 198 sizeof (struct ib_mad_hdr)); 199 200 if (!queue_packet(file, agent, timeout)) 201 return; 202 } 203out: 204 kfree(packet); 205} 206 207static void recv_handler(struct ib_mad_agent *agent, 208 struct ib_mad_recv_wc *mad_recv_wc) 209{ 210 struct ib_umad_file *file = agent->context; 211 struct ib_umad_packet *packet; 212 int length; 213 214 if (mad_recv_wc->wc->status != IB_WC_SUCCESS) 215 goto out; 216 217 length = mad_recv_wc->mad_len; 218 packet = kzalloc(sizeof *packet + length, GFP_KERNEL); 219 if (!packet) 220 goto out; 221 222 packet->length = length; 223 224 ib_coalesce_recv_mad(mad_recv_wc, packet->mad.data); 225 226 packet->mad.hdr.status = 0; 227 packet->mad.hdr.length = length + sizeof (struct ib_user_mad); 228 packet->mad.hdr.qpn = cpu_to_be32(mad_recv_wc->wc->src_qp); 229 packet->mad.hdr.lid = cpu_to_be16(mad_recv_wc->wc->slid); 230 packet->mad.hdr.sl = mad_recv_wc->wc->sl; 231 packet->mad.hdr.path_bits = mad_recv_wc->wc->dlid_path_bits; 232 packet->mad.hdr.grh_present = !!(mad_recv_wc->wc->wc_flags & IB_WC_GRH); 233 if (packet->mad.hdr.grh_present) { 234 /* XXX parse GRH */ 235 packet->mad.hdr.gid_index = 0; 236 packet->mad.hdr.hop_limit = 0; 237 packet->mad.hdr.traffic_class = 0; 238 memset(packet->mad.hdr.gid, 0, 16); 239 packet->mad.hdr.flow_label = 0; 240 } 241 242 if (queue_packet(file, agent, packet)) 243 kfree(packet); 244 245out: 246 ib_free_recv_mad(mad_recv_wc); 247} 248 249static ssize_t ib_umad_read(struct file *filp, char __user *buf, 250 size_t count, loff_t *pos) 251{ 252 struct ib_umad_file *file = filp->private_data; 253 struct ib_umad_packet *packet; 254 ssize_t ret; 255 256 if (count < sizeof (struct ib_user_mad) + sizeof (struct ib_mad)) 257 return -EINVAL; 258 259 spin_lock_irq(&file->recv_lock); 260 261 while (list_empty(&file->recv_list)) { 262 spin_unlock_irq(&file->recv_lock); 263 264 if (filp->f_flags & O_NONBLOCK) 265 return -EAGAIN; 266 267 if (wait_event_interruptible(file->recv_wait, 268 !list_empty(&file->recv_list))) 269 return -ERESTARTSYS; 270 271 spin_lock_irq(&file->recv_lock); 272 } 273 274 packet = list_entry(file->recv_list.next, struct ib_umad_packet, list); 275 list_del(&packet->list); 276 277 spin_unlock_irq(&file->recv_lock); 278 279 if (count < packet->length + sizeof (struct ib_user_mad)) { 280 /* Return length needed (and first RMPP segment) if too small */ 281 if (copy_to_user(buf, &packet->mad, 282 sizeof (struct ib_user_mad) + sizeof (struct ib_mad))) 283 ret = -EFAULT; 284 else 285 ret = -ENOSPC; 286 } else if (copy_to_user(buf, &packet->mad, 287 packet->length + sizeof (struct ib_user_mad))) 288 ret = -EFAULT; 289 else 290 ret = packet->length + sizeof (struct ib_user_mad); 291 if (ret < 0) { 292 /* Requeue packet */ 293 spin_lock_irq(&file->recv_lock); 294 list_add(&packet->list, &file->recv_list); 295 spin_unlock_irq(&file->recv_lock); 296 } else 297 kfree(packet); 298 return ret; 299} 300 301static ssize_t ib_umad_write(struct file *filp, const char __user *buf, 302 size_t count, loff_t *pos) 303{ 304 struct ib_umad_file *file = filp->private_data; 305 struct ib_umad_packet *packet; 306 struct ib_mad_agent *agent; 307 struct ib_ah_attr ah_attr; 308 struct ib_ah *ah; 309 struct ib_rmpp_mad *rmpp_mad; 310 u8 method; 311 __be64 *tid; 312 int ret, length, hdr_len, copy_offset; 313 int rmpp_active = 0; 314 315 if (count < sizeof (struct ib_user_mad)) 316 return -EINVAL; 317 318 length = count - sizeof (struct ib_user_mad); 319 packet = kmalloc(sizeof *packet + IB_MGMT_RMPP_HDR, GFP_KERNEL); 320 if (!packet) 321 return -ENOMEM; 322 323 if (copy_from_user(&packet->mad, buf, 324 sizeof (struct ib_user_mad) + IB_MGMT_RMPP_HDR)) { 325 ret = -EFAULT; 326 goto err; 327 } 328 329 if (packet->mad.hdr.id < 0 || 330 packet->mad.hdr.id >= IB_UMAD_MAX_AGENTS) { 331 ret = -EINVAL; 332 goto err; 333 } 334 335 down_read(&file->port->mutex); 336 337 agent = __get_agent(file, packet->mad.hdr.id); 338 if (!agent) { 339 ret = -EINVAL; 340 goto err_up; 341 } 342 343 memset(&ah_attr, 0, sizeof ah_attr); 344 ah_attr.dlid = be16_to_cpu(packet->mad.hdr.lid); 345 ah_attr.sl = packet->mad.hdr.sl; 346 ah_attr.src_path_bits = packet->mad.hdr.path_bits; 347 ah_attr.port_num = file->port->port_num; 348 if (packet->mad.hdr.grh_present) { 349 ah_attr.ah_flags = IB_AH_GRH; 350 memcpy(ah_attr.grh.dgid.raw, packet->mad.hdr.gid, 16); 351 ah_attr.grh.flow_label = be32_to_cpu(packet->mad.hdr.flow_label); 352 ah_attr.grh.hop_limit = packet->mad.hdr.hop_limit; 353 ah_attr.grh.traffic_class = packet->mad.hdr.traffic_class; 354 } 355 356 ah = ib_create_ah(agent->qp->pd, &ah_attr); 357 if (IS_ERR(ah)) { 358 ret = PTR_ERR(ah); 359 goto err_up; 360 } 361 362 rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; 363 if (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE) { 364 /* RMPP active */ 365 if (!agent->rmpp_version) { 366 ret = -EINVAL; 367 goto err_ah; 368 } 369 370 /* Validate that the management class can support RMPP */ 371 if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) { 372 hdr_len = IB_MGMT_SA_HDR; 373 } else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) && 374 (rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) { 375 hdr_len = IB_MGMT_VENDOR_HDR; 376 } else { 377 ret = -EINVAL; 378 goto err_ah; 379 } 380 rmpp_active = 1; 381 copy_offset = IB_MGMT_RMPP_HDR; 382 } else { 383 hdr_len = IB_MGMT_MAD_HDR; 384 copy_offset = IB_MGMT_MAD_HDR; 385 } 386 387 packet->msg = ib_create_send_mad(agent, 388 be32_to_cpu(packet->mad.hdr.qpn), 389 0, rmpp_active, 390 hdr_len, length - hdr_len, 391 GFP_KERNEL); 392 if (IS_ERR(packet->msg)) { 393 ret = PTR_ERR(packet->msg); 394 goto err_ah; 395 } 396 397 packet->msg->ah = ah; 398 packet->msg->timeout_ms = packet->mad.hdr.timeout_ms; 399 packet->msg->retries = packet->mad.hdr.retries; 400 packet->msg->context[0] = packet; 401 402 /* Copy MAD headers (RMPP header in place) */ 403 memcpy(packet->msg->mad, packet->mad.data, IB_MGMT_MAD_HDR); 404 /* Now, copy rest of message from user into send buffer */ 405 if (copy_from_user(packet->msg->mad + copy_offset, 406 buf + sizeof (struct ib_user_mad) + copy_offset, 407 length - copy_offset)) { 408 ret = -EFAULT; 409 goto err_msg; 410 } 411 412 /* 413 * If userspace is generating a request that will generate a 414 * response, we need to make sure the high-order part of the 415 * transaction ID matches the agent being used to send the 416 * MAD. 417 */ 418 method = ((struct ib_mad_hdr *) packet->msg->mad)->method; 419 420 if (!(method & IB_MGMT_METHOD_RESP) && 421 method != IB_MGMT_METHOD_TRAP_REPRESS && 422 method != IB_MGMT_METHOD_SEND) { 423 tid = &((struct ib_mad_hdr *) packet->msg->mad)->tid; 424 *tid = cpu_to_be64(((u64) agent->hi_tid) << 32 | 425 (be64_to_cpup(tid) & 0xffffffff)); 426 } 427 428 ret = ib_post_send_mad(packet->msg, NULL); 429 if (ret) 430 goto err_msg; 431 432 up_read(&file->port->mutex); 433 434 return count; 435 436err_msg: 437 ib_free_send_mad(packet->msg); 438 439err_ah: 440 ib_destroy_ah(ah); 441 442err_up: 443 up_read(&file->port->mutex); 444 445err: 446 kfree(packet); 447 return ret; 448} 449 450static unsigned int ib_umad_poll(struct file *filp, struct poll_table_struct *wait) 451{ 452 struct ib_umad_file *file = filp->private_data; 453 454 /* we will always be able to post a MAD send */ 455 unsigned int mask = POLLOUT | POLLWRNORM; 456 457 poll_wait(filp, &file->recv_wait, wait); 458 459 if (!list_empty(&file->recv_list)) 460 mask |= POLLIN | POLLRDNORM; 461 462 return mask; 463} 464 465static int ib_umad_reg_agent(struct ib_umad_file *file, unsigned long arg) 466{ 467 struct ib_user_mad_reg_req ureq; 468 struct ib_mad_reg_req req; 469 struct ib_mad_agent *agent; 470 int agent_id; 471 int ret; 472 473 down_write(&file->port->mutex); 474 475 if (!file->port->ib_dev) { 476 ret = -EPIPE; 477 goto out; 478 } 479 480 if (copy_from_user(&ureq, (void __user *) arg, sizeof ureq)) { 481 ret = -EFAULT; 482 goto out; 483 } 484 485 if (ureq.qpn != 0 && ureq.qpn != 1) { 486 ret = -EINVAL; 487 goto out; 488 } 489 490 for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id) 491 if (!__get_agent(file, agent_id)) 492 goto found; 493 494 ret = -ENOMEM; 495 goto out; 496 497found: 498 if (ureq.mgmt_class) { 499 req.mgmt_class = ureq.mgmt_class; 500 req.mgmt_class_version = ureq.mgmt_class_version; 501 memcpy(req.method_mask, ureq.method_mask, sizeof req.method_mask); 502 memcpy(req.oui, ureq.oui, sizeof req.oui); 503 } 504 505 agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num, 506 ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI, 507 ureq.mgmt_class ? &req : NULL, 508 ureq.rmpp_version, 509 send_handler, recv_handler, file); 510 if (IS_ERR(agent)) { 511 ret = PTR_ERR(agent); 512 goto out; 513 } 514 515 if (put_user(agent_id, 516 (u32 __user *) (arg + offsetof(struct ib_user_mad_reg_req, id)))) { 517 ret = -EFAULT; 518 ib_unregister_mad_agent(agent); 519 goto out; 520 } 521 522 file->agent[agent_id] = agent; 523 ret = 0; 524 525out: 526 up_write(&file->port->mutex); 527 return ret; 528} 529 530static int ib_umad_unreg_agent(struct ib_umad_file *file, unsigned long arg) 531{ 532 struct ib_mad_agent *agent = NULL; 533 u32 id; 534 int ret = 0; 535 536 if (get_user(id, (u32 __user *) arg)) 537 return -EFAULT; 538 539 down_write(&file->port->mutex); 540 541 if (id < 0 || id >= IB_UMAD_MAX_AGENTS || !__get_agent(file, id)) { 542 ret = -EINVAL; 543 goto out; 544 } 545 546 agent = file->agent[id]; 547 file->agent[id] = NULL; 548 549out: 550 up_write(&file->port->mutex); 551 552 if (agent) 553 ib_unregister_mad_agent(agent); 554 555 return ret; 556} 557 558static long ib_umad_ioctl(struct file *filp, unsigned int cmd, 559 unsigned long arg) 560{ 561 switch (cmd) { 562 case IB_USER_MAD_REGISTER_AGENT: 563 return ib_umad_reg_agent(filp->private_data, arg); 564 case IB_USER_MAD_UNREGISTER_AGENT: 565 return ib_umad_unreg_agent(filp->private_data, arg); 566 default: 567 return -ENOIOCTLCMD; 568 } 569} 570 571static int ib_umad_open(struct inode *inode, struct file *filp) 572{ 573 struct ib_umad_port *port; 574 struct ib_umad_file *file; 575 int ret = 0; 576 577 spin_lock(&port_lock); 578 port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE]; 579 if (port) 580 kref_get(&port->umad_dev->ref); 581 spin_unlock(&port_lock); 582 583 if (!port) 584 return -ENXIO; 585 586 down_write(&port->mutex); 587 588 if (!port->ib_dev) { 589 ret = -ENXIO; 590 goto out; 591 } 592 593 file = kzalloc(sizeof *file, GFP_KERNEL); 594 if (!file) { 595 kref_put(&port->umad_dev->ref, ib_umad_release_dev); 596 ret = -ENOMEM; 597 goto out; 598 } 599 600 spin_lock_init(&file->recv_lock); 601 INIT_LIST_HEAD(&file->recv_list); 602 init_waitqueue_head(&file->recv_wait); 603 604 file->port = port; 605 filp->private_data = file; 606 607 list_add_tail(&file->port_list, &port->file_list); 608 609out: 610 up_write(&port->mutex); 611 return ret; 612} 613 614static int ib_umad_close(struct inode *inode, struct file *filp) 615{ 616 struct ib_umad_file *file = filp->private_data; 617 struct ib_umad_device *dev = file->port->umad_dev; 618 struct ib_umad_packet *packet, *tmp; 619 int already_dead; 620 int i; 621 622 down_write(&file->port->mutex); 623 624 already_dead = file->agents_dead; 625 file->agents_dead = 1; 626 627 list_for_each_entry_safe(packet, tmp, &file->recv_list, list) 628 kfree(packet); 629 630 list_del(&file->port_list); 631 632 downgrade_write(&file->port->mutex); 633 634 if (!already_dead) 635 for (i = 0; i < IB_UMAD_MAX_AGENTS; ++i) 636 if (file->agent[i]) 637 ib_unregister_mad_agent(file->agent[i]); 638 639 up_read(&file->port->mutex); 640 641 kfree(file); 642 kref_put(&dev->ref, ib_umad_release_dev); 643 644 return 0; 645} 646 647static struct file_operations umad_fops = { 648 .owner = THIS_MODULE, 649 .read = ib_umad_read, 650 .write = ib_umad_write, 651 .poll = ib_umad_poll, 652 .unlocked_ioctl = ib_umad_ioctl, 653 .compat_ioctl = ib_umad_ioctl, 654 .open = ib_umad_open, 655 .release = ib_umad_close 656}; 657 658static int ib_umad_sm_open(struct inode *inode, struct file *filp) 659{ 660 struct ib_umad_port *port; 661 struct ib_port_modify props = { 662 .set_port_cap_mask = IB_PORT_SM 663 }; 664 int ret; 665 666 spin_lock(&port_lock); 667 port = umad_port[iminor(inode) - IB_UMAD_MINOR_BASE - IB_UMAD_MAX_PORTS]; 668 if (port) 669 kref_get(&port->umad_dev->ref); 670 spin_unlock(&port_lock); 671 672 if (!port) 673 return -ENXIO; 674 675 if (filp->f_flags & O_NONBLOCK) { 676 if (down_trylock(&port->sm_sem)) { 677 ret = -EAGAIN; 678 goto fail; 679 } 680 } else { 681 if (down_interruptible(&port->sm_sem)) { 682 ret = -ERESTARTSYS; 683 goto fail; 684 } 685 } 686 687 ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props); 688 if (ret) { 689 up(&port->sm_sem); 690 goto fail; 691 } 692 693 filp->private_data = port; 694 695 return 0; 696 697fail: 698 kref_put(&port->umad_dev->ref, ib_umad_release_dev); 699 return ret; 700} 701 702static int ib_umad_sm_close(struct inode *inode, struct file *filp) 703{ 704 struct ib_umad_port *port = filp->private_data; 705 struct ib_port_modify props = { 706 .clr_port_cap_mask = IB_PORT_SM 707 }; 708 int ret = 0; 709 710 down_write(&port->mutex); 711 if (port->ib_dev) 712 ret = ib_modify_port(port->ib_dev, port->port_num, 0, &props); 713 up_write(&port->mutex); 714 715 up(&port->sm_sem); 716 717 kref_put(&port->umad_dev->ref, ib_umad_release_dev); 718 719 return ret; 720} 721 722static struct file_operations umad_sm_fops = { 723 .owner = THIS_MODULE, 724 .open = ib_umad_sm_open, 725 .release = ib_umad_sm_close 726}; 727 728static struct ib_client umad_client = { 729 .name = "umad", 730 .add = ib_umad_add_one, 731 .remove = ib_umad_remove_one 732}; 733 734static ssize_t show_ibdev(struct class_device *class_dev, char *buf) 735{ 736 struct ib_umad_port *port = class_get_devdata(class_dev); 737 738 if (!port) 739 return -ENODEV; 740 741 return sprintf(buf, "%s\n", port->ib_dev->name); 742} 743static CLASS_DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); 744 745static ssize_t show_port(struct class_device *class_dev, char *buf) 746{ 747 struct ib_umad_port *port = class_get_devdata(class_dev); 748 749 if (!port) 750 return -ENODEV; 751 752 return sprintf(buf, "%d\n", port->port_num); 753} 754static CLASS_DEVICE_ATTR(port, S_IRUGO, show_port, NULL); 755 756static ssize_t show_abi_version(struct class *class, char *buf) 757{ 758 return sprintf(buf, "%d\n", IB_USER_MAD_ABI_VERSION); 759} 760static CLASS_ATTR(abi_version, S_IRUGO, show_abi_version, NULL); 761 762static int ib_umad_init_port(struct ib_device *device, int port_num, 763 struct ib_umad_port *port) 764{ 765 spin_lock(&port_lock); 766 port->dev_num = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS); 767 if (port->dev_num >= IB_UMAD_MAX_PORTS) { 768 spin_unlock(&port_lock); 769 return -1; 770 } 771 set_bit(port->dev_num, dev_map); 772 spin_unlock(&port_lock); 773 774 port->ib_dev = device; 775 port->port_num = port_num; 776 init_MUTEX(&port->sm_sem); 777 init_rwsem(&port->mutex); 778 INIT_LIST_HEAD(&port->file_list); 779 780 port->dev = cdev_alloc(); 781 if (!port->dev) 782 return -1; 783 port->dev->owner = THIS_MODULE; 784 port->dev->ops = &umad_fops; 785 kobject_set_name(&port->dev->kobj, "umad%d", port->dev_num); 786 if (cdev_add(port->dev, base_dev + port->dev_num, 1)) 787 goto err_cdev; 788 789 port->class_dev = class_device_create(umad_class, NULL, port->dev->dev, 790 device->dma_device, 791 "umad%d", port->dev_num); 792 if (IS_ERR(port->class_dev)) 793 goto err_cdev; 794 795 if (class_device_create_file(port->class_dev, &class_device_attr_ibdev)) 796 goto err_class; 797 if (class_device_create_file(port->class_dev, &class_device_attr_port)) 798 goto err_class; 799 800 port->sm_dev = cdev_alloc(); 801 if (!port->sm_dev) 802 goto err_class; 803 port->sm_dev->owner = THIS_MODULE; 804 port->sm_dev->ops = &umad_sm_fops; 805 kobject_set_name(&port->sm_dev->kobj, "issm%d", port->dev_num); 806 if (cdev_add(port->sm_dev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1)) 807 goto err_sm_cdev; 808 809 port->sm_class_dev = class_device_create(umad_class, NULL, port->sm_dev->dev, 810 device->dma_device, 811 "issm%d", port->dev_num); 812 if (IS_ERR(port->sm_class_dev)) 813 goto err_sm_cdev; 814 815 class_set_devdata(port->class_dev, port); 816 class_set_devdata(port->sm_class_dev, port); 817 818 if (class_device_create_file(port->sm_class_dev, &class_device_attr_ibdev)) 819 goto err_sm_class; 820 if (class_device_create_file(port->sm_class_dev, &class_device_attr_port)) 821 goto err_sm_class; 822 823 spin_lock(&port_lock); 824 umad_port[port->dev_num] = port; 825 spin_unlock(&port_lock); 826 827 return 0; 828 829err_sm_class: 830 class_device_destroy(umad_class, port->sm_dev->dev); 831 832err_sm_cdev: 833 cdev_del(port->sm_dev); 834 835err_class: 836 class_device_destroy(umad_class, port->dev->dev); 837 838err_cdev: 839 cdev_del(port->dev); 840 clear_bit(port->dev_num, dev_map); 841 842 return -1; 843} 844 845static void ib_umad_kill_port(struct ib_umad_port *port) 846{ 847 struct ib_umad_file *file; 848 int id; 849 850 class_set_devdata(port->class_dev, NULL); 851 class_set_devdata(port->sm_class_dev, NULL); 852 853 class_device_destroy(umad_class, port->dev->dev); 854 class_device_destroy(umad_class, port->sm_dev->dev); 855 856 cdev_del(port->dev); 857 cdev_del(port->sm_dev); 858 859 spin_lock(&port_lock); 860 umad_port[port->dev_num] = NULL; 861 spin_unlock(&port_lock); 862 863 down_write(&port->mutex); 864 865 port->ib_dev = NULL; 866 867 /* 868 * Now go through the list of files attached to this port and 869 * unregister all of their MAD agents. We need to hold 870 * port->mutex while doing this to avoid racing with 871 * ib_umad_close(), but we can't hold the mutex for writing 872 * while calling ib_unregister_mad_agent(), since that might 873 * deadlock by calling back into queue_packet(). So we 874 * downgrade our lock to a read lock, and then drop and 875 * reacquire the write lock for the next iteration. 876 * 877 * We do list_del_init() on the file's list_head so that the 878 * list_del in ib_umad_close() is still OK, even after the 879 * file is removed from the list. 880 */ 881 while (!list_empty(&port->file_list)) { 882 file = list_entry(port->file_list.next, struct ib_umad_file, 883 port_list); 884 885 file->agents_dead = 1; 886 list_del_init(&file->port_list); 887 888 downgrade_write(&port->mutex); 889 890 for (id = 0; id < IB_UMAD_MAX_AGENTS; ++id) 891 if (file->agent[id]) 892 ib_unregister_mad_agent(file->agent[id]); 893 894 up_read(&port->mutex); 895 down_write(&port->mutex); 896 } 897 898 up_write(&port->mutex); 899 900 clear_bit(port->dev_num, dev_map); 901} 902 903static void ib_umad_add_one(struct ib_device *device) 904{ 905 struct ib_umad_device *umad_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 umad_dev = kzalloc(sizeof *umad_dev + 916 (e - s + 1) * sizeof (struct ib_umad_port), 917 GFP_KERNEL); 918 if (!umad_dev) 919 return; 920 921 kref_init(&umad_dev->ref); 922 923 umad_dev->start_port = s; 924 umad_dev->end_port = e; 925 926 for (i = s; i <= e; ++i) { 927 umad_dev->port[i - s].umad_dev = umad_dev; 928 929 if (ib_umad_init_port(device, i, &umad_dev->port[i - s])) 930 goto err; 931 } 932 933 ib_set_client_data(device, &umad_client, umad_dev); 934 935 return; 936 937err: 938 while (--i >= s) 939 ib_umad_kill_port(&umad_dev->port[i - s]); 940 941 kref_put(&umad_dev->ref, ib_umad_release_dev); 942} 943 944static void ib_umad_remove_one(struct ib_device *device) 945{ 946 struct ib_umad_device *umad_dev = ib_get_client_data(device, &umad_client); 947 int i; 948 949 if (!umad_dev) 950 return; 951 952 for (i = 0; i <= umad_dev->end_port - umad_dev->start_port; ++i) 953 ib_umad_kill_port(&umad_dev->port[i]); 954 955 kref_put(&umad_dev->ref, ib_umad_release_dev); 956} 957 958static int __init ib_umad_init(void) 959{ 960 int ret; 961 962 ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2, 963 "infiniband_mad"); 964 if (ret) { 965 printk(KERN_ERR "user_mad: couldn't register device number\n"); 966 goto out; 967 } 968 969 umad_class = class_create(THIS_MODULE, "infiniband_mad"); 970 if (IS_ERR(umad_class)) { 971 ret = PTR_ERR(umad_class); 972 printk(KERN_ERR "user_mad: couldn't create class infiniband_mad\n"); 973 goto out_chrdev; 974 } 975 976 ret = class_create_file(umad_class, &class_attr_abi_version); 977 if (ret) { 978 printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n"); 979 goto out_class; 980 } 981 982 ret = ib_register_client(&umad_client); 983 if (ret) { 984 printk(KERN_ERR "user_mad: couldn't register ib_umad client\n"); 985 goto out_class; 986 } 987 988 return 0; 989 990out_class: 991 class_destroy(umad_class); 992 993out_chrdev: 994 unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2); 995 996out: 997 return ret; 998} 999 1000static void __exit ib_umad_cleanup(void) 1001{ 1002 ib_unregister_client(&umad_client); 1003 class_destroy(umad_class); 1004 unregister_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2); 1005} 1006 1007module_init(ib_umad_init); 1008module_exit(ib_umad_cleanup); 1009