diff options
Diffstat (limited to 'drivers/infiniband/hw/mlx4/mr.c')
-rw-r--r-- | drivers/infiniband/hw/mlx4/mr.c | 87 |
1 files changed, 82 insertions, 5 deletions
diff --git a/drivers/infiniband/hw/mlx4/mr.c b/drivers/infiniband/hw/mlx4/mr.c index bbaf6176f207..e471f089ff00 100644 --- a/drivers/infiniband/hw/mlx4/mr.c +++ b/drivers/infiniband/hw/mlx4/mr.c | |||
@@ -41,9 +41,19 @@ static u32 convert_access(int acc) | |||
41 | (acc & IB_ACCESS_REMOTE_WRITE ? MLX4_PERM_REMOTE_WRITE : 0) | | 41 | (acc & IB_ACCESS_REMOTE_WRITE ? MLX4_PERM_REMOTE_WRITE : 0) | |
42 | (acc & IB_ACCESS_REMOTE_READ ? MLX4_PERM_REMOTE_READ : 0) | | 42 | (acc & IB_ACCESS_REMOTE_READ ? MLX4_PERM_REMOTE_READ : 0) | |
43 | (acc & IB_ACCESS_LOCAL_WRITE ? MLX4_PERM_LOCAL_WRITE : 0) | | 43 | (acc & IB_ACCESS_LOCAL_WRITE ? MLX4_PERM_LOCAL_WRITE : 0) | |
44 | (acc & IB_ACCESS_MW_BIND ? MLX4_PERM_BIND_MW : 0) | | ||
44 | MLX4_PERM_LOCAL_READ; | 45 | MLX4_PERM_LOCAL_READ; |
45 | } | 46 | } |
46 | 47 | ||
48 | static enum mlx4_mw_type to_mlx4_type(enum ib_mw_type type) | ||
49 | { | ||
50 | switch (type) { | ||
51 | case IB_MW_TYPE_1: return MLX4_MW_TYPE_1; | ||
52 | case IB_MW_TYPE_2: return MLX4_MW_TYPE_2; | ||
53 | default: return -1; | ||
54 | } | ||
55 | } | ||
56 | |||
47 | struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc) | 57 | struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc) |
48 | { | 58 | { |
49 | struct mlx4_ib_mr *mr; | 59 | struct mlx4_ib_mr *mr; |
@@ -68,7 +78,7 @@ struct ib_mr *mlx4_ib_get_dma_mr(struct ib_pd *pd, int acc) | |||
68 | return &mr->ibmr; | 78 | return &mr->ibmr; |
69 | 79 | ||
70 | err_mr: | 80 | err_mr: |
71 | mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr); | 81 | (void) mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr); |
72 | 82 | ||
73 | err_free: | 83 | err_free: |
74 | kfree(mr); | 84 | kfree(mr); |
@@ -163,7 +173,7 @@ struct ib_mr *mlx4_ib_reg_user_mr(struct ib_pd *pd, u64 start, u64 length, | |||
163 | return &mr->ibmr; | 173 | return &mr->ibmr; |
164 | 174 | ||
165 | err_mr: | 175 | err_mr: |
166 | mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr); | 176 | (void) mlx4_mr_free(to_mdev(pd->device)->dev, &mr->mmr); |
167 | 177 | ||
168 | err_umem: | 178 | err_umem: |
169 | ib_umem_release(mr->umem); | 179 | ib_umem_release(mr->umem); |
@@ -177,8 +187,11 @@ err_free: | |||
177 | int mlx4_ib_dereg_mr(struct ib_mr *ibmr) | 187 | int mlx4_ib_dereg_mr(struct ib_mr *ibmr) |
178 | { | 188 | { |
179 | struct mlx4_ib_mr *mr = to_mmr(ibmr); | 189 | struct mlx4_ib_mr *mr = to_mmr(ibmr); |
190 | int ret; | ||
180 | 191 | ||
181 | mlx4_mr_free(to_mdev(ibmr->device)->dev, &mr->mmr); | 192 | ret = mlx4_mr_free(to_mdev(ibmr->device)->dev, &mr->mmr); |
193 | if (ret) | ||
194 | return ret; | ||
182 | if (mr->umem) | 195 | if (mr->umem) |
183 | ib_umem_release(mr->umem); | 196 | ib_umem_release(mr->umem); |
184 | kfree(mr); | 197 | kfree(mr); |
@@ -186,6 +199,70 @@ int mlx4_ib_dereg_mr(struct ib_mr *ibmr) | |||
186 | return 0; | 199 | return 0; |
187 | } | 200 | } |
188 | 201 | ||
202 | struct ib_mw *mlx4_ib_alloc_mw(struct ib_pd *pd, enum ib_mw_type type) | ||
203 | { | ||
204 | struct mlx4_ib_dev *dev = to_mdev(pd->device); | ||
205 | struct mlx4_ib_mw *mw; | ||
206 | int err; | ||
207 | |||
208 | mw = kmalloc(sizeof(*mw), GFP_KERNEL); | ||
209 | if (!mw) | ||
210 | return ERR_PTR(-ENOMEM); | ||
211 | |||
212 | err = mlx4_mw_alloc(dev->dev, to_mpd(pd)->pdn, | ||
213 | to_mlx4_type(type), &mw->mmw); | ||
214 | if (err) | ||
215 | goto err_free; | ||
216 | |||
217 | err = mlx4_mw_enable(dev->dev, &mw->mmw); | ||
218 | if (err) | ||
219 | goto err_mw; | ||
220 | |||
221 | mw->ibmw.rkey = mw->mmw.key; | ||
222 | |||
223 | return &mw->ibmw; | ||
224 | |||
225 | err_mw: | ||
226 | mlx4_mw_free(dev->dev, &mw->mmw); | ||
227 | |||
228 | err_free: | ||
229 | kfree(mw); | ||
230 | |||
231 | return ERR_PTR(err); | ||
232 | } | ||
233 | |||
234 | int mlx4_ib_bind_mw(struct ib_qp *qp, struct ib_mw *mw, | ||
235 | struct ib_mw_bind *mw_bind) | ||
236 | { | ||
237 | struct ib_send_wr wr; | ||
238 | struct ib_send_wr *bad_wr; | ||
239 | int ret; | ||
240 | |||
241 | memset(&wr, 0, sizeof(wr)); | ||
242 | wr.opcode = IB_WR_BIND_MW; | ||
243 | wr.wr_id = mw_bind->wr_id; | ||
244 | wr.send_flags = mw_bind->send_flags; | ||
245 | wr.wr.bind_mw.mw = mw; | ||
246 | wr.wr.bind_mw.bind_info = mw_bind->bind_info; | ||
247 | wr.wr.bind_mw.rkey = ib_inc_rkey(mw->rkey); | ||
248 | |||
249 | ret = mlx4_ib_post_send(qp, &wr, &bad_wr); | ||
250 | if (!ret) | ||
251 | mw->rkey = wr.wr.bind_mw.rkey; | ||
252 | |||
253 | return ret; | ||
254 | } | ||
255 | |||
256 | int mlx4_ib_dealloc_mw(struct ib_mw *ibmw) | ||
257 | { | ||
258 | struct mlx4_ib_mw *mw = to_mmw(ibmw); | ||
259 | |||
260 | mlx4_mw_free(to_mdev(ibmw->device)->dev, &mw->mmw); | ||
261 | kfree(mw); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
189 | struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd, | 266 | struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd, |
190 | int max_page_list_len) | 267 | int max_page_list_len) |
191 | { | 268 | { |
@@ -212,7 +289,7 @@ struct ib_mr *mlx4_ib_alloc_fast_reg_mr(struct ib_pd *pd, | |||
212 | return &mr->ibmr; | 289 | return &mr->ibmr; |
213 | 290 | ||
214 | err_mr: | 291 | err_mr: |
215 | mlx4_mr_free(dev->dev, &mr->mmr); | 292 | (void) mlx4_mr_free(dev->dev, &mr->mmr); |
216 | 293 | ||
217 | err_free: | 294 | err_free: |
218 | kfree(mr); | 295 | kfree(mr); |
@@ -291,7 +368,7 @@ struct ib_fmr *mlx4_ib_fmr_alloc(struct ib_pd *pd, int acc, | |||
291 | return &fmr->ibfmr; | 368 | return &fmr->ibfmr; |
292 | 369 | ||
293 | err_mr: | 370 | err_mr: |
294 | mlx4_mr_free(to_mdev(pd->device)->dev, &fmr->mfmr.mr); | 371 | (void) mlx4_mr_free(to_mdev(pd->device)->dev, &fmr->mfmr.mr); |
295 | 372 | ||
296 | err_free: | 373 | err_free: |
297 | kfree(fmr); | 374 | kfree(fmr); |