staging: kpc2000: use IDA to assign card numbers.
authorJeremy Sowden <jeremy@azazel.net>
Tue, 21 May 2019 10:35:22 +0000 (11:35 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 May 2019 12:44:21 +0000 (14:44 +0200)
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@azazel.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/kpc2000/TODO
drivers/staging/kpc2000/kpc2000/core.c

index 669fe5b..47530e2 100644 (file)
@@ -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
index 6b56ddc..7d6b99f 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0+
 #include <linux/kernel.h>
+#include <linux/idr.h>
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/pci.h>
@@ -25,6 +26,8 @@
 #include "pcie.h"
 #include "uapi.h"
 
+static DEFINE_IDA(card_num_ida);
+
 /*******************************************************
  * SysFS Attributes
  ******************************************************/
@@ -388,7 +391,6 @@ static int kp2000_pcie_probe(struct pci_dev *pdev,
 {
        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;
@@ -414,9 +416,14 @@ static int kp2000_pcie_probe(struct pci_dev *pdev,
        /*
         * 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);
        mutex_lock(&pcard->sem);
@@ -630,6 +637,8 @@ out4:
        pci_disable_device(pcard->pdev);
 out3:
        mutex_unlock(&pcard->sem);
+       ida_simple_remove(&card_num_ida, pcard->card_num);
+out2:
        kfree(pcard);
        return err;
 }
@@ -663,6 +672,7 @@ static void kp2000_pcie_remove(struct pci_dev *pdev)
        pci_disable_device(pcard->pdev);
        pci_set_drvdata(pdev, NULL);
        mutex_unlock(&pcard->sem);
+       ida_simple_remove(&card_num_ida, pcard->card_num);
        kfree(pcard);
 }
 
@@ -698,6 +708,7 @@ static void __exit  kp2000_pcie_exit(void)
 {
        pci_unregister_driver(&kp2000_driver_inst);
        class_destroy(kpc_uio_class);
+       ida_destroy(&card_num_ida);
 }
 module_exit(kp2000_pcie_exit);