IB/mlx4: Add support for memory management extensions and local DMA L_Key
[deliverable/linux.git] / drivers / infiniband / hw / mlx4 / mr.c
index 7dc91a3e712ddb812304984ad5b5f24403709e68..db2086faa4edd9680e872ce8a4d74200e1fe2b71 100644 (file)
@@ -132,7 +132,8 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length,
        if (!mr)
                return ERR_PTR(-ENOMEM);
 
-       mr->umem = ib_umem_get(pd->uobject->context, start, length, access_flags);
+       mr->umem = ib_umem_get(pd->uobject->context, start, length,
+                              access_flags, 0);
        if (IS_ERR(mr->umem)) {
                err = PTR_ERR(mr->umem);
                goto err_free;
@@ -182,6 +183,76 @@ int mlx4_ib_dereg_mr(struct ib_mr *ibmr)
        return 0;
 }
 
+struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd,
+                                       int max_page_list_len)
+{
+       struct mlx4_ib_dev *dev = to_mdev(pd->device);
+       struct mlx4_ib_mr *mr;
+       int err;
+
+       mr = kmalloc(sizeof *mr, GFP_KERNEL);
+       if (!mr)
+               return ERR_PTR(-ENOMEM);
+
+       err = mlx4_mr_alloc(dev->dev, to_mpd(pd)->pdn, 0, 0, 0,
+                           max_page_list_len, 0, &mr->mmr);
+       if (err)
+               goto err_free;
+
+       err = mlx4_mr_enable(dev->dev, &mr->mmr);
+       if (err)
+               goto err_mr;
+
+       return &mr->ibmr;
+
+err_mr:
+       mlx4_mr_free(dev->dev, &mr->mmr);
+
+err_free:
+       kfree(mr);
+       return ERR_PTR(err);
+}
+
+struct ib_fast_reg_page_list *mlx4_ib_alloc_fast_reg_page_list(struct ib_device *ibdev,
+                                                              int page_list_len)
+{
+       struct mlx4_ib_dev *dev = to_mdev(ibdev);
+       struct mlx4_ib_fast_reg_page_list *mfrpl;
+       int size = page_list_len * sizeof (u64);
+
+       if (size > PAGE_SIZE)
+               return ERR_PTR(-EINVAL);
+
+       mfrpl = kmalloc(sizeof *mfrpl, GFP_KERNEL);
+       if (!mfrpl)
+               return ERR_PTR(-ENOMEM);
+
+       mfrpl->ibfrpl.page_list = dma_alloc_coherent(&dev->dev->pdev->dev,
+                                                    size, &mfrpl->map,
+                                                    GFP_KERNEL);
+       if (!mfrpl->ibfrpl.page_list)
+               goto err_free;
+
+       WARN_ON(mfrpl->map & 0x3f);
+
+       return &mfrpl->ibfrpl;
+
+err_free:
+       kfree(mfrpl);
+       return ERR_PTR(-ENOMEM);
+}
+
+void mlx4_ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list)
+{
+       struct mlx4_ib_dev *dev = to_mdev(page_list->device);
+       struct mlx4_ib_fast_reg_page_list *mfrpl = to_mfrpl(page_list);
+       int size = page_list->max_page_list_len * sizeof (u64);
+
+       dma_free_coherent(&dev->dev->pdev->dev, size, page_list->page_list,
+                         mfrpl->map);
+       kfree(mfrpl);
+}
+
 struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc,
                                 struct ib_fmr_attr *fmr_attr)
 {
@@ -199,7 +270,7 @@ struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc,
        if (err)
                goto err_free;
 
-       err = mlx4_mr_enable(to_mdev(pd->device)->dev, &fmr->mfmr.mr);
+       err = mlx4_fmr_enable(to_mdev(pd->device)->dev, &fmr->mfmr);
        if (err)
                goto err_mr;
 
This page took 0.034996 seconds and 5 git commands to generate.