aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/core/user_mad.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/core/user_mad.c')
-rw-r--r--drivers/infiniband/core/user_mad.c188
1 files changed, 164 insertions, 24 deletions
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 1acb99100556..928cdd20e2d1 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -33,6 +33,8 @@
33 * SOFTWARE. 33 * SOFTWARE.
34 */ 34 */
35 35
36#define pr_fmt(fmt) "user_mad: " fmt
37
36#include <linux/module.h> 38#include <linux/module.h>
37#include <linux/init.h> 39#include <linux/init.h>
38#include <linux/device.h> 40#include <linux/device.h>
@@ -504,13 +506,15 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
504 506
505 rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data; 507 rmpp_mad = (struct ib_rmpp_mad *) packet->mad.data;
506 hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class); 508 hdr_len = ib_get_mad_data_offset(rmpp_mad->mad_hdr.mgmt_class);
507 if (!ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)) { 509
508 copy_offset = IB_MGMT_MAD_HDR; 510 if (ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)
509 rmpp_active = 0; 511 && ib_mad_kernel_rmpp_agent(agent)) {
510 } else {
511 copy_offset = IB_MGMT_RMPP_HDR; 512 copy_offset = IB_MGMT_RMPP_HDR;
512 rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & 513 rmpp_active = ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) &
513 IB_MGMT_RMPP_FLAG_ACTIVE; 514 IB_MGMT_RMPP_FLAG_ACTIVE;
515 } else {
516 copy_offset = IB_MGMT_MAD_HDR;
517 rmpp_active = 0;
514 } 518 }
515 519
516 data_len = count - hdr_size(file) - hdr_len; 520 data_len = count - hdr_size(file) - hdr_len;
@@ -556,14 +560,22 @@ static ssize_t ib_umad_write(struct file *filp, const char __user *buf,
556 rmpp_mad->mad_hdr.tid = *tid; 560 rmpp_mad->mad_hdr.tid = *tid;
557 } 561 }
558 562
559 spin_lock_irq(&file->send_lock); 563 if (!ib_mad_kernel_rmpp_agent(agent)
560 ret = is_duplicate(file, packet); 564 && ib_is_mad_class_rmpp(rmpp_mad->mad_hdr.mgmt_class)
561 if (!ret) 565 && (ib_get_rmpp_flags(&rmpp_mad->rmpp_hdr) & IB_MGMT_RMPP_FLAG_ACTIVE)) {
566 spin_lock_irq(&file->send_lock);
562 list_add_tail(&packet->list, &file->send_list); 567 list_add_tail(&packet->list, &file->send_list);
563 spin_unlock_irq(&file->send_lock); 568 spin_unlock_irq(&file->send_lock);
564 if (ret) { 569 } else {
565 ret = -EINVAL; 570 spin_lock_irq(&file->send_lock);
566 goto err_msg; 571 ret = is_duplicate(file, packet);
572 if (!ret)
573 list_add_tail(&packet->list, &file->send_list);
574 spin_unlock_irq(&file->send_lock);
575 if (ret) {
576 ret = -EINVAL;
577 goto err_msg;
578 }
567 } 579 }
568 580
569 ret = ib_post_send_mad(packet->msg, NULL); 581 ret = ib_post_send_mad(packet->msg, NULL);
@@ -614,6 +626,8 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, void __user *arg,
614 mutex_lock(&file->mutex); 626 mutex_lock(&file->mutex);
615 627
616 if (!file->port->ib_dev) { 628 if (!file->port->ib_dev) {
629 dev_notice(file->port->dev,
630 "ib_umad_reg_agent: invalid device\n");
617 ret = -EPIPE; 631 ret = -EPIPE;
618 goto out; 632 goto out;
619 } 633 }
@@ -624,6 +638,9 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, void __user *arg,
624 } 638 }
625 639
626 if (ureq.qpn != 0 && ureq.qpn != 1) { 640 if (ureq.qpn != 0 && ureq.qpn != 1) {
641 dev_notice(file->port->dev,
642 "ib_umad_reg_agent: invalid QPN %d specified\n",
643 ureq.qpn);
627 ret = -EINVAL; 644 ret = -EINVAL;
628 goto out; 645 goto out;
629 } 646 }
@@ -632,11 +649,15 @@ static int ib_umad_reg_agent(struct ib_umad_file *file, void __user *arg,
632 if (!__get_agent(file, agent_id)) 649 if (!__get_agent(file, agent_id))
633 goto found; 650 goto found;
634 651
652 dev_notice(file->port->dev,
653 "ib_umad_reg_agent: Max Agents (%u) reached\n",
654 IB_UMAD_MAX_AGENTS);
635 ret = -ENOMEM; 655 ret = -ENOMEM;
636 goto out; 656 goto out;
637 657
638found: 658found:
639 if (ureq.mgmt_class) { 659 if (ureq.mgmt_class) {
660 memset(&req, 0, sizeof(req));
640 req.mgmt_class = ureq.mgmt_class; 661 req.mgmt_class = ureq.mgmt_class;
641 req.mgmt_class_version = ureq.mgmt_class_version; 662 req.mgmt_class_version = ureq.mgmt_class_version;
642 memcpy(req.oui, ureq.oui, sizeof req.oui); 663 memcpy(req.oui, ureq.oui, sizeof req.oui);
@@ -657,7 +678,7 @@ found:
657 ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI, 678 ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI,
658 ureq.mgmt_class ? &req : NULL, 679 ureq.mgmt_class ? &req : NULL,
659 ureq.rmpp_version, 680 ureq.rmpp_version,
660 send_handler, recv_handler, file); 681 send_handler, recv_handler, file, 0);
661 if (IS_ERR(agent)) { 682 if (IS_ERR(agent)) {
662 ret = PTR_ERR(agent); 683 ret = PTR_ERR(agent);
663 agent = NULL; 684 agent = NULL;
@@ -673,10 +694,11 @@ found:
673 if (!file->already_used) { 694 if (!file->already_used) {
674 file->already_used = 1; 695 file->already_used = 1;
675 if (!file->use_pkey_index) { 696 if (!file->use_pkey_index) {
676 printk(KERN_WARNING "user_mad: process %s did not enable " 697 dev_warn(file->port->dev,
677 "P_Key index support.\n", current->comm); 698 "process %s did not enable P_Key index support.\n",
678 printk(KERN_WARNING "user_mad: Documentation/infiniband/user_mad.txt " 699 current->comm);
679 "has info on the new ABI.\n"); 700 dev_warn(file->port->dev,
701 " Documentation/infiniband/user_mad.txt has info on the new ABI.\n");
680 } 702 }
681 } 703 }
682 704
@@ -694,6 +716,119 @@ out:
694 return ret; 716 return ret;
695} 717}
696 718
719static int ib_umad_reg_agent2(struct ib_umad_file *file, void __user *arg)
720{
721 struct ib_user_mad_reg_req2 ureq;
722 struct ib_mad_reg_req req;
723 struct ib_mad_agent *agent = NULL;
724 int agent_id;
725 int ret;
726
727 mutex_lock(&file->port->file_mutex);
728 mutex_lock(&file->mutex);
729
730 if (!file->port->ib_dev) {
731 dev_notice(file->port->dev,
732 "ib_umad_reg_agent2: invalid device\n");
733 ret = -EPIPE;
734 goto out;
735 }
736
737 if (copy_from_user(&ureq, arg, sizeof(ureq))) {
738 ret = -EFAULT;
739 goto out;
740 }
741
742 if (ureq.qpn != 0 && ureq.qpn != 1) {
743 dev_notice(file->port->dev,
744 "ib_umad_reg_agent2: invalid QPN %d specified\n",
745 ureq.qpn);
746 ret = -EINVAL;
747 goto out;
748 }
749
750 if (ureq.flags & ~IB_USER_MAD_REG_FLAGS_CAP) {
751 dev_notice(file->port->dev,
752 "ib_umad_reg_agent2 failed: invalid registration flags specified 0x%x; supported 0x%x\n",
753 ureq.flags, IB_USER_MAD_REG_FLAGS_CAP);
754 ret = -EINVAL;
755
756 if (put_user((u32)IB_USER_MAD_REG_FLAGS_CAP,
757 (u32 __user *) (arg + offsetof(struct
758 ib_user_mad_reg_req2, flags))))
759 ret = -EFAULT;
760
761 goto out;
762 }
763
764 for (agent_id = 0; agent_id < IB_UMAD_MAX_AGENTS; ++agent_id)
765 if (!__get_agent(file, agent_id))
766 goto found;
767
768 dev_notice(file->port->dev,
769 "ib_umad_reg_agent2: Max Agents (%u) reached\n",
770 IB_UMAD_MAX_AGENTS);
771 ret = -ENOMEM;
772 goto out;
773
774found:
775 if (ureq.mgmt_class) {
776 memset(&req, 0, sizeof(req));
777 req.mgmt_class = ureq.mgmt_class;
778 req.mgmt_class_version = ureq.mgmt_class_version;
779 if (ureq.oui & 0xff000000) {
780 dev_notice(file->port->dev,
781 "ib_umad_reg_agent2 failed: oui invalid 0x%08x\n",
782 ureq.oui);
783 ret = -EINVAL;
784 goto out;
785 }
786 req.oui[2] = ureq.oui & 0x0000ff;
787 req.oui[1] = (ureq.oui & 0x00ff00) >> 8;
788 req.oui[0] = (ureq.oui & 0xff0000) >> 16;
789 memcpy(req.method_mask, ureq.method_mask,
790 sizeof(req.method_mask));
791 }
792
793 agent = ib_register_mad_agent(file->port->ib_dev, file->port->port_num,
794 ureq.qpn ? IB_QPT_GSI : IB_QPT_SMI,
795 ureq.mgmt_class ? &req : NULL,
796 ureq.rmpp_version,
797 send_handler, recv_handler, file,
798 ureq.flags);
799 if (IS_ERR(agent)) {
800 ret = PTR_ERR(agent);
801 agent = NULL;
802 goto out;
803 }
804
805 if (put_user(agent_id,
806 (u32 __user *)(arg +
807 offsetof(struct ib_user_mad_reg_req2, id)))) {
808 ret = -EFAULT;
809 goto out;
810 }
811
812 if (!file->already_used) {
813 file->already_used = 1;
814 file->use_pkey_index = 1;
815 }
816
817 file->agent[agent_id] = agent;
818 ret = 0;
819
820out:
821 mutex_unlock(&file->mutex);
822
823 if (ret && agent)
824 ib_unregister_mad_agent(agent);
825
826 mutex_unlock(&file->port->file_mutex);
827
828 return ret;
829}
830
831
697static int ib_umad_unreg_agent(struct ib_umad_file *file, u32 __user *arg) 832static int ib_umad_unreg_agent(struct ib_umad_file *file, u32 __user *arg)
698{ 833{
699 struct ib_mad_agent *agent = NULL; 834 struct ib_mad_agent *agent = NULL;
@@ -749,6 +884,8 @@ static long ib_umad_ioctl(struct file *filp, unsigned int cmd,
749 return ib_umad_unreg_agent(filp->private_data, (__u32 __user *) arg); 884 return ib_umad_unreg_agent(filp->private_data, (__u32 __user *) arg);
750 case IB_USER_MAD_ENABLE_PKEY: 885 case IB_USER_MAD_ENABLE_PKEY:
751 return ib_umad_enable_pkey(filp->private_data); 886 return ib_umad_enable_pkey(filp->private_data);
887 case IB_USER_MAD_REGISTER_AGENT2:
888 return ib_umad_reg_agent2(filp->private_data, (void __user *) arg);
752 default: 889 default:
753 return -ENOIOCTLCMD; 890 return -ENOIOCTLCMD;
754 } 891 }
@@ -765,6 +902,8 @@ static long ib_umad_compat_ioctl(struct file *filp, unsigned int cmd,
765 return ib_umad_unreg_agent(filp->private_data, compat_ptr(arg)); 902 return ib_umad_unreg_agent(filp->private_data, compat_ptr(arg));
766 case IB_USER_MAD_ENABLE_PKEY: 903 case IB_USER_MAD_ENABLE_PKEY:
767 return ib_umad_enable_pkey(filp->private_data); 904 return ib_umad_enable_pkey(filp->private_data);
905 case IB_USER_MAD_REGISTER_AGENT2:
906 return ib_umad_reg_agent2(filp->private_data, compat_ptr(arg));
768 default: 907 default:
769 return -ENOIOCTLCMD; 908 return -ENOIOCTLCMD;
770 } 909 }
@@ -983,7 +1122,7 @@ static CLASS_ATTR_STRING(abi_version, S_IRUGO,
983 1122
984static dev_t overflow_maj; 1123static dev_t overflow_maj;
985static DECLARE_BITMAP(overflow_map, IB_UMAD_MAX_PORTS); 1124static DECLARE_BITMAP(overflow_map, IB_UMAD_MAX_PORTS);
986static int find_overflow_devnum(void) 1125static int find_overflow_devnum(struct ib_device *device)
987{ 1126{
988 int ret; 1127 int ret;
989 1128
@@ -991,7 +1130,8 @@ static int find_overflow_devnum(void)
991 ret = alloc_chrdev_region(&overflow_maj, 0, IB_UMAD_MAX_PORTS * 2, 1130 ret = alloc_chrdev_region(&overflow_maj, 0, IB_UMAD_MAX_PORTS * 2,
992 "infiniband_mad"); 1131 "infiniband_mad");
993 if (ret) { 1132 if (ret) {
994 printk(KERN_ERR "user_mad: couldn't register dynamic device number\n"); 1133 dev_err(&device->dev,
1134 "couldn't register dynamic device number\n");
995 return ret; 1135 return ret;
996 } 1136 }
997 } 1137 }
@@ -1014,7 +1154,7 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
1014 devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS); 1154 devnum = find_first_zero_bit(dev_map, IB_UMAD_MAX_PORTS);
1015 if (devnum >= IB_UMAD_MAX_PORTS) { 1155 if (devnum >= IB_UMAD_MAX_PORTS) {
1016 spin_unlock(&port_lock); 1156 spin_unlock(&port_lock);
1017 devnum = find_overflow_devnum(); 1157 devnum = find_overflow_devnum(device);
1018 if (devnum < 0) 1158 if (devnum < 0)
1019 return -1; 1159 return -1;
1020 1160
@@ -1200,14 +1340,14 @@ static int __init ib_umad_init(void)
1200 ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2, 1340 ret = register_chrdev_region(base_dev, IB_UMAD_MAX_PORTS * 2,
1201 "infiniband_mad"); 1341 "infiniband_mad");
1202 if (ret) { 1342 if (ret) {
1203 printk(KERN_ERR "user_mad: couldn't register device number\n"); 1343 pr_err("couldn't register device number\n");
1204 goto out; 1344 goto out;
1205 } 1345 }
1206 1346
1207 umad_class = class_create(THIS_MODULE, "infiniband_mad"); 1347 umad_class = class_create(THIS_MODULE, "infiniband_mad");
1208 if (IS_ERR(umad_class)) { 1348 if (IS_ERR(umad_class)) {
1209 ret = PTR_ERR(umad_class); 1349 ret = PTR_ERR(umad_class);
1210 printk(KERN_ERR "user_mad: couldn't create class infiniband_mad\n"); 1350 pr_err("couldn't create class infiniband_mad\n");
1211 goto out_chrdev; 1351 goto out_chrdev;
1212 } 1352 }
1213 1353
@@ -1215,13 +1355,13 @@ static int __init ib_umad_init(void)
1215 1355
1216 ret = class_create_file(umad_class, &class_attr_abi_version.attr); 1356 ret = class_create_file(umad_class, &class_attr_abi_version.attr);
1217 if (ret) { 1357 if (ret) {
1218 printk(KERN_ERR "user_mad: couldn't create abi_version attribute\n"); 1358 pr_err("couldn't create abi_version attribute\n");
1219 goto out_class; 1359 goto out_class;
1220 } 1360 }
1221 1361
1222 ret = ib_register_client(&umad_client); 1362 ret = ib_register_client(&umad_client);
1223 if (ret) { 1363 if (ret) {
1224 printk(KERN_ERR "user_mad: couldn't register ib_umad client\n"); 1364 pr_err("couldn't register ib_umad client\n");
1225 goto out_class; 1365 goto out_class;
1226 } 1366 }
1227 1367