]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/nvme/host/pci.c
nvme/pci: No special case for queue busy on IO
[karo-tx-linux.git] / drivers / nvme / host / pci.c
index 3faefabf339c98d221373437e411512543d29263..d38dae9b5de97aa407b48cbfa188454c8966c367 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/types.h>
 #include <linux/io-64-nonatomic-lo-hi.h>
 #include <asm/unaligned.h>
+#include <linux/sed-opal.h>
 
 #include "nvme.h"
 
@@ -588,7 +589,7 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
         */
        if (ns && ns->ms && !blk_integrity_rq(req)) {
                if (!(ns->pi_type && ns->ms == 8) &&
-                                       req->cmd_type != REQ_TYPE_DRV_PRIV) {
+                   !blk_rq_is_passthrough(req)) {
                        blk_mq_end_request(req, -EFAULT);
                        return BLK_MQ_RQ_QUEUE_OK;
                }
@@ -612,10 +613,7 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
 
        spin_lock_irq(&nvmeq->q_lock);
        if (unlikely(nvmeq->cq_vector < 0)) {
-               if (ns && !test_bit(NVME_NS_DEAD, &ns->flags))
-                       ret = BLK_MQ_RQ_QUEUE_BUSY;
-               else
-                       ret = BLK_MQ_RQ_QUEUE_ERROR;
+               ret = BLK_MQ_RQ_QUEUE_ERROR;
                spin_unlock_irq(&nvmeq->q_lock);
                goto out_cleanup_iod;
        }
@@ -645,7 +643,7 @@ static void nvme_complete_rq(struct request *req)
                        return;
                }
 
-               if (req->cmd_type == REQ_TYPE_DRV_PRIV)
+               if (blk_rq_is_passthrough(req))
                        error = req->errors;
                else
                        error = nvme_error_status(req->errors);
@@ -895,12 +893,11 @@ static enum blk_eh_timer_return nvme_timeout(struct request *req, bool reserved)
                return BLK_EH_HANDLED;
        }
 
-       iod->aborted = 1;
-
        if (atomic_dec_return(&dev->ctrl.abort_limit) < 0) {
                atomic_inc(&dev->ctrl.abort_limit);
                return BLK_EH_RESET_TIMER;
        }
+       iod->aborted = 1;
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.abort.opcode = nvme_admin_abort_cmd;
@@ -1178,6 +1175,7 @@ static int nvme_alloc_admin_tags(struct nvme_dev *dev)
                dev->admin_tagset.timeout = ADMIN_TIMEOUT;
                dev->admin_tagset.numa_node = dev_to_node(dev->dev);
                dev->admin_tagset.cmd_size = nvme_cmd_size(dev);
+               dev->admin_tagset.flags = BLK_MQ_F_NO_SCHED;
                dev->admin_tagset.driver_data = dev;
 
                if (blk_mq_alloc_tag_set(&dev->admin_tagset))
@@ -1738,6 +1736,7 @@ static void nvme_pci_free_ctrl(struct nvme_ctrl *ctrl)
        if (dev->ctrl.admin_q)
                blk_put_queue(dev->ctrl.admin_q);
        kfree(dev->queues);
+       kfree(dev->ctrl.opal_dev);
        kfree(dev);
 }
 
@@ -1754,6 +1753,7 @@ static void nvme_remove_dead_ctrl(struct nvme_dev *dev, int status)
 static void nvme_reset_work(struct work_struct *work)
 {
        struct nvme_dev *dev = container_of(work, struct nvme_dev, reset_work);
+       bool was_suspend = !!(dev->ctrl.ctrl_config & NVME_CC_SHN_NORMAL);
        int result = -ENODEV;
 
        if (WARN_ON(dev->ctrl.state == NVME_CTRL_RESETTING))
@@ -1786,6 +1786,14 @@ static void nvme_reset_work(struct work_struct *work)
        if (result)
                goto out;
 
+       if ((dev->ctrl.oacs & NVME_CTRL_OACS_SEC_SUPP) && !dev->ctrl.opal_dev) {
+               dev->ctrl.opal_dev =
+                       init_opal_dev(&dev->ctrl, &nvme_sec_submit);
+       }
+
+       if (was_suspend)
+               opal_unlock_from_suspend(dev->ctrl.opal_dev);
+
        result = nvme_setup_io_queues(dev);
        if (result)
                goto out;
@@ -1990,8 +1998,10 @@ static void nvme_remove(struct pci_dev *pdev)
 
        pci_set_drvdata(pdev, NULL);
 
-       if (!pci_device_is_present(pdev))
+       if (!pci_device_is_present(pdev)) {
                nvme_change_ctrl_state(&dev->ctrl, NVME_CTRL_DEAD);
+               nvme_dev_disable(dev, false);
+       }
 
        flush_work(&dev->reset_work);
        nvme_uninit_ctrl(&dev->ctrl);