From: Frank Li <Frank.li@oss.nxp.com>
To: tze.yee.ng@altera.com
Cc: "Alexandre Belloni" <alexandre.belloni@bootlin.com>,
"Frank Li" <Frank.Li@nxp.com>,
linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org,
"Jorge Marques" <jorge.marques@analog.com>,
"Przemysław Gaj" <pgaj@cadence.com>,
"Wolfram Sang" <wsa+renesas@sang-engineering.com>,
"Tommaso Merciai" <tommaso.merciai.xr@bp.renesas.com>,
"Miquel Raynal" <miquel.raynal@bootlin.com>,
"Adrian Ng Ho Yin" <adrian.ho.yin.ng@altera.com>,
"Felix Gu" <ustc.gu@gmail.com>,
"Manikanta Guntupalli" <manikanta.guntupalli@amd.com>,
"Sakari Ailus" <sakari.ailus@linux.intel.com>,
"Adrian Hunter" <adrian.hunter@intel.com>,
"Jarkko Nikula" <jarkko.nikula@linux.intel.com>,
imx@lists.linux.dev
Subject: Re: [PATCH v6 4/5] i3c: master: Validate GET CCC payload length and retry Direct GET once
Date: Wed, 8 Jul 2026 09:53:46 -0500 [thread overview]
Message-ID: <ak5kenGbrXOACLuN@SMW015318> (raw)
In-Reply-To: <b467f01edfaaa0710f30e719ce7f2753b06c1a3f.1783493868.git.tze.yee.ng@altera.com>
On Wed, Jul 08, 2026 at 12:17:40AM -0700, tze.yee.ng@altera.com wrote:
> From: Adrian Ng Ho Yin <adrian.ho.yin.ng@altera.com>
>
> Add retries to struct i3c_ccc_cmd. Validate GET payload length in
> i3c_master_send_ccc_cmd_locked() after a successful transfer.
>
> Retry failed Direct GET CCCs up to cmd->retries times when the driver
> reports failure or an I3C error; validation failures are not retried.
> SET CCCs are not retried by default.
>
> Signed-off-by: Adrian Ng Ho Yin <adrian.ho.yin.ng@altera.com>
> Signed-off-by: Tze Yee Ng <tze.yee.ng@altera.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Changes in v5:
> - Split from v4 patch 3/3: retry and strict validation only; optional_bytes
> moved to patch 5/5.
> - Validate GET payload length after a successful transfer.
> - Retry failed Direct GET CCCs when the driver reports failure or an I3C
> error; validation failures are not retried.
>
> Changes in v4:
> - Add optional_bytes to struct i3c_ccc_cmd_payload and retries to
> struct i3c_ccc_cmd (default I3C_CCC_RETRIES for GET, 0 for SET).
> - Replace CCC-ID-specific payload checks with generic validation using
> actual_len, len, and optional_bytes.
> - GETMRL and GETMXDS set optional_bytes at the call site instead of
> hardcoding lengths in the core.
> - Retry failed Direct GET CCCs on any error up to cmd->retries times,
> per I3C spec Direct GET single-retry model (§5.1.9.2.3); drop M0/M2-
> gated retry logic.
> - Drop req_lens save/restore and the stack/kmalloc bookkeeping for
> payload.len.
> - Update I3C master drivers (SVC, Cadence, ADI, Renesas, MIPI HCI) to
> populate actual_len on successful GET transfers.
> - Use actual_len in getmrl_locked(), getmwl_locked(), getmxds_locked(),
> and gethdrcap_locked().
> ---
> drivers/i3c/master.c | 59 ++++++++++++++++++++++++++++++++++++++---
> include/linux/i3c/ccc.h | 5 ++++
> 2 files changed, 60 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 037b3b980717..3b6d3ecd9d12 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -915,17 +915,46 @@ static void i3c_ccc_cmd_dest_cleanup(struct i3c_ccc_cmd_dest *dest)
> kfree(dest->payload.data);
> }
>
> -static void i3c_ccc_cmd_init(struct i3c_ccc_cmd *cmd, bool rnw, u8 id,
> - struct i3c_ccc_cmd_dest *dests,
> - unsigned int ndests)
> +static void i3c_ccc_cmd_init_retries(struct i3c_ccc_cmd *cmd, bool rnw, u8 id,
> + struct i3c_ccc_cmd_dest *dests,
> + unsigned int ndests, unsigned int retries)
> {
> cmd->rnw = rnw ? 1 : 0;
> cmd->id = id;
> cmd->dests = dests;
> cmd->ndests = ndests;
> + cmd->retries = retries;
> cmd->err = I3C_ERROR_UNKNOWN;
> }
>
> +static void i3c_ccc_cmd_init(struct i3c_ccc_cmd *cmd, bool rnw, u8 id,
> + struct i3c_ccc_cmd_dest *dests,
> + unsigned int ndests)
> +{
> + i3c_ccc_cmd_init_retries(cmd, rnw, id, dests, ndests,
> + rnw ? I3C_CCC_RETRIES : 0);
> +}
> +
> +static int i3c_ccc_validate_payload_len(struct i3c_ccc_cmd *cmd)
> +{
> + unsigned int i;
> +
> + if (!cmd->rnw)
> + return 0;
> +
> + for (i = 0; i < cmd->ndests; i++) {
> + struct i3c_ccc_cmd_payload *p = &cmd->dests[i].payload;
> +
> + if (p->actual_len > p->len)
> + return -EIO;
> +
> + if (p->len && p->actual_len != p->len)
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> /**
> * i3c_master_send_ccc_cmd_locked() - send a CCC (Common Command Codes)
> * @master: master used to send frames on the bus
> @@ -937,6 +966,9 @@ static void i3c_ccc_cmd_init(struct i3c_ccc_cmd *cmd, bool rnw, u8 id,
> static int i3c_master_send_ccc_cmd_locked(struct i3c_master_controller *master,
> struct i3c_ccc_cmd *cmd)
> {
> + unsigned int attempt, max_attempts;
> + int ret;
> +
> if (!cmd || !master)
> return -EINVAL;
>
> @@ -954,7 +986,25 @@ static int i3c_master_send_ccc_cmd_locked(struct i3c_master_controller *master,
> !master->ops->supports_ccc_cmd(master, cmd))
> return -EOPNOTSUPP;
>
> - return master->ops->send_ccc_cmd(master, cmd);
> + max_attempts = cmd->retries + 1;
> + ret = -EIO;
> + for (attempt = 0; attempt < max_attempts; attempt++) {
> + unsigned int i;
> +
> + if (cmd->rnw)
> + for (i = 0; i < cmd->ndests; i++)
> + cmd->dests[i].payload.actual_len = 0;
> +
> + cmd->err = I3C_ERROR_UNKNOWN;
> + ret = master->ops->send_ccc_cmd(master, cmd);
> + if (!ret && cmd->err == I3C_ERROR_UNKNOWN)
> + break;
> + }
> +
> + if (!ret)
> + ret = i3c_ccc_validate_payload_len(cmd);
> +
> + return ret;
>
> static struct i2c_dev_desc *
> @@ -1372,6 +1422,7 @@ static int i3c_master_getmxds_locked(struct i3c_master_controller *master,
> * while expecting shorter length from this CCC command.
> */
> dest.payload.len -= 3;
> + i3c_ccc_cmd_init(&cmd, true, I3C_CCC_GETMXDS, &dest, 1);
> ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
> if (ret)
> goto out;
> diff --git a/include/linux/i3c/ccc.h b/include/linux/i3c/ccc.h
> index d8052949e57e..2506d83b8255 100644
> --- a/include/linux/i3c/ccc.h
> +++ b/include/linux/i3c/ccc.h
> @@ -12,6 +12,8 @@
> #include <linux/i3c/device.h>
>
> /* I3C CCC (Common Command Codes) related definitions */
> +#define I3C_CCC_RETRIES 1
> +
> #define I3C_CCC_DIRECT BIT(7)
>
> #define I3C_CCC_ID(id, broadcast) \
> @@ -374,12 +376,15 @@ struct i3c_ccc_cmd_dest {
> * @ndests: number of destinations. Should always be one for broadcast commands
> * @dests: array of destinations and associated payload for this CCC. Most of
> * the time, only one destination is provided
> + * @retries: number of times to retry a failed Direct GET CCC (see
> + * &I3C_CCC_RETRIES)
> * @err: I3C error code
> */
> struct i3c_ccc_cmd {
> u8 rnw;
> u8 id;
> unsigned int ndests;
> + unsigned int retries;
> struct i3c_ccc_cmd_dest *dests;
> enum i3c_error_code err;
> };
> --
> 2.43.7
>
>
WARNING: multiple messages have this Message-ID (diff)
From: Frank Li <Frank.li@oss.nxp.com>
To: tze.yee.ng@altera.com
Cc: "Alexandre Belloni" <alexandre.belloni@bootlin.com>,
"Frank Li" <Frank.Li@nxp.com>,
linux-i3c@lists.infradead.org, linux-kernel@vger.kernel.org,
"Jorge Marques" <jorge.marques@analog.com>,
"Przemysław Gaj" <pgaj@cadence.com>,
"Wolfram Sang" <wsa+renesas@sang-engineering.com>,
"Tommaso Merciai" <tommaso.merciai.xr@bp.renesas.com>,
"Miquel Raynal" <miquel.raynal@bootlin.com>,
"Adrian Ng Ho Yin" <adrian.ho.yin.ng@altera.com>,
"Felix Gu" <ustc.gu@gmail.com>,
"Manikanta Guntupalli" <manikanta.guntupalli@amd.com>,
"Sakari Ailus" <sakari.ailus@linux.intel.com>,
"Adrian Hunter" <adrian.hunter@intel.com>,
"Jarkko Nikula" <jarkko.nikula@linux.intel.com>,
imx@lists.linux.dev
Subject: Re: [PATCH v6 4/5] i3c: master: Validate GET CCC payload length and retry Direct GET once
Date: Wed, 8 Jul 2026 09:53:46 -0500 [thread overview]
Message-ID: <ak5kenGbrXOACLuN@SMW015318> (raw)
In-Reply-To: <b467f01edfaaa0710f30e719ce7f2753b06c1a3f.1783493868.git.tze.yee.ng@altera.com>
On Wed, Jul 08, 2026 at 12:17:40AM -0700, tze.yee.ng@altera.com wrote:
> From: Adrian Ng Ho Yin <adrian.ho.yin.ng@altera.com>
>
> Add retries to struct i3c_ccc_cmd. Validate GET payload length in
> i3c_master_send_ccc_cmd_locked() after a successful transfer.
>
> Retry failed Direct GET CCCs up to cmd->retries times when the driver
> reports failure or an I3C error; validation failures are not retried.
> SET CCCs are not retried by default.
>
> Signed-off-by: Adrian Ng Ho Yin <adrian.ho.yin.ng@altera.com>
> Signed-off-by: Tze Yee Ng <tze.yee.ng@altera.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> Changes in v5:
> - Split from v4 patch 3/3: retry and strict validation only; optional_bytes
> moved to patch 5/5.
> - Validate GET payload length after a successful transfer.
> - Retry failed Direct GET CCCs when the driver reports failure or an I3C
> error; validation failures are not retried.
>
> Changes in v4:
> - Add optional_bytes to struct i3c_ccc_cmd_payload and retries to
> struct i3c_ccc_cmd (default I3C_CCC_RETRIES for GET, 0 for SET).
> - Replace CCC-ID-specific payload checks with generic validation using
> actual_len, len, and optional_bytes.
> - GETMRL and GETMXDS set optional_bytes at the call site instead of
> hardcoding lengths in the core.
> - Retry failed Direct GET CCCs on any error up to cmd->retries times,
> per I3C spec Direct GET single-retry model (§5.1.9.2.3); drop M0/M2-
> gated retry logic.
> - Drop req_lens save/restore and the stack/kmalloc bookkeeping for
> payload.len.
> - Update I3C master drivers (SVC, Cadence, ADI, Renesas, MIPI HCI) to
> populate actual_len on successful GET transfers.
> - Use actual_len in getmrl_locked(), getmwl_locked(), getmxds_locked(),
> and gethdrcap_locked().
> ---
> drivers/i3c/master.c | 59 ++++++++++++++++++++++++++++++++++++++---
> include/linux/i3c/ccc.h | 5 ++++
> 2 files changed, 60 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
> index 037b3b980717..3b6d3ecd9d12 100644
> --- a/drivers/i3c/master.c
> +++ b/drivers/i3c/master.c
> @@ -915,17 +915,46 @@ static void i3c_ccc_cmd_dest_cleanup(struct i3c_ccc_cmd_dest *dest)
> kfree(dest->payload.data);
> }
>
> -static void i3c_ccc_cmd_init(struct i3c_ccc_cmd *cmd, bool rnw, u8 id,
> - struct i3c_ccc_cmd_dest *dests,
> - unsigned int ndests)
> +static void i3c_ccc_cmd_init_retries(struct i3c_ccc_cmd *cmd, bool rnw, u8 id,
> + struct i3c_ccc_cmd_dest *dests,
> + unsigned int ndests, unsigned int retries)
> {
> cmd->rnw = rnw ? 1 : 0;
> cmd->id = id;
> cmd->dests = dests;
> cmd->ndests = ndests;
> + cmd->retries = retries;
> cmd->err = I3C_ERROR_UNKNOWN;
> }
>
> +static void i3c_ccc_cmd_init(struct i3c_ccc_cmd *cmd, bool rnw, u8 id,
> + struct i3c_ccc_cmd_dest *dests,
> + unsigned int ndests)
> +{
> + i3c_ccc_cmd_init_retries(cmd, rnw, id, dests, ndests,
> + rnw ? I3C_CCC_RETRIES : 0);
> +}
> +
> +static int i3c_ccc_validate_payload_len(struct i3c_ccc_cmd *cmd)
> +{
> + unsigned int i;
> +
> + if (!cmd->rnw)
> + return 0;
> +
> + for (i = 0; i < cmd->ndests; i++) {
> + struct i3c_ccc_cmd_payload *p = &cmd->dests[i].payload;
> +
> + if (p->actual_len > p->len)
> + return -EIO;
> +
> + if (p->len && p->actual_len != p->len)
> + return -EIO;
> + }
> +
> + return 0;
> +}
> +
> /**
> * i3c_master_send_ccc_cmd_locked() - send a CCC (Common Command Codes)
> * @master: master used to send frames on the bus
> @@ -937,6 +966,9 @@ static void i3c_ccc_cmd_init(struct i3c_ccc_cmd *cmd, bool rnw, u8 id,
> static int i3c_master_send_ccc_cmd_locked(struct i3c_master_controller *master,
> struct i3c_ccc_cmd *cmd)
> {
> + unsigned int attempt, max_attempts;
> + int ret;
> +
> if (!cmd || !master)
> return -EINVAL;
>
> @@ -954,7 +986,25 @@ static int i3c_master_send_ccc_cmd_locked(struct i3c_master_controller *master,
> !master->ops->supports_ccc_cmd(master, cmd))
> return -EOPNOTSUPP;
>
> - return master->ops->send_ccc_cmd(master, cmd);
> + max_attempts = cmd->retries + 1;
> + ret = -EIO;
> + for (attempt = 0; attempt < max_attempts; attempt++) {
> + unsigned int i;
> +
> + if (cmd->rnw)
> + for (i = 0; i < cmd->ndests; i++)
> + cmd->dests[i].payload.actual_len = 0;
> +
> + cmd->err = I3C_ERROR_UNKNOWN;
> + ret = master->ops->send_ccc_cmd(master, cmd);
> + if (!ret && cmd->err == I3C_ERROR_UNKNOWN)
> + break;
> + }
> +
> + if (!ret)
> + ret = i3c_ccc_validate_payload_len(cmd);
> +
> + return ret;
>
> static struct i2c_dev_desc *
> @@ -1372,6 +1422,7 @@ static int i3c_master_getmxds_locked(struct i3c_master_controller *master,
> * while expecting shorter length from this CCC command.
> */
> dest.payload.len -= 3;
> + i3c_ccc_cmd_init(&cmd, true, I3C_CCC_GETMXDS, &dest, 1);
> ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
> if (ret)
> goto out;
> diff --git a/include/linux/i3c/ccc.h b/include/linux/i3c/ccc.h
> index d8052949e57e..2506d83b8255 100644
> --- a/include/linux/i3c/ccc.h
> +++ b/include/linux/i3c/ccc.h
> @@ -12,6 +12,8 @@
> #include <linux/i3c/device.h>
>
> /* I3C CCC (Common Command Codes) related definitions */
> +#define I3C_CCC_RETRIES 1
> +
> #define I3C_CCC_DIRECT BIT(7)
>
> #define I3C_CCC_ID(id, broadcast) \
> @@ -374,12 +376,15 @@ struct i3c_ccc_cmd_dest {
> * @ndests: number of destinations. Should always be one for broadcast commands
> * @dests: array of destinations and associated payload for this CCC. Most of
> * the time, only one destination is provided
> + * @retries: number of times to retry a failed Direct GET CCC (see
> + * &I3C_CCC_RETRIES)
> * @err: I3C error code
> */
> struct i3c_ccc_cmd {
> u8 rnw;
> u8 id;
> unsigned int ndests;
> + unsigned int retries;
> struct i3c_ccc_cmd_dest *dests;
> enum i3c_error_code err;
> };
> --
> 2.43.7
>
>
--
linux-i3c mailing list
linux-i3c@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-i3c
next prev parent reply other threads:[~2026-07-08 14:54 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-08 7:17 [PATCH v6 0/5] i3c: Improve CCC reliability with actual_len, validation, and Direct GET retry tze.yee.ng
2026-07-08 7:17 ` tze.yee.ng
2026-07-08 7:17 ` [PATCH v6 1/5] i3c: ccc: Add actual_len to struct i3c_ccc_cmd_payload tze.yee.ng
2026-07-08 7:17 ` tze.yee.ng
2026-07-08 13:11 ` Frank Li
2026-07-08 13:11 ` Frank Li
2026-07-08 14:52 ` Alexandre Mergnat
2026-07-08 14:52 ` Alexandre Mergnat
2026-07-08 7:17 ` [PATCH v6 2/5] i3c: master: Report actual GET CCC payload length on success tze.yee.ng
2026-07-08 7:17 ` tze.yee.ng
2026-07-08 9:44 ` sashiko-bot
2026-07-08 9:44 ` sashiko-bot
2026-07-08 13:16 ` Frank Li
2026-07-08 13:16 ` Frank Li
2026-07-08 14:52 ` Alexandre Mergnat
2026-07-08 14:52 ` Alexandre Mergnat
2026-07-08 7:17 ` [PATCH v6 3/5] i3c: master: dw: Map CCC hardware errors to I3C M0/M2 tze.yee.ng
2026-07-08 7:17 ` tze.yee.ng
2026-07-08 13:20 ` Frank Li
2026-07-08 13:20 ` Frank Li
2026-07-08 7:17 ` [PATCH v6 4/5] i3c: master: Validate GET CCC payload length and retry Direct GET once tze.yee.ng
2026-07-08 7:17 ` tze.yee.ng
2026-07-08 10:01 ` sashiko-bot
2026-07-08 10:01 ` sashiko-bot
2026-07-08 14:53 ` Frank Li [this message]
2026-07-08 14:53 ` Frank Li
2026-07-08 15:19 ` Alexandre Mergnat
2026-07-08 15:19 ` Alexandre Mergnat
2026-07-08 7:17 ` [PATCH v6 5/5] i3c: master: Add optional_bytes for variable-length GET CCC validation tze.yee.ng
2026-07-08 7:17 ` tze.yee.ng
2026-07-08 15:01 ` Frank Li
2026-07-08 15:01 ` Frank Li
2026-07-09 2:56 ` NG, TZE YEE
2026-07-09 2:56 ` NG, TZE YEE
2026-07-09 3:37 ` Frank Li
2026-07-09 3:37 ` Frank Li
2026-07-09 11:32 ` Alexandre Mergnat
2026-07-09 11:32 ` Alexandre Mergnat
2026-07-13 13:58 ` [PATCH v6 0/5] i3c: Improve CCC reliability with actual_len, validation, and Direct GET retry claudiu beznea
2026-07-13 13:58 ` claudiu beznea
2026-07-13 17:27 ` Tommaso Merciai
2026-07-13 17:27 ` Tommaso Merciai
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ak5kenGbrXOACLuN@SMW015318 \
--to=frank.li@oss.nxp.com \
--cc=Frank.Li@nxp.com \
--cc=adrian.ho.yin.ng@altera.com \
--cc=adrian.hunter@intel.com \
--cc=alexandre.belloni@bootlin.com \
--cc=imx@lists.linux.dev \
--cc=jarkko.nikula@linux.intel.com \
--cc=jorge.marques@analog.com \
--cc=linux-i3c@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=manikanta.guntupalli@amd.com \
--cc=miquel.raynal@bootlin.com \
--cc=pgaj@cadence.com \
--cc=sakari.ailus@linux.intel.com \
--cc=tommaso.merciai.xr@bp.renesas.com \
--cc=tze.yee.ng@altera.com \
--cc=ustc.gu@gmail.com \
--cc=wsa+renesas@sang-engineering.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.