[ Upstream commit 851bd21cdb55e727ab29280bc9f6b678164f802a ]
If the DTS contains 'assigned-address', a dynamic address leak occurs
during hotjoin events.
Assume a device have assigned-address 0xb.
- Device issue Hotjoin
- Call i3c_master_do_daa()
- Call driver xxx_do_daa()
- Call i3c_master_get_free_addr() to get dynamic address 0x9
- i3c_master_add_i3c_dev_locked(0x9)
- expected_dyn_addr = newdev->boardinfo->init_dyn_addr (0xb);
- i3c_master_reattach_i3c_dev(newdev(0xb), old_dyn_addr(0x9));
- if (dev->info.dyn_addr != old_dyn_addr &&
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0xb != 0x9 -> TRUE
(!dev->boardinfo ||
^^^^^^^^^^^^^^^ -> FALSE
dev->info.dyn_addr != dev->boardinfo->init_dyn_addr)) {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0xb != 0xb -> FALSE
...
i3c_bus_set_addr_slot_status(&master->bus, old_dyn_addr,
I3C_ADDR_SLOT_FREE);
^^^
This will be skipped. So old_dyn_addr never free
}
- i3c_master_get_free_addr() will return increased sequence number.
Remove dev->info.dyn_addr != dev->boardinfo->init_dyn_addr condition check.
dev->info.dyn_addr should be checked before calling this function because
i3c_master_setnewda_locked() has already been called and the target device
has already accepted dyn_addr. It is too late to check if dyn_addr is free
in i3c_master_reattach_i3c_dev().
Add check to ensure expected_dyn_addr is free before
i3c_master_setnewda_locked().
Fixes: cc3a392d69b6 ("i3c: master: fix for SETDASA and DAA process")
Cc: stable@kernel.org
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20241021-i3c_dts_assign-v8-3-4098b8bde01e@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 2f552fa280590e61bd3dbe66a7b54b99caa642a4 ]
Extend the address status bit to 4 and introduce the
I3C_ADDR_SLOT_EXT_DESIRED macro to indicate that a device prefers a
specific address. This is generally set by the 'assigned-address' in the
device tree source (dts) file.
┌────┬─────────────┬───┬─────────┬───┐
│S/Sr│ 7'h7E RnW=0 │ACK│ ENTDAA │ T ├────┐
└────┴─────────────┴───┴─────────┴───┘ │
┌─────────────────────────────────────────┘
│ ┌──┬─────────────┬───┬─────────────────┬────────────────┬───┬─────────┐
└─►│Sr│7'h7E RnW=1 │ACK│48bit UID BCR DCR│Assign 7bit Addr│PAR│ ACK/NACK│
└──┴─────────────┴───┴─────────────────┴────────────────┴───┴─────────┘
Some master controllers (such as HCI) need to prepare the entire above
transaction before sending it out to the I3C bus. This means that a 7-bit
dynamic address needs to be allocated before knowing the target device's
UID information.
However, some I3C targets may request specific addresses (called as
"init_dyn_addr"), which is typically specified by the DT-'s
assigned-address property. Lower addresses having higher IBI priority. If
it is available, i3c_bus_get_free_addr() preferably return a free address
that is not in the list of desired addresses (called as "init_dyn_addr").
This allows the device with the "init_dyn_addr" to switch to its
"init_dyn_addr" when it hot-joins the I3C bus. Otherwise, if the
"init_dyn_addr" is already in use by another I3C device, the target device
will not be able to switch to its desired address.
If the previous step fails, fallback returning one of the remaining
unassigned address, regardless of its state in the desired list.
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20241021-i3c_dts_assign-v8-2-4098b8bde01e@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Stable-dep-of: 851bd21cdb55 ("i3c: master: Fix dynamic address leak when 'assigned-address' is present")
Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit 16aed0a6520ba01b7d22c32e193fc1ec674f92d4 ]
Replace the hardcoded value 2, which indicates 2 bits for I3C address
status, with the predefined macro I3C_ADDR_SLOT_STATUS_BITS.
Improve maintainability and extensibility of the code.
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
Link: https://lore.kernel.org/r/20241021-i3c_dts_assign-v8-1-4098b8bde01e@nxp.com
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Stable-dep-of: 851bd21cdb55 ("i3c: master: Fix dynamic address leak when 'assigned-address' is present")
Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit f18f98110f2b179792cb70d85cba697320a3790f ]
The address slot bitmap is an array of unsigned long's which are the
same size as an int on 32-bit platforms but not 64-bit. Loading the
bitmap into an int could result in the incorrect status being returned
for a slot and slots being reported as the wrong status.
Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
Cc: Boris Brezillon <bbrezillon@kernel.org>
Cc: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Jamie Iles <quic_jiles@quicinc.com>
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/20210922165600.179394-1-quic_jiles@quicinc.com
Stable-dep-of: 851bd21cdb55 ("i3c: master: Fix dynamic address leak when 'assigned-address' is present")
Signed-off-by: Sasha Levin <sashal@kernel.org>
[ Upstream commit cab63f64887616e3c4e31cfd8103320be6ebc8d3 ]
put_device() needs to be called on failure of device_register()
to give up the reference initialized in it to avoid refcount leak.
Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure")
Signed-off-by: Dinghao Liu <dinghao.liu@zju.edu.cn>
Link: https://lore.kernel.org/r/20230921082410.25548-1-dinghao.liu@zju.edu.cn
Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>