mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-22 13:11:27 +00:00
From Erik Habbinga:
- 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: http://svn.code.sf.net/p/scst/svn/trunk@81 d57e44dd-8a1f-0410-8b47-8ef2f437770f
This commit is contained in:
103
mpt/mpt_scst.c
103
mpt/mpt_scst.c
@@ -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]);
|
||||
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;
|
||||
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();
|
||||
|
||||
Reference in New Issue
Block a user