Merge branch 'rdma-cq.2' of git://git.infradead.org/users/hch/rdma into 4.5/rdma-cq
[cascardo/linux.git] / drivers / infiniband / ulp / iser / iser_memory.c
1 /*
2  * Copyright (c) 2004, 2005, 2006 Voltaire, Inc. All rights reserved.
3  * Copyright (c) 2013-2014 Mellanox Technologies. All rights reserved.
4  *
5  * This software is available to you under a choice of one of two
6  * licenses.  You may choose to be licensed under the terms of the GNU
7  * General Public License (GPL) Version 2, available from the file
8  * COPYING in the main directory of this source tree, or the
9  * OpenIB.org BSD license below:
10  *
11  *     Redistribution and use in source and binary forms, with or
12  *     without modification, are permitted provided that the following
13  *     conditions are met:
14  *
15  *      - Redistributions of source code must retain the above
16  *        copyright notice, this list of conditions and the following
17  *        disclaimer.
18  *
19  *      - Redistributions in binary form must reproduce the above
20  *        copyright notice, this list of conditions and the following
21  *        disclaimer in the documentation and/or other materials
22  *        provided with the distribution.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31  * SOFTWARE.
32  */
33 #include <linux/module.h>
34 #include <linux/kernel.h>
35 #include <linux/slab.h>
36 #include <linux/mm.h>
37 #include <linux/highmem.h>
38 #include <linux/scatterlist.h>
39
40 #include "iscsi_iser.h"
41 static
42 int iser_fast_reg_fmr(struct iscsi_iser_task *iser_task,
43                       struct iser_data_buf *mem,
44                       struct iser_reg_resources *rsc,
45                       struct iser_mem_reg *mem_reg);
46 static
47 int iser_fast_reg_mr(struct iscsi_iser_task *iser_task,
48                      struct iser_data_buf *mem,
49                      struct iser_reg_resources *rsc,
50                      struct iser_mem_reg *mem_reg);
51
52 static struct iser_reg_ops fastreg_ops = {
53         .alloc_reg_res  = iser_alloc_fastreg_pool,
54         .free_reg_res   = iser_free_fastreg_pool,
55         .reg_mem        = iser_fast_reg_mr,
56         .unreg_mem      = iser_unreg_mem_fastreg,
57         .reg_desc_get   = iser_reg_desc_get_fr,
58         .reg_desc_put   = iser_reg_desc_put_fr,
59 };
60
61 static struct iser_reg_ops fmr_ops = {
62         .alloc_reg_res  = iser_alloc_fmr_pool,
63         .free_reg_res   = iser_free_fmr_pool,
64         .reg_mem        = iser_fast_reg_fmr,
65         .unreg_mem      = iser_unreg_mem_fmr,
66         .reg_desc_get   = iser_reg_desc_get_fmr,
67         .reg_desc_put   = iser_reg_desc_put_fmr,
68 };
69
70 void iser_reg_comp(struct ib_cq *cq, struct ib_wc *wc)
71 {
72         iser_err_comp(wc, "memreg");
73 }
74
75 int iser_assign_reg_ops(struct iser_device *device)
76 {
77         struct ib_device_attr *dev_attr = &device->dev_attr;
78
79         /* Assign function handles  - based on FMR support */
80         if (device->ib_device->alloc_fmr && device->ib_device->dealloc_fmr &&
81             device->ib_device->map_phys_fmr && device->ib_device->unmap_fmr) {
82                 iser_info("FMR supported, using FMR for registration\n");
83                 device->reg_ops = &fmr_ops;
84         } else
85         if (dev_attr->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
86                 iser_info("FastReg supported, using FastReg for registration\n");
87                 device->reg_ops = &fastreg_ops;
88         } else {
89                 iser_err("IB device does not support FMRs nor FastRegs, can't register memory\n");
90                 return -1;
91         }
92
93         return 0;
94 }
95
96 struct iser_fr_desc *
97 iser_reg_desc_get_fr(struct ib_conn *ib_conn)
98 {
99         struct iser_fr_pool *fr_pool = &ib_conn->fr_pool;
100         struct iser_fr_desc *desc;
101         unsigned long flags;
102
103         spin_lock_irqsave(&fr_pool->lock, flags);
104         desc = list_first_entry(&fr_pool->list,
105                                 struct iser_fr_desc, list);
106         list_del(&desc->list);
107         spin_unlock_irqrestore(&fr_pool->lock, flags);
108
109         return desc;
110 }
111
112 void
113 iser_reg_desc_put_fr(struct ib_conn *ib_conn,
114                      struct iser_fr_desc *desc)
115 {
116         struct iser_fr_pool *fr_pool = &ib_conn->fr_pool;
117         unsigned long flags;
118
119         spin_lock_irqsave(&fr_pool->lock, flags);
120         list_add(&desc->list, &fr_pool->list);
121         spin_unlock_irqrestore(&fr_pool->lock, flags);
122 }
123
124 struct iser_fr_desc *
125 iser_reg_desc_get_fmr(struct ib_conn *ib_conn)
126 {
127         struct iser_fr_pool *fr_pool = &ib_conn->fr_pool;
128
129         return list_first_entry(&fr_pool->list,
130                                 struct iser_fr_desc, list);
131 }
132
133 void
134 iser_reg_desc_put_fmr(struct ib_conn *ib_conn,
135                       struct iser_fr_desc *desc)
136 {
137 }
138
139 #define IS_4K_ALIGNED(addr)     ((((unsigned long)addr) & ~MASK_4K) == 0)
140
141 /**
142  * iser_sg_to_page_vec - Translates scatterlist entries to physical addresses
143  * and returns the length of resulting physical address array (may be less than
144  * the original due to possible compaction).
145  *
146  * we build a "page vec" under the assumption that the SG meets the RDMA
147  * alignment requirements. Other then the first and last SG elements, all
148  * the "internal" elements can be compacted into a list whose elements are
149  * dma addresses of physical pages. The code supports also the weird case
150  * where --few fragments of the same page-- are present in the SG as
151  * consecutive elements. Also, it handles one entry SG.
152  */
153
154 static int iser_sg_to_page_vec(struct iser_data_buf *data,
155                                struct ib_device *ibdev, u64 *pages,
156                                int *offset, int *data_size)
157 {
158         struct scatterlist *sg, *sgl = data->sg;
159         u64 start_addr, end_addr, page, chunk_start = 0;
160         unsigned long total_sz = 0;
161         unsigned int dma_len;
162         int i, new_chunk, cur_page, last_ent = data->dma_nents - 1;
163
164         /* compute the offset of first element */
165         *offset = (u64) sgl[0].offset & ~MASK_4K;
166
167         new_chunk = 1;
168         cur_page  = 0;
169         for_each_sg(sgl, sg, data->dma_nents, i) {
170                 start_addr = ib_sg_dma_address(ibdev, sg);
171                 if (new_chunk)
172                         chunk_start = start_addr;
173                 dma_len = ib_sg_dma_len(ibdev, sg);
174                 end_addr = start_addr + dma_len;
175                 total_sz += dma_len;
176
177                 /* collect page fragments until aligned or end of SG list */
178                 if (!IS_4K_ALIGNED(end_addr) && i < last_ent) {
179                         new_chunk = 0;
180                         continue;
181                 }
182                 new_chunk = 1;
183
184                 /* address of the first page in the contiguous chunk;
185                    masking relevant for the very first SG entry,
186                    which might be unaligned */
187                 page = chunk_start & MASK_4K;
188                 do {
189                         pages[cur_page++] = page;
190                         page += SIZE_4K;
191                 } while (page < end_addr);
192         }
193
194         *data_size = total_sz;
195         iser_dbg("page_vec->data_size:%d cur_page %d\n",
196                  *data_size, cur_page);
197         return cur_page;
198 }
199
200 static void iser_data_buf_dump(struct iser_data_buf *data,
201                                struct ib_device *ibdev)
202 {
203         struct scatterlist *sg;
204         int i;
205
206         for_each_sg(data->sg, sg, data->dma_nents, i)
207                 iser_dbg("sg[%d] dma_addr:0x%lX page:0x%p "
208                          "off:0x%x sz:0x%x dma_len:0x%x\n",
209                          i, (unsigned long)ib_sg_dma_address(ibdev, sg),
210                          sg_page(sg), sg->offset,
211                          sg->length, ib_sg_dma_len(ibdev, sg));
212 }
213
214 static void iser_dump_page_vec(struct iser_page_vec *page_vec)
215 {
216         int i;
217
218         iser_err("page vec length %d data size %d\n",
219                  page_vec->length, page_vec->data_size);
220         for (i = 0; i < page_vec->length; i++)
221                 iser_err("%d %lx\n",i,(unsigned long)page_vec->pages[i]);
222 }
223
224 int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
225                             struct iser_data_buf *data,
226                             enum iser_data_dir iser_dir,
227                             enum dma_data_direction dma_dir)
228 {
229         struct ib_device *dev;
230
231         iser_task->dir[iser_dir] = 1;
232         dev = iser_task->iser_conn->ib_conn.device->ib_device;
233
234         data->dma_nents = ib_dma_map_sg(dev, data->sg, data->size, dma_dir);
235         if (data->dma_nents == 0) {
236                 iser_err("dma_map_sg failed!!!\n");
237                 return -EINVAL;
238         }
239         return 0;
240 }
241
242 void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task,
243                               struct iser_data_buf *data,
244                               enum dma_data_direction dir)
245 {
246         struct ib_device *dev;
247
248         dev = iser_task->iser_conn->ib_conn.device->ib_device;
249         ib_dma_unmap_sg(dev, data->sg, data->size, dir);
250 }
251
252 static int
253 iser_reg_dma(struct iser_device *device, struct iser_data_buf *mem,
254              struct iser_mem_reg *reg)
255 {
256         struct scatterlist *sg = mem->sg;
257
258         reg->sge.lkey = device->pd->local_dma_lkey;
259         reg->rkey = device->mr->rkey;
260         reg->sge.addr = ib_sg_dma_address(device->ib_device, &sg[0]);
261         reg->sge.length = ib_sg_dma_len(device->ib_device, &sg[0]);
262
263         iser_dbg("Single DMA entry: lkey=0x%x, rkey=0x%x, addr=0x%llx,"
264                  " length=0x%x\n", reg->sge.lkey, reg->rkey,
265                  reg->sge.addr, reg->sge.length);
266
267         return 0;
268 }
269
270 /**
271  * iser_reg_page_vec - Register physical memory
272  *
273  * returns: 0 on success, errno code on failure
274  */
275 static
276 int iser_fast_reg_fmr(struct iscsi_iser_task *iser_task,
277                       struct iser_data_buf *mem,
278                       struct iser_reg_resources *rsc,
279                       struct iser_mem_reg *reg)
280 {
281         struct ib_conn *ib_conn = &iser_task->iser_conn->ib_conn;
282         struct iser_device *device = ib_conn->device;
283         struct iser_page_vec *page_vec = rsc->page_vec;
284         struct ib_fmr_pool *fmr_pool = rsc->fmr_pool;
285         struct ib_pool_fmr *fmr;
286         int ret, plen;
287
288         plen = iser_sg_to_page_vec(mem, device->ib_device,
289                                    page_vec->pages,
290                                    &page_vec->offset,
291                                    &page_vec->data_size);
292         page_vec->length = plen;
293         if (plen * SIZE_4K < page_vec->data_size) {
294                 iser_err("page vec too short to hold this SG\n");
295                 iser_data_buf_dump(mem, device->ib_device);
296                 iser_dump_page_vec(page_vec);
297                 return -EINVAL;
298         }
299
300         fmr  = ib_fmr_pool_map_phys(fmr_pool,
301                                     page_vec->pages,
302                                     page_vec->length,
303                                     page_vec->pages[0]);
304         if (IS_ERR(fmr)) {
305                 ret = PTR_ERR(fmr);
306                 iser_err("ib_fmr_pool_map_phys failed: %d\n", ret);
307                 return ret;
308         }
309
310         reg->sge.lkey = fmr->fmr->lkey;
311         reg->rkey = fmr->fmr->rkey;
312         reg->sge.addr = page_vec->pages[0] + page_vec->offset;
313         reg->sge.length = page_vec->data_size;
314         reg->mem_h = fmr;
315
316         iser_dbg("fmr reg: lkey=0x%x, rkey=0x%x, addr=0x%llx,"
317                  " length=0x%x\n", reg->sge.lkey, reg->rkey,
318                  reg->sge.addr, reg->sge.length);
319
320         return 0;
321 }
322
323 /**
324  * Unregister (previosuly registered using FMR) memory.
325  * If memory is non-FMR does nothing.
326  */
327 void iser_unreg_mem_fmr(struct iscsi_iser_task *iser_task,
328                         enum iser_data_dir cmd_dir)
329 {
330         struct iser_mem_reg *reg = &iser_task->rdma_reg[cmd_dir];
331         int ret;
332
333         if (!reg->mem_h)
334                 return;
335
336         iser_dbg("PHYSICAL Mem.Unregister mem_h %p\n", reg->mem_h);
337
338         ret = ib_fmr_pool_unmap((struct ib_pool_fmr *)reg->mem_h);
339         if (ret)
340                 iser_err("ib_fmr_pool_unmap failed %d\n", ret);
341
342         reg->mem_h = NULL;
343 }
344
345 void iser_unreg_mem_fastreg(struct iscsi_iser_task *iser_task,
346                             enum iser_data_dir cmd_dir)
347 {
348         struct iser_device *device = iser_task->iser_conn->ib_conn.device;
349         struct iser_mem_reg *reg = &iser_task->rdma_reg[cmd_dir];
350
351         if (!reg->mem_h)
352                 return;
353
354         device->reg_ops->reg_desc_put(&iser_task->iser_conn->ib_conn,
355                                      reg->mem_h);
356         reg->mem_h = NULL;
357 }
358
359 static void
360 iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs,
361                     struct ib_sig_domain *domain)
362 {
363         domain->sig_type = IB_SIG_TYPE_T10_DIF;
364         domain->sig.dif.pi_interval = scsi_prot_interval(sc);
365         domain->sig.dif.ref_tag = scsi_prot_ref_tag(sc);
366         /*
367          * At the moment we hard code those, but in the future
368          * we will take them from sc.
369          */
370         domain->sig.dif.apptag_check_mask = 0xffff;
371         domain->sig.dif.app_escape = true;
372         domain->sig.dif.ref_escape = true;
373         if (sc->prot_flags & SCSI_PROT_REF_INCREMENT)
374                 domain->sig.dif.ref_remap = true;
375 };
376
377 static int
378 iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
379 {
380         switch (scsi_get_prot_op(sc)) {
381         case SCSI_PROT_WRITE_INSERT:
382         case SCSI_PROT_READ_STRIP:
383                 sig_attrs->mem.sig_type = IB_SIG_TYPE_NONE;
384                 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire);
385                 sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
386                 break;
387         case SCSI_PROT_READ_INSERT:
388         case SCSI_PROT_WRITE_STRIP:
389                 sig_attrs->wire.sig_type = IB_SIG_TYPE_NONE;
390                 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem);
391                 sig_attrs->mem.sig.dif.bg_type = sc->prot_flags & SCSI_PROT_IP_CHECKSUM ?
392                                                 IB_T10DIF_CSUM : IB_T10DIF_CRC;
393                 break;
394         case SCSI_PROT_READ_PASS:
395         case SCSI_PROT_WRITE_PASS:
396                 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire);
397                 sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
398                 iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem);
399                 sig_attrs->mem.sig.dif.bg_type = sc->prot_flags & SCSI_PROT_IP_CHECKSUM ?
400                                                 IB_T10DIF_CSUM : IB_T10DIF_CRC;
401                 break;
402         default:
403                 iser_err("Unsupported PI operation %d\n",
404                          scsi_get_prot_op(sc));
405                 return -EINVAL;
406         }
407
408         return 0;
409 }
410
411 static inline void
412 iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask)
413 {
414         *mask = 0;
415         if (sc->prot_flags & SCSI_PROT_REF_CHECK)
416                 *mask |= ISER_CHECK_REFTAG;
417         if (sc->prot_flags & SCSI_PROT_GUARD_CHECK)
418                 *mask |= ISER_CHECK_GUARD;
419 }
420
421 static void
422 iser_inv_rkey(struct ib_send_wr *inv_wr,
423               struct ib_mr *mr,
424               struct ib_cqe *cqe)
425 {
426         u32 rkey;
427
428         inv_wr->opcode = IB_WR_LOCAL_INV;
429         inv_wr->wr_cqe = cqe;
430         inv_wr->ex.invalidate_rkey = mr->rkey;
431         inv_wr->send_flags = 0;
432         inv_wr->num_sge = 0;
433
434         rkey = ib_inc_rkey(mr->rkey);
435         ib_update_fast_reg_key(mr, rkey);
436 }
437
438 static int
439 iser_reg_sig_mr(struct iscsi_iser_task *iser_task,
440                 struct iser_pi_context *pi_ctx,
441                 struct iser_mem_reg *data_reg,
442                 struct iser_mem_reg *prot_reg,
443                 struct iser_mem_reg *sig_reg)
444 {
445         struct iser_tx_desc *tx_desc = &iser_task->desc;
446         struct ib_sig_attrs *sig_attrs = &tx_desc->sig_attrs;
447         struct ib_cqe *cqe = &iser_task->iser_conn->ib_conn.reg_cqe;
448         struct ib_sig_handover_wr *wr;
449         int ret;
450
451         memset(sig_attrs, 0, sizeof(*sig_attrs));
452         ret = iser_set_sig_attrs(iser_task->sc, sig_attrs);
453         if (ret)
454                 goto err;
455
456         iser_set_prot_checks(iser_task->sc, &sig_attrs->check_mask);
457
458         if (!pi_ctx->sig_mr_valid)
459                 iser_inv_rkey(iser_tx_next_wr(tx_desc), pi_ctx->sig_mr, cqe);
460
461         wr = sig_handover_wr(iser_tx_next_wr(tx_desc));
462         wr->wr.opcode = IB_WR_REG_SIG_MR;
463         wr->wr.wr_cqe = cqe;
464         wr->wr.sg_list = &data_reg->sge;
465         wr->wr.num_sge = 1;
466         wr->wr.send_flags = 0;
467         wr->sig_attrs = sig_attrs;
468         wr->sig_mr = pi_ctx->sig_mr;
469         if (scsi_prot_sg_count(iser_task->sc))
470                 wr->prot = &prot_reg->sge;
471         else
472                 wr->prot = NULL;
473         wr->access_flags = IB_ACCESS_LOCAL_WRITE |
474                            IB_ACCESS_REMOTE_READ |
475                            IB_ACCESS_REMOTE_WRITE;
476         pi_ctx->sig_mr_valid = 0;
477
478         sig_reg->sge.lkey = pi_ctx->sig_mr->lkey;
479         sig_reg->rkey = pi_ctx->sig_mr->rkey;
480         sig_reg->sge.addr = 0;
481         sig_reg->sge.length = scsi_transfer_length(iser_task->sc);
482
483         iser_dbg("lkey=0x%x rkey=0x%x addr=0x%llx length=%u\n",
484                  sig_reg->sge.lkey, sig_reg->rkey, sig_reg->sge.addr,
485                  sig_reg->sge.length);
486 err:
487         return ret;
488 }
489
490 static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task,
491                             struct iser_data_buf *mem,
492                             struct iser_reg_resources *rsc,
493                             struct iser_mem_reg *reg)
494 {
495         struct iser_tx_desc *tx_desc = &iser_task->desc;
496         struct ib_cqe *cqe = &iser_task->iser_conn->ib_conn.reg_cqe;
497         struct ib_mr *mr = rsc->mr;
498         struct ib_reg_wr *wr;
499         int n;
500
501         if (!rsc->mr_valid)
502                 iser_inv_rkey(iser_tx_next_wr(tx_desc), mr, cqe);
503
504         n = ib_map_mr_sg(mr, mem->sg, mem->size, SIZE_4K);
505         if (unlikely(n != mem->size)) {
506                 iser_err("failed to map sg (%d/%d)\n",
507                          n, mem->size);
508                 return n < 0 ? n : -EINVAL;
509         }
510
511         wr = reg_wr(iser_tx_next_wr(tx_desc));
512         wr->wr.opcode = IB_WR_REG_MR;
513         wr->wr.wr_cqe = cqe;
514         wr->wr.send_flags = 0;
515         wr->wr.num_sge = 0;
516         wr->mr = mr;
517         wr->key = mr->rkey;
518         wr->access = IB_ACCESS_LOCAL_WRITE  |
519                      IB_ACCESS_REMOTE_WRITE |
520                      IB_ACCESS_REMOTE_READ;
521
522         rsc->mr_valid = 0;
523
524         reg->sge.lkey = mr->lkey;
525         reg->rkey = mr->rkey;
526         reg->sge.addr = mr->iova;
527         reg->sge.length = mr->length;
528
529         iser_dbg("lkey=0x%x rkey=0x%x addr=0x%llx length=0x%x\n",
530                  reg->sge.lkey, reg->rkey, reg->sge.addr, reg->sge.length);
531
532         return 0;
533 }
534
535 static int
536 iser_reg_prot_sg(struct iscsi_iser_task *task,
537                  struct iser_data_buf *mem,
538                  struct iser_fr_desc *desc,
539                  bool use_dma_key,
540                  struct iser_mem_reg *reg)
541 {
542         struct iser_device *device = task->iser_conn->ib_conn.device;
543
544         if (use_dma_key)
545                 return iser_reg_dma(device, mem, reg);
546
547         return device->reg_ops->reg_mem(task, mem, &desc->pi_ctx->rsc, reg);
548 }
549
550 static int
551 iser_reg_data_sg(struct iscsi_iser_task *task,
552                  struct iser_data_buf *mem,
553                  struct iser_fr_desc *desc,
554                  bool use_dma_key,
555                  struct iser_mem_reg *reg)
556 {
557         struct iser_device *device = task->iser_conn->ib_conn.device;
558
559         if (use_dma_key)
560                 return iser_reg_dma(device, mem, reg);
561
562         return device->reg_ops->reg_mem(task, mem, &desc->rsc, reg);
563 }
564
565 int iser_reg_rdma_mem(struct iscsi_iser_task *task,
566                       enum iser_data_dir dir)
567 {
568         struct ib_conn *ib_conn = &task->iser_conn->ib_conn;
569         struct iser_device *device = ib_conn->device;
570         struct iser_data_buf *mem = &task->data[dir];
571         struct iser_mem_reg *reg = &task->rdma_reg[dir];
572         struct iser_mem_reg *data_reg;
573         struct iser_fr_desc *desc = NULL;
574         bool use_dma_key;
575         int err;
576
577         use_dma_key = (mem->dma_nents == 1 && !iser_always_reg &&
578                        scsi_get_prot_op(task->sc) == SCSI_PROT_NORMAL);
579
580         if (!use_dma_key) {
581                 desc = device->reg_ops->reg_desc_get(ib_conn);
582                 reg->mem_h = desc;
583         }
584
585         if (scsi_get_prot_op(task->sc) == SCSI_PROT_NORMAL)
586                 data_reg = reg;
587         else
588                 data_reg = &task->desc.data_reg;
589
590         err = iser_reg_data_sg(task, mem, desc, use_dma_key, data_reg);
591         if (unlikely(err))
592                 goto err_reg;
593
594         if (scsi_get_prot_op(task->sc) != SCSI_PROT_NORMAL) {
595                 struct iser_mem_reg *prot_reg = &task->desc.prot_reg;
596
597                 if (scsi_prot_sg_count(task->sc)) {
598                         mem = &task->prot[dir];
599                         err = iser_reg_prot_sg(task, mem, desc,
600                                                use_dma_key, prot_reg);
601                         if (unlikely(err))
602                                 goto err_reg;
603                 }
604
605                 err = iser_reg_sig_mr(task, desc->pi_ctx, data_reg,
606                                       prot_reg, reg);
607                 if (unlikely(err))
608                         goto err_reg;
609
610                 desc->pi_ctx->sig_protected = 1;
611         }
612
613         return 0;
614
615 err_reg:
616         if (desc)
617                 device->reg_ops->reg_desc_put(ib_conn, desc);
618
619         return err;
620 }
621
622 void iser_unreg_rdma_mem(struct iscsi_iser_task *task,
623                          enum iser_data_dir dir)
624 {
625         struct iser_device *device = task->iser_conn->ib_conn.device;
626
627         device->reg_ops->unreg_mem(task, dir);
628 }