diff options
author | Gabriele Mazzotta <gabriele.mzt@gmail.com> | 2015-04-25 19:52:37 +0200 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2015-08-07 00:32:06 +0100 |
commit | 6d2cf32d106b396d29fd43a80fb6764535f7a1a3 (patch) | |
tree | b64fa09fd3b8ac1c58e50e9faf80936084de57f2 /drivers/ata | |
parent | bc14e871a99dfdd14fbd685c75e7e4466449c65c (diff) |
libata: Ignore spurious PHY event on LPM policy change
commit 09c5b4803a80a5451d950d6a539d2eb311dc0fb1 upstream.
When the LPM policy is set to ATA_LPM_MAX_POWER, the device might
generate a spurious PHY event that cuases errors on the link.
Ignore this event if it occured within 10s after the policy change.
The timeout was chosen observing that on a Dell XPS13 9333 these
spurious events can occur up to roughly 6s after the policy change.
Link: http://lkml.kernel.org/g/3352987.ugV1Ipy7Z5@xps13
Signed-off-by: Gabriele Mazzotta <gabriele.mzt@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
[bwh: Backported to 3.2: adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 15 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 3 |
2 files changed, 17 insertions, 1 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2c02208cd91c..fcd8586a3045 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -6629,8 +6629,21 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, */ bool sata_lpm_ignore_phy_events(struct ata_link *link) { + unsigned long lpm_timeout = link->last_lpm_change + + msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY); + /* if LPM is enabled, PHYRDY doesn't mean anything */ - return !!(link->lpm_policy > ATA_LPM_MAX_POWER); + if (link->lpm_policy > ATA_LPM_MAX_POWER) + return true; + + /* ignore the first PHY event after the LPM policy changed + * as it is might be spurious + */ + if ((link->flags & ATA_LFLAG_CHANGED) && + time_before(jiffies, lpm_timeout)) + return true; + + return false; } EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 7d1a478c7500..f54b07754c62 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -3423,6 +3423,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, } } + link->last_lpm_change = jiffies; + link->flags |= ATA_LFLAG_CHANGED; + return 0; fail: |