Add a command to update all ucodes. This will search specific paths in the filesystem for new firmware images and update any adapter or disk that is not in the latest firmware version.
Signed-off-by: Gabriel Krisman Bertazi <kris...@linux.vnet.ibm.com> --- iprconfig.8 | 5 +++++ iprconfig.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ iprlib.c | 28 ++++++++++++++++++++++++++++ iprlib.h | 1 + 4 files changed, 81 insertions(+) diff --git a/iprconfig.8 b/iprconfig.8 index 3f07532..be3ef1f 100644 --- a/iprconfig.8 +++ b/iprconfig.8 @@ -577,6 +577,11 @@ the specified microcode file. Limited checking of the microcode image is done. Make sure the specified microcode file is the correct file for the specified device. .TP +.B update-all-ucodes +.br +Update the microcode of every device with the latest version found in +the system. +.TP .B set-format-timeout [disk] [timeout in hours] .br Set the format timeout to be used when formatting the specified disk. diff --git a/iprconfig.c b/iprconfig.c index 90b64fd..7355f83 100644 --- a/iprconfig.c +++ b/iprconfig.c @@ -15206,6 +15206,52 @@ static int update_ucode_cmd(char **args, int num_args) } /** + * update_all_ucodes - update-all-ucodes Command line interface. + * @args: argument vector + * @num_args: number of arguments + * + * Returns: + * 0 if success / non-zero on failure + **/ +static int update_all_ucodes(char **args, int num_args) +{ + struct ipr_ioa *ioa; + struct ipr_dev *dev; + int failed_count = 0; + struct ipr_fw_images *lfw; + int rc; + + for_each_ioa(ioa) { + if (!ioa->ioa.scsi_dev_data) + return; + for_each_dev(ioa, dev) { + if (ipr_is_volume_set(dev)) + continue; + + lfw = get_latest_fw_image(dev); + if (!lfw || lfw->version <= get_fw_version(dev)) + continue; + + if (&dev->ioa->ioa == dev) + rc = update_ioa_ucode(dev->ioa, lfw->file); + else + rc = update_dev_ucode(dev, lfw->file); + + free(lfw); + + if (rc) + failed_count++; + } + } + + if (failed_count) + printf("Failed to update %d devices. Run dmesg for more information.\n", + failed_count); + + return 0; +} + +/** * show_ucode_levels - List microcode level of every device and adapter * @args: argument vector * @num_args: number of arguments @@ -18608,6 +18654,7 @@ static const struct { { "disrupt-device", 1, 0, 1, disrupt_device_cmd, "sg6" }, { "update-ucode", 2, 0, 2, update_ucode_cmd, "sg5 /root/ucode.bin" }, { "show-ucode-levels", 0, 0, 0, show_ucode_levels, "" }, + { "update-all-ucodes", 0, 0, 0, update_all_ucodes, "" }, { "set-format-timeout", 2, 0, 2, set_format_timeout, "sg6 4" }, { "set-qdepth", 2, 0, 2, set_qdepth, "sda 16" }, { "set-tcq-enable", 2, 0, 2, set_tcq_enable, "sda 0" }, diff --git a/iprlib.c b/iprlib.c index 94bcdca..bbdf78f 100644 --- a/iprlib.c +++ b/iprlib.c @@ -8625,6 +8625,34 @@ int get_ses_firmware_image_list(struct ipr_dev *dev, return len; } +/** + * get_fw_image - Common interface to find version of the latest + * microcode image found in the filesystem. + * + * @dev: Device + * + * Returns: + * 0 if success / non-zero on failure + **/ +struct ipr_fw_images *get_latest_fw_image(struct ipr_dev *dev) +{ + struct ipr_fw_images *fw = NULL; + + if (!dev) + return NULL; + + if (dev->scsi_dev_data->type == IPR_TYPE_ADAPTER) + get_ioa_firmware_image_list(dev->ioa, &fw); + else if (ipr_is_ses(dev)) + get_ses_firmware_image_list(dev, &fw); + else if (ipr_is_gscsi(dev) || ipr_is_af_dasd_device(dev)) + get_dasd_firmware_image_list(dev, &fw); + + if (!fw) + return NULL; + + return fw; +} /** * get_firmware_image_list - Common interface to find version of the diff --git a/iprlib.h b/iprlib.h index 9c09cba..3db1612 100644 --- a/iprlib.h +++ b/iprlib.h @@ -2702,6 +2702,7 @@ int get_ioa_firmware_image_list(struct ipr_ioa *, struct ipr_fw_images **); int get_dasd_firmware_image_list(struct ipr_dev *, struct ipr_fw_images **); int get_ses_firmware_image_list(struct ipr_dev *, struct ipr_fw_images **); int get_latest_fw_image_version(struct ipr_dev *); +struct ipr_fw_images *get_latest_fw_image(struct ipr_dev *); int ipr_update_ioa_fw(struct ipr_ioa *, struct ipr_fw_images *, int); int ipr_update_disk_fw(struct ipr_dev *, struct ipr_fw_images *, int); int ipr_init_dev(struct ipr_dev *); -- 2.1.0 ------------------------------------------------------------------------------ _______________________________________________ Iprdd-devel mailing list Iprdd-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iprdd-devel