Merge branch 'linus' into x86/urgent, to pick up dependent changes
[linux-2.6-microblaze.git] / drivers / infiniband / hw / ocrdma / ocrdma_verbs.c
index b4e1777..35ec870 100644 (file)
@@ -47,6 +47,7 @@
 #include <rdma/ib_umem.h>
 #include <rdma/ib_addr.h>
 #include <rdma/ib_cache.h>
+#include <rdma/uverbs_ioctl.h>
 
 #include "ocrdma.h"
 #include "ocrdma_hw.h"
@@ -112,24 +113,6 @@ int ocrdma_query_device(struct ib_device *ibdev, struct ib_device_attr *attr,
        return 0;
 }
 
-struct net_device *ocrdma_get_netdev(struct ib_device *ibdev, u8 port_num)
-{
-       struct ocrdma_dev *dev;
-       struct net_device *ndev = NULL;
-
-       rcu_read_lock();
-
-       dev = get_ocrdma_dev(ibdev);
-       if (dev)
-               ndev = dev->nic_info.netdev;
-       if (ndev)
-               dev_hold(ndev);
-
-       rcu_read_unlock();
-
-       return ndev;
-}
-
 static inline void get_link_speed_and_width(struct ocrdma_dev *dev,
                                            u8 *ib_speed, u8 *ib_width)
 {
@@ -367,6 +350,16 @@ static int ocrdma_get_pd_num(struct ocrdma_dev *dev, struct ocrdma_pd *pd)
        return status;
 }
 
+/*
+ * NOTE:
+ *
+ * ocrdma_ucontext must be used here because this function is also
+ * called from ocrdma_alloc_ucontext where ib_udata does not have
+ * valid ib_ucontext pointer. ib_uverbs_get_context does not call
+ * uobj_{alloc|get_xxx} helpers which are used to store the
+ * ib_ucontext in uverbs_attr_bundle wrapping the ib_udata. so
+ * ib_udata does NOT imply valid ib_ucontext here!
+ */
 static int _ocrdma_alloc_pd(struct ocrdma_dev *dev, struct ocrdma_pd *pd,
                            struct ocrdma_ucontext *uctx,
                            struct ib_udata *udata)
@@ -593,7 +586,6 @@ int ocrdma_mmap(struct ib_ucontext *context, struct vm_area_struct *vma)
 }
 
 static int ocrdma_copy_pd_uresp(struct ocrdma_dev *dev, struct ocrdma_pd *pd,
-                               struct ib_ucontext *ib_ctx,
                                struct ib_udata *udata)
 {
        int status;
@@ -601,7 +593,8 @@ static int ocrdma_copy_pd_uresp(struct ocrdma_dev *dev, struct ocrdma_pd *pd,
        u64 dpp_page_addr = 0;
        u32 db_page_size;
        struct ocrdma_alloc_pd_uresp rsp;
-       struct ocrdma_ucontext *uctx = get_ocrdma_ucontext(ib_ctx);
+       struct ocrdma_ucontext *uctx = rdma_udata_to_drv_context(
+               udata, struct ocrdma_ucontext, ibucontext);
 
        memset(&rsp, 0, sizeof(rsp));
        rsp.id = pd->id;
@@ -639,18 +632,17 @@ dpp_map_err:
        return status;
 }
 
-int ocrdma_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
-                   struct ib_udata *udata)
+int ocrdma_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
 {
        struct ib_device *ibdev = ibpd->device;
        struct ocrdma_dev *dev = get_ocrdma_dev(ibdev);
        struct ocrdma_pd *pd;
-       struct ocrdma_ucontext *uctx = NULL;
        int status;
        u8 is_uctx_pd = false;
+       struct ocrdma_ucontext *uctx = rdma_udata_to_drv_context(
+               udata, struct ocrdma_ucontext, ibucontext);
 
-       if (udata && context) {
-               uctx = get_ocrdma_ucontext(context);
+       if (udata) {
                pd = ocrdma_get_ucontext_pd(uctx);
                if (pd) {
                        is_uctx_pd = true;
@@ -664,8 +656,8 @@ int ocrdma_alloc_pd(struct ib_pd *ibpd, struct ib_ucontext *context,
                goto exit;
 
 pd_mapping:
-       if (udata && context) {
-               status = ocrdma_copy_pd_uresp(dev, pd, context, udata);
+       if (udata) {
+               status = ocrdma_copy_pd_uresp(dev, pd, udata);
                if (status)
                        goto err;
        }
@@ -680,7 +672,7 @@ exit:
        return status;
 }
 
-void ocrdma_dealloc_pd(struct ib_pd *ibpd)
+void ocrdma_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata)
 {
        struct ocrdma_pd *pd = get_ocrdma_pd(ibpd);
        struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device);
@@ -922,7 +914,7 @@ umem_err:
        return ERR_PTR(status);
 }
 
-int ocrdma_dereg_mr(struct ib_mr *ib_mr)
+int ocrdma_dereg_mr(struct ib_mr *ib_mr, struct ib_udata *udata)
 {
        struct ocrdma_mr *mr = get_ocrdma_mr(ib_mr);
        struct ocrdma_dev *dev = get_ocrdma_dev(ib_mr->device);
@@ -946,13 +938,17 @@ int ocrdma_dereg_mr(struct ib_mr *ib_mr)
 }
 
 static int ocrdma_copy_cq_uresp(struct ocrdma_dev *dev, struct ocrdma_cq *cq,
-                               struct ib_udata *udata,
-                               struct ib_ucontext *ib_ctx)
+                               struct ib_udata *udata)
 {
        int status;
-       struct ocrdma_ucontext *uctx = get_ocrdma_ucontext(ib_ctx);
+       struct ocrdma_ucontext *uctx = rdma_udata_to_drv_context(
+               udata, struct ocrdma_ucontext, ibucontext);
        struct ocrdma_create_cq_uresp uresp;
 
+       /* this must be user flow! */
+       if (!udata)
+               return -EINVAL;
+
        memset(&uresp, 0, sizeof(uresp));
        uresp.cq_id = cq->id;
        uresp.page_size = PAGE_ALIGN(cq->len);
@@ -983,13 +979,13 @@ err:
 
 struct ib_cq *ocrdma_create_cq(struct ib_device *ibdev,
                               const struct ib_cq_init_attr *attr,
-                              struct ib_ucontext *ib_ctx,
                               struct ib_udata *udata)
 {
        int entries = attr->cqe;
        struct ocrdma_cq *cq;
        struct ocrdma_dev *dev = get_ocrdma_dev(ibdev);
-       struct ocrdma_ucontext *uctx = NULL;
+       struct ocrdma_ucontext *uctx = rdma_udata_to_drv_context(
+               udata, struct ocrdma_ucontext, ibucontext);
        u16 pd_id = 0;
        int status;
        struct ocrdma_create_cq_ureq ureq;
@@ -1011,18 +1007,16 @@ struct ib_cq *ocrdma_create_cq(struct ib_device *ibdev,
        INIT_LIST_HEAD(&cq->sq_head);
        INIT_LIST_HEAD(&cq->rq_head);
 
-       if (ib_ctx) {
-               uctx = get_ocrdma_ucontext(ib_ctx);
+       if (udata)
                pd_id = uctx->cntxt_pd->id;
-       }
 
        status = ocrdma_mbx_create_cq(dev, cq, entries, ureq.dpp_cq, pd_id);
        if (status) {
                kfree(cq);
                return ERR_PTR(status);
        }
-       if (ib_ctx) {
-               status = ocrdma_copy_cq_uresp(dev, cq, udata, ib_ctx);
+       if (udata) {
+               status = ocrdma_copy_cq_uresp(dev, cq, udata);
                if (status)
                        goto ctx_err;
        }
@@ -1076,7 +1070,7 @@ static void ocrdma_flush_cq(struct ocrdma_cq *cq)
        spin_unlock_irqrestore(&cq->cq_lock, flags);
 }
 
-int ocrdma_destroy_cq(struct ib_cq *ibcq)
+int ocrdma_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata)
 {
        struct ocrdma_cq *cq = get_ocrdma_cq(ibcq);
        struct ocrdma_eq *eq = NULL;
@@ -1697,7 +1691,7 @@ void ocrdma_del_flush_qp(struct ocrdma_qp *qp)
        spin_unlock_irqrestore(&dev->flush_q_lock, flags);
 }
 
-int ocrdma_destroy_qp(struct ib_qp *ibqp)
+int ocrdma_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata)
 {
        struct ocrdma_pd *pd;
        struct ocrdma_qp *qp;
@@ -1793,45 +1787,43 @@ static int ocrdma_copy_srq_uresp(struct ocrdma_dev *dev, struct ocrdma_srq *srq,
        return status;
 }
 
-struct ib_srq *ocrdma_create_srq(struct ib_pd *ibpd,
-                                struct ib_srq_init_attr *init_attr,
-                                struct ib_udata *udata)
+int ocrdma_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init_attr,
+                     struct ib_udata *udata)
 {
-       int status = -ENOMEM;
-       struct ocrdma_pd *pd = get_ocrdma_pd(ibpd);
-       struct ocrdma_dev *dev = get_ocrdma_dev(ibpd->device);
-       struct ocrdma_srq *srq;
+       int status;
+       struct ocrdma_pd *pd = get_ocrdma_pd(ibsrq->pd);
+       struct ocrdma_dev *dev = get_ocrdma_dev(ibsrq->device);
+       struct ocrdma_srq *srq = get_ocrdma_srq(ibsrq);
 
        if (init_attr->attr.max_sge > dev->attr.max_recv_sge)
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
        if (init_attr->attr.max_wr > dev->attr.max_rqe)
-               return ERR_PTR(-EINVAL);
-
-       srq = kzalloc(sizeof(*srq), GFP_KERNEL);
-       if (!srq)
-               return ERR_PTR(status);
+               return -EINVAL;
 
        spin_lock_init(&srq->q_lock);
        srq->pd = pd;
        srq->db = dev->nic_info.db + (pd->id * dev->nic_info.db_page_size);
        status = ocrdma_mbx_create_srq(dev, srq, init_attr, pd);
        if (status)
-               goto err;
+               return status;
 
-       if (udata == NULL) {
-               status = -ENOMEM;
+       if (!udata) {
                srq->rqe_wr_id_tbl = kcalloc(srq->rq.max_cnt, sizeof(u64),
                                             GFP_KERNEL);
-               if (srq->rqe_wr_id_tbl == NULL)
+               if (!srq->rqe_wr_id_tbl) {
+                       status = -ENOMEM;
                        goto arm_err;
+               }
 
                srq->bit_fields_len = (srq->rq.max_cnt / 32) +
                    (srq->rq.max_cnt % 32 ? 1 : 0);
                srq->idx_bit_fields =
                    kmalloc_array(srq->bit_fields_len, sizeof(u32),
                                  GFP_KERNEL);
-               if (srq->idx_bit_fields == NULL)
+               if (!srq->idx_bit_fields) {
+                       status = -ENOMEM;
                        goto arm_err;
+               }
                memset(srq->idx_bit_fields, 0xff,
                       srq->bit_fields_len * sizeof(u32));
        }
@@ -1848,15 +1840,13 @@ struct ib_srq *ocrdma_create_srq(struct ib_pd *ibpd,
                        goto arm_err;
        }
 
-       return &srq->ibsrq;
+       return 0;
 
 arm_err:
        ocrdma_mbx_destroy_srq(dev, srq);
-err:
        kfree(srq->rqe_wr_id_tbl);
        kfree(srq->idx_bit_fields);
-       kfree(srq);
-       return ERR_PTR(status);
+       return status;
 }
 
 int ocrdma_modify_srq(struct ib_srq *ibsrq,
@@ -1885,15 +1875,14 @@ int ocrdma_query_srq(struct ib_srq *ibsrq, struct ib_srq_attr *srq_attr)
        return status;
 }
 
-int ocrdma_destroy_srq(struct ib_srq *ibsrq)
+void ocrdma_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata)
 {
-       int status;
        struct ocrdma_srq *srq;
        struct ocrdma_dev *dev = get_ocrdma_dev(ibsrq->device);
 
        srq = get_ocrdma_srq(ibsrq);
 
-       status = ocrdma_mbx_destroy_srq(dev, srq);
+       ocrdma_mbx_destroy_srq(dev, srq);
 
        if (srq->pd->uctx)
                ocrdma_del_mmap(srq->pd->uctx, (u64) srq->rq.pa,
@@ -1901,8 +1890,6 @@ int ocrdma_destroy_srq(struct ib_srq *ibsrq)
 
        kfree(srq->idx_bit_fields);
        kfree(srq->rqe_wr_id_tbl);
-       kfree(srq);
-       return status;
 }
 
 /* unprivileged verbs and their support functions. */
@@ -2931,9 +2918,8 @@ int ocrdma_arm_cq(struct ib_cq *ibcq, enum ib_cq_notify_flags cq_flags)
        return 0;
 }
 
-struct ib_mr *ocrdma_alloc_mr(struct ib_pd *ibpd,
-                             enum ib_mr_type mr_type,
-                             u32 max_num_sg)
+struct ib_mr *ocrdma_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type,
+                             u32 max_num_sg, struct ib_udata *udata)
 {
        int status;
        struct ocrdma_mr *mr;