--- Orig_ipmi_hpmfwupg.c	2007-09-18 09:30:11.476678000 -0700
+++ ipmi_hpmfwupg.c	2007-09-18 10:54:37.791053000 -0700
@@ -101,6 +101,21 @@
 *    as compared to the Image file (*.hpm).This will ensure that user does 
 *    not update the target incase its already been updated
 *
+* 2007-09-15
+*  - The HPM Spec indicates that whenever the long duration command is sent and
+*    if it returns the completion code of 0x80 (pending) we need to retry after 
+*    minimum of 100 msec. The existing code was sending first upgrade status cmd
+*    immediately and then waiting for 100msec interval. Added the code so that it
+*    waits for the first time also when it sends the upgrade status (ie 100 msec).
+*    Incase of Initiate Upgrade Action (upgrade mode) it waits for 500 msec to give
+*    enough time for IPMC to respond back.
+*  - Fixed a problem in displaying the Rollback version when Current version
+*    and file version were same.  ie "hpm check <filename>"
+*  - Fixed calling Initiate Upgrade action correctly for each component when only a 
+*    single component is called.  ie "hpm upgrade <filename> component <ID>"
+*  - Fixed some printing stuff and also checking of typo-graphical errors when 
+*    user gives "componetn" instead of "component"
+*
 * TODO
 * ===========================================================================
 * 2007-01-11
@@ -773,7 +788,7 @@
 static unsigned char HpmfwupgCalculateChecksum(unsigned char* pData, unsigned int length);
 static int HpmfwupgGetDeviceId(struct ipmi_intf *intf, struct ipm_devid_rsp* pGetDevId);
 static int HpmfwupgGetBufferFromFile(char* imageFilename, struct HpmfwupgUpgradeCtx* pFwupgCtx);
-static int HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx);
+static int HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx,uint8_t cmd);
 
 static struct ipmi_rs *  HpmfwupgSendCmd(struct ipmi_intf *intf, struct ipmi_rq req,
                                          struct HpmfwupgUpgradeCtx* pFwupgCtx);
@@ -824,6 +839,7 @@
     printf("|ID | Name      |    Versions           |    Upload Progress  | Upload| Image |\n");
     printf("|   |           | Active| Backup| File  |0%%       50%%     100%%| Time  | Size  |\n");
     printf("|---|-----------|-------|-------|-------||----+----+----+----||-------|-------|\n");
+    fflush(stdout);
 }
 
 /****************************************************************************
@@ -839,12 +855,12 @@
 {
     int percent;
     static int old_percent=1;
+    fflush(stdout);
     if (skip) 
     { 
         printf("|       Skip        || --.-- | ----- |\n");
         return;
     }
-    fflush(stdout);
     
     percent = ((float)totalSent/displayFWLength)*100;
     if (((percent % 5) == 0))
@@ -889,6 +905,7 @@
         printf("|   |           | Active| Backup|\n");
         HpmDisplayLine("-",33 );        
    }
+    fflush(stdout);
 }
 
 /****************************************************************************
@@ -902,6 +919,7 @@
 {
       char descString[12];
       memset(&descString,0x00,12);
+      fflush(stdout);
       /*
        * Added this to ensure that even if the description string
        * is more than required it does not give problem in displaying it
@@ -941,6 +959,7 @@
               else
                 printf("%3d.%02x |",pVersion->imageMajor,pVersion->imageMinor);
       }
+      fflush(stdout);
 }
 
 
@@ -982,6 +1001,11 @@
         lprintf(LOG_NOTICE,"Board might not be supporting the HPM.1 Standards\n");
         return rc;
     }
+    if (targetCapCmd.resp.hpmVersion != 0x00)
+    {
+        lprintf(LOG_NOTICE,"Board might be supporting the HPM.1 0.90 and not the HPM.1 1.00\n");
+        return rc;
+    }
     if (option & VIEW_MODE)
     {
         lprintf(LOG_NOTICE,"-------Target Information-------");
@@ -1047,12 +1071,12 @@
                 if (rc != HPMFWUPG_SUCCESS)
                 {
                     lprintf(LOG_NOTICE,"Get CompRollbackVersion Failed for component Id %d\n",componentId);
-                } else {
-                    gVersionInfo[componentId].rollbackMajor = getCompProp.resp
-                      .Response.rollbackFwVersionResp.rollbackFwVersion[0];
-                    gVersionInfo[componentId].rollbackMinor = getCompProp.resp
-                      .Response.rollbackFwVersionResp.rollbackFwVersion[1];
+                    return rc;
                 }
+                gVersionInfo[componentId].rollbackMajor = getCompProp.resp
+                    .Response.rollbackFwVersionResp.rollbackFwVersion[0];
+                gVersionInfo[componentId].rollbackMinor = getCompProp.resp
+                    .Response.rollbackFwVersionResp.rollbackFwVersion[1];
                 mode |= ROLLBACK_VER;
             }
 
@@ -1207,7 +1231,7 @@
    }
    else
    {
-      lprintf(LOG_NOTICE,"Firmware upgrade procedure failed\n");
+      lprintf(LOG_NOTICE,"\nFirmware upgrade procedure failed\n");
    }
       
    return rc;
@@ -1614,6 +1638,9 @@
               }
               pVersionInfo->skipUpgrade = FALSE;
 
+              if (pVersionInfo->rollbackSupported)
+                 mode |= ROLLBACK_VER;
+
               if (   (pVersionInfo->imageMajor == pVersionInfo->targetMajor)
                   && (pVersionInfo->imageMinor == pVersionInfo->targetMinor))
               {
@@ -1628,7 +1655,6 @@
                            * Image version -- So now we must skip it */
                            pVersionInfo->skipUpgrade = TRUE;
                       }
-                      mode |= ROLLBACK_VER;
                   }
                   else
                   {
@@ -1888,17 +1914,7 @@
                      break;
                   }
                 
-                  /* Send initiate command */
-                  initUpgActionCmd.req.componentsMask = pActionRecord->components;
-                  /* Action is upgrade */
-                  initUpgActionCmd.req.upgradeAction  = HPMFWUPG_UPGRADE_ACTION_UPGRADE;
-                  rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx);
-               
-                  if (rc != HPMFWUPG_SUCCESS)
-                  {
-                     break;
-                  }
-                  
+ 
                   pVersionInfo = (VERSIONINFO*) &gVersionInfo[componentId];
                   
                   mode = TARGET_VER | IMAGE_VER;
@@ -1928,6 +1944,17 @@
                       HpmDisplayVersion(mode,pVersionInfo);
                   }
 
+                  /* Send initiate command */
+                  initUpgActionCmd.req.componentsMask = pActionRecord->components;
+                  /* Action is upgrade */
+                  initUpgActionCmd.req.upgradeAction  = HPMFWUPG_UPGRADE_ACTION_UPGRADE;
+                  rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx);
+                
+                  if (rc != HPMFWUPG_SUCCESS)
+	              {
+			        break;
+        		  }
+
                   /* pDataInitial is the starting pointer of the image data  */
                   /* pDataTemp is one which we will move across */
                   pData = pDataInitial;
@@ -1970,8 +1997,8 @@
                         else
                         {
                            fflush(stdout);
-                           lprintf(LOG_NOTICE,"\n Error in Upload FIRMWARE command [rc=%d]\n",rc);
-                           lprintf(LOG_NOTICE,"\n TotalSent:0x%x ",totalSent);
+                           lprintf(LOG_NOTICE,"Error in Upload FIRMWARE command [rc=%d]",rc);
+                           lprintf(LOG_NOTICE,"Total Bytes Sent:0x%x ",totalSent);
                            /* Exiting from the function */
                            rc = HPMFWUPG_ERROR;
                            break;
@@ -1985,8 +2012,8 @@
                              * blockLength is the remaining length of the firnware to upload so
                              * if its greater than the firmware length then its kind of error
                              */
-                            lprintf(LOG_NOTICE,"\n Error in Upload FIRMWARE command [rc=%d]\n",rc);
-                            lprintf(LOG_NOTICE,"\n TotalSent:0x%x Img offset:0x%x  Blk length:0x%x  Fwlen:0x%x\n",
+                            lprintf(LOG_NOTICE,"Error in Upload FIRMWARE command [rc=%d]",rc);
+                            lprintf(LOG_NOTICE,"Total Bytes Sent:0x%x Img offset:0x%x  Blk length:0x%x  Fwlen:0x%x",
                                         totalSent,imageOffset,blockLength,firmwareLength);
                             rc = HPMFWUPG_ERROR;                         
                             break;
@@ -2381,10 +2408,16 @@
                if ( verbose )
                {
                   unsigned char i = 0;
-                  lprintf(LOG_NOTICE,"OEM Properties: ");
-                  for (i=0; i < HPMFWUPG_OEM_LENGTH; i++)
+                  // OEM properties command will return Manufacturing ID (OEM Specific) first in the 
+                  // response data bytes and then follow with actual data
+                  lprintf(LOG_NOTICE,"OEM COMPONENT PROPERTIES ");
+                  lprintf(LOG_NOTICE,"-------------------------------");
+                  lprintf(LOG_NOTICE,"Manufacturer Id : 0x%04x (%s)\n",
+                                  buf2short(pCtx->resp.Response.oemProperties.oemRspData),
+                                  val2str(buf2short(pCtx->resp.Response.oemProperties.oemRspData),ipmi_oem_info));
+                  for (i=3; i < HPMFWUPG_OEM_LENGTH; i++)
                   {
-                    lprintf(LOG_NOTICE," 0x%x ", pCtx->resp.Response.oemProperties.oemRspData[i]);
+                    lprintf(LOG_NOTICE,"OEM Data[%d]   :  0x%02x ",i-3,pCtx->resp.Response.oemProperties.oemRspData[i]);
                   }
                 }                                                 
             break;
@@ -2464,7 +2497,7 @@
       /* Long duration command handling */
       if ( rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS )
       {
-         rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
+         rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx,req.msg.cmd);
       }
       else if ( rsp->ccode != 0x00 )
       {
@@ -2529,7 +2562,7 @@
                * firmware returned only offset and length so currently returning it 
                * as 0x82 - Internal CheckSum Error
                */
-              lprintf(LOG_NOTICE,"Error wrong rsp->datalen %d for Upload Firmware block command\n",rsp->data_len);
+              lprintf(LOG_DEBUG,"Error wrong rsp->datalen %d for Upload FW command",rsp->data_len);
               rsp->ccode = HPMFWUPG_INT_CHECKSUM_ERROR;
           }
         }
@@ -2537,7 +2570,7 @@
       /* Long duration command handling */
       if ( rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS )
       {
-         rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
+         rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx,req.msg.cmd);
       }
       /* 
        * If we get 0xcc here this is probably because we send an invalid sequence
@@ -2565,14 +2598,14 @@
          }
          else
          {
-            lprintf(LOG_NOTICE,"Error uploading firmware block, compcode = %x\n",  rsp->ccode);
+            lprintf(LOG_NOTICE,"Error uploading firmware block, compcode = %x",  rsp->ccode);
             rc = HPMFWUPG_ERROR;
          }
       }
    }
    else
    {
-      lprintf(LOG_NOTICE,"Error uploading firmware block\n");
+      lprintf(LOG_NOTICE,"Error uploading firmware block");
       rc = HPMFWUPG_ERROR;
    }
    
@@ -2601,7 +2634,7 @@
       /* Long duration command handling */
       if ( rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS )
       {
-         rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
+         rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx,req.msg.cmd);
       }
       else if ( rsp->ccode != IPMI_CC_OK )
       {
@@ -2644,7 +2677,7 @@
          printf("Waiting firmware activation...");
          fflush(stdout);
          
-         rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx);
+         rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx,req.msg.cmd);
 
          if ( rc == HPMFWUPG_SUCCESS )
          {
@@ -3117,7 +3150,8 @@
    return rsp;
 } 
 
-int HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx)
+
+int HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx,uint8_t longDurationCmd)
 {
    int rc = HPMFWUPG_SUCCESS;
    unsigned char upgradeTimeout = 0;
@@ -3125,6 +3159,28 @@
    struct HpmfwupgGetUpgradeStatusCtx upgStatusCmd;
 
    /* 
+    * Wait before sending the Upgrade Status command immediately 
+    * after sending the first longduration commmand.
+    */
+    switch(longDurationCmd)
+    {
+        case HPMFWUPG_INITIATE_UPGRADE_ACTION:
+                usleep(500000);     /* 500 msec */
+                break;
+        case HPMFWUPG_UPLOAD_FIRMWARE_BLOCK:
+                usleep(100000);     /* 100 msec */
+                break;
+        case HPMFWUPG_FINISH_FIRMWARE_UPLOAD:
+                usleep(100000);     /* 100 msec */
+                break;
+        case HPMFWUPG_ACTIVATE_FIRMWARE:
+                usleep(100000);     /* 100 msec */
+                break;
+        default:
+                break;
+    }
+
+   /* 
     * If we are not in upgrade context, we use default timeout values
     */
    if ( pFwupgCtx != NULL )
@@ -3205,6 +3261,7 @@
    lprintf(LOG_NOTICE,"                          2- Description string");
    lprintf(LOG_NOTICE,"                          3- Rollback firmware version");
    lprintf(LOG_NOTICE,"                          4- Deferred firmware version");
+   lprintf(LOG_NOTICE,"                          192-255 - OEM Component Properties");
    lprintf(LOG_NOTICE,"abort                   - Abort the on-going firmware upgrade");
    lprintf(LOG_NOTICE,"upgstatus               - Returns the status of the last long duration command");
    lprintf(LOG_NOTICE,"rollback                - Performs a manual rollback on the IPM Controller");
@@ -3252,6 +3309,38 @@
    else if ( strcmp(argv[0], "upgrade") == 0) 
    {
      int i =0;
+     int upgradeParamErrorFlag= FALSE;
+
+     if (argc > 5 )
+     {
+        upgradeParamErrorFlag= TRUE;
+     }
+     for (i=2; i< argc ; i++)
+     {
+        /* Check for any typographical errors */
+        if (!( 
+             (strcmp(argv[i],"activate") == 0) ||
+             (strcmp(argv[i],"all") == 0) ||
+             (strcmp(argv[i++],"component") == 0) 
+             /* Skipping the next one for component as the next argument
+              * will be integer */
+           ))
+        {
+            upgradeParamErrorFlag= TRUE;                
+            break;
+        }
+     }
+     if (upgradeParamErrorFlag)
+     {
+        lprintf(LOG_NOTICE,"  Wrong params given for hpm upgrade");
+        lprintf(LOG_NOTICE,"  upgrade <file> ");
+        lprintf(LOG_NOTICE,"  upgrade <file> all");
+        lprintf(LOG_NOTICE,"  upgrade <file> component <id>");
+        lprintf(LOG_NOTICE,"  upgrade <file> activate");
+        lprintf(LOG_NOTICE,"  upgrade <file> all activate");
+        lprintf(LOG_NOTICE,"  upgrade <file> component <id> activate");
+        exit(1);
+     }
      for (i=1; i< argc ; i++)
      {
         if (strcmp(argv[i],"activate") == 0)
@@ -3277,7 +3366,7 @@
                 /* Error Checking */
                 if (componentId >= HPMFWUPG_COMPONENT_ID_MAX) 
                 {
-                        lprintf(LOG_NOTICE,"Given component ID %d exceeds Max Comp ID %d\n",
+                        lprintf(LOG_NOTICE,"Given component ID %d exceeds Max Comp ID %d",
                              componentId, HPMFWUPG_COMPONENT_ID_MAX-1);
                         return  HPMFWUPG_ERROR;
                 }
@@ -3286,7 +3375,7 @@
             {
                 /* That indicates the user has given component on console but not
                  * given any ID */
-                lprintf(LOG_NOTICE,"No component Id provided\n");
+                lprintf(LOG_NOTICE,"No component Id provided");
                 return  HPMFWUPG_ERROR;
             }
         }
