Skip to content

Commit bddc802

Browse files
Guilherme G. Piccoligregkh
authored andcommitted
nvme/quirk: Add a delay before checking for adapter readiness
commit 54adc01055b75ec8769c5a36574c7a0895c0c0b2 upstream. When disabling the controller, the specification says the register NVME_REG_CC should be written and then driver needs to wait the adapter to be ready, which is checked by reading another register bit (NVME_CSTS_RDY). There's a timeout validation in this checking, so in case this timeout is reached the driver gives up and removes the adapter from the system. After a firmware activation procedure, the PCI_DEVICE(0x1c58, 0x0003) (HGST adapter) end up being removed if we issue a reset_controller, because driver keeps verifying the NVME_REG_CSTS until the timeout is reached. This patch adds a necessary quirk for this adapter, by introducing a delay before nvme_wait_ready(), so the reset procedure is able to be completed. This quirk is needed because just increasing the timeout is not enough in case of this adapter - the driver must wait before start reading NVME_REG_CSTS register on this specific device. Signed-off-by: Guilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Jens Axboe <axboe@fb.com> [mauricfo: backport to v4.4.70 without nvme quirk handling & nvme_ctrl] Signed-off-by: Mauricio Faria de Oliveira <mauricfo@linux.vnet.ibm.com> Tested-by: Narasimhan Vaidyanathan <vnarasimhan@in.ibm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent e5f87c7 commit bddc802

2 files changed

Lines changed: 17 additions & 0 deletions

File tree

drivers/nvme/host/nvme.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ enum {
2727
NVME_NS_LIGHTNVM = 1,
2828
};
2929

30+
/* The below value is the specific amount of delay needed before checking
31+
* readiness in case of the PCI_DEVICE(0x1c58, 0x0003), which needs the
32+
* NVME_QUIRK_DELAY_BEFORE_CHK_RDY quirk enabled. The value (in ms) was
33+
* found empirically.
34+
*/
35+
#define NVME_QUIRK_DELAY_AMOUNT 2000
36+
3037
/*
3138
* Represents an NVM Express device. Each nvme_dev is a PCI function.
3239
*/

drivers/nvme/host/pci.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1633,10 +1633,20 @@ static int nvme_wait_ready(struct nvme_dev *dev, u64 cap, bool enabled)
16331633
*/
16341634
static int nvme_disable_ctrl(struct nvme_dev *dev, u64 cap)
16351635
{
1636+
struct pci_dev *pdev = to_pci_dev(dev->dev);
1637+
16361638
dev->ctrl_config &= ~NVME_CC_SHN_MASK;
16371639
dev->ctrl_config &= ~NVME_CC_ENABLE;
16381640
writel(dev->ctrl_config, &dev->bar->cc);
16391641

1642+
/* Checking for dev->tagset is a trick to avoid sleeping on module
1643+
* load, since we only need the quirk on reset_controller. Notice
1644+
* that the HGST device needs this delay only in firmware activation
1645+
* procedure; unfortunately we have no (easy) way to verify this.
1646+
*/
1647+
if (pdev->vendor == 0x1c58 && pdev->device == 0x0003 && dev->tagset)
1648+
msleep(NVME_QUIRK_DELAY_AMOUNT);
1649+
16401650
return nvme_wait_ready(dev, cap, false);
16411651
}
16421652

0 commit comments

Comments
 (0)