[PATCH 6/8] staging: kpc2000: use IDA to assign card numbers.

Jeremy Sowden jeremy at azazel.net
Mon May 20 19:52:32 UTC 2019


Previously the next card number was assigned from a static int local
variable.  Replaced it with an IDA.  Avoids the assignment of ever-
increasing card-numbers by allowing them to be reused.

Updated TODO.

Corrected format-specifier for unsigned pcard->card_num.

Signed-off-by: Jeremy Sowden <jeremy at azazel.net>
---
 drivers/staging/kpc2000/TODO                  |  1 -
 drivers/staging/kpc2000/kpc2000/core.c        | 23 +++++++++++++++----
 .../staging/kpc2000/kpc2000/kp2000_module.c   |  1 +
 drivers/staging/kpc2000/kpc2000/pcie.h        |  9 ++++----
 4 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/kpc2000/TODO b/drivers/staging/kpc2000/TODO
index 669fe5bf9637..47530e23e940 100644
--- a/drivers/staging/kpc2000/TODO
+++ b/drivers/staging/kpc2000/TODO
@@ -1,6 +1,5 @@
 - the kpc_spi driver doesn't seem to let multiple transactions (to different instances of the core) happen in parallel...
 - The kpc_i2c driver is a hot mess, it should probably be cleaned up a ton.  It functions against current hardware though.
-- pcard->card_num in kp2000_pcie_probe() is a global variable and needs atomic / locking / something better.
 - would be nice if the AIO fileops in kpc_dma could be made to work
     - probably want to add a CONFIG_ option to control compilation of the AIO functions
 - if the AIO fileops in kpc_dma start working, next would be making iov_count > 1 work too
diff --git a/drivers/staging/kpc2000/kpc2000/core.c b/drivers/staging/kpc2000/kpc2000/core.c
index 38de7e7a824d..a8383e8159eb 100644
--- a/drivers/staging/kpc2000/kpc2000/core.c
+++ b/drivers/staging/kpc2000/kpc2000/core.c
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0+
+#include <linux/idr.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -18,6 +19,8 @@
 #include <linux/jiffies.h>
 #include "pcie.h"
 
+static DEFINE_IDA(card_num_ida);
+
 /*******************************************************
  * SysFS Attributes
  ******************************************************/
@@ -274,7 +277,6 @@ int kp2000_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 {
 	int err = 0;
 	struct kp2000_device *pcard;
-	static int card_count = 1;
 	int rv;
 	unsigned long reg_bar_phys_addr;
 	unsigned long reg_bar_phys_len;
@@ -300,9 +302,14 @@ int kp2000_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	/*
 	 * Step 2: Initialize trivial pcard elements
 	 */
-	pcard->card_num = card_count;
-	card_count++;
-	scnprintf(pcard->name, 16, "kpcard%d", pcard->card_num);
+	err = ida_simple_get(&card_num_ida, 1, INT_MAX, GFP_KERNEL);
+	if (err < 0) {
+		dev_err(&pdev->dev, "probe: failed to get card number (%d)\n",
+			err);
+		goto out2;
+	}
+	pcard->card_num = err;
+	scnprintf(pcard->name, 16, "kpcard%u", pcard->card_num);
 
 	mutex_init(&pcard->sem);
 	lock_card(pcard);
@@ -517,6 +524,8 @@ int kp2000_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 	pci_disable_device(pcard->pdev);
 out3:
 	unlock_card(pcard);
+	ida_simple_remove(&card_num_ida, pcard->card_num);
+out2:
 	kfree(pcard);
 	return err;
 }
@@ -550,5 +559,11 @@ void kp2000_pcie_remove(struct pci_dev *pdev)
 	pci_disable_device(pcard->pdev);
 	pci_set_drvdata(pdev, NULL);
 	unlock_card(pcard);
+	ida_simple_remove(&card_num_ida, pcard->card_num);
 	kfree(pcard);
 }
+
+void kp2000_pcie_destroy(void)
+{
+	ida_destroy(&card_num_ida);
+}
diff --git a/drivers/staging/kpc2000/kpc2000/kp2000_module.c b/drivers/staging/kpc2000/kpc2000/kp2000_module.c
index fa3bd266ba54..8da8d5f5f8cc 100644
--- a/drivers/staging/kpc2000/kpc2000/kp2000_module.c
+++ b/drivers/staging/kpc2000/kpc2000/kp2000_module.c
@@ -50,5 +50,6 @@ static void __exit  kp2000_pcie_exit(void)
 {
 	pci_unregister_driver(&kp2000_driver_inst);
 	class_destroy(kpc_uio_class);
+	kp2000_pcie_destroy();
 }
 module_exit(kp2000_pcie_exit);
diff --git a/drivers/staging/kpc2000/kpc2000/pcie.h b/drivers/staging/kpc2000/kpc2000/pcie.h
index 8a032a5a962e..b416b792250b 100644
--- a/drivers/staging/kpc2000/kpc2000/pcie.h
+++ b/drivers/staging/kpc2000/kpc2000/pcie.h
@@ -84,10 +84,11 @@ struct kp2000_device {
 extern struct class *kpc_uio_class;
 extern struct attribute *kpc_uio_class_attrs[];
 
-int   kp2000_pcie_probe(struct pci_dev *dev, const struct pci_device_id *id);
-void  kp2000_pcie_remove(struct pci_dev *pdev);
-int   kp2000_probe_cores(struct kp2000_device *pcard);
-void  kp2000_remove_cores(struct kp2000_device *pcard);
+int  kp2000_pcie_probe(struct pci_dev *dev, const struct pci_device_id *id);
+void kp2000_pcie_remove(struct pci_dev *pdev);
+void kp2000_pcie_destroy(void);
+int  kp2000_probe_cores(struct kp2000_device *pcard);
+void kp2000_remove_cores(struct kp2000_device *pcard);
 
 extern struct file_operations  kp2000_fops;
 
-- 
2.20.1



More information about the devel mailing list