1 /* 2 * Copyright (c) 2006 Kontron Canada, Inc. All Rights Reserved. 3 * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * Redistribution of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * Redistribution in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * Neither the name of Sun Microsystems, Inc. or the names of 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * This software is provided "AS IS," without a warranty of any kind. 21 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, 22 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A 23 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. 24 * SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE 25 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING 26 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL 27 * SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, 28 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR 29 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF 30 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, 31 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 32 */ 33 34 #include <ipmitool/ipmi_intf.h> 35 #include <ipmitool/ipmi_mc.h> 36 #include <ipmitool/ipmi_hpmfwupg.h> 37 #include <ipmitool/helper.h> 38 #include <ipmitool/ipmi_strings.h> 39 #include <ipmitool/log.h> 40 #include "../src/plugins/lan/md5.h" 41 #include <stdio.h> 42 #include <time.h> 43 #include <sys/param.h> 44 45 #if HAVE_CONFIG_H 46 # include <config.h> 47 #endif 48 49 extern int verbose; 50 51 int HpmfwupgUpgrade(struct ipmi_intf *intf, char *imageFilename, 52 int activate, int, int); 53 int HpmfwupgValidateImageIntegrity(struct HpmfwupgUpgradeCtx *pFwupgCtx); 54 int HpmfwupgPreparationStage(struct ipmi_intf *intf, 55 struct HpmfwupgUpgradeCtx *pFwupgCtx, int option); 56 int HpmfwupgUpgradeStage(struct ipmi_intf *intf, 57 struct HpmfwupgUpgradeCtx *pFwupgCtx, int option); 58 int HpmfwupgActivationStage(struct ipmi_intf *intf, 59 struct HpmfwupgUpgradeCtx *pFwupgCtx); 60 int HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf, 61 struct HpmfwupgGetTargetUpgCapabilitiesCtx *pCtx); 62 int HpmfwupgGetComponentProperties(struct ipmi_intf *intf, 63 struct HpmfwupgGetComponentPropertiesCtx *pCtx); 64 int HpmfwupgQuerySelftestResult(struct ipmi_intf *intf, 65 struct HpmfwupgQuerySelftestResultCtx *pCtx, 66 struct HpmfwupgUpgradeCtx *pFwupgCtx); 67 int HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf, 68 struct HpmfwupgQueryRollbackStatusCtx *pCtx, 69 struct HpmfwupgUpgradeCtx *pFwupgCtx); 70 int HpmfwupgAbortUpgrade(struct ipmi_intf *intf, 71 struct HpmfwupgAbortUpgradeCtx *pCtx); 72 int HpmfwupgInitiateUpgradeAction(struct ipmi_intf *intf, 73 struct HpmfwupgInitiateUpgradeActionCtx *pCtx, 74 struct HpmfwupgUpgradeCtx *pFwupgCtx); 75 int HpmfwupgUploadFirmwareBlock(struct ipmi_intf *intf, 76 struct HpmfwupgUploadFirmwareBlockCtx *pCtx, 77 struct HpmfwupgUpgradeCtx *pFwupgCtx, int count, 78 unsigned int *pOffset, unsigned int *blockLen); 79 int HpmfwupgFinishFirmwareUpload(struct ipmi_intf *intf, 80 struct HpmfwupgFinishFirmwareUploadCtx *pCtx, 81 struct HpmfwupgUpgradeCtx *pFwupgCtx, int option); 82 int HpmfwupgActivateFirmware(struct ipmi_intf *intf, 83 struct HpmfwupgActivateFirmwareCtx *pCtx, 84 struct HpmfwupgUpgradeCtx *pFwupgCtx); 85 int HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf, 86 struct HpmfwupgGetUpgradeStatusCtx *pCtxstruct, 87 struct HpmfwupgUpgradeCtx *pFwupgCtx, int silent); 88 int HpmfwupgManualFirmwareRollback(struct ipmi_intf *intf, 89 struct HpmfwupgManualFirmwareRollbackCtx *pCtx); 90 void HpmfwupgPrintUsage(void); 91 unsigned char HpmfwupgCalculateChecksum(unsigned char *pData, 92 unsigned int length); 93 int HpmfwupgGetDeviceId(struct ipmi_intf *intf, 94 struct ipm_devid_rsp *pGetDevId); 95 int HpmfwupgGetBufferFromFile(char *imageFilename, 96 struct HpmfwupgUpgradeCtx *pFwupgCtx); 97 int HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf, 98 struct HpmfwupgUpgradeCtx *pFwupgCtx); 99 struct ipmi_rs *HpmfwupgSendCmd(struct ipmi_intf *intf, 100 struct ipmi_rq req, struct HpmfwupgUpgradeCtx* pFwupgCtx); 101 102 103 int HpmFwupgActionUploadFirmware(struct HpmfwupgComponentBitMask components, 104 struct HpmfwupgUpgradeCtx* pFwupgCtx, 105 unsigned char **pImagePtr, 106 struct ipmi_intf *intf, 107 int option, 108 int *pFlagColdReset); 109 110 /* HpmGetuserInput - get input from user 111 * 112 * returns TRUE if its Yes or FALSE if its No 113 */ 114 int 115 HpmGetUserInput(char *str) 116 { 117 char userInput[2]; 118 int ret; 119 120 printf("%s", str); 121 ret = scanf("%s", userInput); 122 if (!ret) { 123 return 1; 124 } 125 if (toupper(userInput[0]) == 'Y') { 126 return 1; 127 } 128 return 0; 129 } 130 131 /* HpmDisplayLine - display the line with the given character 132 */ 133 void 134 HpmDisplayLine(char *s, int n) 135 { 136 while (n--) { 137 printf ("%c", *s); 138 } 139 printf("\n"); 140 } 141 142 /* HpmDisplayUpgradeHeader - display the Upgrade header information 143 */ 144 void 145 HpmDisplayUpgradeHeader(void) 146 { 147 printf("\n"); 148 HpmDisplayLine("-", 79); 149 printf( 150 "|ID | Name | Versions | %% |\n"); 151 printf( 152 "| | | Active | Backup | File | |\n"); 153 printf( 154 "|----|-------------|-----------------|-----------------|-----------------|----|\n"); 155 } 156 157 /* HpmDisplayUpgrade - display the progress of the upgrade; prints the "." 158 * for every 5% of its completion. 159 */ 160 void 161 HpmDisplayUpgrade(int skip, unsigned int totalSent, 162 unsigned int displayFWLength, time_t timeElapsed) 163 { 164 int percent; 165 static int old_percent = -1; 166 if (skip) { 167 printf("Skip|\n"); 168 return; 169 } 170 fflush(stdout); 171 172 percent = ((float)totalSent / displayFWLength) * 100; 173 if (percent != old_percent) { 174 if (old_percent != -1) { 175 printf("\b\b\b\b\b"); 176 } 177 printf("%3d%%|", percent); 178 old_percent = percent; 179 } 180 if (totalSent == displayFWLength) { 181 /* Display the time taken to complete the upgrade */ 182 printf( 183 "\n| |Upload Time: %02ld:%02ld | Image Size: %7d bytes |\n", 184 timeElapsed / 60, timeElapsed % 60, totalSent); 185 old_percent = -1; 186 } 187 } 188 189 /* HpmDisplayVersionHeader - display the information about version header 190 */ 191 void 192 HpmDisplayVersionHeader(int mode) 193 { 194 if (mode & IMAGE_VER) { 195 HpmDisplayLine("-", 74); 196 printf( 197 "|ID | Name | Versions |\n"); 198 printf( 199 "| | | Active | Backup | File |\n"); 200 HpmDisplayLine("-", 74); 201 } else { 202 HpmDisplayLine("-",74 ); 203 printf( 204 "|ID | Name | Versions |\n"); 205 printf( 206 "| | | Active | Backup | Deferred |\n"); 207 HpmDisplayLine("-", 74); 208 } 209 } 210 211 /* HpmDisplayVersion - display the version of the image and target 212 */ 213 void 214 HpmDisplayVersion(int mode, VERSIONINFO *pVersion, int upgradable) 215 { 216 /* 217 * If the cold reset is required then we can display * on it 218 * so that user is aware that he needs to do payload power 219 * cycle after upgrade 220 */ 221 printf("|%c%c%2d|%-13s|", 222 pVersion->coldResetRequired ? '*' : ' ', 223 upgradable ? '^' : ' ', 224 pVersion->componentId, pVersion->descString); 225 226 if (mode & TARGET_VER) { 227 if ((pVersion->targetMajor == 0xFF 228 || (pVersion->targetMajor == 0x7F)) 229 && pVersion->targetMinor == 0xFF) { 230 printf(" ---.-- -------- |"); 231 } else { 232 printf(" %3d.%02x %02X%02X%02X%02X |", 233 pVersion->targetMajor, 234 pVersion->targetMinor, 235 pVersion->targetAux[0], 236 pVersion->targetAux[1], 237 pVersion->targetAux[2], 238 pVersion->targetAux[3]); 239 } 240 if (mode & ROLLBACK_VER) { 241 if ((pVersion->rollbackMajor == 0xFF 242 || (pVersion->rollbackMajor == 0x7F)) 243 && pVersion->rollbackMinor == 0xFF) { 244 printf(" ---.-- -------- |"); 245 } else { 246 printf(" %3d.%02x %02X%02X%02X%02X |", 247 pVersion->rollbackMajor, 248 pVersion->rollbackMinor, 249 pVersion->rollbackAux[0], 250 pVersion->rollbackAux[1], 251 pVersion->rollbackAux[2], 252 pVersion->rollbackAux[3]); 253 } 254 } else { 255 printf(" ---.-- -------- |"); 256 } 257 } 258 if (mode & IMAGE_VER) { 259 if ((pVersion->imageMajor == 0xFF 260 || (pVersion->imageMajor == 0x7F)) 261 && pVersion->imageMinor == 0xFF) { 262 printf(" ---.-- |"); 263 } else { 264 printf(" %3d.%02x %02X%02X%02X%02X |", 265 pVersion->imageMajor, 266 pVersion->imageMinor, 267 pVersion->imageAux[0], 268 pVersion->imageAux[1], 269 pVersion->imageAux[2], 270 pVersion->imageAux[3]); 271 } 272 } else { 273 if ((pVersion->deferredMajor == 0xFF 274 || (pVersion->deferredMajor == 0x7F)) 275 && pVersion->deferredMinor == 0xFF) { 276 printf(" ---.-- -------- |"); 277 } else { 278 printf(" %3d.%02x %02X%02X%02X%02X |", 279 pVersion->deferredMajor, 280 pVersion->deferredMinor, 281 pVersion->deferredAux[0], 282 pVersion->deferredAux[1], 283 pVersion->deferredAux[2], 284 pVersion->deferredAux[3]); 285 } 286 } 287 } 288 289 /* HpmfwupgTargerCheck - get target information and displays it on the screen 290 */ 291 int 292 HpmfwupgTargetCheck(struct ipmi_intf *intf, int option) 293 { 294 struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd; 295 int rc = HPMFWUPG_SUCCESS; 296 int componentId = 0; 297 int flagColdReset = FALSE; 298 struct ipm_devid_rsp devIdrsp; 299 struct HpmfwupgGetComponentPropertiesCtx getCompProp; 300 int mode = 0; 301 rc = HpmfwupgGetDeviceId(intf, &devIdrsp); 302 if (rc != HPMFWUPG_SUCCESS) { 303 lprintf(LOG_NOTICE, 304 "Verify whether the Target board is present \n"); 305 return HPMFWUPG_ERROR; 306 } 307 rc = HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd); 308 if (rc != HPMFWUPG_SUCCESS) { 309 /* That indicates the target is not responding to the command 310 * May be that there is no HPM support 311 */ 312 lprintf(LOG_NOTICE, 313 "Board might not be supporting the HPM.1 Standards\n"); 314 return rc; 315 } 316 if (option & VIEW_MODE) { 317 lprintf(LOG_NOTICE, "-------Target Information-------"); 318 lprintf(LOG_NOTICE, "Device Id : 0x%x", 319 devIdrsp.device_id); 320 lprintf(LOG_NOTICE, "Device Revision : 0x%x", 321 devIdrsp.device_revision); 322 lprintf(LOG_NOTICE, "Product Id : 0x%04x", 323 buf2short(devIdrsp.product_id)); 324 lprintf(LOG_NOTICE, "Manufacturer Id : 0x%04x (%s)\n\n", 325 buf2short(devIdrsp.manufacturer_id), 326 val2str(buf2short(devIdrsp.manufacturer_id),ipmi_oem_info)); 327 HpmDisplayVersionHeader(TARGET_VER|ROLLBACK_VER); 328 } 329 for (componentId = HPMFWUPG_COMPONENT_ID_0; 330 componentId < HPMFWUPG_COMPONENT_ID_MAX; 331 componentId++ ) { 332 /* If the component is supported */ 333 if (((1 << componentId) & targetCapCmd.resp.componentsPresent.ComponentBits.byte)) { 334 memset((PVERSIONINFO)&gVersionInfo[componentId], 0x00, sizeof(VERSIONINFO)); 335 getCompProp.req.componentId = componentId; 336 getCompProp.req.selector = HPMFWUPG_COMP_GEN_PROPERTIES; 337 rc = HpmfwupgGetComponentProperties(intf, &getCompProp); 338 if (rc != HPMFWUPG_SUCCESS) { 339 lprintf(LOG_NOTICE, "Get CompGenProp Failed for component Id %d\n", 340 componentId); 341 return rc; 342 } 343 gVersionInfo[componentId].rollbackSupported = getCompProp.resp.Response. 344 generalPropResp.GeneralCompProperties.bitfield.rollbackBackup; 345 gVersionInfo[componentId].coldResetRequired = getCompProp.resp.Response. 346 generalPropResp.GeneralCompProperties.bitfield.payloadColdReset; 347 getCompProp.req.selector = HPMFWUPG_COMP_DESCRIPTION_STRING; 348 rc = HpmfwupgGetComponentProperties(intf, &getCompProp); 349 if (rc != HPMFWUPG_SUCCESS) { 350 lprintf(LOG_NOTICE, 351 "Get CompDescString Failed for component Id %d\n", 352 componentId); 353 return rc; 354 } 355 memcpy(gVersionInfo[componentId].descString, 356 getCompProp.resp.Response.descStringResp.descString, 357 HPMFWUPG_DESC_STRING_LENGTH); 358 gVersionInfo[componentId].descString[HPMFWUPG_DESC_STRING_LENGTH] = '\0'; 359 getCompProp.req.selector = HPMFWUPG_COMP_CURRENT_VERSION; 360 rc = HpmfwupgGetComponentProperties(intf, &getCompProp); 361 if (rc != HPMFWUPG_SUCCESS) { 362 lprintf(LOG_NOTICE, 363 "Get CompCurrentVersion Failed for component Id %d\n", 364 componentId); 365 return rc; 366 } 367 gVersionInfo[componentId].componentId = componentId; 368 gVersionInfo[componentId].targetMajor = getCompProp.resp.Response. 369 currentVersionResp.currentVersion[0]; 370 gVersionInfo[componentId].targetMinor = getCompProp.resp.Response. 371 currentVersionResp.currentVersion[1]; 372 gVersionInfo[componentId].targetAux[0] = getCompProp.resp.Response. 373 currentVersionResp.currentVersion[2]; 374 gVersionInfo[componentId].targetAux[1] = getCompProp.resp.Response. 375 currentVersionResp.currentVersion[3]; 376 gVersionInfo[componentId].targetAux[2] = getCompProp.resp.Response. 377 currentVersionResp.currentVersion[4]; 378 gVersionInfo[componentId].targetAux[3] = getCompProp.resp.Response. 379 currentVersionResp.currentVersion[5]; 380 mode = TARGET_VER; 381 if (gVersionInfo[componentId].rollbackSupported) { 382 getCompProp.req.selector = HPMFWUPG_COMP_ROLLBACK_FIRMWARE_VERSION; 383 rc = HpmfwupgGetComponentProperties(intf, &getCompProp); 384 if (rc != HPMFWUPG_SUCCESS) { 385 lprintf(LOG_NOTICE, 386 "Get CompRollbackVersion Failed for component Id %d\n", 387 componentId); 388 } else { 389 gVersionInfo[componentId].rollbackMajor = getCompProp.resp 390 .Response.rollbackFwVersionResp.rollbackFwVersion[0]; 391 gVersionInfo[componentId].rollbackMinor = getCompProp.resp 392 .Response.rollbackFwVersionResp.rollbackFwVersion[1]; 393 gVersionInfo[componentId].rollbackAux[0] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[2]; 394 gVersionInfo[componentId].rollbackAux[1] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[3]; 395 gVersionInfo[componentId].rollbackAux[2] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[4]; 396 gVersionInfo[componentId].rollbackAux[3] = getCompProp.resp.Response.rollbackFwVersionResp.rollbackFwVersion[5]; 397 } 398 getCompProp.req.selector = HPMFWUPG_COMP_DEFERRED_FIRMWARE_VERSION; 399 rc = HpmfwupgGetComponentProperties(intf, &getCompProp); 400 if (rc != HPMFWUPG_SUCCESS) { 401 lprintf(LOG_NOTICE, 402 "Get CompRollbackVersion Failed for component Id %d\n", 403 componentId); 404 } else { 405 gVersionInfo[componentId].deferredMajor = getCompProp.resp 406 .Response.deferredFwVersionResp.deferredFwVersion[0]; 407 gVersionInfo[componentId].deferredMinor = getCompProp.resp 408 .Response.deferredFwVersionResp.deferredFwVersion[1]; 409 gVersionInfo[componentId].deferredAux[0] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[2]; 410 gVersionInfo[componentId].deferredAux[1] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[3]; 411 gVersionInfo[componentId].deferredAux[2] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[4]; 412 gVersionInfo[componentId].deferredAux[3] = getCompProp.resp.Response.deferredFwVersionResp.deferredFwVersion[5]; 413 } 414 mode |= ROLLBACK_VER; 415 } else { 416 gVersionInfo[componentId].rollbackMajor = 0xff; 417 gVersionInfo[componentId].rollbackMinor = 0xff; 418 gVersionInfo[componentId].rollbackAux[0] = 0xff; 419 gVersionInfo[componentId].rollbackAux[1] = 0xff; 420 gVersionInfo[componentId].rollbackAux[2] = 0xff; 421 gVersionInfo[componentId].rollbackAux[3] = 0xff; 422 gVersionInfo[componentId].deferredMajor = 0xff; 423 gVersionInfo[componentId].deferredMinor = 0xff; 424 gVersionInfo[componentId].deferredAux[0] = 0xff; 425 gVersionInfo[componentId].deferredAux[1] = 0xff; 426 gVersionInfo[componentId].deferredAux[2] = 0xff; 427 gVersionInfo[componentId].deferredAux[3] = 0xff; 428 } 429 if (gVersionInfo[componentId].coldResetRequired) { 430 /* 431 * If any of the component indicates that the Payload Cold reset is required 432 * then set the flag 433 */ 434 flagColdReset = TRUE; 435 } 436 if (option & VIEW_MODE) { 437 HpmDisplayVersion(mode, 438 &gVersionInfo[componentId], 439 0); 440 printf("\n"); 441 } 442 } 443 } 444 if (option & VIEW_MODE) { 445 HpmDisplayLine("-",74 ); 446 fflush(stdout); 447 lprintf(LOG_NOTICE, 448 "(*) Component requires Payload Cold Reset"); 449 printf("\n\n"); 450 } 451 return HPMFWUPG_SUCCESS; 452 } 453 454 /* HpmfwupgUpgrade - perform the HPM.1 firmware upgrade procedure as defined 455 * the IPM Controller Firmware Upgrade Specification version 1.0 456 */ 457 int 458 HpmfwupgUpgrade(struct ipmi_intf *intf, char *imageFilename, int activate, 459 int componentMask, int option) 460 { 461 int rc = HPMFWUPG_SUCCESS; 462 struct HpmfwupgUpgradeCtx fwupgCtx; 463 /* INITIALIZE UPGRADE CONTEXT */ 464 memset(&fwupgCtx, 0, sizeof (fwupgCtx)); 465 /* GET IMAGE BUFFER FROM FILE */ 466 rc = HpmfwupgGetBufferFromFile(imageFilename, &fwupgCtx); 467 /* VALIDATE IMAGE INTEGRITY */ 468 if (rc == HPMFWUPG_SUCCESS) { 469 printf("Validating firmware image integrity..."); 470 fflush(stdout); 471 rc = HpmfwupgValidateImageIntegrity(&fwupgCtx); 472 if (rc == HPMFWUPG_SUCCESS) { 473 printf("OK\n"); 474 fflush(stdout); 475 } 476 } 477 /* PREPARATION STAGE */ 478 if (rc == HPMFWUPG_SUCCESS) { 479 printf("Performing preparation stage..."); 480 fflush(stdout); 481 rc = HpmfwupgPreparationStage(intf, &fwupgCtx, option); 482 if (rc == HPMFWUPG_SUCCESS) { 483 printf("OK\n"); 484 fflush(stdout); 485 } 486 } 487 /* UPGRADE STAGE */ 488 if (rc == HPMFWUPG_SUCCESS) { 489 if (option & VIEW_MODE) { 490 lprintf(LOG_NOTICE, 491 "\nComparing Target & Image File version"); 492 } else if (option & COMPARE_MODE) { 493 lprintf(LOG_NOTICE, 494 "\nPerforming upload for compare stage:"); 495 } else { 496 lprintf(LOG_NOTICE, "\nPerforming upgrade stage:"); 497 } 498 if (option & VIEW_MODE) { 499 rc = HpmfwupgPreUpgradeCheck(intf, 500 &fwupgCtx,componentMask, VIEW_MODE); 501 } else { 502 rc = HpmfwupgPreUpgradeCheck(intf, &fwupgCtx, 503 componentMask, option); 504 if (rc == HPMFWUPG_SUCCESS) { 505 if (verbose) { 506 printf("Component update mask : 0x%02x\n", 507 fwupgCtx.compUpdateMask.ComponentBits.byte); 508 } 509 rc = HpmfwupgUpgradeStage(intf, &fwupgCtx, option); 510 } 511 } 512 } 513 /* ACTIVATION STAGE */ 514 if (rc == HPMFWUPG_SUCCESS && activate) { 515 /* check if upgrade components mask is non-zero */ 516 if (fwupgCtx.compUpdateMask.ComponentBits.byte) { 517 lprintf(LOG_NOTICE, "Performing activation stage: "); 518 rc = HpmfwupgActivationStage(intf, &fwupgCtx); 519 } else { 520 lprintf(LOG_NOTICE, 521 "No components updated. Skipping activation stage.\n"); 522 } 523 } 524 if (rc == HPMFWUPG_SUCCESS) { 525 if (option & VIEW_MODE) { 526 /* Dont display anything here in case we are just viewing it */ 527 lprintf(LOG_NOTICE," "); 528 } else if (option & COMPARE_MODE) { 529 lprintf(LOG_NOTICE, 530 "\nFirmware comparison procedure complete\n"); 531 } else { 532 lprintf(LOG_NOTICE, 533 "\nFirmware upgrade procedure successful\n"); 534 } 535 } else if (option & VIEW_MODE) { 536 /* Dont display anything here in case we are just viewing it */ 537 lprintf(LOG_NOTICE," "); 538 } else if (option & COMPARE_MODE) { 539 lprintf(LOG_NOTICE, 540 "Firmware comparison procedure failed\n"); 541 } else { 542 lprintf(LOG_NOTICE, "Firmware upgrade procedure failed\n"); 543 } 544 if (fwupgCtx.pImageData) { 545 free(fwupgCtx.pImageData); 546 fwupgCtx.pImageData = NULL; 547 } 548 return rc; 549 } 550 551 /* HpmfwupgValidateImageIntegrity - validate a HPM.1 firmware image file as 552 * defined in section 4 of the IPM Controller Firmware Upgrade Specification 553 * version 1.0 554 */ 555 int 556 HpmfwupgValidateImageIntegrity(struct HpmfwupgUpgradeCtx *pFwupgCtx) 557 { 558 struct HpmfwupgImageHeader *pImageHeader = (struct HpmfwupgImageHeader*)pFwupgCtx->pImageData; 559 md5_state_t ctx; 560 static unsigned char md[HPMFWUPG_MD5_SIGNATURE_LENGTH]; 561 unsigned char *pMd5Sig = pFwupgCtx->pImageData 562 + (pFwupgCtx->imageSize - HPMFWUPG_MD5_SIGNATURE_LENGTH); 563 /* Validate MD5 checksum */ 564 memset(md, 0, HPMFWUPG_MD5_SIGNATURE_LENGTH); 565 memset(&ctx, 0, sizeof(md5_state_t)); 566 md5_init(&ctx); 567 md5_append(&ctx, pFwupgCtx->pImageData, 568 pFwupgCtx->imageSize - HPMFWUPG_MD5_SIGNATURE_LENGTH); 569 md5_finish(&ctx, md); 570 if (memcmp(md, pMd5Sig, HPMFWUPG_MD5_SIGNATURE_LENGTH) != 0) { 571 lprintf(LOG_NOTICE, "\n Invalid MD5 signature"); 572 return HPMFWUPG_ERROR; 573 } 574 /* Validate Header signature */ 575 if(strncmp(pImageHeader->signature, 576 HPMFWUPG_IMAGE_SIGNATURE, 577 HPMFWUPG_HEADER_SIGNATURE_LENGTH) != 0) { 578 lprintf(LOG_NOTICE,"\n Invalid image signature"); 579 return HPMFWUPG_ERROR; 580 } 581 /* Validate Header image format version */ 582 if (pImageHeader->formatVersion != HPMFWUPG_IMAGE_HEADER_VERSION) { 583 lprintf(LOG_NOTICE,"\n Unrecognized image version"); 584 return HPMFWUPG_ERROR; 585 } 586 /* Validate header checksum */ 587 if (HpmfwupgCalculateChecksum((unsigned char*)pImageHeader, 588 sizeof(struct HpmfwupgImageHeader) 589 + pImageHeader->oemDataLength 590 + sizeof(unsigned char)/*checksum*/) != 0) { 591 lprintf(LOG_NOTICE,"\n Invalid header checksum"); 592 return HPMFWUPG_ERROR; 593 } 594 return HPMFWUPG_SUCCESS; 595 } 596 597 /* HpmfwupgPreparationStage - prepere stage of a firmware upgrade procedure as 598 * defined in section 3.2 of the IPM Controller Firmware Upgrade Specification 599 * version 1.0 600 */ 601 int 602 HpmfwupgPreparationStage(struct ipmi_intf *intf, 603 struct HpmfwupgUpgradeCtx *pFwupgCtx, int option) 604 { 605 int componentId; 606 int rc = HPMFWUPG_SUCCESS; 607 struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd; 608 struct HpmfwupgImageHeader *pImageHeader = (struct HpmfwupgImageHeader*) 609 pFwupgCtx->pImageData; 610 /* Get device ID */ 611 rc = HpmfwupgGetDeviceId(intf, &pFwupgCtx->devId); 612 /* Match current IPMC IDs with upgrade image */ 613 if (rc != HPMFWUPG_SUCCESS) { 614 return HPMFWUPG_ERROR; 615 } 616 /* Validate device ID */ 617 if (pImageHeader->deviceId == pFwupgCtx->devId.device_id) { 618 /* Validate product ID */ 619 if (memcmp(pImageHeader->prodId, 620 pFwupgCtx->devId.product_id, 621 HPMFWUPG_PRODUCT_ID_LENGTH ) == 0) { 622 /* Validate man ID */ 623 if (memcmp(pImageHeader->manId, 624 pFwupgCtx->devId.manufacturer_id, 625 HPMFWUPG_MANUFATURER_ID_LENGTH) != 0) { 626 lprintf(LOG_NOTICE, 627 "\n Invalid image file for manufacturer %u", 628 buf2short(pFwupgCtx->devId.manufacturer_id)); 629 rc = HPMFWUPG_ERROR; 630 } 631 } else { 632 lprintf(LOG_NOTICE, 633 "\n Invalid image file for product %u", 634 buf2short(pFwupgCtx->devId.product_id)); 635 rc = HPMFWUPG_ERROR; 636 } 637 } else { 638 lprintf(LOG_NOTICE, "\n Invalid device ID %x", 639 pFwupgCtx->devId.device_id); 640 rc = HPMFWUPG_ERROR; 641 } 642 if (rc != HPMFWUPG_SUCCESS) { 643 /* Giving one more chance to user to check whether its OK to continue even if the 644 * product ID does not match. This is helpful as sometimes we just want to update 645 * and dont care whether we have a different product Id. If the user says NO then 646 * we need to just bail out from here 647 */ 648 if (!((option & FORCE_MODE) || (option & VIEW_MODE))) { 649 printf("\n\n Use \"force\" option for copying all the components\n"); 650 return HPMFWUPG_ERROR; 651 } 652 printf("\n Image Information"); 653 printf("\n Device Id : 0x%x", pImageHeader->deviceId); 654 printf("\n Prod Id : 0x%02x%02x", 655 pImageHeader->prodId[1], pImageHeader->prodId[0]); 656 printf("\n Manuf Id : 0x%02x%02x%02x", 657 pImageHeader->manId[2], 658 pImageHeader->manId[1], 659 pImageHeader->manId[0]); 660 printf("\n Board Information"); 661 printf("\n Device Id : 0x%x", pFwupgCtx->devId.device_id); 662 printf("\n Prod Id : 0x%02x%02x", 663 pFwupgCtx->devId.product_id[1], pFwupgCtx->devId.product_id[0]); 664 printf("\n Manuf Id : 0x%02x%02x%02x", 665 pFwupgCtx->devId.manufacturer_id[2], 666 pFwupgCtx->devId.manufacturer_id[1], 667 pFwupgCtx->devId.manufacturer_id[0]); 668 if (HpmGetUserInput("\n Continue ignoring DeviceID/ProductID/ManufacturingID (Y/N): ")) { 669 rc = HPMFWUPG_SUCCESS; 670 } else { 671 return HPMFWUPG_ERROR; 672 } 673 } 674 /* Validate earliest compatible revision */ 675 /* Validate major & minor revision */ 676 if (pImageHeader->compRevision[0] > pFwupgCtx->devId.fw_rev1 677 || (pImageHeader->compRevision[0] == pFwupgCtx->devId.fw_rev1 678 && pImageHeader->compRevision[1] > pFwupgCtx->devId.fw_rev2)) { 679 /* Version not compatible for upgrade */ 680 lprintf(LOG_NOTICE, "\n Version: Major: %d", pImageHeader->compRevision[0]); 681 lprintf(LOG_NOTICE, " Minor: %x", pImageHeader->compRevision[1]); 682 lprintf(LOG_NOTICE, " Not compatible with "); 683 lprintf(LOG_NOTICE, " Version: Major: %d", pFwupgCtx->devId.fw_rev1); 684 lprintf(LOG_NOTICE, " Minor: %x", pFwupgCtx->devId.fw_rev2); 685 /* Confirming it once again */ 686 if (!((option & FORCE_MODE) || (option & VIEW_MODE))) { 687 return HPMFWUPG_ERROR; 688 } 689 if (HpmGetUserInput("\n Continue IGNORING Earliest compatibility (Y/N): ")) { 690 rc = HPMFWUPG_SUCCESS; 691 } else { 692 return HPMFWUPG_ERROR; 693 } 694 } 695 /* Get target upgrade capabilities */ 696 rc = HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd); 697 if (rc != HPMFWUPG_SUCCESS) { 698 return HPMFWUPG_ERROR; 699 } 700 /* Copy response to context */ 701 memcpy(&pFwupgCtx->targetCap, 702 &targetCapCmd.resp, 703 sizeof(struct HpmfwupgGetTargetUpgCapabilitiesResp)); 704 if (option & VIEW_MODE) { 705 /* do nothing */ 706 } else { 707 /* Make sure all component IDs defined in the 708 * upgrade image are supported by the IPMC 709 */ 710 if ((pImageHeader->components.ComponentBits.byte & 711 pFwupgCtx->targetCap.componentsPresent.ComponentBits.byte) != 712 pImageHeader->components.ComponentBits.byte) { 713 lprintf(LOG_NOTICE, 714 "\n Some components present in the image file are not supported by the IPMC"); 715 return HPMFWUPG_ERROR; 716 } 717 /* Make sure the upgrade is desirable rigth now */ 718 if (pFwupgCtx->targetCap.GlobalCapabilities.bitField.fwUpgUndesirable == 1) { 719 lprintf(LOG_NOTICE, "\n Upgrade undesirable at this moment"); 720 return HPMFWUPG_ERROR; 721 } 722 /* Get confimation from the user if he wants to continue when 723 * service affected during upgrade 724 */ 725 if (!(option & COMPARE_MODE) 726 && (pFwupgCtx->targetCap.GlobalCapabilities.bitField.servAffectDuringUpg == 1 727 || pImageHeader->imageCapabilities.bitField.servAffected == 1)) { 728 if (HpmGetUserInput("\nServices may be affected during upgrade. Do you wish to continue? (y/n): ")) { 729 rc = HPMFWUPG_SUCCESS; 730 } else { 731 return HPMFWUPG_ERROR; 732 } 733 } 734 } 735 /* Get the general properties of each component present in image */ 736 for (componentId = HPMFWUPG_COMPONENT_ID_0; 737 componentId < HPMFWUPG_COMPONENT_ID_MAX; 738 componentId++) { 739 /* Reset component properties */ 740 memset(&pFwupgCtx->genCompProp[componentId], 0, 741 sizeof (struct HpmfwupgGetGeneralPropResp)); 742 if ((1 << componentId & pImageHeader->components.ComponentBits.byte)) { 743 struct HpmfwupgGetComponentPropertiesCtx getCompPropCmd; 744 /* Get general component properties */ 745 getCompPropCmd.req.componentId = componentId; 746 getCompPropCmd.req.selector = HPMFWUPG_COMP_GEN_PROPERTIES; 747 rc = HpmfwupgGetComponentProperties(intf, &getCompPropCmd); 748 if (rc == HPMFWUPG_SUCCESS) { 749 /* Copy response to context */ 750 memcpy(&pFwupgCtx->genCompProp[componentId], 751 &getCompPropCmd.resp, 752 sizeof(struct HpmfwupgGetGeneralPropResp)); 753 } 754 } 755 } 756 return rc; 757 } 758 759 int 760 image_version_upgradable(VERSIONINFO *pVersionInfo) 761 { 762 /* If the image and active target versions are different, then 763 * upgrade */ 764 if ((pVersionInfo->imageMajor != pVersionInfo->targetMajor) 765 || (pVersionInfo->imageMinor != pVersionInfo->targetMinor) 766 || (pVersionInfo->imageAux[0] != pVersionInfo->targetAux[0]) 767 || (pVersionInfo->imageAux[1] != pVersionInfo->targetAux[1]) 768 || (pVersionInfo->imageAux[2] != pVersionInfo->targetAux[2]) 769 || (pVersionInfo->imageAux[3] != pVersionInfo->targetAux[3])) { 770 return (1); 771 } 772 /* If the image and active target versions are the same and rollback 773 * is not supported, then there's nothing to do, skip the upgrade 774 */ 775 if (!pVersionInfo->rollbackSupported) { 776 return (0); 777 } 778 /* If the image and rollback target versions are different, then 779 * go ahead and upgrade 780 */ 781 if ((pVersionInfo->imageMajor != pVersionInfo->rollbackMajor) 782 || (pVersionInfo->imageMinor != pVersionInfo->rollbackMinor) 783 || (pVersionInfo->imageAux[0] != pVersionInfo->rollbackAux[0]) 784 || (pVersionInfo->imageAux[1] != pVersionInfo->rollbackAux[1]) 785 || (pVersionInfo->imageAux[2] != pVersionInfo->rollbackAux[2]) 786 || (pVersionInfo->imageAux[3] != pVersionInfo->rollbackAux[3])) { 787 return (1); 788 } 789 /* Image and rollback target versions are the same too, skip it */ 790 return (0); 791 } 792 793 /* HpmfwupgValidateActionRecordChecksum - validate checksum of the specified 794 * action record header. 795 */ 796 int 797 HpmfwupgValidateActionRecordChecksum(struct HpmfwupgActionRecord *pActionRecord) 798 { 799 int rc = HPMFWUPG_SUCCESS; 800 /* Validate action record checksum */ 801 if (HpmfwupgCalculateChecksum((unsigned char*)pActionRecord, 802 sizeof(struct HpmfwupgActionRecord)) != 0) { 803 /* Due to ambiguity in the HPM.1 specification, for the case of 804 * the Upload Firmware Image action type, the record header length 805 * might be thought as either the first 3 bytes, or the first 34 bytes 806 * which precede the firmware image data. 807 * For the latter case we re-calculate the Upload Firmware Image 808 * record checksum for the 34 byte header length. 809 */ 810 if (pActionRecord->actionType != HPMFWUPG_ACTION_UPLOAD_FIRMWARE 811 || HpmfwupgCalculateChecksum((unsigned char*)pActionRecord, 812 sizeof(struct HpmfwupgActionRecord) 813 + sizeof(struct HpmfwupgFirmwareImage))) { 814 lprintf(LOG_NOTICE, " Invalid Action record."); 815 rc = HPMFWUPG_ERROR; 816 } 817 } 818 return rc; 819 } 820 821 /* HpmfwupgPreUpgradeCheck - make pre-Upgrade check, this mainly helps in 822 * checking which all version upgrade is skippable because the image version 823 * is same as target version. 824 */ 825 int 826 HpmfwupgPreUpgradeCheck(struct ipmi_intf *intf, 827 struct HpmfwupgUpgradeCtx *pFwupgCtx, 828 int componentMask, int option) 829 { 830 unsigned char *pImagePtr; 831 struct HpmfwupgActionRecord *pActionRecord; 832 struct HpmfwupgImageHeader *pImageHeader; 833 int componentId; 834 pImageHeader = (struct HpmfwupgImageHeader*)pFwupgCtx->pImageData; 835 /* Put pointer after image header */ 836 pImagePtr = (unsigned char*)(pFwupgCtx->pImageData 837 + sizeof(struct HpmfwupgImageHeader) 838 + pImageHeader->oemDataLength 839 + sizeof(unsigned char)/*chksum*/); 840 if (option & VIEW_MODE) { 841 HpmDisplayVersionHeader(TARGET_VER|ROLLBACK_VER|IMAGE_VER); 842 } 843 /* Perform actions defined in the image */ 844 while (pImagePtr < (pFwupgCtx->pImageData + pFwupgCtx->imageSize 845 - HPMFWUPG_MD5_SIGNATURE_LENGTH)) { 846 /* Get action record */ 847 pActionRecord = (struct HpmfwupgActionRecord*)pImagePtr; 848 /* Validate action record checksum */ 849 if (HpmfwupgValidateActionRecordChecksum(pActionRecord) != HPMFWUPG_SUCCESS) { 850 return HPMFWUPG_ERROR; 851 } 852 /* Validate affected components */ 853 if (pActionRecord->components.ComponentBits.byte 854 && !pFwupgCtx->targetCap.componentsPresent.ComponentBits.byte) { 855 lprintf(LOG_NOTICE, 856 " Invalid action record. One or more affected components is not supported"); 857 return HPMFWUPG_ERROR; 858 } 859 switch (pActionRecord->actionType) { 860 case HPMFWUPG_ACTION_BACKUP_COMPONENTS: 861 { 862 /* Make sure every component specified by 863 * this action record 864 * supports the backup operation 865 */ 866 for (componentId = HPMFWUPG_COMPONENT_ID_0; 867 componentId < HPMFWUPG_COMPONENT_ID_MAX; 868 componentId++) { 869 if (((1 << componentId) & pActionRecord->components.ComponentBits.byte) 870 && pFwupgCtx->genCompProp[componentId].GeneralCompProperties.bitfield.rollbackBackup == 0) { 871 lprintf(LOG_NOTICE, 872 " Component ID %d does not support backup", 873 componentId); 874 return HPMFWUPG_ERROR; 875 } 876 } 877 pImagePtr += sizeof(struct HpmfwupgActionRecord); 878 } 879 break; 880 case HPMFWUPG_ACTION_PREPARE_COMPONENTS: 881 { 882 /* Make sure every components specified by 883 * this action 884 * supports the prepare operation 885 */ 886 for (componentId = HPMFWUPG_COMPONENT_ID_0; 887 componentId < HPMFWUPG_COMPONENT_ID_MAX; 888 componentId++) { 889 if (((1 << componentId) & pActionRecord->components.ComponentBits.byte) 890 && pFwupgCtx->genCompProp[componentId].GeneralCompProperties.bitfield.preparationSupport == 0) { 891 lprintf(LOG_NOTICE, 892 " Component ID %d does not support preparation", 893 componentId); 894 return HPMFWUPG_ERROR; 895 } 896 } 897 pImagePtr += sizeof(struct HpmfwupgActionRecord); 898 } 899 break; 900 case HPMFWUPG_ACTION_UPLOAD_FIRMWARE: 901 /* Upload all firmware blocks */ 902 { 903 struct HpmfwupgFirmwareImage *pFwImage; 904 unsigned char *pData; 905 unsigned int firmwareLength; 906 unsigned char mode; 907 unsigned char componentId; 908 unsigned char componentIdByte; 909 unsigned int upgrade_comp; 910 VERSIONINFO *pVersionInfo; 911 /* Save component ID on which the upload is done */ 912 componentIdByte = pActionRecord->components.ComponentBits.byte; 913 componentId = 0; 914 while ((componentIdByte >>= 1) != 0) { 915 componentId++; 916 } 917 pFwImage = (struct HpmfwupgFirmwareImage*)(pImagePtr 918 + sizeof(struct HpmfwupgActionRecord)); 919 pData = ((unsigned char*)pFwImage 920 + sizeof(struct HpmfwupgFirmwareImage)); 921 /* Get firmware length */ 922 firmwareLength = pFwImage->length[0]; 923 firmwareLength |= (pFwImage->length[1] << 8) & 0xff00; 924 firmwareLength |= (pFwImage->length[2] << 16) & 0xff0000; 925 firmwareLength |= (pFwImage->length[3] << 24) & 0xff000000; 926 927 pVersionInfo = &gVersionInfo[componentId]; 928 929 pVersionInfo->imageMajor = pFwImage->version[0]; 930 pVersionInfo->imageMinor = pFwImage->version[1]; 931 pVersionInfo->imageAux[0] = pFwImage->version[2]; 932 pVersionInfo->imageAux[1] = pFwImage->version[3]; 933 pVersionInfo->imageAux[2] = pFwImage->version[4]; 934 pVersionInfo->imageAux[3] = pFwImage->version[5]; 935 936 mode = TARGET_VER | IMAGE_VER; 937 /* check if component is selected for upgrade */ 938 upgrade_comp = !componentMask 939 || (componentMask & pActionRecord->components.ComponentBits.byte); 940 /* check if current component version requires upgrade */ 941 if (upgrade_comp && !(option & (FORCE_MODE|COMPARE_MODE))) { 942 upgrade_comp = image_version_upgradable(pVersionInfo); 943 } 944 if (verbose) { 945 lprintf(LOG_NOTICE, 946 "%s component %d", 947 (upgrade_comp ? "Updating" : "Skipping"), 948 componentId); 949 } 950 if (upgrade_comp) { 951 pFwupgCtx->compUpdateMask.ComponentBits.byte|= 1 << componentId; 952 } 953 if (option & VIEW_MODE) { 954 if (pVersionInfo->rollbackSupported) { 955 mode|= ROLLBACK_VER; 956 } 957 HpmDisplayVersion(mode,pVersionInfo, upgrade_comp); 958 printf("\n"); 959 } 960 pImagePtr = pData + firmwareLength; 961 } 962 break; 963 default: 964 lprintf(LOG_NOTICE, 965 " Invalid Action type. Cannot continue"); 966 return HPMFWUPG_ERROR; 967 break; 968 } 969 } 970 if (option & VIEW_MODE) { 971 HpmDisplayLine("-",74); 972 fflush(stdout); 973 lprintf(LOG_NOTICE, 974 "(*) Component requires Payload Cold Reset"); 975 lprintf(LOG_NOTICE, 976 "(^) Indicates component would be upgraded"); 977 } 978 return HPMFWUPG_SUCCESS; 979 } 980 981 /* HpmfwupgUpgradeStage - upgrade stage of a firmware upgrade procedure as 982 * defined in section 3.3 of the IPM Controller Firmware Upgrade Specification 983 * version 1.0 984 */ 985 int 986 HpmfwupgUpgradeStage(struct ipmi_intf *intf, 987 struct HpmfwupgUpgradeCtx *pFwupgCtx, int option) 988 { 989 struct HpmfwupgImageHeader *pImageHeader = (struct HpmfwupgImageHeader*) 990 pFwupgCtx->pImageData; 991 struct HpmfwupgActionRecord* pActionRecord; 992 int rc = HPMFWUPG_SUCCESS; 993 unsigned char *pImagePtr; 994 unsigned int actionsSize; 995 int flagColdReset = FALSE; 996 time_t start,end; 997 /* Put pointer after image header */ 998 pImagePtr = (unsigned char*) 999 (pFwupgCtx->pImageData + sizeof(struct HpmfwupgImageHeader) + 1000 pImageHeader->oemDataLength + sizeof(unsigned char)/*checksum*/); 1001 /* Deternime actions size */ 1002 actionsSize = pFwupgCtx->imageSize - sizeof(struct HpmfwupgImageHeader); 1003 if (!(option & VIEW_MODE)) { 1004 HpmDisplayUpgradeHeader(); 1005 } 1006 /* Perform actions defined in the image */ 1007 while (( pImagePtr < (pFwupgCtx->pImageData + pFwupgCtx->imageSize - 1008 HPMFWUPG_MD5_SIGNATURE_LENGTH)) 1009 && (rc == HPMFWUPG_SUCCESS)) { 1010 /* Get action record */ 1011 pActionRecord = (struct HpmfwupgActionRecord*)pImagePtr; 1012 /* Validate action record checksum */ 1013 rc = HpmfwupgValidateActionRecordChecksum(pActionRecord); 1014 if (rc != HPMFWUPG_SUCCESS) { 1015 continue; 1016 } 1017 switch(pActionRecord->actionType) { 1018 case HPMFWUPG_ACTION_BACKUP_COMPONENTS: 1019 { 1020 if (!(option & COMPARE_MODE)) { 1021 /* Send Upgrade Action command */ 1022 struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd; 1023 /* Affect only selected components */ 1024 initUpgActionCmd.req.componentsMask.ComponentBits.byte = 1025 pFwupgCtx->compUpdateMask.ComponentBits.byte & 1026 pActionRecord->components.ComponentBits.byte; 1027 /* Action is prepare components */ 1028 if (initUpgActionCmd.req.componentsMask.ComponentBits.byte) { 1029 initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_BACKUP; 1030 rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx); 1031 } 1032 } 1033 pImagePtr+= sizeof(struct HpmfwupgActionRecord); 1034 } 1035 break; 1036 case HPMFWUPG_ACTION_PREPARE_COMPONENTS: 1037 { 1038 if (!(option & COMPARE_MODE)) { 1039 /* Send prepare components command */ 1040 struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd; 1041 /* Affect only selected components */ 1042 initUpgActionCmd.req.componentsMask.ComponentBits.byte = 1043 pFwupgCtx->compUpdateMask.ComponentBits.byte & 1044 pActionRecord->components.ComponentBits.byte; 1045 if (initUpgActionCmd.req.componentsMask.ComponentBits.byte) { 1046 /* Action is prepare components */ 1047 initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_PREPARE; 1048 rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx); 1049 } 1050 } 1051 pImagePtr+= sizeof(struct HpmfwupgActionRecord); 1052 } 1053 break; 1054 case HPMFWUPG_ACTION_UPLOAD_FIRMWARE: 1055 /* Upload all firmware blocks */ 1056 rc = HpmFwupgActionUploadFirmware(pActionRecord->components, 1057 pFwupgCtx, 1058 &pImagePtr, 1059 intf, 1060 option, 1061 &flagColdReset); 1062 break; 1063 default: 1064 lprintf(LOG_NOTICE, " Invalid Action type. Cannot continue"); 1065 rc = HPMFWUPG_ERROR; 1066 break; 1067 } 1068 } 1069 HpmDisplayLine("-", 79); 1070 fflush(stdout); 1071 lprintf(LOG_NOTICE, "(*) Component requires Payload Cold Reset"); 1072 return rc; 1073 } 1074 1075 int 1076 HpmFwupgActionUploadFirmware(struct HpmfwupgComponentBitMask components, 1077 struct HpmfwupgUpgradeCtx *pFwupgCtx, 1078 unsigned char **pImagePtr, 1079 struct ipmi_intf *intf, 1080 int option, 1081 int *pFlagColdReset) 1082 { 1083 struct HpmfwupgFirmwareImage *pFwImage; 1084 struct HpmfwupgInitiateUpgradeActionCtx initUpgActionCmd; 1085 struct HpmfwupgUploadFirmwareBlockCtx uploadCmd; 1086 struct HpmfwupgFinishFirmwareUploadCtx finishCmd; 1087 VERSIONINFO *pVersionInfo; 1088 time_t start,end; 1089 1090 int rc = HPMFWUPG_SUCCESS; 1091 int skip = TRUE; 1092 unsigned char *pData, *pDataInitial; 1093 unsigned short count; 1094 unsigned int totalSent = 0; 1095 unsigned short bufLength = 0; 1096 unsigned short bufLengthIsSet = 0; 1097 unsigned int firmwareLength = 0; 1098 1099 unsigned int displayFWLength = 0; 1100 unsigned char *pDataTemp; 1101 unsigned int imageOffset = 0x00; 1102 unsigned int blockLength = 0x00; 1103 unsigned int lengthOfBlock = 0x00; 1104 unsigned int numTxPkts = 0; 1105 unsigned int numRxPkts = 0; 1106 unsigned char mode = 0; 1107 unsigned char componentId = 0x00; 1108 unsigned char componentIdByte = 0x00; 1109 uint16_t max_rq_size; 1110 1111 /* Save component ID on which the upload is done */ 1112 componentIdByte = components.ComponentBits.byte; 1113 while ((componentIdByte>>= 1) != 0) { 1114 componentId++; 1115 } 1116 pFwupgCtx->componentId = componentId; 1117 pVersionInfo = (VERSIONINFO *)&gVersionInfo[componentId]; 1118 pFwImage = (struct HpmfwupgFirmwareImage*)((*pImagePtr) 1119 + sizeof(struct HpmfwupgActionRecord)); 1120 pDataInitial = ((unsigned char *)pFwImage 1121 + sizeof(struct HpmfwupgFirmwareImage)); 1122 pData = pDataInitial; 1123 1124 /* Find max buffer length according the connection parameters */ 1125 max_rq_size = ipmi_intf_get_max_request_data_size(intf); 1126 1127 /* validate lower bound of max request size */ 1128 if (max_rq_size <= sizeof(struct HpmfwupgUploadFirmwareBlockReq)) { 1129 lprintf(LOG_ERROR, "Maximum request size is too small to " 1130 "send a upload request."); 1131 return HPMFWUPG_ERROR; 1132 } 1133 1134 bufLength = max_rq_size - sizeof(struct HpmfwupgUploadFirmwareBlockReq); 1135 1136 /* Get firmware length */ 1137 firmwareLength = pFwImage->length[0]; 1138 firmwareLength|= (pFwImage->length[1] << 8) & 0xff00; 1139 firmwareLength|= (pFwImage->length[2] << 16) & 0xff0000; 1140 firmwareLength|= (pFwImage->length[3] << 24) & 0xff000000; 1141 mode = TARGET_VER | IMAGE_VER; 1142 if (pVersionInfo->rollbackSupported) { 1143 mode |= ROLLBACK_VER; 1144 } 1145 if ((option & DEBUG_MODE)) { 1146 printf("\n\n Comp ID : %d [%-20s]\n", 1147 pVersionInfo->componentId, 1148 pFwImage->desc); 1149 } else { 1150 HpmDisplayVersion(mode, pVersionInfo, 0); 1151 } 1152 if ((1 << componentId) & pFwupgCtx->compUpdateMask.ComponentBits.byte) { 1153 if (verbose) { 1154 lprintf(LOG_NOTICE, "Do not skip %d", 1155 componentId); 1156 } 1157 skip = FALSE; 1158 } 1159 if (!skip) { 1160 HpmDisplayUpgrade(0,0,1,0); 1161 /* Initialize parameters */ 1162 uploadCmd.req = malloc(max_rq_size); 1163 if (!uploadCmd.req) { 1164 lprintf(LOG_ERR, "ipmitool: malloc failure"); 1165 return HPMFWUPG_ERROR; 1166 } 1167 uploadCmd.req->blockNumber = 0; 1168 /* Send Initiate Upgrade Action */ 1169 initUpgActionCmd.req.componentsMask = components; 1170 if (option & COMPARE_MODE) { 1171 /* Action is compare */ 1172 initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_COMPARE; 1173 } else { 1174 /* Action is upgrade */ 1175 initUpgActionCmd.req.upgradeAction = HPMFWUPG_UPGRADE_ACTION_UPGRADE; 1176 } 1177 rc = HpmfwupgInitiateUpgradeAction(intf, &initUpgActionCmd, pFwupgCtx); 1178 if (rc != HPMFWUPG_SUCCESS) { 1179 skip = TRUE; 1180 } 1181 if ((pVersionInfo->coldResetRequired) && (!skip)) { 1182 *pFlagColdReset = TRUE; 1183 } 1184 /* pDataInitial is the starting pointer of the image data */ 1185 /* pDataTemp is one which we will move across */ 1186 pData = pDataInitial; 1187 pDataTemp = pDataInitial; 1188 lengthOfBlock = firmwareLength; 1189 totalSent = 0x00; 1190 displayFWLength= firmwareLength; 1191 time(&start); 1192 while ((pData < (pDataTemp+lengthOfBlock)) && (rc == HPMFWUPG_SUCCESS)) { 1193 if ((pData+bufLength) <= (pDataTemp+lengthOfBlock)) { 1194 count = bufLength; 1195 } else { 1196 count = (unsigned short)((pDataTemp+lengthOfBlock) - pData); 1197 } 1198 memcpy(&uploadCmd.req->data, pData, bufLength); 1199 imageOffset = 0x00; 1200 blockLength = 0x00; 1201 numTxPkts++; 1202 rc = HpmfwupgUploadFirmwareBlock(intf, &uploadCmd, 1203 pFwupgCtx, count, &imageOffset,&blockLength); 1204 numRxPkts++; 1205 if (rc != HPMFWUPG_SUCCESS) { 1206 if (rc == HPMFWUPG_UPLOAD_BLOCK_LENGTH && !bufLengthIsSet) { 1207 rc = HPMFWUPG_SUCCESS; 1208 /* Retry with a smaller buffer length */ 1209 if (strstr(intf->name,"lan") != NULL && bufLength > 8) { 1210 bufLength-= 8; 1211 lprintf(LOG_INFO, 1212 "Trying reduced buffer length: %d", 1213 bufLength); 1214 } else if (bufLength) { 1215 bufLength-= 1; 1216 lprintf(LOG_INFO, 1217 "Trying reduced buffer length: %d", 1218 bufLength); 1219 } else { 1220 rc = HPMFWUPG_ERROR; 1221 } 1222 } else if (rc == HPMFWUPG_UPLOAD_RETRY) { 1223 rc = HPMFWUPG_SUCCESS; 1224 } else { 1225 fflush(stdout); 1226 lprintf(LOG_NOTICE, 1227 "\n Error in Upload FIRMWARE command [rc=%d]\n", 1228 rc); 1229 lprintf(LOG_NOTICE, 1230 "\n TotalSent:0x%x ", 1231 totalSent); 1232 /* Exiting from the function */ 1233 rc = HPMFWUPG_ERROR; 1234 } 1235 } else { 1236 /* success, buf length is valid */ 1237 bufLengthIsSet = 1; 1238 if (blockLength > firmwareLength) { 1239 /* 1240 * blockLength is the remaining length of the firmware to upload so 1241 * if its greater than the firmware length then its kind of error 1242 */ 1243 lprintf(LOG_NOTICE, 1244 "\n Error in Upload FIRMWARE command [rc=%d]\n", 1245 rc); 1246 lprintf(LOG_NOTICE, 1247 "\n TotalSent:0x%x Img offset:0x%x Blk length:0x%x Fwlen:0x%x\n", 1248 totalSent,imageOffset,blockLength,firmwareLength); 1249 rc = HPMFWUPG_ERROR; 1250 } 1251 totalSent += count; 1252 if (imageOffset != 0x00) { 1253 /* block Length is valid */ 1254 lengthOfBlock = blockLength; 1255 pDataTemp = pDataInitial + imageOffset; 1256 pData = pDataTemp; 1257 if (displayFWLength == firmwareLength) { 1258 /* This is basically used only to make sure that we display uptil 100% */ 1259 displayFWLength = blockLength + totalSent; 1260 } 1261 } else { 1262 pData += count; 1263 } 1264 time(&end); 1265 /* 1266 * Just added debug mode in case we need to see exactly how many bytes have 1267 * gone through - Its a hidden option used mainly should be used for debugging 1268 */ 1269 if (option & DEBUG_MODE) { 1270 fflush(stdout); 1271 printf(" Blk Num : %02x Bytes : %05x ", 1272 uploadCmd.req->blockNumber,totalSent); 1273 if (imageOffset || blockLength) { 1274 printf("\n--> ImgOff : %x BlkLen : %x\n", 1275 imageOffset,blockLength); 1276 } 1277 if (displayFWLength == totalSent) { 1278 printf("\n Time Taken %02ld:%02ld", 1279 (end-start)/60, (end-start)%60); 1280 printf("\n\n"); 1281 } 1282 } else { 1283 HpmDisplayUpgrade(0, totalSent, 1284 displayFWLength, (end-start)); 1285 } 1286 uploadCmd.req->blockNumber++; 1287 } 1288 } 1289 /* free buffer */ 1290 free(uploadCmd.req); 1291 uploadCmd.req = NULL; 1292 } 1293 if (skip) { 1294 HpmDisplayUpgrade(1,0,0,0); 1295 if ((option & COMPARE_MODE) 1296 && !pFwupgCtx->genCompProp[pFwupgCtx->componentId].GeneralCompProperties.bitfield.comparisonSupport) { 1297 printf("| |Comparison isn't supported for given compenent. |\n"); 1298 } 1299 *pImagePtr = pDataInitial + firmwareLength; 1300 } 1301 if (rc == HPMFWUPG_SUCCESS && !skip) { 1302 /* Send finish component */ 1303 /* Set image length */ 1304 finishCmd.req.componentId = componentId; 1305 /* We need to send the actual data that is sent 1306 * not the comlete firmware image length 1307 */ 1308 finishCmd.req.imageLength[0] = totalSent & 0xFF; 1309 finishCmd.req.imageLength[1] = (totalSent >> 8) & 0xFF; 1310 finishCmd.req.imageLength[2] = (totalSent >> 16) & 0xFF; 1311 finishCmd.req.imageLength[3] = (totalSent >> 24) & 0xFF; 1312 rc = HpmfwupgFinishFirmwareUpload(intf, &finishCmd, 1313 pFwupgCtx, option); 1314 *pImagePtr = pDataInitial + firmwareLength; 1315 } 1316 return rc; 1317 } 1318 1319 /* HpmfwupgActivationStage - validate stage of a firmware upgrade procedure as 1320 * defined in section 3.4 of the IPM Controller Firmware Upgrade Specification 1321 * version 1.0 1322 */ 1323 int 1324 HpmfwupgActivationStage(struct ipmi_intf *intf, 1325 struct HpmfwupgUpgradeCtx *pFwupgCtx) 1326 { 1327 int rc = HPMFWUPG_SUCCESS; 1328 struct HpmfwupgActivateFirmwareCtx activateCmd; 1329 struct HpmfwupgImageHeader *pImageHeader = (struct HpmfwupgImageHeader*) 1330 pFwupgCtx->pImageData; 1331 /* Print out stuf...*/ 1332 printf(" "); 1333 fflush(stdout); 1334 /* Activate new firmware */ 1335 activateCmd.req.rollback_override = 0; 1336 rc = HpmfwupgActivateFirmware(intf, &activateCmd, pFwupgCtx); 1337 if (rc == HPMFWUPG_SUCCESS) { 1338 /* Query self test result if supported by target and new image */ 1339 if ((pFwupgCtx->targetCap.GlobalCapabilities.bitField.ipmcSelftestCap == 1) 1340 || (pImageHeader->imageCapabilities.bitField.imageSelfTest == 1)) { 1341 struct HpmfwupgQuerySelftestResultCtx selfTestCmd; 1342 rc = HpmfwupgQuerySelftestResult(intf, &selfTestCmd, 1343 pFwupgCtx); 1344 if (rc == HPMFWUPG_SUCCESS) { 1345 /* Get the self test result */ 1346 if (selfTestCmd.resp.result1 != 0x55) { 1347 /* Perform manual rollback if necessary */ 1348 /* BACKUP/ MANUAL ROLLBACK not supported by this UA */ 1349 lprintf(LOG_NOTICE, " Self test failed:"); 1350 lprintf(LOG_NOTICE, " Result1 = %x", 1351 selfTestCmd.resp.result1); 1352 lprintf(LOG_NOTICE, " Result2 = %x", 1353 selfTestCmd.resp.result2); 1354 rc = HPMFWUPG_ERROR; 1355 } 1356 } else { 1357 /* Perform manual rollback if necessary */ 1358 /* BACKUP / MANUAL ROLLBACK not supported by this UA */ 1359 lprintf(LOG_NOTICE," Self test failed."); 1360 } 1361 } 1362 } 1363 /* If activation / self test failed, query rollback 1364 * status if automatic rollback supported 1365 */ 1366 if (rc == HPMFWUPG_ERROR) { 1367 if ((pFwupgCtx->targetCap.GlobalCapabilities.bitField.autRollback == 1) 1368 && (pFwupgCtx->genCompProp[pFwupgCtx->componentId].GeneralCompProperties.bitfield.rollbackBackup != 0x00)) { 1369 struct HpmfwupgQueryRollbackStatusCtx rollCmd; 1370 lprintf(LOG_NOTICE," Getting rollback status..."); 1371 fflush(stdout); 1372 rc = HpmfwupgQueryRollbackStatus(intf, 1373 &rollCmd, pFwupgCtx); 1374 } 1375 } 1376 return rc; 1377 } 1378 1379 int 1380 HpmfwupgGetBufferFromFile(char *imageFilename, 1381 struct HpmfwupgUpgradeCtx *pFwupgCtx) 1382 { 1383 int rc = HPMFWUPG_SUCCESS; 1384 int ret = 0; 1385 FILE *pImageFile = fopen(imageFilename, "rb"); 1386 if (pImageFile == NULL) { 1387 lprintf(LOG_ERR, "Cannot open image file '%s'", 1388 imageFilename); 1389 return HPMFWUPG_ERROR; 1390 } 1391 /* Get the raw data in file */ 1392 fseek(pImageFile, 0, SEEK_END); 1393 pFwupgCtx->imageSize = ftell(pImageFile); 1394 pFwupgCtx->pImageData = malloc(sizeof(unsigned char)*pFwupgCtx->imageSize); 1395 if (pFwupgCtx->pImageData == NULL) { 1396 lprintf(LOG_ERR, "ipmitool: malloc failure"); 1397 fclose(pImageFile); 1398 return HPMFWUPG_ERROR; 1399 } 1400 rewind(pImageFile); 1401 ret = fread(pFwupgCtx->pImageData, 1402 sizeof(unsigned char), 1403 pFwupgCtx->imageSize, 1404 pImageFile); 1405 if (ret != pFwupgCtx->imageSize) { 1406 lprintf(LOG_ERR, 1407 "Failed to read file %s size %d", 1408 imageFilename, 1409 pFwupgCtx->imageSize); 1410 rc = HPMFWUPG_ERROR; 1411 } 1412 fclose(pImageFile); 1413 return rc; 1414 } 1415 1416 int 1417 HpmfwupgGetDeviceId(struct ipmi_intf *intf, struct ipm_devid_rsp *pGetDevId) 1418 { 1419 struct ipmi_rs *rsp; 1420 struct ipmi_rq req; 1421 memset(&req, 0, sizeof(req)); 1422 req.msg.netfn = IPMI_NETFN_APP; 1423 req.msg.cmd = BMC_GET_DEVICE_ID; 1424 req.msg.data_len = 0; 1425 rsp = HpmfwupgSendCmd(intf, req, NULL); 1426 if (rsp == NULL) { 1427 lprintf(LOG_ERR, "Error getting device ID."); 1428 return HPMFWUPG_ERROR; 1429 } 1430 if (rsp->ccode != 0x00) { 1431 lprintf(LOG_ERR, "Error getting device ID."); 1432 lprintf(LOG_ERR, "compcode=0x%x: %s", 1433 rsp->ccode, 1434 val2str(rsp->ccode, completion_code_vals)); 1435 return HPMFWUPG_ERROR; 1436 } 1437 memcpy(pGetDevId, rsp->data, sizeof(struct ipm_devid_rsp)); 1438 return HPMFWUPG_SUCCESS; 1439 } 1440 1441 int 1442 HpmfwupgGetTargetUpgCapabilities(struct ipmi_intf *intf, 1443 struct HpmfwupgGetTargetUpgCapabilitiesCtx *pCtx) 1444 { 1445 struct ipmi_rs *rsp; 1446 struct ipmi_rq req; 1447 pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER; 1448 memset(&req, 0, sizeof(req)); 1449 req.msg.netfn = IPMI_NETFN_PICMG; 1450 req.msg.cmd = HPMFWUPG_GET_TARGET_UPG_CAPABILITIES; 1451 req.msg.data = (unsigned char*)&pCtx->req; 1452 req.msg.data_len = sizeof(struct HpmfwupgGetTargetUpgCapabilitiesReq); 1453 rsp = HpmfwupgSendCmd(intf, req, NULL); 1454 if (rsp == NULL) { 1455 lprintf(LOG_ERR, 1456 "Error getting target upgrade capabilities."); 1457 return HPMFWUPG_ERROR; 1458 } 1459 if (rsp->ccode != 0x00) { 1460 lprintf(LOG_ERR, 1461 "Error getting target upgrade capabilities, ccode: 0x%x: %s", 1462 rsp->ccode, 1463 val2str(rsp->ccode, completion_code_vals)); 1464 return HPMFWUPG_ERROR; 1465 } 1466 memcpy(&pCtx->resp, rsp->data, 1467 sizeof(struct HpmfwupgGetTargetUpgCapabilitiesResp)); 1468 if (verbose) { 1469 lprintf(LOG_NOTICE, "TARGET UPGRADE CAPABILITIES"); 1470 lprintf(LOG_NOTICE, "-------------------------------"); 1471 lprintf(LOG_NOTICE, "HPM.1 version............%d ", 1472 pCtx->resp.hpmVersion); 1473 lprintf(LOG_NOTICE, "Component 0 presence....[%c] ", 1474 pCtx->resp.componentsPresent.ComponentBits.bitField.component0 ? 'y' : 'n'); 1475 lprintf(LOG_NOTICE, "Component 1 presence....[%c] ", 1476 pCtx->resp.componentsPresent.ComponentBits.bitField.component1 ? 'y' : 'n'); 1477 lprintf(LOG_NOTICE, "Component 2 presence....[%c] ", 1478 pCtx->resp.componentsPresent.ComponentBits.bitField.component2 ? 'y' : 'n'); 1479 lprintf(LOG_NOTICE, "Component 3 presence....[%c] ", 1480 pCtx->resp.componentsPresent.ComponentBits.bitField.component3 ? 'y' : 'n'); 1481 lprintf(LOG_NOTICE, "Component 4 presence....[%c] ", 1482 pCtx->resp.componentsPresent.ComponentBits.bitField.component4 ? 'y' : 'n'); 1483 lprintf(LOG_NOTICE, "Component 5 presence....[%c] ", 1484 pCtx->resp.componentsPresent.ComponentBits.bitField.component5 ? 'y' : 'n'); 1485 lprintf(LOG_NOTICE, "Component 6 presence....[%c] ", 1486 pCtx->resp.componentsPresent.ComponentBits.bitField.component6 ? 'y' : 'n'); 1487 lprintf(LOG_NOTICE, "Component 7 presence....[%c] ", 1488 pCtx->resp.componentsPresent.ComponentBits.bitField.component7 ? 'y' : 'n'); 1489 lprintf(LOG_NOTICE, "Upgrade undesirable.....[%c] ", 1490 pCtx->resp.GlobalCapabilities.bitField.fwUpgUndesirable ? 'y' : 'n'); 1491 lprintf(LOG_NOTICE, "Aut rollback override...[%c] ", 1492 pCtx->resp.GlobalCapabilities.bitField.autRollbackOverride ? 'y' : 'n'); 1493 lprintf(LOG_NOTICE, "IPMC degraded...........[%c] ", 1494 pCtx->resp.GlobalCapabilities.bitField.ipmcDegradedDurinUpg ? 'y' : 'n'); 1495 lprintf(LOG_NOTICE, "Defered activation......[%c] ", 1496 pCtx->resp.GlobalCapabilities.bitField.deferActivation ? 'y' : 'n'); 1497 lprintf(LOG_NOTICE, "Service affected........[%c] ", 1498 pCtx->resp.GlobalCapabilities.bitField.servAffectDuringUpg ? 'y' : 'n'); 1499 lprintf(LOG_NOTICE, "Manual rollback.........[%c] ", 1500 pCtx->resp.GlobalCapabilities.bitField.manualRollback ? 'y' : 'n'); 1501 lprintf(LOG_NOTICE, "Automatic rollback......[%c] ", 1502 pCtx->resp.GlobalCapabilities.bitField.autRollback ? 'y' : 'n'); 1503 lprintf(LOG_NOTICE, "Self test...............[%c] ", 1504 pCtx->resp.GlobalCapabilities.bitField.ipmcSelftestCap ? 'y' : 'n'); 1505 lprintf(LOG_NOTICE, "Upgrade timeout.........[%d sec] ", 1506 pCtx->resp.upgradeTimeout*5); 1507 lprintf(LOG_NOTICE, "Self test timeout.......[%d sec] ", 1508 pCtx->resp.selftestTimeout*5); 1509 lprintf(LOG_NOTICE, "Rollback timeout........[%d sec] ", 1510 pCtx->resp.rollbackTimeout*5); 1511 lprintf(LOG_NOTICE, "Inaccessibility timeout.[%d sec] \n", 1512 pCtx->resp.inaccessTimeout*5); 1513 } 1514 return HPMFWUPG_SUCCESS; 1515 } 1516 1517 int 1518 HpmfwupgGetComponentProperties(struct ipmi_intf *intf, 1519 struct HpmfwupgGetComponentPropertiesCtx *pCtx) 1520 { 1521 int rc = HPMFWUPG_SUCCESS; 1522 struct ipmi_rs * rsp; 1523 struct ipmi_rq req; 1524 pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER; 1525 memset(&req, 0, sizeof(req)); 1526 req.msg.netfn = IPMI_NETFN_PICMG; 1527 req.msg.cmd = HPMFWUPG_GET_COMPONENT_PROPERTIES; 1528 req.msg.data = (unsigned char*)&pCtx->req; 1529 req.msg.data_len = sizeof(struct HpmfwupgGetComponentPropertiesReq); 1530 rsp = HpmfwupgSendCmd(intf, req, NULL); 1531 if (rsp == NULL) { 1532 lprintf(LOG_NOTICE, 1533 "Error getting component properties\n"); 1534 return HPMFWUPG_ERROR; 1535 } 1536 if (rsp->ccode != 0x00) { 1537 lprintf(LOG_NOTICE, 1538 "Error getting component properties"); 1539 lprintf(LOG_NOTICE, 1540 "compcode=0x%x: %s", 1541 rsp->ccode, 1542 val2str(rsp->ccode, completion_code_vals)); 1543 return HPMFWUPG_ERROR; 1544 } 1545 switch (pCtx->req.selector) { 1546 case HPMFWUPG_COMP_GEN_PROPERTIES: 1547 memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetGeneralPropResp)); 1548 if (verbose) { 1549 lprintf(LOG_NOTICE, "GENERAL PROPERTIES"); 1550 lprintf(LOG_NOTICE, "-------------------------------"); 1551 lprintf(LOG_NOTICE, "Payload cold reset req....[%c] ", 1552 pCtx->resp.Response.generalPropResp.GeneralCompProperties.bitfield.payloadColdReset ? 'y' : 'n'); 1553 lprintf(LOG_NOTICE, "Def. activation supported.[%c] ", 1554 pCtx->resp.Response.generalPropResp.GeneralCompProperties.bitfield.deferredActivation ? 'y' : 'n'); 1555 lprintf(LOG_NOTICE, "Comparison supported......[%c] ", 1556 pCtx->resp.Response.generalPropResp.GeneralCompProperties.bitfield.comparisonSupport ? 'y' : 'n'); 1557 lprintf(LOG_NOTICE, "Preparation supported.....[%c] ", 1558 pCtx->resp.Response.generalPropResp.GeneralCompProperties.bitfield.preparationSupport ? 'y' : 'n'); 1559 lprintf(LOG_NOTICE, "Rollback supported........[%c] \n", 1560 pCtx->resp.Response.generalPropResp.GeneralCompProperties.bitfield.rollbackBackup ? 'y' : 'n'); 1561 } 1562 break; 1563 case HPMFWUPG_COMP_CURRENT_VERSION: 1564 memcpy(&pCtx->resp, rsp->data, 1565 sizeof(struct HpmfwupgGetCurrentVersionResp)); 1566 if (verbose) { 1567 lprintf(LOG_NOTICE, "Current Version: "); 1568 lprintf(LOG_NOTICE, " Major: %d", 1569 pCtx->resp.Response.currentVersionResp.currentVersion[0]); 1570 lprintf(LOG_NOTICE, " Minor: %x", 1571 pCtx->resp.Response.currentVersionResp.currentVersion[1]); 1572 lprintf(LOG_NOTICE, " Aux : %03d %03d %03d %03d\n", 1573 pCtx->resp.Response.currentVersionResp.currentVersion[2], 1574 pCtx->resp.Response.currentVersionResp.currentVersion[3], 1575 pCtx->resp.Response.currentVersionResp.currentVersion[4], 1576 pCtx->resp.Response.currentVersionResp.currentVersion[5]); 1577 } 1578 break; 1579 case HPMFWUPG_COMP_DESCRIPTION_STRING: 1580 memcpy(&pCtx->resp, rsp->data, 1581 sizeof(struct HpmfwupgGetDescStringResp)); 1582 if (verbose) { 1583 char descString[HPMFWUPG_DESC_STRING_LENGTH + 1]; 1584 memcpy(descString, 1585 pCtx->resp.Response.descStringResp.descString, 1586 HPMFWUPG_DESC_STRING_LENGTH); 1587 descString[HPMFWUPG_DESC_STRING_LENGTH] = '\0'; 1588 lprintf(LOG_NOTICE, 1589 "Description string: %s\n", 1590 descString); 1591 } 1592 break; 1593 case HPMFWUPG_COMP_ROLLBACK_FIRMWARE_VERSION: 1594 memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetRollbackFwVersionResp)); 1595 if (verbose) { 1596 lprintf(LOG_NOTICE, "Rollback FW Version: "); 1597 lprintf(LOG_NOTICE, " Major: %d", 1598 pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[0]); 1599 lprintf(LOG_NOTICE, " Minor: %x", 1600 pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[1]); 1601 lprintf(LOG_NOTICE, " Aux : %03d %03d %03d %03d\n", 1602 pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[2], 1603 pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[3], 1604 pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[4], 1605 pCtx->resp.Response.rollbackFwVersionResp.rollbackFwVersion[5]); 1606 } 1607 break; 1608 case HPMFWUPG_COMP_DEFERRED_FIRMWARE_VERSION: 1609 memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetDeferredFwVersionResp)); 1610 if (verbose) { 1611 lprintf(LOG_NOTICE, "Deferred FW Version: "); 1612 lprintf(LOG_NOTICE, " Major: %d", 1613 pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[0]); 1614 lprintf(LOG_NOTICE, " Minor: %x", 1615 pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[1]); 1616 lprintf(LOG_NOTICE, " Aux : %03d %03d %03d %03d\n", 1617 pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[2], 1618 pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[3], 1619 pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[4], 1620 pCtx->resp.Response.deferredFwVersionResp.deferredFwVersion[5]); 1621 } 1622 break; 1623 case HPMFWUPG_COMP_OEM_PROPERTIES: 1624 /* OEM Properties command */ 1625 memcpy(&pCtx->resp, rsp->data, sizeof(struct HpmfwupgGetOemProperties)); 1626 if (verbose) { 1627 unsigned char i = 0; 1628 lprintf(LOG_NOTICE,"OEM Properties: "); 1629 for (i=0; i < HPMFWUPG_OEM_LENGTH; i++) { 1630 lprintf(LOG_NOTICE, " 0x%x ", 1631 pCtx->resp.Response.oemProperties.oemRspData[i]); 1632 } 1633 } 1634 break; 1635 default: 1636 lprintf(LOG_NOTICE,"Unsupported component selector"); 1637 rc = HPMFWUPG_ERROR; 1638 break; 1639 } 1640 return rc; 1641 } 1642 1643 int 1644 HpmfwupgAbortUpgrade(struct ipmi_intf *intf, 1645 struct HpmfwupgAbortUpgradeCtx *pCtx) 1646 { 1647 int rc = HPMFWUPG_SUCCESS; 1648 struct ipmi_rs *rsp; 1649 struct ipmi_rq req; 1650 pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER; 1651 memset(&req, 0, sizeof(req)); 1652 req.msg.netfn = IPMI_NETFN_PICMG; 1653 req.msg.cmd = HPMFWUPG_ABORT_UPGRADE; 1654 req.msg.data = (unsigned char*)&pCtx->req; 1655 req.msg.data_len = sizeof(struct HpmfwupgAbortUpgradeReq); 1656 rsp = HpmfwupgSendCmd(intf, req, NULL); 1657 if (rsp == NULL) { 1658 lprintf(LOG_ERR, "Error - aborting upgrade."); 1659 return HPMFWUPG_ERROR; 1660 } 1661 if (rsp->ccode != 0x00) { 1662 lprintf(LOG_ERR, "Error aborting upgrade"); 1663 lprintf(LOG_ERR, "compcode=0x%x: %s", 1664 rsp->ccode, 1665 val2str(rsp->ccode, completion_code_vals)); 1666 rc = HPMFWUPG_ERROR; 1667 } 1668 return rc; 1669 } 1670 1671 int 1672 HpmfwupgInitiateUpgradeAction(struct ipmi_intf *intf, 1673 struct HpmfwupgInitiateUpgradeActionCtx *pCtx, 1674 struct HpmfwupgUpgradeCtx *pFwupgCtx) 1675 { 1676 int rc = HPMFWUPG_SUCCESS; 1677 struct ipmi_rs *rsp; 1678 struct ipmi_rq req; 1679 pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER; 1680 memset(&req, 0, sizeof(req)); 1681 req.msg.netfn = IPMI_NETFN_PICMG; 1682 req.msg.cmd = HPMFWUPG_INITIATE_UPGRADE_ACTION; 1683 req.msg.data = (unsigned char*)&pCtx->req; 1684 req.msg.data_len = sizeof(struct HpmfwupgInitiateUpgradeActionReq); 1685 rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx); 1686 if (rsp == NULL) { 1687 lprintf(LOG_ERR, "Error initiating upgrade action."); 1688 return HPMFWUPG_ERROR; 1689 } 1690 /* Long duration command handling */ 1691 if (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) { 1692 rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx); 1693 } else if (rsp->ccode != 0x00) { 1694 lprintf(LOG_NOTICE,"Error initiating upgrade action"); 1695 lprintf(LOG_NOTICE, "compcode=0x%x: %s", 1696 rsp->ccode, 1697 val2str(rsp->ccode, completion_code_vals)); 1698 rc = HPMFWUPG_ERROR; 1699 } 1700 return rc; 1701 } 1702 1703 int 1704 HpmfwupgUploadFirmwareBlock(struct ipmi_intf *intf, 1705 struct HpmfwupgUploadFirmwareBlockCtx *pCtx, 1706 struct HpmfwupgUpgradeCtx *pFwupgCtx, int count, 1707 unsigned int *imageOffset, unsigned int *blockLength) 1708 { 1709 int rc = HPMFWUPG_SUCCESS; 1710 struct ipmi_rs *rsp; 1711 struct ipmi_rq req; 1712 pCtx->req->picmgId = HPMFWUPG_PICMG_IDENTIFIER; 1713 memset(&req, 0, sizeof(req)); 1714 req.msg.netfn = IPMI_NETFN_PICMG; 1715 req.msg.cmd = HPMFWUPG_UPLOAD_FIRMWARE_BLOCK; 1716 req.msg.data = (unsigned char *)pCtx->req; 1717 /* 2 is the size of the upload struct - data */ 1718 req.msg.data_len = 2 + count; 1719 rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx); 1720 if (rsp == NULL) { 1721 lprintf(LOG_NOTICE, "Error uploading firmware block."); 1722 return HPMFWUPG_ERROR; 1723 } 1724 if (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS 1725 || rsp->ccode == 0x00) { 1726 /* 1727 * We need to check if the response also contains the next upload firmware offset 1728 * and the firmware length in its response - These are optional but very vital 1729 */ 1730 if (rsp->data_len > 1) { 1731 /* 1732 * If the response data length is greater than 1 it should contain both the 1733 * the Section offset and section length. Because we cannot just have 1734 * Section offset without section length so the length should be 9 1735 */ 1736 if (rsp->data_len == 9) { 1737 /* rsp->data[1] - LSB rsp->data[2] - rsp->data[3] = MSB */ 1738 *imageOffset = (rsp->data[4] << 24) + (rsp->data[3] << 16) + (rsp->data[2] << 8) + rsp->data[1]; 1739 *blockLength = (rsp->data[8] << 24) + (rsp->data[7] << 16) + (rsp->data[6] << 8) + rsp->data[5]; 1740 } else { 1741 /* 1742 * The Spec does not say much for this kind of errors where the 1743 * firmware returned only offset and length so currently returning it 1744 * as 0x82 - Internal CheckSum Error 1745 */ 1746 lprintf(LOG_NOTICE, 1747 "Error wrong rsp->datalen %d for Upload Firmware block command\n", 1748 rsp->data_len); 1749 rsp->ccode = HPMFWUPG_INT_CHECKSUM_ERROR; 1750 } 1751 } 1752 } 1753 /* Long duration command handling */ 1754 if (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) { 1755 rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx); 1756 } else if (rsp->ccode != 0x00) { 1757 /* PATCH --> This validation is to handle retryables errors codes on IPMB bus. 1758 * This will be fixed in the next release of open ipmi and this 1759 * check will have to be removed. (Buggy version = 39) 1760 */ 1761 if (HPMFWUPG_IS_RETRYABLE(rsp->ccode)) { 1762 lprintf(LOG_DEBUG, "HPM: [PATCH]Retryable error detected"); 1763 rc = HPMFWUPG_UPLOAD_RETRY; 1764 } else if (rsp->ccode == IPMI_CC_REQ_DATA_INV_LENGTH || 1765 rsp->ccode == IPMI_CC_REQ_DATA_FIELD_EXCEED) { 1766 /* If completion code = 0xc7(0xc8), we will retry with a reduced buffer length. 1767 * Do not print error. 1768 */ 1769 rc = HPMFWUPG_UPLOAD_BLOCK_LENGTH; 1770 } else { 1771 lprintf(LOG_ERR, "Error uploading firmware block"); 1772 lprintf(LOG_ERR, "compcode=0x%x: %s", 1773 rsp->ccode, 1774 val2str(rsp->ccode, 1775 completion_code_vals)); 1776 rc = HPMFWUPG_ERROR; 1777 } 1778 } 1779 return rc; 1780 } 1781 1782 int 1783 HpmfwupgFinishFirmwareUpload(struct ipmi_intf *intf, 1784 struct HpmfwupgFinishFirmwareUploadCtx *pCtx, 1785 struct HpmfwupgUpgradeCtx *pFwupgCtx, int option) 1786 { 1787 int rc = HPMFWUPG_SUCCESS; 1788 struct ipmi_rs *rsp; 1789 struct ipmi_rq req; 1790 pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER; 1791 memset(&req, 0, sizeof(req)); 1792 req.msg.netfn = IPMI_NETFN_PICMG; 1793 req.msg.cmd = HPMFWUPG_FINISH_FIRMWARE_UPLOAD; 1794 req.msg.data = (unsigned char*)&pCtx->req; 1795 req.msg.data_len = sizeof(struct HpmfwupgFinishFirmwareUploadReq); 1796 rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx); 1797 if (rsp == NULL) { 1798 lprintf(LOG_ERR, "Error fininshing firmware upload."); 1799 return HPMFWUPG_ERROR; 1800 } 1801 /* Long duration command handling */ 1802 if (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) { 1803 rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx); 1804 } else if ((option & COMPARE_MODE) && rsp->ccode == 0x83) { 1805 printf("| |Component's active copy doesn't match the upgrade image |\n"); 1806 } else if ((option & COMPARE_MODE) && rsp->ccode == IPMI_CC_OK) { 1807 printf("| |Comparison passed |\n"); 1808 } else if ( rsp->ccode != IPMI_CC_OK ) { 1809 lprintf(LOG_ERR, "Error finishing firmware upload"); 1810 lprintf(LOG_ERR, "compcode=0x%x: %s", 1811 rsp->ccode, 1812 val2str(rsp->ccode, completion_code_vals)); 1813 rc = HPMFWUPG_ERROR; 1814 } 1815 return rc; 1816 } 1817 1818 int 1819 HpmfwupgActivateFirmware(struct ipmi_intf *intf, 1820 struct HpmfwupgActivateFirmwareCtx *pCtx, 1821 struct HpmfwupgUpgradeCtx *pFwupgCtx) 1822 { 1823 int rc = HPMFWUPG_SUCCESS; 1824 struct ipmi_rs *rsp; 1825 struct ipmi_rq req; 1826 pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER; 1827 memset(&req, 0, sizeof(req)); 1828 req.msg.netfn = IPMI_NETFN_PICMG; 1829 req.msg.cmd = HPMFWUPG_ACTIVATE_FIRMWARE; 1830 req.msg.data = (unsigned char*)&pCtx->req; 1831 req.msg.data_len = sizeof(struct HpmfwupgActivateFirmwareReq) 1832 - (!pCtx->req.rollback_override ? 1 : 0); 1833 rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx); 1834 if (rsp == NULL) { 1835 lprintf(LOG_ERR, "Error activating firmware."); 1836 return HPMFWUPG_ERROR; 1837 } 1838 /* Long duration command handling */ 1839 if (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) { 1840 printf("Waiting firmware activation..."); 1841 fflush(stdout); 1842 rc = HpmfwupgWaitLongDurationCmd(intf, pFwupgCtx); 1843 if (rc == HPMFWUPG_SUCCESS) { 1844 lprintf(LOG_NOTICE, "OK"); 1845 } else { 1846 lprintf(LOG_NOTICE, "Failed"); 1847 } 1848 } else if (rsp->ccode != IPMI_CC_OK) { 1849 lprintf(LOG_ERR, "Error activating firmware"); 1850 lprintf(LOG_ERR, "compcode=0x%x: %s", 1851 rsp->ccode, 1852 val2str(rsp->ccode, completion_code_vals)); 1853 rc = HPMFWUPG_ERROR; 1854 } 1855 return rc; 1856 } 1857 1858 int 1859 HpmfwupgGetUpgradeStatus(struct ipmi_intf *intf, 1860 struct HpmfwupgGetUpgradeStatusCtx *pCtx, 1861 struct HpmfwupgUpgradeCtx *pFwupgCtx, 1862 int silent) 1863 { 1864 int rc = HPMFWUPG_SUCCESS; 1865 struct ipmi_rs *rsp; 1866 struct ipmi_rq req; 1867 pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER; 1868 memset(&req, 0, sizeof(req)); 1869 req.msg.netfn = IPMI_NETFN_PICMG; 1870 req.msg.cmd = HPMFWUPG_GET_UPGRADE_STATUS; 1871 req.msg.data = (unsigned char*)&pCtx->req; 1872 req.msg.data_len = sizeof(struct HpmfwupgGetUpgradeStatusReq); 1873 rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx); 1874 if (!rsp) { 1875 lprintf(LOG_NOTICE, 1876 "Error getting upgrade status. Failed to get response."); 1877 return HPMFWUPG_ERROR; 1878 } 1879 if (rsp->ccode == 0x00) { 1880 memcpy(&pCtx->resp, rsp->data, 1881 sizeof(struct HpmfwupgGetUpgradeStatusResp)); 1882 if (!silent) { 1883 lprintf(LOG_NOTICE, "Upgrade status:"); 1884 lprintf(LOG_NOTICE, 1885 " Command in progress: %x", 1886 pCtx->resp.cmdInProcess); 1887 lprintf(LOG_NOTICE, 1888 " Last command completion code: %x", 1889 pCtx->resp.lastCmdCompCode); 1890 } 1891 } else if (HPMFWUPG_IS_RETRYABLE(rsp->ccode)) { 1892 /* PATCH --> This validation is to handle retryable errors 1893 * codes on the IPMB bus. 1894 * This will be fixed in the next release of 1895 * open ipmi and this check can be removed. 1896 * (Buggy version = 39) 1897 */ 1898 if (!silent) { 1899 lprintf(LOG_DEBUG, "HPM: Retryable error detected"); 1900 } 1901 pCtx->resp.lastCmdCompCode = HPMFWUPG_COMMAND_IN_PROGRESS; 1902 } else { 1903 lprintf(LOG_NOTICE, "Error getting upgrade status"); 1904 lprintf(LOG_NOTICE, "compcode=0x%x: %s", rsp->ccode, 1905 val2str(rsp->ccode, completion_code_vals)); 1906 return HPMFWUPG_ERROR; 1907 } 1908 return HPMFWUPG_SUCCESS; 1909 } 1910 1911 int 1912 HpmfwupgManualFirmwareRollback(struct ipmi_intf *intf, 1913 struct HpmfwupgManualFirmwareRollbackCtx *pCtx) 1914 { 1915 struct HpmfwupgUpgradeCtx fwupgCtx; 1916 struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd; 1917 int rc = HPMFWUPG_SUCCESS; 1918 struct ipmi_rs *rsp; 1919 struct ipmi_rq req; 1920 /* prepare fake upgrade context */ 1921 memset(&fwupgCtx, 0, sizeof (fwupgCtx)); 1922 verbose--; 1923 rc = HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd); 1924 verbose++; 1925 if (rc != HPMFWUPG_SUCCESS) { 1926 return rc; 1927 } 1928 memcpy(&fwupgCtx.targetCap, &targetCapCmd.resp, sizeof(targetCapCmd.resp)); 1929 pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER; 1930 memset(&req, 0, sizeof(req)); 1931 req.msg.netfn = IPMI_NETFN_PICMG; 1932 req.msg.cmd = HPMFWUPG_MANUAL_FIRMWARE_ROLLBACK; 1933 req.msg.data = (unsigned char*)&pCtx->req; 1934 req.msg.data_len = sizeof(struct HpmfwupgManualFirmwareRollbackReq); 1935 rsp = HpmfwupgSendCmd(intf, req, &fwupgCtx); 1936 if (rsp == NULL) { 1937 lprintf(LOG_ERR, "Error sending manual rollback."); 1938 return HPMFWUPG_ERROR; 1939 } 1940 /* Long duration command handling */ 1941 if (rsp->ccode == IPMI_CC_OK 1942 || rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) { 1943 struct HpmfwupgQueryRollbackStatusCtx resCmd; 1944 printf("Waiting firmware rollback..."); 1945 fflush(stdout); 1946 rc = HpmfwupgQueryRollbackStatus(intf, &resCmd, &fwupgCtx); 1947 } else if ( rsp->ccode != 0x00 ) { 1948 lprintf(LOG_ERR, "Error sending manual rollback"); 1949 lprintf(LOG_ERR, "compcode=0x%x: %s", 1950 rsp->ccode, 1951 val2str(rsp->ccode, completion_code_vals)); 1952 rc = HPMFWUPG_ERROR; 1953 } 1954 return rc; 1955 } 1956 1957 int 1958 HpmfwupgQueryRollbackStatus(struct ipmi_intf *intf, 1959 struct HpmfwupgQueryRollbackStatusCtx *pCtx, 1960 struct HpmfwupgUpgradeCtx *pFwupgCtx) 1961 { 1962 int rc = HPMFWUPG_SUCCESS; 1963 struct ipmi_rs *rsp; 1964 struct ipmi_rq req; 1965 unsigned int rollbackTimeout = 0; 1966 unsigned int timeoutSec1, timeoutSec2; 1967 pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER; 1968 memset(&req, 0, sizeof(req)); 1969 req.msg.netfn = IPMI_NETFN_PICMG; 1970 req.msg.cmd = HPMFWUPG_QUERY_ROLLBACK_STATUS; 1971 req.msg.data = (unsigned char*)&pCtx->req; 1972 req.msg.data_len = sizeof(struct HpmfwupgQueryRollbackStatusReq); 1973 /* If we are not in upgrade context, we use default timeout values */ 1974 if (pFwupgCtx != NULL) { 1975 struct HpmfwupgImageHeader *pImageHeader; 1976 if (pFwupgCtx->pImageData) { 1977 pImageHeader = (struct HpmfwupgImageHeader*)pFwupgCtx->pImageData; 1978 rollbackTimeout = pImageHeader->rollbackTimeout; 1979 } else { 1980 rollbackTimeout = 0; 1981 } 1982 /* Use the greater of the two timeouts (header and target caps) */ 1983 rollbackTimeout = MAX(rollbackTimeout, 1984 pFwupgCtx->targetCap.rollbackTimeout) * 5; 1985 } else { 1986 rollbackTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT; 1987 } 1988 /* Poll rollback status until completion or timeout */ 1989 timeoutSec1 = time(NULL); 1990 timeoutSec2 = time(NULL); 1991 do { 1992 /* Must wait at least 100 ms between status requests */ 1993 usleep(100000); 1994 rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx); 1995 /* PATCH --> This validation is to handle retryables errors codes on IPMB bus. 1996 * This will be fixed in the next release of open ipmi and this 1997 * check will have to be removed. (Buggy version = 39) 1998 */ 1999 if (rsp) { 2000 if (HPMFWUPG_IS_RETRYABLE(rsp->ccode)) { 2001 lprintf(LOG_DEBUG,"HPM: [PATCH]Retryable error detected"); 2002 rsp->ccode = HPMFWUPG_COMMAND_IN_PROGRESS; 2003 } 2004 } 2005 timeoutSec2 = time(NULL); 2006 } while (rsp 2007 && ((rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) 2008 || (rsp->ccode == IPMI_CC_TIMEOUT)) 2009 && (timeoutSec2 - timeoutSec1 < rollbackTimeout)); 2010 if (rsp == NULL) { 2011 lprintf(LOG_ERR, "Error getting upgrade status."); 2012 return HPMFWUPG_ERROR; 2013 } 2014 if (rsp->ccode == 0x00) { 2015 memcpy(&pCtx->resp, rsp->data, 2016 sizeof(struct HpmfwupgQueryRollbackStatusResp)); 2017 if (pCtx->resp.rollbackComp.ComponentBits.byte != 0) { 2018 /* Rollback occured */ 2019 lprintf(LOG_NOTICE, 2020 "Rollback occured on component mask: 0x%02x", 2021 pCtx->resp.rollbackComp.ComponentBits.byte); 2022 } else { 2023 lprintf(LOG_NOTICE, 2024 "No Firmware rollback occured"); 2025 } 2026 } else if (rsp->ccode == 0x81) { 2027 lprintf(LOG_ERR, 2028 "Rollback failed on component mask: 0x%02x", 2029 pCtx->resp.rollbackComp.ComponentBits.byte); 2030 rc = HPMFWUPG_ERROR; 2031 } else { 2032 lprintf(LOG_ERR, 2033 "Error getting rollback status"); 2034 lprintf(LOG_ERR, 2035 "compcode=0x%x: %s", 2036 rsp->ccode, 2037 val2str(rsp->ccode, completion_code_vals)); 2038 rc = HPMFWUPG_ERROR; 2039 } 2040 return rc; 2041 } 2042 2043 int 2044 HpmfwupgQuerySelftestResult(struct ipmi_intf *intf, struct HpmfwupgQuerySelftestResultCtx *pCtx, 2045 struct HpmfwupgUpgradeCtx *pFwupgCtx) 2046 { 2047 int rc = HPMFWUPG_SUCCESS; 2048 struct ipmi_rs *rsp; 2049 struct ipmi_rq req; 2050 unsigned char selfTestTimeout = 0; 2051 unsigned int timeoutSec1, timeoutSec2; 2052 pCtx->req.picmgId = HPMFWUPG_PICMG_IDENTIFIER; 2053 /* If we are not in upgrade context, we use default timeout values */ 2054 if (pFwupgCtx != NULL) { 2055 /* Getting selftest timeout from new image */ 2056 struct HpmfwupgImageHeader *pImageHeader = (struct HpmfwupgImageHeader*) 2057 pFwupgCtx->pImageData; 2058 selfTestTimeout = MAX(pImageHeader->selfTestTimeout, 2059 pFwupgCtx->targetCap.selftestTimeout) * 5; 2060 } else { 2061 selfTestTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT; 2062 } 2063 memset(&req, 0, sizeof(req)); 2064 req.msg.netfn = IPMI_NETFN_PICMG; 2065 req.msg.cmd = HPMFWUPG_QUERY_SELFTEST_RESULT; 2066 req.msg.data = (unsigned char*)&pCtx->req; 2067 req.msg.data_len = sizeof(struct HpmfwupgQuerySelftestResultReq); 2068 /* Poll rollback status until completion or timeout */ 2069 timeoutSec1 = time(NULL); 2070 timeoutSec2 = time(NULL); 2071 do { 2072 /* Must wait at least 100 ms between status requests */ 2073 usleep(100000); 2074 rsp = HpmfwupgSendCmd(intf, req, pFwupgCtx); 2075 /* PATCH --> This validation is to handle retryables errors codes on IPMB bus. 2076 * This will be fixed in the next release of open ipmi and this 2077 * check will have to be removed. (Buggy version = 39) 2078 */ 2079 if (rsp) { 2080 if (HPMFWUPG_IS_RETRYABLE(rsp->ccode)) { 2081 lprintf(LOG_DEBUG, 2082 "HPM: [PATCH]Retryable error detected"); 2083 rsp->ccode = HPMFWUPG_COMMAND_IN_PROGRESS; 2084 } 2085 } 2086 timeoutSec2 = time(NULL); 2087 } while (rsp 2088 && (rsp->ccode == HPMFWUPG_COMMAND_IN_PROGRESS) 2089 && (timeoutSec2 - timeoutSec1 < selfTestTimeout)); 2090 if (rsp == NULL) { 2091 lprintf(LOG_NOTICE, "Error getting upgrade status\n"); 2092 return HPMFWUPG_ERROR; 2093 } 2094 if (rsp->ccode == 0x00) { 2095 memcpy(&pCtx->resp, rsp->data, 2096 sizeof(struct HpmfwupgQuerySelftestResultResp)); 2097 if (verbose) { 2098 lprintf(LOG_NOTICE, "Self test results:"); 2099 lprintf(LOG_NOTICE, "Result1 = %x", 2100 pCtx->resp.result1); 2101 lprintf(LOG_NOTICE, "Result2 = %x", 2102 pCtx->resp.result2); 2103 } 2104 } else { 2105 lprintf(LOG_NOTICE, "Error getting self test results"); 2106 lprintf(LOG_NOTICE, "compcode=0x%x: %s", 2107 rsp->ccode, 2108 val2str(rsp->ccode, completion_code_vals)); 2109 rc = HPMFWUPG_ERROR; 2110 } 2111 return rc; 2112 } 2113 2114 struct ipmi_rs * 2115 HpmfwupgSendCmd(struct ipmi_intf *intf, struct ipmi_rq req, 2116 struct HpmfwupgUpgradeCtx *pFwupgCtx) 2117 { 2118 struct ipmi_rs *rsp; 2119 unsigned int inaccessTimeout = 0, inaccessTimeoutCounter = 0; 2120 unsigned int upgradeTimeout = 0, upgradeTimeoutCounter = 0; 2121 unsigned int timeoutSec1, timeoutSec2; 2122 unsigned char retry = 0; 2123 /* If we are not in upgrade context, we use default timeout values */ 2124 if (pFwupgCtx != NULL) { 2125 inaccessTimeout = pFwupgCtx->targetCap.inaccessTimeout*5; 2126 upgradeTimeout = pFwupgCtx->targetCap.upgradeTimeout*5; 2127 } else { 2128 /* keeping the inaccessTimeout to 60 seconds results in almost 2900 retries 2129 * So if the target is not available it will be retrying the command for 2900 2130 * times which is not effecient -So reducing the Timout to 5 seconds which is 2131 * almost 200 retries if it continuously recieves 0xC3 as completion code. 2132 */ 2133 inaccessTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT; 2134 upgradeTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT; 2135 } 2136 timeoutSec1 = time(NULL); 2137 do { 2138 static unsigned char isValidSize = FALSE; 2139 rsp = intf->sendrecv(intf, &req); 2140 if (rsp == NULL) { 2141 #define HPM_LAN_PACKET_RESIZE_LIMIT 6 2142 /* also covers lanplus */ 2143 if (strstr(intf->name, "lan") != NULL) { 2144 static int errorCount=0; 2145 static struct ipmi_rs fakeRsp; 2146 lprintf(LOG_DEBUG, 2147 "HPM: no response available"); 2148 lprintf(LOG_DEBUG, 2149 "HPM: the command may be rejected for security reasons"); 2150 if (req.msg.netfn == IPMI_NETFN_PICMG 2151 && req.msg.cmd == HPMFWUPG_UPLOAD_FIRMWARE_BLOCK 2152 && errorCount < HPM_LAN_PACKET_RESIZE_LIMIT 2153 && (!isValidSize)) { 2154 lprintf(LOG_DEBUG, 2155 "HPM: upload firmware block API called"); 2156 lprintf(LOG_DEBUG, 2157 "HPM: returning length error to force resize"); 2158 fakeRsp.ccode = IPMI_CC_REQ_DATA_INV_LENGTH; 2159 rsp = &fakeRsp; 2160 errorCount++; 2161 } else if (req.msg.netfn == IPMI_NETFN_PICMG 2162 && (req.msg.cmd == HPMFWUPG_ACTIVATE_FIRMWARE 2163 || req.msg.cmd == HPMFWUPG_MANUAL_FIRMWARE_ROLLBACK)) { 2164 /* 2165 * rsp == NULL and command activate firmware or manual firmware 2166 * rollback most likely occurs when we have sent a firmware activation 2167 * request. Fake a command in progress response. 2168 */ 2169 lprintf(LOG_DEBUG, 2170 "HPM: activate/rollback firmware API called"); 2171 lprintf(LOG_DEBUG, 2172 "HPM: returning in progress to handle IOL session lost"); 2173 fakeRsp.ccode = HPMFWUPG_COMMAND_IN_PROGRESS; 2174 rsp = &fakeRsp; 2175 } else if (req.msg.netfn == IPMI_NETFN_PICMG 2176 && (req.msg.cmd == HPMFWUPG_QUERY_ROLLBACK_STATUS 2177 || req.msg.cmd == HPMFWUPG_GET_UPGRADE_STATUS 2178 || req.msg.cmd == HPMFWUPG_QUERY_SELFTEST_RESULT) 2179 && ( !intf->target_addr || intf->target_addr == intf->my_addr)) { 2180 /* reopen session only if target IPMC is directly accessed */ 2181 /* 2182 * rsp == NULL and command get upgrade status or query rollback 2183 * status most likely occurs when we are waiting for firmware 2184 * activation. Try to re-open the IOL session (re-open will work 2185 * once the IPMC recovers from firmware activation. 2186 */ 2187 lprintf(LOG_DEBUG, "HPM: upg/rollback status firmware API called"); 2188 lprintf(LOG_DEBUG, "HPM: try to re-open IOL session"); 2189 { 2190 /* force session re-open */ 2191 intf->opened = 0; 2192 intf->session->authtype = IPMI_SESSION_AUTHTYPE_NONE; 2193 intf->session->session_id = 0; 2194 intf->session->in_seq = 0; 2195 intf->session->out_seq = 0; 2196 intf->session->active = 0; 2197 intf->session->retry = 10; 2198 while (intf->open(intf) == HPMFWUPG_ERROR 2199 && inaccessTimeoutCounter < inaccessTimeout) { 2200 inaccessTimeoutCounter += (time(NULL) - timeoutSec1); 2201 timeoutSec1 = time(NULL); 2202 } 2203 /* Fake timeout to retry command */ 2204 fakeRsp.ccode = 0xc3; 2205 rsp = &fakeRsp; 2206 } 2207 } 2208 } 2209 } 2210 /* Handle inaccessibility timeout (rsp = NULL if IOL) */ 2211 if (rsp == NULL || rsp->ccode == 0xff || rsp->ccode == 0xc3 || rsp->ccode == 0xd3) { 2212 if (inaccessTimeoutCounter < inaccessTimeout) { 2213 timeoutSec2 = time(NULL); 2214 if (timeoutSec2 > timeoutSec1) { 2215 inaccessTimeoutCounter += timeoutSec2 - timeoutSec1; 2216 timeoutSec1 = time(NULL); 2217 } 2218 usleep(100000); 2219 retry = 1; 2220 } else { 2221 retry = 0; 2222 } 2223 } else if ( rsp->ccode == 0xc0 ) { 2224 /* Handle node busy timeout */ 2225 if (upgradeTimeoutCounter < upgradeTimeout) { 2226 timeoutSec2 = time(NULL); 2227 if (timeoutSec2 > timeoutSec1) { 2228 timeoutSec1 = time(NULL); 2229 upgradeTimeoutCounter += timeoutSec2 - timeoutSec1; 2230 } 2231 usleep(100000); 2232 retry = 1; 2233 } else { 2234 retry = 0; 2235 } 2236 } else { 2237 # ifdef ENABLE_OPENIPMI_V39_PATCH 2238 if (rsp->ccode == IPMI_CC_OK) { 2239 errorCount = 0 ; 2240 } 2241 # endif 2242 retry = 0; 2243 if (req.msg.netfn == IPMI_NETFN_PICMG 2244 && req.msg.cmd == HPMFWUPG_UPLOAD_FIRMWARE_BLOCK 2245 && (!isValidSize)) { 2246 lprintf(LOG_INFO, 2247 "Buffer length is now considered valid"); 2248 isValidSize = TRUE; 2249 } 2250 } 2251 } while (retry); 2252 return rsp; 2253 } 2254 2255 int 2256 HpmfwupgWaitLongDurationCmd(struct ipmi_intf *intf, 2257 struct HpmfwupgUpgradeCtx *pFwupgCtx) 2258 { 2259 int rc = HPMFWUPG_SUCCESS; 2260 unsigned int upgradeTimeout = 0; 2261 unsigned int timeoutSec1, timeoutSec2; 2262 struct HpmfwupgGetUpgradeStatusCtx upgStatusCmd; 2263 /* If we are not in upgrade context, we use default timeout values */ 2264 if (pFwupgCtx != NULL) { 2265 upgradeTimeout = (unsigned int)(pFwupgCtx->targetCap.upgradeTimeout*5); 2266 if (verbose) { 2267 printf("Use File Upgrade Capabilities: %i seconds\n", 2268 upgradeTimeout); 2269 } 2270 } else { 2271 /* Try to retreive from Caps */ 2272 struct HpmfwupgGetTargetUpgCapabilitiesCtx targetCapCmd; 2273 if(HpmfwupgGetTargetUpgCapabilities(intf, &targetCapCmd) != HPMFWUPG_SUCCESS) { 2274 upgradeTimeout = HPMFWUPG_DEFAULT_UPGRADE_TIMEOUT; 2275 if (verbose) { 2276 printf("Use default timeout: %i seconds\n", 2277 upgradeTimeout); 2278 } 2279 } else { 2280 upgradeTimeout = (unsigned int)(targetCapCmd.resp.upgradeTimeout * 5); 2281 if (verbose) { 2282 printf("Use Command Upgrade Capabilities Timeout: %i seconds\n", 2283 upgradeTimeout); 2284 } 2285 } 2286 } 2287 if (rc == HPMFWUPG_SUCCESS) { 2288 /* Poll upgrade status until completion or timeout*/ 2289 timeoutSec1 = time(NULL); 2290 timeoutSec2 = time(NULL); 2291 rc = HpmfwupgGetUpgradeStatus(intf, &upgStatusCmd, 2292 pFwupgCtx, 1); 2293 } 2294 while ( 2295 /* With KCS: Cover the case where we sometime 2296 * receive d5 (on the first get status) from 2297 * the ipmi driver. 2298 */ 2299 (upgStatusCmd.resp.lastCmdCompCode != 0x00 ) 2300 && ((timeoutSec2 - timeoutSec1) < upgradeTimeout ) 2301 && (rc == HPMFWUPG_SUCCESS)) { 2302 /* Must wait at least 1000 ms between status requests */ 2303 usleep(1000000); 2304 timeoutSec2 = time(NULL); 2305 rc = HpmfwupgGetUpgradeStatus(intf, &upgStatusCmd, pFwupgCtx, 1); 2306 /* 2307 * printf("Get Status: %x - %x = %x _ %x [%x]\n", 2308 ( timeoutSec2, timeoutSec1, 2309 * (timeoutSec2 - timeoutSec1), 2310 * upgradeTimeout, rc); 2311 */ 2312 } 2313 if (upgStatusCmd.resp.lastCmdCompCode != 0x00) { 2314 if (verbose) { 2315 lprintf(LOG_NOTICE, 2316 "Error waiting for command %x, compcode = %x", 2317 upgStatusCmd.resp.cmdInProcess, 2318 upgStatusCmd.resp.lastCmdCompCode); 2319 } 2320 rc = HPMFWUPG_ERROR; 2321 } 2322 return rc; 2323 } 2324 2325 unsigned char 2326 HpmfwupgCalculateChecksum(unsigned char *pData, unsigned int length) 2327 { 2328 unsigned char checksum = 0; 2329 int dataIdx = 0; 2330 for (dataIdx = 0; dataIdx < length; dataIdx++) { 2331 checksum += pData[dataIdx]; 2332 } 2333 return checksum; 2334 } 2335 2336 void 2337 HpmfwupgPrintUsage(void) 2338 { 2339 lprintf(LOG_NOTICE, 2340 "help - This help menu."); 2341 lprintf(LOG_NOTICE, 2342 ""); 2343 lprintf(LOG_NOTICE, 2344 "check - Check the target information."); 2345 lprintf(LOG_NOTICE, 2346 "check <file> - If the user is unsure of what update is going to be "); 2347 lprintf(LOG_NOTICE, 2348 " This will display the existing target version and"); 2349 lprintf(LOG_NOTICE, 2350 " image version on the screen"); 2351 lprintf(LOG_NOTICE, 2352 ""); 2353 lprintf(LOG_NOTICE, 2354 "upgrade <file> [component x...] [force] [activate]"); 2355 lprintf(LOG_NOTICE, 2356 " - Copies components from a valid HPM.1 image to the target."); 2357 lprintf(LOG_NOTICE, 2358 " If one or more components specified by \"component\","); 2359 lprintf(LOG_NOTICE, 2360 " only the specified components are copied."); 2361 lprintf(LOG_NOTICE, 2362 " Otherwise, all the image components are copied."); 2363 lprintf(LOG_NOTICE, 2364 " Before copy, each image component undergoes a version check"); 2365 lprintf(LOG_NOTICE, 2366 " and can be skipped if the target component version"); 2367 lprintf(LOG_NOTICE, 2368 " is the same or more recent."); 2369 lprintf(LOG_NOTICE, 2370 " Use \"force\" to bypass the version check results."); 2371 lprintf(LOG_NOTICE, 2372 " Make sure to check the versions first using the"); 2373 lprintf(LOG_NOTICE, 2374 " \"check <file>\" command."); 2375 lprintf(LOG_NOTICE, 2376 " If \"activate\" is specified, the newly uploaded firmware"); 2377 lprintf(LOG_NOTICE, 2378 " is activated."); 2379 lprintf(LOG_NOTICE, 2380 "upgstatus - Returns the status of the last long duration command."); 2381 lprintf(LOG_NOTICE, 2382 ""); 2383 lprintf(LOG_NOTICE, 2384 "compare <file> - Perform \"Comparison of the Active Copy\" action for all the"); 2385 lprintf(LOG_NOTICE, 2386 " components present in the file."); 2387 lprintf(LOG_NOTICE, 2388 "compare <file> component x - Compare only component <x> from the given <file>"); 2389 lprintf(LOG_NOTICE, 2390 "activate - Activate the newly uploaded firmware."); 2391 lprintf(LOG_NOTICE, 2392 "activate norollback - Activate the newly uploaded firmware but inform"); 2393 lprintf(LOG_NOTICE, 2394 " the target to not automatically rollback if "); 2395 lprintf(LOG_NOTICE, 2396 " the upgrade fails."); 2397 lprintf(LOG_NOTICE, 2398 ""); 2399 lprintf(LOG_NOTICE, 2400 "targetcap - Get the target upgrade capabilities."); 2401 lprintf(LOG_NOTICE, 2402 ""); 2403 lprintf(LOG_NOTICE, 2404 "compprop <id> <prop> - Get specified component properties from the target."); 2405 lprintf(LOG_NOTICE, 2406 " Valid component <id>: 0-7 "); 2407 lprintf(LOG_NOTICE, 2408 " Properties <prop> can be one of the following: "); 2409 lprintf(LOG_NOTICE, 2410 " 0- General properties"); 2411 lprintf(LOG_NOTICE, 2412 " 1- Current firmware version"); 2413 lprintf(LOG_NOTICE, 2414 " 2- Description string"); 2415 lprintf(LOG_NOTICE, 2416 " 3- Rollback firmware version"); 2417 lprintf(LOG_NOTICE, 2418 " 4- Deferred firmware version"); 2419 lprintf(LOG_NOTICE, 2420 ""); 2421 lprintf(LOG_NOTICE, 2422 "abort - Abort the on-going firmware upgrade."); 2423 lprintf(LOG_NOTICE, 2424 ""); 2425 lprintf(LOG_NOTICE, 2426 "rollback - Performs a manual rollback on the IPM Controller."); 2427 lprintf(LOG_NOTICE, 2428 " firmware"); 2429 lprintf(LOG_NOTICE, 2430 "rollbackstatus - Query the rollback status."); 2431 lprintf(LOG_NOTICE, 2432 ""); 2433 lprintf(LOG_NOTICE, 2434 "selftestresult - Query the self test results.\n"); 2435 } 2436 2437 int 2438 ipmi_hpmfwupg_main(struct ipmi_intf *intf, int argc, char **argv) 2439 { 2440 int rc = HPMFWUPG_SUCCESS; 2441 int activateFlag = 0x00; 2442 int componentMask = 0; 2443 int componentId = 0; 2444 int option = 0; 2445 2446 lprintf(LOG_DEBUG,"ipmi_hpmfwupg_main()"); 2447 lprintf(LOG_NOTICE, "\nPICMG HPM.1 Upgrade Agent %d.%d.%d: \n", 2448 HPMFWUPG_VERSION_MAJOR, HPMFWUPG_VERSION_MINOR, 2449 HPMFWUPG_VERSION_SUBMINOR); 2450 if (argc < 1) { 2451 lprintf(LOG_ERR, "Not enough parameters given."); 2452 HpmfwupgPrintUsage(); 2453 return HPMFWUPG_ERROR; 2454 } 2455 if (strcmp(argv[0], "help") == 0) { 2456 HpmfwupgPrintUsage(); 2457 return HPMFWUPG_SUCCESS; 2458 } else if ((strcmp(argv[0], "check") == 0)) { 2459 /* hpm check */ 2460 if (argv[1] == NULL) { 2461 rc = HpmfwupgTargetCheck(intf,VIEW_MODE); 2462 } else { 2463 /* hpm check <filename> */ 2464 rc = HpmfwupgTargetCheck(intf,0); 2465 if (rc == HPMFWUPG_SUCCESS) { 2466 rc = HpmfwupgUpgrade(intf, argv[1], 0, 2467 0, VIEW_MODE); 2468 } 2469 } 2470 } else if (strcmp(argv[0], "upgrade") == 0) { 2471 int i =0; 2472 for (i=1; i< argc ; i++) { 2473 if (strcmp(argv[i],"activate") == 0) { 2474 activateFlag = 1; 2475 } 2476 /* hpm upgrade <filename> force */ 2477 if (strcmp(argv[i],"force") == 0) { 2478 option |= FORCE_MODE; 2479 } 2480 /* hpm upgrade <filename> component <comp Id> */ 2481 if (strcmp(argv[i],"component") == 0) { 2482 if (i+1 < argc) { 2483 /* Error Checking */ 2484 if (str2int(argv[i+1], &componentId) != 0 2485 || componentId < 0 2486 || componentId > HPMFWUPG_COMPONENT_ID_MAX) { 2487 lprintf(LOG_ERR, 2488 "Given Component ID '%s' is invalid.", 2489 argv[i+1]); 2490 lprintf(LOG_ERR, 2491 "Valid Compoment ID is: <0..7>"); 2492 return HPMFWUPG_ERROR; 2493 } 2494 if( verbose ) { 2495 lprintf(LOG_NOTICE, 2496 "Component Id %d provided", 2497 componentId ); 2498 } 2499 componentMask |= 1 << componentId; 2500 } else { 2501 /* That indicates the user has 2502 * given component on console but 2503 * not given any ID 2504 */ 2505 lprintf(LOG_NOTICE, 2506 "No component Id provided\n"); 2507 return HPMFWUPG_ERROR; 2508 } 2509 } 2510 if (strcmp(argv[i],"debug") == 0) { 2511 option |= DEBUG_MODE; 2512 } 2513 } 2514 rc = HpmfwupgTargetCheck(intf, 0); 2515 if (rc == HPMFWUPG_SUCCESS) { 2516 /* Call the Upgrade function to start the upgrade */ 2517 rc = HpmfwupgUpgrade(intf, argv[1], activateFlag, 2518 componentMask, option); 2519 } 2520 } else if (strcmp(argv[0], "compare") == 0) { 2521 int i = 0; 2522 for (i=1; i< argc; i++) { 2523 /* hpm compare <file> [component x...] */ 2524 if (strcmp(argv[i],"component") == 0) { 2525 if (i+1 < argc) { 2526 /* Error Checking */ 2527 if (str2int(argv[i+1], &componentId) != 0 2528 || componentId < 0 2529 || componentId > HPMFWUPG_COMPONENT_ID_MAX) { 2530 lprintf(LOG_ERR, 2531 "Given Component ID '%s' is invalid.", 2532 argv[i+1]); 2533 lprintf(LOG_ERR, 2534 "Valid Compoment ID is: <0..7>"); 2535 return HPMFWUPG_ERROR; 2536 } 2537 if( verbose ) { 2538 lprintf(LOG_NOTICE, 2539 "Component Id %d provided", 2540 componentId); 2541 } 2542 componentMask|= 1 << componentId; 2543 } else { 2544 /* That indicates the user 2545 * has given component on 2546 * console but not 2547 * given any ID 2548 */ 2549 lprintf(LOG_NOTICE, 2550 "No component Id provided\n"); 2551 return HPMFWUPG_ERROR; 2552 } 2553 } else if (strcmp(argv[i],"debug") == 0) { 2554 option|= DEBUG_MODE; 2555 } 2556 } 2557 option|= (COMPARE_MODE); 2558 rc = HpmfwupgTargetCheck(intf, 0); 2559 if (rc == HPMFWUPG_SUCCESS) { 2560 rc = HpmfwupgUpgrade(intf, argv[1], 0, 2561 componentMask, option); 2562 } 2563 } else if ((argc >= 1) && (strcmp(argv[0], "activate") == 0)) { 2564 struct HpmfwupgActivateFirmwareCtx cmdCtx; 2565 if ((argc == 2) && (strcmp(argv[1], "norollback") == 0)) { 2566 cmdCtx.req.rollback_override = 1; 2567 } else { 2568 cmdCtx.req.rollback_override = 0; 2569 } 2570 rc = HpmfwupgActivateFirmware(intf, &cmdCtx, NULL); 2571 } else if ((argc == 1) && (strcmp(argv[0], "targetcap") == 0)) { 2572 struct HpmfwupgGetTargetUpgCapabilitiesCtx cmdCtx; 2573 verbose++; 2574 rc = HpmfwupgGetTargetUpgCapabilities(intf, &cmdCtx); 2575 } else if ((argc == 3) && (strcmp(argv[0], "compprop") == 0)) { 2576 struct HpmfwupgGetComponentPropertiesCtx cmdCtx; 2577 if (str2uchar(argv[1], &(cmdCtx.req.componentId)) != 0 2578 || cmdCtx.req.componentId > 7) { 2579 lprintf(LOG_ERR, 2580 "Given Component ID '%s' is invalid.", 2581 argv[1]); 2582 lprintf(LOG_ERR, 2583 "Valid Compoment ID is: <0..7>"); 2584 return (-1); 2585 } 2586 if (str2uchar(argv[2], &(cmdCtx.req.selector)) != 0 2587 || cmdCtx.req.selector > 4) { 2588 lprintf(LOG_ERR, 2589 "Given Properties selector '%s' is invalid.", 2590 argv[2]); 2591 lprintf(LOG_ERR, 2592 "Valid Properties selector is: <0..4>"); 2593 return (-1); 2594 } 2595 verbose++; 2596 rc = HpmfwupgGetComponentProperties(intf, &cmdCtx); 2597 } else if ((argc == 1) && (strcmp(argv[0], "abort") == 0)) { 2598 struct HpmfwupgAbortUpgradeCtx cmdCtx; 2599 verbose++; 2600 rc = HpmfwupgAbortUpgrade(intf, &cmdCtx); 2601 } else if ((argc == 1) && (strcmp(argv[0], "upgstatus") == 0)) { 2602 struct HpmfwupgGetUpgradeStatusCtx cmdCtx; 2603 verbose++; 2604 rc = HpmfwupgGetUpgradeStatus(intf, &cmdCtx, NULL, 0); 2605 } else if ((argc == 1) && (strcmp(argv[0], "rollback") == 0)) { 2606 struct HpmfwupgManualFirmwareRollbackCtx cmdCtx; 2607 verbose++; 2608 rc = HpmfwupgManualFirmwareRollback(intf, &cmdCtx); 2609 } else if ((argc == 1) && (strcmp(argv[0], "rollbackstatus") == 0)) { 2610 struct HpmfwupgQueryRollbackStatusCtx cmdCtx; 2611 verbose++; 2612 rc = HpmfwupgQueryRollbackStatus(intf, &cmdCtx, NULL); 2613 } else if ((argc == 1) && (strcmp(argv[0], "selftestresult") == 0)) { 2614 struct HpmfwupgQuerySelftestResultCtx cmdCtx; 2615 verbose++; 2616 rc = HpmfwupgQuerySelftestResult(intf, &cmdCtx, NULL); 2617 } else { 2618 lprintf(LOG_ERR, "Invalid HPM command: %s", argv[0]); 2619 HpmfwupgPrintUsage(); 2620 rc = HPMFWUPG_ERROR; 2621 } 2622 return rc; 2623 } 2624 2625