Skip to content

Commit 576502f

Browse files
Adam Vodopjangregkh
authored andcommitted
ata: ahci: Fix PCS quirk application for suspend
[ Upstream commit 37e14e4 ] Since kernel 5.3.4 my laptop (ICH8M controller) does not see Kingston SV300S37A60G SSD disk connected into a SATA connector on wake from suspend. The problem was introduced in c312ef1 ("libata/ahci: Drop PCS quirk for Denverton and beyond"): the quirk is not applied on wake from suspend as it originally was. It is worth to mention the commit contained another bug: the quirk is not applied at all to controllers which require it. The fix commit 09d6ac8 ("libata/ahci: Fix PCS quirk application") landed in 5.3.8. So testing my patch anywhere between commits c312ef1 and 09d6ac8 is pointless. Not all disks trigger the problem. For example nothing bad happens with Western Digital WD5000LPCX HDD. Test hardware: - Acer 5920G with ICH8M SATA controller - sda: some SATA HDD connnected into the DVD drive IDE port with a SATA-IDE caddy. It is a boot disk - sdb: Kingston SV300S37A60G SSD connected into the only SATA port Sample "dmesg --notime | grep -E '^(sd |ata)'" output on wake: sd 0:0:0:0: [sda] Starting disk sd 2:0:0:0: [sdb] Starting disk ata4: SATA link down (SStatus 4 SControl 300) ata3: SATA link down (SStatus 4 SControl 300) ata1.00: ACPI cmd ef/03:0c:00:00:00:a0 (SET FEATURES) filtered out ata1.00: ACPI cmd ef/03:42:00:00:00:a0 (SET FEATURES) filtered out ata1: FORCE: cable set to 80c ata5: SATA link down (SStatus 0 SControl 300) ata3: SATA link down (SStatus 4 SControl 300) ata3: SATA link down (SStatus 4 SControl 300) ata3.00: disabled sd 2:0:0:0: rejecting I/O to offline device ata3.00: detaching (SCSI 2:0:0:0) sd 2:0:0:0: [sdb] Start/Stop Unit failed: Result: hostbyte=DID_NO_CONNECT driverbyte=DRIVER_OK sd 2:0:0:0: [sdb] Synchronizing SCSI cache sd 2:0:0:0: [sdb] Synchronize Cache(10) failed: Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK sd 2:0:0:0: [sdb] Stopping disk sd 2:0:0:0: [sdb] Start/Stop Unit failed: Result: hostbyte=DID_BAD_TARGET driverbyte=DRIVER_OK Commit c312ef1 dropped ahci_pci_reset_controller() which internally calls ahci_reset_controller() and applies the PCS quirk if needed after that. It was called each time a reset was required instead of just ahci_reset_controller(). This patch puts the function back in place. Fixes: c312ef1 ("libata/ahci: Drop PCS quirk for Denverton and beyond") Signed-off-by: Adam Vodopjan <[email protected]> Signed-off-by: Damien Le Moal <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 7949b0d commit 576502f

File tree

1 file changed

+23
-9
lines changed

1 file changed

+23
-9
lines changed

drivers/ata/ahci.c

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ enum board_ids {
8383
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
8484
static void ahci_remove_one(struct pci_dev *dev);
8585
static void ahci_shutdown_one(struct pci_dev *dev);
86+
static void ahci_intel_pcs_quirk(struct pci_dev *pdev, struct ahci_host_priv *hpriv);
8687
static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
8788
unsigned long deadline);
8889
static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
@@ -668,6 +669,25 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
668669
ahci_save_initial_config(&pdev->dev, hpriv);
669670
}
670671

672+
static int ahci_pci_reset_controller(struct ata_host *host)
673+
{
674+
struct pci_dev *pdev = to_pci_dev(host->dev);
675+
struct ahci_host_priv *hpriv = host->private_data;
676+
int rc;
677+
678+
rc = ahci_reset_controller(host);
679+
if (rc)
680+
return rc;
681+
682+
/*
683+
* If platform firmware failed to enable ports, try to enable
684+
* them here.
685+
*/
686+
ahci_intel_pcs_quirk(pdev, hpriv);
687+
688+
return 0;
689+
}
690+
671691
static void ahci_pci_init_controller(struct ata_host *host)
672692
{
673693
struct ahci_host_priv *hpriv = host->private_data;
@@ -869,7 +889,7 @@ static int ahci_pci_device_runtime_resume(struct device *dev)
869889
struct ata_host *host = pci_get_drvdata(pdev);
870890
int rc;
871891

872-
rc = ahci_reset_controller(host);
892+
rc = ahci_pci_reset_controller(host);
873893
if (rc)
874894
return rc;
875895
ahci_pci_init_controller(host);
@@ -904,7 +924,7 @@ static int ahci_pci_device_resume(struct device *dev)
904924
ahci_mcp89_apple_enable(pdev);
905925

906926
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
907-
rc = ahci_reset_controller(host);
927+
rc = ahci_pci_reset_controller(host);
908928
if (rc)
909929
return rc;
910930

@@ -1789,12 +1809,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
17891809
/* save initial config */
17901810
ahci_pci_save_initial_config(pdev, hpriv);
17911811

1792-
/*
1793-
* If platform firmware failed to enable ports, try to enable
1794-
* them here.
1795-
*/
1796-
ahci_intel_pcs_quirk(pdev, hpriv);
1797-
17981812
/* prepare host */
17991813
if (hpriv->cap & HOST_CAP_NCQ) {
18001814
pi.flags |= ATA_FLAG_NCQ;
@@ -1904,7 +1918,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
19041918
if (rc)
19051919
return rc;
19061920

1907-
rc = ahci_reset_controller(host);
1921+
rc = ahci_pci_reset_controller(host);
19081922
if (rc)
19091923
return rc;
19101924

0 commit comments

Comments
 (0)