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