Changes of Revision 3
[-] | Changed | cciss_vol_status.changes |
1
2 ------------------------------------------------------------------- 3 +Sat May 25 11:38:01 UTC 2013 - cs@linux-administrator.com 4 + 5 +- update to release 1.11 6 + 7 +------------------------------------------------------------------- 8 Sun Aug 12 09:37:22 UTC 2012 - cs@linux-administrator.com 9 10 - initial build of version 1.10 11 |
||
[-] | Changed | cciss_vol_status.spec ^ |
8 1
2 Name: cciss_vol_status 3 -Version: 1.10 4 +Version: 1.11 5 Release: 1 6 Summary: Report status of drives on HP Smart Array Controllers 7 Url: http://cciss.sourceforge.net/#cciss_utils 8 |
||
[+] | Changed | cciss_vol_status-1.11.tar.bz2/ChangeLog ^ |
@@ -129,3 +129,14 @@ * Added .gitignore and cvsignore files * regenerated configure, aclocal.m4, and Makefile.in on RHEL6u2. * Made -p shortcut for --persnickety actualy work. + +Changes since 1.10 + + * Added support for new controllers + * Now can report status of nonvolatile cache + * Misc. code cleanup and refactoring + * Do not spin up sleeping spare drives. This is done by using + "extended" CISS_REPORT_LUNS to obtain the device type instead of + sending inquiries to every device returned by standard + CISS_REPORT_LUNS to get the device type. + | ||
[+] | Changed | cciss_vol_status-1.11.tar.bz2/cciss_vol_status.8 ^ |
@@ -1,7 +1,7 @@ -.\" Copyright (C) 2006,2007,2012 Hewlett-Packard Development Company, L.P. +.\" Copyright (C) 2006,2007,2012,2013 Hewlett-Packard Development Company, L.P. .\" .\" -.\" Copyright 2006,2007,2012 Hewlett-Packard Development Company, L.P. +.\" Copyright 2006,2007,2012,2013 Hewlett-Packard Development Company, L.P. .\" .\" Author: Stephen M. Cameron .\" @@ -21,7 +21,7 @@ .\" along with cciss_vol_status; if not, write to the Free Software .\" Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA .\" -.TH CCISS_VOL_STATUS "8" "Aug 2012" "cciss_vol_status (ccissutils) " "" +.TH CCISS_VOL_STATUS "8" "May 2013" "cciss_vol_status (ccissutils) " "" .SH NAME cciss_vol_status \- show status of logical drives attached to HP Smartarray controllers .SH SYNOPSIS @@ -173,16 +173,23 @@ /dev/cciss/c0d0: (Smart Array P800) Enclosure MSA60 (S/N: USP6340B3F) on Bus 2, Physical Port 2E status: OK. - - [root@localhost]# ./cciss_vol_status --verbose /dev/sg0 - Controller: Smart Array P410 - Board ID: 0x3243103c + [root@localhost cciss_vol_status]# ./cciss_vol_status --verbose /dev/sg0 + Controller: Smart Array P420i + Board ID: 0x3354103c Logical drives: 1 - Running firmware: 5.70 - ROM firmware: 5.70 - /dev/sda: (Smart Array P410) RAID 0 Volume 0 status: OK. - Physical drives: 1 - connector 2I box 1 bay 1 HP EG0146FAWHU 6SD1QH2X0000B117LGHR HPDE OK + Running firmware: 3.42 + ROM firmware: 3.42 + /dev/sda: (Smart Array P420i) RAID 1 Volume 0 status: OK. + Physical drives: 2 + connector 1I box 2 bay 1 HP EG1200FCVBQ KZG21NVD HPD1 OK + connector 2I box 2 bay 5 HP EG1200FCVBQ KZG20X7D HPD1 OK + /dev/sg0(Smart Array P420i:0): Non-Volatile Cache status: + Cache configured: Yes + Read cache memory: 81 MiB + Write cache memory: 735 MiB + Write cache enabled: Yes + Flash backed cache present + .DE .fi | ||
[+] | Changed | cciss_vol_status-1.11.tar.bz2/cciss_vol_status.c ^ |
@@ -1,5 +1,5 @@ /* - Copyright (C) 2006,2007 Hewlett-Packard Development Company, L.P. + Copyright (C) 2006,2007,2012,2013 Hewlett-Packard Development Company, L.P. Author: Stephen M. Cameron This file is part of cciss_vol_status. @@ -38,6 +38,17 @@ #include <unistd.h> #endif /* HAVE_UNISTD_H */ +#ifdef HAVE_STDBOOL_H +# include <stdbool.h> +#else +# ifndef HAVE__BOOL +# define _Bool signed char +# endif +# define bool _Bool +# define false 0 +# define true 1 +#endif /* HAVE_STDBOOL_H */ + #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> @@ -84,7 +95,7 @@ #define ID_CTLR 0x11 /* Identify controller */ #define ID_LSTATUS 0x12 /* identify logical drive status */ -int everything_hunky_dory = 1; +bool everything_hunky_dory = true; int persnickety = 0; int be_quiet = 1; int try_unknown_devices = 0; @@ -146,6 +157,21 @@ { 0x3354103C, "Smart Array P420i", 0, 1}, { 0x3355103C, "Smart Array P220i", 0, 1}, { 0x3356103C, "Smart Array P721m", 0, 1}, + { 0x1920103C, "Smart Array", 0, 1}, + { 0x1921103C, "Smart Array", 0, 1}, + { 0x1922103C, "Smart Array", 0, 1}, + { 0x1923103C, "Smart Array", 0, 1}, + { 0x1924103C, "Smart Array", 0, 1}, + { 0x1925103C, "Smart Array", 0, 1}, + { 0x1926103C, "Smart Array", 0, 1}, + { 0x1928103C, "Smart Array", 0, 1}, + { 0x334D103C, "Smart Array P822se", 0, 1}, + { 0x00451590, "Dynamic Smart Array B320i", 0, 1}, + { 0x00471590, "Dynamic Smart Array B320i", 0, 1}, + { 0x00481590, "Dynamic Smart Array B120i", 0, 1}, + { 0x006C1590, "Dynamic Smart Array B120i", 0, 1}, + { 0x00841590, "Dynamic Smart Array B120i", 0, 1}, + #ifdef HAVE_SCSI_SG_H { MSA1000_ID, "MSA1000", 1, 0}, @@ -158,17 +184,19 @@ #define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) #define UNKNOWN_CONTROLLER ARRAYSIZE(smartarray_id) -unsigned long long zero_lun = 0x00ULL; -#define ZEROLUN ((unsigned char *) &zero_lun) +static unsigned char *zero_lun = (unsigned char *) "\0\0\0\0\0\0\0\0"; /* cciss_to_bmic maps cciss logical lun to correspoding (controller_lun, BMIC drive number) tuple via cross referencing inquiry page 0x83 data with BMIC ID logical drive data */ +#define CISS_LUN_ADDR_SIZE 8 +#define MAX_LUNS 1024 /* 1024 should do us for awhile */ + struct cciss_bmic_addr_t { - unsigned char logical_lun[8]; - unsigned char controller_lun[8]; + unsigned char logical_lun[CISS_LUN_ADDR_SIZE]; + unsigned char controller_lun[CISS_LUN_ADDR_SIZE]; unsigned short bmic_drive_number; unsigned char bmic_id_ctlr_data[100]; unsigned char inq_pg_0x83_data[100]; @@ -177,21 +205,21 @@ }; struct bmic_addr_t { - unsigned char controller_lun[8]; + unsigned char controller_lun[CISS_LUN_ADDR_SIZE]; unsigned short bmic_drive_number; int tolerance_type; }; struct cciss_to_bmic_t { int naddrs; - struct cciss_bmic_addr_t addr[1024]; /* 1024 should do us for awhile */ + struct cciss_bmic_addr_t addr[MAX_LUNS]; } cciss_to_bmic; /* List of controllers -- not all controllers in the system, just the internal one (e.g. all zero luns, plus externally attached ones -- like MSA500. */ #define MAX_CONTROLLERS 256 /* this is a ridiculously large number */ -unsigned char controller_lun_list[MAX_CONTROLLERS][8]; +unsigned char controller_lun_list[MAX_CONTROLLERS][CISS_LUN_ADDR_SIZE]; int busses_on_this_ctlr[MAX_CONTROLLERS]; int num_controllers = 0; @@ -260,7 +288,6 @@ unsigned char reserved3[5]; unsigned char marketing_revision; unsigned char controller_flags; - // unsigned char reserved4[2]; unsigned char host_flags; unsigned char expand_disable_code; unsigned char scsi_chip_count; @@ -488,6 +515,83 @@ #define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15 #pragma pack() +#define CISS_READ 0x26 +#define CISS_MAX_CDB_LEN 16 +#define DEVICE_TYPE_RAID 0x0c +#define CISS_REPORT_LOGICAL_LUNS 0xc2 +#define CISS_REPORT_PHYSICAL_LUNS 0xc3 +#define REPORT_LUNS_FLAG_PHYSICAL_NODE_IDS (1 << 0) +#define REPORT_LUNS_FLAG_OTHER_PHYS_DEV_INFO (1 << 1) +#define REPORT_LUNS_EXTENDED_MASK 0x03 +#define REPORT_LUNS_HEADER_SIZE 8 +#define REPORT_LUNS_ENTRY_SIZE(extended) (8 + (extended ? 1 : 0) * 16) +#define EXTENDED_REPORT_LUNS_ENTRY_SIZE REPORT_LUNS_ENTRY_SIZE(true) + +#pragma pack(1) +#define BMIC_SENSE_CACHE_CONFIGURATION 0xc1 +#define SENSE_CACHE_CONFIG_CDB_LEN 10 +struct bmic_transfer_data { + uint8_t memory_address_hi_dir; + uint16_t memory_address_lo; + uint16_t transfer_count; +}; + +struct bmic_cache_configuration { + uint32_t posted_writes_drive_bit_map; + uint16_t mem_for_read_cache; + uint16_t mem_for_write_cache; + uint8_t disable_flag; + uint16_t offset_to_ecu_bitmap; + uint16_t offset_to_ecf_bitmap; + uint16_t offset_to_ercdu_bitmap; + uint8_t reserved1; + uint32_t total_length; + uint16_t max_log_drv_supported; + uint8_t reserved2[10]; + uint32_t status; +#define BMIC_POSTED_WRITE_STATUS_ENABLED (1 << 0) +#define BMIC_POSTED_WRITE_TEMP_DISABLED (1 << 1) +#define BMIC_POSTED_WRITE_PERM_DISABLED (1 << 2) +#define BMIC_POSTED_WRITE_VALID_DATA_ON_RESET_FOUND (1 << 3) +#define BMIC_POSTED_WRITE_POSSIBLE_DATA_LOSS_ON_RESET (1 << 4) + /* bits 5,6 not implemented, 7 is weird */ +#define BMIC_POSTED_WRITE_UNFLUSHED_DIRTY_DATA (1 << 8) +#define BMIC_POSTED_WRITE_DIRTY_DATA_LIMIT_REACHED (1 << 9) +#define BMIC_POSTED_WRITE_ECC_ERRORS_DETECTED (1 << 10) +#define BMIC_POSTED_WRITE_DATA_LOSS_OTHER (1 << 11) +#define BMIC_POSTED_WRITE_AUTO_RECONFIG (1 << 12) +#define BMIC_POSTED_WRITE_REDUNDCTLR_VALID_DATA_FOUND (1 << 13) +#define BMIC_POSTED_WRITE_BATTERY_ENABLE_HW_PROBLEM (1 << 14) +#define BMIC_POSTED_WRITE_CPLD_BBWC_INCOMPATIBILITY (1 << 15) +#define BMIC_POSTED_WRITE_CAPACITOR_ATTACHED (1 << 16) +#define BMIC_POSTED_WRITE_161718_CACHE_DISABLED (1 << 30) + uint16_t disable_code; + uint16_t total_memory_size; + uint16_t battery_count; + uint16_t good_battery_map; + uint16_t parity_read_errors; + uint16_t parity_write_errors; +#define BMIC_XFER_DATA_ERROR_LOG_LENGTH 32 + struct bmic_transfer_data error_log[BMIC_XFER_DATA_ERROR_LOG_LENGTH]; + uint16_t failed_battery_map; + uint8_t daughter_board_attached; + uint32_t cache_failure_map; + uint8_t max_error_log_entries; + uint8_t nvarm_load_status; + uint8_t memory_size_shift_factor; + uint16_t non_battery_backed_memory_size; + uint8_t memory_state; + uint8_t cache_autorev; + uint16_t total_attached_memory; + uint8_t percent_read_cache; + uint8_t percent_write_cache; + uint8_t default_percent_read_cache; + uint8_t default_percent_write_cache; +#define BMIC_CACHE_CONFIG_PAD_TO_512_BYTES 284 + uint8_t reserved[BMIC_CACHE_CONFIG_PAD_TO_512_BYTES]; +}; +#pragma pack() + char *progname = "cciss_vol_status"; void usage() @@ -503,6 +607,13 @@ exit(-1); } +static void set_cdb_buffer_length(unsigned char *cdb, uint16_t buflen) +{ +#define CDBBUFLEN 7 /* buffer length commonly stored at byte 7 in CDB */ + cdb[CDBBUFLEN] = (buflen >> 8) & 0xff; + cdb[CDBBUFLEN + 1] = buflen & 0xff; +} + static void find_bus_target(struct identify_controller *id, int bmic_drive_number, int *bus, int *target) { @@ -638,7 +749,7 @@ { memset(cmd, 0, sizeof(*cmd)); if (lun != NULL) - memcpy(&cmd->LUN_info, lun, 8); + memcpy(&cmd->LUN_info, lun, CISS_LUN_ADDR_SIZE); cmd->Request.CDBLen = cdblen; cmd->Request.Type.Type = TYPE_CMD; cmd->Request.Type.Attribute = ATTR_SIMPLE; @@ -649,44 +760,66 @@ cmd->buf = buf; } -static int do_report_luns(char *filename, int fd, int *count, unsigned char *lun, int physical) +static void print_report_lun_data(char *title, int count_in_bytes, + unsigned char *data, bool extended) +{ + int i; + int lun_count; + int bytes_per_lun; + int lun; + + bytes_per_lun = REPORT_LUNS_ENTRY_SIZE(extended); + + lun_count = count_in_bytes / REPORT_LUNS_ENTRY_SIZE(extended); + + printf("%s (%s)\n", title, extended ? "(extended)" : ""); + printf("bytecount = %d, lun count = %d \n", count_in_bytes, lun_count); + + lun = 0; + for (i = 0; i < count_in_bytes; i++) { + if ((i % bytes_per_lun) == 0) + printf("\n%d: ", lun); + printf("%02x", data[i - REPORT_LUNS_HEADER_SIZE]); + } + printf("\n\n"); +} + +static int do_report_luns(char *filename, int fd, int *count, + unsigned char *lun, int physical, int extended_flags) { IOCTL_Command_struct cmd; int rc; - unsigned char cdb[16]; + unsigned char cdb[CISS_MAX_CDB_LEN]; unsigned int bufsize; char *cmdname; int becount; + bool extended = (extended_flags & REPORT_LUNS_EXTENDED_MASK); - memset(lun, 0, *count * 8); - bufsize = htonl(*count *8); + memset(lun, 0, *count * REPORT_LUNS_ENTRY_SIZE(extended)); + bufsize = htonl(*count * REPORT_LUNS_ENTRY_SIZE(extended)); memset(cdb, 0, 16); - cdb[0] = physical ? 0xc3 : 0xc2; /* report physical/logical LUNs */ + cdb[0] = physical ? CISS_REPORT_PHYSICAL_LUNS : CISS_REPORT_LOGICAL_LUNS; + cdb[1] = extended_flags; memcpy(&cdb[6], &bufsize, 4); - setup_for_ioctl(&cmd, ZEROLUN, cdb, 12, 0, lun, *count * 8); + setup_for_ioctl(&cmd, zero_lun, cdb, 12, 0, lun, *count * 8); rc = ioctl(fd, CCISS_PASSTHRU, &cmd); - cmdname = physical ? "REPORT_PHYSICAL" : "REPORT_LOGICAL"; + + if (physical) + cmdname = extended ? "REPORT_PHYSICAL (extended)" : "REPORT_PHYSICAL"; + else + cmdname = extended ? "REPORT_LOGICAL (extended)" : "REPORT_LOGICAL"; CHECK_IOCTL(filename, cmdname, rc, &cmd, -1); /* macro which may return... */ /* memcpy to avoid possible unaligned access on ia64, */ /* in case lun isn't aligned on a 4 byte boundary */ /* (it is, but, why assume it?). */ memcpy(&becount, lun, sizeof(becount)); - *count = ntohl(becount) / 8; + *count = ntohl(becount) / REPORT_LUNS_ENTRY_SIZE(extended); - if (debug) { - int i; - fprintf(stderr, "%s: %d %s luns:\n\n", filename, *count, physical ? "physical" : "logical"); - for (i = 8; i < (*count+1) * 8; i++) { - if ((i % 8) == 0) - fprintf(stderr, "%d: ", (i-1) / 8); - fprintf(stderr, "%02x", lun[i]); - if (((i+1) % 8) == 0) - fprintf(stderr, "\n"); - } - fprintf(stderr, "\n"); - } + if (debug) + print_report_lun_data(physical ? "Report physical luns" : "Report logical luns", + ntohl(becount), lun, extended); return 0; } @@ -695,15 +828,14 @@ unsigned char *buffer) { IOCTL_Command_struct cmd; - unsigned char cdb[16]; - unsigned short buffer_size = htons(512); /* Always 512 bytes for this cmd */ + unsigned char cdb[CISS_MAX_CDB_LEN]; int rc; memset(cdb, 0, 16); - cdb[0] = 0x26; /* cciss read */ + cdb[0] = CISS_READ; cdb[1] = 0xff & bmic_drive_number; cdb[6] = ID_LOGICAL_DRIVE; - memcpy(&cdb[7], &buffer_size, 2); + set_cdb_buffer_length(cdb, 512); /* Always 512 bytes for this cmd */ cdb[9] = 0xff && (bmic_drive_number >> 8); setup_for_ioctl(&cmd, controller_lun, cdb, 16, 0, buffer, 512); @@ -712,31 +844,52 @@ return 0; } +static int do_sense_cache_configuration(char *filename, int fd, + unsigned char *controller_lun, + struct bmic_cache_configuration *cache_config) +{ + IOCTL_Command_struct cmd; + unsigned char cdb[CISS_MAX_CDB_LEN]; + int rc; + + memset(cdb, 0, 16); + cdb[0] = CISS_READ; + cdb[6] = BMIC_SENSE_CACHE_CONFIGURATION; + set_cdb_buffer_length(cdb, sizeof(*cache_config)); + + setup_for_ioctl(&cmd, controller_lun, cdb, SENSE_CACHE_CONFIG_CDB_LEN, 0, + (unsigned char *) cache_config, + sizeof(*cache_config)); + rc = ioctl(fd, CCISS_PASSTHRU, &cmd); + CHECK_IOCTL(filename, "BMIC_SENSE_CACHE_CONFIGURATION", + rc, &cmd, -1); /* macro which may return... */ + return 0; +} + static int do_bmic_identify_physical_device(char *filename, int fd, unsigned char *controller_lun, int bmic_drive_number, struct identify_physical_device *id_phys_device) { IOCTL_Command_struct cmd; int is_internal_controller; - uint8_t lunzero[8]; - uint16_t buflen_be; + uint8_t lunzero[CISS_LUN_ADDR_SIZE]; int rc; memset(&cmd, 0, sizeof(cmd)); memset(lunzero, 0, sizeof(lunzero)); - is_internal_controller = (memcmp(lunzero, controller_lun, 8) == 0); - buflen_be = htons(sizeof(*id_phys_device)); + is_internal_controller = (memcmp(lunzero, controller_lun, + CISS_LUN_ADDR_SIZE) == 0); memcpy(&cmd.LUN_info, controller_lun, sizeof(cmd.LUN_info)); cmd.Request.CDBLen = 10; - cmd.Request.CDB[0] = 0x26; /* CISS READ */ + cmd.Request.CDB[0] = CISS_READ; if (is_internal_controller) cmd.Request.CDB[2] = bmic_drive_number & 0xff; else cmd.Request.CDB[5] = bmic_drive_number & 0xff; cmd.Request.CDB[6] = BMIC_IDENTIFY_PHYSICAL_DEVICE; cmd.Request.CDB[9] = (bmic_drive_number >> 8) & 0xff; - memcpy(&cmd.Request.CDB[7], &buflen_be, sizeof(buflen_be)); + set_cdb_buffer_length(cmd.Request.CDB, sizeof(*id_phys_device)); cmd.Request.Type.Type = TYPE_CMD; cmd.Request.Type.Attribute = ATTR_SIMPLE; cmd.Request.Type.Direction = XFER_READ; @@ -755,13 +908,12 @@ static int do_sgio_bmic_identify_physical_device(int fd, int bmic_drive_number, struct identify_physical_device *id_phys_device) { - unsigned char cdb[16]; - uint8_t lunzero[8]; - uint16_t buflen_be; + unsigned char cdb[CISS_MAX_CDB_LEN]; + uint8_t lunzero[CISS_LUN_ADDR_SIZE]; memset(lunzero, 0, sizeof(lunzero)); - cdb[0] = 0x26; /* CISS READ */ + cdb[0] = CISS_READ; /* This is tricky. We're supposed to use either byte 2, or byte 5 * for the bmic drive number depending on if the controller is internal @@ -774,8 +926,7 @@ cdb[5] = bmic_drive_number & 0xff; cdb[6] = BMIC_IDENTIFY_PHYSICAL_DEVICE; cdb[9] = (bmic_drive_number >> 8) & 0xff; - buflen_be = htons(sizeof(id_phys_device)); - memcpy(&cdb[7], &buflen_be, sizeof(buflen_be)); + set_cdb_buffer_length(cdb, sizeof(id_phys_device)); return do_sg_io(fd, cdb, 10, (unsigned char *) &id_phys_device, sizeof(id_phys_device), SG_DXFER_FROM_DEV); @@ -786,18 +937,16 @@ static int id_ctlr_fd(char * filename, int fd, unsigned char *lun, struct identify_controller *id) { int rc; - unsigned char cdb[16]; + unsigned char cdb[CISS_MAX_CDB_LEN]; IOCTL_Command_struct cmd; - unsigned short bebufsize; int ctlrtype; memset(id, 0, sizeof(*id)); memset(&cmd, 0, sizeof(cmd)); memset(cdb, 0, 16); - bebufsize = htons(sizeof(*id)); - cdb[0] = 0x26; + cdb[0] = CISS_READ; cdb[6] = ID_CTLR; - memcpy(&cdb[7], &bebufsize, 2); + set_cdb_buffer_length(cdb, sizeof(*id)); setup_for_ioctl(&cmd, lun, cdb, 10, 0, (unsigned char *) id, sizeof(*id)); rc = ioctl(fd, CCISS_PASSTHRU, &cmd); @@ -807,7 +956,7 @@ if (ctlrtype == -1) { fprintf(stderr, "%s: Warning: unknown controller type 0x%08x\n", progname, id->board_id); - everything_hunky_dory = 0; + everything_hunky_dory = false; } else if (ctlrtype == -1 || smartarray_id[ctlrtype].supports_sas) { id->drives_per_scsi_bus = 16; /* bit of a kludge here */ id->scsi_chip_count = 8; @@ -925,7 +1074,7 @@ } if (vs->status != 0) - everything_hunky_dory = 0; + everything_hunky_dory = false; switch (tolerance_type) { case 0: sprintf(raid_level, "RAID 0"); @@ -987,7 +1136,7 @@ } } if (failed_drive_count != 0) { - everything_hunky_dory = 0; + everything_hunky_dory = false; printf(" Total of %d failed physical drives " "detected on this logical drive.\n", failed_drive_count); @@ -1052,7 +1201,7 @@ alarms = bus_param->alarm_data.alarm_status & bus_param->alarm_data.valid_alarm_bits; if (alarms) { - everything_hunky_dory = 0; + everything_hunky_dory = false; status[0] = '\0'; if (alarms & 0x1) { @@ -1189,29 +1338,26 @@ { unsigned char sensebuffer[64]; int direction = SG_DXFER_FROM_DEV; - unsigned char cdb[16]; + unsigned char cdb[CISS_MAX_CDB_LEN]; int cdblen; - unsigned short bufsize; memset(cdb, 0, sizeof(cdb)); memset(sensebuffer, 0, 64); switch (cmd) { case ID_LOGICAL_DRIVE: case ID_LSTATUS: { - bufsize = htons((unsigned short) size); - cdb[0] = 0x26; + cdb[0] = CISS_READ; cdb[1] = log_unit; cdb[6] = cmd; - memcpy(&cdb[7], &bufsize, sizeof(bufsize)); + set_cdb_buffer_length(cdb, size); direction = SG_DXFER_FROM_DEV; cdblen = 10; break; } case ID_CTLR: { /* 0x11 */ - bufsize = htons((unsigned short) size); - cdb[0] = 0x26; + cdb[0] = CISS_READ; cdb[6] = cmd; - memcpy(&cdb[7], &bufsize, sizeof(bufsize)); + set_cdb_buffer_length(cdb, size); direction = SG_DXFER_FROM_DEV; cdblen = 10; break; @@ -1464,7 +1610,7 @@ unsigned char buf_size) { IOCTL_Command_struct cmd; - unsigned char cdb[16]; + unsigned char cdb[CISS_MAX_CDB_LEN]; int status; memset(&cmd, 0, sizeof(cmd)); @@ -1487,6 +1633,21 @@ return 0; } +static void append_internal_controller_lunid_to_extended_report_luns(unsigned char *data, + int *lun_count) +{ + int offset = REPORT_LUNS_HEADER_SIZE + + *lun_count * EXTENDED_REPORT_LUNS_ENTRY_SIZE; + memset(&data[offset], 0, EXTENDED_REPORT_LUNS_ENTRY_SIZE); + data[offset + EXTENDED_REPORT_LUNS_ENTRY_SIZE - 1] = DEVICE_TYPE_RAID; + (*lun_count)++; +} + +static unsigned char get_device_type(unsigned char *extended_report_luns_entry) +{ + return extended_report_luns_entry[EXTENDED_REPORT_LUNS_ENTRY_SIZE - 1]; +} + /***************************************************************** init_cciss_to_bmic() @@ -1559,11 +1720,12 @@ #pragma pack(1) struct identify_logical_drive id_logical_drive_data; #pragma pack() - unsigned long long lunlist[1025]; - int luncount = 1024; - unsigned long long physlunlist[1025]; + uint64_t lunlist[MAX_LUNS + 1]; + int lun_count = MAX_LUNS; + unsigned char physlunlist[(MAX_LUNS + 1) * EXTENDED_REPORT_LUNS_ENTRY_SIZE + + REPORT_LUNS_HEADER_SIZE]; unsigned char buf[256]; - struct bmic_addr_t missed_drive[1025]; + struct bmic_addr_t missed_drive[MAX_LUNS + 1]; int nmissed = 0; int nguessed = 0; int rc; @@ -1576,22 +1738,23 @@ memset(missed_drive, 0, sizeof(missed_drive)); /* Do report LOGICAL LUNs to get a list of all logical drives */ - rc = do_report_luns(file, fd, &luncount, (unsigned char *) lunlist, 0); + rc = do_report_luns(file, fd, &lun_count, (unsigned char *) lunlist, 0, 0); if (rc != 0) { fprintf(stderr, "do_report_luns(logical) failed.\n"); - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } - cciss_to_bmic.naddrs = luncount; + cciss_to_bmic.naddrs = lun_count; /* For each logical drive... */ for (i = 0; i < cciss_to_bmic.naddrs; i++) { - memcpy(cciss_to_bmic.addr[i].logical_lun, &lunlist[i+1], 8); + memcpy(cciss_to_bmic.addr[i].logical_lun, &lunlist[i+1], + CISS_LUN_ADDR_SIZE); if (debug) { unsigned char *x = (unsigned char *) &lunlist[i+1]; fprintf(stderr, "%d: ", i); - for (j = 0; j < 8; j++) + for (j = 0; j < CISS_LUN_ADDR_SIZE; j++) fprintf(stderr, "%02x", x[j]); fprintf(stderr, "\n"); } @@ -1610,56 +1773,41 @@ } /* Get a list of physical luns... we're looking for RAID controller devices */ - luncount = 1024; - rc = do_report_luns(file, fd, &luncount, (unsigned char *) physlunlist, 1); + lun_count = MAX_LUNS; + rc = do_report_luns(file, fd, &lun_count, physlunlist, 1, + REPORT_LUNS_FLAG_OTHER_PHYS_DEV_INFO); if (rc != 0) { fprintf(stderr, "%s: do_report_physical failed.\n", progname); - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } /* Add the PCI host controller itself to this list... */ - /* Careful, first 8 bytes of physlunlist are a count, not lun */ - memcpy(&physlunlist[luncount+1], ZEROLUN, 8); - luncount++; + append_internal_controller_lunid_to_extended_report_luns(physlunlist, &lun_count); + memset(controller_lun_list[0], 0, 8); num_controllers = 0; - for (i = 0;i < luncount;i++) { /* For each physical LUN... */ + for (i = 0; i < lun_count; i++) { /* For each physical LUN... */ struct identify_controller id_ctlr_data; int max_possible_drives = 0; + int byteoffset = REPORT_LUNS_HEADER_SIZE + + i * EXTENDED_REPORT_LUNS_ENTRY_SIZE; + unsigned char *this_lun_data = &physlunlist[byteoffset]; - /* Get the standard inquiry page, so we can look at the device type */ - memset(buf, 0, 100); - rc = do_cciss_inquiry(file, fd, (unsigned char *) &physlunlist[i+1], 0, buf, 100); - if (rc != 0) { - if (debug) - fprintf(stderr, "Inquiry to phys device %d failed.\n", i); - /* Some devices won't respond well to inquiry, this is expected, if hokey. */ - continue; - } - - /* If it's not a RAID controller, skip it. */ - if ((buf[0] & 0x0f) != 0x0C) { /* devicetype != RAID_CONTROLLER */ + /* If the device type is not RAID CONTROLLER, skip this device. */ + if (get_device_type(this_lun_data) != DEVICE_TYPE_RAID) { if (debug) fprintf(stderr, "Not a RAID controller, skipping.\n"); continue; } - if (debug) { - int m; - fprintf(stderr, "Querying RAID controller: "); - for (m = 16; m < 36; m++) - fprintf(stderr, "%c", buf[m]); - fprintf(stderr,"\n"); - } - /* Issue IDENTIFY_PHYSICAL_CONTROLLER to get number of logical drives */ /* possible and present on this particular controller */ memset(&id_ctlr_data, 0, sizeof(id_ctlr_data)); - rc = id_ctlr_fd(file, fd, (unsigned char *) &physlunlist[i+1], &id_ctlr_data); + rc = id_ctlr_fd(file, fd, this_lun_data, &id_ctlr_data); if (rc != 0) { fprintf(stderr, "%s: do_id_ctlr on lun %d failed.\n", progname, i); continue; @@ -1679,7 +1827,8 @@ } /* Record this controller for later checking of fan/power/temp status */ - memcpy(controller_lun_list[num_controllers], (unsigned char *) &physlunlist[i+1], 8); + memcpy(controller_lun_list[num_controllers], this_lun_data, + CISS_LUN_ADDR_SIZE); busses_on_this_ctlr[num_controllers] = id_ctlr_data.scsi_chip_count; /* For SAS controllers, there's a different way to figure "busses" @@ -1723,12 +1872,11 @@ /* For each possible logical drive on this raid controller... */ for (j = 0; j < max_possible_drives; j++) { - unsigned char *lundata = (unsigned char *) &physlunlist[i+1]; /* Issue BMIC IDENTIFY_LOGICAL_DRIVE cmd to get unique identifier */ memset(&id_logical_drive_data, 0, sizeof(id_logical_drive_data)); rc = do_bmic_id_logical_drive(file, fd, - lundata, j, (unsigned char *) &id_logical_drive_data); + this_lun_data, j, (unsigned char *) &id_logical_drive_data); if (rc != 0) { fprintf(stderr, "%s: do_bmic_id_logical_drive failed for drive %d\n", progname, j); @@ -1746,8 +1894,10 @@ if (debug) { fprintf(stderr, "Logical drive 0x%02x%02x%02x%02x%02x%02x%02x%02x:%d has unique id: 0x", - lundata[0], lundata[1], lundata[2], lundata[3], - lundata[4], lundata[5], lundata[6], lundata[7], j); + this_lun_data[0], this_lun_data[1], + this_lun_data[2], this_lun_data[3], + this_lun_data[4], this_lun_data[5], + this_lun_data[6], this_lun_data[7], j); for (m = 0; m < 16; m++) fprintf(stderr, "%02x", id_logical_drive_data.unique_volume_id[m]); fprintf(stderr, "\nSearching....\n"); @@ -1773,7 +1923,8 @@ if (debug) fprintf(stderr, "Found!, k = %d\n", k); cciss_to_bmic.addr[k].bmic_drive_number = j; - memcpy(cciss_to_bmic.addr[k].controller_lun, &physlunlist[i+1], 8); + memcpy(cciss_to_bmic.addr[k].controller_lun, + this_lun_data, CISS_LUN_ADDR_SIZE); memcpy(cciss_to_bmic.addr[k].bmic_id_ctlr_data, id_logical_drive_data.unique_volume_id, 16); cciss_to_bmic.addr[k].tolerance_type = @@ -1785,7 +1936,8 @@ if (k == cciss_to_bmic.naddrs) { if (debug) fprintf(stderr, "Didn't find %d here. Adding to missed drive list as bmic drive %d\n", i, j); - memcpy(missed_drive[nmissed].controller_lun, &physlunlist[i+1], 8); + memcpy(missed_drive[nmissed].controller_lun, + this_lun_data, CISS_LUN_ADDR_SIZE); missed_drive[nmissed].bmic_drive_number = j; missed_drive[nmissed].tolerance_type = id_logical_drive_data.tolerance_type; nmissed++; @@ -1862,19 +2014,18 @@ sense_bus_param *bus_param) { memset(c, 0, sizeof(*c)); - memcpy(&c->LUN_info, lunaddr, 8); + memcpy(&c->LUN_info, lunaddr, CISS_LUN_ADDR_SIZE); c->Request.CDBLen = 10; c->Request.Type.Type = TYPE_CMD; c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_READ; c->Request.Timeout = 0; - c->Request.CDB[0] = 0x26; /* 0x26 means "CCISS READ" */ + c->Request.CDB[0] = CISS_READ; c->Request.CDB[1] = 0; /* logical drive id? */ c->Request.CDB[5] = bus; /* bus id */ c->Request.CDB[6] = SENSE_BUS_PARAM; c->buf_size = sizeof(*bus_param); - c->Request.CDB[7] = (c->buf_size >> 8) & 0xff; - c->Request.CDB[8] = c->buf_size & 0xff; + set_cdb_buffer_length(c->Request.CDB, c->buf_size); c->buf = (unsigned char *) bus_param; } @@ -1914,7 +2065,7 @@ fprintf(stderr, "%s: %s: ioctl: controller: %d bus: %d %s\n", progname, file, ctlr, bus, strerror(errno)); /* This really should not ever happen. */ - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } @@ -1929,7 +2080,7 @@ fprintf(stderr, "Error getting status for %s " "controller: %d bus: %d: Commandstatus is %d\n", file, ctlr, bus, c.error_info.CommandStatus); - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } if (debug) @@ -1955,6 +2106,236 @@ } } +static char *cache_disable_info[] = { + /* 0 */ + "Temporary disable condition. Data was found in posted\n" + "write memory, but the configuration signature in the\n" + "posted write memory does not match the one stored in\n" + "the configuration data stored on the drives. Therefore\n" + "the data cannot be written to the drives. This disable\n" + "condition is also reported if the controller firmware is\n" + "replaced with one that is incompatible with the format of\n" + "data found in the posted write memory.\n\n", + + /* 1 */ + "Temporary disable condition. Posted write operations have\n" + "been disabled due to the fact that less than 75% of the\n" + "battery packs are at the sufficient voltage level.\n", + + /* 2 */ + "Temporary disable condition. Posted write operations were\n" + "disabled by the user.\n", + + /* 3 */ + "Temporary disable condition. The adapter does not currently\n" + "have sufficient resources to perform posted write operations.\n" + "(e.g. drive rebuild operations are occurring, etc.)\n", + + /* 4 */ + "Temporary disable condition: The array accelerator board is\n" + "not attached.\n", + + /* 5 */ + "Temporary disable condition: The array accelerator memory is\n" + "in use by an Expand operation that is queued up or in progress.\n", + + /* 6 */ + "Temporary disable condition: The array accelerator memory is\n" + "in use by a Snapshot operation that is queued up or in progress.\n", + /* 7 */ + "Temporary disable condition: The batteries on the redundant\n" + "controller are not at a sufficient charge level to support\n" + "reliable posting of write data.\n", + /* 8 */ + "Temporary disable condition: A cache size mismatch exists\n" + "between the two controllers in a redundant environment.\n", + /* 9 */ + "Temporary disable condition: A cache failure has been detected\n" + "by the other controller in a redundant environment.\n", + /* 10 */ + "Temporary disable condition: The cache has been disabled to\n" + "penalize the user who has an RAID ADG volume configured but the\n" + "ADG Enabler Dongle is broken or missing.\n", + /* 11 */ + "Temporary disable condition: The cache has been disabled because\n" + "SA 6400 EM Controller is configured as boot controller. This is\n" + "not a recommended configuration. User is advised to migrate the\n" + "boot volume to SA 6400 Controller and configure it as boot\n" + "controller.\n", + /* 12 */ + "Temporary disable condition: The posted write cache has been\n" + "disabled in a flash-backed write cache module because the\n" + "capacitor charge is low.\n", + /* 13 */ + "Temporary disable condition: The posted write cache has been\n" + "disabled in a flash-backed write cache module because its\n" + "flash memory is being erased.\n", + /* 14 */ + "", /* unused code */ + /* 15 */ + "", /* unused code */ + /* 16 */ + "Permanent disable condition. Data was found at reset\n" + "initialization in the posted write memory, however, the\n" + "mirror data compare test failed resulting in that data being\n" + "marked as invalid. This is a possible data loss circumstance.\n" + "This disable condition only occurs on controllers with\n" + "mirrored cache RAM (very very old controllers). You won’t see\n" + "this with any remotely recent controller.\n", + /* 17 */ + "Permanent disable condition. Unrecoverable error reading data\n" + "from the cache. For mirrored caches, (very very old controllers)\n" + "this means that read parity errors were detected on both sides\n" + "of the mirror. For ECC protected caches, (non-ancient hardware)\n" + "this means an unrecoverable ECC read error occurred. This is a\n" + "definite data loss circumstance.\n", + /* 18 */ + "Permanent disable condition. Data could not be written to the\n" + "cache memory. This typically means that a parity error was\n" + "detected while writing data to the cache. This could be caused\n" + "by such things as an incomplete connection between the cache card\n" + "and the controller. This is not a data loss circumstance.\n", + /* 19 */ + "Permanent disable condition: Configuration changes were made but\n" + "cache configuration was not updated. (Note: This condition will\n" + "not occur except on very very old controllers.)\n", +}; + +static void decode_cache_disable_code(unsigned short disable_code) +{ + +#define CACHE_DECODE_INDENT " " + + if (disable_code >= ARRAYSIZE(cache_disable_info)) { + printf(CACHE_DECODE_INDENT + "Unknown cache disable code: %d\n", disable_code); + return; + } + + if (strcmp(cache_disable_info[disable_code], "") == 0) { /* unused code */ + printf(CACHE_DECODE_INDENT + "Unknown cache disable code: %d\n", disable_code); + return; + } + + printf(CACHE_DECODE_INDENT "%s", cache_disable_info[disable_code]); +} + +static void print_cache_config_status(struct bmic_cache_configuration *cache_config, + uint32_t cache_config_status_bit, + char *message) +{ + if (!(cache_config->status & cache_config_status_bit)) + return; + printf(" %s\n", message); + + /* special case for write cache disabled, have to decode why */ + if (cache_config_status_bit & (BMIC_POSTED_WRITE_TEMP_DISABLED | + BMIC_POSTED_WRITE_PERM_DISABLED)) + decode_cache_disable_code(cache_config->disable_code); +} + +static void check_one_nonvolatile_cache_status(char *file, int ctlrtype, + int instance, struct bmic_cache_configuration *cache_config) +{ + uint32_t trouble = + BMIC_POSTED_WRITE_TEMP_DISABLED | + BMIC_POSTED_WRITE_PERM_DISABLED | + BMIC_POSTED_WRITE_POSSIBLE_DATA_LOSS_ON_RESET | + BMIC_POSTED_WRITE_UNFLUSHED_DIRTY_DATA | + BMIC_POSTED_WRITE_DIRTY_DATA_LIMIT_REACHED | + BMIC_POSTED_WRITE_ECC_ERRORS_DETECTED | + BMIC_POSTED_WRITE_DATA_LOSS_OTHER | + BMIC_POSTED_WRITE_BATTERY_ENABLE_HW_PROBLEM | + BMIC_POSTED_WRITE_CPLD_BBWC_INCOMPATIBILITY; + + /* I'm not going to worry about trying to report + * whether cache is enabled or disabled for individual logical + * drives, instead will concentrate on the health of the cache + * module + */ + + if (!(trouble & cache_config->status)) { + if (!verbose) + return; /* Cache is ok. */ + } else { + everything_hunky_dory = false; + } + + printf("%s(%s:%d): Non-Volatile Cache status:\n", + file, smartarray_id[ctlrtype].board_name, instance); + + /* For *very* old controllers, these values are KiB, not MiB. */ + printf("%35s: %s\n", "Cache configured", + cache_config->disable_flag == 0 ? "Yes" : "No"); + if (cache_config->disable_flag) + return; + + printf("%35s: %hu MiB\n", "Read cache memory", cache_config->mem_for_read_cache); + printf("%35s: %hu MiB\n", "Write cache memory", cache_config->mem_for_write_cache); + printf("%35s: %s\n", "Write cache enabled", + (cache_config->status & BMIC_POSTED_WRITE_STATUS_ENABLED) ? "Yes" : "No"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_TEMP_DISABLED, + "Write cache temporarily disabled"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_PERM_DISABLED, + "Write Cache permanently disabled"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_POSSIBLE_DATA_LOSS_ON_RESET, + "Possible data loss on last reset"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_UNFLUSHED_DIRTY_DATA, + "Cache contains unflushed data:"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_DIRTY_DATA_LIMIT_REACHED, + "Cache dirty limit reached"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_ECC_ERRORS_DETECTED, + "Excessive ECC errors detected:"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_DATA_LOSS_OTHER, + "Non power related data loss"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_AUTO_RECONFIG, + "Auto-reconfigured on last reset"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_REDUNDCTLR_VALID_DATA_FOUND, + "Redundant controller data flushed on reset"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_BATTERY_ENABLE_HW_PROBLEM, + "HW problem with battery enable"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_CPLD_BBWC_INCOMPATIBILITY, + "CPLD battery backed write cache incompatibility"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_CAPACITOR_ATTACHED, + "Flash backed cache present"); + print_cache_config_status(cache_config, + BMIC_POSTED_WRITE_161718_CACHE_DISABLED, + "Permanent disable condition detected"); +} + +static void check_nonvolatile_cache_status(char *file, int ctlrtype, + int fd, int num_controllers) +{ + int i; + + for (i = 0; i < num_controllers; i++) { + struct bmic_cache_configuration cache_config; + + memset(&cache_config, 0, sizeof(cache_config)); + if (do_sense_cache_configuration(file, fd, controller_lun_list[i], + &cache_config) != 0) { + everything_hunky_dory = false; + fprintf(stderr, "%s:%s(%d): cannot get non-volatile " + "cache configuration\n", progname, file, i); + continue; + } + check_one_nonvolatile_cache_status(file, ctlrtype, i, &cache_config); + } +} + static int msa1000_status(char *file, int fd) { int i, rc, numluns; @@ -1965,7 +2346,7 @@ fprintf(stderr, "%s: %s: Can't identify controller, id = 0x%08x.\n", progname, file, id.board_id); if (persnickety) - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } numluns = id.num_logical_drives; @@ -1988,7 +2369,7 @@ fprintf(stderr, "%s: cannot stat %s: %s\n", progname, file, strerror(errno)); if (persnickety) - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } @@ -2004,7 +2385,7 @@ fprintf(stderr, "%s: %s is not a %s device.\n", progname, file, WANTED_DEVICE_TYPE_STRING); if (persnickety) - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } return 0; @@ -2021,18 +2402,18 @@ /* Construct command to get logical drive status */ memset(&c, 0, sizeof(c)); memset(&ldstatus, 0, sizeof(ldstatus)); - memcpy(&c.LUN_info, cciss_to_bmic.addr[volume_number].controller_lun, 8); + memcpy(&c.LUN_info, cciss_to_bmic.addr[volume_number].controller_lun, + CISS_LUN_ADDR_SIZE); c.Request.CDBLen = 10; c.Request.Type.Type = TYPE_CMD; c.Request.Type.Attribute = ATTR_SIMPLE; c.Request.Type.Direction = XFER_READ; c.Request.Timeout = 0; - c.Request.CDB[0] = 0x26; /* 0x26 means "CCISS READ" */ + c.Request.CDB[0] = CISS_READ; c.Request.CDB[1] = cciss_to_bmic.addr[volume_number].bmic_drive_number & 0xff; c.Request.CDB[6] = ID_LSTATUS; c.buf_size = sizeof(ldstatus); - c.Request.CDB[7] = (c.buf_size >> 8) & 0xff; - c.Request.CDB[8] = c.buf_size & 0xff; + set_cdb_buffer_length(c.Request.CDB, c.buf_size); c.Request.CDB[9] = (cciss_to_bmic.addr[volume_number].bmic_drive_number >> 8) & 0x0ff; c.buf = (unsigned char *) &ldstatus; @@ -2044,14 +2425,14 @@ fprintf(stderr, "%s: %s: ioctl: logical drive: %d %s\n", progname, file, volume_number, strerror(errno)); /* This really should not ever happen. */ - everything_hunky_dory = 0; + everything_hunky_dory = false; return; } if (c.error_info.CommandStatus != 0) { fprintf(stderr, "Error getting status for %s " "volume %d: Commandstatus is %d\n", file, volume_number, c.error_info.CommandStatus); - everything_hunky_dory = 0; + everything_hunky_dory = false; return; } else { if (debug) @@ -2140,7 +2521,7 @@ controller_lun[0], controller_lun[1], controller_lun[2], controller_lun[3], controller_lun[4], controller_lun[5], controller_lun[6], controller_lun[7], bmic_drive_number); - everything_hunky_dory = 0; + everything_hunky_dory = false; return; } @@ -2155,7 +2536,7 @@ if (!(device_data.more_physical_drive_flags & 0x04)) /* S.M.A.R.T enabled? */ goto print_data; if (device_data.more_physical_drive_flags & 0x02) { /* S.M.A.R.T. predictive failure bit set? */ - everything_hunky_dory = 0; + everything_hunky_dory = false; sprintf(status, "S.M.A.R.T. predictive failure."); } print_data: @@ -2177,7 +2558,7 @@ file, controller_lun[0], controller_lun[1], controller_lun[2], controller_lun[3], controller_lun[4], controller_lun[5], controller_lun[6], controller_lun[7]); - everything_hunky_dory = 0; + everything_hunky_dory = false; return; } @@ -2234,7 +2615,7 @@ fprintf(stderr, "%s: open %s: %s\n", progname, file, strerror(errno)); if (persnickety) - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } @@ -2250,7 +2631,7 @@ if (!is_smartarray_driver(fd)) { fprintf(stderr, "%s: %s: Unknown SCSI device.\n", progname, file); if (persnickety) - everything_hunky_dory = 0; + everything_hunky_dory = false; close(fd); return -1; } @@ -2260,10 +2641,10 @@ return -1; /* See if it's a smartarray of some kind... */ - rc = id_ctlr_fd(file, fd, ZEROLUN, &id); + rc = id_ctlr_fd(file, fd, zero_lun, &id); if (rc < 0) { if (persnickety) - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } @@ -2273,7 +2654,7 @@ fprintf(stderr, "%s: %s: Unknown controller, board_id = 0x%08x\n", progname, file, id.board_id); if (persnickety) - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } @@ -2284,7 +2665,7 @@ if (rc != 0) { fprintf(stderr, "%s: Internal error, could not construct CISS to BMIC mapping.\n", progname); - everything_hunky_dory = 0; + everything_hunky_dory = false; return -1; } @@ -2295,6 +2676,7 @@ /* Check the fan/power/temp status of each controller */ check_fan_power_temp(file, ctlrtype, fd, num_controllers); + check_nonvolatile_cache_status(file, ctlrtype, fd, num_controllers); close(fd); return 0; } @@ -2378,6 +2760,6 @@ for (i = optind; i < argc; i++) cciss_status(argv[i]); free_device_node_cache(); - exit((everything_hunky_dory != 1)); + exit(!everything_hunky_dory); } | ||
[+] | Changed | cciss_vol_status-1.11.tar.bz2/config.h.in ^ |
@@ -34,6 +34,9 @@ /* 1 if Linux SCSI Generic header file present */ #undef HAVE_SCSI_SG_H +/* Define to 1 if stdbool.h conforms to C99. */ +#undef HAVE_STDBOOL_H + /* Define to 1 if you have the <stdint.h> header file. */ #undef HAVE_STDINT_H @@ -64,6 +67,9 @@ /* Define to 1 if you have the <unistd.h> header file. */ #undef HAVE_UNISTD_H +/* Define to 1 if the system has the type `_Bool'. */ +#undef HAVE__BOOL + /* Name of package */ #undef PACKAGE | ||
[+] | Changed | cciss_vol_status-1.11.tar.bz2/configure ^ |
@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.63 for cciss_vol_status 1.10. +# Generated by GNU Autoconf 2.63 for cciss_vol_status 1.11. # # Report bugs to <smcameron@users.sourceforge.net>. # @@ -596,8 +596,8 @@ # Identity of this package. PACKAGE_NAME='cciss_vol_status' PACKAGE_TARNAME='cciss_vol_status' -PACKAGE_VERSION='1.10' -PACKAGE_STRING='cciss_vol_status 1.10' +PACKAGE_VERSION='1.11' +PACKAGE_STRING='cciss_vol_status 1.11' PACKAGE_BUGREPORT='smcameron@users.sourceforge.net' ac_unique_file="cciss_vol_status.c" @@ -1286,7 +1286,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures cciss_vol_status 1.10 to adapt to many kinds of systems. +\`configure' configures cciss_vol_status 1.11 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1353,7 +1353,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of cciss_vol_status 1.10:";; + short | recursive ) echo "Configuration of cciss_vol_status 1.11:";; esac cat <<\_ACEOF @@ -1440,7 +1440,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -cciss_vol_status configure 1.10 +cciss_vol_status configure 1.11 generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1454,7 +1454,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by cciss_vol_status $as_me 1.10, which was +It was created by cciss_vol_status $as_me 1.11, which was generated by GNU Autoconf 2.63. Invocation command line was $ $0 $@ @@ -2307,7 +2307,7 @@ # Define the identity of the package. PACKAGE='cciss_vol_status' - VERSION='1.10' + VERSION='1.11' cat >>confdefs.h <<_ACEOF @@ -4097,6 +4097,236 @@ done +{ $as_echo "$as_me:$LINENO: checking for stdbool.h that conforms to C99" >&5 +$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; } +if test "${ac_cv_header_stdbool_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include <stdbool.h> +#ifndef bool + "error: bool is not defined" +#endif +#ifndef false + "error: false is not defined" +#endif +#if false + "error: false is not 0" +#endif +#ifndef true + "error: true is not defined" +#endif +#if true != 1 + "error: true is not 1" +#endif +#ifndef __bool_true_false_are_defined + "error: __bool_true_false_are_defined is not defined" +#endif + + struct s { _Bool s: 1; _Bool t; } s; + + char a[true == 1 ? 1 : -1]; + char b[false == 0 ? 1 : -1]; + char c[__bool_true_false_are_defined == 1 ? 1 : -1]; + char d[(bool) 0.5 == true ? 1 : -1]; + bool e = &s; + char f[(_Bool) 0.0 == false ? 1 : -1]; + char g[true]; + char h[sizeof (_Bool)]; + char i[sizeof s.t]; + enum { j = false, k = true, l = false * true, m = true * 256 }; + /* The following fails for + HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */ + _Bool n[m]; + char o[sizeof n == m * sizeof n[0] ? 1 : -1]; + char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1]; +# if defined __xlc__ || defined __GNUC__ + /* Catch a bug in IBM AIX xlc compiler version 6.0.0.0 + reported by James Lemley on 2005-10-05; see + http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html + This test is not quite right, since xlc is allowed to + reject this program, as the initializer for xlcbug is + not one of the forms that C requires support for. + However, doing the test right would require a runtime + test, and that would make cross-compilation harder. + Let us hope that IBM fixes the xlc bug, and also adds + support for this kind of constant expression. In the + meantime, this test will reject xlc, which is OK, since + our stdbool.h substitute should suffice. We also test + this with GCC, where it should work, to detect more + quickly whether someone messes up the test in the + future. */ + char digs[] = "0123456789"; + int xlcbug = 1 / (&(digs + 5)[-2 + (bool) 1] == &digs[4] ? 1 : -1); +# endif + /* Catch a bug in an HP-UX C compiler. See + http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html + http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html + */ + _Bool q = true; + _Bool *pq = &q; + +int +main () +{ + + *pq |= q; + *pq |= ! q; + /* Refer to every declared value, to avoid compiler optimizations. */ + return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l + + !m + !n + !o + !p + !q + !pq); + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdbool_h=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdbool_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdbool_h" >&5 +$as_echo "$ac_cv_header_stdbool_h" >&6; } +{ $as_echo "$as_me:$LINENO: checking for _Bool" >&5 +$as_echo_n "checking for _Bool... " >&6; } +if test "${ac_cv_type__Bool+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_type__Bool=no +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof (_Bool)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((_Bool))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_type__Bool=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type__Bool" >&5 +$as_echo "$ac_cv_type__Bool" >&6; } +if test "x$ac_cv_type__Bool" = x""yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE__BOOL 1 +_ACEOF + + +fi + +if test $ac_cv_header_stdbool_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_STDBOOL_H 1 +_ACEOF + +fi + @@ -5946,7 +6176,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by cciss_vol_status $as_me 1.10, which was +This file was extended by cciss_vol_status $as_me 1.11, which was generated by GNU Autoconf 2.63. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -6009,7 +6239,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ -cciss_vol_status config.status 1.10 +cciss_vol_status config.status 1.11 configured by $0, generated by GNU Autoconf 2.63, with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" | ||
[+] | Changed | cciss_vol_status-1.11.tar.bz2/configure.ac ^ |
@@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.59) -AC_INIT(cciss_vol_status, 1.10, smcameron@users.sourceforge.net) +AC_INIT(cciss_vol_status, 1.11, smcameron@users.sourceforge.net) AC_CONFIG_SRCDIR([cciss_vol_status.c]) AC_CONFIG_HEADER([config.h]) @@ -14,6 +14,7 @@ # Checks for header files. AC_HEADER_STDC +AC_HEADER_STDBOOL AC_CHECK_HEADERS([errno.h fcntl.h inttypes.h netinet/in.h stdlib.h string.h sys/ioctl.h unistd.h]) AC_CHECK_HEADER(scsi/sg.h, AC_DEFINE([HAVE_SCSI_SG_H], 1, [1 if Linux SCSI Generic header file present]), AC_MSG_WARN([scsi/sg.h not found so MSA1000 support will not be compiled.])) AC_CHECK_HEADER(scsi/scsi.h, AC_DEFINE([HAVE_SCSI_SCSI_H], 1, [1 if Linux SCSI header file present])) |