From Erik Habbinga:
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 18 Jan 2007 10:59:48 +0000 (10:59 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Thu, 18 Jan 2007 10:59:48 +0000 (10:59 +0000)
- corrects the amount of data transferred when cached sense data is used to satisfy a REQUEST SENSE command.

- removes support for non scatterlist buffers in scst_cmd (sg_cnt == 0).

git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@81 d57e44dd-8a1f-0410-8b47-8ef2f437770f

mpt/mpt_scst.c

index b775618..36b0357 100644 (file)
@@ -685,23 +685,17 @@ stm_data_done(MPT_ADAPTER *ioc, u32 reply_word,
                struct scst_cmd *scst_cmd, struct mpt_cmd *cmd, int index)
 {
        MPT_STM_PRIV *priv = mpt_stm_priv[ioc->id];
-       uint8_t *buf = NULL;
 
        TRACE_ENTRY();
        TRACE_DBG("scst cmd %p, index %d, data done",  scst_cmd, index);
 
        if (scst_cmd_get_resp_data_len(scst_cmd) > 0) {
                TRACE_DBG("clear the data flags <%p>", scst_cmd);
-               if (scst_cmd_get_sg_cnt(scst_cmd)) {
-                       pci_unmap_sg(priv->ioc->pcidev,
-                               scst_cmd_get_sg(scst_cmd),
-                               scst_cmd_get_sg_cnt(scst_cmd),
-                               scst_to_tgt_dma_dir(scst_cmd_get_data_direction(scst_cmd)));
-               } else {
-                       pci_unmap_single(priv->ioc->pcidev, cmd->dma_handle,
-                               scst_get_buf_first(scst_cmd, &buf),
-                               scst_to_tgt_dma_dir(scst_cmd_get_data_direction(scst_cmd)));
-               }
+               sBUG_ON(scst_cmd_get_sg_cnt(scst_cmd) == 0);
+               pci_unmap_sg(priv->ioc->pcidev,
+                       scst_cmd_get_sg(scst_cmd),
+                       scst_cmd_get_sg_cnt(scst_cmd),
+                       scst_to_tgt_dma_dir(scst_cmd_get_data_direction(scst_cmd)));
        }
        TRACE_EXIT();
 }
@@ -1083,53 +1077,31 @@ static inline void
 mpt_sge_to_sgl(struct mpt_prm *prm, MPT_STM_PRIV *priv, MPT_SGL *sgl)
 {
        unsigned int bufflen = prm->bufflen;
+       int i;
+
        TRACE_ENTRY();
        TRACE_DBG("bufflen %d, %p", bufflen, prm->buffer);
-       if (prm->use_sg) {
-               int i;
-               prm->sg = (struct scatterlist *)prm->buffer;
-               prm->seg_cnt = 
-                       pci_map_sg(priv->ioc->pcidev, prm->sg, prm->use_sg,
+       sBUG_ON(prm->use_sg == 0);
+
+       prm->sg = (struct scatterlist *)prm->buffer;
+       prm->seg_cnt = pci_map_sg(priv->ioc->pcidev, prm->sg, prm->use_sg,
                                   scst_to_tgt_dma_dir(prm->data_direction));
                
-               pci_dma_sync_sg_for_cpu(priv->ioc->pcidev, prm->sg, 
-                               prm->use_sg, 
-                               scst_to_tgt_dma_dir(prm->data_direction));
-               for (i = 0; i < prm->use_sg; i++) {
-                       sgl->sge[i].length = sg_dma_len(&prm->sg[i]);
-                       sgl->sge[i].address = sg_dma_address(&prm->sg[i]);
-
-                       TRACE_DBG("%d, %d", bufflen, prm->sg[i].length);
-                       if (bufflen < prm->sg[i].length) {
-                               sgl->sge[i].length = bufflen;
-                       }
-                       mpt_dump_sge(&sgl->sge[i], &prm->sg[i]);
-                       bufflen -= sgl->sge[i].length;
+       pci_dma_sync_sg_for_cpu(priv->ioc->pcidev, prm->sg, prm->use_sg, 
+                       scst_to_tgt_dma_dir(prm->data_direction));
+       for (i = 0; i < prm->use_sg; i++) {
+               sgl->sge[i].length = sg_dma_len(&prm->sg[i]);
+               sgl->sge[i].address = sg_dma_address(&prm->sg[i]);
+
+               TRACE_DBG("%d, %d", bufflen, prm->sg[i].length);
+               if (bufflen < prm->sg[i].length) {
+                       sgl->sge[i].length = bufflen;
                }
-               pci_dma_sync_sg_for_device(priv->ioc->pcidev, prm->sg, 
-                               prm->use_sg, 
-                               scst_to_tgt_dma_dir(prm->data_direction));
-       } else {
-               prm->cmd->dma_handle = 
-                       pci_map_single(priv->ioc->pcidev, prm->buffer, 
-                                      prm->bufflen,
-                                      scst_to_tgt_dma_dir(prm->data_direction));
-               
-               pci_dma_sync_single_for_cpu(priv->ioc->pcidev, 
-                               prm->cmd->dma_handle, 
-                               prm->bufflen, 
-                               scst_to_tgt_dma_dir(prm->data_direction));
-               sgl->sge[0].length = prm->bufflen;
-               sgl->sge[0].address = virt_to_phys(prm->buffer);
-               
-               mpt_dump_sge(&sgl->sge[0], NULL);
-               pci_dma_sync_single_for_device(priv->ioc->pcidev, 
-                               prm->cmd->dma_handle, 
-                               prm->bufflen, 
-                               scst_to_tgt_dma_dir(prm->data_direction));
-
-               prm->seg_cnt = 1;
+               mpt_dump_sge(&sgl->sge[i], &prm->sg[i]);
+               bufflen -= sgl->sge[i].length;
        }
+       pci_dma_sync_sg_for_device(priv->ioc->pcidev, prm->sg, prm->use_sg, 
+                       scst_to_tgt_dma_dir(prm->data_direction));
        
        sgl->num_sges = prm->seg_cnt;
        
@@ -1500,6 +1472,7 @@ stmapp_pending_sense(struct mpt_cmd *mpt_cmd)
        u8 *cdb;
        struct mpt_prm prm = { 0 };
        struct scst_cmd *scst_cmd;
+       struct scatterlist sg;
 
        TRACE_ENTRY();
 
@@ -1546,11 +1519,19 @@ stmapp_pending_sense(struct mpt_cmd *mpt_cmd)
 
                                        flags = TARGET_ASSIST_FLAGS_AUTO_STATUS;
                                        prm.cmd = mpt_cmd;
+                                       /* smallest amount of data between
+                                        * requested length, buffer size,
+                                        * and cached length */
                                        prm.bufflen = min((size_t)cdb[4], 
-                                                       (size_t)SCSI_SENSE_BUFFERSIZE);
-                                       prm.buffer = 
-                                               priv->pending_sense_buffer[init_index];
-                                       prm.use_sg = 0;
+                                               (size_t)SCSI_SENSE_BUFFERSIZE);
+                                       prm.bufflen = min(prm.bufflen, 
+                                               (size_t)(priv->pending_sense_buffer[init_index][7] 
+                                                        + 8));
+                                       sg.page = virt_to_page(priv->pending_sense_buffer[init_index]);
+                                       sg.offset = offset_in_page(priv->pending_sense_buffer[init_index]);
+                                       sg.length = prm.bufflen;
+                                       prm.buffer = &sg;
+                                       prm.use_sg = 1;
                                        prm.data_direction = SCST_DATA_READ;
                                        prm.tgt = priv->tgt->sess[init_index]->tgt;
                                        prm.cmd->state = MPT_STATE_DATA_OUT;
@@ -1712,20 +1693,14 @@ mpt_inquiry_no_tagged_commands(MPT_STM_PRIV *priv, struct scst_cmd *scst_cmd)
         */
        if (IsScsi(priv) && (scst_cmd->cdb[0] == INQUIRY) && 
                        !(scst_cmd->cdb[1] & 0x1)) {
-               if (!scst_cmd->sg_cnt) {
-                       address = (uint8_t *)scst_cmd->sg;
-                       length = scst_cmd->bufflen;
-               } else {
-                       length = scst_get_buf_first(scst_cmd, &address);
-               }
+               sBUG_ON(scst_cmd->sg_cnt == 0);
+               length = scst_get_buf_first(scst_cmd, &address);
                if (length >= 8) {
                        TRACE_DBG("clearing BQUE + CMDQUE 0x%p", address);
                        address[6] &= ~0x80; /* turn off BQUE */
                        address[7] &= ~0x02; /* turn off CMDQUE */
                }
-               if (scst_cmd->sg_cnt) {
-                       scst_put_buf(scst_cmd, address);
-               }
+               scst_put_buf(scst_cmd, address);
        }
 
        TRACE_EXIT();