scsi: target: cxgbit: Unmap DMA buffer before calling target_execute_cmd()
[linux-2.6-microblaze.git] / drivers / target / iscsi / cxgbit / cxgbit_ddp.c
index af35251..b044999 100644 (file)
@@ -265,12 +265,13 @@ void cxgbit_unmap_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
        struct cxgbit_cmd *ccmd = iscsit_priv_cmd(cmd);
 
        if (ccmd->release) {
-               struct cxgbi_task_tag_info *ttinfo = &ccmd->ttinfo;
-
-               if (ttinfo->sgl) {
+               if (cmd->se_cmd.se_cmd_flags & SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC) {
+                       put_page(sg_page(&ccmd->sg));
+               } else {
                        struct cxgbit_sock *csk = conn->context;
                        struct cxgbit_device *cdev = csk->com.cdev;
                        struct cxgbi_ppm *ppm = cdev2ppm(cdev);
+                       struct cxgbi_task_tag_info *ttinfo = &ccmd->ttinfo;
 
                        /* Abort the TCP conn if DDP is not complete to
                         * avoid any possibility of DDP after freeing
@@ -280,14 +281,14 @@ void cxgbit_unmap_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd)
                                     cmd->se_cmd.data_length))
                                cxgbit_abort_conn(csk);
 
+                       if (unlikely(ttinfo->sgl)) {
+                               dma_unmap_sg(&ppm->pdev->dev, ttinfo->sgl,
+                                            ttinfo->nents, DMA_FROM_DEVICE);
+                               ttinfo->nents = 0;
+                               ttinfo->sgl = NULL;
+                       }
                        cxgbi_ppm_ppod_release(ppm, ttinfo->idx);
-
-                       dma_unmap_sg(&ppm->pdev->dev, ttinfo->sgl,
-                                    ttinfo->nents, DMA_FROM_DEVICE);
-               } else {
-                       put_page(sg_page(&ccmd->sg));
                }
-
                ccmd->release = false;
        }
 }