[PATCH V3 3/7] i3c: master: Prevent reuse of dynamic address on device add failure

Frank Li Frank.li at oss.nxp.com
Thu Jun 11 09:09:19 PDT 2026


On Wed, Jun 10, 2026 at 10:28:48AM +0300, Adrian Hunter wrote:
> i3c_master_add_i3c_dev_locked() is called after a device has already
> been assigned a dynamic address.  If the function fails, the address
> remains marked as free and may be reallocated to another device,
> leading to address conflicts on the bus.
>
> Ensure the address is not marked as free on failure, by updating the
> address slot state to prevent the address from being re-used.
>
> Emit an error message to inform of the failure.
>
> Opportunistically remove the !master check because it is impossible.
>
> Note, directly resetting the device's dynamic address is no longer
> an option, since Direct RSTDAA was deprecated from I3C starting from
> version 1.1 and v1.1 (or later) target devices are meant to NACK it.
>
> Fixes: 3a379bbcea0af ("i3c: Add core I3C infrastructure")
> Signed-off-by: Adrian Hunter <adrian.hunter at intel.com>
> ---

Reviewed-by: Frank Li <Frank.Li at nxp.com>

>
>
> Changes in V3:
>
> 	Add note to commit message about Direct RSTDAA deprecation
>
> Changes in V2:
>
> 	Fix 'if (IS_ERR(newdev)' error path.
> 	Be defensive and do not change the addr_slot_status if it is not
> 	free, and update commit message accordingly.
> 	Amend commit message to note removal of unnecesary 'if (!master)'
> 	check.
> 	Add Fixes tag.
>
>
>  drivers/i3c/master.c | 19 ++++++++++++++-----
>  1 file changed, 14 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index f87bf0099d3c..7b60b0c7f646 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -2345,12 +2345,11 @@ int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master,
>  	bool enable_ibi = false;
>  	int ret;
>
> -	if (!master)
> -		return -EINVAL;
> -
>  	newdev = i3c_master_alloc_i3c_dev(master, &info);
> -	if (IS_ERR(newdev))
> -		return PTR_ERR(newdev);
> +	if (IS_ERR(newdev)) {
> +		ret = PTR_ERR(newdev);
> +		goto err_prevent_addr_reuse;
> +	}
>
>  	ret = i3c_master_attach_i3c_dev(master, newdev);
>  	if (ret)
> @@ -2472,6 +2471,16 @@ int i3c_master_add_i3c_dev_locked(struct i3c_master_controller *master,
>  err_free_dev:
>  	i3c_master_free_i3c_dev(newdev);
>
> +err_prevent_addr_reuse:
> +	/*
> +	 * Although the device has not been added, the address has been
> +	 * assigned. Prevent the address from being used again.
> +	 */
> +	if (i3c_bus_get_addr_slot_status(&master->bus, addr) == I3C_ADDR_SLOT_FREE)
> +		i3c_bus_set_addr_slot_status(&master->bus, addr, I3C_ADDR_SLOT_I3C_DEV);
> +
> +	dev_err(&master->dev, "Failed to add I3C device at address %u, error %d\n", addr, ret);
> +
>  	return ret;
>  }
>  EXPORT_SYMBOL_GPL(i3c_master_add_i3c_dev_locked);
> --
> 2.51.0
>



More information about the linux-i3c mailing list