]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/infiniband/hw/cxgb4/resource.c
Merge tag 'v2.6.37' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / infiniband / hw / cxgb4 / resource.c
index 83b23dfa250dea9171ef44a9e37fa3fc7efe3698..4fb50d58b4934a18fb298e3ef542a7c2f424dab5 100644 (file)
@@ -311,6 +311,9 @@ u32 c4iw_pblpool_alloc(struct c4iw_rdev *rdev, int size)
 {
        unsigned long addr = gen_pool_alloc(rdev->pbl_pool, size);
        PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size);
+       if (!addr && printk_ratelimit())
+               printk(KERN_WARNING MOD "%s: Out of PBL memory\n",
+                      pci_name(rdev->lldi.pdev));
        return (u32)addr;
 }
 
@@ -370,6 +373,9 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size)
 {
        unsigned long addr = gen_pool_alloc(rdev->rqt_pool, size << 6);
        PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size << 6);
+       if (!addr && printk_ratelimit())
+               printk(KERN_WARNING MOD "%s: Out of RQT memory\n",
+                      pci_name(rdev->lldi.pdev));
        return (u32)addr;
 }
 
@@ -416,3 +422,59 @@ void c4iw_rqtpool_destroy(struct c4iw_rdev *rdev)
 {
        gen_pool_destroy(rdev->rqt_pool);
 }
+
+/*
+ * On-Chip QP Memory.
+ */
+#define MIN_OCQP_SHIFT 12      /* 4KB == min ocqp size */
+
+u32 c4iw_ocqp_pool_alloc(struct c4iw_rdev *rdev, int size)
+{
+       unsigned long addr = gen_pool_alloc(rdev->ocqp_pool, size);
+       PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size);
+       return (u32)addr;
+}
+
+void c4iw_ocqp_pool_free(struct c4iw_rdev *rdev, u32 addr, int size)
+{
+       PDBG("%s addr 0x%x size %d\n", __func__, addr, size);
+       gen_pool_free(rdev->ocqp_pool, (unsigned long)addr, size);
+}
+
+int c4iw_ocqp_pool_create(struct c4iw_rdev *rdev)
+{
+       unsigned start, chunk, top;
+
+       rdev->ocqp_pool = gen_pool_create(MIN_OCQP_SHIFT, -1);
+       if (!rdev->ocqp_pool)
+               return -ENOMEM;
+
+       start = rdev->lldi.vr->ocq.start;
+       chunk = rdev->lldi.vr->ocq.size;
+       top = start + chunk;
+
+       while (start < top) {
+               chunk = min(top - start + 1, chunk);
+               if (gen_pool_add(rdev->ocqp_pool, start, chunk, -1)) {
+                       PDBG("%s failed to add OCQP chunk (%x/%x)\n",
+                            __func__, start, chunk);
+                       if (chunk <= 1024 << MIN_OCQP_SHIFT) {
+                               printk(KERN_WARNING MOD
+                                      "Failed to add all OCQP chunks (%x/%x)\n",
+                                      start, top - start);
+                               return 0;
+                       }
+                       chunk >>= 1;
+               } else {
+                       PDBG("%s added OCQP chunk (%x/%x)\n",
+                            __func__, start, chunk);
+                       start += chunk;
+               }
+       }
+       return 0;
+}
+
+void c4iw_ocqp_pool_destroy(struct c4iw_rdev *rdev)
+{
+       gen_pool_destroy(rdev->ocqp_pool);
+}