IB/iser: Use correct dma direction when unmapping SGs
[firefly-linux-kernel-4.4.55.git] / drivers / infiniband / ulp / iser / iser_memory.c
index 6c5ce357fba6baa19fc62d39bd4c9b79be8c48a2..341040bf09849d41e4e01c613e0d0e01683fceda 100644 (file)
@@ -73,7 +73,6 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_task *iser_task,
 
        if (cmd_dir == ISER_DIR_OUT) {
                /* copy the unaligned sg the buffer which is used for RDMA */
-               int i;
                char *p, *from;
 
                sgl = (struct scatterlist *)data->buf;
@@ -333,12 +332,13 @@ int iser_dma_map_task_data(struct iscsi_iser_task *iser_task,
 }
 
 void iser_dma_unmap_task_data(struct iscsi_iser_task *iser_task,
-                             struct iser_data_buf *data)
+                             struct iser_data_buf *data,
+                             enum dma_data_direction dir)
 {
        struct ib_device *dev;
 
        dev = iser_task->iser_conn->ib_conn.device->ib_device;
-       ib_dma_unmap_sg(dev, data->buf, data->size, DMA_FROM_DEVICE);
+       ib_dma_unmap_sg(dev, data->buf, data->size, dir);
 }
 
 static int fall_to_bounce_buf(struct iscsi_iser_task *iser_task,
@@ -358,7 +358,9 @@ static int fall_to_bounce_buf(struct iscsi_iser_task *iser_task,
                iser_data_buf_dump(mem, ibdev);
 
        /* unmap the command data before accessing it */
-       iser_dma_unmap_task_data(iser_task, mem);
+       iser_dma_unmap_task_data(iser_task, mem,
+                                (cmd_dir == ISER_DIR_OUT) ?
+                                DMA_TO_DEVICE : DMA_FROM_DEVICE);
 
        /* allocate copy buf, if we are writing, copy the */
        /* unaligned scatterlist, dma map the copy        */
@@ -409,7 +411,6 @@ int iser_reg_rdma_mem_fmr(struct iscsi_iser_task *iser_task,
                regd_buf->reg.rkey = device->mr->rkey;
                regd_buf->reg.len  = ib_sg_dma_len(ibdev, &sg[0]);
                regd_buf->reg.va   = ib_sg_dma_address(ibdev, &sg[0]);
-               regd_buf->reg.is_mr = 0;
 
                iser_dbg("PHYSICAL Mem.register: lkey: 0x%08X rkey: 0x%08X  "
                         "va: 0x%08lX sz: %ld]\n",
@@ -440,13 +441,13 @@ int iser_reg_rdma_mem_fmr(struct iscsi_iser_task *iser_task,
        return 0;
 }
 
-static inline void
+static void
 iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs,
                    struct ib_sig_domain *domain)
 {
        domain->sig_type = IB_SIG_TYPE_T10_DIF;
-       domain->sig.dif.pi_interval = sc->device->sector_size;
-       domain->sig.dif.ref_tag = scsi_get_lba(sc) & 0xffffffff;
+       domain->sig.dif.pi_interval = scsi_prot_interval(sc);
+       domain->sig.dif.ref_tag = scsi_prot_ref_tag(sc);
        /*
         * At the moment we hard code those, but in the future
         * we will take them from sc.
@@ -454,8 +455,7 @@ iser_set_dif_domain(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs,
        domain->sig.dif.apptag_check_mask = 0xffff;
        domain->sig.dif.app_escape = true;
        domain->sig.dif.ref_escape = true;
-       if (scsi_get_prot_type(sc) == SCSI_PROT_DIF_TYPE1 ||
-           scsi_get_prot_type(sc) == SCSI_PROT_DIF_TYPE2)
+       if (sc->prot_flags & SCSI_PROT_REF_INCREMENT)
                domain->sig.dif.ref_remap = true;
 };
 
@@ -473,26 +473,16 @@ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
        case SCSI_PROT_WRITE_STRIP:
                sig_attrs->wire.sig_type = IB_SIG_TYPE_NONE;
                iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem);
-               /*
-                * At the moment we use this modparam to tell what is
-                * the memory bg_type, in the future we will take it
-                * from sc.
-                */
-               sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM :
-                                                IB_T10DIF_CRC;
+               sig_attrs->mem.sig.dif.bg_type = sc->prot_flags & SCSI_PROT_IP_CHECKSUM ?
+                                               IB_T10DIF_CSUM : IB_T10DIF_CRC;
                break;
        case SCSI_PROT_READ_PASS:
        case SCSI_PROT_WRITE_PASS:
                iser_set_dif_domain(sc, sig_attrs, &sig_attrs->wire);
                sig_attrs->wire.sig.dif.bg_type = IB_T10DIF_CRC;
                iser_set_dif_domain(sc, sig_attrs, &sig_attrs->mem);
-               /*
-                * At the moment we use this modparam to tell what is
-                * the memory bg_type, in the future we will take it
-                * from sc.
-                */
-               sig_attrs->mem.sig.dif.bg_type = iser_pi_guard ? IB_T10DIF_CSUM :
-                                                IB_T10DIF_CRC;
+               sig_attrs->mem.sig.dif.bg_type = sc->prot_flags & SCSI_PROT_IP_CHECKSUM ?
+                                               IB_T10DIF_CSUM : IB_T10DIF_CRC;
                break;
        default:
                iser_err("Unsupported PI operation %d\n",
@@ -503,26 +493,28 @@ iser_set_sig_attrs(struct scsi_cmnd *sc, struct ib_sig_attrs *sig_attrs)
        return 0;
 }
 
-static int
+static inline void
 iser_set_prot_checks(struct scsi_cmnd *sc, u8 *mask)
 {
-       switch (scsi_get_prot_type(sc)) {
-       case SCSI_PROT_DIF_TYPE0:
-               break;
-       case SCSI_PROT_DIF_TYPE1:
-       case SCSI_PROT_DIF_TYPE2:
-               *mask = ISER_CHECK_GUARD | ISER_CHECK_REFTAG;
-               break;
-       case SCSI_PROT_DIF_TYPE3:
-               *mask = ISER_CHECK_GUARD;
-               break;
-       default:
-               iser_err("Unsupported protection type %d\n",
-                        scsi_get_prot_type(sc));
-               return -EINVAL;
-       }
+       *mask = 0;
+       if (sc->prot_flags & SCSI_PROT_REF_CHECK)
+               *mask |= ISER_CHECK_REFTAG;
+       if (sc->prot_flags & SCSI_PROT_GUARD_CHECK)
+               *mask |= ISER_CHECK_GUARD;
+}
 
-       return 0;
+static void
+iser_inv_rkey(struct ib_send_wr *inv_wr, struct ib_mr *mr)
+{
+       u32 rkey;
+
+       memset(inv_wr, 0, sizeof(*inv_wr));
+       inv_wr->opcode = IB_WR_LOCAL_INV;
+       inv_wr->wr_id = ISER_FASTREG_LI_WRID;
+       inv_wr->ex.invalidate_rkey = mr->rkey;
+
+       rkey = ib_inc_rkey(mr->rkey);
+       ib_update_fast_reg_key(mr, rkey);
 }
 
 static int
@@ -536,26 +528,17 @@ iser_reg_sig_mr(struct iscsi_iser_task *iser_task,
        struct ib_send_wr *bad_wr, *wr = NULL;
        struct ib_sig_attrs sig_attrs;
        int ret;
-       u32 key;
 
        memset(&sig_attrs, 0, sizeof(sig_attrs));
        ret = iser_set_sig_attrs(iser_task->sc, &sig_attrs);
        if (ret)
                goto err;
 
-       ret = iser_set_prot_checks(iser_task->sc, &sig_attrs.check_mask);
-       if (ret)
-               goto err;
+       iser_set_prot_checks(iser_task->sc, &sig_attrs.check_mask);
 
        if (!(desc->reg_indicators & ISER_SIG_KEY_VALID)) {
-               memset(&inv_wr, 0, sizeof(inv_wr));
-               inv_wr.opcode = IB_WR_LOCAL_INV;
-               inv_wr.wr_id = ISER_FASTREG_LI_WRID;
-               inv_wr.ex.invalidate_rkey = pi_ctx->sig_mr->rkey;
+               iser_inv_rkey(&inv_wr, pi_ctx->sig_mr);
                wr = &inv_wr;
-               /* Bump the key */
-               key = (u8)(pi_ctx->sig_mr->rkey & 0x000000FF);
-               ib_update_fast_reg_key(pi_ctx->sig_mr, ++key);
        }
 
        memset(&sig_wr, 0, sizeof(sig_wr));
@@ -585,12 +568,7 @@ iser_reg_sig_mr(struct iscsi_iser_task *iser_task,
 
        sig_sge->lkey = pi_ctx->sig_mr->lkey;
        sig_sge->addr = 0;
-       sig_sge->length = data_sge->length + prot_sge->length;
-       if (scsi_get_prot_op(iser_task->sc) == SCSI_PROT_WRITE_INSERT ||
-           scsi_get_prot_op(iser_task->sc) == SCSI_PROT_READ_STRIP) {
-               sig_sge->length += (data_sge->length /
-                                  iser_task->sc->device->sector_size) * 8;
-       }
+       sig_sge->length = scsi_transfer_length(iser_task->sc);
 
        iser_dbg("sig_sge: addr: 0x%llx  length: %u lkey: 0x%x\n",
                 sig_sge->addr, sig_sge->length,
@@ -613,7 +591,6 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task,
        struct ib_fast_reg_page_list *frpl;
        struct ib_send_wr fastreg_wr, inv_wr;
        struct ib_send_wr *bad_wr, *wr = NULL;
-       u8 key;
        int ret, offset, size, plen;
 
        /* if there a single dma entry, dma mr suffices */
@@ -645,14 +622,8 @@ static int iser_fast_reg_mr(struct iscsi_iser_task *iser_task,
        }
 
        if (!(desc->reg_indicators & ind)) {
-               memset(&inv_wr, 0, sizeof(inv_wr));
-               inv_wr.wr_id = ISER_FASTREG_LI_WRID;
-               inv_wr.opcode = IB_WR_LOCAL_INV;
-               inv_wr.ex.invalidate_rkey = mr->rkey;
+               iser_inv_rkey(&inv_wr, mr);
                wr = &inv_wr;
-               /* Bump the key */
-               key = (u8)(mr->rkey & 0x000000FF);
-               ib_update_fast_reg_key(mr, ++key);
        }
 
        /* Prepare FASTREG WR */
@@ -770,15 +741,11 @@ int iser_reg_rdma_mem_fastreg(struct iscsi_iser_task *iser_task,
                regd_buf->reg.rkey = desc->pi_ctx->sig_mr->rkey;
                regd_buf->reg.va = sig_sge.addr;
                regd_buf->reg.len = sig_sge.length;
-               regd_buf->reg.is_mr = 1;
        } else {
-               if (desc) {
+               if (desc)
                        regd_buf->reg.rkey = desc->data_mr->rkey;
-                       regd_buf->reg.is_mr = 1;
-               } else {
+               else
                        regd_buf->reg.rkey = device->mr->rkey;
-                       regd_buf->reg.is_mr = 0;
-               }
 
                regd_buf->reg.lkey = data_sge.lkey;
                regd_buf->reg.va = data_sge.addr;