libata: disable pdev on all suspend events
[powerpc.git] / drivers / ata / libata-core.c
index 249d487..b71a7ef 100644 (file)
@@ -600,6 +600,8 @@ void ata_dev_disable(struct ata_device *dev)
 {
        if (ata_dev_enabled(dev) && ata_msg_drv(dev->ap)) {
                ata_dev_printk(dev, KERN_WARNING, "disabled\n");
+               ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 |
+                                            ATA_DNXFER_QUIET);
                dev->class++;
        }
 }
@@ -1778,9 +1780,8 @@ int ata_bus_probe(struct ata_port *ap)
 {
        unsigned int classes[ATA_MAX_DEVICES];
        int tries[ATA_MAX_DEVICES];
-       int i, rc, down_xfermask;
+       int i, rc;
        struct ata_device *dev;
-       int dnxfer_sel;
 
        ata_port_probe(ap);
 
@@ -1788,8 +1789,6 @@ int ata_bus_probe(struct ata_port *ap)
                tries[i] = ATA_PROBE_MAX_TRIES;
 
  retry:
-       down_xfermask = 0;
-
        /* reset and determine device classes */
        ap->ops->phy_reset(ap);
 
@@ -1837,10 +1836,8 @@ int ata_bus_probe(struct ata_port *ap)
 
        /* configure transfer mode */
        rc = ata_set_mode(ap, &dev);
-       if (rc) {
-               down_xfermask = 1;
+       if (rc)
                goto fail;
-       }
 
        for (i = 0; i < ATA_MAX_DEVICES; i++)
                if (ata_dev_enabled(&ap->device[i]))
@@ -1852,27 +1849,29 @@ int ata_bus_probe(struct ata_port *ap)
        return -ENODEV;
 
  fail:
+       tries[dev->devno]--;
+
        switch (rc) {
        case -EINVAL:
-       case -ENODEV:
+               /* eeek, something went very wrong, give up */
                tries[dev->devno] = 0;
                break;
+
+       case -ENODEV:
+               /* give it just one more chance */
+               tries[dev->devno] = min(tries[dev->devno], 1);
        case -EIO:
-               sata_down_spd_limit(ap);
-               /* fall through */
-       default:
-               tries[dev->devno]--;
-               dnxfer_sel = ATA_DNXFER_ANY;
-               if (tries[dev->devno] == 1)
-                       dnxfer_sel = ATA_DNXFER_FORCE_PIO0;
-               if (down_xfermask && ata_down_xfermask_limit(dev, dnxfer_sel))
-                       tries[dev->devno] = 0;
+               if (tries[dev->devno] == 1) {
+                       /* This is the last chance, better to slow
+                        * down than lose it.
+                        */
+                       sata_down_spd_limit(ap);
+                       ata_down_xfermask_limit(dev, ATA_DNXFER_PIO);
+               }
        }
 
-       if (!tries[dev->devno]) {
-               ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0);
+       if (!tries[dev->devno])
                ata_dev_disable(dev);
-       }
 
        goto retry;
 }
@@ -2361,15 +2360,6 @@ int ata_down_xfermask_limit(struct ata_device *dev, unsigned int sel)
                udma_mask = 0;
                break;
 
-       case ATA_DNXFER_ANY:
-               /* don't gear down to MWDMA from UDMA, go directly to PIO */
-               if (xfer_mask & ATA_MASK_UDMA)
-                       xfer_mask &= ~ATA_MASK_MWDMA;
-
-               highbit = fls(xfer_mask) - 1;
-               xfer_mask &= ~(1 << highbit);
-               break;
-
        default:
                BUG();
        }
@@ -5958,11 +5948,7 @@ ata_probe_ent_alloc(struct device *dev, const struct ata_port_info *port)
 {
        struct ata_probe_ent *probe_ent;
 
-       /* XXX - the following if can go away once all LLDs are managed */
-       if (!list_empty(&dev->devres_head))
-               probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
-       else
-               probe_ent = kzalloc(sizeof(*probe_ent), GFP_KERNEL);
+       probe_ent = devm_kzalloc(dev, sizeof(*probe_ent), GFP_KERNEL);
        if (!probe_ent) {
                printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
                       kobject_name(&(dev->kobj)));
@@ -6068,11 +6054,10 @@ int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
 void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg)
 {
        pci_save_state(pdev);
+       pci_disable_device(pdev);
 
-       if (mesg.event == PM_EVENT_SUSPEND) {
-               pci_disable_device(pdev);
+       if (mesg.event == PM_EVENT_SUSPEND)
                pci_set_power_state(pdev, PCI_D3hot);
-       }
 }
 
 int ata_pci_device_do_resume(struct pci_dev *pdev)