diff options
-rw-r--r-- | init.d/iprupdate | 25 | ||||
-rw-r--r-- | iprconfig.c | 152 | ||||
-rw-r--r-- | iprdbg.c | 91 | ||||
-rw-r--r-- | iprdump.c | 5 | ||||
-rwxr-xr-x | iprinit.c | 6 | ||||
-rw-r--r-- | iprlib.c | 56 | ||||
-rw-r--r-- | iprlib.h | 7 | ||||
-rw-r--r-- | iprupdate.c | 57 | ||||
-rw-r--r-- | spec/iprutils.spec | 2 | ||||
-rw-r--r-- | version.mk | 4 |
10 files changed, 238 insertions, 167 deletions
diff --git a/init.d/iprupdate b/init.d/iprupdate index dd1c2fe..17b9a6d 100644 --- a/init.d/iprupdate +++ b/init.d/iprupdate @@ -41,19 +41,36 @@ start() { } stop() { - exit 3 + echo -n "Shutting down ipr update daemon" + log_success_msg " " + return 0 } restart() { - exit 3 + $0 stop + $0 start + return $RETVAL } reload() { - exit 3 + $0 stop + $0 start + return $RETVAL } status() { - exit 3 + echo -n "Checking ipr microcode levels" + $IPRUPDATE --check_only + + RETVAL=$? + if [ $RETVAL -eq 0 ]; then + log_success_msg " " + else + echo " " + echo -n "ipr microcode updates required" + log_success_msg " " + fi + return $RETVAL } case "$1" in diff --git a/iprconfig.c b/iprconfig.c index 8ad25f9..f1633d3 100644 --- a/iprconfig.c +++ b/iprconfig.c @@ -1513,9 +1513,8 @@ int device_details(i_container *i_con) char *buffer; char *body = NULL; struct ipr_dev *device; - int rc; + int rc, i; struct scsi_dev_data *scsi_dev_data; - int i; u8 product_id[IPR_PROD_ID_LEN+1]; u8 vendor_id[IPR_VENDOR_ID_LEN+1]; u8 plant_code[IPR_VPD_PLANT_CODE_LEN+1]; @@ -1529,9 +1528,7 @@ int device_details(i_container *i_con) long double device_capacity; unsigned long long max_user_lba_int; double lba_divisor; - int scsi_channel; - int scsi_id; - int scsi_lun; + int scsi_channel, scsi_id, scsi_lun; struct ipr_ioa_vpd ioa_vpd; struct ipr_cfc_vpd cfc_vpd; struct ipr_dram_vpd dram_vpd; @@ -1554,8 +1551,9 @@ int device_details(i_container *i_con) return rc; scsi_dev_data = device->scsi_dev_data; - array_record = - (struct ipr_array_record *)device->qac_entry; + common_record = device->qac_entry; + array_record = (struct ipr_array_record *)common_record; + device_record = (struct ipr_dev_record *)common_record; rc = 0; memset(&ioa_vpd, 0, sizeof(ioa_vpd)); @@ -1568,9 +1566,7 @@ int device_details(i_container *i_con) scsi_id = scsi_dev_data->id; scsi_lun = scsi_dev_data->lun; } else if (device->qac_entry) { - common_record = device->qac_entry; if (common_record->record_id == IPR_RECORD_ID_DEVICE_RECORD) { - device_record = (struct ipr_dev_record *)common_record; scsi_channel = device_record->last_resource_addr.bus; scsi_id = device_record->last_resource_addr.target; scsi_lun = device_record->last_resource_addr.lun; @@ -5349,6 +5345,59 @@ int confirm_init_device(i_container *i_con) return rc; } +static int disable_qerr(struct ipr_dev *dev) +{ + u8 ioctl_buffer[IOCTL_BUFFER_SIZE]; + u8 ioctl_buffer2[IOCTL_BUFFER_SIZE]; + struct ipr_control_mode_page *control_mode_page; + struct ipr_control_mode_page *control_mode_page_changeable; + struct ipr_mode_parm_hdr *mode_parm_hdr; + int status; + u8 length; + + /* Issue mode sense to get the control mode page */ + status = ipr_mode_sense(dev, 0x0a, &ioctl_buffer); + + if (status) + return -EIO; + + /* Issue mode sense to get the control mode page */ + status = ipr_mode_sense(dev, 0x4a, &ioctl_buffer2); + + if (status) + return -EIO; + + mode_parm_hdr = (struct ipr_mode_parm_hdr *)ioctl_buffer2; + + control_mode_page_changeable = (struct ipr_control_mode_page *) + (((u8 *)(mode_parm_hdr+1)) + mode_parm_hdr->block_desc_len); + + mode_parm_hdr = (struct ipr_mode_parm_hdr *)ioctl_buffer; + + control_mode_page = (struct ipr_control_mode_page *) + (((u8 *)(mode_parm_hdr+1)) + mode_parm_hdr->block_desc_len); + + /* Turn off QERR since some drives do not like QERR + and IMMED bit at the same time. */ + IPR_SET_MODE(control_mode_page_changeable->qerr, + control_mode_page->qerr, 0); + + /* Issue mode select to set page x0A */ + length = mode_parm_hdr->length + 1; + + mode_parm_hdr->length = 0; + control_mode_page->hdr.parms_saveable = 0; + mode_parm_hdr->medium_type = 0; + mode_parm_hdr->device_spec_parms = 0; + + status = ipr_mode_select(dev, &ioctl_buffer, length); + + if (status) + return -EIO; + + return 0; +} + int send_dev_inits(i_container *i_con) { u8 num_devs = 0; @@ -5545,63 +5594,7 @@ int send_dev_inits(i_container *i_con) continue; } - /* Issue mode sense to get the control mode page */ - status = ipr_mode_sense(cur_dev_init->ipr_dev, - 0x0a, &ioctl_buffer); - - if (status) - { - cur_dev_init->do_init = 0; - num_devs--; - failure++; - continue; - } - - /* Issue mode sense to get the control mode page */ - status = ipr_mode_sense(cur_dev_init->ipr_dev, - 0x4a, &ioctl_buffer2); - - if (status) - { - cur_dev_init->do_init = 0; - num_devs--; - failure++; - continue; - } - - mode_parm_hdr = (struct ipr_mode_parm_hdr *)ioctl_buffer2; - - control_mode_page_changeable = (struct ipr_control_mode_page *) - (((u8 *)(mode_parm_hdr+1)) + mode_parm_hdr->block_desc_len); - - mode_parm_hdr = (struct ipr_mode_parm_hdr *)ioctl_buffer; - - control_mode_page = (struct ipr_control_mode_page *) - (((u8 *)(mode_parm_hdr+1)) + mode_parm_hdr->block_desc_len); - - /* Turn off QERR since some drives do not like QERR - and IMMED bit at the same time. */ - IPR_SET_MODE(control_mode_page_changeable->qerr, - control_mode_page->qerr, 0); - - /* Issue mode select to set page x0A */ - length = mode_parm_hdr->length + 1; - - mode_parm_hdr->length = 0; - control_mode_page->hdr.parms_saveable = 0; - mode_parm_hdr->medium_type = 0; - mode_parm_hdr->device_spec_parms = 0; - - status = ipr_mode_select(cur_dev_init->ipr_dev, - &ioctl_buffer, length); - - if (status) - { - cur_dev_init->do_init = 0; - num_devs--; - failure++; - continue; - } + disable_qerr(cur_dev_init->ipr_dev); /* Issue mode select to setup block size */ mode_parm_hdr = (struct ipr_mode_parm_hdr *)ioctl_buffer; @@ -5679,18 +5672,14 @@ int dev_init_complete(u8 num_devs) percent_cmplt = 100; done_bad = 0; - for (cur_dev_init = dev_init_head; cur_dev_init != NULL; - cur_dev_init = cur_dev_init->next) { - - if ((cur_dev_init->do_init) && - (cur_dev_init->dev_type == IPR_AF_DASD_DEVICE)) { - + for (cur_dev_init = dev_init_head; cur_dev_init; cur_dev_init = cur_dev_init->next) { + if (cur_dev_init->do_init && + cur_dev_init->dev_type == IPR_AF_DASD_DEVICE) { rc = ipr_query_command_status(cur_dev_init->ipr_dev, &cmd_status); - if ((rc) || (cmd_status.num_records == 0)) { + if (rc || cmd_status.num_records == 0) continue; - } status_record = cmd_status.record; if (status_record->status == IPR_CMD_STATUS_FAILED) { @@ -5700,10 +5689,8 @@ int dev_init_complete(u8 num_devs) percent_cmplt = status_record->percent_complete; not_done = 1; } - } - else if ((cur_dev_init->do_init) && - (cur_dev_init->dev_type == IPR_JBOD_DASD_DEVICE)) - { + } else if (cur_dev_init->do_init && + cur_dev_init->dev_type == IPR_JBOD_DASD_DEVICE) { /* Send Test Unit Ready to find percent complete in sense data. */ rc = ipr_test_unit_ready(cur_dev_init->ipr_dev, &sense_data); @@ -5711,10 +5698,9 @@ int dev_init_complete(u8 num_devs) if (rc < 0) continue; - if ((rc == CHECK_CONDITION) && - ((sense_data.error_code & 0x7F) == 0x70) && - ((sense_data.sense_key & 0x0F) == 0x02)) { - + if (rc == CHECK_CONDITION && + (sense_data.error_code & 0x7F) == 0x70 && + (sense_data.sense_key & 0x0F) == 0x02) { cur_dev_init->cmplt = ((int)sense_data.sense_key_spec[1]*100)/0x100; if (cur_dev_init->cmplt < percent_cmplt) percent_cmplt = cur_dev_init->cmplt; @@ -5724,10 +5710,8 @@ int dev_init_complete(u8 num_devs) } if (!not_done) { - for (cur_dev_init = dev_init_head; cur_dev_init; cur_dev_init = cur_dev_init->next) { - if (!cur_dev_init->do_init) continue; @@ -10,7 +10,7 @@ */ /* - * $Header: /cvsroot/iprdd/iprutils/iprdbg.c,v 1.11 2004/03/24 20:02:33 bjking1 Exp $ + * $Header: /cvsroot/iprdd/iprutils/iprdbg.c,v 1.12 2004/04/06 21:10:25 bjking1 Exp $ */ #ifndef iprlib_h @@ -121,50 +121,51 @@ static int debug_ioctl(int fd, enum iprdbg_cmd cmd, int ioa_adx, int mask, static int format_flit(struct ipr_flit *flit) { - int num_entries = ntohl(flit->num_entries) - 1; - struct ipr_flit_entry *flit_entry; - - signed int len; - u8 filename[IPR_FLIT_FILENAME_LEN+1]; - u8 time[IPR_FLIT_TIMESTAMP_LEN+1]; - u8 buf1[IPR_FLIT_FILENAME_LEN+1]; - u8 buf2[IPR_FLIT_FILENAME_LEN+1]; - u8 lid_name[IPR_FLIT_FILENAME_LEN+1]; - u8 path[IPR_FLIT_FILENAME_LEN+1]; - int num_args, i; - - for (i = 0, flit_entry = flit->flit_entry; - (i < num_entries) && (*flit_entry->timestamp); - flit_entry++, i++) { - snprintf(time, IPR_FLIT_TIMESTAMP_LEN, flit_entry->timestamp); - time[IPR_FLIT_TIMESTAMP_LEN] = '\0'; - - snprintf(filename, IPR_FLIT_FILENAME_LEN, flit_entry->filename); - filename[IPR_FLIT_FILENAME_LEN] = '\0'; - - num_args = sscanf(filename, "%184s " "%184s " "%184s " - "%184s ", buf1, buf2, lid_name, path); - - if (num_args != 4) { - syslog(LOG_ERR, "Cannot parse flit\n"); - return 1; - } - - len = strlen(path); - - iprprint("LID Name: %s (%8X)\n", lid_name, ntohl(flit_entry->load_name)); - iprprint("Time Stamp: %s\n", time); - iprprint("LID Path: %s\n", lid_name); - iprprint("Text Segment: Address %08X, Length %8X\n", - ntohl(flit_entry->text_ptr), ntohl(flit_entry->text_len)); - iprprint("Data Segment: Address %08X, Length %8X\n", - ntohl(flit_entry->data_ptr), ntohl(flit_entry->data_len)); - iprprint("BSS Segment: Address %08X, Length %8X\n", - ntohl(flit_entry->bss_ptr), ntohl(flit_entry->bss_len)); - iprprint("\n"); - } - - return 0; + int num_entries = ntohl(flit->num_entries) - 1; + struct ipr_flit_entry *flit_entry; + + signed int len; + u8 filename[IPR_FLIT_FILENAME_LEN+1]; + u8 time[IPR_FLIT_TIMESTAMP_LEN+1]; + u8 buf1[IPR_FLIT_FILENAME_LEN+1]; + u8 buf2[IPR_FLIT_FILENAME_LEN+1]; + u8 lid_name[IPR_FLIT_FILENAME_LEN+1]; + u8 path[IPR_FLIT_FILENAME_LEN+1]; + int num_args, i; + + for (i = 0, flit_entry = flit->flit_entry; + (i < num_entries) && (*flit_entry->timestamp); + flit_entry++, i++) { + snprintf(time, IPR_FLIT_TIMESTAMP_LEN, flit_entry->timestamp); + time[IPR_FLIT_TIMESTAMP_LEN] = '\0'; + + snprintf(filename, IPR_FLIT_FILENAME_LEN, flit_entry->filename); + filename[IPR_FLIT_FILENAME_LEN] = '\0'; + + num_args = sscanf(filename, "%184s " "%184s " "%184s " + "%184s ", buf1, buf2, lid_name, path); + + if (num_args != 4) { + syslog(LOG_ERR, "Cannot parse flit\n"); + return 1; + } + + len = strlen(path); + + iprprint("LID Name: %s (%8X)\n", lid_name, ntohl(flit_entry->load_name)); + iprprint("LID Path: %s\n", path); + iprprint("Time Stamp: %s\n", time); + iprprint("LID Path: %s\n", lid_name); + iprprint("Text Segment: Address %08X, Length %8X\n", + ntohl(flit_entry->text_ptr), ntohl(flit_entry->text_len)); + iprprint("Data Segment: Address %08X, Length %8X\n", + ntohl(flit_entry->data_ptr), ntohl(flit_entry->data_len)); + iprprint("BSS Segment: Address %08X, Length %8X\n", + ntohl(flit_entry->bss_ptr), ntohl(flit_entry->bss_len)); + iprprint("\n"); + } + + return 0; } int main(int argc, char *argv[]) @@ -10,7 +10,7 @@ */ /* - * $Header: /cvsroot/iprdd/iprutils/iprdump.c,v 1.9 2004/03/24 20:02:34 bjking1 Exp $ + * $Header: /cvsroot/iprdd/iprutils/iprdump.c,v 1.10 2004/04/06 21:10:25 bjking1 Exp $ */ #ifndef iprlib_h @@ -277,8 +277,7 @@ int main(int argc, char *argv[]) } } - if (fork()) - return 0; + ipr_daemonize(); signal(SIGINT, handle_signal); signal(SIGQUIT, handle_signal); @@ -10,7 +10,7 @@ */ /* - * $Header: /cvsroot/iprdd/iprutils/iprinit.c,v 1.14 2004/03/29 23:23:29 bjking1 Exp $ + * $Header: /cvsroot/iprdd/iprutils/iprinit.c,v 1.15 2004/04/06 21:10:25 bjking1 Exp $ */ #include <unistd.h> @@ -55,9 +55,7 @@ int main(int argc, char *argv[]) if (daemonize) { if (!daemonized) { daemonized = 1; - if (fork()) - return 0; - + ipr_daemonize(); } sleep(60); } @@ -10,7 +10,7 @@ */ /* - * $Header: /cvsroot/iprdd/iprutils/iprlib.c,v 1.47 2004/03/29 23:23:29 bjking1 Exp $ + * $Header: /cvsroot/iprdd/iprutils/iprlib.c,v 1.48 2004/04/06 21:10:25 bjking1 Exp $ */ #ifndef iprlib_h @@ -2437,7 +2437,7 @@ void ipr_modify_bus_attr(struct ipr_ioa *ioa, struct ipr_scsi_buses *sbus) } } -static struct unsupported_af_dasd * +struct unsupported_af_dasd * get_unsupp_af(struct ipr_std_inq_data *inq, struct ipr_dasd_inquiry_page3 *page3) { @@ -2476,8 +2476,8 @@ get_unsupp_af(struct ipr_std_inq_data *inq, return NULL; } -static bool disk_needs_msl(struct unsupported_af_dasd *unsupp_af, - struct ipr_std_inq_data *inq) +bool disk_needs_msl(struct unsupported_af_dasd *unsupp_af, + struct ipr_std_inq_data *inq) { u32 ros_rcv_ram_rsvd, min_ucode_level; int j; @@ -2714,8 +2714,8 @@ int get_ioa_firmware_image_list(struct ipr_ioa *ioa, rc = scandir(HOTPLUG_BASE_DIR, &dirent, NULL, alphasort); for (i = 0; i < rc && rc > 0; i++) { - /* xxx fix this to look for IBM-eServer-xxx */ - if (strstr(dirent[i]->d_name, parms->fw_name)) { + if (strstr(dirent[i]->d_name, "IBM-eServer-") && + strstr(dirent[i]->d_name, parms->fw_name)) { ret = realloc(ret, sizeof(*ret) * (j + 1)); sprintf(ret[j].file, HOTPLUG_BASE_DIR"/%s", dirent[i]->d_name); @@ -2852,8 +2852,8 @@ int get_dasd_firmware_image_list(struct ipr_dev *dev, rc--; for (i = rc ; i >= 0; i--) { - /* xxx fix this to look for IBM-eServer-xxx */ - if (strstr(dirent[i]->d_name, prefix)) { + if (strstr(dirent[i]->d_name, "IBM-eServer-") && + strstr(dirent[i]->d_name, prefix)) { ret = realloc(ret, sizeof(*ret) * (j + 1)); sprintf(ret[j].file, HOTPLUG_BASE_DIR"/%s", dirent[i]->d_name); @@ -3408,18 +3408,16 @@ struct ipr_dev *get_dev_from_addr(struct ipr_res_addr *res_addr) struct scsi_dev_data *scsi_dev_data; for(cur_ioa = ipr_ioa_head; cur_ioa != NULL; cur_ioa = cur_ioa->next) { - for (j = 0; j < cur_ioa->num_devices; j++) { - scsi_dev_data = cur_ioa->dev[j].scsi_dev_data; if (scsi_dev_data == NULL) continue; - if ((scsi_dev_data->host == res_addr->host) && - (scsi_dev_data->channel == res_addr->bus) && - (scsi_dev_data->id == res_addr->target) && - (scsi_dev_data->lun == res_addr->lun)) + if (scsi_dev_data->host == res_addr->host && + scsi_dev_data->channel == res_addr->bus && + scsi_dev_data->id == res_addr->target && + scsi_dev_data->lun == res_addr->lun) return &cur_ioa->dev[j]; } } @@ -3435,21 +3433,19 @@ struct ipr_dev *get_dev_from_handle(u32 res_handle) struct ipr_array_record *array_record; for(cur_ioa = ipr_ioa_head; cur_ioa != NULL; cur_ioa = cur_ioa->next) { - for (j = 0; j < cur_ioa->num_devices; j++) { - device_record = (struct ipr_dev_record *)cur_ioa->dev[j].qac_entry; array_record = (struct ipr_array_record *)cur_ioa->dev[j].qac_entry; if (device_record == NULL) continue; - if ((device_record->common.record_id == IPR_RECORD_ID_DEVICE_RECORD) && - (device_record->resource_handle == res_handle)) + if (device_record->common.record_id == IPR_RECORD_ID_DEVICE_RECORD && + device_record->resource_handle == res_handle) return &cur_ioa->dev[j]; - if ((array_record->common.record_id == IPR_RECORD_ID_ARRAY_RECORD) && - (array_record->resource_handle == res_handle)) + if (array_record->common.record_id == IPR_RECORD_ID_ARRAY_RECORD && + array_record->resource_handle == res_handle) return &cur_ioa->dev[j]; } @@ -3457,3 +3453,23 @@ struct ipr_dev *get_dev_from_handle(u32 res_handle) return NULL; } + +void ipr_daemonize() +{ + int rc = fork(); + + if (rc < 0) { + syslog(LOG_ERR, "Failed to daemonize\n"); + exit(1); + } else if (rc) { + exit(0); + } + + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + open("/dev/null",O_RDONLY); + open("/dev/null",O_WRONLY); + open("/dev/null",O_WRONLY); + setsid(); +} @@ -12,7 +12,7 @@ */ /* - * $Header: /cvsroot/iprdd/iprutils/iprlib.h,v 1.40 2004/03/29 23:23:30 bjking1 Exp $ + * $Header: /cvsroot/iprdd/iprutils/iprlib.h,v 1.41 2004/04/06 21:10:25 bjking1 Exp $ */ #include <stdarg.h> @@ -1200,6 +1200,11 @@ void ipr_init_ioa(struct ipr_ioa *); int device_supported(struct ipr_dev *); struct ipr_dev *get_dev_from_addr(struct ipr_res_addr *res_addr); struct ipr_dev *get_dev_from_handle(u32 res_handle); +void ipr_daemonize(); +struct unsupported_af_dasd *get_unsupp_af(struct ipr_std_inq_data *, + struct ipr_dasd_inquiry_page3 *); +bool disk_needs_msl(struct unsupported_af_dasd *, + struct ipr_std_inq_data *); /*--------------------------------------------------------------------------- * Purpose: Identify Advanced Function DASD present diff --git a/iprupdate.c b/iprupdate.c index 9e5256c..bcb5b52 100644 --- a/iprupdate.c +++ b/iprupdate.c @@ -10,7 +10,7 @@ */ /* - * $Header: /cvsroot/iprdd/iprutils/iprupdate.c,v 1.11 2004/03/24 20:02:34 bjking1 Exp $ + * $Header: /cvsroot/iprdd/iprutils/iprupdate.c,v 1.12 2004/04/06 21:10:25 bjking1 Exp $ */ #include <unistd.h> @@ -24,6 +24,48 @@ #include <sys/mman.h> +static int ioa_needs_update(struct ipr_ioa *ioa) +{ + struct sysfs_class_device *class_device; + struct sysfs_attribute *attr; + u32 fw_version; + + class_device = sysfs_open_class_device("scsi_host", ioa->host_name); + attr = sysfs_get_classdev_attr(class_device, "fw_version"); + sscanf(attr->value, "%8X", &fw_version); + sysfs_close_class_device(class_device); + + if (fw_version >= ioa->msl) + return 0; + + ioa_info(ioa, "Adapter needs microcode update\n"); + return 1; +} + +static int dev_needs_update(struct ipr_dev *dev) +{ + struct ipr_std_inq_data std_inq_data; + struct ipr_dasd_inquiry_page3 page3_inq; + struct unsupported_af_dasd *unsupp_af; + + memset(&std_inq_data, 0, sizeof(std_inq_data)); + if (ipr_inquiry(dev, IPR_STD_INQUIRY, &std_inq_data, sizeof(std_inq_data))) + return 0; + + if (ipr_inquiry(dev, 3, &page3_inq, sizeof(page3_inq))) + return 0; + + unsupp_af = get_unsupp_af(&std_inq_data, &page3_inq); + if (!unsupp_af) + return 0; + + if (!disk_needs_msl(unsupp_af, &std_inq_data)) + return 0; + + scsi_info(dev, "Device needs microcode update\n"); + return 1; +} + static void update_ioa_fw(struct ipr_ioa *ioa, int force) { int rc; @@ -60,6 +102,7 @@ int main(int argc, char *argv[]) int rc = 0; int i; int force_devs, force_ioas; + int check_levels = 0; struct ipr_ioa *ioa; struct ipr_dev *dev; @@ -77,6 +120,8 @@ int main(int argc, char *argv[]) force_devs = 1; } else if (strcmp(argv[1], "--force-ioas") == 0) { force_ioas = 1; + } else if (strcmp(argv[1], "--check_only") == 0) { + check_levels = 1; } else { printf("Usage: iprdate [options]\n"); printf(" Options: --version Print iprupdate version\n"); @@ -89,7 +134,10 @@ int main(int argc, char *argv[]) check_current_config(false); for (ioa = ipr_ioa_head; ioa; ioa = ioa->next) { - update_ioa_fw(ioa, force_ioas); + if (check_levels) + rc |= ioa_needs_update(ioa); + else + update_ioa_fw(ioa, force_ioas); for (i = 0; i < ioa->num_devices; i++) { dev = &ioa->dev[i]; @@ -101,7 +149,10 @@ int main(int argc, char *argv[]) dev->scsi_dev_data->type != IPR_TYPE_AF_DISK)) continue; - update_disk_fw(dev, force_devs); + if (check_levels) + rc |= dev_needs_update(dev); + else + update_disk_fw(dev, force_devs); } } diff --git a/spec/iprutils.spec b/spec/iprutils.spec index 7a5af1e..fbd41b4 100644 --- a/spec/iprutils.spec +++ b/spec/iprutils.spec @@ -1,6 +1,6 @@ Summary: Utilities for the IBM Power Linux RAID adapters Name: iprutils -Version: 2.0.4 +Version: 2.0.5 Release: 1 License: CPL Group: System Environment/Base @@ -6,9 +6,9 @@ IPR_MAJOR_RELEASE=2 IPR_MINOR_RELEASE=0 -IPR_FIX_LEVEL=4 +IPR_FIX_LEVEL=5 IPR_RELEASE=1 -IPR_FIX_DATE=(March 29, 2004) +IPR_FIX_DATE=(April 6, 2004) IPR_VERSION_STR=$(IPR_MAJOR_RELEASE).$(IPR_MINOR_RELEASE).$(IPR_FIX_LEVEL) $(IPR_FIX_DATE) |