Hi All,

Please find in the attached the patch for HPM.1 functionality of ipmitool.

The patch includes the following fixes and improvements:

- The length of the Upload Firmware Block command is shrunk to conform to the IPMI-defined maximum for non-bridged messages (32 bytes) when sent via KCS interface.

- Double bridging via LAN is taken into account when calculating the maximum Upload Firmware Block command length.

- Handling of the long response option of the Upload Firmware Block command is implemented.

- The Component parameter of the Finish Firmware Upload command is changed from component mask to component ID to conform to the HPM.1 specification.

- The Rollback Override parameter of the Activate Firmware command is implemented. The hpm activate command-line parameter is extended with optional "norollback" parameter.

- A bug that prevented from usage of multiple components in a single upgrade image is fixed.

- Garbage in output of the component's description property is eliminated.

Regards,
Dmitry

Index: lib/ipmi_hpmfwupg.c
===================================================================
RCS file: /cvsroot/ipmitool/ipmitool/lib/ipmi_hpmfwupg.c,v
retrieving revision 1.11
diff -p -u -r1.11 ipmi_hpmfwupg.c
--- lib/ipmi_hpmfwupg.c 18 Jun 2007 12:45:04 -0000      1.11
+++ lib/ipmi_hpmfwupg.c 6 Jul 2007 14:13:51 -0000
@@ -424,7 +424,7 @@ struct HpmfwupgInitiateUpgradeActionCtx
  */
 
 #define HPMFWUPG_SEND_DATA_COUNT_MAX   32
-#define HPMFWUPG_SEND_DATA_COUNT_KCS   HPMFWUPG_SEND_DATA_COUNT_MAX
+#define HPMFWUPG_SEND_DATA_COUNT_KCS   30
 #define HPMFWUPG_SEND_DATA_COUNT_LAN   26
 #define HPMFWUPG_SEND_DATA_COUNT_IPMB  26
 #define HPMFWUPG_SEND_DATA_COUNT_IPMBL 26
@@ -433,12 +433,15 @@ struct HpmfwupgUploadFirmwareBlockReq
 {
    unsigned char picmgId;
    unsigned char blockNumber;
-   unsigned char data[HPMFWUPG_SEND_DATA_COUNT_MAX];
+   unsigned char data[HPMFWUPG_SEND_DATA_COUNT_MAX - 2];
 }__attribute__ ((packed));
 
 struct HpmfwupgUploadFirmwareBlockResp
 {
   unsigned char picmgId;
+  unsigned long offset;
+  unsigned long size;
+  unsigned char long_resp;
 }__attribute__ ((packed));
 
 struct HpmfwupgUploadFirmwareBlockCtx
@@ -457,7 +460,7 @@ struct HpmfwupgUploadFirmwareBlockCtx
 struct HpmfwupgFinishFirmwareUploadReq
 {
    unsigned char picmgId;
-   struct HpmfwupgComponentBitMask componentsMask;
+   unsigned char component;
    unsigned char imageLength[HPMFWUPG_IMAGE_SIZE_BYTE_COUNT];
 }__attribute__ ((packed));
 
@@ -479,6 +482,7 @@ struct HpmfwupgFinishFirmwareUploadCtx
 struct HpmfwupgActivateFirmwareReq
 {
    unsigned char picmgId;
+   unsigned char rollback_override;
 }__attribute__ ((packed));
 
 struct HpmfwupgActivateFirmwareResp
@@ -1031,7 +1035,7 @@ int HpmfwupgPreparationStage(struct ipmi
             componentId++ )
       {
          /* Reset component properties */
-         memset(&pFwupgCtx->genCompProp[0], 0, sizeof (struct 
HpmfwupgGetGeneralPropResp));
+         memset(&pFwupgCtx->genCompProp[componentId], 0, sizeof (struct 
HpmfwupgGetGeneralPropResp));
          
          if ( (1 << componentId & pImageHeader->components.ComponentBits.byte) 
)
          {
@@ -1156,11 +1160,11 @@ int HpmfwupgUpgradeStage(struct ipmi_int
                struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd;
                struct HpmfwupgUploadFirmwareBlockCtx   uploadCmd;
                struct HpmfwupgFinishFirmwareUploadCtx  finishCmd;
-               unsigned char* pData, *pDataInitial;
+               unsigned char* pData1, *pData2, *pDataInitial;
                unsigned char  count;
                unsigned int   totalSent = 0;
                unsigned char  bufLength = 0;
-               unsigned int   firmwareLength = 0;
+               unsigned int   firmwareLength = 0, upload_size, totalSize;
                
                /* Send initiate command */
                initUpgActionCmd.req.componentsMask = pActionRecord->components;
@@ -1187,13 +1191,16 @@ int HpmfwupgUpgradeStage(struct ipmi_int
                                                                
pFwImage->version[5]); 
                      
                   pDataInitial = ((unsigned char*)pFwImage + sizeof(struct 
HpmfwupgFirmwareImage));
-                  pData = pDataInitial;
+                  pData1 = pDataInitial;
+                  pData2 = pDataInitial;  
                                     
                   /* Find max buffer length according the connection 
                      parameters */
                   if ( strstr(intf->name,"lan") != NULL )
                   {
-                     bufLength = HPMFWUPG_SEND_DATA_COUNT_LAN;
+                     bufLength = HPMFWUPG_SEND_DATA_COUNT_LAN - 3;
+                     if ( intf->transit_addr != intf->my_addr && 
intf->transit_addr != 0 )
+                         bufLength -= 8;
                   }
                   else
                   {
@@ -1206,7 +1213,7 @@ int HpmfwupgUpgradeStage(struct ipmi_int
                         )
                      )
                      {
-                        bufLength = HPMFWUPG_SEND_DATA_COUNT_KCS;
+                        bufLength = HPMFWUPG_SEND_DATA_COUNT_KCS - 2;
                      }
                      else
                      {
@@ -1227,30 +1234,39 @@ int HpmfwupgUpgradeStage(struct ipmi_int
                   firmwareLength |= (pFwImage->length[2] << 16) & 0xff0000;
                   firmwareLength |= (pFwImage->length[3] << 24) & 0xff000000;
 
-                  while ( (pData < (pDataInitial + firmwareLength)) && 
+                  totalSize = upload_size = firmwareLength;  
+
+                  while ( (pData1 < (pData2 + upload_size)) && 
                           (rc == HPMFWUPG_SUCCESS) )
                   {
-                     if ( pData + bufLength 
-                          <= (pDataInitial + firmwareLength) )
+                     if ( pData1 + bufLength 
+                          <= (pData2 + upload_size) )
                      {        
                         count = bufLength;                
                      }
                      else
                      {
-                        count = (unsigned char)((pDataInitial + 
firmwareLength) - pData);
+                        count = (unsigned char)((pData2 + upload_size) - 
pData1);
                      }
                      totalSent += count;
-                     memcpy(&uploadCmd.req.data, pData, bufLength);
+                     memcpy(&uploadCmd.req.data, pData1, bufLength);
                      
                      rc = HpmfwupgUploadFirmwareBlock(intf, &uploadCmd, 
pFwupgCtx, count);
                   
                      if ( rc == HPMFWUPG_SUCCESS )
                      {
                         uploadCmd.req.blockNumber++;
-                        pData += count;
+                        if (uploadCmd.resp.long_resp)
+                        {
+                            pData1 = pData2 = pDataInitial + 
uploadCmd.resp.offset;
+                            upload_size = uploadCmd.resp.size;
+                            totalSize = totalSent + upload_size;
+                            continue;
+                        }
+                        pData1 += count;
                         /* avoid lprintf to control \n generation */
                         printf("    Writing firmware: %.0f %c completed\r", 
-                               (float)totalSent/firmwareLength*100, '%');
+                               (float)totalSent/totalSize*100, '%');
                         fflush(stdout);
                      }
                      else if ( rc == HPMFWUPG_UPLOAD_BLOCK_LENGTH )
@@ -1268,13 +1284,21 @@ int HpmfwupgUpgradeStage(struct ipmi_int
                
                   if ( rc == HPMFWUPG_SUCCESS )
                   {
+                     int i;
+
+                     for (i = 0; i < HPMFWUPG_COMPONENT_ID_MAX; i++) {
+                        if (pActionRecord->components.ComponentBits.byte & (1 
<< i)) {
+                            break;
+                        }
+                     }
+
                      /* Send finish component */
                      /* Set image length */
-                     finishCmd.req.componentsMask = pActionRecord->components;
-                     finishCmd.req.imageLength[0] = pFwImage->length[0];
-                     finishCmd.req.imageLength[1] = pFwImage->length[1];
-                     finishCmd.req.imageLength[2] = pFwImage->length[2];
-                     finishCmd.req.imageLength[3] = pFwImage->length[3];
+                     finishCmd.req.component = i;
+                     finishCmd.req.imageLength[0] = totalSent & 0xFF;
+                     finishCmd.req.imageLength[1] = (totalSent >> 8) & 0xFF;
+                     finishCmd.req.imageLength[2] = (totalSent >> 16) & 0xFF;
+                     finishCmd.req.imageLength[3] = (totalSent >> 24) & 0xFF;
                      rc = HpmfwupgFinishFirmwareUpload(intf, &finishCmd, 
pFwupgCtx);
                      pImagePtr = pDataInitial + firmwareLength;
                   }
@@ -1566,7 +1590,11 @@ int HpmfwupgGetComponentProperties(struc
                memcpy(&pCtx->resp, rsp->data, sizeof(struct 
HpmfwupgGetDescStringResp));
                if ( verbose )
                {
-                  lprintf(LOG_NOTICE,"Description string: %s\n", 
pCtx->resp.Response.descStringResp.descString);
+                  char desc[HPMFWUPG_DESC_STRING_LENGTH + 1];
+                  int len = HPMFWUPG_DESC_STRING_LENGTH > rsp->data_len ? 
rsp->data_len : HPMFWUPG_DESC_STRING_LENGTH;
+                  memcpy(desc, pCtx->resp.Response.descStringResp.descString, 
len);
+                  desc[len] = 0;
+                  lprintf(LOG_NOTICE,"Description string: %s\n", desc);
                }
             break;
             case HPMFWUPG_COMP_ROLLBACK_FIRMWARE_VERSION:
@@ -1743,6 +1771,29 @@ int HpmfwupgUploadFirmwareBlock(struct i
             rc = HPMFWUPG_ERROR;
          }
       }
+      else if ( rsp->ccode == 0x00 )
+      {
+         if ( (rsp->data_len != 1) && (rsp->data_len != 9))
+         {
+            lprintf(LOG_NOTICE,"Error uploading firmware block\n");
+            rc = HPMFWUPG_ERROR;
+         }
+         else
+         {
+            memset(&pCtx->resp, 0, sizeof(pCtx->resp));
+            if ( rsp->data_len == 9 ) {
+               pCtx->resp.long_resp = 1;
+               pCtx->resp.offset = rsp->data[1];
+               pCtx->resp.offset |= (unsigned long)rsp->data[2] << 8;
+               pCtx->resp.offset |= (unsigned long)rsp->data[3] << 16;
+               pCtx->resp.offset |= (unsigned long)rsp->data[4] << 24;
+               pCtx->resp.size = rsp->data[5];
+               pCtx->resp.size |= (unsigned long)rsp->data[6] << 8;
+               pCtx->resp.size |= (unsigned long)rsp->data[7] << 16;
+               pCtx->resp.size |= (unsigned long)rsp->data[8] << 24;
+            }
+         }
+      }
    }
    else
    {
@@ -1805,7 +1856,8 @@ int HpmfwupgActivateFirmware(struct ipmi
    req.msg.netfn    = IPMI_NETFN_PICMG;
        req.msg.cmd      = HPMFWUPG_ACTIVATE_FIRMWARE;
        req.msg.data     = (unsigned char*)&pCtx->req;
-       req.msg.data_len = sizeof(struct HpmfwupgActivateFirmwareReq);
+       req.msg.data_len = sizeof(struct HpmfwupgActivateFirmwareReq) -
+          (!pCtx->req.rollback_override ? 1 : 0);
       
    rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx); 
    
@@ -2187,7 +2239,8 @@ struct ipmi_rs * HpmfwupgSendCmd(struct 
                req.msg.netfn == IPMI_NETFN_PICMG
                &&
                ( req.msg.cmd == HPMFWUPG_ACTIVATE_FIRMWARE ||
-                 req.msg.cmd == HPMFWUPG_MANUAL_FIRMWARE_ROLLBACK )
+                 req.msg.cmd == HPMFWUPG_MANUAL_FIRMWARE_ROLLBACK ||
+                 req.msg.cmd == HPMFWUPG_GET_UPGRADE_STATUS )
                  
             )
             {
@@ -2350,7 +2403,7 @@ static void HpmfwupgPrintUsage(void)
    lprintf(LOG_NOTICE,"upgrade <file> activate - Upgrade the firmware using a 
valid HPM.1 image <file>");
    lprintf(LOG_NOTICE,"                          If activate is specified, 
activate new firmware rigth");
    lprintf(LOG_NOTICE,"                          away");
-   lprintf(LOG_NOTICE,"activate                - Activate the newly uploaded 
firmware");
+   lprintf(LOG_NOTICE,"activate [norollback]   - Activate the newly uploaded 
firmware");
    lprintf(LOG_NOTICE,"targetcap               - Get the target upgrade 
capabilities");
    lprintf(LOG_NOTICE,"compprop <id> <select>  - Get the specified component 
properties");
    lprintf(LOG_NOTICE,"                          Valid component <ID> 0-7 ");
@@ -2397,9 +2450,13 @@ int ipmi_hpmfwupg_main(struct ipmi_intf 
          HpmfwupgPrintUsage();         
       }
    }
-   else if ( (argc == 1) && (strcmp(argv[0], "activate") == 0) )
+   else if ( (argc >= 1) && (strcmp(argv[0], "activate") == 0) )
    {
       struct HpmfwupgActivateFirmwareCtx cmdCtx;
+      if ( (argc == 2) && (strcmp(argv[1], "norollback") == 0) )
+         cmdCtx.req.rollback_override = 1;
+      else
+         cmdCtx.req.rollback_override = 0;
       rc = HpmfwupgActivateFirmware(intf, &cmdCtx, NULL);
    }
    else if ( (argc == 1) && (strcmp(argv[0], "targetcap") == 0) )
-------------------------------------------------------------------------
This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/
_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel

Reply via email to