nvme/quirk: Add a delay before checking for adapter readiness
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>
This commit is contained in:
parent
41d512e51b
commit
54adc01055
3 changed files with 24 additions and 0 deletions
|
@ -1109,6 +1109,15 @@ int nvme_disable_ctrl(struct nvme_ctrl *ctrl, u64 cap)
|
|||
ret = ctrl->ops->reg_write32(ctrl, NVME_REG_CC, ctrl->ctrl_config);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Checking for ctrl->tagset is a trick to avoid sleeping on module
|
||||
* load, since we only need the quirk on reset_controller. Notice
|
||||
* that the HGST device needs this delay only in firmware activation
|
||||
* procedure; unfortunately we have no (easy) way to verify this.
|
||||
*/
|
||||
if ((ctrl->quirks & NVME_QUIRK_DELAY_BEFORE_CHK_RDY) && ctrl->tagset)
|
||||
msleep(NVME_QUIRK_DELAY_AMOUNT);
|
||||
|
||||
return nvme_wait_ready(ctrl, cap, false);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(nvme_disable_ctrl);
|
||||
|
|
|
@ -68,8 +68,21 @@ enum nvme_quirks {
|
|||
* logical blocks.
|
||||
*/
|
||||
NVME_QUIRK_DISCARD_ZEROES = (1 << 2),
|
||||
|
||||
/*
|
||||
* The controller needs a delay before starts checking the device
|
||||
* readiness, which is done by reading the NVME_CSTS_RDY bit.
|
||||
*/
|
||||
NVME_QUIRK_DELAY_BEFORE_CHK_RDY = (1 << 3),
|
||||
};
|
||||
|
||||
/* The below value is the specific amount of delay needed before checking
|
||||
* readiness in case of the PCI_DEVICE(0x1c58, 0x0003), which needs the
|
||||
* NVME_QUIRK_DELAY_BEFORE_CHK_RDY quirk enabled. The value (in ms) was
|
||||
* found empirically.
|
||||
*/
|
||||
#define NVME_QUIRK_DELAY_AMOUNT 2000
|
||||
|
||||
enum nvme_ctrl_state {
|
||||
NVME_CTRL_NEW,
|
||||
NVME_CTRL_LIVE,
|
||||
|
|
|
@ -2094,6 +2094,8 @@ static const struct pci_device_id nvme_id_table[] = {
|
|||
NVME_QUIRK_DISCARD_ZEROES, },
|
||||
{ PCI_VDEVICE(INTEL, 0x5845), /* Qemu emulated controller */
|
||||
.driver_data = NVME_QUIRK_IDENTIFY_CNS, },
|
||||
{ PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */
|
||||
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY, },
|
||||
{ PCI_DEVICE_CLASS(PCI_CLASS_STORAGE_EXPRESS, 0xffffff) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, 0x2001) },
|
||||
{ 0, }
|
||||
|
|
Loading…
Reference in a new issue