i3c master: GETMRL's 3rd byte is optional even with BCR_IBI_PAYLOAD

According to the I3C spec v1.1 document, GETMRL's payload is 2 bytes,
with an optional 3rd byte if the IBI private payload is larger than
1 byte. The whole GETMRL may also be optional so max_ibi_len already
defaults to 1 if BCR_IBI_PAYLOAD prior to the i3c_master_getmrl_locked()
call.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com>
Link: https://lore.kernel.org/linux-i3c/nycvar.YSQ.7.76.2004151623060.2671@knanqh.ubzr
This commit is contained in:
Nicolas Pitre 2020-04-15 16:30:01 -04:00 committed by Boris Brezillon
parent 8f3d9f3542
commit b4203ce055

View File

@ -1008,7 +1008,6 @@ static int i3c_master_getmrl_locked(struct i3c_master_controller *master,
struct i3c_device_info *info)
{
struct i3c_ccc_cmd_dest dest;
unsigned int expected_len;
struct i3c_ccc_mrl *mrl;
struct i3c_ccc_cmd cmd;
int ret;
@ -1024,22 +1023,23 @@ static int i3c_master_getmrl_locked(struct i3c_master_controller *master,
if (!(info->bcr & I3C_BCR_IBI_PAYLOAD))
dest.payload.len -= 1;
expected_len = dest.payload.len;
i3c_ccc_cmd_init(&cmd, true, I3C_CCC_GETMRL, &dest, 1);
ret = i3c_master_send_ccc_cmd_locked(master, &cmd);
if (ret)
goto out;
if (dest.payload.len != expected_len) {
switch (dest.payload.len) {
case 3:
info->max_ibi_len = mrl->ibi_len;
fallthrough;
case 2:
info->max_read_len = be16_to_cpu(mrl->read_len);
break;
default:
ret = -EIO;
goto out;
}
info->max_read_len = be16_to_cpu(mrl->read_len);
if (info->bcr & I3C_BCR_IBI_PAYLOAD)
info->max_ibi_len = mrl->ibi_len;
out:
i3c_ccc_cmd_dest_cleanup(&dest);