@@ -1047,7 +1047,7 @@ struct mpi3mr_ioc {
struct list_head list;
struct pci_dev *pdev;
struct Scsi_Host *shost;
- u8 id;
+ int id;
int cpu_count;
bool enable_segqueue;
u32 irqpoll_sleep;
@@ -8,11 +8,12 @@
*/
#include "mpi3mr.h"
+#include <linux/idr.h>
/* global driver scop variables */
LIST_HEAD(mrioc_list);
DEFINE_SPINLOCK(mrioc_list_lock);
-static int mrioc_ids;
+static DEFINE_IDA(mrioc_ida);
static int warn_non_secure_ctlr;
atomic64_t event_counter;
@@ -5060,7 +5061,10 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
mrioc = shost_priv(shost);
- mrioc->id = mrioc_ids++;
+ retval = ida_alloc(&mrioc_ida, GFP_KERNEL);
+ if (retval < 0)
+ goto id_alloc_failed;
+ mrioc->id = retval;
sprintf(mrioc->driver_name, "%s", MPI3MR_DRIVER_NAME);
sprintf(mrioc->name, "%s%d", mrioc->driver_name, mrioc->id);
INIT_LIST_HEAD(&mrioc->list);
@@ -5207,9 +5211,11 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
resource_alloc_failed:
destroy_workqueue(mrioc->fwevt_worker_thread);
fwevtthread_failed:
+ ida_free(&mrioc_ida, mrioc->id);
spin_lock(&mrioc_list_lock);
list_del(&mrioc->list);
spin_unlock(&mrioc_list_lock);
+id_alloc_failed:
scsi_host_put(shost);
shost_failed:
return retval;
@@ -5295,6 +5301,7 @@ static void mpi3mr_remove(struct pci_dev *pdev)
mrioc->sas_hba.num_phys = 0;
}
+ ida_free(&mrioc_ida, mrioc->id);
spin_lock(&mrioc_list_lock);
list_del(&mrioc->list);
spin_unlock(&mrioc_list_lock);
@@ -5502,6 +5509,7 @@ static void __exit mpi3mr_exit(void)
&driver_attr_event_counter);
pci_unregister_driver(&mpi3mr_pci_driver);
sas_release_transport(mpi3mr_transport_template);
+ ida_destroy(&mrioc_ida);
}
module_init(mpi3mr_init);
To ensure that the same id is not obtained during concurrent execution of the probe, an ida is used to manage the mrioc's id. Signed-off-by: Guixin Liu <kanie@linux.alibaba.com> --- drivers/scsi/mpi3mr/mpi3mr.h | 2 +- drivers/scsi/mpi3mr/mpi3mr_os.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-)