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 <kamlakant.pa...@cavium.com> Reported-by: Karthikeyan M <karthikey...@amiindia.co.in> --- 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 Openipmi-developer@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/openipmi-developer