On 07/16/2018 05:46 AM, Kamlakant Patel wrote:
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.

Sorry, but not being able to send 64, 96, etc. byte messages is just not an
option.  It certainly violates the principle of least surprise.

What we need to do is find out what the spec writers really meant. I looked
at the errata and I couldn't find anything.

-corey

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:



------------------------------------------------------------------------------
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

Reply via email to