diff options
author | Tejun Heo <htejun@gmail.com> | 2007-06-27 02:48:43 +0900 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-06-27 02:50:08 -0400 |
commit | b9a4197e266a40d5d1d16c9fb2a852cf10743afe (patch) | |
tree | 6ec97e0122aae58944deee21c6619e23d86be64a /drivers/ata | |
parent | e00f1ff3c8977eff07d0214d2f3478ac947bda0f (diff) |
libata: use PIO for non-16 byte aligned ATAPI commands
The IDE driver used DMA for ATAPI commands if READ/WRITE command is
multiple of sector size or sg command is multiple of 16 bytes. For
libata, READ/WRITE sector alignment is guaranteed by the high level
driver (sr), so we only have to worry about the 16 byte alignment.
This patch makes ata_check_atapi_dma() always request PIO for all data
transfer commands which are not multiple of 16 bytes.
The following reports are related to this problem.
http://bugzilla.kernel.org/show_bug.cgi?id=8605 (confirmed)
http://thread.gmane.org/gmane.linux.kernel/476620 (confirmed)
https://bugzilla.novell.com/show_bug.cgi?id=229260 (probably)
Albert first pointed out the difference between IDE and libata. Kudos
to him.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Cc: Albert Lee <albertcc@tw.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 33 |
1 files changed, 10 insertions, 23 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 642097a7d60..094b51891db 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4109,6 +4109,7 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) if (idx) ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT); } + /** * ata_check_atapi_dma - Check whether ATAPI DMA can be supported * @qc: Metadata associated with taskfile to check @@ -4126,33 +4127,19 @@ static void ata_fill_sg(struct ata_queued_cmd *qc) int ata_check_atapi_dma(struct ata_queued_cmd *qc) { struct ata_port *ap = qc->ap; - int rc = 0; /* Assume ATAPI DMA is OK by default */ - - /* some drives can only do ATAPI DMA on read/write */ - if (unlikely(qc->dev->horkage & ATA_HORKAGE_DMA_RW_ONLY)) { - struct scsi_cmnd *cmd = qc->scsicmd; - u8 *scsicmd = cmd->cmnd; - - switch (scsicmd[0]) { - case READ_10: - case WRITE_10: - case READ_12: - case WRITE_12: - case READ_6: - case WRITE_6: - /* atapi dma maybe ok */ - break; - default: - /* turn off atapi dma */ - return 1; - } - } + + /* Don't allow DMA if it isn't multiple of 16 bytes. Quite a + * few ATAPI devices choke on such DMA requests. + */ + if (unlikely(qc->nbytes & 15)) + return 1; if (ap->ops->check_atapi_dma) - rc = ap->ops->check_atapi_dma(qc); + return ap->ops->check_atapi_dma(qc); - return rc; + return 0; } + /** * ata_qc_prep - Prepare taskfile for submission * @qc: Metadata associated with taskfile to be prepared |