Code cleanup, various updates

This commit is contained in:
brking 2005-09-26 20:19:36 +00:00
commit d25c37a87d
13 changed files with 966 additions and 201 deletions

View file

@ -11,7 +11,7 @@ include version.mk
CFLAGS = -g -Wall $(IPR_DEFINES)
UTILS_VER = $(IPR_MAJOR_RELEASE).$(IPR_MINOR_RELEASE).$(IPR_FIX_LEVEL)
TAR = cd .. && tar -zcpf iprutils-$(UTILS_VER)-src.tgz --exclude CVS --exclude applied-patches --exclude series --exclude txt --exclude pc --exclude patches --exclude *~* iprutils
TAR = cd .. && tar -zcpf iprutils-$(UTILS_VER)-src.tgz --exclude CVS --exclude applied-patches --exclude series --exclude txt --exclude pc --exclude patches --exclude debug --exclude *~* iprutils
all: iprconfig iprupdate iprdump iprinit iprdbg docs
@ -28,7 +28,7 @@ iprinit:iprinit.c iprlib.o
$(CC) $(CFLAGS) $(INCLUDEDIR) -o iprinit iprlib.o iprinit.c -lsysfs
iprdbg:iprdbg.c iprlib.o
$(CC) $(CFLAGS) $(INCLUDEDIR) -o iprdbg iprlib.o iprdbg.c -lsysfs
$(CC) $(CFLAGS) $(INCLUDEDIR) -o iprdbg iprlib.o iprdbg.c -lsysfs -lncurses
iprucode:iprucode.c iprlib.o
$(CC) $(CFLAGS) $(INCLUDEDIR) -o iprucode iprlib.o iprucode.c -lsysfs

102
debug/iprcache.c Executable file
View file

@ -0,0 +1,102 @@
/**
* IBM IPR adapter drive write caching utility
*
* (C) Copyright 2005
* International Business Machines Corporation and others.
* All Rights Reserved. This program and the accompanying
* materials are made available under the terms of the
* Common Public License v1.0 which accompanies this distribution.
*
*/
/*
* $Header: /cvsroot/iprdd/iprutils/debug/iprcache.c,v 1.1 2005/09/26 20:19:36 brking Exp $
*/
#include <unistd.h>
#include <sys/ioctl.h>
#include <scsi/sg.h>
#include <scsi/scsi.h>
#include <sys/stat.h>
#ifndef iprlib_h
#include "iprlib.h"
#endif
#include <sys/mman.h>
char *tool_name = "iprcache";
struct ipr_caching_mode_page {
/* Mode page 0x08 */
struct ipr_mode_page_hdr hdr;
#if defined (__BIG_ENDIAN_BITFIELD)
u8 ic:1;
u8 abpf:1;
u8 cap:1;
u8 disc:1;
u8 size:1;
u8 wce:1;
u8 mf:1;
u8 rcd:1;
#elif defined (__LITTLE_ENDIAN_BITFIELD)
u8 rcd:1;
u8 mf:1;
u8 wce:1;
u8 size:1;
u8 disc:1;
u8 cap:1;
u8 abpf:1;
u8 ic:1;
#endif
u8 data[17];
};
static int set_caching_page(struct ipr_dev *dev)
{
struct ipr_mode_pages mode_pages;
struct ipr_caching_mode_page *page;
int rc;
int len;
rc = ipr_mode_sense(dev, 8, &mode_pages);
if (rc)
return rc;
page = (struct ipr_caching_mode_page *) (((u8 *)&mode_pages) +
mode_pages.hdr.block_desc_len +
sizeof(mode_pages.hdr));
page->wce = 0;
len = mode_pages.hdr.length + 1;
mode_pages.hdr.length = 0;
mode_pages.hdr.medium_type = 0;
mode_pages.hdr.device_spec_parms = 0;
page->hdr.parms_saveable = 0;
rc = ipr_mode_select(dev, &mode_pages, len);
return rc;
}
int main(int argc, char *argv[])
{
struct ipr_dev *dev;
int rc;
openlog("iprcache", LOG_PERROR | LOG_PID | LOG_CONS, LOG_USER);
tool_init(1);
check_current_config(false);
dev = find_gen_dev(argv[1]);
if (!dev)
dev = find_blk_dev(argv[1]);
if (!dev) {
fprintf(stderr, "Cannot find %s\n", argv[1]);
return -EINVAL;
}
return set_caching_page(dev);
}

154
debug/iprperf.c Executable file
View file

@ -0,0 +1,154 @@
/**
* IBM IPR adapter performance analysis utility
*
* (C) Copyright 2005
* International Business Machines Corporation and others.
* All Rights Reserved. This program and the accompanying
* materials are made available under the terms of the
* Common Public License v1.0 which accompanies this distribution.
*
*/
/*
* $Header: /cvsroot/iprdd/iprutils/debug/iprperf.c,v 1.1 2005/09/26 20:19:36 brking Exp $
*/
#include <unistd.h>
#include <sys/ioctl.h>
#include <scsi/sg.h>
#include <scsi/scsi.h>
#include <sys/stat.h>
#ifndef iprlib_h
#include "iprlib.h"
#endif
#include <sys/mman.h>
char *tool_name = "iprperf";
struct log_sense {
u8 page_code;
u8 reserved;
u16 len;
u8 reserved2[3];
u8 parm_len;
u16 num_seeks_0;
u16 num_seeks_gt_2_3;
u16 num_seeks_gt_1_3;
u16 num_seeks_gt_1_6;
u16 num_seeks_gt_1_12;
u16 num_seeks_gt_0;
u8 reserved3[4];
u16 num_dev_read_buf_overruns;
u16 num_dev_write_buf_overruns;
u32 num_dev_cache_read_hits;
u32 num_dev_cache_partial_read_hits;
u32 num_dev_cache_write_hits;
u32 num_dev_cache_fast_writes;
u32 reserved4[2];
u32 num_device_read_ops;
u32 num_device_write_ops;
u32 num_ioa_cache_read_hits;
u32 num_ioa_cache_partial_read_hits;
u32 num_ioa_cache_write_hits;
u32 num_ioa_cache_fast_writes;
u32 num_ioa_emul_read_cache_hits;
u32 ioa_idle_loop_count[2];
u32 ioa_idle_loop_count_value;
u8 ioa_idle_count_value_units;
u8 reserved5[3];
};
static int get_counters(struct ipr_dev *dev, struct log_sense *log)
{
int fd;
u8 cdb[IPR_CCB_CDB_LEN];
struct sense_data_t sense_data;
int rc;
if (strlen(dev->gen_name) == 0)
return -ENOENT;
fd = open(dev->gen_name, O_RDWR);
if (fd <= 1) {
syslog(LOG_ERR, "Could not open %s. %m\n", dev->gen_name);
return errno;
}
memset(cdb, 0, IPR_CCB_CDB_LEN);
memset(log, 0, sizeof(*log));
cdb[0] = LOG_SENSE;
cdb[2] = 0x70;
cdb[7] = sizeof(*log) >> 8;
cdb[8] = sizeof(*log) & 0xff;
rc = sg_ioctl(fd, cdb, log,
sizeof(*log), SG_DXFER_FROM_DEV,
&sense_data, IPR_ARRAY_CMD_TIMEOUT);
if (rc != 0)
scsi_cmd_err(dev, &sense_data, "Log Sense", rc);
close(fd);
return rc;
}
static void print_counters(struct ipr_dev *dev, struct log_sense *log)
{
printf("Number of seeks = zero length : %d\n", ntohs(log->num_seeks_0));
printf("Number of seeks >= 2/3 disk : %d\n", ntohs(log->num_seeks_gt_2_3));
printf("Number of seeks >= 1/3 and < 2/3 disk : %d\n", ntohs(log->num_seeks_gt_1_3));
printf("Number of seeks >= 1/6 and < 1/3 disk : %d\n", ntohs(log->num_seeks_gt_1_6));
printf("Number of seeks >= 1/12 and < 1/6 disk : %d\n", ntohs(log->num_seeks_gt_1_12));
printf("Number of seeks > 0 and < 1/12 disk : %d\n", ntohs(log->num_seeks_gt_0));
printf("Number of device read buffer overruns : %d\n", ntohs(log->num_dev_read_buf_overruns));
printf("Number of device write buffer underruns : %d\n", ntohs(log->num_dev_write_buf_overruns));
printf("Number of device cache read hits : %d\n", ntohl(log->num_dev_cache_read_hits));
printf("Number of device cache partial read hits : %d\n", ntohl(log->num_dev_cache_partial_read_hits));
printf("Number of device cache write hits : %d\n", ntohl(log->num_dev_cache_write_hits));
printf("Number of device cache fast writes : %d\n", ntohl(log->num_dev_cache_fast_writes));
if (ipr_is_gscsi(dev))
return;
printf("\n");
printf("Number of device read ops : %d\n", ntohl(log->num_device_read_ops));
printf("Number of device write ops : %d\n", ntohl(log->num_device_write_ops));
printf("Number of IOA cache read hits : %d\n", ntohl(log->num_ioa_cache_read_hits));
printf("Number of IOA cache partial read hits : %d\n", ntohl(log->num_ioa_cache_partial_read_hits));
printf("Number of IOA cache write hits : %d\n", ntohl(log->num_ioa_cache_write_hits));
printf("Number of IOA cache fast writes : %d\n", ntohl(log->num_ioa_cache_fast_writes));
printf("Number of IOA emulated read cache hits : %d\n", ntohl(log->num_ioa_emul_read_cache_hits));
printf("IOA Idle loop count : %X%08X\n",
ntohl(log->ioa_idle_loop_count[0]), ntohl(log->ioa_idle_loop_count[1]));
printf("IOA Idle loop count value : %X\n", ntohl(log->ioa_idle_loop_count_value));
printf("IOA Idle count value units : %d\n", log->ioa_idle_count_value_units);
}
int main(int argc, char *argv[])
{
struct ipr_dev *dev;
struct log_sense log;
int rc;
openlog("iprperf", LOG_PERROR | LOG_PID | LOG_CONS, LOG_USER);
tool_init(1);
check_current_config(false);
dev = find_gen_dev(argv[1]);
if (!dev)
dev = find_blk_dev(argv[1]);
if (!dev) {
fprintf(stderr, "Cannot find %s\n", argv[1]);
return -EINVAL;
}
rc = get_counters(dev, &log);
if (rc)
return rc;
print_counters(dev, &log);
return 0;
}

86
debug/iprshutdown.c Executable file
View file

@ -0,0 +1,86 @@
/**
* IBM IPR adapter shutdown utility
*
* (C) Copyright 2005
* International Business Machines Corporation and others.
* All Rights Reserved. This program and the accompanying
* materials are made available under the terms of the
* Common Public License v1.0 which accompanies this distribution.
*
*/
/*
* $Header: /cvsroot/iprdd/iprutils/debug/iprshutdown.c,v 1.1 2005/09/26 20:19:36 brking Exp $
*/
#include <unistd.h>
#include <sys/ioctl.h>
#include <scsi/sg.h>
#include <scsi/scsi.h>
#include <sys/stat.h>
#ifndef iprlib_h
#include "iprlib.h"
#endif
#include <sys/mman.h>
char *tool_name = "iprshutdown";
static void init_all()
{
struct ipr_ioa *ioa;
tool_init(1);
check_current_config(false);
for_each_ioa(ioa)
ipr_init_ioa(ioa);
}
static int ipr_ioa_flush(struct ipr_ioa *ioa)
{
int fd;
u8 cdb[IPR_CCB_CDB_LEN];
struct sense_data_t sense_data;
int rc;
if (strlen(ioa->ioa.gen_name) == 0)
return -ENOENT;
fd = open(ioa->ioa.gen_name, O_RDWR);
if (fd <= 1) {
syslog(LOG_ERR, "Could not open %s. %m\n", ioa->ioa.gen_name);
return errno;
}
memset(cdb, 0, IPR_CCB_CDB_LEN);
cdb[0] = 0xF7;
cdb[1] = 0x40;
rc = sg_ioctl(fd, cdb, ioa->qac_data,
0, SG_DXFER_TO_DEV,
&sense_data, IPR_ARRAY_CMD_TIMEOUT);
if (rc != 0)
ioa_cmd_err(ioa, &sense_data, 0xF7, rc);
close(fd);
return rc;
}
int main(int argc, char *argv[])
{
struct ipr_ioa *ioa;
tool_init(1);
check_current_config(false);
for_each_ioa(ioa) {
if (!strcmp(ioa->ioa.gen_name, argv[1])) {
ipr_ioa_flush(ioa);
return 0;
}
}
return -EINVAL;
}

184
debug/iprtest.c Executable file
View file

@ -0,0 +1,184 @@
/**
* IBM IPR adapter performance utility
*
* (C) Copyright 2005
* International Business Machines Corporation and others.
* All Rights Reserved. This program and the accompanying
* materials are made available under the terms of the
* Common Public License v1.0 which accompanies this distribution.
*
*/
/*
* $Header: /cvsroot/iprdd/iprutils/debug/iprtest.c,v 1.1 2005/09/26 20:19:36 brking Exp $
*/
#include <unistd.h>
#include <sys/ioctl.h>
#include <scsi/sg.h>
#include <scsi/scsi.h>
#include <sys/stat.h>
#ifndef iprlib_h
#include "iprlib.h"
#endif
#include <sys/mman.h>
char *tool_name = "iprperf";
struct log_sense {
u8 page_code;
u8 reserved;
u16 len;
u8 reserved2[3];
u8 parm_len;
u16 num_seeks_0;
u16 num_seeks_gt_2_3;
u16 num_seeks_gt_1_3;
u16 num_seeks_gt_1_6;
u16 num_seeks_gt_1_12;
u16 num_seeks_gt_0;
u8 reserved3[4];
u16 num_dev_read_buf_overruns;
u16 num_dev_write_buf_overruns;
u32 num_dev_cache_read_hits;
u32 num_dev_cache_partial_read_hits;
u32 num_dev_cache_write_hits;
u32 num_dev_cache_fast_writes;
u32 reserved4[2];
u32 num_device_read_ops;
u32 num_device_write_ops;
u32 num_ioa_cache_read_hits;
u32 num_ioa_cache_partial_read_hits;
u32 num_ioa_cache_write_hits;
u32 num_ioa_cache_fast_writes;
u32 num_ioa_emul_read_cache_hits;
u32 ioa_idle_loop_count[2];
u32 ioa_idle_loop_count_value;
u8 ioa_idle_count_value_units;
u8 reserved5[3];
};
static int get_counters(struct ipr_dev *dev, struct log_sense *log)
{
int fd;
u8 cdb[IPR_CCB_CDB_LEN];
struct sense_data_t sense_data;
int rc;
if (strlen(dev->gen_name) == 0)
return -ENOENT;
fd = open(dev->gen_name, O_RDWR);
if (fd <= 1) {
syslog(LOG_ERR, "Could not open %s. %m\n", dev->gen_name);
return errno;
}
memset(cdb, 0, IPR_CCB_CDB_LEN);
memset(log, 0, sizeof(*log));
cdb[0] = LOG_SENSE;
cdb[2] = 0x70;
cdb[7] = sizeof(*log) >> 8;
cdb[8] = sizeof(*log) & 0xff;
rc = sg_ioctl(fd, cdb, log,
sizeof(*log), SG_DXFER_FROM_DEV,
&sense_data, IPR_ARRAY_CMD_TIMEOUT);
if (rc != 0)
scsi_cmd_err(dev, &sense_data, "Log Sense", rc);
close(fd);
return rc;
}
#define logd(item, desc, xlate) \
if (old_log->item != new_log->item) \
printf("%s: %d\n", desc, xlate(new_log->item) - xlate(old_log->item)); \
#define logs(desc, item) logd(item, desc, ntohs)
#define logl(desc, item) logd(item, desc, ntohl)
static void print_counters(struct ipr_dev *dev, struct log_sense *old_log, struct log_sense *new_log)
{
printf("===============================================\n");
scsi_info(dev, "Device counters\n");
logs("Number of seeks = zero length ", num_seeks_0);
logs("Number of seeks >= 2/3 disk ", num_seeks_gt_2_3);
logs("Number of seeks >= 1/3 and < 2/3 disk ", num_seeks_gt_1_3);
logs("Number of seeks >= 1/6 and < 1/3 disk ", num_seeks_gt_1_6);
logs("Number of seeks >= 1/12 and < 1/6 disk ", num_seeks_gt_1_12);
logs("Number of seeks > 0 and < 1/12 disk ", num_seeks_gt_0);
logs("Number of device read buffer overruns ", num_dev_read_buf_overruns);
logs("Number of device write buffer underruns ", num_dev_write_buf_overruns);
logl("Number of device cache read hits ", num_dev_cache_read_hits);
logl("Number of device cache partial read hits ", num_dev_cache_partial_read_hits);
logl("Number of device cache write hits ", num_dev_cache_write_hits);
logl("Number of device cache fast writes ", num_dev_cache_fast_writes);
if (ipr_is_gscsi(dev)) {
printf("===============================================\n");
return;
}
logl("Number of device read ops ", num_device_read_ops);
logl("Number of device write ops ", num_device_write_ops);
logl("Number of IOA cache read hits ", num_ioa_cache_read_hits);
logl("Number of IOA cache partial read hits ", num_ioa_cache_partial_read_hits);
logl("Number of IOA cache write hits ", num_ioa_cache_write_hits);
logl("Number of IOA cache fast writes ", num_ioa_cache_fast_writes);
logl("Number of IOA emulated read cache hits ", num_ioa_emul_read_cache_hits);
logl("IOA Idle loop count[0] ", ioa_idle_loop_count[0]);
logl("IOA Idle loop count[1] ", ioa_idle_loop_count[1]);
printf("IOA Idle loop count value : %X\n", ntohl(new_log->ioa_idle_loop_count_value));
printf("IOA Idle count value units : %d\n", new_log->ioa_idle_count_value_units);
printf("===============================================\n");
}
int main(int argc, char *argv[])
{
struct ipr_dev *dev[2];
struct log_sense old_log[2], new_log[2];
int rc, i;
openlog("iprperf", LOG_PERROR | LOG_PID | LOG_CONS, LOG_USER);
tool_init(1);
check_current_config(false);
for (i = 0; i < 2; i++) {
dev[i] = find_gen_dev(argv[1+i]);
if (!dev[i])
dev[i] = find_blk_dev(argv[1+i]);
if (!dev[i]) {
fprintf(stderr, "Cannot find %s\n", argv[1+i]);
return -EINVAL;
}
}
for (i = 0; i < 2; i++) {
rc = get_counters(dev[i], &old_log[i]);
if (rc)
return rc;
}
printf("***********************************************\n");
system(argv[3]);
for (i = 0; i < 2; i++) {
rc = get_counters(dev[i], &new_log[i]);
if (rc)
return rc;
}
for (i = 0; i < 2; i++) {
print_counters(dev[i], &old_log[i], &new_log[i]);
}
printf("***********************************************\n");
return 0;
}

81
debug/iprwritebuffer.c Executable file
View file

@ -0,0 +1,81 @@
/**
* IBM IPR adapter low level drive microcode update utility
*
* (C) Copyright 2005
* International Business Machines Corporation and others.
* All Rights Reserved. This program and the accompanying
* materials are made available under the terms of the
* Common Public License v1.0 which accompanies this distribution.
*
*/
/*
* $Header: /cvsroot/iprdd/iprutils/debug/iprwritebuffer.c,v 1.1 2005/09/26 20:19:36 brking Exp $
*/
#include <unistd.h>
#include <sys/ioctl.h>
#include <scsi/sg.h>
#include <scsi/scsi.h>
#include <sys/stat.h>
#ifndef iprlib_h
#include "iprlib.h"
#endif
#include <sys/mman.h>
char *tool_name = "iprwritebuffer";
static int ipr_update_ucode(struct ipr_dev *dev, char *fname)
{
struct stat ucode_stats;
int fd, rc;
char *buffer;
fd = open(fname, O_RDONLY);
if (fd < 0) {
syslog_dbg("Could not open firmware file %s.\n", fname);
return;
}
rc = fstat(fd, &ucode_stats);
if (rc != 0) {
syslog(LOG_ERR, "Failed to stat firmware file: %s.\n", fname);
close(fd);
return rc;
}
buffer = mmap(NULL, ucode_stats.st_size,
PROT_READ, MAP_SHARED, fd, 0);
rc = ipr_write_buffer(dev, buffer, ucode_stats.st_size);
ipr_init_dev(dev);
close(fd);
return rc;
}
int main(int argc, char *argv[])
{
struct ipr_dev *dev;
if (argc != 3) {
fprintf(stderr, "Usage iprwritebuffer /dev/sgX ucode_image.bin\n");
return -EINVAL;
}
tool_init(1);
check_current_config(false);
dev = find_blk_dev(argv[1]);
if (!dev)
dev = find_gen_dev(argv[1]);
if (!dev) {
fprintf(stderr, "Cannot find device: %s\n", argv[1]);
return -EINVAL;
}
return ipr_update_ucode(dev, argv[2]);
}

View file

@ -173,6 +173,15 @@ name. Only 1 array can be deleted with a single command. Example:
.br
This would delete the disk array represented by /dev/sda
.TP
.B status [device]
.br
Prints the status of the specified device. This is the same status as which shows
up in the last column of the Display hardware status menu. Can specify either a
/dev/sdX name or a /dev/sgX name. Example:
.br
.B iprconfig -c status /dev/sda
.br
.TP
.B \-\-version
Print version number of
.B iprconfig

View file

@ -3517,7 +3517,7 @@ int configure_raid_include(i_container *i_con)
struct screen_output *s_out;
for_each_icon(temp_i_con) {
cur_raid_cmd = i_con->data;
cur_raid_cmd = temp_i_con->data;
if (!cur_raid_cmd)
continue;
@ -4534,7 +4534,7 @@ int disk_unit_recovery(i_container *i_con)
return rc;
}
static void get_res_addr(struct ipr_dev *dev, struct ipr_res_addr *res_addr)
static int get_res_addr(struct ipr_dev *dev, struct ipr_res_addr *res_addr)
{
struct ipr_dev_record *dev_record = dev->dev_rcd;
struct ipr_array_record *array_record = dev->array_rcd;
@ -4555,20 +4555,24 @@ static void get_res_addr(struct ipr_dev *dev, struct ipr_res_addr *res_addr)
res_addr->bus = dev_record->resource_addr.bus;
res_addr->target = dev_record->resource_addr.target;
res_addr->lun = dev_record->resource_addr.lun;
}
} else
return -1;
} else if (ipr_is_volume_set(dev)) {
if (array_record && array_record->no_config_entry) {
res_addr->host = dev->ioa->host_num;
res_addr->bus = array_record->last_resource_addr.bus;
res_addr->target = array_record->last_resource_addr.target;
res_addr->lun = array_record->last_resource_addr.lun;
} else if (dev_record) {
} else if (array_record) {
res_addr->host = dev->ioa->host_num;
res_addr->bus = array_record->resource_addr.bus;
res_addr->target = array_record->resource_addr.target;
res_addr->lun = array_record->resource_addr.lun;
}
}
} else
return -1;
} else
return -1;
return 0;
}
int process_conc_maint(i_container *i_con, int action)
@ -4603,7 +4607,8 @@ int process_conc_maint(i_container *i_con, int action)
if (found != 1)
return INVALID_OPTION_STATUS;
get_res_addr(dev, &res_addr);
if (get_res_addr(dev, &res_addr))
return INVALID_OPTION_STATUS; /* FIXME */
if (ipr_is_af_dasd_device(dev) &&
(action == IPR_VERIFY_CONC_REMOVE || action == IPR_WAIT_CONC_REMOVE)) {
@ -4795,6 +4800,7 @@ int start_conc_maint(i_container *i_con, int action)
int toggle = 1;
s_node *n_screen;
int header_lines;
u8 scsi_id_found;
processing();
@ -4822,8 +4828,13 @@ int start_conc_maint(i_container *i_con, int action)
continue;
ses_channel = ses->scsi_dev_data->channel;
scsi_id_found = 0;
for_each_elem_status(i, &ses_data) {
if (scsi_id_found & (1 << ses_data.elem_status[i].scsi_id))
continue;
scsi_id_found |= (1 << ses_data.elem_status[i].scsi_id);
if (ses_data.elem_status[i].status == IPR_DRIVE_ELEM_STATUS_EMPTY) {
local_dev = realloc(local_dev, (sizeof(void *) *
local_dev_count) + 1);
@ -4844,7 +4855,10 @@ int start_conc_maint(i_container *i_con, int action)
}
for_each_dev(ioa, dev) {
get_res_addr(dev, &res_addr);
if (get_res_addr(dev, &res_addr)) {
scsi_dbg(dev, "Cannot find resource address\n");
continue;
}
if (res_addr.bus == ses_channel &&
res_addr.target == ses_data.elem_status[i].scsi_id) {
if (action == IPR_CONC_REMOVE) {
@ -5012,23 +5026,9 @@ int init_device(i_container *i_con)
continue;
if (can_init) {
if (dev_init_head) {
dev_init_tail->next = malloc(sizeof(struct devs_to_init_t));
dev_init_tail = dev_init_tail->next;
}
else
dev_init_head = dev_init_tail = malloc(sizeof(struct devs_to_init_t));
memset(dev_init_tail, 0, sizeof(struct devs_to_init_t));
dev_init_tail->ioa = ioa;
dev_init_tail->dev_type = dev_type;
dev_init_tail->dev = dev;
dev_init_tail->new_block_size = 0;
add_format_device(dev, 0);
print_dev(k, dev, buffer, "%1", ioa, k);
i_con = add_i_con(i_con,"\0",dev_init_tail);
num_devs++;
}
}
@ -5137,7 +5137,7 @@ int confirm_init_device(i_container *i_con)
static int dev_init_complete(u8 num_devs)
{
int done_bad;
int done_bad = 0;
struct ipr_cmd_status cmd_status;
struct ipr_cmd_status_record *status_record;
int not_done = 0;
@ -5162,7 +5162,6 @@ static int dev_init_complete(u8 num_devs)
}
percent_cmplt = 100;
done_bad = 0;
for_each_dev_to_init(dev) {
if (!dev->do_init || dev->done)
@ -5213,6 +5212,7 @@ static int dev_init_complete(u8 num_devs)
if (rc < 0) {
dev->done = 1;
done_bad = 1;
continue;
}
@ -5236,9 +5236,11 @@ static int dev_init_complete(u8 num_devs)
continue;
ioa = dev->ioa;
if (dev->new_block_size != ioa->af_block_size && ipr_is_gscsi(dev->dev)) {
if (ipr_is_gscsi(dev->dev)) {
rc = ipr_test_unit_ready(dev->dev, &sense_data);
if (rc == 0) {
if (rc) {
done_bad = 1;
} else if (dev->new_block_size != ioa->af_block_size) {
ipr_write_dev_attr(dev->dev, "rescan", "1");
ipr_init_dev(dev->dev);
}
@ -6463,7 +6465,7 @@ int bus_attr_menu(struct ipr_ioa *ioa, struct bus_attr *bus_attr, int start_row,
{
int i, scsi_id, found;
int num_menu_items;
int menu_index;
int menu_index = 0;
ITEM **menu_item = NULL;
struct ipr_scsi_buses *page_28_cur;
struct ipr_dev *dev;
@ -8410,29 +8412,18 @@ int ibm_boot_log(i_container *i_con)
return 1; /* return with no status */
}
char *print_device(struct ipr_dev *ipr_dev, char *body, char *option,
struct ipr_ioa *ioa, int type)
static void get_status(struct ipr_dev *ipr_dev, char *buf, int type)
{
u16 len = 0;
struct scsi_dev_data *scsi_dev_data = ipr_dev->scsi_dev_data;
int i, rc;
struct ipr_ioa *ioa = ipr_dev->ioa;
int rc;
struct ipr_query_res_state res_state;
struct ipr_res_addr res_addr;
u8 ioctl_buffer[255];
char raid_str[48];
int status;
int format_req = 0;
struct ipr_mode_parm_hdr *mode_parm_hdr;
struct ipr_block_desc *block_desc;
struct sense_data_t sense_data;
char *dev_name = ipr_dev->dev_name;
char *gen_name = ipr_dev->gen_name;
char node_name[7];
int tab_stop = 0;
char vendor_id[IPR_VENDOR_ID_LEN + 1];
char product_id[IPR_PROD_ID_LEN + 1];
struct ipr_common_record *common_record;
struct ipr_dev_record *device_record;
struct ipr_array_record *array_record;
struct ipr_cmd_status cmd_status;
struct ipr_cmd_status_record *status_record;
@ -8440,83 +8431,16 @@ char *print_device(struct ipr_dev *ipr_dev, char *body, char *option,
int format_in_progress = 0;
int resync_in_progress = 0;
if (body)
len = strlen(body);
body = realloc(body, len + 256);
if (((type & 3) == 2) && (strlen(gen_name) > 5))
ipr_strncpy_0(node_name, &gen_name[5], 6);
else if (strlen(dev_name) > 5)
ipr_strncpy_0(node_name, &dev_name[5], 6);
else
node_name[0] = '\0';
len += sprintf(body + len, " %s %-6s %s/%d:",
option,
node_name,
ioa->pci_address,
ioa->host_num);
if (scsi_dev_data && scsi_dev_data->type == IPR_TYPE_ADAPTER) {
if (type&1) {
len += sprintf(body + len," %-25s ", get_ioa_desc(ipr_dev->ioa));
} else
len += sprintf(body + len," %-8s %-16s ",
scsi_dev_data->vendor_id,
scsi_dev_data->product_id);
if (ioa->ioa_dead)
len += sprintf(body + len, "Not Operational\n");
sprintf(buf, "Not Operational");
else if (ioa->nr_ioa_microcode)
len += sprintf(body + len, "Not Ready\n");
sprintf(buf, "Not Ready");
else
len += sprintf(body + len, "Operational\n");
} else if ((scsi_dev_data) &&
(scsi_dev_data->type == IPR_TYPE_EMPTY_SLOT)) {
tab_stop = sprintf(body + len,"%d:%d: ",
scsi_dev_data->channel,
scsi_dev_data->id);
len += tab_stop;
for (i = 0; i < 12-tab_stop; i++)
body[len+i] = ' ';
len += 12-tab_stop;
len += sprintf(body + len, "%-8s %-16s "," ", " ");
len += sprintf(body + len, "Empty\n");
sprintf(buf, "Operational");
} else if (scsi_dev_data && scsi_dev_data->type == IPR_TYPE_EMPTY_SLOT) {
sprintf(buf, "Empty");
} else {
get_res_addr(ipr_dev, &res_addr);
tab_stop = sprintf(body + len,"%d:%d:%d ", res_addr.bus,
res_addr.target, res_addr.lun);
if (scsi_dev_data) {
ipr_strncpy_0(vendor_id, scsi_dev_data->vendor_id, IPR_VENDOR_ID_LEN);
ipr_strncpy_0(product_id, scsi_dev_data->product_id, IPR_PROD_ID_LEN);
}
else if (ipr_dev->qac_entry) {
common_record = ipr_dev->qac_entry;
if (common_record->record_id == IPR_RECORD_ID_DEVICE_RECORD) {
device_record = (struct ipr_dev_record *)common_record;
ipr_strncpy_0(vendor_id, device_record->vendor_id, IPR_VENDOR_ID_LEN);
ipr_strncpy_0(product_id , device_record->product_id, IPR_PROD_ID_LEN);
} else if (common_record->record_id == IPR_RECORD_ID_ARRAY_RECORD) {
array_record = (struct ipr_array_record *)common_record;
ipr_strncpy_0(vendor_id, array_record->vendor_id, IPR_VENDOR_ID_LEN);
ipr_strncpy_0(product_id , array_record->product_id,
IPR_PROD_ID_LEN);
}
}
len += tab_stop;
for (i = 0; i < 12-tab_stop; i++)
body[len+i] = ' ';
len += 12-tab_stop;
if (ipr_is_volume_set(ipr_dev)) {
rc = ipr_query_command_status(&ioa->ioa, &cmd_status);
@ -8537,7 +8461,6 @@ char *print_device(struct ipr_dev *ipr_dev, char *body, char *option,
rc = ipr_query_command_status(ipr_dev, &cmd_status);
if ((rc == 0) && (cmd_status.num_records != 0)) {
status_record = cmd_status.record;
if ((status_record->status != IPR_CMD_STATUS_SUCCESSFUL) &&
(status_record->status != IPR_CMD_STATUS_FAILED)) {
@ -8560,36 +8483,6 @@ char *print_device(struct ipr_dev *ipr_dev, char *body, char *option,
}
}
if (!(type&1)) {
len += sprintf(body + len, "%-8s %-16s ",
vendor_id, product_id);
} else {
if (ipr_is_hot_spare(ipr_dev))
len += sprintf(body + len, "%-25s ", "Hot Spare");
else if (ipr_is_volume_set(ipr_dev)) {
sprintf(ioctl_buffer, "RAID %s Disk Array",
ipr_dev->prot_level_str);
len += sprintf(body + len, "%-25s ", ioctl_buffer);
} else if (ipr_is_array_member(ipr_dev)) {
if (type&2)
sprintf(raid_str," RAID %s Array Member",
ipr_dev->prot_level_str);
else
sprintf(raid_str,"RAID %s Array Member",
ipr_dev->prot_level_str);
len += sprintf(body + len, "%-25s ", raid_str);
} else if (ipr_is_af_dasd_device(ipr_dev))
len += sprintf(body + len, "%-25s ", "Advanced Function Disk");
else if (scsi_dev_data && scsi_dev_data->type == TYPE_ENCLOSURE)
len += sprintf(body + len, "%-25s ", "Enclosure");
else if (scsi_dev_data && scsi_dev_data->type == TYPE_PROCESSOR)
len += sprintf(body + len, "%-25s ", "Processor");
else
len += sprintf(body + len, "%-25s ", "Physical Disk");
}
if (ipr_is_af(ipr_dev)) {
memset(&res_state, 0, sizeof(res_state));
@ -8636,43 +8529,165 @@ char *print_device(struct ipr_dev *ipr_dev, char *body, char *option,
}
if (format_in_progress)
sprintf(body + len, "%d%% Formatted\n", percent_cmplt);
sprintf(buf, "%d%% Formatted", percent_cmplt);
else if (!scsi_dev_data && ipr_dev->ioa->is_secondary)
sprintf(body + len, "Remote\n");
sprintf(buf, "Remote");
else if (!scsi_dev_data)
sprintf(body + len, "Missing\n");
sprintf(buf, "Missing");
else if (!scsi_dev_data->online)
sprintf(body + len, "Offline\n");
sprintf(buf, "Offline");
else if (res_state.not_oper || res_state.not_func)
sprintf(body + len, "Failed\n");
sprintf(buf, "Failed");
else if (res_state.read_write_prot)
sprintf(body + len, "R/W Protected\n");
sprintf(buf, "R/W Protected");
else if (res_state.prot_dev_failed)
sprintf(body + len, "Failed\n");
sprintf(buf, "Failed");
else if (ipr_is_volume_set(ipr_dev)) {
if (res_state.prot_suspended && ipr_is_volume_set(ipr_dev))
sprintf(body + len, "Degraded\n");
sprintf(buf, "Degraded");
else if (res_state.prot_resuming && ipr_is_volume_set(ipr_dev)) {
if (!(type&1) || (percent_cmplt == 0))
sprintf(body + len, "Rebuilding\n");
sprintf(buf, "Rebuilding");
else
sprintf(body + len, "%d%% Rebuilt\n", percent_cmplt);
sprintf(buf, "%d%% Rebuilt", percent_cmplt);
} else if (resync_in_progress) {
if (!(type&1) || (percent_cmplt == 0))
sprintf(body + len, "Checking\n");
sprintf(buf, "Checking");
else
sprintf(body + len, "%d%% Checked\n", percent_cmplt);
sprintf(buf, "%d%% Checked", percent_cmplt);
} else if (res_state.degraded_oper || res_state.service_req)
sprintf(body + len, "Degraded\n");
sprintf(buf, "Degraded");
else
sprintf(body + len, "Active\n");
sprintf(buf, "Active");
} else if (format_req)
sprintf(body + len, "Format Required\n");
sprintf(buf, "Format Required");
else if (ipr_device_is_zeroed(ipr_dev))
sprintf(body + len, "Zeroed\n");
sprintf(buf, "Zeroed");
else
sprintf(body + len, "Active\n");
sprintf(buf, "Active");
}
}
char *print_device(struct ipr_dev *ipr_dev, char *body, char *option,
struct ipr_ioa *ioa, int type)
{
u16 len = 0;
struct scsi_dev_data *scsi_dev_data = ipr_dev->scsi_dev_data;
int i;
struct ipr_res_addr res_addr;
u8 ioctl_buffer[255];
char raid_str[48];
char *dev_name = ipr_dev->dev_name;
char *gen_name = ipr_dev->gen_name;
char node_name[7], buf[100];
int tab_stop = 0;
char vendor_id[IPR_VENDOR_ID_LEN + 1];
char product_id[IPR_PROD_ID_LEN + 1];
struct ipr_common_record *common_record;
struct ipr_dev_record *device_record;
struct ipr_array_record *array_record;
if (body)
len = strlen(body);
body = realloc(body, len + 256);
if (((type & 3) == 2) && (strlen(gen_name) > 5))
ipr_strncpy_0(node_name, &gen_name[5], 6);
else if (strlen(dev_name) > 5)
ipr_strncpy_0(node_name, &dev_name[5], 6);
else
node_name[0] = '\0';
len += sprintf(body + len, " %s %-6s %s/%d:",
option,
node_name,
ioa->pci_address,
ioa->host_num);
if (scsi_dev_data && scsi_dev_data->type == IPR_TYPE_ADAPTER) {
if (type&1) {
len += sprintf(body + len," %-25s ", get_ioa_desc(ipr_dev->ioa));
} else
len += sprintf(body + len," %-8s %-16s ",
scsi_dev_data->vendor_id,
scsi_dev_data->product_id);
} else if ((scsi_dev_data) &&
(scsi_dev_data->type == IPR_TYPE_EMPTY_SLOT)) {
tab_stop = sprintf(body + len,"%d:%d: ",
scsi_dev_data->channel,
scsi_dev_data->id);
len += tab_stop;
for (i = 0; i < 12-tab_stop; i++)
body[len+i] = ' ';
len += 12-tab_stop;
len += sprintf(body + len, "%-8s %-16s "," ", " ");
} else {
get_res_addr(ipr_dev, &res_addr);
tab_stop = sprintf(body + len,"%d:%d:%d ", res_addr.bus,
res_addr.target, res_addr.lun);
if (scsi_dev_data) {
ipr_strncpy_0(vendor_id, scsi_dev_data->vendor_id, IPR_VENDOR_ID_LEN);
ipr_strncpy_0(product_id, scsi_dev_data->product_id, IPR_PROD_ID_LEN);
}
else if (ipr_dev->qac_entry) {
common_record = ipr_dev->qac_entry;
if (common_record->record_id == IPR_RECORD_ID_DEVICE_RECORD) {
device_record = (struct ipr_dev_record *)common_record;
ipr_strncpy_0(vendor_id, device_record->vendor_id, IPR_VENDOR_ID_LEN);
ipr_strncpy_0(product_id , device_record->product_id, IPR_PROD_ID_LEN);
} else if (common_record->record_id == IPR_RECORD_ID_ARRAY_RECORD) {
array_record = (struct ipr_array_record *)common_record;
ipr_strncpy_0(vendor_id, array_record->vendor_id, IPR_VENDOR_ID_LEN);
ipr_strncpy_0(product_id , array_record->product_id,
IPR_PROD_ID_LEN);
}
}
len += tab_stop;
for (i = 0; i < 12-tab_stop; i++)
body[len+i] = ' ';
len += 12-tab_stop;
if (!(type&1)) {
len += sprintf(body + len, "%-8s %-16s ",
vendor_id, product_id);
} else {
if (ipr_is_hot_spare(ipr_dev))
len += sprintf(body + len, "%-25s ", "Hot Spare");
else if (ipr_is_volume_set(ipr_dev)) {
sprintf(ioctl_buffer, "RAID %s Disk Array",
ipr_dev->prot_level_str);
len += sprintf(body + len, "%-25s ", ioctl_buffer);
} else if (ipr_is_array_member(ipr_dev)) {
if (type&2)
sprintf(raid_str," RAID %s Array Member",
ipr_dev->prot_level_str);
else
sprintf(raid_str,"RAID %s Array Member",
ipr_dev->prot_level_str);
len += sprintf(body + len, "%-25s ", raid_str);
} else if (ipr_is_af_dasd_device(ipr_dev))
len += sprintf(body + len, "%-25s ", "Advanced Function Disk");
else if (scsi_dev_data && scsi_dev_data->type == TYPE_ENCLOSURE)
len += sprintf(body + len, "%-25s ", "Enclosure");
else if (scsi_dev_data && scsi_dev_data->type == TYPE_PROCESSOR)
len += sprintf(body + len, "%-25s ", "Processor");
else
len += sprintf(body + len, "%-25s ", "Physical Disk");
}
}
get_status(ipr_dev, buf, type);
sprintf(body + len, "%s\n", buf);
return body;
}
@ -8742,6 +8757,15 @@ static int raid_create_check_num_devs(struct ipr_array_cap_entry *cap,
return 0;
}
static void curses_init()
{
/* makes program compatible with all terminals -
originally did not display text correctly when user was running xterm */
setenv("TERM", "vt100", 1);
setlocale(LC_ALL, "");
initscr();
}
static int raid_create(char **args, int num_args)
{
int i, num_devs = 0, rc;
@ -8753,6 +8777,7 @@ static int raid_create(char **args, int num_args)
struct ipr_ioa *ioa = NULL;
struct ipr_array_cap_entry *cap;
curses_init();
next_raid_level = 0;
next_stripe_size = 0;
next_qdepth = 0;
@ -8874,6 +8899,8 @@ static int raid_delete(char **args, int num_args)
return -EINVAL;
}
curses_init();
dev->array_rcd->issue_cmd = 1;
if (dev->scsi_dev_data)
rc = ipr_start_stop_stop(dev);
@ -8883,6 +8910,23 @@ static int raid_delete(char **args, int num_args)
return rc;
}
static int print_status(char *name)
{
struct ipr_dev *dev = find_blk_dev(name);
char buf[100];
if (!dev)
dev = find_gen_dev(name);
if (!dev) {
printf("Missing\n");
return -EINVAL;
}
get_status(dev, buf, 0);
printf("%s\n", buf);
return 0;
}
int main(int argc, char *argv[])
{
int next_editor, next_dir, next_cmd, next_dev, i, rc = 0;
@ -8890,11 +8934,6 @@ int main(int argc, char *argv[])
char **dev = NULL;
int non_interactive = 0, num_devs = 0;
/* makes program compatible with all terminals -
originally did not display text correctly when user was running xterm */
setenv("TERM", "vt100", 1);
setlocale(LC_ALL, "");
strcpy(parm_dir, DEFAULT_LOG_DIR);
strcpy(parm_editor, DEFAULT_EDITOR);
@ -8947,7 +8986,6 @@ int main(int argc, char *argv[])
system("modprobe sg");
exit_func = tool_exit_func;
tool_init(0);
initscr();
if (non_interactive) {
exit_func = cmdline_exit_func;
@ -8967,6 +9005,8 @@ int main(int argc, char *argv[])
rc = raid_create(dev, num_devs);
else if (strcmp(cmd, "raid-delete") == 0)
rc = raid_delete(dev, num_devs);
else if (strcmp(cmd, "status") == 0)
rc = print_status(dev[0]);
else {
exit_func();
usage();
@ -8976,6 +9016,7 @@ int main(int argc, char *argv[])
return rc;
}
curses_init();
cbreak(); /* take input chars one at a time, no wait for \n */
keypad(stdscr,TRUE);

View file

@ -10,7 +10,7 @@
*/
/*
* $Header: /cvsroot/iprdd/iprutils/iprdbg.c,v 1.16 2005/03/07 17:20:16 brking Exp $
* $Header: /cvsroot/iprdd/iprutils/iprdbg.c,v 1.17 2005/09/26 20:19:36 brking Exp $
*/
#ifndef iprlib_h
@ -24,6 +24,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <curses.h>
#include <term.h>
#define IPR_MAX_FLIT_ENTRIES 59
#define IPR_FLIT_TIMESTAMP_LEN 12
@ -170,6 +172,49 @@ static int format_flit(struct ipr_flit *flit)
return 0;
}
static char *term;
static char *k_up;
static char *k_down;
static unsigned char hindex;
static char *history[256];
static void ipr_fgets(char *buf, int size, FILE *stream)
{
int i, ch = 0;
for (i = 0; ch != EOF && i < (size - 1); i++) {
ch = fgetc(stream);
if (ch == '\n')
break;
buf[i] = ch;
if (!strcmp(buf, k_up)) {
rewind(stdin);
if (history[hindex]) {
fprintf(stdout, "%s", history[--hindex]);
strcpy(buf, history[hindex]);
i = strlen(buf) + 1;
}
} else if (!strcmp(buf, k_down)) {
rewind(stdin);
if (history[hindex]) {
fprintf(stdout, "%s", history[++hindex]);
strcpy(buf, history[hindex]);
i = strlen(buf) + 1;
}
}
}
buf[i] = '\0';
if (history[hindex])
free(history[hindex]);
history[hindex] = malloc(strlen(buf) + 2);
strcpy(history[hindex++], buf);
strcat(buf, "\n");
}
int main(int argc, char *argv[])
{
int num_args, address, prev_address = 0;
@ -182,6 +227,23 @@ int main(int argc, char *argv[])
struct ipr_ioa *ioa;
char ascii_buffer[17];
struct ipr_flit flit;
char *term_type;
term_type = getenv ("TERM");
if (!term_type) {
fprintf(stderr, "Cannot determine terminal type. Is TERM set?\n");
return -EIO;
}
rc = tgetent (term, term_type);
if (rc < 0) {
fprintf(stderr, "Cannot determine terminal type\n");
return -EIO;
}
k_up = tgetstr ("ku", NULL);
k_down = tgetstr ("kd", NULL);
openlog("iprdbg",
LOG_PERROR | /* Print error to stderr as well */
@ -246,7 +308,7 @@ int main(int argc, char *argv[])
memset(arg, 0, sizeof(arg));
address = 0;
fgets(cmd_line, 999, stdin);
ipr_fgets(cmd_line, 999, stdin);
logtofile("\n%s\n", cmd_line);

View file

@ -10,7 +10,7 @@
*/
/*
* $Header: /cvsroot/iprdd/iprutils/iprlib.c,v 1.71 2005/07/20 18:07:09 brking Exp $
* $Header: /cvsroot/iprdd/iprutils/iprlib.c,v 1.72 2005/09/26 20:19:36 brking Exp $
*/
#ifndef iprlib_h
@ -1069,6 +1069,7 @@ static void resolve_ioa(struct ipr_ioa *ioa, struct ipr_ioa *old_ioa)
for_each_dev(old_ioa, old_dev) {
if (!same_dev(dev, old_dev))
continue;
memcpy(&dev->attr, &old_dev->attr, sizeof(dev->attr));
resolve_dev(dev, old_dev);
break;
}
@ -2575,6 +2576,7 @@ int format_req(struct ipr_dev *dev)
}
#define IPR_MAX_XFER 0x8000
const int cdb_size[] ={6, 10, 10, 0, 16, 12, 16, 16};
static int _sg_ioctl(int fd, u8 cdb[IPR_CCB_CDB_LEN],
void *data, u32 xfer_len, u32 data_direction,
@ -2588,6 +2590,7 @@ static int _sg_ioctl(int fd, u8 cdb[IPR_CCB_CDB_LEN],
int i;
int buff_len, segment_size;
void *dxferp;
u8 *buf;
/* check if scatter gather should be used */
if (xfer_len > IPR_MAX_XFER) {
@ -2599,7 +2602,8 @@ static int _sg_ioctl(int fd, u8 cdb[IPR_CCB_CDB_LEN],
for (i = 0; (i < iovec_count) && (buff_len != 0); i++) {
iovec[i].iov_base = malloc(segment_size);
memcpy(iovec[i].iov_base, data + (IPR_MAX_XFER * i), segment_size);
if (data_direction == SG_DXFER_TO_DEV)
memcpy(iovec[i].iov_base, data + (IPR_MAX_XFER * i), segment_size);
iovec[i].iov_len = segment_size;
buff_len -= segment_size;
@ -2644,8 +2648,12 @@ static int _sg_ioctl(int fd, u8 cdb[IPR_CCB_CDB_LEN],
}
if (iovec_count) {
for (i = 0; i < iovec_count; i++)
for (i = 0, buf = (u8 *)data; i < iovec_count; i++) {
if (data_direction == SG_DXFER_FROM_DEV)
memcpy(buf, iovec[i].iov_base, iovec[i].iov_len);
buf += iovec[i].iov_len;
free(iovec[i].iov_base);
}
free(iovec);
}
@ -2794,11 +2802,11 @@ int get_scsi_dev_data(struct scsi_dev_data **scsi_dev_ref)
sysfs_attr = sysfs_get_device_attr(sysfs_device_device, "vendor");
if (sysfs_attr)
ipr_strncpy_0(scsi_dev_data->vendor_id, sysfs_attr->value, IPR_VENDOR_ID_LEN);
ipr_strncpy_0n(scsi_dev_data->vendor_id, sysfs_attr->value, IPR_VENDOR_ID_LEN);
sysfs_attr = sysfs_get_device_attr(sysfs_device_device, "model");
if (sysfs_attr)
ipr_strncpy_0(scsi_dev_data->product_id, sysfs_attr->value, IPR_PROD_ID_LEN);
ipr_strncpy_0n(scsi_dev_data->product_id, sysfs_attr->value, IPR_PROD_ID_LEN);
strcpy(scsi_dev_data->dev_name,"");
strcpy(scsi_dev_data->gen_name,"");
@ -4484,6 +4492,7 @@ void ipr_update_ioa_fw(struct ipr_ioa *ioa,
struct stat ucode_stats;
u32 fw_version;
int fd, rc;
int host_num = ioa->host_num;
char *tmp;
char ucode_file[200];
DIR *dir;
@ -4545,6 +4554,13 @@ void ipr_update_ioa_fw(struct ipr_ioa *ioa,
if (rc != 0)
ioa_err(ioa, "Microcode update failed. rc=%d\n", rc);
check_current_config(false);
for_each_ioa(ioa) {
if (ioa->host_num != host_num)
continue;
ipr_init_ioa(ioa);
break;
}
} else
ipr_log_ucode_error(ioa);
@ -4929,7 +4945,9 @@ static void init_af_dev(struct ipr_dev *dev)
if (ipr_set_dasd_timeouts(dev))
return;
if (polling_mode && (!dev->should_init || !dev_init_allowed(dev)))
if (polling_mode && (!dev->should_init && !memcmp(&attr, &dev->attr, sizeof(attr))))
return;
if (polling_mode && !dev_init_allowed(dev))
return;
if (setup_page0x00(dev))
return;
@ -4951,6 +4969,7 @@ static void init_af_dev(struct ipr_dev *dev)
if (ipr_modify_dev_attr(dev, &attr))
return;
memcpy(&dev->attr, &attr, sizeof(attr));
if (ipr_set_dev_attr(dev, &attr, 0))
return;
}

View file

@ -12,7 +12,7 @@
*/
/*
* $Header: /cvsroot/iprdd/iprutils/iprlib.h,v 1.56 2005/07/20 18:07:11 brking Exp $
* $Header: /cvsroot/iprdd/iprutils/iprlib.h,v 1.57 2005/09/26 20:19:36 brking Exp $
*/
#include <stdarg.h>
@ -999,6 +999,20 @@ struct ipr_multi_ioa_status {
*/
};
struct ipr_disk_attr {
int queue_depth;
int tcq_enabled;
int format_timeout;
};
struct ipr_vset_attr {
int queue_depth;
};
struct ipr_ioa_attr {
int preferred_primary;
};
struct ipr_dev {
char dev_name[64];
char gen_name[64];
@ -1007,6 +1021,7 @@ struct ipr_dev {
u32 should_init:1;
u32 init_not_allowed:1;
struct scsi_dev_data *scsi_dev_data;
struct ipr_disk_attr attr;
union {
struct ipr_common_record *qac_entry;
struct ipr_dev_record *dev_rcd;
@ -1173,20 +1188,6 @@ struct ipr_scsi_buses {
struct ipr_scsi_bus_attr bus[IPR_MAX_NUM_BUSES];
};
struct ipr_disk_attr {
int queue_depth;
int tcq_enabled;
int format_timeout;
};
struct ipr_vset_attr {
int queue_depth;
};
struct ipr_ioa_attr {
int preferred_primary;
};
struct ipr_dasd_timeout_record {
u8 op_code;
u8 reserved;
@ -1456,8 +1457,8 @@ struct ipr_encl_status_ctl_pg
};
#define for_each_elem_status(i, ses_data) \
for (i = 0; i < ((ntohs((ses_data)->byte_count)-8)/sizeof(struct ipr_drive_elem_status)) \
&& i < IPR_NUM_DRIVE_ELEM_STATUS_ENTRIES; i++)
for (i = 0; i < ((ntohs((ses_data)->byte_count)-8)/sizeof(struct ipr_drive_elem_status)) && \
i < IPR_NUM_DRIVE_ELEM_STATUS_ENTRIES; i++)
int sg_ioctl(int, u8 *, void *, u32, u32, struct sense_data_t *, u32);
int sg_ioctl_noretry(int, u8 *, void *, u32, u32, struct sense_data_t *, u32);
@ -1639,6 +1640,16 @@ static inline void ipr_strncpy_0(char *dest, char *source, int length)
dest[length] = '\0';
}
static inline void ipr_strncpy_0n(char *dest, char *source, int length)
{
char *ch;
memcpy(dest, source, length);
dest[length] = '\0';
ch = strchr(dest, '\n');
if (ch)
*ch = '\0';
}
#define syslog_dbg(...) \
do { \
if (ipr_debug) \
@ -1656,10 +1667,10 @@ if (dev->scsi_dev_data && !dev->ioa->ioa_dead) { \
#define scsi_dbg(dev, fmt, ...) \
do { \
if (dev->scsi_dev_data) { \
syslog_dbg("%d:%d:%d:%d: " fmt, dev->ioa->host_num, \
dev->scsi_dev_data->channel, dev->scsi_dev_data->id, \
dev->scsi_dev_data->lun, ##__VA_ARGS__); \
if ((dev)->scsi_dev_data) { \
syslog_dbg("%d:%d:%d:%d: " fmt, (dev)->ioa->host_num, \
(dev)->scsi_dev_data->channel, (dev)->scsi_dev_data->id, \
(dev)->scsi_dev_data->lun, ##__VA_ARGS__); \
} \
} while (0)

View file

@ -56,6 +56,22 @@ rm -rf $RPM_BUILD_ROOT
%{_sysconfdir}/init.d/*
%changelog
* Wed Aug 17 2005 Brian King <brking@us.ibm.com> 2.0.15.4
- Fix a couple of uninitialized variable compile errors
* Wed Jul 27 2005 Brian King <brking@us.ibm.com> 2.0.15.3
- Fix: iprconfig: IOA microcode update would leave AF DASD
(disks that are in disk arrays) in a state where they were
no longer tagged queueing. Fix iprconfig to run iprinit on the
adapter after a microcode download to ensure all attached devices
are properly setup after a microcode download.
- Fix iprinit: If an IOA was reset for some reason at runtime,
this would cause AF DASD devices to get tagged queueing turned
off and it would never get turned back on. Change iprinit to
detect this and turn tagged queueing back on if this happens.
- Changing the queue depth for a disk array was broken. Fix iprinit
to properly restore the queue depth from the ipr configuration file.
- Fix iprconfig to handle disk format failures better
- Fix potential iprutils segfaults when iterating over disk arrays
* Wed Jun 1 2005 Brian King <brking@us.ibm.com> 2.0.15.1
- Fix iprconfig Analyze Log options
* Wed May 18 2005 Brian King <brking@us.ibm.com> 2.0.15

View file

@ -7,8 +7,8 @@
IPR_MAJOR_RELEASE=2
IPR_MINOR_RELEASE=1
IPR_FIX_LEVEL=0
IPR_RELEASE=dev
IPR_FIX_DATE=(July 20, 2005)
IPR_RELEASE=cvs
IPR_FIX_DATE=(September 23, 2005)
IPR_VERSION_STR=$(IPR_MAJOR_RELEASE).$(IPR_MINOR_RELEASE).$(IPR_FIX_LEVEL) $(IPR_FIX_DATE)