diff options
author | Sui Chen <suichen6@gmail.com> | 2017-05-09 08:47:22 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2017-05-16 11:23:28 -0400 |
commit | 8bfd174312629866efa535193d9e563768ff4307 (patch) | |
tree | a5408d346ffd532800bd2877bf81425fc14da243 | |
parent | a95cfad947d5f40cfbf9ad3019575aac1d8ac7a6 (diff) |
ahci: Acer SA5-271 SSD Not Detected Fix
(Correction in this resend: fixed function name acer_sa5_271_workaround; fixed
the always-true condition in the function; fixed description.)
On the Acer Switch Alpha 12 (model number: SA5-271), the internal SSD may not
get detected because the port_map and CAP.nr_ports combination causes the driver
to skip the port that is actually connected to the SSD. More specifically,
either all SATA ports are identified as DUMMY, or all ports get ``link down''
and never get up again.
This problem occurs occasionally. When this problem occurs, CAP may hold a
value of 0xC734FF00 or 0xC734FF01 and port_map may hold a value of 0x00 or 0x01.
When this problem does not occur, CAP holds a value of 0xC734FF02 and port_map
may hold a value of 0x07. Overriding the CAP value to 0xC734FF02 and port_map to
0x7 significantly reduces the occurrence of this problem.
Link: https://bugzilla.kernel.org/attachment.cgi?id=253091
Signed-off-by: Sui Chen <suichen6@gmail.com>
Tested-by: Damian Ivanov <damianatorrpm@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r-- | drivers/ata/ahci.c | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 2fc52407306c..c69954023c2e 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1364,6 +1364,40 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) | |||
1364 | {} | 1364 | {} |
1365 | #endif | 1365 | #endif |
1366 | 1366 | ||
1367 | /* | ||
1368 | * On the Acer Aspire Switch Alpha 12, sometimes all SATA ports are detected | ||
1369 | * as DUMMY, or detected but eventually get a "link down" and never get up | ||
1370 | * again. When this happens, CAP.NP may hold a value of 0x00 or 0x01, and the | ||
1371 | * port_map may hold a value of 0x00. | ||
1372 | * | ||
1373 | * Overriding CAP.NP to 0x02 and the port_map to 0x7 will reveal all 3 ports | ||
1374 | * and can significantly reduce the occurrence of the problem. | ||
1375 | * | ||
1376 | * https://bugzilla.kernel.org/show_bug.cgi?id=189471 | ||
1377 | */ | ||
1378 | static void acer_sa5_271_workaround(struct ahci_host_priv *hpriv, | ||
1379 | struct pci_dev *pdev) | ||
1380 | { | ||
1381 | static const struct dmi_system_id sysids[] = { | ||
1382 | { | ||
1383 | .ident = "Acer Switch Alpha 12", | ||
1384 | .matches = { | ||
1385 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
1386 | DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271") | ||
1387 | }, | ||
1388 | }, | ||
1389 | { } | ||
1390 | }; | ||
1391 | |||
1392 | if (dmi_check_system(sysids)) { | ||
1393 | dev_info(&pdev->dev, "enabling Acer Switch Alpha 12 workaround\n"); | ||
1394 | if ((hpriv->saved_cap & 0xC734FF00) == 0xC734FF00) { | ||
1395 | hpriv->port_map = 0x7; | ||
1396 | hpriv->cap = 0xC734FF02; | ||
1397 | } | ||
1398 | } | ||
1399 | } | ||
1400 | |||
1367 | #ifdef CONFIG_ARM64 | 1401 | #ifdef CONFIG_ARM64 |
1368 | /* | 1402 | /* |
1369 | * Due to ERRATA#22536, ThunderX needs to handle HOST_IRQ_STAT differently. | 1403 | * Due to ERRATA#22536, ThunderX needs to handle HOST_IRQ_STAT differently. |
@@ -1636,6 +1670,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1636 | "online status unreliable, applying workaround\n"); | 1670 | "online status unreliable, applying workaround\n"); |
1637 | } | 1671 | } |
1638 | 1672 | ||
1673 | |||
1674 | /* Acer SA5-271 workaround modifies private_data */ | ||
1675 | acer_sa5_271_workaround(hpriv, pdev); | ||
1676 | |||
1639 | /* CAP.NP sometimes indicate the index of the last enabled | 1677 | /* CAP.NP sometimes indicate the index of the last enabled |
1640 | * port, at other times, that of the last possible port, so | 1678 | * port, at other times, that of the last possible port, so |
1641 | * determining the maximum port number requires looking at | 1679 | * determining the maximum port number requires looking at |