summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--init.d/iprupdate25
-rw-r--r--iprconfig.c152
-rw-r--r--iprdbg.c91
-rw-r--r--iprdump.c5
-rwxr-xr-xiprinit.c6
-rw-r--r--iprlib.c56
-rw-r--r--iprlib.h7
-rw-r--r--iprupdate.c57
-rw-r--r--spec/iprutils.spec2
-rw-r--r--version.mk4
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;
diff --git a/iprdbg.c b/iprdbg.c
index 3f8f185..8ea4472 100644
--- a/iprdbg.c
+++ b/iprdbg.c
@@ -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[])
diff --git a/iprdump.c b/iprdump.c
index 0a884bc..368f665 100644
--- a/iprdump.c
+++ b/iprdump.c
@@ -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);
diff --git a/iprinit.c b/iprinit.c
index 3117206..cb4a12f 100755
--- a/iprinit.c
+++ b/iprinit.c
@@ -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);
}
diff --git a/iprlib.c b/iprlib.c
index 44f9eb5..3d85baf 100644
--- a/iprlib.c
+++ b/iprlib.c
@@ -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();
+}
diff --git a/iprlib.h b/iprlib.h
index aeb3681..92ffaca 100644
--- a/iprlib.h
+++ b/iprlib.h
@@ -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
diff --git a/version.mk b/version.mk
index cbc7e27..779f64c 100644
--- a/version.mk
+++ b/version.mk
@@ -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)