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
[email protected]
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel