summaryrefslogtreecommitdiffstats
path: root/drivers/ntb/ntb_hw.c
diff options
context:
space:
mode:
authorJon Mason <jon.mason@intel.com>2013-07-30 15:58:49 -0700
committerJon Mason <jon.mason@intel.com>2013-09-03 11:14:54 -0700
commit1517a3f21a1dd321f16bcf44204bddff9d21abd0 (patch)
tree45b8eb39ea33fae5f66af89376f5029e45d09127 /drivers/ntb/ntb_hw.c
parentb6750cfe0710a14fd147ba27fddbecae8ba88c77 (diff)
downloadlinux-1517a3f21a1dd321f16bcf44204bddff9d21abd0.tar.bz2
NTB: Correct debugfs to work with more than 1 NTB Device
Debugfs was setup in NTB to only have a single debugfs directory. This resulted in the leaking of debugfs directories and files when multiple NTB devices were present, due to each device stomping on the variables containing the previous device's values (thus preventing them from being freed on cleanup). Correct this by creating a secondary directory of the PCI BDF for each device present, and nesting the previously existing information in those directories. Signed-off-by: Jon Mason <jon.mason@intel.com>
Diffstat (limited to 'drivers/ntb/ntb_hw.c')
-rw-r--r--drivers/ntb/ntb_hw.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c
index 26b808b4d3a0..b9bf8b551e3c 100644
--- a/drivers/ntb/ntb_hw.c
+++ b/drivers/ntb/ntb_hw.c
@@ -78,6 +78,8 @@ enum {
BWD_HW,
};
+static struct dentry *debugfs_dir;
+
/* Translate memory window 0,1 to BAR 2,4 */
#define MW_TO_BAR(mw) (mw * 2 + 2)
@@ -998,6 +1000,28 @@ static void ntb_free_callbacks(struct ntb_device *ndev)
kfree(ndev->db_cb);
}
+static void ntb_setup_debugfs(struct ntb_device *ndev)
+{
+ if (!debugfs_initialized())
+ return;
+
+ if (!debugfs_dir)
+ debugfs_dir = debugfs_create_dir(KBUILD_MODNAME, NULL);
+
+ ndev->debugfs_dir = debugfs_create_dir(pci_name(ndev->pdev),
+ debugfs_dir);
+}
+
+static void ntb_free_debugfs(struct ntb_device *ndev)
+{
+ debugfs_remove_recursive(ndev->debugfs_dir);
+
+ if (debugfs_dir && simple_empty(debugfs_dir)) {
+ debugfs_remove_recursive(debugfs_dir);
+ debugfs_dir = NULL;
+ }
+}
+
static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct ntb_device *ndev;
@@ -1010,6 +1034,7 @@ static int ntb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
ndev->pdev = pdev;
ndev->link_status = NTB_LINK_DOWN;
pci_set_drvdata(pdev, ndev);
+ ntb_setup_debugfs(ndev);
rc = pci_enable_device(pdev);
if (rc)
@@ -1106,6 +1131,7 @@ err2:
err1:
pci_disable_device(pdev);
err:
+ ntb_free_debugfs(ndev);
kfree(ndev);
dev_err(&pdev->dev, "Error loading %s module\n", KBUILD_MODNAME);
@@ -1135,6 +1161,7 @@ static void ntb_pci_remove(struct pci_dev *pdev)
iounmap(ndev->reg_base);
pci_release_selected_regions(pdev, NTB_BAR_MASK);
pci_disable_device(pdev);
+ ntb_free_debugfs(ndev);
kfree(ndev);
}