diff options
author | Mans Rullgard <mans@mansr.com> | 2016-04-26 12:03:08 +0300 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2016-05-10 12:29:18 -0400 |
commit | ae4c3485fa861af51336e066e1ba42b92af03627 (patch) | |
tree | 4b060815783d2c9d9a4492cf2413c9cd9304738a /drivers/ata | |
parent | e1c1bee34f077baf88f78b24d08c0ba1ba506abd (diff) | |
download | linux-stable-ae4c3485fa861af51336e066e1ba42b92af03627.tar.gz linux-stable-ae4c3485fa861af51336e066e1ba42b92af03627.tar.bz2 linux-stable-ae4c3485fa861af51336e066e1ba42b92af03627.zip |
ata: sata_dwc_460ex: skip dma setup for non-dma commands
Calling dmaengine_prep_slave_sg() for non-dma ATA commands is
unnecessary at best and could be harmful if the dma driver reacts
badly to this. It also causes this driver to print a bogus error
message in these cases.
This patch changes sata_dwc_qc_issue() to only do the dma setup
for dma commands and also reports an error to libata if if fails.
Tested-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: Mans Rullgard <mans@mansr.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/sata_dwc_460ex.c | 35 |
1 files changed, 9 insertions, 26 deletions
diff --git a/drivers/ata/sata_dwc_460ex.c b/drivers/ata/sata_dwc_460ex.c index 1250e18ad856..038e5fbf9921 100644 --- a/drivers/ata/sata_dwc_460ex.c +++ b/drivers/ata/sata_dwc_460ex.c @@ -1023,36 +1023,12 @@ static void sata_dwc_bmdma_start(struct ata_queued_cmd *qc) sata_dwc_bmdma_start_by_tag(qc, tag); } -/* - * Function : sata_dwc_qc_prep_by_tag - * arguments : ata_queued_cmd *qc, u8 tag - * Return value : None - * qc_prep for a particular queued command based on tag - */ -static void sata_dwc_qc_prep_by_tag(struct ata_queued_cmd *qc, u8 tag) -{ - struct dma_async_tx_descriptor *desc; - struct ata_port *ap = qc->ap; - struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); - - dev_dbg(ap->dev, "%s: port=%d dma dir=%s n_elem=%d\n", - __func__, ap->port_no, get_dma_dir_descript(qc->dma_dir), - qc->n_elem); - - desc = dma_dwc_xfer_setup(qc); - if (!desc) { - dev_err(ap->dev, "%s: dma_dwc_xfer_setup returns NULL\n", - __func__); - return; - } - hsdevp->desc[tag] = desc; -} - static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc) { u32 sactive; u8 tag = qc->tag; struct ata_port *ap = qc->ap; + struct sata_dwc_device_port *hsdevp = HSDEVP_FROM_AP(ap); #ifdef DEBUG_NCQ if (qc->tag > 0 || ap->link.sactive > 1) @@ -1066,7 +1042,14 @@ static unsigned int sata_dwc_qc_issue(struct ata_queued_cmd *qc) if (!ata_is_ncq(qc->tf.protocol)) tag = 0; - sata_dwc_qc_prep_by_tag(qc, tag); + + if (ata_is_dma(qc->tf.protocol)) { + hsdevp->desc[tag] = dma_dwc_xfer_setup(qc); + if (!hsdevp->desc[tag]) + return AC_ERR_SYSTEM; + } else { + hsdevp->desc[tag] = NULL; + } if (ata_is_ncq(qc->tf.protocol)) { sactive = core_scr_read(SCR_ACTIVE); |