tags 754807 + patch
thanks
Description: Retry ssif reads as needed
Bug-Debian: http://bugs.debian.org/754807
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/freeipmi/+bug/1324992
Author: Shashi Dande <shashi.da...@hp.com>
Last-Update: 2014-05-30
Applied-Upstream: http://svn.savannah.gnu.org/viewvc?view=rev&root=freeipmi&revision=10072

Index: freeipmi/libfreeipmi/api/ipmi-ssif-driver-api.c
===================================================================
--- freeipmi.orig/libfreeipmi/api/ipmi-ssif-driver-api.c
+++ freeipmi/libfreeipmi/api/ipmi-ssif-driver-api.c
@@ -319,6 +319,8 @@ ipmi_ssif_cmd_api (ipmi_ctx_t ctx,
   uint8_t cmd = 0;             /* used for debugging */
   uint8_t group_extension = 0; /* used for debugging */
   uint64_t val;
+  struct timespec request, remain;
+  uint8_t retry = IPMI_SSIF_RETRY_DEFAULT;
 
   if (!ctx || ctx->magic != IPMI_CTX_MAGIC)
     {
@@ -368,8 +370,38 @@ ipmi_ssif_cmd_api (ipmi_ctx_t ctx,
   if (_ssif_cmd_write (ctx, cmd, group_extension, obj_cmd_rq) < 0)
     return (-1);
 
+  /******************************************************************************
+    12.9 SMBus NACKs and Error Recovery:
+    ====================================
+    The BMC can NACK the SMBus host controller if it is not ready to accept a new 
+    transaction. Typically, this will be exhibited by the BMC NACK'ing its slave 
+    address. 
+    
+    If the BMC NACKs a single part transaction, software can simply retry it. 
+    If a 'middle' or 'end' transaction is NACK'd, software should not retry the 
+    particular but should restart the multi-part read or write from the beginning
+    Start transaction for the transfer.
+  *******************************************************************************/
   if (_ssif_cmd_read (ctx, cmd, group_extension, obj_cmd_rs) < 0)
-    return (-1);
+    {
+      while (1)
+        {
+          request.tv_sec = 0; 
+          request.tv_nsec = IPMI_SSIF_TIMEOUT_DEFAULT;
+          if (nanosleep (&request, &remain) < 0 )
+            return (-1);
+
+          if (_ssif_cmd_read (ctx, cmd, group_extension, obj_cmd_rs) < 0)
+            {
+              if (retry == 0)
+                return (-1);
+        
+              retry--;        
+            }
+            else
+              break;
+        }
+    }
 
   return (0);
 }
Index: freeipmi/libfreeipmi/api/ipmi-ssif-driver-api.h
===================================================================
--- freeipmi.orig/libfreeipmi/api/ipmi-ssif-driver-api.h
+++ freeipmi/libfreeipmi/api/ipmi-ssif-driver-api.h
@@ -23,6 +23,9 @@
 #include <freeipmi/api/ipmi-api.h>
 #include <freeipmi/fiid/fiid.h>
 
+#define IPMI_SSIF_RETRY_DEFAULT       5
+#define IPMI_SSIF_TIMEOUT_DEFAULT     20000000 /* 20 ms */
+
 int ipmi_ssif_cmd_api (ipmi_ctx_t ctx,
                        fiid_obj_t obj_cmd_rq,
                        fiid_obj_t obj_cmd_rs);

Reply via email to