aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Bates <sbates@raithlin.com>2016-10-05 22:01:12 -0400
committerJens Axboe <axboe@fb.com>2016-10-12 13:10:28 -0400
commit202021c1a63c6ed69b3260e0fe10530c51f1e53e (patch)
tree48023a64bfabdc013b46797c5f1564b766f41c90
parentc5f6ce97c12104668784ee17fb927c52a944d3d8 (diff)
nvme : Add sysfs entry for NVMe CMBs when appropriate
Add a sysfs attribute that contains salient information about the NVMe Controller Memory Buffer when one is present. For now, just display the information about the CMB available from the control registers. We attach the CMB attribute file to the existing nvme_ctrl sysfs group so it can handle the sysfs teardown. Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Reviewed-by: Jay Freyensee <james_p_freyensee@linux.intel.com> Signed-off-by: Stephen Bates <sbates@raithlin.com> Acked-by Jon Derrick: <jonathan.derrick@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/nvme/host/pci.c44
1 files changed, 35 insertions, 9 deletions
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index 12357d616eeb..a7c6e9d74943 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -99,6 +99,7 @@ struct nvme_dev {
99 dma_addr_t cmb_dma_addr; 99 dma_addr_t cmb_dma_addr;
100 u64 cmb_size; 100 u64 cmb_size;
101 u32 cmbsz; 101 u32 cmbsz;
102 u32 cmbloc;
102 struct nvme_ctrl ctrl; 103 struct nvme_ctrl ctrl;
103 struct completion ioq_wait; 104 struct completion ioq_wait;
104}; 105};
@@ -1330,28 +1331,37 @@ static int nvme_create_io_queues(struct nvme_dev *dev)
1330 return ret >= 0 ? 0 : ret; 1331 return ret >= 0 ? 0 : ret;
1331} 1332}
1332 1333
1334static ssize_t nvme_cmb_show(struct device *dev,
1335 struct device_attribute *attr,
1336 char *buf)
1337{
1338 struct nvme_dev *ndev = to_nvme_dev(dev_get_drvdata(dev));
1339
1340 return snprintf(buf, PAGE_SIZE, "cmbloc : x%08x\ncmbsz : x%08x\n",
1341 ndev->cmbloc, ndev->cmbsz);
1342}
1343static DEVICE_ATTR(cmb, S_IRUGO, nvme_cmb_show, NULL);
1344
1333static void __iomem *nvme_map_cmb(struct nvme_dev *dev) 1345static void __iomem *nvme_map_cmb(struct nvme_dev *dev)
1334{ 1346{
1335 u64 szu, size, offset; 1347 u64 szu, size, offset;
1336 u32 cmbloc;
1337 resource_size_t bar_size; 1348 resource_size_t bar_size;
1338 struct pci_dev *pdev = to_pci_dev(dev->dev); 1349 struct pci_dev *pdev = to_pci_dev(dev->dev);
1339 void __iomem *cmb; 1350 void __iomem *cmb;
1340 dma_addr_t dma_addr; 1351 dma_addr_t dma_addr;
1341 1352
1342 if (!use_cmb_sqes)
1343 return NULL;
1344
1345 dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ); 1353 dev->cmbsz = readl(dev->bar + NVME_REG_CMBSZ);
1346 if (!(NVME_CMB_SZ(dev->cmbsz))) 1354 if (!(NVME_CMB_SZ(dev->cmbsz)))
1347 return NULL; 1355 return NULL;
1356 dev->cmbloc = readl(dev->bar + NVME_REG_CMBLOC);
1348 1357
1349 cmbloc = readl(dev->bar + NVME_REG_CMBLOC); 1358 if (!use_cmb_sqes)
1359 return NULL;
1350 1360
1351 szu = (u64)1 << (12 + 4 * NVME_CMB_SZU(dev->cmbsz)); 1361 szu = (u64)1 << (12 + 4 * NVME_CMB_SZU(dev->cmbsz));
1352 size = szu * NVME_CMB_SZ(dev->cmbsz); 1362 size = szu * NVME_CMB_SZ(dev->cmbsz);
1353 offset = szu * NVME_CMB_OFST(cmbloc); 1363 offset = szu * NVME_CMB_OFST(dev->cmbloc);
1354 bar_size = pci_resource_len(pdev, NVME_CMB_BIR(cmbloc)); 1364 bar_size = pci_resource_len(pdev, NVME_CMB_BIR(dev->cmbloc));
1355 1365
1356 if (offset > bar_size) 1366 if (offset > bar_size)
1357 return NULL; 1367 return NULL;
@@ -1364,7 +1374,7 @@ static void __iomem *nvme_map_cmb(struct nvme_dev *dev)
1364 if (size > bar_size - offset) 1374 if (size > bar_size - offset)
1365 size = bar_size - offset; 1375 size = bar_size - offset;
1366 1376
1367 dma_addr = pci_resource_start(pdev, NVME_CMB_BIR(cmbloc)) + offset; 1377 dma_addr = pci_resource_start(pdev, NVME_CMB_BIR(dev->cmbloc)) + offset;
1368 cmb = ioremap_wc(dma_addr, size); 1378 cmb = ioremap_wc(dma_addr, size);
1369 if (!cmb) 1379 if (!cmb)
1370 return NULL; 1380 return NULL;
@@ -1615,9 +1625,25 @@ static int nvme_pci_enable(struct nvme_dev *dev)
1615 dev->q_depth); 1625 dev->q_depth);
1616 } 1626 }
1617 1627
1618 if (readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 2)) 1628 /*
1629 * CMBs can currently only exist on >=1.2 PCIe devices. We only
1630 * populate sysfs if a CMB is implemented. Note that we add the
1631 * CMB attribute to the nvme_ctrl kobj which removes the need to remove
1632 * it on exit. Since nvme_dev_attrs_group has no name we can pass
1633 * NULL as final argument to sysfs_add_file_to_group.
1634 */
1635
1636 if (readl(dev->bar + NVME_REG_VS) >= NVME_VS(1, 2)) {
1619 dev->cmb = nvme_map_cmb(dev); 1637 dev->cmb = nvme_map_cmb(dev);
1620 1638
1639 if (dev->cmbsz) {
1640 if (sysfs_add_file_to_group(&dev->ctrl.device->kobj,
1641 &dev_attr_cmb.attr, NULL))
1642 dev_warn(dev->dev,
1643 "failed to add sysfs attribute for CMB\n");
1644 }
1645 }
1646
1621 pci_enable_pcie_error_reporting(pdev); 1647 pci_enable_pcie_error_reporting(pdev);
1622 pci_save_state(pdev); 1648 pci_save_state(pdev);
1623 return 0; 1649 return 0;