diff options
author | Tejun Heo <htejun@gmail.com> | 2007-02-02 02:22:30 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-02-21 04:58:16 -0500 |
commit | 4ae72a1e469a3bcfd3c1f77dac62392c489bf9ca (patch) | |
tree | 8408499b85ddbe70077671117aa30da274f03363 /drivers/ata/libata-core.c | |
parent | 458337dbb120d33f326e2b19d54eca8cf179b5c0 (diff) |
libata: improve probe failure handling
* Move forcing device to PIO0 on device disable into
ata_dev_disable(). This makes both old and new EHs act the same
way.
* Speed down only PIO mode on probe failure. All commands used during
probing are PIO commands. There's no point in speeding down DMA.
* Retry at least once after -ENODEV. Some devices report garbled
IDENTIFY data after certain events. This shouldn't cause device
detach and re-attach.
* Rearrange EH failure path for simplicity.
Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 249d487c091e..24c6505f062d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -600,6 +600,8 @@ void ata_dev_disable(struct ata_device *dev) | |||
600 | { | 600 | { |
601 | if (ata_dev_enabled(dev) && ata_msg_drv(dev->ap)) { | 601 | if (ata_dev_enabled(dev) && ata_msg_drv(dev->ap)) { |
602 | ata_dev_printk(dev, KERN_WARNING, "disabled\n"); | 602 | ata_dev_printk(dev, KERN_WARNING, "disabled\n"); |
603 | ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0 | | ||
604 | ATA_DNXFER_QUIET); | ||
603 | dev->class++; | 605 | dev->class++; |
604 | } | 606 | } |
605 | } | 607 | } |
@@ -1778,9 +1780,8 @@ int ata_bus_probe(struct ata_port *ap) | |||
1778 | { | 1780 | { |
1779 | unsigned int classes[ATA_MAX_DEVICES]; | 1781 | unsigned int classes[ATA_MAX_DEVICES]; |
1780 | int tries[ATA_MAX_DEVICES]; | 1782 | int tries[ATA_MAX_DEVICES]; |
1781 | int i, rc, down_xfermask; | 1783 | int i, rc; |
1782 | struct ata_device *dev; | 1784 | struct ata_device *dev; |
1783 | int dnxfer_sel; | ||
1784 | 1785 | ||
1785 | ata_port_probe(ap); | 1786 | ata_port_probe(ap); |
1786 | 1787 | ||
@@ -1788,8 +1789,6 @@ int ata_bus_probe(struct ata_port *ap) | |||
1788 | tries[i] = ATA_PROBE_MAX_TRIES; | 1789 | tries[i] = ATA_PROBE_MAX_TRIES; |
1789 | 1790 | ||
1790 | retry: | 1791 | retry: |
1791 | down_xfermask = 0; | ||
1792 | |||
1793 | /* reset and determine device classes */ | 1792 | /* reset and determine device classes */ |
1794 | ap->ops->phy_reset(ap); | 1793 | ap->ops->phy_reset(ap); |
1795 | 1794 | ||
@@ -1837,10 +1836,8 @@ int ata_bus_probe(struct ata_port *ap) | |||
1837 | 1836 | ||
1838 | /* configure transfer mode */ | 1837 | /* configure transfer mode */ |
1839 | rc = ata_set_mode(ap, &dev); | 1838 | rc = ata_set_mode(ap, &dev); |
1840 | if (rc) { | 1839 | if (rc) |
1841 | down_xfermask = 1; | ||
1842 | goto fail; | 1840 | goto fail; |
1843 | } | ||
1844 | 1841 | ||
1845 | for (i = 0; i < ATA_MAX_DEVICES; i++) | 1842 | for (i = 0; i < ATA_MAX_DEVICES; i++) |
1846 | if (ata_dev_enabled(&ap->device[i])) | 1843 | if (ata_dev_enabled(&ap->device[i])) |
@@ -1852,27 +1849,29 @@ int ata_bus_probe(struct ata_port *ap) | |||
1852 | return -ENODEV; | 1849 | return -ENODEV; |
1853 | 1850 | ||
1854 | fail: | 1851 | fail: |
1852 | tries[dev->devno]--; | ||
1853 | |||
1855 | switch (rc) { | 1854 | switch (rc) { |
1856 | case -EINVAL: | 1855 | case -EINVAL: |
1857 | case -ENODEV: | 1856 | /* eeek, something went very wrong, give up */ |
1858 | tries[dev->devno] = 0; | 1857 | tries[dev->devno] = 0; |
1859 | break; | 1858 | break; |
1859 | |||
1860 | case -ENODEV: | ||
1861 | /* give it just one more chance */ | ||
1862 | tries[dev->devno] = min(tries[dev->devno], 1); | ||
1860 | case -EIO: | 1863 | case -EIO: |
1861 | sata_down_spd_limit(ap); | 1864 | if (tries[dev->devno] == 1) { |
1862 | /* fall through */ | 1865 | /* This is the last chance, better to slow |
1863 | default: | 1866 | * down than lose it. |
1864 | tries[dev->devno]--; | 1867 | */ |
1865 | dnxfer_sel = ATA_DNXFER_ANY; | 1868 | sata_down_spd_limit(ap); |
1866 | if (tries[dev->devno] == 1) | 1869 | ata_down_xfermask_limit(dev, ATA_DNXFER_PIO); |
1867 | dnxfer_sel = ATA_DNXFER_FORCE_PIO0; | 1870 | } |
1868 | if (down_xfermask && ata_down_xfermask_limit(dev, dnxfer_sel)) | ||
1869 | tries[dev->devno] = 0; | ||
1870 | } | 1871 | } |
1871 | 1872 | ||
1872 | if (!tries[dev->devno]) { | 1873 | if (!tries[dev->devno]) |
1873 | ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO0); | ||
1874 | ata_dev_disable(dev); | 1874 | ata_dev_disable(dev); |
1875 | } | ||
1876 | 1875 | ||
1877 | goto retry; | 1876 | goto retry; |
1878 | } | 1877 | } |