@@ -489,13 +489,13 @@ static int ipmi_ssif_thread(void *data)
489
489
490
490
if (ssif_info -> i2c_read_write == I2C_SMBUS_WRITE ) {
491
491
result = i2c_smbus_write_block_data (
492
- ssif_info -> client , SSIF_IPMI_REQUEST ,
492
+ ssif_info -> client , ssif_info -> i2c_command ,
493
493
ssif_info -> i2c_data [0 ],
494
494
ssif_info -> i2c_data + 1 );
495
495
ssif_info -> done_handler (ssif_info , result , NULL , 0 );
496
496
} else {
497
497
result = i2c_smbus_read_block_data (
498
- ssif_info -> client , SSIF_IPMI_RESPONSE ,
498
+ ssif_info -> client , ssif_info -> i2c_command ,
499
499
ssif_info -> i2c_data );
500
500
if (result < 0 )
501
501
ssif_info -> done_handler (ssif_info , result ,
@@ -534,6 +534,7 @@ static void start_get(struct ssif_info *ssif_info)
534
534
int rv ;
535
535
536
536
ssif_info -> rtc_us_timer = 0 ;
537
+ ssif_info -> multi_pos = 0 ;
537
538
538
539
rv = ssif_i2c_send (ssif_info , msg_done_handler , I2C_SMBUS_READ ,
539
540
SSIF_IPMI_RESPONSE ,
@@ -631,9 +632,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
631
632
ssif_inc_stat (ssif_info , received_message_parts );
632
633
633
634
/* Remove the multi-part read marker. */
634
- for (i = 0 ; i < (len - 2 ); i ++ )
635
- ssif_info -> data [i ] = data [i + 2 ];
636
635
len -= 2 ;
636
+ for (i = 0 ; i < len ; i ++ )
637
+ ssif_info -> data [i ] = data [i + 2 ];
637
638
ssif_info -> multi_len = len ;
638
639
ssif_info -> multi_pos = 1 ;
639
640
@@ -660,9 +661,9 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
660
661
goto continue_op ;
661
662
}
662
663
663
- blocknum = data [ssif_info -> multi_len ];
664
+ blocknum = data [0 ];
664
665
665
- if (ssif_info -> multi_len + len - 1 > IPMI_MAX_MSG_LENGTH ) {
666
+ if (ssif_info -> multi_len + len - 1 > IPMI_MAX_MSG_LENGTH ) {
666
667
/* Received message too big, abort the operation. */
667
668
result = - E2BIG ;
668
669
if (ssif_info -> ssif_debug & SSIF_DEBUG_MSG )
@@ -672,15 +673,15 @@ static void msg_done_handler(struct ssif_info *ssif_info, int result,
672
673
}
673
674
674
675
/* Remove the blocknum from the data. */
675
- for (i = 0 ; i < (len - 1 ); i ++ )
676
- ssif_info -> data [i + ssif_info -> multi_len ] = data [i + 1 ];
677
676
len -- ;
677
+ for (i = 0 ; i < len ; i ++ )
678
+ ssif_info -> data [i + ssif_info -> multi_len ] = data [i + 1 ];
678
679
ssif_info -> multi_len += len ;
679
680
if (blocknum == 0xff ) {
680
681
/* End of read */
681
682
len = ssif_info -> multi_len ;
682
683
data = ssif_info -> data ;
683
- } else if (( blocknum + 1 ) != ssif_info -> multi_pos ) {
684
+ } else if (blocknum + 1 != ssif_info -> multi_pos ) {
684
685
/*
685
686
* Out of sequence block, just abort. Block
686
687
* numbers start at zero for the second block,
@@ -880,7 +881,11 @@ static void msg_written_handler(struct ssif_info *ssif_info, int result,
880
881
}
881
882
882
883
if (ssif_info -> multi_data ) {
883
- /* In the middle of a multi-data write. */
884
+ /*
885
+ * In the middle of a multi-data write. See the comment
886
+ * in the SSIF_MULTI_n_PART case in the probe function
887
+ * for details on the intricacies of this.
888
+ */
884
889
int left ;
885
890
886
891
ssif_inc_stat (ssif_info , sent_messages_parts );
@@ -984,7 +989,7 @@ static int start_send(struct ssif_info *ssif_info,
984
989
return - E2BIG ;
985
990
986
991
ssif_info -> retries_left = SSIF_SEND_RETRIES ;
987
- memcpy (ssif_info -> data + 1 , data , len );
992
+ memcpy (ssif_info -> data + 1 , data , len );
988
993
ssif_info -> data_len = len ;
989
994
return start_resend (ssif_info );
990
995
}
@@ -1487,13 +1492,33 @@ static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id)
1487
1492
break ;
1488
1493
1489
1494
case SSIF_MULTI_2_PART :
1490
- if (ssif_info -> max_xmit_msg_size > 64 )
1491
- ssif_info -> max_xmit_msg_size = 64 ;
1495
+ if (ssif_info -> max_xmit_msg_size > 63 )
1496
+ ssif_info -> max_xmit_msg_size = 63 ;
1492
1497
if (ssif_info -> max_recv_msg_size > 62 )
1493
1498
ssif_info -> max_recv_msg_size = 62 ;
1494
1499
break ;
1495
1500
1496
1501
case SSIF_MULTI_n_PART :
1502
+ /*
1503
+ * The specification is rather confusing at
1504
+ * this point, but I think I understand what
1505
+ * is meant. At least I have a workable
1506
+ * solution. With multi-part messages, you
1507
+ * cannot send a message that is a multiple of
1508
+ * 32-bytes in length, because the start and
1509
+ * middle messages are 32-bytes and the end
1510
+ * message must be at least one byte. You
1511
+ * can't fudge on an extra byte, that would
1512
+ * screw up things like fru data writes. So
1513
+ * we limit the length to 63 bytes. That way
1514
+ * a 32-byte message gets sent as a single
1515
+ * part. A larger message will be a 32-byte
1516
+ * start and the next message is always going
1517
+ * to be 1-31 bytes in length. Not ideal, but
1518
+ * it should work.
1519
+ */
1520
+ if (ssif_info -> max_xmit_msg_size > 63 )
1521
+ ssif_info -> max_xmit_msg_size = 63 ;
1497
1522
break ;
1498
1523
1499
1524
default :
0 commit comments