diff options
Diffstat (limited to 'drivers/nvme/host/pci.c')
| -rw-r--r-- | drivers/nvme/host/pci.c | 48 | 
1 files changed, 27 insertions, 21 deletions
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 4a2121335f48..3f5a04c586ce 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -24,6 +24,7 @@  #include <linux/mm.h>  #include <linux/module.h>  #include <linux/mutex.h> +#include <linux/once.h>  #include <linux/pci.h>  #include <linux/poison.h>  #include <linux/t10-pi.h> @@ -93,7 +94,7 @@ struct nvme_dev {  	struct mutex shutdown_lock;  	bool subsystem;  	void __iomem *cmb; -	dma_addr_t cmb_dma_addr; +	pci_bus_addr_t cmb_bus_addr;  	u64 cmb_size;  	u32 cmbsz;  	u32 cmbloc; @@ -540,6 +541,20 @@ static void nvme_dif_complete(u32 p, u32 v, struct t10_pi_tuple *pi)  }  #endif +static void nvme_print_sgl(struct scatterlist *sgl, int nents) +{ +	int i; +	struct scatterlist *sg; + +	for_each_sg(sgl, sg, nents, i) { +		dma_addr_t phys = sg_phys(sg); +		pr_warn("sg[%d] phys_addr:%pad offset:%d length:%d " +			"dma_address:%pad dma_length:%d\n", +			i, &phys, sg->offset, sg->length, &sg_dma_address(sg), +			sg_dma_len(sg)); +	} +} +  static blk_status_t nvme_setup_prps(struct nvme_dev *dev, struct request *req)  {  	struct nvme_iod *iod = blk_mq_rq_to_pdu(req); @@ -622,19 +637,10 @@ static blk_status_t nvme_setup_prps(struct nvme_dev *dev, struct request *req)  	return BLK_STS_OK;   bad_sgl: -	if (WARN_ONCE(1, "Invalid SGL for payload:%d nents:%d\n", -				blk_rq_payload_bytes(req), iod->nents)) { -		for_each_sg(iod->sg, sg, iod->nents, i) { -			dma_addr_t phys = sg_phys(sg); -			pr_warn("sg[%d] phys_addr:%pad offset:%d length:%d " -			       "dma_address:%pad dma_length:%d\n", i, &phys, -					sg->offset, sg->length, -					&sg_dma_address(sg), -					sg_dma_len(sg)); -		} -	} +	WARN(DO_ONCE(nvme_print_sgl, iod->sg, iod->nents), +			"Invalid SGL for payload:%d nents:%d\n", +			blk_rq_payload_bytes(req), iod->nents);  	return BLK_STS_IOERR; -  }  static blk_status_t nvme_map_data(struct nvme_dev *dev, struct request *req, @@ -1220,7 +1226,7 @@ static int nvme_alloc_sq_cmds(struct nvme_dev *dev, struct nvme_queue *nvmeq,  	if (qid && dev->cmb && use_cmb_sqes && NVME_CMB_SQS(dev->cmbsz)) {  		unsigned offset = (qid - 1) * roundup(SQ_SIZE(depth),  						      dev->ctrl.page_size); -		nvmeq->sq_dma_addr = dev->cmb_dma_addr + offset; +		nvmeq->sq_dma_addr = dev->cmb_bus_addr + offset;  		nvmeq->sq_cmds_io = dev->cmb + offset;  	} else {  		nvmeq->sq_cmds = dma_alloc_coherent(dev->dev, SQ_SIZE(depth), @@ -1313,11 +1319,11 @@ static int nvme_create_queue(struct nvme_queue *nvmeq, int qid)  	if (result < 0)  		goto release_cq; +	nvme_init_queue(nvmeq, qid);  	result = queue_request_irq(nvmeq);  	if (result < 0)  		goto release_sq; -	nvme_init_queue(nvmeq, qid);  	return result;   release_sq: @@ -1464,6 +1470,7 @@ static int nvme_pci_configure_admin_queue(struct nvme_dev *dev)  		return result;  	nvmeq->cq_vector = 0; +	nvme_init_queue(nvmeq, 0);  	result = queue_request_irq(nvmeq);  	if (result) {  		nvmeq->cq_vector = -1; @@ -1520,7 +1527,7 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev)  	resource_size_t bar_size;  	struct pci_dev *pdev = to_pci_dev(dev->dev);  	void __iomem *cmb; -	dma_addr_t dma_addr; +	int bar;  	dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ);  	if (!(NVME_CMB_SZ(dev->cmbsz))) @@ -1533,7 +1540,8 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev)  	szu = (u64)1 << (12 + 4 * NVME_CMB_SZU(dev->cmbsz));  	size = szu * NVME_CMB_SZ(dev->cmbsz);  	offset = szu * NVME_CMB_OFST(dev->cmbloc); -	bar_size = pci_resource_len(pdev, NVME_CMB_BIR(dev->cmbloc)); +	bar = NVME_CMB_BIR(dev->cmbloc); +	bar_size = pci_resource_len(pdev, bar);  	if (offset > bar_size)  		return NULL; @@ -1546,12 +1554,11 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev)  	if (size > bar_size - offset)  		size = bar_size - offset; -	dma_addr = pci_resource_start(pdev, NVME_CMB_BIR(dev->cmbloc)) + offset; -	cmb = ioremap_wc(dma_addr, size); +	cmb = ioremap_wc(pci_resource_start(pdev, bar) + offset, size);  	if (!cmb)  		return NULL; -	dev->cmb_dma_addr = dma_addr; +	dev->cmb_bus_addr = pci_bus_address(pdev, bar) + offset;  	dev->cmb_size = size;  	return cmb;  } @@ -2156,7 +2163,6 @@ static void nvme_reset_work(struct work_struct *work)  	if (result)  		goto out; -	nvme_init_queue(dev->queues[0], 0);  	result = nvme_alloc_admin_tags(dev);  	if (result)  		goto out;  |