Commit 35eded62 authored by Federico Vaga's avatar Federico Vaga

fmc: fix fmc_carrier_add_slot error handling process

The device release function and the fmc_carrier_add_slot error handling
process were freeing the IDA is twice. Somehow, the id triggered a NULL
pointer bug. Not clear where that comes from, but fixing the error
management fixed the NULL pointer reference as well (I think, but I do
not have time to investigate further).
Signed-off-by: Federico Vaga's avatarFederico Vaga <federico.vaga@cern.ch>
parent 92c324fc
......@@ -87,8 +87,9 @@ static void fmc_slot_release(struct device *dev)
struct fmc_slot *slot = to_fmc_slot(dev);
i2c_put_adapter(slot->adapter);
slot->adapter = NULL;
ida_simple_remove(&fmc_slot_ida, slot->dev.id);
slot->dev.id = -1;
}
static const struct device_type fmc_slot_type = {
......@@ -148,39 +149,42 @@ static struct fmc_slot *fmc_carrier_add_slot(struct fmc_carrier *carrier,
struct fmc_slot_info *info)
{
struct fmc_slot *slot;
int ret, err, id;
int ret, err;
if (WARN(!info, "Invalid slot info"))
return ERR_PTR(-EINVAL);
id = fmc_slot_id(carrier, info->lun);
id = ida_simple_get(&fmc_slot_ida, id, id + 1, GFP_KERNEL);
if (id < 0) {
dev_err(&carrier->dev,
"can't assign ID to slot (LUN: %dGA: 0x%02x)\n",
info->lun, info->ga);
err = id;
goto err_ida;
}
slot = devm_kzalloc(&carrier->dev, sizeof(struct fmc_slot), GFP_KERNEL);
if (!slot) {
err = -ENOMEM;
goto err_alloc;
}
slot->ga = info->ga;
slot->lun = info->lun;
slot->dev.class = &fmc_class;
slot->dev.type = &fmc_slot_type;
slot->dev.parent = &carrier->dev;
slot->dev.id = fmc_slot_id(carrier, info->lun);
slot->dev.id = ida_simple_get(&fmc_slot_ida,
slot->dev.id, slot->dev.id + 1,
GFP_KERNEL);
if (slot->dev.id < 0) {
dev_err(&carrier->dev,
"can't assign ID to slot (LUN: %dGA: 0x%02x)\n",
info->lun, info->ga);
err = slot->dev.id;
goto err_ida;
}
slot->adapter = i2c_get_adapter(info->i2c_bus_nr);
if (!slot->adapter) {
err = -ENODEV;
goto err_i2c;
}
slot->dev.class = &fmc_class;
slot->dev.type = &fmc_slot_type;
slot->dev.parent = &carrier->dev;
slot->dev.id = id;
err = dev_set_name(&slot->dev, "fmc-slot-%d.%d",
carrier->dev.id,
slot->lun);
......@@ -209,10 +213,10 @@ err_reg:
err_name:
i2c_put_adapter(slot->adapter);
err_i2c:
ida_simple_remove(&fmc_slot_ida, slot->dev.id);
err_ida:
devm_kfree(&carrier->dev, slot);
err_alloc:
ida_simple_remove(&fmc_slot_ida, id);
err_ida:
return ERR_PTR(err);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment