Re: [PATCH v3 2/3] i3c: master: dw: Map CCC hardware errors to I3C M0/M2
"NG, TZE YEE" <[email protected]>
| Newsgroups | org.infradead.lists.linux-i3c,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
On 20/6/2026 3:26 am, Frank Li wrote: > On Wed, Jun 10, 2026 at 06:54:07PM -0700, [email protected] wrote: >> From: Adrian Ng Ho Yin <[email protected]> >> >> Map DesignWare response-queue status to standard I3C error codes in >> ccc->err: >> >> - RESPONSE_ERROR_IBA_NACK and RESPONSE_ERROR_ADDRESS_NACK -> I3C_ERROR_M2 >> - RESPONSE_ERROR_CRC, RESPONSE_ERROR_PARITY, RESPONSE_ERROR_FRAME and >> RESPONSE_ERROR_TRANSF_ABORT -> I3C_ERROR_M0 >> >> Return -EIO for RESPONSE_ERROR_ADDRESS_NACK so bus NACKs are not reported >> as -EINVAL alongside I3C_ERROR_M2, consistent with IBA_NACK handling and >> other I3C master drivers. >> >> The M0 mappings match the generic I/O failures already reported by >> dw_i3c_master_end_xfer_locked() so the core can retry transient bus >> integrity errors on CCC transfers. >> >> Reset ccc->err to I3C_ERROR_UNKNOWN before each transfer. >> >> Signed-off-by: Adrian Ng Ho Yin <[email protected]> >> Signed-off-by: Tze Yee Ng <[email protected]> >> --- >> drivers/i3c/master/dw-i3c-master.c | 31 +++++++++++++++++++++++++----- >> 1 file changed, 26 insertions(+), 5 deletions(-) >> >> diff --git a/drivers/i3c/master/dw-i3c-master.c b/drivers/i3c/master/dw-i3c-master.c >> index 06fdf8857b9c..45bde92d0342 100644 >> --- a/drivers/i3c/master/dw-i3c-master.c >> +++ b/drivers/i3c/master/dw-i3c-master.c >> @@ -493,6 +493,7 @@ static void dw_i3c_master_end_xfer_locked(struct dw_i3c_master *master, u32 isr) >> break; >> case RESPONSE_ERROR_PARITY: >> case RESPONSE_ERROR_IBA_NACK: >> + case RESPONSE_ERROR_ADDRESS_NACK: >> case RESPONSE_ERROR_TRANSF_ABORT: >> case RESPONSE_ERROR_CRC: >> case RESPONSE_ERROR_FRAME: >> @@ -502,7 +503,6 @@ static void dw_i3c_master_end_xfer_locked(struct dw_i3c_master *master, u32 isr) >> ret = -ENOSPC; >> break; >> case RESPONSE_ERROR_I2C_W_NACK_ERR: >> - case RESPONSE_ERROR_ADDRESS_NACK: >> default: >> ret = -EINVAL; >> break; >> @@ -708,12 +708,32 @@ static void dw_i3c_master_bus_cleanup(struct i3c_master_controller *m) >> dw_i3c_master_disable(master); >> } >> >> +static void dw_i3c_ccc_map_err(struct i3c_ccc_cmd *ccc, struct dw_i3c_cmd *cmd) >> +{ >> + switch (cmd->error) { >> + case RESPONSE_ERROR_IBA_NACK: >> + case RESPONSE_ERROR_ADDRESS_NACK: >> + ccc->err = I3C_ERROR_M2; >> + break; >> + case RESPONSE_ERROR_CRC: >> + case RESPONSE_ERROR_PARITY: >> + case RESPONSE_ERROR_FRAME: >> + case RESPONSE_ERROR_TRANSF_ABORT: >> + ccc->err = I3C_ERROR_M0; >> + break; >> + default: >> + break; >> + } >> +} >> + > > generaly this type map function like > > enum i3c_error_code dw_i3c_ccc_map_err(int dw_err) > { > .... > } > > ccc->err = dw_i3c_ccc_map_err(cmd->error); > > Frank Agree, in v4, we will change it to return enum i3c_error_code from the DW error code.>> static int dw_i3c_ccc_set(struct dw_i3c_master *master, >> struct i3c_ccc_cmd *ccc) >> { >> struct dw_i3c_cmd *cmd; >> int ret, pos = 0; >> >> + ccc->err = I3C_ERROR_UNKNOWN; >> + >> if (ccc->id & I3C_CCC_DIRECT) { >> pos = dw_i3c_master_get_addr_pos(master, ccc->dests[0].addr); >> if (pos < 0) >> @@ -742,8 +762,8 @@ static int dw_i3c_ccc_set(struct dw_i3c_master *master, >> dw_i3c_master_dequeue_xfer(master, xfer); >> >> ret = xfer->ret; >> - if (xfer->cmds[0].error == RESPONSE_ERROR_IBA_NACK) >> - ccc->err = I3C_ERROR_M2; >> + cmd = &xfer->cmds[0]; >> + dw_i3c_ccc_map_err(ccc, cmd); >> >> return ret; >> } >> @@ -754,6 +774,8 @@ static int dw_i3c_ccc_get(struct dw_i3c_master *master, struct i3c_ccc_cmd *ccc) >> u16 req_len; >> int ret, pos; >> >> + ccc->err = I3C_ERROR_UNKNOWN; >> + >> pos = dw_i3c_master_get_addr_pos(master, ccc->dests[0].addr); >> if (pos < 0) >> return pos; >> @@ -784,10 +806,9 @@ static int dw_i3c_ccc_get(struct dw_i3c_master *master, struct i3c_ccc_cmd *ccc) >> >> ret = xfer->ret; >> cmd = &xfer->cmds[0]; >> + dw_i3c_ccc_map_err(ccc, cmd); >> if (!ret) >> ccc->dests[0].payload.len = cmd->rx_len; >> - if (cmd->error == RESPONSE_ERROR_IBA_NACK) >> - ccc->err = I3C_ERROR_M2; >> >> return ret; >> } >> -- >> 2.43.7 >> -- linux-i3c mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-i3c