diff options
| -rw-r--r-- | drivers/ata/libata-core.c | 15 | ||||
| -rw-r--r-- | drivers/ata/libata-eh.c | 3 | ||||
| -rw-r--r-- | include/linux/libata.h | 9 |
3 files changed, 26 insertions, 1 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 12adcf78f94b..85e659945c12 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -6766,8 +6766,21 @@ u32 ata_wait_register(struct ata_port *ap, void __iomem *reg, u32 mask, u32 val, | |||
| 6766 | */ | 6766 | */ |
| 6767 | bool sata_lpm_ignore_phy_events(struct ata_link *link) | 6767 | bool sata_lpm_ignore_phy_events(struct ata_link *link) |
| 6768 | { | 6768 | { |
| 6769 | unsigned long lpm_timeout = link->last_lpm_change + | ||
| 6770 | msecs_to_jiffies(ATA_TMOUT_SPURIOUS_PHY); | ||
| 6771 | |||
| 6769 | /* if LPM is enabled, PHYRDY doesn't mean anything */ | 6772 | /* if LPM is enabled, PHYRDY doesn't mean anything */ |
| 6770 | return !!(link->lpm_policy > ATA_LPM_MAX_POWER); | 6773 | if (link->lpm_policy > ATA_LPM_MAX_POWER) |
| 6774 | return true; | ||
| 6775 | |||
| 6776 | /* ignore the first PHY event after the LPM policy changed | ||
| 6777 | * as it is might be spurious | ||
| 6778 | */ | ||
| 6779 | if ((link->flags & ATA_LFLAG_CHANGED) && | ||
| 6780 | time_before(jiffies, lpm_timeout)) | ||
| 6781 | return true; | ||
| 6782 | |||
| 6783 | return false; | ||
| 6771 | } | 6784 | } |
| 6772 | EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); | 6785 | EXPORT_SYMBOL_GPL(sata_lpm_ignore_phy_events); |
| 6773 | 6786 | ||
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 07f41be38fbe..cf0022ec07f2 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -3597,6 +3597,9 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
| 3597 | } | 3597 | } |
| 3598 | } | 3598 | } |
| 3599 | 3599 | ||
| 3600 | link->last_lpm_change = jiffies; | ||
| 3601 | link->flags |= ATA_LFLAG_CHANGED; | ||
| 3602 | |||
| 3600 | return 0; | 3603 | return 0; |
| 3601 | 3604 | ||
| 3602 | fail: | 3605 | fail: |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 6138d87277af..28aeae46f355 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -205,6 +205,7 @@ enum { | |||
| 205 | ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */ | 205 | ATA_LFLAG_SW_ACTIVITY = (1 << 7), /* keep activity stats */ |
| 206 | ATA_LFLAG_NO_LPM = (1 << 8), /* disable LPM on this link */ | 206 | ATA_LFLAG_NO_LPM = (1 << 8), /* disable LPM on this link */ |
| 207 | ATA_LFLAG_RST_ONCE = (1 << 9), /* limit recovery to one reset */ | 207 | ATA_LFLAG_RST_ONCE = (1 << 9), /* limit recovery to one reset */ |
| 208 | ATA_LFLAG_CHANGED = (1 << 10), /* LPM state changed on this link */ | ||
| 208 | 209 | ||
| 209 | /* struct ata_port flags */ | 210 | /* struct ata_port flags */ |
| 210 | ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ | 211 | ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ |
| @@ -309,6 +310,12 @@ enum { | |||
| 309 | */ | 310 | */ |
| 310 | ATA_TMOUT_PMP_SRST_WAIT = 5000, | 311 | ATA_TMOUT_PMP_SRST_WAIT = 5000, |
| 311 | 312 | ||
| 313 | /* When the LPM policy is set to ATA_LPM_MAX_POWER, there might | ||
| 314 | * be a spurious PHY event, so ignore the first PHY event that | ||
| 315 | * occurs within 10s after the policy change. | ||
| 316 | */ | ||
| 317 | ATA_TMOUT_SPURIOUS_PHY = 10000, | ||
| 318 | |||
| 312 | /* ATA bus states */ | 319 | /* ATA bus states */ |
| 313 | BUS_UNKNOWN = 0, | 320 | BUS_UNKNOWN = 0, |
| 314 | BUS_DMA = 1, | 321 | BUS_DMA = 1, |
| @@ -788,6 +795,8 @@ struct ata_link { | |||
| 788 | struct ata_eh_context eh_context; | 795 | struct ata_eh_context eh_context; |
| 789 | 796 | ||
| 790 | struct ata_device device[ATA_MAX_DEVICES]; | 797 | struct ata_device device[ATA_MAX_DEVICES]; |
| 798 | |||
| 799 | unsigned long last_lpm_change; /* when last LPM change happened */ | ||
| 791 | }; | 800 | }; |
| 792 | #define ATA_LINK_CLEAR_BEGIN offsetof(struct ata_link, active_tag) | 801 | #define ATA_LINK_CLEAR_BEGIN offsetof(struct ata_link, active_tag) |
| 793 | #define ATA_LINK_CLEAR_END offsetof(struct ata_link, device[0]) | 802 | #define ATA_LINK_CLEAR_END offsetof(struct ata_link, device[0]) |
