Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Apr 2019 16:23:57 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r346239 - stable/11/sys/dev/nvme
Message-ID:  <201904151623.x3FGNvOI038127@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Mon Apr 15 16:23:57 2019
New Revision: 346239
URL: https://svnweb.freebsd.org/changeset/base/346239

Log:
  MFC r339775: Put a workaround in for command timeout malfunctioning
  
  At least one NVMe drive has a bug that makeing the Command Time Out
  PCIe feature unreliable. The workaround is to disable this
  feature. The driver wouldn't deal correctly with a timeout anyway.
  Only do this for drives that are known bad.

Modified:
  stable/11/sys/dev/nvme/nvme.c
  stable/11/sys/dev/nvme/nvme_private.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/dev/nvme/nvme.c
==============================================================================
--- stable/11/sys/dev/nvme/nvme.c	Mon Apr 15 15:35:42 2019	(r346238)
+++ stable/11/sys/dev/nvme/nvme.c	Mon Apr 15 16:23:57 2019	(r346239)
@@ -104,6 +104,7 @@ static struct _pcsid
 	{ 0x05401c5f,		0, 0, "Memblaze Pblaze4", QUIRK_DELAY_B4_CHK_RDY },
 	{ 0xa821144d,		0, 0, "Samsung PM1725", QUIRK_DELAY_B4_CHK_RDY },
 	{ 0xa822144d,		0, 0, "Samsung PM1725a", QUIRK_DELAY_B4_CHK_RDY },
+	{ 0x01161179,		0, 0, "Toshiba XG5", QUIRK_DISABLE_TIMEOUT },
 	{ 0x00000000,		0, 0, NULL  }
 };
 
@@ -263,6 +264,25 @@ nvme_attach(device_t dev)
 	if (status != 0) {
 		nvme_ctrlr_destruct(ctrlr, dev);
 		return (status);
+	}
+
+	/*
+	 * Some drives do not implement the completion timeout feature
+	 * correctly. There's a WAR from the manufacturer to just disable it.
+	 * The driver wouldn't respond correctly to a timeout anyway.
+	 */
+	if (ep->quirks & QUIRK_DISABLE_TIMEOUT) {
+		int ptr;
+		uint16_t devctl2;
+
+		status = pci_find_cap(dev, PCIY_EXPRESS, &ptr);
+		if (status) {
+			device_printf(dev, "Can't locate PCIe capability?");
+			return (status);
+		}
+		devctl2 = pci_read_config(dev, ptr + PCIER_DEVICE_CTL2, sizeof(devctl2));
+		devctl2 |= PCIEM_CTL2_COMP_TIMO_DISABLE;
+		pci_write_config(dev, ptr + PCIER_DEVICE_CTL2, devctl2, sizeof(devctl2));
 	}
 
 	/*

Modified: stable/11/sys/dev/nvme/nvme_private.h
==============================================================================
--- stable/11/sys/dev/nvme/nvme_private.h	Mon Apr 15 15:35:42 2019	(r346238)
+++ stable/11/sys/dev/nvme/nvme_private.h	Mon Apr 15 16:23:57 2019	(r346239)
@@ -245,7 +245,8 @@ struct nvme_controller {
 
 	uint32_t		ready_timeout_in_ms;
 	uint32_t		quirks;
-#define QUIRK_DELAY_B4_CHK_RDY 1		/* Can't touch MMIO on disable */
+#define	QUIRK_DELAY_B4_CHK_RDY	1		/* Can't touch MMIO on disable */
+#define	QUIRK_DISABLE_TIMEOUT	2		/* Disable broken completion timeout feature */
 
 	bus_space_tag_t		bus_tag;
 	bus_space_handle_t	bus_handle;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201904151623.x3FGNvOI038127>