* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-10-20 21:20 ` Sam Agazaryan
0 siblings, 0 replies; 40+ messages in thread
From: Sam Agazaryan @ 2026-10-20 21:20 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Wolfram Sang, linux-i3c, Alexandre Belloni, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
> Did I miss this in the initial explanation? If not, please add it next time.
That is just how the existing I3C core enumerates targets during DAA,
not something added by this series. I will add a sentence to the
cover letter and Patch 4 commit message in v6 contrasting it with
i2c-dev to make that context clear.
> Do we have such use cases IRL? Do we have tooling support (at least pending)
> somewhere? Why does it require user space interaction in _this_ way (meaning
> IOCTL and /dev node)?
Yes, this is used in real systems today:
1. Tooling & production users:
- i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
years).
- OCP Secure Firmware Recovery (DCR 0xBD) [1] and Caliptra Root-of-Trust
recovery agents on OpenBMC/gBMC platforms (e.g., AST2700 / Caliptra
MCU recovery tooling and BMC recovery daemons). Because Vitor's
original i3cdev series was not merged in 2019, multiple silicon
vendors and OpenBMC trees have been carrying out-of-tree forks of i3cdev;
upstreaming consolidates those diverging implementations.
2. Why an ioctl is required over a read and write:
- In the OCP Secure Firmware Recovery v1.1 specification (Section
8.4, "Recovery I3C Interface Block Read via Private Write and
Private Read"), every recovery command read is a combined transaction
consisting of a Private Write with no STOP, followed by a Repeated START,
followed by a Private Read, and finally a STOP.
- Because write() and read() only submit a single transfer at a time
(nxfers = 1), the controller emits a STOP condition on the wire
at the end of write() and drops the bus lock. Submitting multiple
i3c_ioc_xfer descriptors in a single I3C_IOC_XFER(N) ioctl is
required so i3c_device_do_xfers() queues them together under one
bus lock acquisition and the controller emits a Repeated START
between messages (as well as passing HDR mode/cmd parameters).
[1] https://www.opencompute.org/documents/ocp-recovery-document-1p1-final-pdf
> So, imagine that someone submits a kernel driver for a simple device, while
> another person already uses the driver for multi-functional device where the
> former one is driving only part of it. Strictly speaking the kernel driver
> submission becomes a user space regression. Which effectively means that whenever
> you open i3cdev, no other kernel drivers may appear. Yes, I understand that
> a poor victim of such an unlikely course of events may recompile the kernel,
> disable driver, et cetera, but this still raises the same question, why do
> we do that to the mere users?
Note that a user does not need to recompile the kernel if a kernel
driver binds to a device they wish to access via i3cdev. Because i3cdev
handles BUS_NOTIFY_UNBOUND_DRIVER, unbinding the kernel driver at
runtime via sysfs:
echo <dev> > /sys/bus/i3c/devices/<dev>/driver/unbind
automatically triggers i3cdev_attach() and exposes /dev/bus/i3c/<dev>
without rebuilding the kernel. Also, I3C drivers match against a
target's MIPI-assigned DCR or 48-bit PID (Manufacturer ID + Part ID),
so a driver for a simple device will not accidentally match a different
chip's PID or a dedicated DCR like 0xBD.
> P.S> Still not convinced, that this has to be an ABI. For debugfs and something
> like this, no objections, but ABI.
Production BMC recovery daemons cannot rely on debugfs, which is
optional and restricted or unmounted on production builds. A character
device in /dev/bus/i3c/* provides the stable ioctl those tools need and
integrates with udev so non-root daemons can be granted access to
specific target nodes (e.g. matching on DCR 0xBD), similar to spidev
and hidraw.
> Forgot to ask, but do they interfere?
Is this in reference to i2c devices on the i3c bus? No, I3C transfers
and legacy
I2C transfers on a mixed-mode bus do not interfere:
1. Both i3c_device_do_xfers() and i3c_master_i2c_adapter_xfer() acquire
i3c_bus_normaluse_lock(&master->bus), so I3C and I2C transactions on
the same bus are serialized by the I3C core.
2. Attached I2C client addresses are marked as I3C_ADDR_SLOT_I2C_DEV in
the bus address slot table, preventing DAA from assigning an I2C
device's address to an I3C target.
Thanks,
Sam
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
2026-10-20 21:20 ` Sam Agazaryan
@ 2026-10-21 9:57 ` Alexandre Belloni
-1 siblings, 0 replies; 40+ messages in thread
From: Alexandre Belloni @ 2026-10-21 9:57 UTC (permalink / raw)
To: Sam Agazaryan
Cc: Andy Shevchenko, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On 20/10/2026 14:20:16-0700, Sam Agazaryan wrote:
> > Did I miss this in the initial explanation? If not, please add it next time.
>
> That is just how the existing I3C core enumerates targets during DAA,
> not something added by this series. I will add a sentence to the
> cover letter and Patch 4 commit message in v6 contrasting it with
> i2c-dev to make that context clear.
>
> > Do we have such use cases IRL? Do we have tooling support (at least pending)
> > somewhere? Why does it require user space interaction in _this_ way (meaning
> > IOCTL and /dev node)?
>
> Yes, this is used in real systems today:
>
> 1. Tooling & production users:
>
> - i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
> AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
> years).
>
> - OCP Secure Firmware Recovery (DCR 0xBD) [1] and Caliptra Root-of-Trust
> recovery agents on OpenBMC/gBMC platforms (e.g., AST2700 / Caliptra
> MCU recovery tooling and BMC recovery daemons). Because Vitor's
> original i3cdev series was not merged in 2019, multiple silicon
> vendors and OpenBMC trees have been carrying out-of-tree forks of i3cdev;
> upstreaming consolidates those diverging implementations.
>
> 2. Why an ioctl is required over a read and write:
>
> - In the OCP Secure Firmware Recovery v1.1 specification (Section
> 8.4, "Recovery I3C Interface Block Read via Private Write and
> Private Read"), every recovery command read is a combined transaction
> consisting of a Private Write with no STOP, followed by a Repeated START,
> followed by a Private Read, and finally a STOP.
>
> - Because write() and read() only submit a single transfer at a time
> (nxfers = 1), the controller emits a STOP condition on the wire
> at the end of write() and drops the bus lock. Submitting multiple
> i3c_ioc_xfer descriptors in a single I3C_IOC_XFER(N) ioctl is
> required so i3c_device_do_xfers() queues them together under one
> bus lock acquisition and the controller emits a Repeated START
> between messages (as well as passing HDR mode/cmd parameters).
>
> [1] https://www.opencompute.org/documents/ocp-recovery-document-1p1-final-pdf
>
> > So, imagine that someone submits a kernel driver for a simple device, while
> > another person already uses the driver for multi-functional device where the
> > former one is driving only part of it. Strictly speaking the kernel driver
> > submission becomes a user space regression. Which effectively means that whenever
> > you open i3cdev, no other kernel drivers may appear. Yes, I understand that
> > a poor victim of such an unlikely course of events may recompile the kernel,
> > disable driver, et cetera, but this still raises the same question, why do
> > we do that to the mere users?
>
> Note that a user does not need to recompile the kernel if a kernel
> driver binds to a device they wish to access via i3cdev. Because i3cdev
> handles BUS_NOTIFY_UNBOUND_DRIVER, unbinding the kernel driver at
> runtime via sysfs:
>
> echo <dev> > /sys/bus/i3c/devices/<dev>/driver/unbind
>
> automatically triggers i3cdev_attach() and exposes /dev/bus/i3c/<dev>
> without rebuilding the kernel. Also, I3C drivers match against a
> target's MIPI-assigned DCR or 48-bit PID (Manufacturer ID + Part ID),
> so a driver for a simple device will not accidentally match a different
> chip's PID or a dedicated DCR like 0xBD.
>
> > P.S> Still not convinced, that this has to be an ABI. For debugfs and something
> > like this, no objections, but ABI.
>
> Production BMC recovery daemons cannot rely on debugfs, which is
> optional and restricted or unmounted on production builds. A character
> device in /dev/bus/i3c/* provides the stable ioctl those tools need and
> integrates with udev so non-root daemons can be granted access to
> specific target nodes (e.g. matching on DCR 0xBD), similar to spidev
> and hidraw.
>
>
> > Forgot to ask, but do they interfere?
>
> Is this in reference to i2c devices on the i3c bus? No, I3C transfers
> and legacy
> I2C transfers on a mixed-mode bus do not interfere:
>
> 1. Both i3c_device_do_xfers() and i3c_master_i2c_adapter_xfer() acquire
> i3c_bus_normaluse_lock(&master->bus), so I3C and I2C transactions on
> the same bus are serialized by the I3C core.
>
> 2. Attached I2C client addresses are marked as I3C_ADDR_SLOT_I2C_DEV in
> the bus address slot table, preventing DAA from assigning an I2C
> device's address to an I3C target.
On my side, I believe i3cdev can be added to the kernel and that it is
way safer than i2cdev but I agree that the ABI has to be properly
designed, maybe we need to version it or have a way to probe for
supported features so we can update safely later on. It is failry simple
right now but I feel like we are going to see people with more needs
than initiating transfers.
Also, I think this should not bind to any devices by default and make
binding explicit.
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-10-21 9:57 ` Alexandre Belloni
0 siblings, 0 replies; 40+ messages in thread
From: Alexandre Belloni @ 2026-10-21 9:57 UTC (permalink / raw)
To: Sam Agazaryan
Cc: Andy Shevchenko, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On 20/10/2026 14:20:16-0700, Sam Agazaryan wrote:
> > Did I miss this in the initial explanation? If not, please add it next time.
>
> That is just how the existing I3C core enumerates targets during DAA,
> not something added by this series. I will add a sentence to the
> cover letter and Patch 4 commit message in v6 contrasting it with
> i2c-dev to make that context clear.
>
> > Do we have such use cases IRL? Do we have tooling support (at least pending)
> > somewhere? Why does it require user space interaction in _this_ way (meaning
> > IOCTL and /dev node)?
>
> Yes, this is used in real systems today:
>
> 1. Tooling & production users:
>
> - i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
> AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
> years).
>
> - OCP Secure Firmware Recovery (DCR 0xBD) [1] and Caliptra Root-of-Trust
> recovery agents on OpenBMC/gBMC platforms (e.g., AST2700 / Caliptra
> MCU recovery tooling and BMC recovery daemons). Because Vitor's
> original i3cdev series was not merged in 2019, multiple silicon
> vendors and OpenBMC trees have been carrying out-of-tree forks of i3cdev;
> upstreaming consolidates those diverging implementations.
>
> 2. Why an ioctl is required over a read and write:
>
> - In the OCP Secure Firmware Recovery v1.1 specification (Section
> 8.4, "Recovery I3C Interface Block Read via Private Write and
> Private Read"), every recovery command read is a combined transaction
> consisting of a Private Write with no STOP, followed by a Repeated START,
> followed by a Private Read, and finally a STOP.
>
> - Because write() and read() only submit a single transfer at a time
> (nxfers = 1), the controller emits a STOP condition on the wire
> at the end of write() and drops the bus lock. Submitting multiple
> i3c_ioc_xfer descriptors in a single I3C_IOC_XFER(N) ioctl is
> required so i3c_device_do_xfers() queues them together under one
> bus lock acquisition and the controller emits a Repeated START
> between messages (as well as passing HDR mode/cmd parameters).
>
> [1] https://www.opencompute.org/documents/ocp-recovery-document-1p1-final-pdf
>
> > So, imagine that someone submits a kernel driver for a simple device, while
> > another person already uses the driver for multi-functional device where the
> > former one is driving only part of it. Strictly speaking the kernel driver
> > submission becomes a user space regression. Which effectively means that whenever
> > you open i3cdev, no other kernel drivers may appear. Yes, I understand that
> > a poor victim of such an unlikely course of events may recompile the kernel,
> > disable driver, et cetera, but this still raises the same question, why do
> > we do that to the mere users?
>
> Note that a user does not need to recompile the kernel if a kernel
> driver binds to a device they wish to access via i3cdev. Because i3cdev
> handles BUS_NOTIFY_UNBOUND_DRIVER, unbinding the kernel driver at
> runtime via sysfs:
>
> echo <dev> > /sys/bus/i3c/devices/<dev>/driver/unbind
>
> automatically triggers i3cdev_attach() and exposes /dev/bus/i3c/<dev>
> without rebuilding the kernel. Also, I3C drivers match against a
> target's MIPI-assigned DCR or 48-bit PID (Manufacturer ID + Part ID),
> so a driver for a simple device will not accidentally match a different
> chip's PID or a dedicated DCR like 0xBD.
>
> > P.S> Still not convinced, that this has to be an ABI. For debugfs and something
> > like this, no objections, but ABI.
>
> Production BMC recovery daemons cannot rely on debugfs, which is
> optional and restricted or unmounted on production builds. A character
> device in /dev/bus/i3c/* provides the stable ioctl those tools need and
> integrates with udev so non-root daemons can be granted access to
> specific target nodes (e.g. matching on DCR 0xBD), similar to spidev
> and hidraw.
>
>
> > Forgot to ask, but do they interfere?
>
> Is this in reference to i2c devices on the i3c bus? No, I3C transfers
> and legacy
> I2C transfers on a mixed-mode bus do not interfere:
>
> 1. Both i3c_device_do_xfers() and i3c_master_i2c_adapter_xfer() acquire
> i3c_bus_normaluse_lock(&master->bus), so I3C and I2C transactions on
> the same bus are serialized by the I3C core.
>
> 2. Attached I2C client addresses are marked as I3C_ADDR_SLOT_I2C_DEV in
> the bus address slot table, preventing DAA from assigning an I2C
> device's address to an I3C target.
On my side, I believe i3cdev can be added to the kernel and that it is
way safer than i2cdev but I agree that the ABI has to be properly
designed, maybe we need to version it or have a way to probe for
supported features so we can update safely later on. It is failry simple
right now but I feel like we are going to see people with more needs
than initiating transfers.
Also, I think this should not bind to any devices by default and make
binding explicit.
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
2026-10-21 9:57 ` Alexandre Belloni
@ 2026-10-21 13:03 ` Andy Shevchenko
-1 siblings, 0 replies; 40+ messages in thread
From: Andy Shevchenko @ 2026-10-21 13:03 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Sam Agazaryan, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On Wed, Oct 21, 2026 at 11:57:56AM +0200, Alexandre Belloni wrote:
> On 20/10/2026 14:20:16-0700, Sam Agazaryan wrote:
> > > Did I miss this in the initial explanation? If not, please add it next time.
> >
> > That is just how the existing I3C core enumerates targets during DAA,
> > not something added by this series. I will add a sentence to the
> > cover letter and Patch 4 commit message in v6 contrasting it with
> > i2c-dev to make that context clear.
> >
> > > Do we have such use cases IRL? Do we have tooling support (at least pending)
> > > somewhere? Why does it require user space interaction in _this_ way (meaning
> > > IOCTL and /dev node)?
> >
> > Yes, this is used in real systems today:
> >
> > 1. Tooling & production users:
> >
> > - i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
> > AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
> > years).
> >
> > - OCP Secure Firmware Recovery (DCR 0xBD) [1] and Caliptra Root-of-Trust
> > recovery agents on OpenBMC/gBMC platforms (e.g., AST2700 / Caliptra
> > MCU recovery tooling and BMC recovery daemons). Because Vitor's
> > original i3cdev series was not merged in 2019, multiple silicon
> > vendors and OpenBMC trees have been carrying out-of-tree forks of i3cdev;
> > upstreaming consolidates those diverging implementations.
> >
> > 2. Why an ioctl is required over a read and write:
> >
> > - In the OCP Secure Firmware Recovery v1.1 specification (Section
> > 8.4, "Recovery I3C Interface Block Read via Private Write and
> > Private Read"), every recovery command read is a combined transaction
> > consisting of a Private Write with no STOP, followed by a Repeated START,
> > followed by a Private Read, and finally a STOP.
> >
> > - Because write() and read() only submit a single transfer at a time
> > (nxfers = 1), the controller emits a STOP condition on the wire
> > at the end of write() and drops the bus lock. Submitting multiple
> > i3c_ioc_xfer descriptors in a single I3C_IOC_XFER(N) ioctl is
> > required so i3c_device_do_xfers() queues them together under one
> > bus lock acquisition and the controller emits a Repeated START
> > between messages (as well as passing HDR mode/cmd parameters).
> >
> > [1] https://www.opencompute.org/documents/ocp-recovery-document-1p1-final-pdf
> >
> > > So, imagine that someone submits a kernel driver for a simple device, while
> > > another person already uses the driver for multi-functional device where the
> > > former one is driving only part of it. Strictly speaking the kernel driver
> > > submission becomes a user space regression. Which effectively means that whenever
> > > you open i3cdev, no other kernel drivers may appear. Yes, I understand that
> > > a poor victim of such an unlikely course of events may recompile the kernel,
> > > disable driver, et cetera, but this still raises the same question, why do
> > > we do that to the mere users?
> >
> > Note that a user does not need to recompile the kernel if a kernel
> > driver binds to a device they wish to access via i3cdev. Because i3cdev
> > handles BUS_NOTIFY_UNBOUND_DRIVER, unbinding the kernel driver at
> > runtime via sysfs:
> >
> > echo <dev> > /sys/bus/i3c/devices/<dev>/driver/unbind
> >
> > automatically triggers i3cdev_attach() and exposes /dev/bus/i3c/<dev>
> > without rebuilding the kernel. Also, I3C drivers match against a
> > target's MIPI-assigned DCR or 48-bit PID (Manufacturer ID + Part ID),
> > so a driver for a simple device will not accidentally match a different
> > chip's PID or a dedicated DCR like 0xBD.
> >
> > > P.S> Still not convinced, that this has to be an ABI. For debugfs and something
> > > like this, no objections, but ABI.
> >
> > Production BMC recovery daemons cannot rely on debugfs, which is
> > optional and restricted or unmounted on production builds. A character
> > device in /dev/bus/i3c/* provides the stable ioctl those tools need and
> > integrates with udev so non-root daemons can be granted access to
> > specific target nodes (e.g. matching on DCR 0xBD), similar to spidev
> > and hidraw.
> >
> >
> > > Forgot to ask, but do they interfere?
> >
> > Is this in reference to i2c devices on the i3c bus? No, I3C transfers
> > and legacy
> > I2C transfers on a mixed-mode bus do not interfere:
> >
> > 1. Both i3c_device_do_xfers() and i3c_master_i2c_adapter_xfer() acquire
> > i3c_bus_normaluse_lock(&master->bus), so I3C and I2C transactions on
> > the same bus are serialized by the I3C core.
> >
> > 2. Attached I2C client addresses are marked as I3C_ADDR_SLOT_I2C_DEV in
> > the bus address slot table, preventing DAA from assigning an I2C
> > device's address to an I3C target.
>
> On my side, I believe i3cdev can be added to the kernel and that it is
> way safer than i2cdev but I agree that the ABI has to be properly
> designed, maybe we need to version it or have a way to probe for
> supported features so we can update safely later on. It is failry simple
> right now but I feel like we are going to see people with more needs
> than initiating transfers.
Yeah, I really think that i2cdev was a pure mistake (as to be an ABI).
I don't want to repeat it now, when we learnt about that case a lot.
If we ever going to have i3cdev (which justification I also put in doubts)
it needs to be very strict of what can be done and how.
> Also, I think this should not bind to any devices by default and make
> binding explicit.
Yes, this is quite dangerous "feature".
--
With Best Regards,
Andy Shevchenko
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-10-21 13:03 ` Andy Shevchenko
0 siblings, 0 replies; 40+ messages in thread
From: Andy Shevchenko @ 2026-10-21 13:03 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Sam Agazaryan, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On Wed, Oct 21, 2026 at 11:57:56AM +0200, Alexandre Belloni wrote:
> On 20/10/2026 14:20:16-0700, Sam Agazaryan wrote:
> > > Did I miss this in the initial explanation? If not, please add it next time.
> >
> > That is just how the existing I3C core enumerates targets during DAA,
> > not something added by this series. I will add a sentence to the
> > cover letter and Patch 4 commit message in v6 contrasting it with
> > i2c-dev to make that context clear.
> >
> > > Do we have such use cases IRL? Do we have tooling support (at least pending)
> > > somewhere? Why does it require user space interaction in _this_ way (meaning
> > > IOCTL and /dev node)?
> >
> > Yes, this is used in real systems today:
> >
> > 1. Tooling & production users:
> >
> > - i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
> > AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
> > years).
> >
> > - OCP Secure Firmware Recovery (DCR 0xBD) [1] and Caliptra Root-of-Trust
> > recovery agents on OpenBMC/gBMC platforms (e.g., AST2700 / Caliptra
> > MCU recovery tooling and BMC recovery daemons). Because Vitor's
> > original i3cdev series was not merged in 2019, multiple silicon
> > vendors and OpenBMC trees have been carrying out-of-tree forks of i3cdev;
> > upstreaming consolidates those diverging implementations.
> >
> > 2. Why an ioctl is required over a read and write:
> >
> > - In the OCP Secure Firmware Recovery v1.1 specification (Section
> > 8.4, "Recovery I3C Interface Block Read via Private Write and
> > Private Read"), every recovery command read is a combined transaction
> > consisting of a Private Write with no STOP, followed by a Repeated START,
> > followed by a Private Read, and finally a STOP.
> >
> > - Because write() and read() only submit a single transfer at a time
> > (nxfers = 1), the controller emits a STOP condition on the wire
> > at the end of write() and drops the bus lock. Submitting multiple
> > i3c_ioc_xfer descriptors in a single I3C_IOC_XFER(N) ioctl is
> > required so i3c_device_do_xfers() queues them together under one
> > bus lock acquisition and the controller emits a Repeated START
> > between messages (as well as passing HDR mode/cmd parameters).
> >
> > [1] https://www.opencompute.org/documents/ocp-recovery-document-1p1-final-pdf
> >
> > > So, imagine that someone submits a kernel driver for a simple device, while
> > > another person already uses the driver for multi-functional device where the
> > > former one is driving only part of it. Strictly speaking the kernel driver
> > > submission becomes a user space regression. Which effectively means that whenever
> > > you open i3cdev, no other kernel drivers may appear. Yes, I understand that
> > > a poor victim of such an unlikely course of events may recompile the kernel,
> > > disable driver, et cetera, but this still raises the same question, why do
> > > we do that to the mere users?
> >
> > Note that a user does not need to recompile the kernel if a kernel
> > driver binds to a device they wish to access via i3cdev. Because i3cdev
> > handles BUS_NOTIFY_UNBOUND_DRIVER, unbinding the kernel driver at
> > runtime via sysfs:
> >
> > echo <dev> > /sys/bus/i3c/devices/<dev>/driver/unbind
> >
> > automatically triggers i3cdev_attach() and exposes /dev/bus/i3c/<dev>
> > without rebuilding the kernel. Also, I3C drivers match against a
> > target's MIPI-assigned DCR or 48-bit PID (Manufacturer ID + Part ID),
> > so a driver for a simple device will not accidentally match a different
> > chip's PID or a dedicated DCR like 0xBD.
> >
> > > P.S> Still not convinced, that this has to be an ABI. For debugfs and something
> > > like this, no objections, but ABI.
> >
> > Production BMC recovery daemons cannot rely on debugfs, which is
> > optional and restricted or unmounted on production builds. A character
> > device in /dev/bus/i3c/* provides the stable ioctl those tools need and
> > integrates with udev so non-root daemons can be granted access to
> > specific target nodes (e.g. matching on DCR 0xBD), similar to spidev
> > and hidraw.
> >
> >
> > > Forgot to ask, but do they interfere?
> >
> > Is this in reference to i2c devices on the i3c bus? No, I3C transfers
> > and legacy
> > I2C transfers on a mixed-mode bus do not interfere:
> >
> > 1. Both i3c_device_do_xfers() and i3c_master_i2c_adapter_xfer() acquire
> > i3c_bus_normaluse_lock(&master->bus), so I3C and I2C transactions on
> > the same bus are serialized by the I3C core.
> >
> > 2. Attached I2C client addresses are marked as I3C_ADDR_SLOT_I2C_DEV in
> > the bus address slot table, preventing DAA from assigning an I2C
> > device's address to an I3C target.
>
> On my side, I believe i3cdev can be added to the kernel and that it is
> way safer than i2cdev but I agree that the ABI has to be properly
> designed, maybe we need to version it or have a way to probe for
> supported features so we can update safely later on. It is failry simple
> right now but I feel like we are going to see people with more needs
> than initiating transfers.
Yeah, I really think that i2cdev was a pure mistake (as to be an ABI).
I don't want to repeat it now, when we learnt about that case a lot.
If we ever going to have i3cdev (which justification I also put in doubts)
it needs to be very strict of what can be done and how.
> Also, I think this should not bind to any devices by default and make
> binding explicit.
Yes, this is quite dangerous "feature".
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
2026-10-21 13:03 ` Andy Shevchenko
@ 2026-10-22 20:23 ` Sam Agazaryan
-1 siblings, 0 replies; 40+ messages in thread
From: Sam Agazaryan @ 2026-10-22 20:23 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Alexandre Belloni, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
> > 1. Tooling & production users:
> >
> > - i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
> > AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
> > years).
>
> So, nothing in production, meaning we can design that in kernel differently.
In hindsight I should have ordered that list differently, the second bullet
right below that is the production use case: production BMC firmware update
and recovery daemons running in OpenBMC server fleets (managing Caliptra
Root-of-Trust and SoC recovery targets over I3C), as well as production
server accelerator management daemons.
> But why recovery mechanism can't be kernel-driven? With some sysfs
> (just as an example) knobs to say "I want to run now a recovery flow
> on this bus", et cetera.
To make sure we're talking about the same thing: "OCP Secure Firmware
Recovery" is not electrical bus recovery (like recovering an i2c or
i3c bus itself by bit-banging to unstick a hung bus). It is device
firmware recovery and provisioning (similar in concept to USB DFU) to
recover and boot a target device that sits on the bus.
This lives in userspace because it is part of the BMC's Redfish/RoT
firmware management stack (handling network image streaming, signing/key
management, and chassis-level recovery policies), rather than a single
"recover this bus" hardware toggle. And it uses I3C_IOC_XFER because
each protocol register read/write requires combined Write + Repeated
START + Read transfers (or HDR transfers) to that specific target node.
> Oh, that's quite a dangerous "feature"! Can we avoid doing that? Otherwise it
> means any missed guard against unbind for the system controller related chips
> may lead to real HW damage. I'm totally against this feature to be in any way
> of an ABI. If you want that, do it exclusively via debugfs with a big fat
> warning that this may lead to HW damages.
Agreed -- as Alexandre also suggested in his reply, it sounds like
automatic binding isn't favored here due to risk of hardware damage.
> Can i2c device require an i2c recovery flow on the bus? If so, how would
> it be combined together with the i3c recovery flow(s)?
If you mean electrical bus recovery, i3cdev doesn't perform
bus-level electrical recovery. It only submits normal target-addressed
transfers via i3c_device_do_xfers().
If you mean OCP device firmware recovery on a mixed bus:
An I2C recovery target on a mixed bus uses standard SMBus Block
Read/Write transactions through the controller's i2c_adapter (not
i3cdev) while an I3C recovery target uses I3C Private Write/Read
transfers via i3cdev. On a mixed bus, the Linux I3C core already
configures the bus mode/SCL rate according to the I2C targets' LVR
spike-filter capabilities and serializes both paths via
i3c_bus_normaluse_lock(&master->bus).
Thanks,
Sam
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-10-22 20:23 ` Sam Agazaryan
0 siblings, 0 replies; 40+ messages in thread
From: Sam Agazaryan @ 2026-10-22 20:23 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Alexandre Belloni, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
> > 1. Tooling & production users:
> >
> > - i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
> > AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
> > years).
>
> So, nothing in production, meaning we can design that in kernel differently.
In hindsight I should have ordered that list differently, the second bullet
right below that is the production use case: production BMC firmware update
and recovery daemons running in OpenBMC server fleets (managing Caliptra
Root-of-Trust and SoC recovery targets over I3C), as well as production
server accelerator management daemons.
> But why recovery mechanism can't be kernel-driven? With some sysfs
> (just as an example) knobs to say "I want to run now a recovery flow
> on this bus", et cetera.
To make sure we're talking about the same thing: "OCP Secure Firmware
Recovery" is not electrical bus recovery (like recovering an i2c or
i3c bus itself by bit-banging to unstick a hung bus). It is device
firmware recovery and provisioning (similar in concept to USB DFU) to
recover and boot a target device that sits on the bus.
This lives in userspace because it is part of the BMC's Redfish/RoT
firmware management stack (handling network image streaming, signing/key
management, and chassis-level recovery policies), rather than a single
"recover this bus" hardware toggle. And it uses I3C_IOC_XFER because
each protocol register read/write requires combined Write + Repeated
START + Read transfers (or HDR transfers) to that specific target node.
> Oh, that's quite a dangerous "feature"! Can we avoid doing that? Otherwise it
> means any missed guard against unbind for the system controller related chips
> may lead to real HW damage. I'm totally against this feature to be in any way
> of an ABI. If you want that, do it exclusively via debugfs with a big fat
> warning that this may lead to HW damages.
Agreed -- as Alexandre also suggested in his reply, it sounds like
automatic binding isn't favored here due to risk of hardware damage.
> Can i2c device require an i2c recovery flow on the bus? If so, how would
> it be combined together with the i3c recovery flow(s)?
If you mean electrical bus recovery, i3cdev doesn't perform
bus-level electrical recovery. It only submits normal target-addressed
transfers via i3c_device_do_xfers().
If you mean OCP device firmware recovery on a mixed bus:
An I2C recovery target on a mixed bus uses standard SMBus Block
Read/Write transactions through the controller's i2c_adapter (not
i3cdev) while an I3C recovery target uses I3C Private Write/Read
transfers via i3cdev. On a mixed bus, the Linux I3C core already
configures the bus mode/SCL rate according to the I2C targets' LVR
spike-filter capabilities and serializes both paths via
i3c_bus_normaluse_lock(&master->bus).
Thanks,
Sam
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
2026-10-22 20:23 ` Sam Agazaryan
@ 2026-10-26 10:55 ` Andy Shevchenko
-1 siblings, 0 replies; 40+ messages in thread
From: Andy Shevchenko @ 2026-10-26 10:55 UTC (permalink / raw)
To: Sam Agazaryan
Cc: Alexandre Belloni, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On Thu, Oct 22, 2026 at 01:23:10PM -0700, Sam Agazaryan wrote:
> > > 1. Tooling & production users:
> > >
> > > - i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
> > > AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
> > > years).
> >
> > So, nothing in production, meaning we can design that in kernel differently.
>
> In hindsight I should have ordered that list differently, the second bullet
> right below that is the production use case: production BMC firmware update
> and recovery daemons running in OpenBMC server fleets (managing Caliptra
> Root-of-Trust and SoC recovery targets over I3C), as well as production
> server accelerator management daemons.
Okay, but they are not (obviously) use the upstream solutions for that.
> > But why recovery mechanism can't be kernel-driven? With some sysfs
> > (just as an example) knobs to say "I want to run now a recovery flow
> > on this bus", et cetera.
>
> To make sure we're talking about the same thing: "OCP Secure Firmware
> Recovery" is not electrical bus recovery (like recovering an i2c or
> i3c bus itself by bit-banging to unstick a hung bus). It is device
> firmware recovery and provisioning (similar in concept to USB DFU) to
> recover and boot a target device that sits on the bus.
A-ha, so this is a device programming protocol on the top of the i3c bus.
> This lives in userspace because it is part of the BMC's Redfish/RoT
> firmware management stack (handling network image streaming, signing/key
> management, and chassis-level recovery policies), rather than a single
> "recover this bus" hardware toggle. And it uses I3C_IOC_XFER because
> each protocol register read/write requires combined Write + Repeated
> START + Read transfers (or HDR transfers) to that specific target node.
But it's still unclear to me why this can't be moved to the kernel space?
There is no user space that communicates with upstream kernel in the way
you described, they should have used a custom (out-of-tree) solutions, right?
> > Oh, that's quite a dangerous "feature"! Can we avoid doing that? Otherwise it
> > means any missed guard against unbind for the system controller related chips
> > may lead to real HW damage. I'm totally against this feature to be in any way
> > of an ABI. If you want that, do it exclusively via debugfs with a big fat
> > warning that this may lead to HW damages.
>
> Agreed -- as Alexandre also suggested in his reply, it sounds like
> automatic binding isn't favored here due to risk of hardware damage.
>
> > Can i2c device require an i2c recovery flow on the bus? If so, how would
> > it be combined together with the i3c recovery flow(s)?
>
> If you mean electrical bus recovery, i3cdev doesn't perform
> bus-level electrical recovery. It only submits normal target-addressed
> transfers via i3c_device_do_xfers().
But how it will do if the i2c device blocks the i3c bus in mixed mode?
I mean, how will it affect the i3c transfers on the wire?
> If you mean OCP device firmware recovery on a mixed bus:
>
> An I2C recovery target on a mixed bus uses standard SMBus Block
> Read/Write transactions through the controller's i2c_adapter (not
> i3cdev) while an I3C recovery target uses I3C Private Write/Read
> transfers via i3cdev. On a mixed bus, the Linux I3C core already
> configures the bus mode/SCL rate according to the I2C targets' LVR
> spike-filter capabilities and serializes both paths via
> i3c_bus_normaluse_lock(&master->bus).
Good to know, thanks!
--
With Best Regards,
Andy Shevchenko
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-10-26 10:55 ` Andy Shevchenko
0 siblings, 0 replies; 40+ messages in thread
From: Andy Shevchenko @ 2026-10-26 10:55 UTC (permalink / raw)
To: Sam Agazaryan
Cc: Alexandre Belloni, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On Thu, Oct 22, 2026 at 01:23:10PM -0700, Sam Agazaryan wrote:
> > > 1. Tooling & production users:
> > >
> > > - i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
> > > AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
> > > years).
> >
> > So, nothing in production, meaning we can design that in kernel differently.
>
> In hindsight I should have ordered that list differently, the second bullet
> right below that is the production use case: production BMC firmware update
> and recovery daemons running in OpenBMC server fleets (managing Caliptra
> Root-of-Trust and SoC recovery targets over I3C), as well as production
> server accelerator management daemons.
Okay, but they are not (obviously) use the upstream solutions for that.
> > But why recovery mechanism can't be kernel-driven? With some sysfs
> > (just as an example) knobs to say "I want to run now a recovery flow
> > on this bus", et cetera.
>
> To make sure we're talking about the same thing: "OCP Secure Firmware
> Recovery" is not electrical bus recovery (like recovering an i2c or
> i3c bus itself by bit-banging to unstick a hung bus). It is device
> firmware recovery and provisioning (similar in concept to USB DFU) to
> recover and boot a target device that sits on the bus.
A-ha, so this is a device programming protocol on the top of the i3c bus.
> This lives in userspace because it is part of the BMC's Redfish/RoT
> firmware management stack (handling network image streaming, signing/key
> management, and chassis-level recovery policies), rather than a single
> "recover this bus" hardware toggle. And it uses I3C_IOC_XFER because
> each protocol register read/write requires combined Write + Repeated
> START + Read transfers (or HDR transfers) to that specific target node.
But it's still unclear to me why this can't be moved to the kernel space?
There is no user space that communicates with upstream kernel in the way
you described, they should have used a custom (out-of-tree) solutions, right?
> > Oh, that's quite a dangerous "feature"! Can we avoid doing that? Otherwise it
> > means any missed guard against unbind for the system controller related chips
> > may lead to real HW damage. I'm totally against this feature to be in any way
> > of an ABI. If you want that, do it exclusively via debugfs with a big fat
> > warning that this may lead to HW damages.
>
> Agreed -- as Alexandre also suggested in his reply, it sounds like
> automatic binding isn't favored here due to risk of hardware damage.
>
> > Can i2c device require an i2c recovery flow on the bus? If so, how would
> > it be combined together with the i3c recovery flow(s)?
>
> If you mean electrical bus recovery, i3cdev doesn't perform
> bus-level electrical recovery. It only submits normal target-addressed
> transfers via i3c_device_do_xfers().
But how it will do if the i2c device blocks the i3c bus in mixed mode?
I mean, how will it affect the i3c transfers on the wire?
> If you mean OCP device firmware recovery on a mixed bus:
>
> An I2C recovery target on a mixed bus uses standard SMBus Block
> Read/Write transactions through the controller's i2c_adapter (not
> i3cdev) while an I3C recovery target uses I3C Private Write/Read
> transfers via i3cdev. On a mixed bus, the Linux I3C core already
> configures the bus mode/SCL rate according to the I2C targets' LVR
> spike-filter capabilities and serializes both paths via
> i3c_bus_normaluse_lock(&master->bus).
Good to know, thanks!
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
2026-10-26 10:55 ` Andy Shevchenko
@ 2026-11-09 6:11 ` Sam Agazaryan
-1 siblings, 0 replies; 40+ messages in thread
From: Sam Agazaryan @ 2026-11-09 6:11 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Alexandre Belloni, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
> > [...] production BMC firmware update
> > and recovery daemons running in OpenBMC server fleets (managing Caliptra
> > Root-of-Trust and SoC recovery targets over I3C), as well as production
> > server accelerator management daemons.
>
> Okay, but they are not (obviously) use the upstream solutions for that.
Right, they run on vendor kernels carrying out-of-tree i3cdev patches
based on an earlier version of this series, so there is no upstream ABI
to stay compatible with. This series already departs from that ABI
and v6 will change it further based on the review in this thread.
> But it's still unclear to me why this can't be moved to the kernel space?
> There is no user space that communicates with upstream kernel in the way
> you described, they should have used a custom (out-of-tree) solutions, right?
It could be, and the closest in kernel fit would be an OCP recovery
i3c_driver exposing fw_upload. But pushing an image is only one part of
the spec, and an in kernel driver would have to cover all of it, not
just the subset one recovery agent happens to use:
- status and identity: PROT_CAP, DEVICE_ID, DEVICE_STATUS (with
recovery reason codes), RECOVERY_STATUS and HW_STATUS
- reset and boot control: DEVICE_RESET with forced recovery and
flashless boot, and multi-stage activation through RECOVERY_CTRL
- memory spaces: code, critical logging and vendor-defined CMS
regions, through either the indirect window or the FIFO interface
- the VENDOR command and vendor-specific status, which differ per
SoC vendor
Which of these an agent uses, when to trigger recovery, and which image
goes with each stage all vary by platform, and the BMC's userspace
already makes those decisions.
An in-kernel driver would need new sysfs ABI for this, and that ABI
would have to grow as the spec evolves: v1.1 alone added multi-stage
activation, flashless boot and the indirect FIFO interface. With a
target-scoped transfer interface, none of that needs kernel changes.
fw_upload and lib/pldmfw fit well where a kernel driver already owns
the device; here the only consumer is the BMC's management stack.
The kernel already splits things this way on I3C for MCTP: mctp-i3c
binds by DCR and provides the transport, while PLDM firmware update
runs in userspace. i3cdev could be made to bind the same way, by the
OCP recovery DCR, instead of binding to every unbound target. Outside
I3C it is the same pattern: nvme-cli does NVMe firmware download/commit
through the passthrough ioctls, and fwupd updates devices over hidraw,
usbfs and drm_dp_aux_dev.
So the kernel side stays a small mechanism consisting of target-scoped
transfers to explicitly bound devices, and the recovery policy stays
in userspace, where it can follow new spec revisions without new kernel
ABI.
> > If you mean electrical bus recovery, i3cdev doesn't perform
> > bus-level electrical recovery. It only submits normal target-addressed
> > transfers via i3c_device_do_xfers().
>
> But how it will do if the i2c device blocks the i3c bus in mixed mode?
> I mean, how will it affect the i3c transfers on the wire?
Electrically speaking, SDA and SCL are shared, so an I2C target that
holds SDA low blocks every transfer on that bus, I3C and I2C alike,
regardless of which driver issued it. The controller reports the failure
as a NACK, arbitration loss or timeout, depending on the controller.
i3c_device_do_xfers() returns the error, and i3cdev passes it back to
userspace from the ioctl.
So i3cdev behaves the same as any in kernel I3C driver on that bus
since it uses the same transfer path. Getting a stuck bus released is
up to the controller driver rather than i3cdev. For what it's worth,
section 8.4.1 of the OCP recovery spec recommends a pure I3C bus for
critical recovery paths, and for mixed buses requires validating that
I2C targets have spike filters and considering isolating or
disabling the ones that can't. I2C devices on a mixed bus are also not
allowed to stretch the clock.
> > On a mixed bus, the Linux I3C core already
> > configures the bus mode/SCL rate according to the I2C targets' LVR
> > spike-filter capabilities and serializes both paths via
> > i3c_bus_normaluse_lock(&master->bus).
>
> Good to know, thanks!
One correction to my previous statements: i3c_bus_normaluse_lock() is
a shared lock that only excludes maintenance operations such as DAA.
The I2C and I3C transfers themselves are serialized by the master
driver's own locking, which is what keeps them from being interleaved
on the wire.
Thanks,
Sam
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-11-09 6:11 ` Sam Agazaryan
0 siblings, 0 replies; 40+ messages in thread
From: Sam Agazaryan @ 2026-11-09 6:11 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Alexandre Belloni, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
> > [...] production BMC firmware update
> > and recovery daemons running in OpenBMC server fleets (managing Caliptra
> > Root-of-Trust and SoC recovery targets over I3C), as well as production
> > server accelerator management daemons.
>
> Okay, but they are not (obviously) use the upstream solutions for that.
Right, they run on vendor kernels carrying out-of-tree i3cdev patches
based on an earlier version of this series, so there is no upstream ABI
to stay compatible with. This series already departs from that ABI
and v6 will change it further based on the review in this thread.
> But it's still unclear to me why this can't be moved to the kernel space?
> There is no user space that communicates with upstream kernel in the way
> you described, they should have used a custom (out-of-tree) solutions, right?
It could be, and the closest in kernel fit would be an OCP recovery
i3c_driver exposing fw_upload. But pushing an image is only one part of
the spec, and an in kernel driver would have to cover all of it, not
just the subset one recovery agent happens to use:
- status and identity: PROT_CAP, DEVICE_ID, DEVICE_STATUS (with
recovery reason codes), RECOVERY_STATUS and HW_STATUS
- reset and boot control: DEVICE_RESET with forced recovery and
flashless boot, and multi-stage activation through RECOVERY_CTRL
- memory spaces: code, critical logging and vendor-defined CMS
regions, through either the indirect window or the FIFO interface
- the VENDOR command and vendor-specific status, which differ per
SoC vendor
Which of these an agent uses, when to trigger recovery, and which image
goes with each stage all vary by platform, and the BMC's userspace
already makes those decisions.
An in-kernel driver would need new sysfs ABI for this, and that ABI
would have to grow as the spec evolves: v1.1 alone added multi-stage
activation, flashless boot and the indirect FIFO interface. With a
target-scoped transfer interface, none of that needs kernel changes.
fw_upload and lib/pldmfw fit well where a kernel driver already owns
the device; here the only consumer is the BMC's management stack.
The kernel already splits things this way on I3C for MCTP: mctp-i3c
binds by DCR and provides the transport, while PLDM firmware update
runs in userspace. i3cdev could be made to bind the same way, by the
OCP recovery DCR, instead of binding to every unbound target. Outside
I3C it is the same pattern: nvme-cli does NVMe firmware download/commit
through the passthrough ioctls, and fwupd updates devices over hidraw,
usbfs and drm_dp_aux_dev.
So the kernel side stays a small mechanism consisting of target-scoped
transfers to explicitly bound devices, and the recovery policy stays
in userspace, where it can follow new spec revisions without new kernel
ABI.
> > If you mean electrical bus recovery, i3cdev doesn't perform
> > bus-level electrical recovery. It only submits normal target-addressed
> > transfers via i3c_device_do_xfers().
>
> But how it will do if the i2c device blocks the i3c bus in mixed mode?
> I mean, how will it affect the i3c transfers on the wire?
Electrically speaking, SDA and SCL are shared, so an I2C target that
holds SDA low blocks every transfer on that bus, I3C and I2C alike,
regardless of which driver issued it. The controller reports the failure
as a NACK, arbitration loss or timeout, depending on the controller.
i3c_device_do_xfers() returns the error, and i3cdev passes it back to
userspace from the ioctl.
So i3cdev behaves the same as any in kernel I3C driver on that bus
since it uses the same transfer path. Getting a stuck bus released is
up to the controller driver rather than i3cdev. For what it's worth,
section 8.4.1 of the OCP recovery spec recommends a pure I3C bus for
critical recovery paths, and for mixed buses requires validating that
I2C targets have spike filters and considering isolating or
disabling the ones that can't. I2C devices on a mixed bus are also not
allowed to stretch the clock.
> > On a mixed bus, the Linux I3C core already
> > configures the bus mode/SCL rate according to the I2C targets' LVR
> > spike-filter capabilities and serializes both paths via
> > i3c_bus_normaluse_lock(&master->bus).
>
> Good to know, thanks!
One correction to my previous statements: i3c_bus_normaluse_lock() is
a shared lock that only excludes maintenance operations such as DAA.
The I2C and I3C transfers themselves are serialized by the master
driver's own locking, which is what keeps them from being interleaved
on the wire.
Thanks,
Sam
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
2026-11-09 6:11 ` Sam Agazaryan
@ 2026-11-09 21:49 ` Andy Shevchenko
-1 siblings, 0 replies; 40+ messages in thread
From: Andy Shevchenko @ 2026-11-09 21:49 UTC (permalink / raw)
To: Sam Agazaryan
Cc: Alexandre Belloni, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On Sun, Nov 08, 2026 at 10:11:52PM -0800, Sam Agazaryan wrote:
[...]
> > > production BMC firmware update and recovery daemons running in OpenBMC
> > > server fleets (managing Caliptra Root-of-Trust and SoC recovery targets
> > > over I3C), as well as production server accelerator management daemons.
> >
> > Okay, but they are not (obviously) use the upstream solutions for that.
>
> Right, they run on vendor kernels carrying out-of-tree i3cdev patches
> based on an earlier version of this series, so there is no upstream ABI
> to stay compatible with. This series already departs from that ABI
> and v6 will change it further based on the review in this thread.
>
> > But it's still unclear to me why this can't be moved to the kernel space?
> > There is no user space that communicates with upstream kernel in the way
> > you described, they should have used a custom (out-of-tree) solutions, right?
>
> It could be, and the closest in kernel fit would be an OCP recovery
> i3c_driver exposing fw_upload. But pushing an image is only one part of
> the spec, and an in kernel driver would have to cover all of it, not
> just the subset one recovery agent happens to use:
>
> - status and identity: PROT_CAP, DEVICE_ID, DEVICE_STATUS (with
> recovery reason codes), RECOVERY_STATUS and HW_STATUS
> - reset and boot control: DEVICE_RESET with forced recovery and
> flashless boot, and multi-stage activation through RECOVERY_CTRL
> - memory spaces: code, critical logging and vendor-defined CMS
> regions, through either the indirect window or the FIFO interface
> - the VENDOR command and vendor-specific status, which differ per
> SoC vendor
Good. We can see that being implemented step-by-step.
> Which of these an agent uses, when to trigger recovery, and which image
> goes with each stage all vary by platform, and the BMC's userspace
> already makes those decisions.
Based on the absence of any interface in the kernel before, there is no chance
to regress anything. It might be just a good will to try hard to support
existing out-of-tree solutions.
> An in-kernel driver would need new sysfs ABI for this, and that ABI
> would have to grow as the spec evolves: v1.1 alone added multi-stage
> activation, flashless boot and the indirect FIFO interface. With a
> target-scoped transfer interface, none of that needs kernel changes.
> fw_upload and lib/pldmfw fit well where a kernel driver already owns
> the device; here the only consumer is the BMC's management stack.
Yes, and I see no issues with that. Opening the whole i3cdev just for the same
reason sounds like an overkill. Especially if we do *not* expect any more users.
> The kernel already splits things this way on I3C for MCTP: mctp-i3c
> binds by DCR and provides the transport, while PLDM firmware update
> runs in userspace. i3cdev could be made to bind the same way, by the
> OCP recovery DCR, instead of binding to every unbound target. Outside
> I3C it is the same pattern: nvme-cli does NVMe firmware download/commit
> through the passthrough ioctls, and fwupd updates devices over hidraw,
> usbfs and drm_dp_aux_dev.
>
> So the kernel side stays a small mechanism consisting of target-scoped
> transfers to explicitly bound devices, and the recovery policy stays
> in userspace, where it can follow new spec revisions without new kernel
> ABI.
If there are success stories, those examples might help to justify your
approach. It makes sense to mention that in the cover letter with the
summary on their designs (and split).
> > > If you mean electrical bus recovery, i3cdev doesn't perform
> > > bus-level electrical recovery. It only submits normal target-addressed
> > > transfers via i3c_device_do_xfers().
> >
> > But how it will do if the i2c device blocks the i3c bus in mixed mode?
> > I mean, how will it affect the i3c transfers on the wire?
>
> Electrically speaking, SDA and SCL are shared, so an I2C target that
> holds SDA low blocks every transfer on that bus, I3C and I2C alike,
> regardless of which driver issued it. The controller reports the failure
> as a NACK, arbitration loss or timeout, depending on the controller.
> i3c_device_do_xfers() returns the error, and i3cdev passes it back to
> userspace from the ioctl.
>
> So i3cdev behaves the same as any in kernel I3C driver on that bus
> since it uses the same transfer path. Getting a stuck bus released is
> up to the controller driver rather than i3cdev. For what it's worth,
> section 8.4.1 of the OCP recovery spec recommends a pure I3C bus for
> critical recovery paths, and for mixed buses requires validating that
> I2C targets have spike filters and considering isolating or
> disabling the ones that can't. I2C devices on a mixed bus are also not
> allowed to stretch the clock.
--
With Best Regards,
Andy Shevchenko
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-11-09 21:49 ` Andy Shevchenko
0 siblings, 0 replies; 40+ messages in thread
From: Andy Shevchenko @ 2026-11-09 21:49 UTC (permalink / raw)
To: Sam Agazaryan
Cc: Alexandre Belloni, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On Sun, Nov 08, 2026 at 10:11:52PM -0800, Sam Agazaryan wrote:
[...]
> > > production BMC firmware update and recovery daemons running in OpenBMC
> > > server fleets (managing Caliptra Root-of-Trust and SoC recovery targets
> > > over I3C), as well as production server accelerator management daemons.
> >
> > Okay, but they are not (obviously) use the upstream solutions for that.
>
> Right, they run on vendor kernels carrying out-of-tree i3cdev patches
> based on an earlier version of this series, so there is no upstream ABI
> to stay compatible with. This series already departs from that ABI
> and v6 will change it further based on the review in this thread.
>
> > But it's still unclear to me why this can't be moved to the kernel space?
> > There is no user space that communicates with upstream kernel in the way
> > you described, they should have used a custom (out-of-tree) solutions, right?
>
> It could be, and the closest in kernel fit would be an OCP recovery
> i3c_driver exposing fw_upload. But pushing an image is only one part of
> the spec, and an in kernel driver would have to cover all of it, not
> just the subset one recovery agent happens to use:
>
> - status and identity: PROT_CAP, DEVICE_ID, DEVICE_STATUS (with
> recovery reason codes), RECOVERY_STATUS and HW_STATUS
> - reset and boot control: DEVICE_RESET with forced recovery and
> flashless boot, and multi-stage activation through RECOVERY_CTRL
> - memory spaces: code, critical logging and vendor-defined CMS
> regions, through either the indirect window or the FIFO interface
> - the VENDOR command and vendor-specific status, which differ per
> SoC vendor
Good. We can see that being implemented step-by-step.
> Which of these an agent uses, when to trigger recovery, and which image
> goes with each stage all vary by platform, and the BMC's userspace
> already makes those decisions.
Based on the absence of any interface in the kernel before, there is no chance
to regress anything. It might be just a good will to try hard to support
existing out-of-tree solutions.
> An in-kernel driver would need new sysfs ABI for this, and that ABI
> would have to grow as the spec evolves: v1.1 alone added multi-stage
> activation, flashless boot and the indirect FIFO interface. With a
> target-scoped transfer interface, none of that needs kernel changes.
> fw_upload and lib/pldmfw fit well where a kernel driver already owns
> the device; here the only consumer is the BMC's management stack.
Yes, and I see no issues with that. Opening the whole i3cdev just for the same
reason sounds like an overkill. Especially if we do *not* expect any more users.
> The kernel already splits things this way on I3C for MCTP: mctp-i3c
> binds by DCR and provides the transport, while PLDM firmware update
> runs in userspace. i3cdev could be made to bind the same way, by the
> OCP recovery DCR, instead of binding to every unbound target. Outside
> I3C it is the same pattern: nvme-cli does NVMe firmware download/commit
> through the passthrough ioctls, and fwupd updates devices over hidraw,
> usbfs and drm_dp_aux_dev.
>
> So the kernel side stays a small mechanism consisting of target-scoped
> transfers to explicitly bound devices, and the recovery policy stays
> in userspace, where it can follow new spec revisions without new kernel
> ABI.
If there are success stories, those examples might help to justify your
approach. It makes sense to mention that in the cover letter with the
summary on their designs (and split).
> > > If you mean electrical bus recovery, i3cdev doesn't perform
> > > bus-level electrical recovery. It only submits normal target-addressed
> > > transfers via i3c_device_do_xfers().
> >
> > But how it will do if the i2c device blocks the i3c bus in mixed mode?
> > I mean, how will it affect the i3c transfers on the wire?
>
> Electrically speaking, SDA and SCL are shared, so an I2C target that
> holds SDA low blocks every transfer on that bus, I3C and I2C alike,
> regardless of which driver issued it. The controller reports the failure
> as a NACK, arbitration loss or timeout, depending on the controller.
> i3c_device_do_xfers() returns the error, and i3cdev passes it back to
> userspace from the ioctl.
>
> So i3cdev behaves the same as any in kernel I3C driver on that bus
> since it uses the same transfer path. Getting a stuck bus released is
> up to the controller driver rather than i3cdev. For what it's worth,
> section 8.4.1 of the OCP recovery spec recommends a pure I3C bus for
> critical recovery paths, and for mixed buses requires validating that
> I2C targets have spike filters and considering isolating or
> disabling the ones that can't. I2C devices on a mixed bus are also not
> allowed to stretch the clock.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
2026-11-09 21:49 ` Andy Shevchenko
@ 2026-11-11 5:20 ` Sam Agazaryan
-1 siblings, 0 replies; 40+ messages in thread
From: Sam Agazaryan @ 2026-11-11 5:20 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Alexandre Belloni, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
> > An in-kernel driver would need new sysfs ABI for this, and that ABI
> > would have to grow as the spec evolves: v1.1 alone added multi-stage
> > activation, flashless boot and the indirect FIFO interface. With a
> > target-scoped transfer interface, none of that needs kernel changes.
> > fw_upload and lib/pldmfw fit well where a kernel driver already owns
> > the device; here the only consumer is the BMC's management stack.
>
> Yes, and I see no issues with that. Opening the whole i3cdev just for the same
> reason sounds like an overkill. Especially if we do *not* expect any more users.
OCP recovery isn't the only user. In her thread, Meagan described a
separate one [1]: accelerator cards that plug into different server
SKUs, where the I3C hubs and devices on the bus can differ per SKU, so
the hub setup has to be discovered and programmed from userspace at
runtime instead of being fixed in devicetree. She posted her own i3cdev
series and can speak to the details better than I can.
Also, with the explicit binding planned for v6, i3cdev would not open
the whole bus. It would only bind device classes listed in its ID
table, starting with the OCP recovery DCR, and any other class would
have to be added there deliberately, with its own justification.
> If there are success stories, those examples might help to justify your
> approach. It makes sense to mention that in the cover letter with the
> summary on their designs (and split).
Will do. I'll summarize in the v6 cover letter.
[1] https://lore.kernel.org/linux-i3c/20260924-86692413bdae0e78a12c1425@linux.microsoft.com/
Thanks,
Sam
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-11-11 5:20 ` Sam Agazaryan
0 siblings, 0 replies; 40+ messages in thread
From: Sam Agazaryan @ 2026-11-11 5:20 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Alexandre Belloni, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
> > An in-kernel driver would need new sysfs ABI for this, and that ABI
> > would have to grow as the spec evolves: v1.1 alone added multi-stage
> > activation, flashless boot and the indirect FIFO interface. With a
> > target-scoped transfer interface, none of that needs kernel changes.
> > fw_upload and lib/pldmfw fit well where a kernel driver already owns
> > the device; here the only consumer is the BMC's management stack.
>
> Yes, and I see no issues with that. Opening the whole i3cdev just for the same
> reason sounds like an overkill. Especially if we do *not* expect any more users.
OCP recovery isn't the only user. In her thread, Meagan described a
separate one [1]: accelerator cards that plug into different server
SKUs, where the I3C hubs and devices on the bus can differ per SKU, so
the hub setup has to be discovered and programmed from userspace at
runtime instead of being fixed in devicetree. She posted her own i3cdev
series and can speak to the details better than I can.
Also, with the explicit binding planned for v6, i3cdev would not open
the whole bus. It would only bind device classes listed in its ID
table, starting with the OCP recovery DCR, and any other class would
have to be added there deliberately, with its own justification.
> If there are success stories, those examples might help to justify your
> approach. It makes sense to mention that in the cover letter with the
> summary on their designs (and split).
Will do. I'll summarize in the v6 cover letter.
[1] https://lore.kernel.org/linux-i3c/20260924-86692413bdae0e78a12c1425@linux.microsoft.com/
Thanks,
Sam
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
2026-10-21 9:57 ` Alexandre Belloni
@ 2026-10-23 0:17 ` Sam Agazaryan
-1 siblings, 0 replies; 40+ messages in thread
From: Sam Agazaryan @ 2026-10-23 0:17 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Andy Shevchenko, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
> On my side, I believe i3cdev can be added to the kernel and that it is
> way safer than i2cdev but I agree that the ABI has to be properly
> designed, maybe we need to version it or have a way to probe for
> supported features so we can update safely later on. It is failry simple
> right now but I feel like we are going to see people with more needs
> than initiating transfers.
For feature probing and ABI extension, what do you think of:
1. Adding an extensible I3C_IOC_GET_CAPS ioctl:
struct i3c_ioc_caps {
__u32 size; /* sizeof(struct i3c_ioc_caps) */
__u32 pad; /* must be 0 */
__u64 caps; /* Bitmask of supported I3C_CAP_* features */
};
Today caps can report the transfer modes supported by the controller
and target (I3C_CAP_SDR, I3C_CAP_HDR_DDR, I3C_CAP_HDR_TSP,
I3C_CAP_HDR_TSL), and new bits in caps (or new fields appended to
the end of the struct) can advertise future capabilities beyond basic
transfers.
2. In struct i3c_ioc_xfer, we already have __u8 pad[2] at the end which
is strictly checked to be 0 (-EINVAL if non-zero), reserving 16 bits
for future per-transfer flags without changing the struct size.
> Also, I think this should not bind to any devices by default and make
> binding explicit.
This seems to be the consensus so far. I can convert i3cdev from a bus
notifier into a standard struct i3c_driver so it does not auto-attach
to all unbound targets on boot or on unbind while dropping patches 1
and 2.
Since Greg KH noted earlier [1] that driver_override / manual sysfs
bind is only for debugging and will taint the kernel in the near
future, what do you think of:
Matching explicit opt-in entries in i3cdev's i3c_device_id table (starting
with 0xBD for OCP Secure Firmware Recovery), and optionally
exposing a new_id sysfs attribute on the i3cdev driver for dynamically
adding target IDs at runtime? That also keeps everything self-contained
in i3cdev without needing cross-subsystem changes to hwmon/iio drivers.
[1] https://lore.kernel.org/linux-i3c/2026091834-bats-palpitate-5614@gregkh/
Thanks,
Sam
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 40+ messages in thread* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-10-23 0:17 ` Sam Agazaryan
0 siblings, 0 replies; 40+ messages in thread
From: Sam Agazaryan @ 2026-10-23 0:17 UTC (permalink / raw)
To: Alexandre Belloni
Cc: Andy Shevchenko, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
> On my side, I believe i3cdev can be added to the kernel and that it is
> way safer than i2cdev but I agree that the ABI has to be properly
> designed, maybe we need to version it or have a way to probe for
> supported features so we can update safely later on. It is failry simple
> right now but I feel like we are going to see people with more needs
> than initiating transfers.
For feature probing and ABI extension, what do you think of:
1. Adding an extensible I3C_IOC_GET_CAPS ioctl:
struct i3c_ioc_caps {
__u32 size; /* sizeof(struct i3c_ioc_caps) */
__u32 pad; /* must be 0 */
__u64 caps; /* Bitmask of supported I3C_CAP_* features */
};
Today caps can report the transfer modes supported by the controller
and target (I3C_CAP_SDR, I3C_CAP_HDR_DDR, I3C_CAP_HDR_TSP,
I3C_CAP_HDR_TSL), and new bits in caps (or new fields appended to
the end of the struct) can advertise future capabilities beyond basic
transfers.
2. In struct i3c_ioc_xfer, we already have __u8 pad[2] at the end which
is strictly checked to be 0 (-EINVAL if non-zero), reserving 16 bits
for future per-transfer flags without changing the struct size.
> Also, I think this should not bind to any devices by default and make
> binding explicit.
This seems to be the consensus so far. I can convert i3cdev from a bus
notifier into a standard struct i3c_driver so it does not auto-attach
to all unbound targets on boot or on unbind while dropping patches 1
and 2.
Since Greg KH noted earlier [1] that driver_override / manual sysfs
bind is only for debugging and will taint the kernel in the near
future, what do you think of:
Matching explicit opt-in entries in i3cdev's i3c_device_id table (starting
with 0xBD for OCP Secure Firmware Recovery), and optionally
exposing a new_id sysfs attribute on the i3cdev driver for dynamically
adding target IDs at runtime? That also keeps everything self-contained
in i3cdev without needing cross-subsystem changes to hwmon/iio drivers.
[1] https://lore.kernel.org/linux-i3c/2026091834-bats-palpitate-5614@gregkh/
Thanks,
Sam
^ permalink raw reply [flat|nested] 40+ messages in thread* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
2026-10-23 0:17 ` Sam Agazaryan
@ 2026-11-12 9:41 ` Alexandre Belloni
-1 siblings, 0 replies; 40+ messages in thread
From: Alexandre Belloni @ 2026-11-12 9:41 UTC (permalink / raw)
To: Sam Agazaryan
Cc: Andy Shevchenko, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On 22/10/2026 17:17:20-0700, Sam Agazaryan wrote:
> > On my side, I believe i3cdev can be added to the kernel and that it is
> > way safer than i2cdev but I agree that the ABI has to be properly
> > designed, maybe we need to version it or have a way to probe for
> > supported features so we can update safely later on. It is failry simple
> > right now but I feel like we are going to see people with more needs
> > than initiating transfers.
>
> For feature probing and ABI extension, what do you think of:
>
> 1. Adding an extensible I3C_IOC_GET_CAPS ioctl:
>
> struct i3c_ioc_caps {
> __u32 size; /* sizeof(struct i3c_ioc_caps) */
> __u32 pad; /* must be 0 */
> __u64 caps; /* Bitmask of supported I3C_CAP_* features */
> };
>
> Today caps can report the transfer modes supported by the controller
> and target (I3C_CAP_SDR, I3C_CAP_HDR_DDR, I3C_CAP_HDR_TSP,
> I3C_CAP_HDR_TSL), and new bits in caps (or new fields appended to
> the end of the struct) can advertise future capabilities beyond basic
> transfers.
This works but my point was also that we need to expose the i3cdev
capabilities so userspace can discover what is available. I guess we can
assume .read and .write are going to always be available and so this is
fine for now.
>
> 2. In struct i3c_ioc_xfer, we already have __u8 pad[2] at the end which
> is strictly checked to be 0 (-EINVAL if non-zero), reserving 16 bits
> for future per-transfer flags without changing the struct size.
>
> > Also, I think this should not bind to any devices by default and make
> > binding explicit.
>
> This seems to be the consensus so far. I can convert i3cdev from a bus
> notifier into a standard struct i3c_driver so it does not auto-attach
> to all unbound targets on boot or on unbind while dropping patches 1
> and 2.
>
> Since Greg KH noted earlier [1] that driver_override / manual sysfs
> bind is only for debugging and will taint the kernel in the near
> future, what do you think of:
>
> Matching explicit opt-in entries in i3cdev's i3c_device_id table (starting
> with 0xBD for OCP Secure Firmware Recovery), and optionally
> exposing a new_id sysfs attribute on the i3cdev driver for dynamically
> adding target IDs at runtime? That also keeps everything self-contained
> in i3cdev without needing cross-subsystem changes to hwmon/iio drivers.
>
We can add new_id later if necessary.
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 40+ messages in thread* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-11-12 9:41 ` Alexandre Belloni
0 siblings, 0 replies; 40+ messages in thread
From: Alexandre Belloni @ 2026-11-12 9:41 UTC (permalink / raw)
To: Sam Agazaryan
Cc: Andy Shevchenko, Wolfram Sang, linux-i3c, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On 22/10/2026 17:17:20-0700, Sam Agazaryan wrote:
> > On my side, I believe i3cdev can be added to the kernel and that it is
> > way safer than i2cdev but I agree that the ABI has to be properly
> > designed, maybe we need to version it or have a way to probe for
> > supported features so we can update safely later on. It is failry simple
> > right now but I feel like we are going to see people with more needs
> > than initiating transfers.
>
> For feature probing and ABI extension, what do you think of:
>
> 1. Adding an extensible I3C_IOC_GET_CAPS ioctl:
>
> struct i3c_ioc_caps {
> __u32 size; /* sizeof(struct i3c_ioc_caps) */
> __u32 pad; /* must be 0 */
> __u64 caps; /* Bitmask of supported I3C_CAP_* features */
> };
>
> Today caps can report the transfer modes supported by the controller
> and target (I3C_CAP_SDR, I3C_CAP_HDR_DDR, I3C_CAP_HDR_TSP,
> I3C_CAP_HDR_TSL), and new bits in caps (or new fields appended to
> the end of the struct) can advertise future capabilities beyond basic
> transfers.
This works but my point was also that we need to expose the i3cdev
capabilities so userspace can discover what is available. I guess we can
assume .read and .write are going to always be available and so this is
fine for now.
>
> 2. In struct i3c_ioc_xfer, we already have __u8 pad[2] at the end which
> is strictly checked to be 0 (-EINVAL if non-zero), reserving 16 bits
> for future per-transfer flags without changing the struct size.
>
> > Also, I think this should not bind to any devices by default and make
> > binding explicit.
>
> This seems to be the consensus so far. I can convert i3cdev from a bus
> notifier into a standard struct i3c_driver so it does not auto-attach
> to all unbound targets on boot or on unbind while dropping patches 1
> and 2.
>
> Since Greg KH noted earlier [1] that driver_override / manual sysfs
> bind is only for debugging and will taint the kernel in the near
> future, what do you think of:
>
> Matching explicit opt-in entries in i3cdev's i3c_device_id table (starting
> with 0xBD for OCP Secure Firmware Recovery), and optionally
> exposing a new_id sysfs attribute on the i3cdev driver for dynamically
> adding target IDs at runtime? That also keeps everything self-contained
> in i3cdev without needing cross-subsystem changes to hwmon/iio drivers.
>
We can add new_id later if necessary.
--
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
2026-10-20 21:20 ` Sam Agazaryan
@ 2026-10-21 13:00 ` Andy Shevchenko
-1 siblings, 0 replies; 40+ messages in thread
From: Andy Shevchenko @ 2026-10-21 13:00 UTC (permalink / raw)
To: Sam Agazaryan
Cc: Wolfram Sang, linux-i3c, Alexandre Belloni, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On Tue, Oct 20, 2026 at 02:20:16PM -0700, Sam Agazaryan wrote:
> > Did I miss this in the initial explanation? If not, please add it next time.
>
> That is just how the existing I3C core enumerates targets during DAA,
> not something added by this series. I will add a sentence to the
> cover letter and Patch 4 commit message in v6 contrasting it with
> i2c-dev to make that context clear.
>
> > Do we have such use cases IRL? Do we have tooling support (at least pending)
> > somewhere? Why does it require user space interaction in _this_ way (meaning
> > IOCTL and /dev node)?
>
> Yes, this is used in real systems today:
>
> 1. Tooling & production users:
>
> - i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
> AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
> years).
So, nothing in production, meaning we can design that in kernel differently.
> - OCP Secure Firmware Recovery (DCR 0xBD) [1] and Caliptra Root-of-Trust
> recovery agents on OpenBMC/gBMC platforms (e.g., AST2700 / Caliptra
> MCU recovery tooling and BMC recovery daemons). Because Vitor's
> original i3cdev series was not merged in 2019, multiple silicon
> vendors and OpenBMC trees have been carrying out-of-tree forks of i3cdev;
> upstreaming consolidates those diverging implementations.
>
> 2. Why an ioctl is required over a read and write:
>
> - In the OCP Secure Firmware Recovery v1.1 specification (Section
> 8.4, "Recovery I3C Interface Block Read via Private Write and
> Private Read"), every recovery command read is a combined transaction
> consisting of a Private Write with no STOP, followed by a Repeated START,
> followed by a Private Read, and finally a STOP.
>
> - Because write() and read() only submit a single transfer at a time
> (nxfers = 1), the controller emits a STOP condition on the wire
> at the end of write() and drops the bus lock. Submitting multiple
> i3c_ioc_xfer descriptors in a single I3C_IOC_XFER(N) ioctl is
> required so i3c_device_do_xfers() queues them together under one
> bus lock acquisition and the controller emits a Repeated START
> between messages (as well as passing HDR mode/cmd parameters).
Thanks, probably I was unclear, my specific question was why this needs a user
space to issue those recovery flows. And why it needs to be IOCTL-based and not
some higher level one.
> [1] https://www.opencompute.org/documents/ocp-recovery-document-1p1-final-pdf
>
> > So, imagine that someone submits a kernel driver for a simple device, while
> > another person already uses the driver for multi-functional device where the
> > former one is driving only part of it. Strictly speaking the kernel driver
> > submission becomes a user space regression. Which effectively means that whenever
> > you open i3cdev, no other kernel drivers may appear. Yes, I understand that
> > a poor victim of such an unlikely course of events may recompile the kernel,
> > disable driver, et cetera, but this still raises the same question, why do
> > we do that to the mere users?
>
> Note that a user does not need to recompile the kernel if a kernel
> driver binds to a device they wish to access via i3cdev. Because i3cdev
> handles BUS_NOTIFY_UNBOUND_DRIVER, unbinding the kernel driver at
> runtime via sysfs:
>
> echo <dev> > /sys/bus/i3c/devices/<dev>/driver/unbind
>
> automatically triggers i3cdev_attach() and exposes /dev/bus/i3c/<dev>
> without rebuilding the kernel.
Oh, that's quite a dangerous "feature"! Can we avoid doing that? Otherwise it
means any missed guard against unbind for the system controller related chips
may lead to real HW damage. I'm totally against this feature to be in any way
of an ABI. If you want that, do it exclusively via debugfs with a big fat
warning that this may lead to HW damages.
> Also, I3C drivers match against a
> target's MIPI-assigned DCR or 48-bit PID (Manufacturer ID + Part ID),
> so a driver for a simple device will not accidentally match a different
> chip's PID or a dedicated DCR like 0xBD.
Yes, but we are talking about opening a Pandora's box in user space, aren't we?
> > P.S> Still not convinced, that this has to be an ABI. For debugfs and something
> > like this, no objections, but ABI.
>
> Production BMC recovery daemons cannot rely on debugfs, which is
> optional and restricted or unmounted on production builds. A character
> device in /dev/bus/i3c/* provides the stable ioctl those tools need and
> integrates with udev so non-root daemons can be granted access to
> specific target nodes (e.g. matching on DCR 0xBD), similar to spidev
> and hidraw.
But why recovery mechanism can't be kernel-driven? With some sysfs
(just as an example) knobs to say "I want to run now a recovery flow
on this bus", et cetera.
> > Forgot to ask, but do they interfere?
>
> Is this in reference to i2c devices on the i3c bus? No, I3C transfers
> and legacy I2C transfers on a mixed-mode bus do not interfere:
>
> 1. Both i3c_device_do_xfers() and i3c_master_i2c_adapter_xfer() acquire
> i3c_bus_normaluse_lock(&master->bus), so I3C and I2C transactions on
> the same bus are serialized by the I3C core.
>
> 2. Attached I2C client addresses are marked as I3C_ADDR_SLOT_I2C_DEV in
> the bus address slot table, preventing DAA from assigning an I2C
> device's address to an I3C target.
Can i2c device require an i2c recovery flow on the bus? If so, how would
it be combined together with the i3c recovery flow(s)?
--
With Best Regards,
Andy Shevchenko
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
^ permalink raw reply [flat|nested] 40+ messages in thread
* Re: [PATCH v5 0/5] i3c: add i3cdev module to expose i3c dev in /dev
@ 2026-10-21 13:00 ` Andy Shevchenko
0 siblings, 0 replies; 40+ messages in thread
From: Andy Shevchenko @ 2026-10-21 13:00 UTC (permalink / raw)
To: Sam Agazaryan
Cc: Wolfram Sang, linux-i3c, Alexandre Belloni, Frank Li,
Greg Kroah-Hartman, Arnd Bergmann, Adrian Hunter, Meagan Lloyd,
Vitor Soares, Oleksandr Shulzhenko, Boris Brezillon, linux-kernel
On Tue, Oct 20, 2026 at 02:20:16PM -0700, Sam Agazaryan wrote:
> > Did I miss this in the initial explanation? If not, please add it next time.
>
> That is just how the existing I3C core enumerates targets during DAA,
> not something added by this series. I will add a sentence to the
> cover letter and Patch 4 commit message in v6 contrasting it with
> i2c-dev to make that context clear.
>
> > Do we have such use cases IRL? Do we have tooling support (at least pending)
> > somewhere? Why does it require user space interaction in _this_ way (meaning
> > IOCTL and /dev node)?
>
> Yes, this is used in real systems today:
>
> 1. Tooling & production users:
>
> - i3ctransfer (Patch 5/5 of this series, and carried out-of-tree in
> AspeedTech-BMC/i3c-tools and vendor OpenBMC BSPs for several
> years).
So, nothing in production, meaning we can design that in kernel differently.
> - OCP Secure Firmware Recovery (DCR 0xBD) [1] and Caliptra Root-of-Trust
> recovery agents on OpenBMC/gBMC platforms (e.g., AST2700 / Caliptra
> MCU recovery tooling and BMC recovery daemons). Because Vitor's
> original i3cdev series was not merged in 2019, multiple silicon
> vendors and OpenBMC trees have been carrying out-of-tree forks of i3cdev;
> upstreaming consolidates those diverging implementations.
>
> 2. Why an ioctl is required over a read and write:
>
> - In the OCP Secure Firmware Recovery v1.1 specification (Section
> 8.4, "Recovery I3C Interface Block Read via Private Write and
> Private Read"), every recovery command read is a combined transaction
> consisting of a Private Write with no STOP, followed by a Repeated START,
> followed by a Private Read, and finally a STOP.
>
> - Because write() and read() only submit a single transfer at a time
> (nxfers = 1), the controller emits a STOP condition on the wire
> at the end of write() and drops the bus lock. Submitting multiple
> i3c_ioc_xfer descriptors in a single I3C_IOC_XFER(N) ioctl is
> required so i3c_device_do_xfers() queues them together under one
> bus lock acquisition and the controller emits a Repeated START
> between messages (as well as passing HDR mode/cmd parameters).
Thanks, probably I was unclear, my specific question was why this needs a user
space to issue those recovery flows. And why it needs to be IOCTL-based and not
some higher level one.
> [1] https://www.opencompute.org/documents/ocp-recovery-document-1p1-final-pdf
>
> > So, imagine that someone submits a kernel driver for a simple device, while
> > another person already uses the driver for multi-functional device where the
> > former one is driving only part of it. Strictly speaking the kernel driver
> > submission becomes a user space regression. Which effectively means that whenever
> > you open i3cdev, no other kernel drivers may appear. Yes, I understand that
> > a poor victim of such an unlikely course of events may recompile the kernel,
> > disable driver, et cetera, but this still raises the same question, why do
> > we do that to the mere users?
>
> Note that a user does not need to recompile the kernel if a kernel
> driver binds to a device they wish to access via i3cdev. Because i3cdev
> handles BUS_NOTIFY_UNBOUND_DRIVER, unbinding the kernel driver at
> runtime via sysfs:
>
> echo <dev> > /sys/bus/i3c/devices/<dev>/driver/unbind
>
> automatically triggers i3cdev_attach() and exposes /dev/bus/i3c/<dev>
> without rebuilding the kernel.
Oh, that's quite a dangerous "feature"! Can we avoid doing that? Otherwise it
means any missed guard against unbind for the system controller related chips
may lead to real HW damage. I'm totally against this feature to be in any way
of an ABI. If you want that, do it exclusively via debugfs with a big fat
warning that this may lead to HW damages.
> Also, I3C drivers match against a
> target's MIPI-assigned DCR or 48-bit PID (Manufacturer ID + Part ID),
> so a driver for a simple device will not accidentally match a different
> chip's PID or a dedicated DCR like 0xBD.
Yes, but we are talking about opening a Pandora's box in user space, aren't we?
> > P.S> Still not convinced, that this has to be an ABI. For debugfs and something
> > like this, no objections, but ABI.
>
> Production BMC recovery daemons cannot rely on debugfs, which is
> optional and restricted or unmounted on production builds. A character
> device in /dev/bus/i3c/* provides the stable ioctl those tools need and
> integrates with udev so non-root daemons can be granted access to
> specific target nodes (e.g. matching on DCR 0xBD), similar to spidev
> and hidraw.
But why recovery mechanism can't be kernel-driven? With some sysfs
(just as an example) knobs to say "I want to run now a recovery flow
on this bus", et cetera.
> > Forgot to ask, but do they interfere?
>
> Is this in reference to i2c devices on the i3c bus? No, I3C transfers
> and legacy I2C transfers on a mixed-mode bus do not interfere:
>
> 1. Both i3c_device_do_xfers() and i3c_master_i2c_adapter_xfer() acquire
> i3c_bus_normaluse_lock(&master->bus), so I3C and I2C transactions on
> the same bus are serialized by the I3C core.
>
> 2. Attached I2C client addresses are marked as I3C_ADDR_SLOT_I2C_DEV in
> the bus address slot table, preventing DAA from assigning an I2C
> device's address to an I3C target.
Can i2c device require an i2c recovery flow on the bus? If so, how would
it be combined together with the i3c recovery flow(s)?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 40+ messages in thread