]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/infiniband/hw/mthca/mthca_provider.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[linux-2.6-omap-h63xx.git] / drivers / infiniband / hw / mthca / mthca_provider.c
index 6bcde1cb9688f9860b8116fb22526553a23d5746..be34f99ca62579b916970d5387110b370b99602d 100644 (file)
@@ -39,6 +39,8 @@
 #include <rdma/ib_smi.h>
 #include <rdma/ib_umem.h>
 #include <rdma/ib_user_verbs.h>
+
+#include <linux/sched.h>
 #include <linux/mm.h>
 
 #include "mthca_dev.h"
@@ -60,7 +62,7 @@ static int mthca_query_device(struct ib_device *ibdev,
        struct ib_smp *in_mad  = NULL;
        struct ib_smp *out_mad = NULL;
        int err = -ENOMEM;
-       struct mthca_devmdev = to_mdev(ibdev);
+       struct mthca_dev *mdev = to_mdev(ibdev);
 
        u8 status;
 
@@ -367,6 +369,8 @@ static struct ib_ucontext *mthca_alloc_ucontext(struct ib_device *ibdev,
                return ERR_PTR(-EFAULT);
        }
 
+       context->reg_mr_warned = 0;
+
        return &context->ibucontext;
 }
 
@@ -540,6 +544,9 @@ static struct ib_qp *mthca_create_qp(struct ib_pd *pd,
        struct mthca_qp *qp;
        int err;
 
+       if (init_attr->create_flags)
+               return ERR_PTR(-EINVAL);
+
        switch (init_attr->qp_type) {
        case IB_QPT_RC:
        case IB_QPT_UC:
@@ -923,17 +930,13 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd       *pd,
        struct mthca_mr *mr;
        u64 *page_list;
        u64 total_size;
-       u64 mask;
+       unsigned long mask;
        int shift;
        int npages;
        int err;
        int i, j, n;
 
-       /* First check that we have enough alignment */
-       if ((*iova_start & ~PAGE_MASK) != (buffer_list[0].addr & ~PAGE_MASK))
-               return ERR_PTR(-EINVAL);
-
-       mask = 0;
+       mask = buffer_list[0].addr ^ *iova_start;
        total_size = 0;
        for (i = 0; i < num_phys_buf; ++i) {
                if (i != 0)
@@ -947,17 +950,7 @@ static struct ib_mr *mthca_reg_phys_mr(struct ib_pd       *pd,
        if (mask & ~PAGE_MASK)
                return ERR_PTR(-EINVAL);
 
-       /* Find largest page shift we can use to cover buffers */
-       for (shift = PAGE_SHIFT; shift < 31; ++shift)
-               if (num_phys_buf > 1) {
-                       if ((1ULL << shift) & mask)
-                               break;
-               } else {
-                       if (1ULL << shift >=
-                           buffer_list[0].size +
-                           (buffer_list[0].addr & ((1ULL << shift) - 1)))
-                               break;
-               }
+       shift = __ffs(mask | 1 << 31);
 
        buffer_list[0].size += buffer_list[0].addr & ((1ULL << shift) - 1);
        buffer_list[0].addr &= ~0ull << shift;
@@ -1017,17 +1010,31 @@ static struct ib_mr *mthca_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        struct mthca_dev *dev = to_mdev(pd->device);
        struct ib_umem_chunk *chunk;
        struct mthca_mr *mr;
+       struct mthca_reg_mr ucmd;
        u64 *pages;
        int shift, n, len;
        int i, j, k;
        int err = 0;
        int write_mtt_size;
 
+       if (udata->inlen - sizeof (struct ib_uverbs_cmd_hdr) < sizeof ucmd) {
+               if (!to_mucontext(pd->uobject->context)->reg_mr_warned) {
+                       mthca_warn(dev, "Process '%s' did not pass in MR attrs.\n",
+                                  current->comm);
+                       mthca_warn(dev, "  Update libmthca to fix this.\n");
+               }
+               ++to_mucontext(pd->uobject->context)->reg_mr_warned;
+               ucmd.mr_attrs = 0;
+       } else if (ib_copy_from_udata(&ucmd, udata, sizeof ucmd))
+               return ERR_PTR(-EFAULT);
+
        mr = kmalloc(sizeof *mr, GFP_KERNEL);
        if (!mr)
                return ERR_PTR(-ENOMEM);
 
-       mr->umem = ib_umem_get(pd->uobject->context, start, length, acc);
+       mr->umem = ib_umem_get(pd->uobject->context, start, length, acc,
+                              ucmd.mr_attrs & MTHCA_MR_DMASYNC);
+
        if (IS_ERR(mr->umem)) {
                err = PTR_ERR(mr->umem);
                goto err;
@@ -1181,23 +1188,29 @@ static int mthca_unmap_fmr(struct list_head *fmr_list)
        return 0;
 }
 
-static ssize_t show_rev(struct class_device *cdev, char *buf)
+static ssize_t show_rev(struct device *device, struct device_attribute *attr,
+                       char *buf)
 {
-       struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+       struct mthca_dev *dev =
+               container_of(device, struct mthca_dev, ib_dev.dev);
        return sprintf(buf, "%x\n", dev->rev_id);
 }
 
-static ssize_t show_fw_ver(struct class_device *cdev, char *buf)
+static ssize_t show_fw_ver(struct device *device, struct device_attribute *attr,
+                          char *buf)
 {
-       struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+       struct mthca_dev *dev =
+               container_of(device, struct mthca_dev, ib_dev.dev);
        return sprintf(buf, "%d.%d.%d\n", (int) (dev->fw_ver >> 32),
                       (int) (dev->fw_ver >> 16) & 0xffff,
                       (int) dev->fw_ver & 0xffff);
 }
 
-static ssize_t show_hca(struct class_device *cdev, char *buf)
+static ssize_t show_hca(struct device *device, struct device_attribute *attr,
+                       char *buf)
 {
-       struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+       struct mthca_dev *dev =
+               container_of(device, struct mthca_dev, ib_dev.dev);
        switch (dev->pdev->device) {
        case PCI_DEVICE_ID_MELLANOX_TAVOR:
                return sprintf(buf, "MT23108\n");
@@ -1213,22 +1226,24 @@ static ssize_t show_hca(struct class_device *cdev, char *buf)
        }
 }
 
-static ssize_t show_board(struct class_device *cdev, char *buf)
+static ssize_t show_board(struct device *device, struct device_attribute *attr,
+                         char *buf)
 {
-       struct mthca_dev *dev = container_of(cdev, struct mthca_dev, ib_dev.class_dev);
+       struct mthca_dev *dev =
+               container_of(device, struct mthca_dev, ib_dev.dev);
        return sprintf(buf, "%.*s\n", MTHCA_BOARD_ID_LEN, dev->board_id);
 }
 
-static CLASS_DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
-static CLASS_DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
-static CLASS_DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
-static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
+static DEVICE_ATTR(hw_rev,   S_IRUGO, show_rev,    NULL);
+static DEVICE_ATTR(fw_ver,   S_IRUGO, show_fw_ver, NULL);
+static DEVICE_ATTR(hca_type, S_IRUGO, show_hca,    NULL);
+static DEVICE_ATTR(board_id, S_IRUGO, show_board,  NULL);
 
-static struct class_device_attribute *mthca_class_attributes[] = {
-       &class_device_attr_hw_rev,
-       &class_device_attr_fw_ver,
-       &class_device_attr_hca_type,
-       &class_device_attr_board_id
+static struct device_attribute *mthca_dev_attributes[] = {
+       &dev_attr_hw_rev,
+       &dev_attr_fw_ver,
+       &dev_attr_hca_type,
+       &dev_attr_board_id
 };
 
 static int mthca_init_node_data(struct mthca_dev *dev)
@@ -1270,6 +1285,8 @@ static int mthca_init_node_data(struct mthca_dev *dev)
                goto out;
        }
 
+       if (mthca_is_memfree(dev))
+               dev->rev_id = be32_to_cpup((__be32 *) (out_mad->data + 32));
        memcpy(&dev->ib_dev.node_guid, out_mad->data + 12, 8);
 
 out:
@@ -1388,9 +1405,9 @@ int mthca_register_device(struct mthca_dev *dev)
        if (ret)
                return ret;
 
-       for (i = 0; i < ARRAY_SIZE(mthca_class_attributes); ++i) {
-               ret = class_device_create_file(&dev->ib_dev.class_dev,
-                                              mthca_class_attributes[i]);
+       for (i = 0; i < ARRAY_SIZE(mthca_dev_attributes); ++i) {
+               ret = device_create_file(&dev->ib_dev.dev,
+                                        mthca_dev_attributes[i]);
                if (ret) {
                        ib_unregister_device(&dev->ib_dev);
                        return ret;