Vu, you pointed out that the current SRP code might look at an IU that
it sent after that IU has been reused for a different command.  I
realized that a simple fix for this is just to keep the DMA address
(the only thing we look at in the IU) in the request structure.

To add FMR support, we can just put all the FMR stuff in the request
structure instead of the IU structure.  This saves bloating the IUs we
use for receives and task management, so it seems like a win anyway.

Does this patch seem OK and work for you?  It works for me in my setup.

 - R.

--- linux-kernel/infiniband/ulp/srp/ib_srp.c    (revision 3613)
+++ linux-kernel/infiniband/ulp/srp/ib_srp.c    (working copy)
@@ -523,9 +523,9 @@ err:
 }
 
 static int srp_map_data(struct scsi_cmnd *scmnd, struct srp_target_port 
*target,
-                       struct srp_iu *iu)
+                       struct srp_request *req)
 {
-       struct srp_cmd *cmd = iu->buf;
+       struct srp_cmd *cmd = req->cmd->buf;
        int len;
        u8 fmt;
 
@@ -569,7 +569,7 @@ static int srp_map_data(struct scsi_cmnd
                        else
                                cmd->data_in_desc_cnt = n;
 
-                       buf->table_desc.va  = cpu_to_be64(iu->dma +
+                       buf->table_desc.va  = cpu_to_be64(req->cmd->dma +
                                                          sizeof *cmd +
                                                          sizeof *buf);
                        buf->table_desc.key =
@@ -606,6 +606,8 @@ static int srp_map_data(struct scsi_cmnd
                        return -EINVAL;
                }
 
+               pci_unmap_addr_set(req, direct_mapping, dma);
+
                buf->va  = cpu_to_be64(dma);
                buf->key = cpu_to_be32(target->srp_host->mr->rkey);
                buf->len = cpu_to_be32(scmnd->request_bufflen);
@@ -626,7 +628,7 @@ static int srp_map_data(struct scsi_cmnd
 
 static void srp_unmap_data(struct scsi_cmnd *scmnd,
                           struct srp_target_port *target,
-                          struct srp_cmd *cmd)
+                          struct srp_request *req)
 {
        if (!scmnd->request_buffer ||
            (scmnd->sc_data_direction != DMA_TO_DEVICE &&
@@ -639,7 +641,7 @@ static void srp_unmap_data(struct scsi_c
                             scmnd->use_sg, scmnd->sc_data_direction);
        else
                dma_unmap_single(target->srp_host->dev->dma_device,
-                                be64_to_cpu(((struct srp_direct_buf *) 
cmd->add_data)->va),
+                                pci_unmap_addr(req, direct_mapping),
                                 scmnd->request_bufflen,
                                 scmnd->sc_data_direction);
 }
@@ -648,7 +650,6 @@ static void srp_process_rsp(struct srp_t
 {
        struct srp_request *req;
        struct scsi_cmnd *scmnd;
-       struct srp_iu *iu;
        unsigned long flags;
        s32 delta;
 
@@ -667,7 +668,6 @@ static void srp_process_rsp(struct srp_t
                        req->tsk_status = rsp->data[3];
                complete(&req->done);
        } else {
-               iu            = req->cmd;
                scmnd         = req->scmnd;
                scmnd->result = rsp->status;
 
@@ -683,7 +683,7 @@ static void srp_process_rsp(struct srp_t
                else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | 
SRP_RSP_FLAG_DIUNDER))
                        scmnd->resid = be32_to_cpu(rsp->data_in_res_cnt);
 
-               srp_unmap_data(scmnd, target, iu->buf);
+               srp_unmap_data(scmnd, target, req);
 
                if (!req->tsk_mgmt) {
                        req->scmnd = NULL;
@@ -919,7 +919,7 @@ static int srp_queuecommand(struct scsi_
        req->cmd_done = 0;
        req->tsk_mgmt = NULL;
 
-       len = srp_map_data(scmnd, target, iu);
+       len = srp_map_data(scmnd, target, req);
        if (len < 0) {
                printk(KERN_ERR PFX "Failed to map data\n");
                goto err;
@@ -944,7 +944,7 @@ static int srp_queuecommand(struct scsi_
        return 0;
 
 err_unmap:
-       srp_unmap_data(scmnd, target, cmd);
+       srp_unmap_data(scmnd, target, req);
 
 err:
        return SCSI_MLQUEUE_HOST_BUSY;
--- linux-kernel/infiniband/ulp/srp/ib_srp.h    (revision 3613)
+++ linux-kernel/infiniband/ulp/srp/ib_srp.h    (working copy)
@@ -94,6 +94,7 @@ struct srp_request {
        struct scsi_cmnd       *scmnd;
        struct srp_iu          *cmd;
        struct srp_iu          *tsk_mgmt;
+       DECLARE_PCI_UNMAP_ADDR(direct_mapping)
        struct completion       done;
        short                   next;
        u8                      cmd_done;
_______________________________________________
openib-general mailing list
[email protected]
http://openib.org/mailman/listinfo/openib-general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to