- Still in development

- Implementation now aligned with specification HPM.1 draft 0.9
- Tested with Kontron implementation
This commit is contained in:
Jean-Michel Audet 2006-12-01 16:36:54 +00:00
parent 68afc1b001
commit b548d3573b

View File

@ -41,12 +41,14 @@
/****************************************************************************
*
* Copyright (c) 2006 Kontron Canada, Inc. All Rights Reserved.
*
* HPM.1
* Hardware Platform Management
* IPM Controller Firmware Upgrade Procedure
*
* This module implements an Upgrade Agent for the IPM Controller
* Firmware Upgrade Procedure (HPM.1) specification version draft 0.74.
* Firmware Upgrade Procedure (HPM.1) specification version draft 0.9.
*
* DISCLAIMER: This module is in constant evolution and based on a non-official
* specification release. It also may not fulfill all the Upgrade
@ -94,8 +96,8 @@ extern int verbose;
#define HPMFWUPG_PICMG_IDENTIFIER 0
#define HPMFWUPG_VERSION_SIZE 6
#define HPMFWUPG_DESC_STRING_LENGTH 12
#define HPMFWUPG_DEFAULT_INACCESS_TIMEOUT 30 /* sec */
#define HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT 30 /* sec */
#define HPMFWUPG_DEFAULT_INACCESS_TIMEOUT 60 /* sec */
#define HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT 60 /* sec */
#define HPMFWUPG_MD5_SIGNATURE_LENGTH 16
/* Component IDs */
@ -160,7 +162,8 @@ struct HpmfwupgGetTargetUpgCapabilitiesResp
unsigned char ipmcRollback : 1;
unsigned char ipmcDeferActivation : 1;
unsigned char manualRollback : 1;
unsigned char reserved : 2;
unsigned char payloadAffected : 1;
unsigned char reserved : 1;
}bitField;
}GlobalCapabilities;
unsigned char upgradeTimeout;
@ -324,8 +327,8 @@ struct HpmfwupgBackupComponentsCtx
#define HPMFWUPG_SEND_DATA_COUNT_MAX 32
#define HPMFWUPG_SEND_DATA_COUNT_KCS HPMFWUPG_SEND_DATA_COUNT_MAX
#define HPMFWUPG_SEND_DATA_COUNT_LAN 28
#define HPMFWUPG_SEND_DATA_COUNT_IPMB 20
#define HPMFWUPG_SEND_DATA_COUNT_LAN 26
#define HPMFWUPG_SEND_DATA_COUNT_IPMB 18
#define HPMFWUPG_SEND_DATA_COUNT_IPMBL 14
struct HpmfwupgUploadFirmwareBlockReq
@ -482,54 +485,47 @@ struct HpmfwupgQuerySelftestResultCtx
* HPM.1 IMAGE DEFINITIONS
*/
#define HEADER_SIGNATURE_LENGTH 8
#define MANUFATURER_ID_LENGTH 3
#define PRODUCT_ID_LENGTH 2
#define TIME_LENGTH 4
#define TIMEOUT_LENGTH 2
#define COMP_REVISION_LENGTH 2
#define FIRM_REVISION_LENGTH 6
#define IMAGE_HEADER_VERSION 0
#define IMAGE_SIGNATURE "PICMGFWU"
#define HPMFWUPG_HEADER_SIGNATURE_LENGTH 8
#define HPMFWUPG_MANUFATURER_ID_LENGTH 3
#define HPMFWUPG_PRODUCT_ID_LENGTH 2
#define HPMFWUPG_TIME_LENGTH 4
#define HPMFWUPG_TIMEOUT_LENGTH 2
#define HPMFWUPG_COMP_REVISION_LENGTH 2
#define HPMFWUPG_FIRM_REVISION_LENGTH 6
#define HPMFWUPG_IMAGE_HEADER_VERSION 0
#define HPMFWUPG_IMAGE_SIGNATURE "PICMGFWU"
struct HpmfwupgImageHeader
{
char signature[HEADER_SIGNATURE_LENGTH];
char signature[HPMFWUPG_HEADER_SIGNATURE_LENGTH];
unsigned char formatVersion;
unsigned char deviceId;
unsigned char manId[MANUFATURER_ID_LENGTH];
unsigned char prodId[PRODUCT_ID_LENGTH];
unsigned char time[TIME_LENGTH];
unsigned char manId[HPMFWUPG_MANUFATURER_ID_LENGTH];
unsigned char prodId[HPMFWUPG_PRODUCT_ID_LENGTH];
unsigned char time[HPMFWUPG_TIME_LENGTH];
union
{
struct
{
unsigned char reserved : 5;
unsigned char payloadReset : 1;
unsigned char rollback : 1;
unsigned char selfTest : 1;
unsigned char reserved : 5;
unsigned char payloadAffected : 1;
unsigned char imageRollback : 1;
unsigned char imageSelfTest : 1;
} bitField;
unsigned char byte;
}imageCapabilities;
struct HpmfwupgComponentBitMask components;
unsigned char selfTestTimeout[TIMEOUT_LENGTH];
unsigned char rollbackTimeout[TIMEOUT_LENGTH];
unsigned char inaccessTimeout[TIMEOUT_LENGTH];
unsigned char compRevision[COMP_REVISION_LENGTH];
unsigned char firmRevision[FIRM_REVISION_LENGTH];
unsigned char selfTestTimeout[HPMFWUPG_TIMEOUT_LENGTH];
unsigned char rollbackTimeout[HPMFWUPG_TIMEOUT_LENGTH];
unsigned char inaccessTimeout[HPMFWUPG_TIMEOUT_LENGTH];
unsigned char compRevision[HPMFWUPG_COMP_REVISION_LENGTH];
unsigned char firmRevision[HPMFWUPG_FIRM_REVISION_LENGTH];
unsigned short oemDataLength;
unsigned char checksum;
}__attribute__ ((packed));
}__attribute__ ((packed));
#define HPMFWUPG_DESCRIPTION_LENGTH 21
struct HpmfwupgFirmwareImage
{
unsigned char version[FIRM_REVISION_LENGTH];
char desc[HPMFWUPG_DESCRIPTION_LENGTH];
unsigned int length;
}__attribute__ ((packed));
struct HpmfwupgActionRecord
{
unsigned char actionType;
@ -537,6 +533,14 @@ struct HpmfwupgActionRecord
unsigned char checksum;
}__attribute__ ((packed));
#define HPMFWUPG_FIRMWARE_SIZE_LENGTH 3
struct HpmfwupgFirmwareImage
{
unsigned char version[HPMFWUPG_FIRM_REVISION_LENGTH];
char desc[HPMFWUPG_DESCRIPTION_LENGTH];
unsigned char length[HPMFWUPG_FIRMWARE_SIZE_LENGTH];
}__attribute__ ((packed));
struct HpmfwupgUpgradeCtx
{
@ -563,26 +567,37 @@ static int HpmfwupgUpgrade(struct ipmi_intf *intf, char* imageFilename, int acti
static int HpmfwupgValidateImageIntegrity(struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgPreparationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgValidationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf, struct HpmfwupgGetTargetUpgCapabilitiesCtx* pCtx);
static int HpmfwupgGetComponentProperties(struct ipmi_intf *intf, struct HpmfwupgGetComponentPropertiesCtx* pCtx);
static int HpmfwupgQuerySelftestResult(struct ipmi_intf *intf, struct HpmfwupgQuerySelftestResultCtx* pCtx,
static int HpmfwupgActivationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf,
struct HpmfwupgGetTargetUpgCapabilitiesCtx* pCtx);
static int HpmfwupgGetComponentProperties(struct ipmi_intf *intf,
struct HpmfwupgGetComponentPropertiesCtx* pCtx);
static int HpmfwupgQuerySelftestResult(struct ipmi_intf *intf,
struct HpmfwupgQuerySelftestResultCtx* pCtx,
struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf, struct HpmfwupgQueryRollbackStatusCtx* pCtx,
static int HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf,
struct HpmfwupgQueryRollbackStatusCtx* pCtx,
struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgPrepareComponents(struct ipmi_intf *intf, struct HpmfwupgPrepareComponentsCtx* pCtx,
static int HpmfwupgPrepareComponents(struct ipmi_intf *intf,
struct HpmfwupgPrepareComponentsCtx* pCtx,
struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgBackupComponents(struct ipmi_intf *intf, struct HpmfwupgBackupComponentsCtx* pCtx,
static int HpmfwupgBackupComponents(struct ipmi_intf *intf,
struct HpmfwupgBackupComponentsCtx* pCtx,
struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgUploadFirmwareBlock(struct ipmi_intf *intf, struct HpmfwupgUploadFirmwareBlockCtx* pCtx,
static int HpmfwupgUploadFirmwareBlock(struct ipmi_intf *intf,
struct HpmfwupgUploadFirmwareBlockCtx* pCtx,
struct HpmfwupgUpgradeCtx* pFwupgCtx, int count);
static int HpmfwupgFinishFirmwareUpload(struct ipmi_intf *intf, struct HpmfwupgFinishFirmwareUploadCtx* pCtx,
static int HpmfwupgFinishFirmwareUpload(struct ipmi_intf *intf,
struct HpmfwupgFinishFirmwareUploadCtx* pCtx,
struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgActivateFirmware(struct ipmi_intf *intf, struct HpmfwupgActivateFirmwareCtx* pCtx,
static int HpmfwupgActivateFirmware(struct ipmi_intf *intf,
struct HpmfwupgActivateFirmwareCtx* pCtx,
struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf, struct HpmfwupgGetUpgradeStatusCtx* pCtxstruct,
static int HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf,
struct HpmfwupgGetUpgradeStatusCtx* pCtxstruct,
struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmfwupgManualFirmwareRollback(struct ipmi_intf *intf, struct HpmfwupgManualFirmwareRollbackCtx* pCtx,
static int HpmfwupgManualFirmwareRollback(struct ipmi_intf *intf,
struct HpmfwupgManualFirmwareRollbackCtx* pCtx,
struct HpmfwupgUpgradeCtx* pFwupgCtx);
static void HpmfwupgPrintUsage(void);
static unsigned char HpmfwupgCalculateChecksum(unsigned char* pData, unsigned int length);
@ -599,7 +614,7 @@ static struct ipmi_rs * HpmfwupgSendCmd(struct ipmi_intf *intf, struct ipmi_rq
*
* Description: This function performs the HPM.1 firmware upgrade procedure as
* defined the IPM Controller Firmware Upgrade Specification
* version x.xx
* version 0.9
*
*****************************************************************************/
int HpmfwupgUpgrade(struct ipmi_intf *intf, char* imageFilename, int activate)
@ -668,12 +683,12 @@ int HpmfwupgUpgrade(struct ipmi_intf *intf, char* imageFilename, int activate)
}
/*
* VALIDATION STAGE
* ACTIVATION STAGE
*/
if ( rc == HPMFWUPG_SUCCESS && activate )
{
printf("Performing validation stage: \n");
rc = HpmfwupgValidationStage(intf, &fwupgCtx);
printf("Performing activation stage: \n");
rc = HpmfwupgActivationStage(intf, &fwupgCtx);
if ( rc != HPMFWUPG_SUCCESS )
{
free(fwupgCtx.pImageData);
@ -689,7 +704,7 @@ int HpmfwupgUpgrade(struct ipmi_intf *intf, char* imageFilename, int activate)
{
printf("\nFirmware upgrade procedure failed\n\n");
}
return rc;
}
@ -699,7 +714,7 @@ int HpmfwupgUpgrade(struct ipmi_intf *intf, char* imageFilename, int activate)
*
* Description: This function validates a HPM.1 firmware image file as defined
* in section 4 of the IPM Controller Firmware Upgrade
* Specification version draft 0.74
* Specification version draft 0.9
*
*****************************************************************************/
int HpmfwupgValidateImageIntegrity(struct HpmfwupgUpgradeCtx* pFwupgCtx)
@ -729,13 +744,16 @@ int HpmfwupgValidateImageIntegrity(struct HpmfwupgUpgradeCtx* pFwupgCtx)
if ( rc == HPMFWUPG_SUCCESS )
{
/* Validate Header signature */
if ( strncmp(pImageHeader->signature, IMAGE_SIGNATURE, HEADER_SIGNATURE_LENGTH) == 0 )
if ( strncmp(pImageHeader->signature, HPMFWUPG_IMAGE_SIGNATURE, HPMFWUPG_HEADER_SIGNATURE_LENGTH) == 0 )
{
/* Validate Header image format version */
if ( pImageHeader->formatVersion == IMAGE_HEADER_VERSION )
if ( pImageHeader->formatVersion == HPMFWUPG_IMAGE_HEADER_VERSION )
{
/* Validate header checksum */
if ( HpmfwupgCalculateChecksum((unsigned char*)pImageHeader, sizeof(struct HpmfwupgImageHeader)) != 0 )
if ( HpmfwupgCalculateChecksum((unsigned char*)pImageHeader,
sizeof(struct HpmfwupgImageHeader) +
pImageHeader->oemDataLength +
sizeof(unsigned char)/*checksum*/) != 0 )
{
printf("\n Invalid header checksum\n");
rc = HPMFWUPG_ERROR;
@ -762,7 +780,7 @@ int HpmfwupgValidateImageIntegrity(struct HpmfwupgUpgradeCtx* pFwupgCtx)
*
* Description: This function the preperation stage of a firmware upgrade
* procedure as defined in section 3.2 of the IPM Controller
* Firmware Upgrade Specification version draft 0.74
* Firmware Upgrade Specification version draft 0.9
*
*****************************************************************************/
int HpmfwupgPreparationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx)
@ -781,18 +799,21 @@ int HpmfwupgPreparationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx*
if ( pImageHeader->deviceId == pFwupgCtx->devId.device_id )
{
/* Validate product ID */
if ( memcmp(pImageHeader->prodId, pFwupgCtx->devId.product_id, PRODUCT_ID_LENGTH ) == 0 )
if ( memcmp(pImageHeader->prodId, pFwupgCtx->devId.product_id, HPMFWUPG_PRODUCT_ID_LENGTH ) == 0 )
{
/* Validate man ID */
if ( memcmp(pImageHeader->manId, pFwupgCtx->devId.manufacturer_id, MANUFATURER_ID_LENGTH ) != 0 )
if ( memcmp(pImageHeader->manId, pFwupgCtx->devId.manufacturer_id,
HPMFWUPG_MANUFATURER_ID_LENGTH ) != 0 )
{
printf("\n Invalid image file for manufacturer %u\n", buf2short(pImageHeader->manId));
printf("\n Invalid image file for manufacturer %u\n",
buf2short(pFwupgCtx->devId.manufacturer_id));
rc = HPMFWUPG_ERROR;
}
}
else
{
printf("\n Invalid image file for product %u\n", buf2short(pImageHeader->prodId));
printf("\n Invalid image file for product %u\n",
buf2short(pFwupgCtx->devId.product_id));
rc = HPMFWUPG_ERROR;
}
@ -829,7 +850,7 @@ int HpmfwupgPreparationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx*
}
else
{
printf("\n Upgrade agent use both IPMB-A and IPMB-B. Cannot ontinue\n");
printf("\n This Upgrade Agent uses both IPMB-A and IPMB-B. Cannot continue\n");
rc = HPMFWUPG_ERROR;
}
}
@ -878,7 +899,7 @@ int HpmfwupgPreparationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx*
*
* Description: This function the upgrade stage of a firmware upgrade
* procedure as defined in section 3.3 of the IPM Controller
* Firmware Upgrade Specification version draft 0.74
* Firmware Upgrade Specification version draft 0.9
*
*****************************************************************************/
int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx)
@ -887,16 +908,20 @@ int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwu
unsigned char* pImagePtr;
struct HpmfwupgActionRecord* pActionRecord;
unsigned int actionsSize;
struct HpmfwupgImageHeader* pImageHeader = (struct HpmfwupgImageHeader*)
pFwupgCtx->pImageData;
/* Place pointer after image header */
pImagePtr = (unsigned char*)
(pFwupgCtx->pImageData + sizeof(struct HpmfwupgImageHeader));
(pFwupgCtx->pImageData + sizeof(struct HpmfwupgImageHeader) +
pImageHeader->oemDataLength + sizeof(unsigned char)/*checksum*/);
/* Deternime actions size */
actionsSize = pFwupgCtx->imageSize - sizeof(struct HpmfwupgImageHeader);
/* Perform actions defined in the image */
while( ( pImagePtr < (pFwupgCtx->pImageData + pFwupgCtx->imageSize - 16)) &&
while( ( pImagePtr < (pFwupgCtx->pImageData + pFwupgCtx->imageSize -
HPMFWUPG_MD5_SIGNATURE_LENGTH)) &&
( rc == HPMFWUPG_SUCCESS) )
{
/* Get action record */
@ -967,6 +992,8 @@ int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwu
unsigned char count;
unsigned int totalSent = 0;
unsigned char bufLength = 0;
unsigned int firmwareLength = 0;
/* Initialize parameters */
uploadCmd.req.componentsMask = pActionRecord->components;
uploadCmd.req.blockNumber = 0;
@ -979,6 +1006,7 @@ int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwu
pFwImage->version[3],
pFwImage->version[4],
pFwImage->version[5]);
pDataInitial = ((unsigned char*)pFwImage + sizeof(struct HpmfwupgFirmwareImage));
pData = pDataInitial;
@ -1007,24 +1035,30 @@ int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwu
}
}
while ( (pData < (pDataInitial + pFwImage->length)) &&
/* Get firmware length */
firmwareLength = pFwImage->length[0];
firmwareLength |= (pFwImage->length[1] << 8) & 0xff00;
firmwareLength |= (pFwImage->length[2] << 16) & 0xff0000;
while ( (pData < (pDataInitial + firmwareLength)) &&
(rc == HPMFWUPG_SUCCESS) )
{
if ( pData + bufLength
<= (pDataInitial + pFwImage->length) )
<= (pDataInitial + firmwareLength) )
{
count = bufLength;
}
else
{
count = (unsigned char)((pDataInitial + pFwImage->length) - pData);
count = (unsigned char)((pDataInitial + firmwareLength) - pData);
}
totalSent += count;
memcpy(&uploadCmd.req.data, pData, bufLength);
rc = HpmfwupgUploadFirmwareBlock(intf, &uploadCmd, pFwupgCtx, count);
uploadCmd.req.blockNumber++;
pData += count;
printf(" Writing firmware: %.0f %c completed\r", (float)totalSent/pFwImage->length*100, '%');
printf(" Writing firmware: %.0f %c completed\r",
(float)totalSent/firmwareLength*100, '%');
fflush(stdout);
}
printf("\n");
@ -1034,11 +1068,11 @@ int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwu
/* Send finish component */
/* Set image length */
finishCmd.req.componentsMask = pActionRecord->components;
finishCmd.req.imageLength[0] = pFwImage->length & 0xff;
finishCmd.req.imageLength[1] = (pFwImage->length >> 8) & 0xff;
finishCmd.req.imageLength[2] = (pFwImage->length >> 16) & 0xff;
finishCmd.req.imageLength[0] = pFwImage->length[0];
finishCmd.req.imageLength[1] = pFwImage->length[1];
finishCmd.req.imageLength[2] = pFwImage->length[2];
rc = HpmfwupgFinishFirmwareUpload(intf, &finishCmd, pFwupgCtx);
pImagePtr = pDataInitial + pFwImage->length;
pImagePtr = pDataInitial + firmwareLength;
}
}
break;
@ -1054,14 +1088,14 @@ int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwu
/****************************************************************************
*
* Function Name: HpmfwupgValidationStage
* Function Name: HpmfwupgActivationStage
*
* Description: This function the validation stage of a firmware upgrade
* procedure as defined in section 3.4 of the IPM Controller
* Firmware Upgrade Specification version draft 0.74
* Firmware Upgrade Specification version draft 0.9
*
*****************************************************************************/
static int HpmfwupgValidationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx)
static int HpmfwupgActivationStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwupgCtx)
{
int rc = HPMFWUPG_SUCCESS;
struct HpmfwupgActivateFirmwareCtx activateCmd;
@ -1077,7 +1111,7 @@ static int HpmfwupgValidationStage(struct ipmi_intf *intf, struct HpmfwupgUpgrad
{
/* Query self test result if supported by target and new image */
if ( (pFwupgCtx->targetCap.resp.GlobalCapabilities.bitField.ipmcSelftest == 1) &&
(pImageHeader->imageCapabilities.bitField.selfTest == 1) )
(pImageHeader->imageCapabilities.bitField.imageSelfTest == 1) )
{
struct HpmfwupgQuerySelftestResultCtx selfTestCmd;
rc = HpmfwupgQuerySelftestResult(intf, &selfTestCmd, pFwupgCtx);
@ -1187,7 +1221,8 @@ int HpmfwupgGetDeviceId(struct ipmi_intf *intf, struct ipm_devid_rsp* pGetDevId)
return rc;
}
int HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf, struct HpmfwupgGetTargetUpgCapabilitiesCtx* pCtx)
int HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf,
struct HpmfwupgGetTargetUpgCapabilitiesCtx* pCtx)
{
int rc = HPMFWUPG_SUCCESS;
struct ipmi_rs * rsp;
@ -1227,7 +1262,9 @@ int HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf, struct HpmfwupgGetT
printf("Component 6 presence....[%c] \n", pCtx->resp.componentsPresent.ComponentBits.
bitField.component6 ? 'y' : 'n');
printf("Component 7 presence....[%c] \n", pCtx->resp.componentsPresent.ComponentBits.
bitField.component7 ? 'y' : 'n');
bitField.component7 ? 'y' : 'n');
printf("Payload affected........[%c] \n", pCtx->resp.GlobalCapabilities.
bitField.payloadAffected ? 'y' : 'n');
printf("Manual rollback.........[%c] \n", pCtx->resp.GlobalCapabilities.
bitField.manualRollback ? 'y' : 'n');
printf("Defered activation......[%c] \n", pCtx->resp.GlobalCapabilities.
@ -1248,7 +1285,7 @@ int HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf, struct HpmfwupgGetT
}
else
{
printf("Error getting target upgrade capabilities, compcode = %x\n\n", rsp->ccode);
printf("Error getting target upgrade capabilities\n\n", rsp->ccode);
rc = HPMFWUPG_ERROR;
}
}
@ -1302,8 +1339,10 @@ int HpmfwupgGetComponentProperties(struct ipmi_intf *intf, struct HpmfwupgGetCom
GeneralCompProperties.bitfield.preparationSupport ? 'y' : 'n');
printf("Validation supported......[%c] \n", pCtx->resp.Response.generalPropResp.
GeneralCompProperties.bitfield.validationSupport ? 'y' : 'n');
printf("Def. activation supported.[%c] \n\n", pCtx->resp.Response.generalPropResp.
printf("Def. activation supported.[%c] \n", pCtx->resp.Response.generalPropResp.
GeneralCompProperties.bitfield.deferredActivation ? 'y' : 'n');
printf("Payload cold reset req....[%c] \n\n", pCtx->resp.Response.generalPropResp.
GeneralCompProperties.bitfield.payloadColdReset ? 'y' : 'n');
}
break;
case HPMFWUPG_COMP_CURRENT_VERSION:
@ -1556,7 +1595,7 @@ int HpmfwupgActivateFirmware(struct ipmi_intf *intf, struct HpmfwupgActivateFirm
req.msg.data_len = sizeof(struct HpmfwupgActivateFirmwareReq);
rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
if ( rsp )
{
/* Long duration command handling */
@ -1582,7 +1621,7 @@ int HpmfwupgActivateFirmware(struct ipmi_intf *intf, struct HpmfwupgActivateFirm
}
else
{
printf("Error activating firmware, compcode = %x\n\n", rsp->ccode);
printf("Error activating firmware\n\n");
rc = HPMFWUPG_ERROR;
}
@ -1607,7 +1646,7 @@ int HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf, struct HpmfwupgGetUpgradeSt
rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
if ( rsp )
{
{
if ( rsp->ccode == 0x00 )
{
memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetUpgradeStatusResp));
@ -1615,7 +1654,7 @@ int HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf, struct HpmfwupgGetUpgradeSt
{
printf("Upgrade status:\n");
printf(" Command in progress: %x\n", pCtx->resp.cmdInProcess);
printf(" Last command completion code: %x\n\n", pCtx->resp.lastCmdCompCode);
printf(" Last command completion code: %x\n", pCtx->resp.lastCmdCompCode);
}
}
else
@ -1631,7 +1670,7 @@ int HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf, struct HpmfwupgGetUpgradeSt
{
if ( verbose )
{
printf("Error getting upgrade status, compcode = %x\n\n", rsp->ccode);
printf("Error getting upgrade status\n");
rc = HPMFWUPG_ERROR;
}
}
@ -1709,17 +1748,21 @@ int HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf, struct HpmfwupgQueryRoll
rollbackTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT;
}
/* Poll rollback status until completion or timeout*/
/* Poll rollback status until completion or timeout */
timeoutSec1 = time(NULL);
do
timeoutSec2 = time(NULL);
rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
while( rsp &&
(rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) &&
(timeoutSec2 - timeoutSec1 < rollbackTimeout ) )
{
timeoutSec2 = time(NULL);
/* Must wait at least 100 ms between status requests */
usleep(100000);
rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
}while( rsp &&
(rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) &&
(timeoutSec2 - timeoutSec1 < rollbackTimeout ) );
}
if ( rsp )
@ -1730,7 +1773,8 @@ int HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf, struct HpmfwupgQueryRoll
if ( pCtx->resp.rollbackComp.ComponentBits.byte != 0 )
{
/* Rollback occured */
printf("Rollback occured on compononent mask: 0x%02x\n", pCtx->resp.rollbackComp.ComponentBits.byte);
printf("Rollback occured on compononent mask: 0x%02x\n",
pCtx->resp.rollbackComp.ComponentBits.byte);
}
else
{
@ -1739,7 +1783,8 @@ int HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf, struct HpmfwupgQueryRoll
}
else if ( rsp->ccode == 0x81 )
{
printf("Rollback failed on component mask: 0x%02x\n", pCtx->resp.rollbackComp.ComponentBits.byte);
printf("Rollback failed on component mask: 0x%02x\n",
pCtx->resp.rollbackComp.ComponentBits.byte);
rc = HPMFWUPG_ERROR;
}
else
@ -1750,7 +1795,7 @@ int HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf, struct HpmfwupgQueryRoll
}
else
{
printf("Error getting upgrade status, compcode = %x\n\n", rsp->ccode);
printf("Error getting upgrade status\n\n");
rc = HPMFWUPG_ERROR;
}
@ -1793,15 +1838,18 @@ int HpmfwupgQuerySelftestResult(struct ipmi_intf *intf, struct HpmfwupgQuerySelf
/* Poll upgrade status until completion or timeout*/
timeoutSec1 = time(NULL);
do
timeoutSec2 = time(NULL);
rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
while( rsp &&
(rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) &&
(timeoutSec2 - timeoutSec1 < selfTestTimeout ) )
{
timeoutSec2 = time(NULL);
/* Must wait at least 100 ms between status requests */
usleep(100000);
rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx);
}while( rsp &&
(rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) &&
(timeoutSec2 - timeoutSec1 < selfTestTimeout ) );
}
if ( rsp )
{
@ -1823,7 +1871,7 @@ int HpmfwupgQuerySelftestResult(struct ipmi_intf *intf, struct HpmfwupgQuerySelf
}
else
{
printf("Error getting upgrade status, compcode = %x\n\n", rsp->ccode);
printf("Error getting upgrade status\n\n");
rc = HPMFWUPG_ERROR;
}
@ -1859,55 +1907,59 @@ struct ipmi_rs * HpmfwupgSendCmd(struct ipmi_intf *intf, struct ipmi_rq req,
{
rsp = intf->sendrecv(intf, &req);
if ( rsp )
{
/* Handle inaccessibility timeout */
if ( rsp->ccode == 0xff || rsp->ccode == 0xc3 )
{
/* Reset upgrade timeout counter */
upgradeTimeoutCounter = 0;
if ( inaccessTimeoutCounter < inaccessTimeout )
{
timeoutSec2 = time(NULL);
if ( timeoutSec2 > timeoutSec1 )
{
inaccessTimeoutCounter += timeoutSec2 - timeoutSec1;
timeoutSec1 = time(NULL);
}
retry = 1;
}
else
{
retry = 0;
}
}
/* Handle node busy timeout */
else if ( rsp->ccode == 0xc0 )
{
/* Reset inaccessibility timeout counter */
inaccessTimeoutCounter = 0;
if ( upgradeTimeoutCounter < upgradeTimeout )
{
timeoutSec2 = time(NULL);
if ( timeoutSec2 > timeoutSec1 )
{
timeoutSec1 = time(NULL);
upgradeTimeoutCounter += timeoutSec2 - timeoutSec1;
}
retry = 1;
}
else
{
retry = 0;
}
}
else
{
retry = 0;
}
}
}while( rsp && retry );
/* Handle inaccessibility timeout (rsp = NULL if IOL) */
if ( rsp == NULL || rsp->ccode == 0xff || rsp->ccode == 0xc3 )
{
if ( inaccessTimeoutCounter < inaccessTimeout )
{
timeoutSec2 = time(NULL);
if ( timeoutSec2 > timeoutSec1 )
{
inaccessTimeoutCounter += timeoutSec2 - timeoutSec1;
timeoutSec1 = time(NULL);
}
retry = 1;
}
else
{
retry = 0;
}
}
/* Handle node busy timeout */
else if ( rsp->ccode == 0xc0 )
{
if ( upgradeTimeoutCounter < upgradeTimeout )
{
timeoutSec2 = time(NULL);
if ( timeoutSec2 > timeoutSec1 )
{
timeoutSec1 = time(NULL);
upgradeTimeoutCounter += timeoutSec2 - timeoutSec1;
}
retry = 1;
}
else
{
retry = 0;
}
}
else if ( (rsp->ccode == 0xd4) && (strstr(intf->name,"lan")) != NULL )
{
/*
* We have to re-open the LAN session after inacessiblity
* 0xd4 indicates we have insufficient privilege to exectute
* the command and this is certainly because a reset occured
* on the IPMC.
*/
intf->opened = 0;
intf->open(intf);
retry = 1;
}
else
{
retry = 0;
}
}while( retry );
return rsp;
}
@ -1932,16 +1984,19 @@ int HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf, struct HpmfwupgUpgradeCt
/* Poll upgrade status until completion or timeout*/
timeoutSec1 = time(NULL);
do
timeoutSec2 = time(NULL);
rc = HpmfwupgGetUpgradeStatus(intf, &upgStatusCmd, pFwupgCtx);
while((upgStatusCmd.resp.lastCmdCompCode == HPMFWUPG_COMMAND_IN_PROGRESS) &&
(timeoutSec2 - timeoutSec1 < upgradeTimeout ) &&
(rc == HPMFWUPG_SUCCESS) )
{
timeoutSec2 = time(NULL);
/* Must wait at least 100 ms between status requests */
usleep(100000);
timeoutSec2 = time(NULL);
rc = HpmfwupgGetUpgradeStatus(intf, &upgStatusCmd, pFwupgCtx);
}while( (upgStatusCmd.resp.lastCmdCompCode == HPMFWUPG_COMMAND_IN_PROGRESS) &&
(timeoutSec2 - timeoutSec1 < upgradeTimeout ) &&
(rc == HPMFWUPG_SUCCESS) );
}
if ( upgStatusCmd.resp.lastCmdCompCode != 0x00 )
{
if ( verbose )
@ -1971,7 +2026,7 @@ static void HpmfwupgPrintUsage(void)
{
printf("help - This help menu\n");
printf("upgrade <file> activate - Upgrade the firmware using a valid HPM.1 image <file>\n");
printf(" If activate is specified, activate new firmware rigth'n");
printf(" If activate is specified, activate new firmware rigth\n");
printf(" away\n");
printf("activate - Activate the newly uploaded firmware\n");
printf("targetcap - Get the target upgrade capabilities\n");