updated HPM firmware agent to version 1.04

2009-02-11
  - With multi-component HPM file, if one component need to be skipped because
    the component is already up-to-date,  ipmitool sends "Initiate upgrade
    action / Upload for upgrade" anyway.

    If the component needs to be skipped, ipmitool will not send "Initiate
    upgrade action / Upload for upgrade"

  - Incremented version to 1.03

  2009-02-11
  - Fixed side effect introduced by last version, "forced" update didn't
    work anymore
  - Incremented version to 1.04
This commit is contained in:
Francois Isabelle 2009-03-18 20:19:23 +00:00
parent 756c22a866
commit e2b72d82de

View File

@ -105,6 +105,21 @@
* - Reduce buffer length more aggressively when no response from iol.
* - Incremented version to 1.02
*
* 2009-02-11
* - With multi-component HPM file, if one component need to be skipped because
* the component is already up-to-date, ipmitool sends "Initiate upgrade
* action / Upload for upgrade" anyway.
*
* If the component needs to be skipped, ipmitool will not send "Initiate
* upgrade action / Upload for upgrade"
*
* - Incremented version to 1.03
*
* 2009-02-11
* - Fixed side effect introduced by last version, "forced" update didn't
* work anymore
* - Incremented version to 1.04
*
* ===========================================================================
* TODO
* ===========================================================================
@ -121,7 +136,7 @@ extern int verbose;
*/
#define HPMFWUPG_VERSION_MAJOR 1
#define HPMFWUPG_VERSION_MINOR 0
#define HPMFWUPG_VERSION_SUBMINOR 2
#define HPMFWUPG_VERSION_SUBMINOR 4
/*
* HPM.1 FIRMWARE UPGRADE COMMANDS (part of PICMG)
@ -1042,6 +1057,18 @@ static int HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf, struct HpmfwupgUp
static struct ipmi_rs * HpmfwupgSendCmd(struct ipmi_intf *intf, struct ipmi_rq req,
struct HpmfwupgUpgradeCtx* pFwupgCtx);
static int HpmFwupgActionUploadFirmware
(
struct HpmfwupgComponentBitMask components,
struct HpmfwupgUpgradeCtx* pFwupgCtx,
unsigned char** pImagePtr,
int componentToUpload,
struct ipmi_intf *intf,
int option,
int* pFlagColdReset
);
/****************************************************************************
*
* Function Name: HpmGetuserInput
@ -1958,7 +1985,6 @@ int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwu
/* Deternime actions size */
actionsSize = pFwupgCtx->imageSize - sizeof(struct HpmfwupgImageHeader);
if (option & VERSIONCHECK_MODE || option & FORCE_MODE)
{
HpmDisplayUpgradeHeader(0);
@ -2054,275 +2080,17 @@ int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwu
case HPMFWUPG_ACTION_UPLOAD_FIRMWARE:
/* Upload all firmware blocks */
{
struct HpmfwupgFirmwareImage* pFwImage;
struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd;
struct HpmfwupgUploadFirmwareBlockCtx uploadCmd;
struct HpmfwupgFinishFirmwareUploadCtx finishCmd;
struct HpmfwupgGetComponentPropertiesCtx getCompProp;
VERSIONINFO *pVersionInfo;
rc = HpmFwupgActionUploadFirmware
(
pActionRecord->components,
pFwupgCtx,
&pImagePtr,
componentToUpload,
intf,
option,
&flagColdReset
);
unsigned char* pData, *pDataInitial;
unsigned char count;
unsigned int totalSent = 0;
unsigned char bufLength = 0;
unsigned int firmwareLength = 0;
unsigned int displayFWLength = 0;
unsigned char *pDataTemp;
unsigned int imageOffset = 0x00;
unsigned int blockLength = 0x00;
unsigned int lengthOfBlock = 0x00;
unsigned int numTxPkts = 0;
unsigned int numRxPkts = 0;
unsigned char mode = 0;
unsigned char componentId = 0x00;
unsigned char componentIdByte = 0x00;
/* Save component ID on which the upload is done */
componentIdByte = pActionRecord->components.ComponentBits.byte;
while ((componentIdByte>>=1)!=0)
{
componentId++;
}
pFwupgCtx->componentId = componentId;
/* Initialize parameters */
uploadCmd.req.blockNumber = 0;
pFwImage = (struct HpmfwupgFirmwareImage*)(pImagePtr +
sizeof(struct HpmfwupgActionRecord));
/*
* lprintf(LOG_NOTICE," Upgrading %s", pFwImage->desc);
* lprintf(LOG_NOTICE," with Version: Major: %d", pFwImage->version[0]);
* lprintf(LOG_NOTICE," Minor: %x", pFwImage->version[1]);
* lprintf(LOG_NOTICE," Aux : %03d %03d %03d %03d", pFwImage->version[2],
* pFwImage->version[3],
* pFwImage->version[4],
* pFwImage->version[5]);
*/
pDataInitial = ((unsigned char*)pFwImage + sizeof(struct HpmfwupgFirmwareImage));
pData = pDataInitial;
/* Find max buffer length according the connection parameters */
if ( strstr(intf->name,"lan") != NULL )
{
bufLength = HPMFWUPG_SEND_DATA_COUNT_LAN - 2;
if ( intf->transit_addr != intf->my_addr && intf->transit_addr != 0 )
bufLength -= 8;
}
else
{
if
(
strstr(intf->name,"open") != NULL
&&
(
intf->target_addr == intf->my_addr
)
)
{
bufLength = HPMFWUPG_SEND_DATA_COUNT_KCS - 2;
}
else
{
if ( intf->target_channel == 7 )
{
bufLength = HPMFWUPG_SEND_DATA_COUNT_IPMBL;
}
else
{
bufLength = HPMFWUPG_SEND_DATA_COUNT_IPMB;
}
}
}
/* Get firmware length */
firmwareLength = pFwImage->length[0];
firmwareLength |= (pFwImage->length[1] << 8) & 0xff00;
firmwareLength |= (pFwImage->length[2] << 16) & 0xff0000;
firmwareLength |= (pFwImage->length[3] << 24) & 0xff000000;
if ( (!(1<<componentToUpload & pActionRecord->components.ComponentBits.byte))
&& (componentToUpload != DEFAULT_COMPONENT_UPLOAD))
{
/* We will skip if the user has given some components in command line "component 2" */
pImagePtr = pDataInitial + firmwareLength;
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;
if (pVersionInfo->rollbackSupported)
{
mode |= ROLLBACK_VER;
}
if ( pVersionInfo->coldResetRequired)
{
flagColdReset = TRUE;
}
if( (option & VERSIONCHECK_MODE) && pVersionInfo->skipUpgrade)
{
HpmDisplayVersion(mode,pVersionInfo);
HpmDisplayUpgrade(1,0,0,0);
pImagePtr = pDataInitial + firmwareLength;
break;
}
if ((option & DEBUG_MODE))
{
printf("\n\n Comp ID : %d [%-20s]\n",pVersionInfo->componentId,pFwImage->desc);
}
else
{
HpmDisplayVersion(mode,pVersionInfo);
}
/* pDataInitial is the starting pointer of the image data */
/* pDataTemp is one which we will move across */
pData = pDataInitial;
pDataTemp = pDataInitial;
lengthOfBlock = firmwareLength;
totalSent = 0x00;
displayFWLength= firmwareLength;
time(&start);
while ( (pData < (pDataTemp+lengthOfBlock)) && (rc == HPMFWUPG_SUCCESS) )
{
if ( (pData+bufLength) <= (pDataTemp+lengthOfBlock) )
{
count = bufLength;
}
else
{
count = (unsigned char)((pDataTemp+lengthOfBlock) - pData);
}
memcpy(&uploadCmd.req.data, pData, bufLength);
imageOffset = 0x00;
blockLength = 0x00;
numTxPkts++;
rc = HpmfwupgUploadFirmwareBlock(intf, &uploadCmd, pFwupgCtx, count,
&imageOffset,&blockLength);
numRxPkts++;
if ( rc != HPMFWUPG_SUCCESS)
{
if ( rc == HPMFWUPG_UPLOAD_BLOCK_LENGTH )
{
/* Retry with a smaller buffer length */
if ( strstr(intf->name,"lan") != NULL )
{
bufLength -= (unsigned char)8;
}
else
{
bufLength -= (unsigned char)1;
}
rc = HPMFWUPG_SUCCESS;
}
else if ( rc == HPMFWUPG_UPLOAD_RETRY )
{
rc = HPMFWUPG_SUCCESS;
}
else
{
fflush(stdout);
lprintf(LOG_NOTICE,"\n Error in Upload FIRMWARE command [rc=%d]\n",rc);
lprintf(LOG_NOTICE,"\n TotalSent:0x%x ",totalSent);
/* Exiting from the function */
rc = HPMFWUPG_ERROR;
break;
}
}
else
{
if (blockLength > firmwareLength)
{
/*
* 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",
totalSent,imageOffset,blockLength,firmwareLength);
rc = HPMFWUPG_ERROR;
break;
}
totalSent += count;
if (imageOffset != 0x00)
{
/* block Length is valid */
lengthOfBlock = blockLength;
pDataTemp = pDataInitial + imageOffset;
pData = pDataTemp;
if ( displayFWLength == firmwareLength)
{
/* This is basically used only to make sure that we display uptil 100% */
displayFWLength = blockLength + totalSent;
}
}
else
{
pData += count;
}
time(&end);
/*
* Just added debug mode in case we need to see exactly how many bytes have
* gone through - Its a hidden option used mainly should be used for debugging
*/
if ( option & DEBUG_MODE)
{
fflush(stdout);
printf(" Blk Num : %02x Bytes : %05x \r",
uploadCmd.req.blockNumber,totalSent);
if (imageOffset || blockLength)
{
printf("\n\r--> ImgOff : %x BlkLen : %x\n",imageOffset,blockLength);
}
if (displayFWLength == totalSent)
{
printf("\n Time Taken %02d:%02d",(end-start)/60, (end-start)%60);
printf("\n\n");
}
}
else
{
HpmDisplayUpgrade(0,totalSent,displayFWLength,(end-start));
}
uploadCmd.req.blockNumber++;
}
}
if (rc == HPMFWUPG_SUCCESS)
{
/* Send finish component */
/* Set image length */
finishCmd.req.componentId = componentId;
/* We need to send the actual data that is sent
* not the comlete firmware image length
*/
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;
}
}
break;
default:
lprintf(LOG_NOTICE," Invalid Action type. Cannot continue");
@ -2342,6 +2110,298 @@ int HpmfwupgUpgradeStage(struct ipmi_intf *intf, struct HpmfwupgUpgradeCtx* pFwu
return rc;
}
static int HpmFwupgActionUploadFirmware
(
struct HpmfwupgComponentBitMask components,
struct HpmfwupgUpgradeCtx* pFwupgCtx,
unsigned char** pImagePtr,
int componentToUpload,
struct ipmi_intf *intf,
int option,
int *pFlagColdReset
)
{
struct HpmfwupgFirmwareImage* pFwImage;
struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd;
struct HpmfwupgUploadFirmwareBlockCtx uploadCmd;
struct HpmfwupgFinishFirmwareUploadCtx finishCmd;
struct HpmfwupgGetComponentPropertiesCtx getCompProp;
VERSIONINFO *pVersionInfo;
time_t start,end;
int rc = HPMFWUPG_SUCCESS;
int skip = FALSE;
unsigned char* pData, *pDataInitial;
unsigned char count;
unsigned int totalSent = 0;
unsigned char bufLength = 0;
unsigned int firmwareLength = 0;
unsigned int displayFWLength = 0;
unsigned char *pDataTemp;
unsigned int imageOffset = 0x00;
unsigned int blockLength = 0x00;
unsigned int lengthOfBlock = 0x00;
unsigned int numTxPkts = 0;
unsigned int numRxPkts = 0;
unsigned char mode = 0;
unsigned char componentId = 0x00;
unsigned char componentIdByte = 0x00;
/* Save component ID on which the upload is done */
componentIdByte = components.ComponentBits.byte;
while ((componentIdByte>>=1)!=0)
{
componentId++;
}
pFwupgCtx->componentId = componentId;
pVersionInfo = (VERSIONINFO*) &gVersionInfo[componentId];
pFwImage = (struct HpmfwupgFirmwareImage*)((*pImagePtr) +
sizeof(struct HpmfwupgActionRecord));
pDataInitial = ((unsigned char*)pFwImage + sizeof(struct HpmfwupgFirmwareImage));
pData = pDataInitial;
/* Get firmware length */
firmwareLength = pFwImage->length[0];
firmwareLength |= (pFwImage->length[1] << 8) & 0xff00;
firmwareLength |= (pFwImage->length[2] << 16) & 0xff0000;
firmwareLength |= (pFwImage->length[3] << 24) & 0xff000000;
mode = TARGET_VER | IMAGE_VER;
if (pVersionInfo->rollbackSupported)
{
mode |= ROLLBACK_VER;
}
if ((option & DEBUG_MODE))
{
printf("\n\n Comp ID : %d [%-20s]\n",pVersionInfo->componentId,pFwImage->desc);
}
else
{
HpmDisplayVersion(mode,pVersionInfo);
}
if
(
(
(pVersionInfo->skipUpgrade)
||
(
/* We will skip if the user has given some components in command line "component 2" */
(!(1<<componentToUpload & components.ComponentBits.byte))
&&
(componentToUpload != DEFAULT_COMPONENT_UPLOAD)
)
)
&&
((option & FORCE_MODE_ALL) != FORCE_MODE_ALL)
)
{
skip = TRUE;
}
if(!skip)
{
/* Initialize parameters */
uploadCmd.req.blockNumber = 0;
/* Find max buffer length according the connection parameters */
if ( strstr(intf->name,"lan") != NULL )
{
bufLength = HPMFWUPG_SEND_DATA_COUNT_LAN - 2;
if ( intf->transit_addr != intf->my_addr && intf->transit_addr != 0 )
bufLength -= 8;
}
else
{
if
(
strstr(intf->name,"open") != NULL
&&
(
intf->target_addr == intf->my_addr
)
)
{
bufLength = HPMFWUPG_SEND_DATA_COUNT_KCS - 2;
}
else
{
if ( intf->target_channel == 7 )
{
bufLength = HPMFWUPG_SEND_DATA_COUNT_IPMBL;
}
else
{
bufLength = HPMFWUPG_SEND_DATA_COUNT_IPMB;
}
}
}
/* Send Initiate Upgrade Action */
initUpgActionCmd.req.componentsMask = components;
/* Action is upgrade */
initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_UPGRADE;
rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx);
if (rc != HPMFWUPG_SUCCESS)
{
skip = TRUE;
}
if ( (pVersionInfo->coldResetRequired) && (!skip))
{
*pFlagColdReset = TRUE;
}
/* pDataInitial is the starting pointer of the image data */
/* pDataTemp is one which we will move across */
pData = pDataInitial;
pDataTemp = pDataInitial;
lengthOfBlock = firmwareLength;
totalSent = 0x00;
displayFWLength= firmwareLength;
time(&start);
while ( (pData < (pDataTemp+lengthOfBlock)) && (rc == HPMFWUPG_SUCCESS) )
{
if ( (pData+bufLength) <= (pDataTemp+lengthOfBlock) )
{
count = bufLength;
}
else
{
count = (unsigned char)((pDataTemp+lengthOfBlock) - pData);
}
memcpy(&uploadCmd.req.data, pData, bufLength);
imageOffset = 0x00;
blockLength = 0x00;
numTxPkts++;
rc = HpmfwupgUploadFirmwareBlock(intf, &uploadCmd, pFwupgCtx, count,
&imageOffset,&blockLength);
numRxPkts++;
if ( rc != HPMFWUPG_SUCCESS)
{
if ( rc == HPMFWUPG_UPLOAD_BLOCK_LENGTH )
{
/* Retry with a smaller buffer length */
if ( strstr(intf->name,"lan") != NULL )
{
bufLength -= (unsigned char)8;
}
else
{
bufLength -= (unsigned char)1;
}
rc = HPMFWUPG_SUCCESS;
}
else if ( rc == HPMFWUPG_UPLOAD_RETRY )
{
rc = HPMFWUPG_SUCCESS;
}
else
{
fflush(stdout);
lprintf(LOG_NOTICE,"\n Error in Upload FIRMWARE command [rc=%d]\n",rc);
lprintf(LOG_NOTICE,"\n TotalSent:0x%x ",totalSent);
/* Exiting from the function */
rc = HPMFWUPG_ERROR;
}
}
else
{
if (blockLength > firmwareLength)
{
/*
* blockLength is the remaining length of the firmware 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",
totalSent,imageOffset,blockLength,firmwareLength);
rc = HPMFWUPG_ERROR;
}
totalSent += count;
if (imageOffset != 0x00)
{
/* block Length is valid */
lengthOfBlock = blockLength;
pDataTemp = pDataInitial + imageOffset;
pData = pDataTemp;
if ( displayFWLength == firmwareLength)
{
/* This is basically used only to make sure that we display uptil 100% */
displayFWLength = blockLength + totalSent;
}
}
else
{
pData += count;
}
time(&end);
/*
* Just added debug mode in case we need to see exactly how many bytes have
* gone through - Its a hidden option used mainly should be used for debugging
*/
if ( option & DEBUG_MODE)
{
fflush(stdout);
printf(" Blk Num : %02x Bytes : %05x \r",
uploadCmd.req.blockNumber,totalSent);
if (imageOffset || blockLength)
{
printf("\n\r--> ImgOff : %x BlkLen : %x\n",imageOffset,blockLength);
}
if (displayFWLength == totalSent)
{
printf("\n Time Taken %02d:%02d",(end-start)/60, (end-start)%60);
printf("\n\n");
}
}
else
{
HpmDisplayUpgrade(0,totalSent,displayFWLength,(end-start));
}
uploadCmd.req.blockNumber++;
}
}
}
if (skip)
{
HpmDisplayUpgrade(1,0,0,0);
*pImagePtr = pDataInitial + firmwareLength;
}
if
(
(rc == HPMFWUPG_SUCCESS)
&&
(!skip)
)
{
/* Send finish component */
/* Set image length */
finishCmd.req.componentId = componentId;
/* We need to send the actual data that is sent
* not the comlete firmware image length
*/
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;
}
return rc;
}
/****************************************************************************
*
* Function Name: HpmfwupgActivationStage