ahci: disable 64bit dma on sb600
authorTejun Heo <htejun@gmail.com>
Fri, 18 May 2007 14:23:19 +0000 (16:23 +0200)
committerJeff Garzik <jeff@garzik.org>
Tue, 22 May 2007 00:00:25 +0000 (20:00 -0400)
SB600 claims it can do 64bit DMA but it can't.  Disable it.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/ata/ahci.c

index e00e1b913d28b5501dbe700d1b4511c328353f13..bb940475d87c1fa318669f857dbb0248e86fcdc2 100644 (file)
@@ -170,6 +170,7 @@ enum {
        AHCI_FLAG_IGN_IRQ_IF_ERR        = (1 << 25), /* ignore IRQ_IF_ERR */
        AHCI_FLAG_HONOR_PI              = (1 << 26), /* honor PORTS_IMPL */
        AHCI_FLAG_IGN_SERR_INTERNAL     = (1 << 27), /* ignore SERR_INTERNAL */
+       AHCI_FLAG_32BIT_ONLY            = (1 << 28), /* force 32bit */
 
        AHCI_FLAG_COMMON                = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                          ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
@@ -354,7 +355,8 @@ static const struct ata_port_info ahci_port_info[] = {
        /* board_ahci_sb600 */
        {
                .flags          = AHCI_FLAG_COMMON |
-                                 AHCI_FLAG_IGN_SERR_INTERNAL,
+                                 AHCI_FLAG_IGN_SERR_INTERNAL |
+                                 AHCI_FLAG_32BIT_ONLY,
                .pio_mask       = 0x1f, /* pio0-4 */
                .udma_mask      = 0x7f, /* udma0-6 ; FIXME */
                .port_ops       = &ahci_ops,
@@ -492,6 +494,13 @@ static void ahci_save_initial_config(struct pci_dev *pdev,
        hpriv->saved_cap = cap = readl(mmio + HOST_CAP);
        hpriv->saved_port_map = port_map = readl(mmio + HOST_PORTS_IMPL);
 
+       /* some chips lie about 64bit support */
+       if ((cap & HOST_CAP_64) && (pi->flags & AHCI_FLAG_32BIT_ONLY)) {
+               dev_printk(KERN_INFO, &pdev->dev,
+                          "controller can't do 64bit DMA, forcing 32bit\n");
+               cap &= ~HOST_CAP_64;
+       }
+
        /* fixup zero port_map */
        if (!port_map) {
                port_map = (1 << ahci_nr_ports(hpriv->cap)) - 1;