Commit dfcc173d71b029eb2b10cf99bb5b4e8749e09799

Authored by Tejun Heo
Committed by Jeff Garzik
1 parent 08cf69d005

libata: consider errors not associated with commands for speed down

libata EH used to ignore errors not associated with commands when
determining whether speed down is necessary or not.  This leads to the
following problems.

* Errors not associated with commands can occur indefinitely without
  libata EH taking corrective actions.

* Upstream link errors don't trigger speed down when PMP is attached
  to it and commands issued to downstream device trigger errors on the
  upstream link.

This patch makes ata_eh_link_autopsy() consider errors not associated
with command for speed down.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

Showing 1 changed file with 13 additions and 6 deletions Side-by-side Diff

drivers/ata/libata-eh.c
... ... @@ -1747,6 +1747,7 @@
1747 1747 {
1748 1748 struct ata_port *ap = link->ap;
1749 1749 struct ata_eh_context *ehc = &link->eh_context;
  1750 + struct ata_device *dev;
1750 1751 unsigned int all_err_mask = 0;
1751 1752 int tag, is_io = 0;
1752 1753 u32 serror;
1753 1754  
1754 1755  
... ... @@ -1818,17 +1819,23 @@
1818 1819 (!is_io && (all_err_mask & ~AC_ERR_DEV)))
1819 1820 ehc->i.action |= ATA_EH_REVALIDATE;
1820 1821  
1821   - /* if we have offending qcs and the associated failed device */
  1822 + /* If we have offending qcs and the associated failed device,
  1823 + * perform per-dev EH action only on the offending device.
  1824 + */
1822 1825 if (ehc->i.dev) {
1823   - /* speed down */
1824   - ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io,
1825   - all_err_mask);
1826   -
1827   - /* perform per-dev EH action only on the offending device */
1828 1826 ehc->i.dev_action[ehc->i.dev->devno] |=
1829 1827 ehc->i.action & ATA_EH_PERDEV_MASK;
1830 1828 ehc->i.action &= ~ATA_EH_PERDEV_MASK;
1831 1829 }
  1830 +
  1831 + /* consider speeding down */
  1832 + dev = ehc->i.dev;
  1833 + if (!dev && ata_link_max_devices(link) == 1 &&
  1834 + ata_dev_enabled(link->device))
  1835 + dev = link->device;
  1836 +
  1837 + if (dev)
  1838 + ehc->i.action |= ata_eh_speed_down(dev, is_io, all_err_mask);
1832 1839  
1833 1840 DPRINTK("EXIT\n");
1834 1841 }