| From a2941f6aa71a72be2c82c0a168523a492d093530 Mon Sep 17 00:00:00 2001 |
| From: Keith Busch <kbusch@kernel.org> |
| Date: Mon, 27 Sep 2021 08:43:06 -0700 |
| Subject: nvme: add command id quirk for apple controllers |
| |
| From: Keith Busch <kbusch@kernel.org> |
| |
| commit a2941f6aa71a72be2c82c0a168523a492d093530 upstream. |
| |
| 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@svenpeter.dev> |
| Reported-by: Orlando Chamberlain <redecorating@protonmail.com> |
| Reported-by: Aditya Garg <gargaditya08@live.com> |
| Signed-off-by: Keith Busch <kbusch@kernel.org> |
| Reviewed-by: Christoph Hellwig <hch@lst.de> |
| Tested-by: Sven Peter <sven@svenpeter.dev> |
| Link: https://lore.kernel.org/r/20210927154306.387437-1-kbusch@kernel.org |
| Signed-off-by: Jens Axboe <axboe@kernel.dk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| 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(-) |
| |
| --- a/drivers/nvme/host/core.c |
| +++ b/drivers/nvme/host/core.c |
| @@ -831,6 +831,7 @@ EXPORT_SYMBOL_GPL(nvme_cleanup_cmd); |
| blk_status_t nvme_setup_cmd(struct nvme_ns *ns, struct request *req, |
| struct nvme_command *cmd) |
| { |
| + struct nvme_ctrl *ctrl = nvme_req(req)->ctrl; |
| blk_status_t ret = BLK_STS_OK; |
| |
| nvme_clear_nvme_request(req); |
| @@ -877,7 +878,8 @@ blk_status_t nvme_setup_cmd(struct nvme_ |
| 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; |
| --- a/drivers/nvme/host/nvme.h |
| +++ b/drivers/nvme/host/nvme.h |
| @@ -144,6 +144,12 @@ enum nvme_quirks { |
| * NVMe 1.3 compliance. |
| */ |
| NVME_QUIRK_NO_NS_DESC_LIST = (1 << 15), |
| + |
| + /* |
| + * The controller requires the command_id value be be limited, so skip |
| + * encoding the generation sequence number. |
| + */ |
| + NVME_QUIRK_SKIP_CID_GEN = (1 << 17), |
| }; |
| |
| /* |
| --- a/drivers/nvme/host/pci.c |
| +++ b/drivers/nvme/host/pci.c |
| @@ -3259,7 +3259,8 @@ static const struct pci_device_id nvme_i |
| { 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, } |