[PATCHv2] nvme: add command id quirk for apple controllers

Aditya Garg gargaditya08 at live.com
Mon Sep 27 22:38:10 PDT 2021


This patch fixes the issue on my MacBook Pro 16,1. I have tested this on 5.14.7 thus it has fixed the problem on stable.

Tested-by: Aditya Garg <gargaditya08 at live.com>
________________________________________
From: Keith Busch <kbusch at kernel.org>
Sent: Monday, September 27, 2021 3:43 PM
To: linux-nvme at lists.infradead.org; sagi at grimberg.me; hch at lst.de
Cc: linux-kernel at vger.kernel.org; axboe at kernel.dk; Keith Busch; Sven Peter; Orlando Chamberlain; Aditya Garg
Subject: [PATCHv2] nvme: add command id quirk for apple controllers

Some apple controllers use the command id as an index to implementation
specific data structures and will fail if the value is out of bounds.
The nvme driver's recently introduced command sequence number breaks
this controller.

Provide a quirk so these spec incompliant controllers can function as
before. The driver will not have the ability to detect bad completions
when this quirk is used, but we weren't previously checking this anyway.

The quirk bit was selected so that it can readily apply to stable.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=214509
Cc: Sven Peter <sven at svenpeter.dev>
Reported-by: Orlando Chamberlain <redecorating at protonmail.com>
Reported-by: Aditya Garg <gargaditya08 at live.com>
Signed-off-by: Keith Busch <kbusch at kernel.org>
---
v1->v2: fixed logical bug checking the quirk setting

 drivers/nvme/host/core.c | 4 +++-
 drivers/nvme/host/nvme.h | 6 ++++++
 drivers/nvme/host/pci.c  | 3 ++-
 3 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index e486845d2c7e..7712a8f78337 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -978,6 +978,7 @@ EXPORT_SYMBOL_GPL(nvme_cleanup_cmd);
 blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
 {
        struct nvme_command *cmd = nvme_req(req)->cmd;
+       struct nvme_ctrl *ctrl = nvme_req(req)->ctrl;
        blk_status_t ret = BLK_STS_OK;

        if (!(req->rq_flags & RQF_DONTPREP)) {
@@ -1026,7 +1027,8 @@ blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req)
                return BLK_STS_IOERR;
        }

-       nvme_req(req)->genctr++;
+       if (!(ctrl->quirks & NVME_QUIRK_SKIP_CID_GEN))
+               nvme_req(req)->genctr++;
        cmd->common.command_id = nvme_cid(req);
        trace_nvme_setup_cmd(req, cmd);
        return ret;
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 9871c0c9374c..ed79a6c7e804 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -138,6 +138,12 @@ enum nvme_quirks {
         * 48 bits.
         */
        NVME_QUIRK_DMA_ADDRESS_BITS_48          = (1 << 16),
+
+       /*
+        * The controller requires the command_id value be be limited, so skip
+        * encoding the generation sequence number.
+        */
+       NVME_QUIRK_SKIP_CID_GEN                 = (1 << 17),
 };

 /*
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index b82492cd7503..456a0e8a5718 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -3369,7 +3369,8 @@ static const struct pci_device_id nvme_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2005),
                .driver_data = NVME_QUIRK_SINGLE_VECTOR |
                                NVME_QUIRK_128_BYTES_SQES |
-                               NVME_QUIRK_SHARED_TAGS },
+                               NVME_QUIRK_SHARED_TAGS |
+                               NVME_QUIRK_SKIP_CID_GEN },

        { PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
        { 0, }
--
2.25.4




More information about the Linux-nvme mailing list