Skip to content

Commit 37e14e4

Browse files
Adam VodopjanDamien Le Moal
authored andcommitted
ata: ahci: Fix PCS quirk application for suspend
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]>
1 parent 1b929c0 commit 37e14e4

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,
@@ -676,6 +677,25 @@ static void ahci_pci_save_initial_config(struct pci_dev *pdev,
676677
ahci_save_initial_config(&pdev->dev, hpriv);
677678
}
678679

680+
static int ahci_pci_reset_controller(struct ata_host *host)
681+
{
682+
struct pci_dev *pdev = to_pci_dev(host->dev);
683+
struct ahci_host_priv *hpriv = host->private_data;
684+
int rc;
685+
686+
rc = ahci_reset_controller(host);
687+
if (rc)
688+
return rc;
689+
690+
/*
691+
* If platform firmware failed to enable ports, try to enable
692+
* them here.
693+
*/
694+
ahci_intel_pcs_quirk(pdev, hpriv);
695+
696+
return 0;
697+
}
698+
679699
static void ahci_pci_init_controller(struct ata_host *host)
680700
{
681701
struct ahci_host_priv *hpriv = host->private_data;
@@ -870,7 +890,7 @@ static int ahci_pci_device_runtime_resume(struct device *dev)
870890
struct ata_host *host = pci_get_drvdata(pdev);
871891
int rc;
872892

873-
rc = ahci_reset_controller(host);
893+
rc = ahci_pci_reset_controller(host);
874894
if (rc)
875895
return rc;
876896
ahci_pci_init_controller(host);
@@ -906,7 +926,7 @@ static int ahci_pci_device_resume(struct device *dev)
906926
ahci_mcp89_apple_enable(pdev);
907927

908928
if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
909-
rc = ahci_reset_controller(host);
929+
rc = ahci_pci_reset_controller(host);
910930
if (rc)
911931
return rc;
912932

@@ -1784,12 +1804,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
17841804
/* save initial config */
17851805
ahci_pci_save_initial_config(pdev, hpriv);
17861806

1787-
/*
1788-
* If platform firmware failed to enable ports, try to enable
1789-
* them here.
1790-
*/
1791-
ahci_intel_pcs_quirk(pdev, hpriv);
1792-
17931807
/* prepare host */
17941808
if (hpriv->cap & HOST_CAP_NCQ) {
17951809
pi.flags |= ATA_FLAG_NCQ;
@@ -1899,7 +1913,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
18991913
if (rc)
19001914
return rc;
19011915

1902-
rc = ahci_reset_controller(host);
1916+
rc = ahci_pci_reset_controller(host);
19031917
if (rc)
19041918
return rc;
19051919

0 commit comments

Comments
 (0)