aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/nvme/host/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/nvme/host/pci.c')
-rw-r--r--drivers/nvme/host/pci.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 97b6640a3745..3dfc28875cc3 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -90,7 +90,7 @@ static struct class *nvme_class;
90 90
91static int __nvme_reset(struct nvme_dev *dev); 91static int __nvme_reset(struct nvme_dev *dev);
92static int nvme_reset(struct nvme_dev *dev); 92static int nvme_reset(struct nvme_dev *dev);
93static int nvme_process_cq(struct nvme_queue *nvmeq); 93static void nvme_process_cq(struct nvme_queue *nvmeq);
94static void nvme_dead_ctrl(struct nvme_dev *dev); 94static void nvme_dead_ctrl(struct nvme_dev *dev);
95 95
96struct async_cmd_info { 96struct async_cmd_info {
@@ -935,7 +935,7 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
935 return BLK_MQ_RQ_QUEUE_BUSY; 935 return BLK_MQ_RQ_QUEUE_BUSY;
936} 936}
937 937
938static int nvme_process_cq(struct nvme_queue *nvmeq) 938static void __nvme_process_cq(struct nvme_queue *nvmeq, unsigned int *tag)
939{ 939{
940 u16 head, phase; 940 u16 head, phase;
941 941
@@ -953,6 +953,8 @@ static int nvme_process_cq(struct nvme_queue *nvmeq)
953 head = 0; 953 head = 0;
954 phase = !phase; 954 phase = !phase;
955 } 955 }
956 if (tag && *tag == cqe.command_id)
957 *tag = -1;
956 ctx = nvme_finish_cmd(nvmeq, cqe.command_id, &fn); 958 ctx = nvme_finish_cmd(nvmeq, cqe.command_id, &fn);
957 fn(nvmeq, ctx, &cqe); 959 fn(nvmeq, ctx, &cqe);
958 } 960 }
@@ -964,14 +966,18 @@ static int nvme_process_cq(struct nvme_queue *nvmeq)
964 * a big problem. 966 * a big problem.
965 */ 967 */
966 if (head == nvmeq->cq_head && phase == nvmeq->cq_phase) 968 if (head == nvmeq->cq_head && phase == nvmeq->cq_phase)
967 return 0; 969 return;
968 970
969 writel(head, nvmeq->q_db + nvmeq->dev->db_stride); 971 writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
970 nvmeq->cq_head = head; 972 nvmeq->cq_head = head;
971 nvmeq->cq_phase = phase; 973 nvmeq->cq_phase = phase;
972 974
973 nvmeq->cqe_seen = 1; 975 nvmeq->cqe_seen = 1;
974 return 1; 976}
977
978static void nvme_process_cq(struct nvme_queue *nvmeq)
979{
980 __nvme_process_cq(nvmeq, NULL);
975} 981}
976 982
977static irqreturn_t nvme_irq(int irq, void *data) 983static irqreturn_t nvme_irq(int irq, void *data)
@@ -995,6 +1001,23 @@ static irqreturn_t nvme_irq_check(int irq, void *data)
995 return IRQ_WAKE_THREAD; 1001 return IRQ_WAKE_THREAD;
996} 1002}
997 1003
1004static int nvme_poll(struct blk_mq_hw_ctx *hctx, unsigned int tag)
1005{
1006 struct nvme_queue *nvmeq = hctx->driver_data;
1007
1008 if ((le16_to_cpu(nvmeq->cqes[nvmeq->cq_head].status) & 1) ==
1009 nvmeq->cq_phase) {
1010 spin_lock_irq(&nvmeq->q_lock);
1011 __nvme_process_cq(nvmeq, &tag);
1012 spin_unlock_irq(&nvmeq->q_lock);
1013
1014 if (tag == -1)
1015 return 1;
1016 }
1017
1018 return 0;
1019}
1020
998/* 1021/*
999 * Returns 0 on success. If the result is negative, it's a Linux error code; 1022 * Returns 0 on success. If the result is negative, it's a Linux error code;
1000 * if the result is positive, it's an NVM Express status code 1023 * if the result is positive, it's an NVM Express status code
@@ -1656,6 +1679,7 @@ static struct blk_mq_ops nvme_mq_ops = {
1656 .init_hctx = nvme_init_hctx, 1679 .init_hctx = nvme_init_hctx,
1657 .init_request = nvme_init_request, 1680 .init_request = nvme_init_request,
1658 .timeout = nvme_timeout, 1681 .timeout = nvme_timeout,
1682 .poll = nvme_poll,
1659}; 1683};
1660 1684
1661static void nvme_dev_remove_admin(struct nvme_dev *dev) 1685static void nvme_dev_remove_admin(struct nvme_dev *dev)