aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/libata.h
diff options
context:
space:
mode:
authorNiklas Cassel <niklas.cassel@wdc.com>2022-09-21 17:57:52 +0200
committerDamien Le Moal <damien.lemoal@opensource.wdc.com>2022-09-24 15:31:00 +0900
commit71d7b6e51ad3370d850303b61b79528fb2872f0a (patch)
treeba8af8d436731e514cfc37c4bae1c3b684007210 /include/linux/libata.h
parentata: libata: drop superfluous ata_eh_analyze_tf() parameter (diff)
downloadlinux-dev-71d7b6e51ad3370d850303b61b79528fb2872f0a.tar.xz
linux-dev-71d7b6e51ad3370d850303b61b79528fb2872f0a.zip
ata: libata-eh: avoid needless hard reset when revalidating link
Performing a revalidation on a AHCI controller supporting LPM, while using a lpm mode of e.g. med_power_with_dip (hipm + dipm) or medium_power (hipm), will currently always lead to a hard reset. The expected behavior is that a hard reset is only performed when revalidate fails, because the properties of the drive has changed. A revalidate performed after e.g. a NCQ error, or such a simple thing as disabling write-caching (hdparm -W 0 /dev/sda), should succeed on the first try (and should therefore not cause the link to be reset). This unwarranted hard reset happens because ata_phys_link_offline() returns true for a link that is in deep sleep. Thus the call to ata_phys_link_offline() in ata_eh_revalidate_and_attach() will cause the revalidation to fail, which causes ata_eh_handle_dev_fail() to be called, which will set ehc->i.action |= ATA_EH_RESET, such that the link is reset before retrying revalidation. When the link is reset, the link is reestablished, so when ata_eh_revalidate_and_attach() is called the second time, directly after the link has been reset, ata_phys_link_offline() will return false, and the revalidation will succeed. Looking at "8.3.1.3 HBA Initiated" in the AHCI 1.3.1 specification, it is clear the when host software writes a new command to memory, by setting a bit in the PxCI/PxSACT HBA port registers, the HBA will automatically bring back the link before sending out the Command FIS. However, simply reading a SCR (like ata_phys_link_offline() does), will not cause the HBA to automatically bring back the link. As long as hipm is enabled, the HBA will put an idle link into deep sleep. Avoid this needless hard reset on revalidation by temporarily disabling hipm, by setting the LPM mode to ATA_LPM_MAX_POWER. After revalidation is complete, ata_eh_recover() will restore the link policy by setting the LPM mode to ap->target_lpm_policy. Signed-off-by: Niklas Cassel <niklas.cassel@wdc.com> Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
Diffstat (limited to 'include/linux/libata.h')
0 files changed, 0 insertions, 0 deletions