diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx4/mr.c')
-rw-r--r-- | drivers/infiniband/hw/mlx4/mr.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index 68e92485fc76..db2086faa4ed 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
@@ -183,6 +183,76 @@ int mlx4_ib_dereg_mr(struct ib_mr *ibmr) | |||
183 | return 0; | 183 | return 0; |
184 | } | 184 | } |
185 | 185 | ||
186 | struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd, | ||
187 | int max_page_list_len) | ||
188 | { | ||
189 | struct mlx4_ib_dev *dev = to_mdev(pd->device); | ||
190 | struct mlx4_ib_mr *mr; | ||
191 | int err; | ||
192 | |||
193 | mr = kmalloc(sizeof *mr, GFP_KERNEL); | ||
194 | if (!mr) | ||
195 | return ERR_PTR(-ENOMEM); | ||
196 | |||
197 | err = mlx4_mr_alloc(dev->dev, to_mpd(pd)->pdn, 0, 0, 0, | ||
198 | max_page_list_len, 0, &mr->mmr); | ||
199 | if (err) | ||
200 | goto err_free; | ||
201 | |||
202 | err = mlx4_mr_enable(dev->dev, &mr->mmr); | ||
203 | if (err) | ||
204 | goto err_mr; | ||
205 | |||
206 | return &mr->ibmr; | ||
207 | |||
208 | err_mr: | ||
209 | mlx4_mr_free(dev->dev, &mr->mmr); | ||
210 | |||
211 | err_free: | ||
212 | kfree(mr); | ||
213 | return ERR_PTR(err); | ||
214 | } | ||
215 | |||
216 | struct ib_fast_reg_page_list *mlx4_ib_alloc_fast_reg_page_list(struct ib_device *ibdev, | ||
217 | int page_list_len) | ||
218 | { | ||
219 | struct mlx4_ib_dev *dev = to_mdev(ibdev); | ||
220 | struct mlx4_ib_fast_reg_page_list *mfrpl; | ||
221 | int size = page_list_len * sizeof (u64); | ||
222 | |||
223 | if (size > PAGE_SIZE) | ||
224 | return ERR_PTR(-EINVAL); | ||
225 | |||
226 | mfrpl = kmalloc(sizeof *mfrpl, GFP_KERNEL); | ||
227 | if (!mfrpl) | ||
228 | return ERR_PTR(-ENOMEM); | ||
229 | |||
230 | mfrpl->ibfrpl.page_list = dma_alloc_coherent(&dev->dev->pdev->dev, | ||
231 | size, &mfrpl->map, | ||
232 | GFP_KERNEL); | ||
233 | if (!mfrpl->ibfrpl.page_list) | ||
234 | goto err_free; | ||
235 | |||
236 | WARN_ON(mfrpl->map & 0x3f); | ||
237 | |||
238 | return &mfrpl->ibfrpl; | ||
239 | |||
240 | err_free: | ||
241 | kfree(mfrpl); | ||
242 | return ERR_PTR(-ENOMEM); | ||
243 | } | ||
244 | |||
245 | void mlx4_ib_free_fast_reg_page_list(struct ib_fast_reg_page_list *page_list) | ||
246 | { | ||
247 | struct mlx4_ib_dev *dev = to_mdev(page_list->device); | ||
248 | struct mlx4_ib_fast_reg_page_list *mfrpl = to_mfrpl(page_list); | ||
249 | int size = page_list->max_page_list_len * sizeof (u64); | ||
250 | |||
251 | dma_free_coherent(&dev->dev->pdev->dev, size, page_list->page_list, | ||
252 | mfrpl->map); | ||
253 | kfree(mfrpl); | ||
254 | } | ||
255 | |||
186 | struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc, | 256 | struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc, |
187 | struct ib_fmr_attr *fmr_attr) | 257 | struct ib_fmr_attr *fmr_attr) |
188 | { | 258 | { |