Currently, by setting the xmit_msg_size to 63, the ssif driver never
does a SSIF_MULTI_n_PART, it falls back to only SSIF_MULTI_2_PART.
Due to this all IPMI commands with request size more than 63 bytes
will not work.
As per IPMI spec, SSIF supports message size up to 255 bytes.
In a multi-part message, the first part must carry 32 bytes. All
intermediate ("middle") parts must carry 32 bytes. The end part
can carry 1-31 bytes, but not zero bytes.
Update ssif max_xmit_msg_size to 255 to handle multi-part messages up
to 255 bytes. Add additional logic to check if the messages is of
length n * 32 bytes where n > 1. If so, return error.
Signed-off-by: Kamlakant Patel <[email protected]>
Reported-by: Karthikeyan M <[email protected]>
---
drivers/char/ipmi/ipmi_ssif.c | 24 ++++++++++++++++++++++--
1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c
index 18e4650..fd64d52 100644
--- a/drivers/char/ipmi/ipmi_ssif.c
+++ b/drivers/char/ipmi/ipmi_ssif.c
@@ -88,6 +88,8 @@
#define SSIF_MSG_JIFFIES ((SSIF_MSG_USEC * 1000) / TICK_NSEC)
#define SSIF_MSG_PART_JIFFIES ((SSIF_MSG_PART_USEC * 1000) / TICK_NSEC)
+#define SSIF_MAX_MSG_LENGTH 255
+
enum ssif_intf_state {
SSIF_NORMAL,
SSIF_GETTING_FLAGS,
@@ -956,10 +958,21 @@ static int start_resend(struct ssif_info *ssif_info)
ssif_info->multi_data = ssif_info->data;
ssif_info->multi_len = ssif_info->data_len;
/*
+ * As per spec SSIF_MULTI_n_PART's middle transfers
+ * must be of size 32 bytes, and the last message
+ * should be of bytes 1-31. We won't be able to transfer
+ * any messages coming from the upper layer which is exactly
+ * n multiple of 32 where n > 1.
+ */
+
+ if (!(ssif_info->data_len % 32))
+ return -EINVAL;
+ /*
* Subtle thing, this is 32, not 33, because we will
* overwrite the thing at position 32 (which was just
* transmitted) with the new length.
*/
+
ssif_info->multi_pos = 32;
ssif_info->data[0] = 32;
} else {
@@ -1499,9 +1512,16 @@ static int ssif_probe(struct i2c_client *client, const
struct i2c_device_id *id)
* start and the next message is always going
* to be 1-31 bytes in length. Not ideal, but
* it should work.
+ * SSIF supports message length up to 255 bytes.
+ * If we limit the length to 63 here, we won't be
+ * able to send messages larger than 63 bytes.
+ * Chunking of data is done based on 32 bytes and
+ * not based on the max_xmit_msg_size. So additional
+ * logic to check whether the message length is n*32,
+ * where n > 1, is done in function start_resend().
*/
- if (ssif_info->max_xmit_msg_size > 63)
- ssif_info->max_xmit_msg_size = 63;
+ if (ssif_info->max_xmit_msg_size > SSIF_MAX_MSG_LENGTH)
+ ssif_info->max_xmit_msg_size =
SSIF_MAX_MSG_LENGTH;
break;
default:
--
2.7.4
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Openipmi-developer mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openipmi-developer