From 35f6bedccf4c4280f02d48e4f7d194e64e9a62d8 Mon Sep 17 00:00:00 2001 From: Damien Le Moal Date: Wed, 13 Aug 2025 18:08:53 +0900 Subject: [PATCH] ata: libata-eh: Fix link state check for IDE/PATA ports Commit 4371fe1ba400 ("ata: libata-eh: Avoid unnecessary resets when revalidating devices") replaced the call to ata_phys_link_offline() in ata_eh_revalidate_and_attach() with the new function ata_eh_link_established() which relaxes the checks on a device link state to account for low power mode transitions. However, this change assumed that the device port has a valid scr_read method to obtain the SStatus register for the port. This is not always the case, especially with older IDE/PATA adapters (e.g. PATA/IDE devices emulated with QEMU). For such adapter, ata_eh_link_established() will always return false, causing ata_eh_revalidate_and_attach() to go into its error path and ultimately to the device being disabled. Avoid this by restoring the previous behavior, which is to assume that the link is online if reading the port SStatus register fails. While at it, also fix the spelling of SStatus in the comment describing the function ata_eh_link_established(). Reported-by: Shin'ichiro Kawasaki Fixes: 4371fe1ba400 ("ata: libata-eh: Avoid unnecessary resets when revalidating devices") Signed-off-by: Damien Le Moal Tested-by: Shin'ichiro Kawasaki Reviewed-by: Niklas Cassel --- drivers/ata/libata-eh.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 2946ae6d4b2c..2586e77ebf45 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2075,7 +2075,7 @@ out: * Check if a link is established. This is a relaxed version of * ata_phys_link_online() which accounts for the fact that this is potentially * called after changing the link power management policy, which may not be - * reflected immediately in the SSTAUS register (e.g., we may still be seeing + * reflected immediately in the SStatus register (e.g., we may still be seeing * the PHY in partial, slumber or devsleep Partial power management state. * So check that: * - A device is still present, that is, DET is 1h (Device presence detected @@ -2089,8 +2089,13 @@ static bool ata_eh_link_established(struct ata_link *link) u32 sstatus; u8 det, ipm; + /* + * For old IDE/PATA adapters that do not have a valid scr_read method, + * or if reading the SStatus register fails, assume that the device is + * present. Device probe will determine if that is really the case. + */ if (sata_scr_read(link, SCR_STATUS, &sstatus)) - return false; + return true; det = sstatus & 0x0f; ipm = (sstatus >> 8) & 0x0f; -- 2.25.1