fsi: Improve master indexing

Master indexing is problematic if a hub is rescanned while the
root master is being rescanned. Always allocate an index for the
FSI master, and set the device name if it hasn't already been set.
Move the call to ida_free to the bottom of master unregistration
and set the number of links to 0 in case another call to scan
comes in before the device is removed.

Signed-off-by: Eddie James <eajames@linux.ibm.com>
Link: https://lore.kernel.org/r/20230809180814.151984-2-eajames@linux.ibm.com
Signed-off-by: Joel Stanley <joel@jms.id.au>
This commit is contained in:
Eddie James 2023-08-09 13:08:13 -05:00 committed by Joel Stanley
parent 85f4e899de
commit adde0e112c

View file

@ -1309,11 +1309,21 @@ int fsi_master_register(struct fsi_master *master)
struct device_node *np;
mutex_init(&master->scan_lock);
master->idx = ida_alloc(&master_ida, GFP_KERNEL);
/* Alloc the requested index if it's non-zero */
if (master->idx) {
master->idx = ida_alloc_range(&master_ida, master->idx,
master->idx, GFP_KERNEL);
} else {
master->idx = ida_alloc(&master_ida, GFP_KERNEL);
}
if (master->idx < 0)
return master->idx;
dev_set_name(&master->dev, "fsi%d", master->idx);
if (!dev_name(&master->dev))
dev_set_name(&master->dev, "fsi%d", master->idx);
master->dev.class = &fsi_master_class;
rc = device_register(&master->dev);
@ -1335,17 +1345,17 @@ EXPORT_SYMBOL_GPL(fsi_master_register);
void fsi_master_unregister(struct fsi_master *master)
{
trace_fsi_master_unregister(master);
int idx = master->idx;
if (master->idx >= 0) {
ida_free(&master_ida, master->idx);
master->idx = -1;
}
trace_fsi_master_unregister(master);
mutex_lock(&master->scan_lock);
fsi_master_unscan(master);
master->n_links = 0;
mutex_unlock(&master->scan_lock);
device_unregister(&master->dev);
ida_free(&master_ida, idx);
}
EXPORT_SYMBOL_GPL(fsi_master_unregister);