libata: implement ATA_HORKAGE_ATAPI_MOD16_DMA and apply it
authorTejun Heo <tj@kernel.org>
Mon, 3 Nov 2008 10:01:09 +0000 (19:01 +0900)
committerJeff Garzik <jgarzik@redhat.com>
Tue, 4 Nov 2008 06:08:27 +0000 (01:08 -0500)
libata always uses PIO for ATAPI commands when the number of bytes to
transfer isn't multiple of 16 but quantum DAT72 chokes on odd bytes
PIO transfers.  Implement a horkage to skip the mod16 check and apply
it to the quantum device.

This is reported by John Clark in the following thread.

  http://thread.gmane.org/gmane.linux.ide/34748

Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: John Clark <clarkjc@runbox.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
drivers/ata/libata-core.c
include/linux/libata.h

index 82af7011f2ddd137e2a601ae95c704a4219ada9e..91b478f205572ec6570e17bb41bda4b635593311 100644 (file)
@@ -4024,6 +4024,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
 
        /* Weird ATAPI devices */
        { "TORiSAN DVD-ROM DRD-N216", NULL,     ATA_HORKAGE_MAX_SEC_128 },
+       { "QUANTUM DAT    DAT72-000", NULL,     ATA_HORKAGE_ATAPI_MOD16_DMA },
 
        /* Devices we expect to fail diagnostics */
 
@@ -4444,7 +4445,8 @@ int atapi_check_dma(struct ata_queued_cmd *qc)
        /* 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))
+       if (!(qc->dev->horkage & ATA_HORKAGE_ATAPI_MOD16_DMA) &&
+           unlikely(qc->nbytes & 15))
                return 1;
 
        if (ap->ops->check_atapi_dma)
index f5441edee55f647be39b6432edb30f83bc81bb13..c7665a4134c552af7559ff1d4737eba9e33e30b3 100644 (file)
@@ -373,6 +373,8 @@ enum {
        ATA_HORKAGE_IVB         = (1 << 8),     /* cbl det validity bit bugs */
        ATA_HORKAGE_STUCK_ERR   = (1 << 9),     /* stuck ERR on next PACKET */
        ATA_HORKAGE_BRIDGE_OK   = (1 << 10),    /* no bridge limits */
+       ATA_HORKAGE_ATAPI_MOD16_DMA = (1 << 11), /* use ATAPI DMA for commands
+                                                   not multiple of 16 bytes */
 
         /* DMA mask for user DMA control: User visible values; DO NOT
            renumber */