Merge branches 'core', 'cxgb4', 'ip-roce', 'iser', 'misc', 'mlx4', 'nes', 'ocrdma...
[cascardo/linux.git] / drivers / infiniband / hw / nes / nes_verbs.c
index 9722eee..218dd35 100644 (file)
@@ -1186,7 +1186,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd,
                                        nes_free_resource(nesadapter, nesadapter->allocated_qps, qp_num);
                                        kfree(nesqp->allocated_buffer);
                                        nes_debug(NES_DBG_QP, "ib_copy_from_udata() Failed \n");
-                                       return NULL;
+                                       return ERR_PTR(-EFAULT);
                                }
                                if (req.user_wqe_buffers) {
                                        virt_wqs = 1;
@@ -2309,7 +2309,7 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        struct nes_device *nesdev = nesvnic->nesdev;
        struct nes_adapter *nesadapter = nesdev->nesadapter;
        struct ib_mr *ibmr = ERR_PTR(-EINVAL);
-       struct ib_umem_chunk *chunk;
+       struct scatterlist *sg;
        struct nes_ucontext *nes_ucontext;
        struct nes_pbl *nespbl;
        struct nes_mr *nesmr;
@@ -2317,7 +2317,7 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        struct nes_mem_reg_req req;
        struct nes_vpbl vpbl;
        struct nes_root_vpbl root_vpbl;
-       int nmap_index, page_index;
+       int entry, page_index;
        int page_count = 0;
        int err, pbl_depth = 0;
        int chunk_pages;
@@ -2332,6 +2332,7 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        u16 pbl_count;
        u8 single_page = 1;
        u8 stag_key;
+       int first_page = 1;
 
        region = ib_umem_get(pd->uobject->context, start, length, acc, 0);
        if (IS_ERR(region)) {
@@ -2382,128 +2383,125 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                        }
                        nesmr->region = region;
 
-                       list_for_each_entry(chunk, &region->chunk_list, list) {
-                               nes_debug(NES_DBG_MR, "Chunk: nents = %u, nmap = %u .\n",
-                                               chunk->nents, chunk->nmap);
-                               for (nmap_index = 0; nmap_index < chunk->nmap; ++nmap_index) {
-                                       if (sg_dma_address(&chunk->page_list[nmap_index]) & ~PAGE_MASK) {
-                                               ib_umem_release(region);
-                                               nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-                                               nes_debug(NES_DBG_MR, "Unaligned Memory Buffer: 0x%x\n",
-                                                               (unsigned int) sg_dma_address(&chunk->page_list[nmap_index]));
-                                               ibmr = ERR_PTR(-EINVAL);
-                                               kfree(nesmr);
-                                               goto reg_user_mr_err;
-                                       }
+                       for_each_sg(region->sg_head.sgl, sg, region->nmap, entry) {
+                               if (sg_dma_address(sg) & ~PAGE_MASK) {
+                                       ib_umem_release(region);
+                                       nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
+                                       nes_debug(NES_DBG_MR, "Unaligned Memory Buffer: 0x%x\n",
+                                                 (unsigned int) sg_dma_address(sg));
+                                       ibmr = ERR_PTR(-EINVAL);
+                                       kfree(nesmr);
+                                       goto reg_user_mr_err;
+                               }
 
-                                       if (!sg_dma_len(&chunk->page_list[nmap_index])) {
-                                               ib_umem_release(region);
-                                               nes_free_resource(nesadapter, nesadapter->allocated_mrs,
-                                                               stag_index);
-                                               nes_debug(NES_DBG_MR, "Invalid Buffer Size\n");
-                                               ibmr = ERR_PTR(-EINVAL);
-                                               kfree(nesmr);
-                                               goto reg_user_mr_err;
-                                       }
+                               if (!sg_dma_len(sg)) {
+                                       ib_umem_release(region);
+                                       nes_free_resource(nesadapter, nesadapter->allocated_mrs,
+                                                         stag_index);
+                                       nes_debug(NES_DBG_MR, "Invalid Buffer Size\n");
+                                       ibmr = ERR_PTR(-EINVAL);
+                                       kfree(nesmr);
+                                       goto reg_user_mr_err;
+                               }
 
-                                       region_length += sg_dma_len(&chunk->page_list[nmap_index]);
-                                       chunk_pages = sg_dma_len(&chunk->page_list[nmap_index]) >> 12;
-                                       region_length -= skip_pages << 12;
-                                       for (page_index=skip_pages; page_index < chunk_pages; page_index++) {
-                                               skip_pages = 0;
-                                               if ((page_count!=0)&&(page_count<<12)-(region->offset&(4096-1))>=region->length)
-                                                       goto enough_pages;
-                                               if ((page_count&0x01FF) == 0) {
-                                                       if (page_count >= 1024 * 512) {
+                               region_length += sg_dma_len(sg);
+                               chunk_pages = sg_dma_len(sg) >> 12;
+                               region_length -= skip_pages << 12;
+                               for (page_index = skip_pages; page_index < chunk_pages; page_index++) {
+                                       skip_pages = 0;
+                                       if ((page_count != 0) && (page_count<<12)-(region->offset&(4096-1)) >= region->length)
+                                               goto enough_pages;
+                                       if ((page_count&0x01FF) == 0) {
+                                               if (page_count >= 1024 * 512) {
+                                                       ib_umem_release(region);
+                                                       nes_free_resource(nesadapter,
+                                                                         nesadapter->allocated_mrs, stag_index);
+                                                       kfree(nesmr);
+                                                       ibmr = ERR_PTR(-E2BIG);
+                                                       goto reg_user_mr_err;
+                                               }
+                                               if (root_pbl_index == 1) {
+                                                       root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev,
+                                                                       8192, &root_vpbl.pbl_pbase);
+                                                       nes_debug(NES_DBG_MR, "Allocating root PBL, va = %p, pa = 0x%08X\n",
+                                                                 root_vpbl.pbl_vbase, (unsigned int)root_vpbl.pbl_pbase);
+                                                       if (!root_vpbl.pbl_vbase) {
                                                                ib_umem_release(region);
-                                                               nes_free_resource(nesadapter,
-                                                                               nesadapter->allocated_mrs, stag_index);
+                                                               pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase,
+                                                                                   vpbl.pbl_pbase);
+                                                               nes_free_resource(nesadapter, nesadapter->allocated_mrs,
+                                                                                 stag_index);
                                                                kfree(nesmr);
-                                                               ibmr = ERR_PTR(-E2BIG);
+                                                               ibmr = ERR_PTR(-ENOMEM);
                                                                goto reg_user_mr_err;
                                                        }
-                                                       if (root_pbl_index == 1) {
-                                                               root_vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev,
-                                                                               8192, &root_vpbl.pbl_pbase);
-                                                               nes_debug(NES_DBG_MR, "Allocating root PBL, va = %p, pa = 0x%08X\n",
-                                                                               root_vpbl.pbl_vbase, (unsigned int)root_vpbl.pbl_pbase);
-                                                               if (!root_vpbl.pbl_vbase) {
-                                                                       ib_umem_release(region);
-                                                                       pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase,
-                                                                                       vpbl.pbl_pbase);
-                                                                       nes_free_resource(nesadapter, nesadapter->allocated_mrs,
-                                                                                       stag_index);
-                                                                       kfree(nesmr);
-                                                                       ibmr = ERR_PTR(-ENOMEM);
-                                                                       goto reg_user_mr_err;
-                                                               }
-                                                               root_vpbl.leaf_vpbl = kzalloc(sizeof(*root_vpbl.leaf_vpbl)*1024,
-                                                                               GFP_KERNEL);
-                                                               if (!root_vpbl.leaf_vpbl) {
-                                                                       ib_umem_release(region);
-                                                                       pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase,
-                                                                                       root_vpbl.pbl_pbase);
-                                                                       pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase,
-                                                                                       vpbl.pbl_pbase);
-                                                                       nes_free_resource(nesadapter, nesadapter->allocated_mrs,
-                                                                                       stag_index);
-                                                                       kfree(nesmr);
-                                                                       ibmr = ERR_PTR(-ENOMEM);
-                                                                       goto reg_user_mr_err;
-                                                               }
-                                                               root_vpbl.pbl_vbase[0].pa_low =
-                                                                               cpu_to_le32((u32)vpbl.pbl_pbase);
-                                                               root_vpbl.pbl_vbase[0].pa_high =
-                                                                               cpu_to_le32((u32)((((u64)vpbl.pbl_pbase) >> 32)));
-                                                               root_vpbl.leaf_vpbl[0] = vpbl;
-                                                       }
-                                                       vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096,
-                                                                       &vpbl.pbl_pbase);
-                                                       nes_debug(NES_DBG_MR, "Allocating leaf PBL, va = %p, pa = 0x%08X\n",
-                                                                       vpbl.pbl_vbase, (unsigned int)vpbl.pbl_pbase);
-                                                       if (!vpbl.pbl_vbase) {
+                                                       root_vpbl.leaf_vpbl = kzalloc(sizeof(*root_vpbl.leaf_vpbl)*1024,
+                                                                       GFP_KERNEL);
+                                                       if (!root_vpbl.leaf_vpbl) {
                                                                ib_umem_release(region);
-                                                               nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
-                                                               ibmr = ERR_PTR(-ENOMEM);
+                                                               pci_free_consistent(nesdev->pcidev, 8192, root_vpbl.pbl_vbase,
+                                                                                   root_vpbl.pbl_pbase);
+                                                               pci_free_consistent(nesdev->pcidev, 4096, vpbl.pbl_vbase,
+                                                                                   vpbl.pbl_pbase);
+                                                               nes_free_resource(nesadapter, nesadapter->allocated_mrs,
+                                                                                 stag_index);
                                                                kfree(nesmr);
+                                                               ibmr = ERR_PTR(-ENOMEM);
                                                                goto reg_user_mr_err;
                                                        }
-                                                       if (1 <= root_pbl_index) {
-                                                               root_vpbl.pbl_vbase[root_pbl_index].pa_low =
-                                                                               cpu_to_le32((u32)vpbl.pbl_pbase);
-                                                               root_vpbl.pbl_vbase[root_pbl_index].pa_high =
-                                                                               cpu_to_le32((u32)((((u64)vpbl.pbl_pbase)>>32)));
-                                                               root_vpbl.leaf_vpbl[root_pbl_index] = vpbl;
-                                                       }
-                                                       root_pbl_index++;
-                                                       cur_pbl_index = 0;
+                                                       root_vpbl.pbl_vbase[0].pa_low =
+                                                                       cpu_to_le32((u32)vpbl.pbl_pbase);
+                                                       root_vpbl.pbl_vbase[0].pa_high =
+                                                                       cpu_to_le32((u32)((((u64)vpbl.pbl_pbase) >> 32)));
+                                                       root_vpbl.leaf_vpbl[0] = vpbl;
                                                }
-                                               if (single_page) {
-                                                       if (page_count != 0) {
-                                                               if ((last_dma_addr+4096) !=
-                                                                               (sg_dma_address(&chunk->page_list[nmap_index])+
-                                                                               (page_index*4096)))
-                                                                       single_page = 0;
-                                                               last_dma_addr = sg_dma_address(&chunk->page_list[nmap_index])+
-                                                                               (page_index*4096);
-                                                       } else {
-                                                               first_dma_addr = sg_dma_address(&chunk->page_list[nmap_index])+
-                                                                               (page_index*4096);
-                                                               last_dma_addr = first_dma_addr;
-                                                       }
+                                               vpbl.pbl_vbase = pci_alloc_consistent(nesdev->pcidev, 4096,
+                                                               &vpbl.pbl_pbase);
+                                               nes_debug(NES_DBG_MR, "Allocating leaf PBL, va = %p, pa = 0x%08X\n",
+                                                         vpbl.pbl_vbase, (unsigned int)vpbl.pbl_pbase);
+                                               if (!vpbl.pbl_vbase) {
+                                                       ib_umem_release(region);
+                                                       nes_free_resource(nesadapter, nesadapter->allocated_mrs, stag_index);
+                                                       ibmr = ERR_PTR(-ENOMEM);
+                                                       kfree(nesmr);
+                                                       goto reg_user_mr_err;
+                                               }
+                                               if (1 <= root_pbl_index) {
+                                                       root_vpbl.pbl_vbase[root_pbl_index].pa_low =
+                                                                       cpu_to_le32((u32)vpbl.pbl_pbase);
+                                                       root_vpbl.pbl_vbase[root_pbl_index].pa_high =
+                                                                       cpu_to_le32((u32)((((u64)vpbl.pbl_pbase)>>32)));
+                                                       root_vpbl.leaf_vpbl[root_pbl_index] = vpbl;
+                                               }
+                                               root_pbl_index++;
+                                               cur_pbl_index = 0;
+                                       }
+                                       if (single_page) {
+                                               if (page_count != 0) {
+                                                       if ((last_dma_addr+4096) !=
+                                                                       (sg_dma_address(sg)+
+                                                                       (page_index*4096)))
+                                                               single_page = 0;
+                                                       last_dma_addr = sg_dma_address(sg)+
+                                                                       (page_index*4096);
+                                               } else {
+                                                       first_dma_addr = sg_dma_address(sg)+
+                                                                       (page_index*4096);
+                                                       last_dma_addr = first_dma_addr;
                                                }
-
-                                               vpbl.pbl_vbase[cur_pbl_index].pa_low =
-                                                               cpu_to_le32((u32)(sg_dma_address(&chunk->page_list[nmap_index])+
-                                                               (page_index*4096)));
-                                               vpbl.pbl_vbase[cur_pbl_index].pa_high =
-                                                               cpu_to_le32((u32)((((u64)(sg_dma_address(&chunk->page_list[nmap_index])+
-                                                               (page_index*4096))) >> 32)));
-                                               cur_pbl_index++;
-                                               page_count++;
                                        }
+
+                                       vpbl.pbl_vbase[cur_pbl_index].pa_low =
+                                                       cpu_to_le32((u32)(sg_dma_address(sg)+
+                                                       (page_index*4096)));
+                                       vpbl.pbl_vbase[cur_pbl_index].pa_high =
+                                                       cpu_to_le32((u32)((((u64)(sg_dma_address(sg)+
+                                                       (page_index*4096))) >> 32)));
+                                       cur_pbl_index++;
+                                       page_count++;
                                }
                        }
+
                        enough_pages:
                        nes_debug(NES_DBG_MR, "calculating stag, stag_index=0x%08x, driver_key=0x%08x,"
                                        " stag_key=0x%08x\n",
@@ -2615,25 +2613,28 @@ static struct ib_mr *nes_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
                                  nespbl->pbl_size, (unsigned long) nespbl->pbl_pbase,
                                  (void *) nespbl->pbl_vbase, nespbl->user_base);
 
-                       list_for_each_entry(chunk, &region->chunk_list, list) {
-                               for (nmap_index = 0; nmap_index < chunk->nmap; ++nmap_index) {
-                                       chunk_pages = sg_dma_len(&chunk->page_list[nmap_index]) >> 12;
-                                       chunk_pages += (sg_dma_len(&chunk->page_list[nmap_index]) & (4096-1)) ? 1 : 0;
-                                       nespbl->page = sg_page(&chunk->page_list[0]);
-                                       for (page_index=0; page_index<chunk_pages; page_index++) {
-                                               ((__le32 *)pbl)[0] = cpu_to_le32((u32)
-                                                               (sg_dma_address(&chunk->page_list[nmap_index])+
-                                                               (page_index*4096)));
-                                               ((__le32 *)pbl)[1] = cpu_to_le32(((u64)
-                                                               (sg_dma_address(&chunk->page_list[nmap_index])+
-                                                               (page_index*4096)))>>32);
-                                               nes_debug(NES_DBG_MR, "pbl=%p, *pbl=0x%016llx, 0x%08x%08x\n", pbl,
-                                                               (unsigned long long)*pbl,
-                                                               le32_to_cpu(((__le32 *)pbl)[1]), le32_to_cpu(((__le32 *)pbl)[0]));
-                                               pbl++;
-                                       }
+                       for_each_sg(region->sg_head.sgl, sg, region->nmap, entry) {
+                               chunk_pages = sg_dma_len(sg) >> 12;
+                               chunk_pages += (sg_dma_len(sg) & (4096-1)) ? 1 : 0;
+                               if (first_page) {
+                                       nespbl->page = sg_page(sg);
+                                       first_page = 0;
+                               }
+
+                               for (page_index = 0; page_index < chunk_pages; page_index++) {
+                                       ((__le32 *)pbl)[0] = cpu_to_le32((u32)
+                                                       (sg_dma_address(sg)+
+                                                       (page_index*4096)));
+                                       ((__le32 *)pbl)[1] = cpu_to_le32(((u64)
+                                                       (sg_dma_address(sg)+
+                                                       (page_index*4096)))>>32);
+                                       nes_debug(NES_DBG_MR, "pbl=%p, *pbl=0x%016llx, 0x%08x%08x\n", pbl,
+                                                 (unsigned long long)*pbl,
+                                                 le32_to_cpu(((__le32 *)pbl)[1]), le32_to_cpu(((__le32 *)pbl)[0]));
+                                       pbl++;
                                }
                        }
+
                        if (req.reg_type == IWNES_MEMREG_TYPE_QP) {
                                list_add_tail(&nespbl->list, &nes_ucontext->qp_reg_mem_list);
                        } else {