Commit dfcc173d authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik

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: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 08cf69d0
...@@ -1747,6 +1747,7 @@ static void ata_eh_link_autopsy(struct ata_link *link) ...@@ -1747,6 +1747,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)
{ {
struct ata_port *ap = link->ap; struct ata_port *ap = link->ap;
struct ata_eh_context *ehc = &link->eh_context; struct ata_eh_context *ehc = &link->eh_context;
struct ata_device *dev;
unsigned int all_err_mask = 0; unsigned int all_err_mask = 0;
int tag, is_io = 0; int tag, is_io = 0;
u32 serror; u32 serror;
...@@ -1818,18 +1819,24 @@ static void ata_eh_link_autopsy(struct ata_link *link) ...@@ -1818,18 +1819,24 @@ static void ata_eh_link_autopsy(struct ata_link *link)
(!is_io && (all_err_mask & ~AC_ERR_DEV))) (!is_io && (all_err_mask & ~AC_ERR_DEV)))
ehc->i.action |= ATA_EH_REVALIDATE; ehc->i.action |= ATA_EH_REVALIDATE;
/* if we have offending qcs and the associated failed device */ /* If we have offending qcs and the associated failed device,
* perform per-dev EH action only on the offending device.
*/
if (ehc->i.dev) { if (ehc->i.dev) {
/* speed down */
ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io,
all_err_mask);
/* perform per-dev EH action only on the offending device */
ehc->i.dev_action[ehc->i.dev->devno] |= ehc->i.dev_action[ehc->i.dev->devno] |=
ehc->i.action & ATA_EH_PERDEV_MASK; ehc->i.action & ATA_EH_PERDEV_MASK;
ehc->i.action &= ~ATA_EH_PERDEV_MASK; ehc->i.action &= ~ATA_EH_PERDEV_MASK;
} }
/* consider speeding down */
dev = ehc->i.dev;
if (!dev && ata_link_max_devices(link) == 1 &&
ata_dev_enabled(link->device))
dev = link->device;
if (dev)
ehc->i.action |= ata_eh_speed_down(dev, is_io, all_err_mask);
DPRINTK("EXIT\n"); DPRINTK("EXIT\n");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment