|
@@ -1367,7 +1367,7 @@ static bool nvme_should_reset(struct nvme_dev *dev, u32 csts)
|
|
|
bool nssro = dev->subsystem && (csts & NVME_CSTS_NSSRO);
|
|
|
|
|
|
/* If there is a reset ongoing, we shouldn't reset again. */
|
|
|
- if (work_busy(&dev->reset_work))
|
|
|
+ if (dev->ctrl.state == NVME_CTRL_RESETTING)
|
|
|
return false;
|
|
|
|
|
|
/* We shouldn't reset unless the controller is on fatal error state
|
|
@@ -1903,7 +1903,7 @@ static void nvme_reset_work(struct work_struct *work)
|
|
|
bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL);
|
|
|
int result = -ENODEV;
|
|
|
|
|
|
- if (WARN_ON(dev->ctrl.state == NVME_CTRL_RESETTING))
|
|
|
+ if (WARN_ON(dev->ctrl.state != NVME_CTRL_RESETTING))
|
|
|
goto out;
|
|
|
|
|
|
/*
|
|
@@ -1913,9 +1913,6 @@ static void nvme_reset_work(struct work_struct *work)
|
|
|
if (dev->ctrl.ctrl_config & NVME_CC_ENABLE)
|
|
|
nvme_dev_disable(dev, false);
|
|
|
|
|
|
- if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING))
|
|
|
- goto out;
|
|
|
-
|
|
|
result = nvme_pci_enable(dev);
|
|
|
if (result)
|
|
|
goto out;
|
|
@@ -2009,8 +2006,8 @@ static int nvme_reset(struct nvme_dev *dev)
|
|
|
{
|
|
|
if (!dev->ctrl.admin_q || blk_queue_dying(dev->ctrl.admin_q))
|
|
|
return -ENODEV;
|
|
|
- if (work_busy(&dev->reset_work))
|
|
|
- return -ENODEV;
|
|
|
+ if (!nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING))
|
|
|
+ return -EBUSY;
|
|
|
if (!queue_work(nvme_workq, &dev->reset_work))
|
|
|
return -EBUSY;
|
|
|
return 0;
|
|
@@ -2136,6 +2133,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|
|
if (result)
|
|
|
goto release_pools;
|
|
|
|
|
|
+ nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_RESETTING);
|
|
|
dev_info(dev->ctrl.device, "pci function %s\n", dev_name(&pdev->dev));
|
|
|
|
|
|
queue_work(nvme_workq, &dev->reset_work);
|
|
@@ -2179,6 +2177,7 @@ static void nvme_remove(struct pci_dev *pdev)
|
|
|
|
|
|
nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DELETING);
|
|
|
|
|
|
+ cancel_work_sync(&dev->reset_work);
|
|
|
pci_set_drvdata(pdev, NULL);
|
|
|
|
|
|
if (!pci_device_is_present(pdev)) {
|