[PATCH 1/1] If device hotplug out, controller status become 0xFFFF_FFFF 1. Controller fatal status become true in nvme_kthread() 2. Ready bit will not be reset to 0 in nvme_wait_ready() for controller disable above two scenarios controller status data is not a valid data, since device/controller is already removed (hotplug)
Mundu
mundu2510 at gmail.com
Tue Jul 22 10:25:39 PDT 2014
Signed-off-by: Mundu <mundu2510 at gmail.com>
---
drivers/block/nvme-core.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index 28aec2d..6c6998e 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -1396,10 +1396,14 @@ static int nvme_wait_ready(struct nvme_dev *dev, u64 cap, bool enabled)
{
unsigned long timeout;
u32 bit = enabled ? NVME_CSTS_RDY : 0;
+ u32 csts;
timeout = ((NVME_CAP_TIMEOUT(cap) + 1) * HZ / 2) + jiffies;
- while ((readl(&dev->bar->csts) & NVME_CSTS_RDY) != bit) {
+ while (((csts = readl(&dev->bar->csts)) & NVME_CSTS_RDY) != bit) {
+ /* If device is hot plugout, csts become 0xFFFFFFFF */
+ if (csts == -1)
+ return -ENODEV;
msleep(100);
if (fatal_signal_pending(current))
return -EINTR;
@@ -1905,14 +1909,19 @@ static int nvme_submit_async_req(struct nvme_queue *nvmeq)
static int nvme_kthread(void *data)
{
struct nvme_dev *dev, *next;
+ u32 csts;
while (!kthread_should_stop()) {
set_current_state(TASK_INTERRUPTIBLE);
spin_lock(&dev_list_lock);
list_for_each_entry_safe(dev, next, &dev_list, node) {
int i;
- if (readl(&dev->bar->csts) & NVME_CSTS_CFS &&
+ if ((csts = readl(&dev->bar->csts)) & NVME_CSTS_CFS &&
dev->initialized) {
+ /* If device is hot plugout,
+ csts become 0xFFFFFFFF */
+ if (csts == -1)
+ continue;
if (work_busy(&dev->reset_work))
continue;
list_del_init(&dev->node);
--
1.9.1
More information about the Linux-nvme
mailing list