libata: add CONFIG_PM to libata core layer
[powerpc.git] / drivers / ata / libata-core.c
index e74e972..dc362fa 100644 (file)
@@ -59,7 +59,7 @@
 
 #include "libata.h"
 
-#define DRV_VERSION    "2.10"  /* must be exactly four chars */
+#define DRV_VERSION    "2.20"  /* must be exactly four chars */
 
 
 /* debounce timing parameters in msecs { interval, duration, timeout } */
@@ -1850,8 +1850,11 @@ int ata_bus_probe(struct ata_port *ap)
        for (i = 0; i < ATA_MAX_DEVICES; i++)
                ap->device[i].pio_mode = XFER_PIO_0;
 
-       /* read IDENTIFY page and configure devices */
-       for (i = 0; i < ATA_MAX_DEVICES; i++) {
+       /* read IDENTIFY page and configure devices. We have to do the identify
+          specific sequence bass-ackwards so that PDIAG- is released by
+          the slave device */
+
+       for (i = ATA_MAX_DEVICES - 1; i >=  0; i--) {
                dev = &ap->device[i];
 
                if (tries[i])
@@ -1864,6 +1867,15 @@ int ata_bus_probe(struct ata_port *ap)
                                     dev->id);
                if (rc)
                        goto fail;
+       }
+
+       /* After the identify sequence we can now set up the devices. We do
+          this in the normal order so that the user doesn't get confused */
+
+       for(i = 0; i < ATA_MAX_DEVICES; i++) {
+               dev = &ap->device[i];
+               if (!ata_dev_enabled(dev))
+                       continue;
 
                ap->eh_context.i.flags |= ATA_EHI_PRINTINFO;
                rc = ata_dev_configure(dev);
@@ -2556,12 +2568,11 @@ int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)
         * host channels are not permitted to do so.
         */
        if (used_dma && (ap->host->flags & ATA_HOST_SIMPLEX))
-               ap->host->simplex_claimed = 1;
+               ap->host->simplex_claimed = ap;
 
        /* step5: chip specific finalisation */
        if (ap->ops->post_set_mode)
                ap->ops->post_set_mode(ap);
-
  out:
        if (rc)
                *r_failed_dev = dev;
@@ -3346,6 +3357,8 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        /* Devices where NCQ should be avoided */
        /* NCQ is slow */
         { "WDC WD740ADFD-00",   NULL,          ATA_HORKAGE_NONCQ },
+       /* http://thread.gmane.org/gmane.linux.ide/14907 */
+       { "FUJITSU MHT2060BH",  NULL,           ATA_HORKAGE_NONCQ },
 
        /* Devices with NCQ limits */
 
@@ -3442,7 +3455,7 @@ static void ata_dev_xfermask(struct ata_device *dev)
                               "device is on DMA blacklist, disabling DMA\n");
        }
 
-       if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed) {
+       if ((host->flags & ATA_HOST_SIMPLEX) && host->simplex_claimed != ap) {
                xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
                ata_dev_printk(dev, KERN_WARNING, "simplex DMA is claimed by "
                               "other device, disabling DMA\n");
@@ -5341,6 +5354,7 @@ int ata_flush_cache(struct ata_device *dev)
        return 0;
 }
 
+#ifdef CONFIG_PM
 static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
                               unsigned int action, unsigned int ehi_flags,
                               int wait)
@@ -5456,6 +5470,7 @@ void ata_host_resume(struct ata_host *host)
                            ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
        host->dev->power.power_state = PMSG_ON;
 }
+#endif
 
 /**
  *     ata_port_start - Set port up for dma.
@@ -5680,6 +5695,8 @@ static void ata_host_release(struct device *gendev, void *res)
 
        if (host->ops->host_stop)
                host->ops->host_stop(host);
+
+       dev_set_drvdata(gendev, NULL);
 }
 
 /**
@@ -5902,7 +5919,6 @@ int ata_device_add(const struct ata_probe_ent *ent)
 
  err_out:
        devres_release_group(dev, ata_device_add);
-       dev_set_drvdata(dev, NULL);
        VPRINTK("EXIT, returning %d\n", rc);
        return 0;
 }
@@ -6090,6 +6106,7 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
        return (tmp == bits->val) ? 1 : 0;
 }
 
+#ifdef CONFIG_PM
 void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
        pci_save_state(pdev);
@@ -6141,6 +6158,8 @@ int ata_pci_device_resume(struct pci_dev *pdev)
                ata_host_resume(host);
        return rc;
 }
+#endif /* CONFIG_PM */
+
 #endif /* CONFIG_PCI */
 
 
@@ -6349,8 +6368,10 @@ EXPORT_SYMBOL_GPL(sata_scr_write);
 EXPORT_SYMBOL_GPL(sata_scr_write_flush);
 EXPORT_SYMBOL_GPL(ata_port_online);
 EXPORT_SYMBOL_GPL(ata_port_offline);
+#ifdef CONFIG_PM
 EXPORT_SYMBOL_GPL(ata_host_suspend);
 EXPORT_SYMBOL_GPL(ata_host_resume);
+#endif /* CONFIG_PM */
 EXPORT_SYMBOL_GPL(ata_id_string);
 EXPORT_SYMBOL_GPL(ata_id_c_string);
 EXPORT_SYMBOL_GPL(ata_id_to_dma_mode);
@@ -6366,16 +6387,20 @@ EXPORT_SYMBOL_GPL(pci_test_config_bits);
 EXPORT_SYMBOL_GPL(ata_pci_init_native_mode);
 EXPORT_SYMBOL_GPL(ata_pci_init_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+#ifdef CONFIG_PM
 EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
 EXPORT_SYMBOL_GPL(ata_pci_device_do_resume);
 EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
 EXPORT_SYMBOL_GPL(ata_pci_device_resume);
+#endif /* CONFIG_PM */
 EXPORT_SYMBOL_GPL(ata_pci_default_filter);
 EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
 #endif /* CONFIG_PCI */
 
+#ifdef CONFIG_PM
 EXPORT_SYMBOL_GPL(ata_scsi_device_suspend);
 EXPORT_SYMBOL_GPL(ata_scsi_device_resume);
+#endif /* CONFIG_PM */
 
 EXPORT_SYMBOL_GPL(ata_eng_timeout);
 EXPORT_SYMBOL_GPL(ata_port_schedule_eh);