]> err.no Git - linux-2.6/blobdiff - drivers/infiniband/hw/ehca/ehca_cq.c
IB/mthca: Avoid changing userspace ABI to handle DMA write barrier attribute
[linux-2.6] / drivers / infiniband / hw / ehca / ehca_cq.c
index 81aff36101ba5944fab04c22030f7b35a1a61f07..5540b276a33cab4877bdf56833f16fc0c316fb22 100644 (file)
@@ -43,8 +43,6 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include <asm/current.h>
-
 #include "ehca_iverbs.h"
 #include "ehca_classes.h"
 #include "ehca_irq.h"
@@ -134,10 +132,19 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
        if (cqe >= 0xFFFFFFFF - 64 - additional_cqe)
                return ERR_PTR(-EINVAL);
 
+       if (!atomic_add_unless(&shca->num_cqs, 1, ehca_max_cq)) {
+               ehca_err(device, "Unable to create CQ, max number of %i "
+                       "CQs reached.", ehca_max_cq);
+               ehca_err(device, "To increase the maximum number of CQs "
+                       "use the number_of_cqs module parameter.\n");
+               return ERR_PTR(-ENOSPC);
+       }
+
        my_cq = kmem_cache_zalloc(cq_cache, GFP_KERNEL);
        if (!my_cq) {
                ehca_err(device, "Out of memory for ehca_cq struct device=%p",
                         device);
+               atomic_dec(&shca->num_cqs);
                return ERR_PTR(-ENOMEM);
        }
 
@@ -148,7 +155,6 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
        spin_lock_init(&my_cq->task_lock);
        atomic_set(&my_cq->nr_events, 0);
        init_waitqueue_head(&my_cq->wait_completion);
-       my_cq->ownpid = current->tgid;
 
        cq = &my_cq->ib_cq;
 
@@ -166,7 +172,6 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
                write_lock_irqsave(&ehca_cq_idr_lock, flags);
                ret = idr_get_new(&ehca_cq_idr, my_cq, &my_cq->token);
                write_unlock_irqrestore(&ehca_cq_idr_lock, flags);
-
        } while (ret == -EAGAIN);
 
        if (ret) {
@@ -176,6 +181,12 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
                goto create_cq_exit1;
        }
 
+       if (my_cq->token > 0x1FFFFFF) {
+               cq = ERR_PTR(-ENOMEM);
+               ehca_err(device, "Invalid number of cq. device=%p", device);
+               goto create_cq_exit2;
+       }
+
        /*
         * CQs maximum depth is 4GB-64, but we need additional 20 as buffer
         * for receiving errors CQEs.
@@ -185,7 +196,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
 
        if (h_ret != H_SUCCESS) {
                ehca_err(device, "hipz_h_alloc_resource_cq() failed "
-                        "h_ret=%lx device=%p", h_ret, device);
+                        "h_ret=%li device=%p", h_ret, device);
                cq = ERR_PTR(ehca2ib_return_code(h_ret));
                goto create_cq_exit2;
        }
@@ -193,7 +204,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
        ipz_rc = ipz_queue_ctor(NULL, &my_cq->ipz_queue, param.act_pages,
                                EHCA_PAGESIZE, sizeof(struct ehca_cqe), 0, 0);
        if (!ipz_rc) {
-               ehca_err(device, "ipz_queue_ctor() failed ipz_rc=%x device=%p",
+               ehca_err(device, "ipz_queue_ctor() failed ipz_rc=%i device=%p",
                         ipz_rc, device);
                cq = ERR_PTR(-EINVAL);
                goto create_cq_exit3;
@@ -221,7 +232,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
 
                if (h_ret < H_SUCCESS) {
                        ehca_err(device, "hipz_h_register_rpage_cq() failed "
-                                "ehca_cq=%p cq_num=%x h_ret=%lx counter=%i "
+                                "ehca_cq=%p cq_num=%x h_ret=%li counter=%i "
                                 "act_pages=%i", my_cq, my_cq->cq_number,
                                 h_ret, counter, param.act_pages);
                        cq = ERR_PTR(-EINVAL);
@@ -233,7 +244,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
                        if ((h_ret != H_SUCCESS) || vpage) {
                                ehca_err(device, "Registration of pages not "
                                         "complete ehca_cq=%p cq_num=%x "
-                                        "h_ret=%lx", my_cq, my_cq->cq_number,
+                                        "h_ret=%li", my_cq, my_cq->cq_number,
                                         h_ret);
                                cq = ERR_PTR(-EAGAIN);
                                goto create_cq_exit4;
@@ -241,7 +252,7 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
                } else {
                        if (h_ret != H_PAGE_REGISTERED) {
                                ehca_err(device, "Registration of page failed "
-                                        "ehca_cq=%p cq_num=%x h_ret=%lx"
+                                        "ehca_cq=%p cq_num=%x h_ret=%l"
                                         "counter=%i act_pages=%i",
                                         my_cq, my_cq->cq_number,
                                         h_ret, counter, param.act_pages);
@@ -276,6 +287,8 @@ struct ib_cq *ehca_create_cq(struct ib_device *device, int cqe, int comp_vector,
                resp.ipz_queue.queue_length = ipz_queue->queue_length;
                resp.ipz_queue.pagesize = ipz_queue->pagesize;
                resp.ipz_queue.toggle_state = ipz_queue->toggle_state;
+               resp.fw_handle_ofs = (u32)
+                       (my_cq->galpas.user.fw_handle & (PAGE_SIZE - 1));
                if (ib_copy_to_udata(udata, &resp, sizeof(resp))) {
                        ehca_err(device, "Copy to udata failed.");
                        goto create_cq_exit4;
@@ -291,7 +304,7 @@ create_cq_exit3:
        h_ret = hipz_h_destroy_cq(adapter_handle, my_cq, 1);
        if (h_ret != H_SUCCESS)
                ehca_err(device, "hipz_h_destroy_cq() failed ehca_cq=%p "
-                        "cq_num=%x h_ret=%lx", my_cq, my_cq->cq_number, h_ret);
+                        "cq_num=%x h_ret=%li", my_cq, my_cq->cq_number, h_ret);
 
 create_cq_exit2:
        write_lock_irqsave(&ehca_cq_idr_lock, flags);
@@ -301,6 +314,7 @@ create_cq_exit2:
 create_cq_exit1:
        kmem_cache_free(cq_cache, my_cq);
 
+       atomic_dec(&shca->num_cqs);
        return cq;
 }
 
@@ -313,7 +327,6 @@ int ehca_destroy_cq(struct ib_cq *cq)
        struct ehca_shca *shca = container_of(device, struct ehca_shca,
                                              ib_device);
        struct ipz_adapter_handle adapter_handle = shca->ipz_hca_handle;
-       u32 cur_pid = current->tgid;
        unsigned long flags;
 
        if (cq->uobject) {
@@ -322,12 +335,6 @@ int ehca_destroy_cq(struct ib_cq *cq)
                                 "user space cq_num=%x", my_cq->cq_number);
                        return -EINVAL;
                }
-               if (my_cq->ownpid != cur_pid) {
-                       ehca_err(device, "Invalid caller pid=%x ownpid=%x "
-                                "cq_num=%x",
-                                cur_pid, my_cq->ownpid, my_cq->cq_number);
-                       return -EINVAL;
-               }
        }
 
        /*
@@ -355,27 +362,19 @@ int ehca_destroy_cq(struct ib_cq *cq)
                                 cq_num);
        }
        if (h_ret != H_SUCCESS) {
-               ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%lx "
+               ehca_err(device, "hipz_h_destroy_cq() failed h_ret=%li "
                         "ehca_cq=%p cq_num=%x", h_ret, my_cq, cq_num);
                return ehca2ib_return_code(h_ret);
        }
        ipz_queue_dtor(NULL, &my_cq->ipz_queue);
        kmem_cache_free(cq_cache, my_cq);
 
+       atomic_dec(&shca->num_cqs);
        return 0;
 }
 
 int ehca_resize_cq(struct ib_cq *cq, int cqe, struct ib_udata *udata)
 {
-       struct ehca_cq *my_cq = container_of(cq, struct ehca_cq, ib_cq);
-       u32 cur_pid = current->tgid;
-
-       if (cq->uobject && my_cq->ownpid != cur_pid) {
-               ehca_err(cq->device, "Invalid caller pid=%x ownpid=%x",
-                        cur_pid, my_cq->ownpid);
-               return -EINVAL;
-       }
-
        /* TODO: proper resize needs to be done */
        ehca_err(cq->device, "not implemented yet");