drivers: i3c: cdns: handle variable length ccc with m0 err
The CDNS will report a M0 error if the data length is not what it expects, but certain CCCs can have a variable length such as GETMXDS and GETCAPS. This sets it up to ignore the M0 error if it sees that ccc was GETMXDS or GETCAPS. Signed-off-by: Ryan McClelland <ryanmcclelland@meta.com>
This commit is contained in:
parent
bb66b7b870
commit
c75783219f
1 changed files with 34 additions and 1 deletions
|
|
@ -1350,9 +1350,42 @@ static void cdns_i3c_complete_transfer(const struct device *dev)
|
|||
}
|
||||
break;
|
||||
|
||||
case CMDR_M0_ERROR: {
|
||||
uint8_t ccc = data->xfer.cmds[i].cmd1 & 0xFF;
|
||||
/*
|
||||
* The M0 is an illegally formatted CCC. i.e. the Controller
|
||||
* receives 1 byte instead of 2 with the GETMWL CCC. This can
|
||||
* be problematic for CCCs that can have variable length such
|
||||
* as GETMXDS and GETCAPS. Verify the number of bytes received matches
|
||||
* what's expected from the specification and ignore the error. The IP will
|
||||
* still retramsit the same CCC and theres nothing that can be done to
|
||||
* prevent this. It it still up to the application to read `num_xfer` to
|
||||
* determine the number of bytes returned.
|
||||
*/
|
||||
if (ccc == I3C_CCC_GETMXDS) {
|
||||
/*
|
||||
* Whether GETMXDS format 1 and format 2 can't be known ahead of
|
||||
* time which will be returned.
|
||||
*/
|
||||
if ((*data->xfer.cmds[i].num_xfer !=
|
||||
sizeof(((union i3c_ccc_getmxds *)0)->fmt1)) &&
|
||||
(*data->xfer.cmds[i].num_xfer !=
|
||||
sizeof(((union i3c_ccc_getmxds *)0)->fmt2))) {
|
||||
ret = -EIO;
|
||||
}
|
||||
} else if (ccc == I3C_CCC_GETCAPS) {
|
||||
/* GETCAPS can only return 1-4 bytes */
|
||||
if (*data->xfer.cmds[i].num_xfer > sizeof(union i3c_ccc_getcaps)) {
|
||||
ret = -EIO;
|
||||
}
|
||||
} else {
|
||||
ret = -EIO;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CMDR_DDR_PREAMBLE_ERROR:
|
||||
case CMDR_DDR_PARITY_ERROR:
|
||||
case CMDR_M0_ERROR:
|
||||
case CMDR_M1_ERROR:
|
||||
case CMDR_M2_ERROR:
|
||||
case CMDR_NACK_RESP:
|
||||
|
|
|
|||
Loading…
Reference in a new issue