diff mbox series

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

Message ID nycvar.YSQ.7.76.2004151623060.2671@knanqh.ubzr (mailing list archive)
State Mainlined
Commit b4203ce0556348dcfe29f897d1dbe65102874d89
Headers show
Series i3c master: GETMRL's 3rd byte is optional even with BCR_IBI_PAYLOAD | expand

Commit Message

Nicolas Pitre April 15, 2020, 8:30 p.m. UTC
From: Nicolas Pitre <npitre@baylibre.com>

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>
diff mbox series

Patch

diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c
index 7f8f896fa0..d7e99fb0c9 100644
--- a/drivers/i3c/master.c
+++ b/drivers/i3c/master.c
@@ -986,7 +986,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;
@@ -1002,22 +1001,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);