aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@kernel.org>2017-04-20 16:37:55 -0400
committerJens Axboe <axboe@fb.com>2017-04-20 16:42:09 -0400
commitff5350a86b20de23991e474e006e2ff2732b218e (patch)
tree825aa0a8058499cd7eea77ee9413cc8dd4a09261 /drivers
parent4981d04dd8f1ab19e2cce008da556d7f099b6e68 (diff)
nvme: Adjust the Samsung APST quirk
I got a couple more reports: the Samsung APST issues appears to affect multiple 950-series devices in Dell XPS 15 9550 and Precision 5510 laptops. Change the quirk: rather than blacklisting the firmware on the first problematic SSD that was reported, disable APST on all 144d:a802 devices if they're installed in the two affected Dell models. While we're at it, disable only the deepest sleep state instead of all of them -- the reporters say that this is sufficient to fix the problem. (I have a device that appears to be entirely identical to one of the affected devices, but I have a different Dell laptop, so it's not the case that all Samsung devices with firmware BXW75D0Q are broken under all circumstances.) Samsung engineers have an affected system, and hopefully they'll give us a better workaround some time soon. In the mean time, this should minimize regressions. See https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1678184 Cc: Kai-Heng Feng <kai.heng.feng@canonical.com> Signed-off-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/nvme/host/core.c18
-rw-r--r--drivers/nvme/host/nvme.h5
-rw-r--r--drivers/nvme/host/pci.c26
3 files changed, 38 insertions, 11 deletions
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 9583a5f58a1d..00b2818dac31 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1316,6 +1316,14 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
1316 table->entries[state] = target; 1316 table->entries[state] = target;
1317 1317
1318 /* 1318 /*
1319 * Don't allow transitions to the deepest state
1320 * if it's quirked off.
1321 */
1322 if (state == ctrl->npss &&
1323 (ctrl->quirks & NVME_QUIRK_NO_DEEPEST_PS))
1324 continue;
1325
1326 /*
1319 * Is this state a useful non-operational state for 1327 * Is this state a useful non-operational state for
1320 * higher-power states to autonomously transition to? 1328 * higher-power states to autonomously transition to?
1321 */ 1329 */
@@ -1387,16 +1395,6 @@ struct nvme_core_quirk_entry {
1387}; 1395};
1388 1396
1389static const struct nvme_core_quirk_entry core_quirks[] = { 1397static const struct nvme_core_quirk_entry core_quirks[] = {
1390 /*
1391 * Seen on a Samsung "SM951 NVMe SAMSUNG 256GB": using APST causes
1392 * the controller to go out to lunch. It dies when the watchdog
1393 * timer reads CSTS and gets 0xffffffff.
1394 */
1395 {
1396 .vid = 0x144d,
1397 .fr = "BXW75D0Q",
1398 .quirks = NVME_QUIRK_NO_APST,
1399 },
1400}; 1398};
1401 1399
1402/* match is null-terminated but idstr is space-padded. */ 1400/* match is null-terminated but idstr is space-padded. */
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 2aa20e3e5675..ab2d6ec7eb5c 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -83,6 +83,11 @@ enum nvme_quirks {
83 * APST should not be used. 83 * APST should not be used.
84 */ 84 */
85 NVME_QUIRK_NO_APST = (1 << 4), 85 NVME_QUIRK_NO_APST = (1 << 4),
86
87 /*
88 * The deepest sleep state should not be used.
89 */
90 NVME_QUIRK_NO_DEEPEST_PS = (1 << 5),
86}; 91};
87 92
88/* 93/*
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 26a5fd05fe88..5d309535abbd 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -19,6 +19,7 @@
19#include <linux/blk-mq-pci.h> 19#include <linux/blk-mq-pci.h>
20#include <linux/cpu.h> 20#include <linux/cpu.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/dmi.h>
22#include <linux/errno.h> 23#include <linux/errno.h>
23#include <linux/fs.h> 24#include <linux/fs.h>
24#include <linux/genhd.h> 25#include <linux/genhd.h>
@@ -1943,10 +1944,31 @@ static int nvme_dev_map(struct nvme_dev *dev)
1943 return -ENODEV; 1944 return -ENODEV;
1944} 1945}
1945 1946
1947static unsigned long check_dell_samsung_bug(struct pci_dev *pdev)
1948{
1949 if (pdev->vendor == 0x144d && pdev->device == 0xa802) {
1950 /*
1951 * Several Samsung devices seem to drop off the PCIe bus
1952 * randomly when APST is on and uses the deepest sleep state.
1953 * This has been observed on a Samsung "SM951 NVMe SAMSUNG
1954 * 256GB", a "PM951 NVMe SAMSUNG 512GB", and a "Samsung SSD
1955 * 950 PRO 256GB", but it seems to be restricted to two Dell
1956 * laptops.
1957 */
1958 if (dmi_match(DMI_SYS_VENDOR, "Dell Inc.") &&
1959 (dmi_match(DMI_PRODUCT_NAME, "XPS 15 9550") ||
1960 dmi_match(DMI_PRODUCT_NAME, "Precision 5510")))
1961 return NVME_QUIRK_NO_DEEPEST_PS;
1962 }
1963
1964 return 0;
1965}
1966
1946static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) 1967static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1947{ 1968{
1948 int node, result = -ENOMEM; 1969 int node, result = -ENOMEM;
1949 struct nvme_dev *dev; 1970 struct nvme_dev *dev;
1971 unsigned long quirks = id->driver_data;
1950 1972
1951 node = dev_to_node(&pdev->dev); 1973 node = dev_to_node(&pdev->dev);
1952 if (node == NUMA_NO_NODE) 1974 if (node == NUMA_NO_NODE)
@@ -1978,8 +2000,10 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1978 if (result) 2000 if (result)
1979 goto put_pci; 2001 goto put_pci;
1980 2002
2003 quirks |= check_dell_samsung_bug(pdev);
2004
1981 result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops, 2005 result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops,
1982 id->driver_data); 2006 quirks);
1983 if (result) 2007 if (result)
1984 goto release_pools; 2008 goto release_pools;
1985 2009