aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Günther <guenther@tum.de>2015-11-07 20:07:02 -0500
committerJens Axboe <axboe@fb.com>2015-11-11 11:36:56 -0500
commita310acd7a7ea53533886c11bb7edd11ffd61a036 (patch)
tree233c4cfac009f9fc03dd1817d4fa056619deaa01
parent1fa8cc52f46c14fb1afc20c220855c40a5d28fcd (diff)
NVMe: use split lo_hi_{read,write}q
Some controllers may require ordered split transfers even on 64bit machines, e.g. Apple's NVMe controller as found in the MacBook8,1 and MacBookAir7,1 (256/512GB models). This patch enforces ordered split transfers on 64bit platforms, which works around that issue for all controllers. As pointed out by Christoph [1] there should be no performance impact due to that modification. [1] http://lists.infradead.org/pipermail/linux-nvme/2015-November/002965.html Signed-off-by: Stephan Guenther <guenther@tum.de> Signed-off-by: Maurice Leclaire <leclaire@in.tum.de> Reviewed-by: Christoph Hellwig <hch@lst.de> Updated by me to explicitly use lo_hi_read/writeq instead of playing define tricks. Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/nvme/host/pci.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index cb89789df40c..3435d79a99ee 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -1725,7 +1725,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
1725{ 1725{
1726 int result; 1726 int result;
1727 u32 aqa; 1727 u32 aqa;
1728 u64 cap = readq(&dev->bar->cap); 1728 u64 cap = lo_hi_readq(&dev->bar->cap);
1729 struct nvme_queue *nvmeq; 1729 struct nvme_queue *nvmeq;
1730 unsigned page_shift = PAGE_SHIFT; 1730 unsigned page_shift = PAGE_SHIFT;
1731 unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12; 1731 unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12;
@@ -1774,8 +1774,8 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
1774 dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES; 1774 dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES;
1775 1775
1776 writel(aqa, &dev->bar->aqa); 1776 writel(aqa, &dev->bar->aqa);
1777 writeq(nvmeq->sq_dma_addr, &dev->bar->asq); 1777 lo_hi_writeq(nvmeq->sq_dma_addr, &dev->bar->asq);
1778 writeq(nvmeq->cq_dma_addr, &dev->bar->acq); 1778 lo_hi_writeq(nvmeq->cq_dma_addr, &dev->bar->acq);
1779 1779
1780 result = nvme_enable_ctrl(dev, cap); 1780 result = nvme_enable_ctrl(dev, cap);
1781 if (result) 1781 if (result)
@@ -2606,7 +2606,7 @@ static int nvme_dev_add(struct nvme_dev *dev)
2606 struct pci_dev *pdev = to_pci_dev(dev->dev); 2606 struct pci_dev *pdev = to_pci_dev(dev->dev);
2607 int res; 2607 int res;
2608 struct nvme_id_ctrl *ctrl; 2608 struct nvme_id_ctrl *ctrl;
2609 int shift = NVME_CAP_MPSMIN(readq(&dev->bar->cap)) + 12; 2609 int shift = NVME_CAP_MPSMIN(lo_hi_readq(&dev->bar->cap)) + 12;
2610 2610
2611 res = nvme_identify_ctrl(dev, &ctrl); 2611 res = nvme_identify_ctrl(dev, &ctrl);
2612 if (res) { 2612 if (res) {
@@ -2697,7 +2697,7 @@ static int nvme_dev_map(struct nvme_dev *dev)
2697 goto unmap; 2697 goto unmap;
2698 } 2698 }
2699 2699
2700 cap = readq(&dev->bar->cap); 2700 cap = lo_hi_readq(&dev->bar->cap);
2701 dev->q_depth = min_t(int, NVME_CAP_MQES(cap) + 1, NVME_Q_DEPTH); 2701 dev->q_depth = min_t(int, NVME_CAP_MQES(cap) + 1, NVME_Q_DEPTH);
2702 dev->db_stride = 1 << NVME_CAP_STRIDE(cap); 2702 dev->db_stride = 1 << NVME_CAP_STRIDE(cap);
2703 dev->dbs = ((void __iomem *)dev->bar) + 4096; 2703 dev->dbs = ((void __iomem *)dev->bar) + 4096;
@@ -2760,7 +2760,7 @@ static void nvme_wait_dq(struct nvme_delq_ctx *dq, struct nvme_dev *dev)
2760 * queues than admin tags. 2760 * queues than admin tags.
2761 */ 2761 */
2762 set_current_state(TASK_RUNNING); 2762 set_current_state(TASK_RUNNING);
2763 nvme_disable_ctrl(dev, readq(&dev->bar->cap)); 2763 nvme_disable_ctrl(dev, lo_hi_readq(&dev->bar->cap));
2764 nvme_clear_queue(dev->queues[0]); 2764 nvme_clear_queue(dev->queues[0]);
2765 flush_kthread_worker(dq->worker); 2765 flush_kthread_worker(dq->worker);
2766 nvme_disable_queue(dev, 0); 2766 nvme_disable_queue(dev, 0);