On 06/29/2015 04:39 PM, Gabriel Krisman Bertazi wrote: > show-ucode-levels prints all IPR adapters and devices, along with their > current firmware levels as well as the latest available version found on > disk which could be updated to. > > Signed-off-by: Gabriel Krisman Bertazi <kris...@linux.vnet.ibm.com> > --- > iprconfig.8 | 5 ++++ > iprconfig.c | 81 > +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > iprlib.c | 34 ++++++++++++++++++++++++++ > iprlib.h | 1 + > 4 files changed, 121 insertions(+) > > diff --git a/iprconfig.8 b/iprconfig.8 > index 2282fac..3f07532 100644 > --- a/iprconfig.8 > +++ b/iprconfig.8 > @@ -337,6 +337,11 @@ Show the microcode level that is currently loaded on the > specified device. > Note: The device specified may be the sg device associated with an IOA, > in which case the IOA's microcode level will be shown. > .TP > +.B show-ucode-levels > +.br > +Show the microcode level that is currently loaded for every device and > +adapter in the system. > +.TP > .B query-format-timeout [device] > .br > Show the current format timeout to be used when formatting the specified > disk. > diff --git a/iprconfig.c b/iprconfig.c > index d664a23..322e566 100644 > --- a/iprconfig.c > +++ b/iprconfig.c > @@ -15078,6 +15078,86 @@ static int update_ucode_cmd(char **args, int > num_args) > return update_dev_ucode(dev, args[1]); > } > > +static int _show_ucode_levels(char *buffer, size_t size) > +{ > + struct ipr_ioa *ioa; > + struct ipr_dev *dev; > + > + int cur_ulevel; > + int newest_ulevel; > + char *name; > + char updatable; > + char loc[128]; > + int offset; > + > + offset = snprintf(buffer, size, "\ > +Name PCI/SCSI Location Vendor Product ID Current > Available\n\ > +----- ---------------------- -------- ---------------- --------- > ----------\n");
As we already discussed privately, let's see if we can use print_device for this rather than doing something different here. Then this code would look more like show_config. > + > + for_each_ioa(ioa) { > + if (!ioa->ioa.scsi_dev_data) > + return; If you use print_device, than you can use functions like print_ses_devices to print all the SES devices. Suggest we try to print each IOA, followed by the attached devices under it, like we do on the display hardware status screen today. > + > + for_each_dev(ioa, dev) { > + if (ipr_is_volume_set(dev)) > + continue; > + > + if (strlen(dev->dev_name)) > + name = dev->dev_name; > + else > + name = dev->gen_name; > + > + if (dev->scsi_dev_data->type == IPR_TYPE_ADAPTER) > + snprintf(loc, 128, "%s/%d:", This code might go away when you redo this, but I'd prefer in code like this to replace the 128 with a sizeof(loc) > + dev->ioa->pci_address, > + dev->ioa->host_num); > + else > + snprintf(loc, 128, "%s/%d:%d:%d:%d", > + dev->ioa->pci_address, > + dev->ioa->host_num, > + dev->scsi_dev_data->channel, > + dev->scsi_dev_data->id, > + dev->scsi_dev_data->lun); > + > + cur_ulevel = get_fw_version(dev); > + if (cur_ulevel == 0) > + continue; > + > + newest_ulevel = get_latest_fw_image_version(dev); > + > + if (newest_ulevel < 0) { > + /* Could not find any ucode image. */ > + newest_ulevel = cur_ulevel; > + } > + > + updatable = (newest_ulevel > cur_ulevel) ? '*' : ' '; > + > + offset += snprintf(buffer+offset, size-offset, > + "%-5s %-22s %-8.8s %-16.16s %-10X > %X%c\n", > + basename(name), loc, > + dev->scsi_dev_data->vendor_id, > + dev->scsi_dev_data->product_id, > + cur_ulevel, newest_ulevel, updatable); > + } > + } > +} > + > +/** > + * show_ucode_levels - List microcode level of every device and adapter > + * @args: argument vector > + * @num_args: number of arguments > + * > + * Returns: > + * 0 if success / non-zero on failure > + **/ > +static int show_ucode_levels(char **args, int num_args) > +{ > + char buffer[BUFSIZ]; > + _show_ucode_levels(buffer, BUFSIZ); > + printf("%s", buffer); > + return 0; > +} > + > /** > * disrupt_device_cmd - > * @args: argument vector > @@ -18457,6 +18537,7 @@ static const struct { > { "raid-rebuild", 1, 0, 1, raid_rebuild_cmd, > "sg6" }, > { "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, "" > }, > { "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 9b0b4a4..94bcdca 100644 > --- a/iprlib.c > +++ b/iprlib.c > @@ -8625,6 +8625,40 @@ int get_ses_firmware_image_list(struct ipr_dev *dev, > return len; > } > > + > +/** > + * get_firmware_image_list - Common interface to find version of the > + * latest microcode image found in the filesystem. > + * > + * @dev: Device > + * > + * Returns: > + * 0 if success / non-zero on failure > + **/ > +int get_latest_fw_image_version(struct ipr_dev *dev) > +{ > + struct ipr_fw_images *fw = NULL; > + u32 version = 0; > + > + if (!dev) > + return -ENODEV; > + > + 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 -EINVAL; > + > + version = fw->version; > + free(fw); > + > + return version; > +} > + > struct ipr_ioa_desc { > u16 type; > const char *desc; > diff --git a/iprlib.h b/iprlib.h > index e66ea47..9c09cba 100644 > --- a/iprlib.h > +++ b/iprlib.h > @@ -2701,6 +2701,7 @@ int ipr_query_dasd_timeouts(struct ipr_dev *, struct > ipr_query_dasd_timeouts *); > 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 *); > 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 *); > -- Brian King Power Linux I/O IBM Linux Technology Center ------------------------------------------------------------------------------ Don't Limit Your Business. Reach for the Cloud. GigeNET's Cloud Solutions provide you with the tools and support that you need to offload your IT needs and focus on growing your business. Configured For All Businesses. Start Your Cloud Today. https://www.gigenetcloud.com/ _______________________________________________ Iprdd-devel mailing list Iprdd-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/iprdd-devel