]> err.no Git - linux-2.6/blobdiff - drivers/ata/ahci.c
Merge branch 'for-2.6.26' of master.kernel.org:/pub/scm/linux/kernel/git/jwboyer...
[linux-2.6] / drivers / ata / ahci.c
index 739ba3f222e851407cd97dcc2ed52ac509e32edc..8cace9aa9c0398bafe101115ba511bb5dd29f0fb 100644 (file)
@@ -273,8 +273,8 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
 static int ahci_pci_device_resume(struct pci_dev *pdev);
 #endif
 
-static struct class_device_attribute *ahci_shost_attrs[] = {
-       &class_device_attr_link_power_management_policy,
+static struct device_attribute *ahci_shost_attrs[] = {
+       &dev_attr_link_power_management_policy,
        NULL
 };
 
@@ -358,7 +358,7 @@ static const struct ata_port_info ahci_port_info[] = {
        /* board_ahci_sb600 */
        {
                AHCI_HFLAGS     (AHCI_HFLAG_IGN_SERR_INTERNAL |
-                                AHCI_HFLAG_32BIT_ONLY |
+                                AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI |
                                 AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP),
                .flags          = AHCI_FLAG_COMMON,
                .pio_mask       = 0x1f, /* pio0-4 */
@@ -556,16 +556,27 @@ static inline void __iomem *ahci_port_base(struct ata_port *ap)
 
 static void ahci_enable_ahci(void __iomem *mmio)
 {
+       int i;
        u32 tmp;
 
        /* turn on AHCI_EN */
        tmp = readl(mmio + HOST_CTL);
-       if (!(tmp & HOST_AHCI_EN)) {
+       if (tmp & HOST_AHCI_EN)
+               return;
+
+       /* Some controllers need AHCI_EN to be written multiple times.
+        * Try a few times before giving up.
+        */
+       for (i = 0; i < 5; i++) {
                tmp |= HOST_AHCI_EN;
                writel(tmp, mmio + HOST_CTL);
                tmp = readl(mmio + HOST_CTL);   /* flush && sanity check */
-               WARN_ON(!(tmp & HOST_AHCI_EN));
+               if (tmp & HOST_AHCI_EN)
+                       return;
+               msleep(10);
        }
+
+       WARN_ON(1);
 }
 
 /**