From: Andrew Vasquez <andrew.vasquez@qlogic.com>
To: Linux-SCSI Mailing List <linux-scsi@vger.kernel.org>,
James Bottomley <James.Bottomley@SteelEye.com>
Cc: Andrew Vasquez <andrew.vasquez@qlogic.com>
Subject: PATCH [4/5] qla2xxx: cleanup DMA mappings...
Date: Wed, 13 Apr 2005 12:19:04 -0700 [thread overview]
Message-ID: <20050413191904.GM9703@plap.qlogic.org> (raw)
In-Reply-To: <20050413191548.GI9703@plap.qlogic.org>
Don't use cmd->request->nr_hw_segments as it may not be initialized
(SG_IO in particular bypasses anything that initializes this and just
uses scsi_do_req to insert a scsi_request directly on the head of the
queue) and a bogus value here can trip up the checks to make sure that
the number of segments will fit in the queue ring buffer, resulting in
commands that are never completed.
Fix up several issues with PCI DMA mapping and failure to check return
values on the mappings.
Make the check for space in the ring buffer happen after the DMA mapping
is done since any checks done before the mapping has taken place are
bogus.
Doug Ledford <dledford@redhat.com>.
Signed-off-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
drivers/scsi/qla2xxx/qla_iocb.c | 77 +++++++++++++++++++---------------------
1 files changed, 38 insertions(+), 39 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_iocb.c 2005-04-13 08:45:53.000000000 -0700
+++ b/drivers/scsi/qla2xxx/qla_iocb.c 2005-04-13 08:56:17.000000000 -0700
@@ -216,18 +216,7 @@ void qla2x00_build_scsi_iocbs_32(srb_t *
cur_seg++;
}
} else {
- dma_addr_t req_dma;
- struct page *page;
- unsigned long offset;
-
- page = virt_to_page(cmd->request_buffer);
- offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK);
- req_dma = pci_map_page(ha->pdev, page, offset,
- cmd->request_bufflen, cmd->sc_data_direction);
-
- sp->dma_handle = req_dma;
-
- *cur_dsd++ = cpu_to_le32(req_dma);
+ *cur_dsd++ = cpu_to_le32(sp->dma_handle);
*cur_dsd++ = cpu_to_le32(cmd->request_bufflen);
}
}
@@ -299,19 +288,8 @@ void qla2x00_build_scsi_iocbs_64(srb_t *
cur_seg++;
}
} else {
- dma_addr_t req_dma;
- struct page *page;
- unsigned long offset;
-
- page = virt_to_page(cmd->request_buffer);
- offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK);
- req_dma = pci_map_page(ha->pdev, page, offset,
- cmd->request_bufflen, cmd->sc_data_direction);
-
- sp->dma_handle = req_dma;
-
- *cur_dsd++ = cpu_to_le32(LSD(req_dma));
- *cur_dsd++ = cpu_to_le32(MSD(req_dma));
+ *cur_dsd++ = cpu_to_le32(LSD(sp->dma_handle));
+ *cur_dsd++ = cpu_to_le32(MSD(sp->dma_handle));
*cur_dsd++ = cpu_to_le32(cmd->request_bufflen);
}
}
@@ -345,6 +323,8 @@ qla2x00_start_scsi(srb_t *sp)
ha = sp->ha;
reg = ha->iobase;
cmd = sp->cmd;
+ /* So we know we haven't pci_map'ed anything yet */
+ tot_dsds = 0;
/* Send marker if required */
if (ha->marker_needed != 0) {
@@ -369,8 +349,32 @@ qla2x00_start_scsi(srb_t *sp)
if (index == MAX_OUTSTANDING_COMMANDS)
goto queuing_error;
+ /* Map the sg table so we have an accurate count of sg entries needed */
+ if (cmd->use_sg) {
+ sg = (struct scatterlist *) cmd->request_buffer;
+ tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg,
+ cmd->sc_data_direction);
+ if (tot_dsds == 0)
+ goto queuing_error;
+ } else if (cmd->request_bufflen) {
+ dma_addr_t req_dma;
+ struct page *page;
+ unsigned long offset;
+
+ page = virt_to_page(cmd->request_buffer);
+ offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK);
+ req_dma = pci_map_page(ha->pdev, page, offset,
+ cmd->request_bufflen, cmd->sc_data_direction);
+
+ if (dma_mapping_error(req_dma))
+ goto queuing_error;
+
+ sp->dma_handle = req_dma;
+ tot_dsds = 1;
+ }
+
/* Calculate the number of request entries needed. */
- req_cnt = (ha->calc_request_entries)(cmd->request->nr_hw_segments);
+ req_cnt = (ha->calc_request_entries)(tot_dsds);
if (ha->req_q_cnt < (req_cnt + 2)) {
cnt = RD_REG_WORD_RELAXED(ISP_REQ_Q_OUT(ha, reg));
if (ha->req_ring_index < cnt)
@@ -382,19 +386,6 @@ qla2x00_start_scsi(srb_t *sp)
if (ha->req_q_cnt < (req_cnt + 2))
goto queuing_error;
- /* Finally, we have enough space, now perform mappings. */
- tot_dsds = 0;
- if (cmd->use_sg) {
- sg = (struct scatterlist *) cmd->request_buffer;
- tot_dsds = pci_map_sg(ha->pdev, sg, cmd->use_sg,
- cmd->sc_data_direction);
- if (tot_dsds == 0)
- goto queuing_error;
- } else if (cmd->request_bufflen) {
- tot_dsds++;
- }
- req_cnt = (ha->calc_request_entries)(tot_dsds);
-
/* Build command packet */
ha->current_outstanding_cmd = handle;
ha->outstanding_cmds[handle] = sp;
@@ -461,6 +452,14 @@ qla2x00_start_scsi(srb_t *sp)
return (QLA_SUCCESS);
queuing_error:
+ if (cmd->use_sg && tot_dsds) {
+ sg = (struct scatterlist *) cmd->request_buffer;
+ pci_unmap_sg(ha->pdev, sg, cmd->use_sg,
+ cmd->sc_data_direction);
+ } else if (tot_dsds) {
+ pci_unmap_page(ha->pdev, sp->dma_handle, cmd->request_bufflen,
+ cmd->sc_data_direction);
+ }
spin_unlock_irqrestore(&ha->hardware_lock, flags);
return (QLA_FUNCTION_FAILED);
--
Andrew Vasquez
next prev parent reply other threads:[~2005-04-13 19:19 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-04-13 19:15 PATCH [0/5] qla2xxx: remote port rework Andrew Vasquez
2005-04-13 19:18 ` PATCH [1/5] qla2xxx: remove internal queuing Andrew Vasquez
2005-04-13 19:18 ` PATCH [2/5] qla2xxx: add remote port codes Andrew Vasquez
2005-04-13 21:40 ` Christoph Hellwig
2005-04-19 6:33 ` Andrew Vasquez
2005-04-19 7:27 ` Andrew Vasquez
2005-04-19 21:13 ` Christoph Hellwig
2005-05-20 6:17 ` Jeremy Higdon
2005-05-20 15:15 ` Andrew Vasquez
2005-05-27 7:51 ` Jeremy Higdon
2005-04-17 15:18 ` James Bottomley
2005-04-13 19:18 ` PATCH [3/5] qla2xxx: remove lun discovery codes Andrew Vasquez
2005-04-13 19:19 ` Andrew Vasquez [this message]
2005-04-13 21:34 ` PATCH [4/5] qla2xxx: cleanup DMA mappings Christoph Hellwig
2005-04-15 18:06 ` Andrew Vasquez
2005-04-13 19:19 ` PATCH [5/5] qla2xxx: remove /proc interface Andrew Vasquez
2005-04-13 19:42 ` PATCH [0/5] qla2xxx: remote port rework Matthew Wilcox
2005-04-13 20:50 ` PATCH [6/5] qla2xxx: update version :) Andrew Vasquez
2005-04-13 20:57 ` James Bottomley
2005-04-13 21:24 ` Andrew Vasquez
2005-04-19 21:15 ` Christoph Hellwig
2005-04-22 7:22 ` Andrew Vasquez
2005-04-24 10:53 ` Christoph Hellwig
2005-04-13 21:17 ` Christoph Hellwig
2005-04-15 17:38 ` Andrew Vasquez
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050413191904.GM9703@plap.qlogic.org \
--to=andrew.vasquez@qlogic.com \
--cc=James.Bottomley@SteelEye.com \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox