]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/ahci.c
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzi...
[linux-2.6-omap-h63xx.git] / drivers / ata / ahci.c
index 66e012cd3271f98cc8541c95ca13fb327b4dd7c7..57be6bea48eb123cdac22c4e1a53d6d54e3aafb5 100644 (file)
@@ -78,6 +78,7 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,
 static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
                                        ssize_t size);
 #define MAX_SLOTS 8
+#define MAX_RETRY 15
 
 enum {
        AHCI_PCI_BAR            = 5,
@@ -404,7 +405,7 @@ static const struct ata_port_info ahci_port_info[] = {
        /* board_ahci */
        {
                .flags          = AHCI_FLAG_COMMON,
-               .pio_mask       = 0x1f, /* pio0-4 */
+               .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
@@ -412,7 +413,7 @@ static const struct ata_port_info ahci_port_info[] = {
        {
                AHCI_HFLAGS     (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
                .flags          = AHCI_FLAG_COMMON,
-               .pio_mask       = 0x1f, /* pio0-4 */
+               .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_vt8251_ops,
        },
@@ -420,7 +421,7 @@ static const struct ata_port_info ahci_port_info[] = {
        {
                AHCI_HFLAGS     (AHCI_HFLAG_IGN_IRQ_IF_ERR),
                .flags          = AHCI_FLAG_COMMON,
-               .pio_mask       = 0x1f, /* pio0-4 */
+               .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
@@ -430,7 +431,7 @@ static const struct ata_port_info ahci_port_info[] = {
                                 AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
                                 AHCI_HFLAG_SECT255),
                .flags          = AHCI_FLAG_COMMON,
-               .pio_mask       = 0x1f, /* pio0-4 */
+               .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_sb600_ops,
        },
@@ -440,7 +441,7 @@ static const struct ata_port_info ahci_port_info[] = {
                                 AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                  ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
-               .pio_mask       = 0x1f, /* pio0-4 */
+               .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
@@ -448,7 +449,7 @@ static const struct ata_port_info ahci_port_info[] = {
        {
                AHCI_HFLAGS     (AHCI_HFLAG_IGN_SERR_INTERNAL),
                .flags          = AHCI_FLAG_COMMON,
-               .pio_mask       = 0x1f, /* pio0-4 */
+               .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_sb600_ops,
        },
@@ -456,7 +457,7 @@ static const struct ata_port_info ahci_port_info[] = {
        {
                AHCI_HFLAGS     (AHCI_HFLAG_YES_NCQ),
                .flags          = AHCI_FLAG_COMMON,
-               .pio_mask       = 0x1f, /* pio0-4 */
+               .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
@@ -464,7 +465,7 @@ static const struct ata_port_info ahci_port_info[] = {
        {
                AHCI_HFLAGS     (AHCI_HFLAG_NO_PMP),
                .flags          = AHCI_FLAG_COMMON,
-               .pio_mask       = 0x1f, /* pio0-4 */
+               .pio_mask       = ATA_PIO4,
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &ahci_ops,
        },
@@ -1115,6 +1116,8 @@ static void ahci_start_port(struct ata_port *ap)
        struct ahci_port_priv *pp = ap->private_data;
        struct ata_link *link;
        struct ahci_em_priv *emp;
+       ssize_t rc;
+       int i;
 
        /* enable FIS reception */
        ahci_start_fis_rx(ap);
@@ -1126,7 +1129,17 @@ static void ahci_start_port(struct ata_port *ap)
        if (ap->flags & ATA_FLAG_EM) {
                ata_for_each_link(link, ap, EDGE) {
                        emp = &pp->em_priv[link->pmp];
-                       ahci_transmit_led_message(ap, emp->led_state, 4);
+
+                       /* EM Transmit bit maybe busy during init */
+                       for (i = 0; i < MAX_RETRY; i++) {
+                               rc = ahci_transmit_led_message(ap,
+                                                              emp->led_state,
+                                                              4);
+                               if (rc == -EBUSY)
+                                       udelay(100);
+                               else
+                                       break;
+                       }
                }
        }
 
@@ -1331,7 +1344,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
        em_ctl = readl(mmio + HOST_EM_CTL);
        if (em_ctl & EM_CTL_TM) {
                spin_unlock_irqrestore(ap->lock, flags);
-               return -EINVAL;
+               return -EBUSY;
        }
 
        /*
@@ -1348,7 +1361,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
        writel(message[1], mmio + hpriv->em_loc+4);
 
        /* save off new led state for port/slot */
-       emp->led_state = message[1];
+       emp->led_state = state;
 
        /*
         * tell hardware to transmit the message
@@ -2405,10 +2418,10 @@ static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
        int rc;
 
        if (using_dac &&
-           !pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
-               rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
+           !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
+               rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
                if (rc) {
-                       rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+                       rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
                        if (rc) {
                                dev_printk(KERN_ERR, &pdev->dev,
                                           "64-bit DMA enable failed\n");
@@ -2416,13 +2429,13 @@ static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
                        }
                }
        } else {
-               rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+               rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
                if (rc) {
                        dev_printk(KERN_ERR, &pdev->dev,
                                   "32-bit DMA enable failed\n");
                        return rc;
                }
-               rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
+               rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
                if (rc) {
                        dev_printk(KERN_ERR, &pdev->dev,
                                   "32-bit consistent DMA enable failed\n");
@@ -2565,6 +2578,15 @@ static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
                        /* PCI slot number of the controller */
                        .driver_data = (void *)0x1FUL,
                },
+               {
+                       .ident = "HP Compaq 6720s",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6720s"),
+                       },
+                       /* PCI slot number of the controller */
+                       .driver_data = (void *)0x1FUL,
+               },
 
                { }     /* terminate list */
        };
@@ -2647,8 +2669,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
                hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
 
-       if ((hpriv->flags & AHCI_HFLAG_NO_MSI) || pci_enable_msi(pdev))
-               pci_intx(pdev, 1);
+       if (!(hpriv->flags & AHCI_HFLAG_NO_MSI))
+               pci_enable_msi(pdev);
 
        /* save initial config */
        ahci_save_initial_config(pdev, hpriv);