diff -Nur mpt-status-1.1.6/doc/Changelog mpt-status-1.2.0-RC4/doc/Changelog --- mpt-status-1.1.6/doc/Changelog 2006-03-06 19:21:22.000000000 +0100 +++ mpt-status-1.2.0-RC4/doc/Changelog 2006-04-21 00:08:15.000000000 +0200 @@ -1,7 +1,34 @@ +2006-04-20, ratz [ratz@drugphish.ch]: + o mpt-status.c + - reworked physical disk section + - integrated the exit status patch submitted by Leandro Santi + +2006-04-16, ratz [ratz@drugphish.ch]: + o mpt-status.c + - merged Steffen Joeris patch to support integrating mpt-status + into the KFreeBSD project. + +2006-03-09, ratz [ratz@drugphish.ch]: + o mpt-status.c + - Martin Hamant reported an issue regarding the IOC unit, which + did not work for more than 1 controler. Fix it, by setting + ioc_unit as part of the address unit passed over to readpage. + 2006-03-06, ratz [ratz@drugphish.ch]: - * Version: 1.1.6 [released] (Codename: Brown Paper Bag I) o mpt-status.c - - commented out SGE pointer debug information + - removed SGE debugging lines + - added checkForLibraryMode() which reads the __MPT_STATUS_LIB + environment variable and if set will initialise the library + functionality of mpt-status. + - changed the output to please Martin Hamant and to also ease + up the scriptability. + +2006-03-05, ratz [ratz@drugphish.ch]: + o doc/Changelog + - fixed overly long line + o mpt-status.c + - added human readable output for IM, IME, IS, which is nothing + else than RAID0, RAID1E and RAID1. 2006-03-04, ratz [ratz@drugphish.ch]: * Version: 1.1.5 [released] (Codename: Sebnem) @@ -38,7 +65,8 @@ o mpt-status.{ch} - s/log_id/vol_id/ in the first line if -s is submitted - added --probe_id which will probe for the first scsi id - - fixed a long standing bug resulting in a coredump when using the -d parameter + - fixed a long standing bug resulting in a coredump when using + the -d parameter - moved print_status_only, id_of_primary_device, ioc_unit into global context, so there is no need to pass those variables through the stack all the time diff -Nur mpt-status-1.1.6/doc/DeveloperNotes mpt-status-1.2.0-RC4/doc/DeveloperNotes --- mpt-status-1.1.6/doc/DeveloperNotes 2006-02-12 20:04:09.000000000 +0100 +++ mpt-status-1.2.0-RC4/doc/DeveloperNotes 2006-04-17 23:55:01.000000000 +0200 @@ -1,3 +1,9 @@ +Regarding 64bit +--------------- + +http://www-128.ibm.com/developerworks/linux/library/l-port64.html + + From the OpenBSD mpt(4) man page: The LSI Logic SCSI and Fibre Channel controllers contain firmware that diff -Nur mpt-status-1.1.6/doc/ReleaseNotes mpt-status-1.2.0-RC4/doc/ReleaseNotes --- mpt-status-1.1.6/doc/ReleaseNotes 2006-03-06 19:23:32.000000000 +0100 +++ mpt-status-1.2.0-RC4/doc/ReleaseNotes 2006-03-06 20:33:55.000000000 +0100 @@ -1,6 +1,6 @@ -Release Notes mpt-status 1.1.6 (2006-03-06) +Release Notes mpt-status 1.2.0 (2006-mm-dd) ============================== -Codename: Brown Paper Bag I +Codename: About ----- @@ -29,26 +29,15 @@ General Information ------------------- -This release brings you following fixes and new things: -o Removed debugging statements in the normal output -Please skip version 1.1.5! +Problems +-------- Upgrade ------- -No problems are expected when upgrading from the previous (1.1.4) version. Outlook ------- -The next version will bring 64bit support and based on this, sanitized kernel -headers. SuSE and Debian folks have already started this, however only for a -limited range of machine types. Another thing that will be worked on is the -much requested report of the spare disk and a /proc/mdstat like percentage -output to completion of the synchronisation process. - -The next version will probably also break your scripts, because the output -format will slightely be changed to make more sense. This is a heads-up for the -distro maintainters. diff -Nur mpt-status-1.1.6/doc/THANKS mpt-status-1.2.0-RC4/doc/THANKS --- mpt-status-1.1.6/doc/THANKS 2006-03-04 15:45:47.000000000 +0100 +++ mpt-status-1.2.0-RC4/doc/THANKS 2006-04-21 00:08:45.000000000 +0200 @@ -1,5 +1,5 @@ This file is to thank all the contributors of this software. There is no -specific order or preference, it's a silly little tool anyway ;). +specific order or preference, it's only a little tool anyway ;). Klaus Ade Johnstad: - Offered me remote access to hardware to develop and @@ -14,10 +14,12 @@ helps distro packagers. Jimmy Stewpot: - Generously offered my access to his hardware so I could develop and test the auto-probing feature. -Max Shaposhnikov - Has given me 2 months access to his Opteron system +Max Shaposhnikov: - Has given me 2 months access to his Opteron system and was very helpful when I rendered his system unusable. Hopefully I get the 64bit stuff working on his nodes. +Steffen Joeris: - Support for the KFreeBSD project +Leandro Santi: - Added support for meaningful exit status If I have forgotten you, please drop me an email and I will add you to this diff -Nur mpt-status-1.1.6/incl/mpt-sanitized.h mpt-status-1.2.0-RC4/incl/mpt-sanitized.h --- mpt-status-1.1.6/incl/mpt-sanitized.h 1970-01-01 01:00:00.000000000 +0100 +++ mpt-status-1.2.0-RC4/incl/mpt-sanitized.h 2006-04-20 22:58:48.000000000 +0200 @@ -0,0 +1,198 @@ +#define MPI_FUNCTION_CONFIG (0x04) +#define MPI_CONFIG_ACTION_PAGE_HEADER (0x00) +#define MPI_CONFIG_PAGETYPE_RAID_VOLUME (0x08) +#define MPI_CONFIG_ACTION_PAGE_READ_CURRENT (0x01) +#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x01) +#define MPI_RAIDVOL0_STATUS_FLAG_ENABLED (0x01) +#define MPI_RAIDVOL0_STATUS_FLAG_QUIESCED (0x02) +#define MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x04) +#define MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE (0x08) +#define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL (0x00) +#define MPI_RAIDVOL0_STATUS_STATE_DEGRADED (0x01) +#define MPI_RAIDVOL0_STATUS_STATE_FAILED (0x02) +#define MPI_CONFIG_PAGETYPE_RAID_PHYSDISK (0x0A) +#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x00) +#define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x01) +#define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED (0x02) +#define MPI_PHYSDISK0_STATUS_ONLINE (0x00) +#define MPI_PHYSDISK0_STATUS_MISSING (0x01) +#define MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE (0x02) +#define MPI_PHYSDISK0_STATUS_FAILED (0x03) +#define MPI_PHYSDISK0_STATUS_FAILED_REQUESTED (0x06) +#define MPI_PHYSDISK0_STATUS_INITIALIZING (0x04) +#define MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED (0x05) +#define MPI_PHYSDISK0_STATUS_FAILED_REQUESTED (0x06) +#define MPI_PHYSDISK0_STATUS_OTHER_OFFLINE (0xFF) +#define MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX (1) + +#define MPT_MAGIC_NUMBER 'm' +#define MPTCOMMAND _IOWR(MPT_MAGIC_NUMBER,20,struct mpt_ioctl_command) + +typedef struct ConfigPageHeader_t { + uint8_t PageVersion; /* 00h */ + uint8_t PageLength; /* 01h */ + uint8_t PageNumber; /* 02h */ + uint8_t PageType; /* 03h */ +} ConfigPageHeader_t; + +typedef struct SGESimpleUnion_t { + uint32_t FlagsLength; + union { + uint32_t Address32; + uint64_t Address64; + } u; +} SGESimpleUnion_t; + +typedef struct SGEChainUnion_t { + uint16_t Length; + uint8_t NextChainOffset; + uint8_t Flags; + union { + uint32_t Address32; + uint64_t Address64; + } u; +} SGEChainUnion_t; + +typedef struct SGEIOUnion_t { + union { + SGESimpleUnion_t Simple; + SGEChainUnion_t Chain; + } u; +} SGEIOUnion_t; + +typedef struct Config_t { + uint8_t Action; /* 00h */ + uint8_t Reserved; /* 01h */ + uint8_t ChainOffset; /* 02h */ + uint8_t Function; /* 03h */ + uint16_t ExtPageLength; /* 04h */ + uint8_t ExtPageType; /* 06h */ + uint8_t MsgFlags; /* 07h */ + uint32_t MsgContext; /* 08h */ + uint8_t Reserved2[8]; /* 0Ch */ + ConfigPageHeader_t Header; /* 14h */ + uint32_t PageAddress; /* 18h */ + SGEIOUnion_t PageBufferSGE; /* 1Ch */ +} Config_t; + +typedef struct ConfigReply_t { + uint8_t Action; /* 00h */ + uint8_t Reserved; /* 01h */ + uint8_t MsgLength; /* 02h */ + uint8_t Function; /* 03h */ + uint16_t ExtPageLength; /* 04h */ + uint8_t ExtPageType; /* 06h */ + uint8_t MsgFlags; /* 07h */ + uint32_t MsgContext; /* 08h */ + uint8_t Reserved2[2]; /* 0Ch */ + uint16_t IOCStatus; /* 0Eh */ + uint32_t IOCLogInfo; /* 10h */ + ConfigPageHeader_t Header; /* 14h */ +} ConfigReply_t; + +typedef struct RaidVol0Status_t { + uint8_t Flags; /* 00h */ + uint8_t State; /* 01h */ + uint16_t Reserved; /* 02h */ +} RaidVol0Status_t; + +typedef struct RaidVol0Settings { + uint16_t Settings; /* 00h */ + uint8_t HotSparePool; /* 01h *//* MPI_RAID_HOT_SPARE_POOL_ */ + uint8_t Reserved; /* 02h */ +} RaidVol0Settings; + +typedef struct RaidVol0PhysDisk_t { + uint16_t Reserved; /* 00h */ + uint8_t PhysDiskMap; /* 02h */ + uint8_t PhysDiskNum; /* 03h */ +} RaidVol0PhysDisk_t; + +typedef struct RaidVolumePage0_t { + ConfigPageHeader_t Header; /* 00h */ + uint8_t VolumeID; /* 04h */ + uint8_t VolumeBus; /* 05h */ + uint8_t VolumeIOC; /* 06h */ + uint8_t VolumeType; /* 07h *//* MPI_RAID_VOL_TYPE_ */ + RaidVol0Status_t VolumeStatus; /* 08h */ + RaidVol0Settings VolumeSettings; /* 0Ch */ + uint32_t MaxLBA; /* 10h */ + uint32_t Reserved1; /* 14h */ + uint32_t StripeSize; /* 18h */ + uint32_t Reserved2; /* 1Ch */ + uint32_t Reserved3; /* 20h */ + uint8_t NumPhysDisks; /* 24h */ + uint8_t Reserved4; /* 25h */ + uint16_t Reserved5; /* 26h */ + RaidVol0PhysDisk_t PhysDisk[MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX]; /* 28h */ +} RaidVolumePage0_t; + +typedef struct RaidPhysDiskSettings_t { + uint8_t SepID; /* 00h */ + uint8_t SepBus; /* 01h */ + uint8_t HotSparePool; /* 02h *//* MPI_RAID_HOT_SPARE_POOL_ */ + uint8_t PhysDiskSettings; /* 03h */ +} RaidPhysDiskSettings_t; + +typedef struct RaidPhysDisk0InquiryData { + uint8_t VendorID[8]; /* 00h */ + uint8_t ProductID[16]; /* 08h */ + uint8_t ProductRevLevel[4]; /* 18h */ + uint8_t Info[32]; /* 1Ch */ +} RaidPhysDisk0InquiryData; + +typedef struct RaidPhysDiskStatus_t { + uint8_t Flags; /* 00h */ + uint8_t State; /* 01h */ + uint16_t Reserved; /* 02h */ +} RaidPhysDiskStatus_t; + +typedef struct RaidPhysDisk0ErrorData_t { + uint8_t ErrorCdbByte; /* 00h */ + uint8_t ErrorSenseKey; /* 01h */ + uint16_t Reserved; /* 02h */ + uint16_t ErrorCount; /* 04h */ + uint8_t ErrorASC; /* 06h */ + uint8_t ErrorASCQ; /* 07h */ + uint16_t SmartCount; /* 08h */ + uint8_t SmartASC; /* 0Ah */ + uint8_t SmartASCQ; /* 0Bh */ +} RaidPhysDisk0ErrorData_t; + +typedef struct RaidPhysDiskPage0_t { + ConfigPageHeader_t Header; /* 00h */ + uint8_t PhysDiskID; /* 04h */ + uint8_t PhysDiskBus; /* 05h */ + uint8_t PhysDiskIOC; /* 06h */ + uint8_t PhysDiskNum; /* 07h */ + RaidPhysDiskSettings_t PhysDiskSettings; /* 08h */ + uint32_t Reserved1; /* 0Ch */ + uint32_t Reserved2; /* 10h */ + uint32_t Reserved3; /* 14h */ + uint8_t DiskIdentifier[16]; /* 18h */ + RaidPhysDisk0InquiryData InquiryData; /* 28h */ + RaidPhysDiskStatus_t PhysDiskStatus; /* 64h */ + uint32_t MaxLBA; /* 68h */ + RaidPhysDisk0ErrorData_t ErrorData; /* 6Ch */ +} RaidPhysDiskPage0_t; + +typedef struct mpt_ioctl_header { + unsigned int iocnum; /* IOC unit number */ + unsigned int port; /* IOC port number */ + int maxDataSize; /* Maximum Num. bytes to transfer on read */ +} mpt_ioctl_header; + +struct mpt_ioctl_command { + mpt_ioctl_header hdr; + int timeout; /* optional (seconds) */ + char *replyFrameBufPtr; + char *dataInBufPtr; + char *dataOutBufPtr; + char *senseDataPtr; + int maxReplyBytes; + int dataInSize; + int dataOutSize; + int maxSenseBytes; + int dataSgeOffset; + char MF[1]; +}; diff -Nur mpt-status-1.1.6/incl/sles.h mpt-status-1.2.0-RC4/incl/sles.h --- mpt-status-1.1.6/incl/sles.h 2006-02-12 18:42:35.000000000 +0100 +++ mpt-status-1.2.0-RC4/incl/sles.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,198 +0,0 @@ -#define MPI_FUNCTION_CONFIG (0x04) -#define MPI_CONFIG_ACTION_PAGE_HEADER (0x00) -#define MPI_CONFIG_PAGETYPE_RAID_VOLUME (0x08) -#define MPI_CONFIG_ACTION_PAGE_READ_CURRENT (0x01) -#define MPI_RAIDVOLPAGE0_PAGEVERSION (0x01) -#define MPI_RAIDVOL0_STATUS_FLAG_ENABLED (0x01) -#define MPI_RAIDVOL0_STATUS_FLAG_QUIESCED (0x02) -#define MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS (0x04) -#define MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE (0x08) -#define MPI_RAIDVOL0_STATUS_STATE_OPTIMAL (0x00) -#define MPI_RAIDVOL0_STATUS_STATE_DEGRADED (0x01) -#define MPI_RAIDVOL0_STATUS_STATE_FAILED (0x02) -#define MPI_CONFIG_PAGETYPE_RAID_PHYSDISK (0x0A) -#define MPI_RAIDPHYSDISKPAGE0_PAGEVERSION (0x00) -#define MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC (0x01) -#define MPI_PHYSDISK0_STATUS_FLAG_QUIESCED (0x02) -#define MPI_PHYSDISK0_STATUS_ONLINE (0x00) -#define MPI_PHYSDISK0_STATUS_MISSING (0x01) -#define MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE (0x02) -#define MPI_PHYSDISK0_STATUS_FAILED (0x03) -#define MPI_PHYSDISK0_STATUS_FAILED_REQUESTED (0x06) -#define MPI_PHYSDISK0_STATUS_INITIALIZING (0x04) -#define MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED (0x05) -#define MPI_PHYSDISK0_STATUS_FAILED_REQUESTED (0x06) -#define MPI_PHYSDISK0_STATUS_OTHER_OFFLINE (0xFF) -#define MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX (1) - -#define MPT_MAGIC_NUMBER 'm' -#define MPTCOMMAND _IOWR(MPT_MAGIC_NUMBER,20,struct mpt_ioctl_command) - -typedef struct ConfigPageHeader_t { - uint8_t PageVersion; /* 00h */ - uint8_t PageLength; /* 01h */ - uint8_t PageNumber; /* 02h */ - uint8_t PageType; /* 03h */ -} ConfigPageHeader_t; - -typedef struct SGESimpleUnion_t { - uint32_t FlagsLength; - union { - uint32_t Address32; - uint64_t Address64; - } u; -} SGESimpleUnion_t; - -typedef struct SGEChainUnion_t { - uint16_t Length; - uint8_t NextChainOffset; - uint8_t Flags; - union { - uint32_t Address32; - uint64_t Address64; - } u; -} SGEChainUnion_t; - -typedef struct SGEIOUnion_t { - union { - SGESimpleUnion_t Simple; - SGEChainUnion_t Chain; - } u; -} SGEIOUnion_t; - -typedef struct Config_t { - uint8_t Action; /* 00h */ - uint8_t Reserved; /* 01h */ - uint8_t ChainOffset; /* 02h */ - uint8_t Function; /* 03h */ - uint16_t ExtPageLength; /* 04h */ - uint8_t ExtPageType; /* 06h */ - uint8_t MsgFlags; /* 07h */ - uint32_t MsgContext; /* 08h */ - uint8_t Reserved2[8]; /* 0Ch */ - ConfigPageHeader_t Header; /* 14h */ - uint32_t PageAddress; /* 18h */ - SGEIOUnion_t PageBufferSGE; /* 1Ch */ -} Config_t; - -typedef struct ConfigReply_t { - uint8_t Action; /* 00h */ - uint8_t Reserved; /* 01h */ - uint8_t MsgLength; /* 02h */ - uint8_t Function; /* 03h */ - uint16_t ExtPageLength; /* 04h */ - uint8_t ExtPageType; /* 06h */ - uint8_t MsgFlags; /* 07h */ - uint32_t MsgContext; /* 08h */ - uint8_t Reserved2[2]; /* 0Ch */ - uint16_t IOCStatus; /* 0Eh */ - uint32_t IOCLogInfo; /* 10h */ - ConfigPageHeader_t Header; /* 14h */ -} ConfigReply_t; - -typedef struct RaidVol0Status_t { - uint8_t Flags; /* 00h */ - uint8_t State; /* 01h */ - uint16_t Reserved; /* 02h */ -} RaidVol0Status_t; - -typedef struct RaidVol0Settings { - uint16_t Settings; /* 00h */ - uint8_t HotSparePool; /* 01h *//* MPI_RAID_HOT_SPARE_POOL_ */ - uint8_t Reserved; /* 02h */ -} RaidVol0Settings; - -typedef struct RaidVol0PhysDisk_t { - uint16_t Reserved; /* 00h */ - uint8_t PhysDiskMap; /* 02h */ - uint8_t PhysDiskNum; /* 03h */ -} RaidVol0PhysDisk_t; - -typedef struct RaidVolumePage0_t { - ConfigPageHeader_t Header; /* 00h */ - uint8_t VolumeID; /* 04h */ - uint8_t VolumeBus; /* 05h */ - uint8_t VolumeIOC; /* 06h */ - uint8_t VolumeType; /* 07h *//* MPI_RAID_VOL_TYPE_ */ - RaidVol0Status_t VolumeStatus; /* 08h */ - RaidVol0Settings VolumeSettings; /* 0Ch */ - uint32_t MaxLBA; /* 10h */ - uint32_t Reserved1; /* 14h */ - uint32_t StripeSize; /* 18h */ - uint32_t Reserved2; /* 1Ch */ - uint32_t Reserved3; /* 20h */ - uint8_t NumPhysDisks; /* 24h */ - uint8_t Reserved4; /* 25h */ - uint16_t Reserved5; /* 26h */ - RaidVol0PhysDisk_t PhysDisk[MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX]; /* 28h */ -} RaidVolumePage0_t; - -typedef struct RaidPhysDiskSettings_t { - uint8_t SepID; /* 00h */ - uint8_t SepBus; /* 01h */ - uint8_t HotSparePool; /* 02h *//* MPI_RAID_HOT_SPARE_POOL_ */ - uint8_t PhysDiskSettings; /* 03h */ -} RaidPhysDiskSettings_t; - -typedef struct RaidPhysDisk0InquiryData { - uint8_t VendorID[8]; /* 00h */ - uint8_t ProductID[16]; /* 08h */ - uint8_t ProductRevLevel[4]; /* 18h */ - uint8_t Info[32]; /* 1Ch */ -} RaidPhysDisk0InquiryData; - -typedef struct RaidPhysDiskStatus_t { - uint8_t Flags; /* 00h */ - uint8_t State; /* 01h */ - uint16_t Reserved; /* 02h */ -} RaidPhysDiskStatus_t; - -typedef struct RaidPhysDisk0ErrorData_t { - uint8_t ErrorCdbByte; /* 00h */ - uint8_t ErrorSenseKey; /* 01h */ - uint16_t Reserved; /* 02h */ - uint16_t ErrorCount; /* 04h */ - uint8_t ErrorASC; /* 06h */ - uint8_t ErrorASCQ; /* 07h */ - uint16_t SmartCount; /* 08h */ - uint8_t SmartASC; /* 0Ah */ - uint8_t SmartASCQ; /* 0Bh */ -} RaidPhysDisk0ErrorData_t; - -typedef struct RaidPhysDiskPage0_t { - ConfigPageHeader_t Header; /* 00h */ - uint8_t PhysDiskID; /* 04h */ - uint8_t PhysDiskBus; /* 05h */ - uint8_t PhysDiskIOC; /* 06h */ - uint8_t PhysDiskNum; /* 07h */ - RaidPhysDiskSettings_t PhysDiskSettings; /* 08h */ - uint32_t Reserved1; /* 0Ch */ - uint32_t Reserved2; /* 10h */ - uint32_t Reserved3; /* 14h */ - uint8_t DiskIdentifier[16]; /* 18h */ - RaidPhysDisk0InquiryData InquiryData; /* 28h */ - RaidPhysDiskStatus_t PhysDiskStatus; /* 64h */ - uint32_t MaxLBA; /* 68h */ - RaidPhysDisk0ErrorData_t ErrorData; /* 6Ch */ -} RaidPhysDiskPage0_t; - -typedef struct mpt_ioctl_header { - unsigned int iocnum; /* IOC unit number */ - unsigned int port; /* IOC port number */ - int maxDataSize; /* Maximum Num. bytes to transfer on read */ -} mpt_ioctl_header; - -struct mpt_ioctl_command { - mpt_ioctl_header hdr; - int timeout; /* optional (seconds) */ - char *replyFrameBufPtr; - char *dataInBufPtr; - char *dataOutBufPtr; - char *senseDataPtr; - int maxReplyBytes; - int dataInSize; - int dataOutSize; - int maxSenseBytes; - int dataSgeOffset; - char MF[1]; -}; diff -Nur mpt-status-1.1.6/Makefile mpt-status-1.2.0-RC4/Makefile --- mpt-status-1.1.6/Makefile 2006-03-04 14:18:43.000000000 +0100 +++ mpt-status-1.2.0-RC4/Makefile 2006-04-23 20:26:46.000000000 +0200 @@ -1,27 +1,21 @@ PROG := mpt-status -KERNEL_PATH := /usr/src/linux PREFIX := /usr -CFLAGS := -I${KERNEL_PATH}/drivers/message/fusion -Iincl -Wall -W -O2 -DFLAGS := +KERNEL_PATH := /usr/src/linux +CFLAGS := -Iincl -Wall -W -O2 -I${KERNEL_PATH}/drivers/message/fusion +DFLAGS := -DNEWSTYLE #-DSANITIZED_KERNEL_HEADERS #-DVAR_DIV LDFLAGS := DESTDIR := CC := gcc INSTALL := install ARCH := $(shell uname -m) -REDHAT := $(shell if [ -e /etc/redhat-release ]; \ - then echo "true"; else echo "false"; fi) -ifeq "${REDHAT}" "true" - DFLAGS := ${FLAGS} -DREDHAT -endif ifeq "${ARCH}" "sparc64" - CFLAGS := -I${KERNEL_PATH}/drivers/message/fusion -Iincl -Wall -W -O2 \ - -m64 -pipe -mcpu=ultrasparc -mcmodel=medlow + CFLAGS := -Iincl -Wall -W -O2 -m64 -pipe \ + -mcpu=ultrasparc -mcmodel=medlow endif # This part is for the 1.2.0 version of mpt-status #ifeq "${ARCH}" "x86_64" -# CFLAGS := -I${KERNEL_PATH}/drivers/message/fusion -Iincl -Wall -W -O2 \ -# -m64 +# CFLAGS := -Iincl -Wall -W -O2 -m64 -I${KERNEL_PATH}/drivers/message/fusion #endif ${PROG}: ${PROG}.c ${PROG}.h diff -Nur mpt-status-1.1.6/mpt-status.c mpt-status-1.2.0-RC4/mpt-status.c --- mpt-status-1.1.6/mpt-status.c 2006-03-06 19:19:44.000000000 +0100 +++ mpt-status-1.2.0-RC4/mpt-status.c 2006-04-23 22:15:36.000000000 +0200 @@ -23,17 +23,16 @@ */ +#define _GNU_SOURCE #include #include #include +#include #include #include #include #include #include - -#include -#include #include "mpt-status.h" #define ARG_M_A 0x0001 @@ -45,6 +44,11 @@ static int debug_level = 0; static int auto_load = 0; static int probe_id = 0; +static int mpt_exit_mask = MPT_EXIT_OKAY; +static int print_status_only = PRINT_STATUS_ONLY; +static int id_of_primary_device = 0; +static int ioc_unit = 0; +//static int library_mode = 0; static int sel; static const struct option long_options[] = { @@ -79,48 +83,190 @@ "\n" " You can write ``-o arg'' or ``--option arg'' or ``--option=arg''\n" " Note that for some parameters only the long format is supported.\n" + "\n" + " The program's exit(2) status is meant to be interpreted as a bit\n" + " mask. If everything went well, zero is returned. If not (i.e. if\n" + " for example an error or unknown condition is detected), the eight\n" + " different bits of the return value shall be interpreded as:\n" + "\n" + " Bit 0: Abnormal condition detected. This includes -but it's not\n" + " limited to- unknown error conditions.\n" + " Bit 1: A logical volume has failed.\n" + " Bit 2: A logical volume is degraded.\n" + " Bit 3: A logical volume is resyncing.\n" + " Bit 4: At least one physical disk failed.\n" + " Bit 5: At least one physical disk is in warning condition.\n" "\n"; -static int print_status_only = PRINT_STATUS_ONLY; -static int id_of_primary_device = 0; -static int ioc_unit = 0; + +static char *VolumeTypes[] = { "IS", "IME", "IM" }; +static char *VolumeTypesHuman[] = { "0", "1E", "1" }; //Raid levels +mpiIoctlBlk_t *mpiBlkPtr = NULL; +unsigned char g_command[BIG]; +char g_data[4*BIG]; +char g_reply[BIG]; +int g_bigEndian = 0; + +/* function declaration */ +static void __check_endianess(void); +static unsigned int cpu_to_le32 (unsigned int); +static unsigned short le16_to_cpu(unsigned short); +static void freeMem(void); +static int allocDataFrame(int); +static int allocReplyFrame(void); +static void mpt_exit(int); +static int mpt_printf(const char *format, ...); +static int mpt_fprintf(FILE *, const char *, ...); +static void print_usage(const char *); +static void print_version(void); +static void *read_page(uint, uint, uint, uint, uint); +static int __probe_scsi_id(void); +static int read_page2(uint); +static void GetVolumeInfo(void); +static void GetPhysDiskInfo(RaidVol0PhysDisk_t *, int); +static void GetResyncPercentage(RaidVol0PhysDisk_t *, unsigned char *, int); +static void print_information(void); +static void do_init(void); + +static void __check_endianess(void) { + test_endianess_t test; + test.u.foo = 0x01020304; + if (test.u.bar[0] != (test.u.foo & 0xFF)) + g_bigEndian = 1; +} + +static unsigned int cpu_to_le32 (unsigned int x) { + if (g_bigEndian) { + unsigned int y; + y = (x & 0xFF00) << 8; + y |= (x & 0xFF) << 24; + y |= (x & 0xFF0000) >> 8; + y |= (x & 0xFF000000) >> 24; + return y; + } + return x; +} + +static unsigned short le16_to_cpu(unsigned short x) { + if (g_bigEndian) { + unsigned short y = (((x & 0xFF00) >> 8) | ((x & 0xFF) << 8)); + return y; + } + return x; +} + +static void freeMem(void) { + if (mpiBlkPtr->replyFrameBufPtr) + mpiBlkPtr->replyFrameBufPtr = NULL; + if (mpiBlkPtr->dataOutBufPtr) + mpiBlkPtr->dataOutBufPtr = NULL; + if (mpiBlkPtr->dataInBufPtr) + mpiBlkPtr->dataInBufPtr = NULL; + mpiBlkPtr = NULL; +} + +static int allocDataFrame(int dir) { + if (dir == DATA_DIR_OUT) { + if (mpiBlkPtr->dataOutSize > (4*BIG)) + return 1; + mpiBlkPtr->dataOutBufPtr = (char *)&g_data; + memset(mpiBlkPtr->dataOutBufPtr, 0, mpiBlkPtr->dataOutSize); + + } else if (dir == DATA_DIR_IN) { + if (mpiBlkPtr->dataInSize > (4*BIG)) + return 1; + mpiBlkPtr->dataInBufPtr = (char *)&g_data; + memset(mpiBlkPtr->dataInBufPtr, 0, mpiBlkPtr->dataInSize); + } + return 0; +} + +static int allocReplyFrame(void) { + mpiBlkPtr->replyFrameBufPtr = (char *) &g_reply; + memset (mpiBlkPtr->replyFrameBufPtr, 0, REPLY_SIZE); + mpiBlkPtr->maxReplyBytes = REPLY_SIZE; + return 0; +} + +mpiIoctlBlk_t *allocIoctlBlk(uint numBytes) { + int blksize = sizeof(mpiIoctlBlk_t) + numBytes; + + if (blksize >= BIG) { + return NULL; + } + mpiBlkPtr = (mpiIoctlBlk_t *) &g_command; + memset(mpiBlkPtr, 0, blksize); + if (allocReplyFrame()) { + printf("allocReplyFrame call failed\n"); + freeMem(); + return NULL; + } + return mpiBlkPtr; +} + +static void mpt_exit(int status) { + if (status & MPT_EXIT_FREEMEM) { + freeMem(); + } + if (status & MPT_EXIT_NOCLOSE) { + close(m); + } + exit(mpt_exit_mask |= status); +} + +static int mpt_printf(const char *format, ...) { + int result; + va_list ap; + + if (quiet_mode) + return 0; + va_start(ap, format); + result = vprintf(format, ap); + va_end(ap); + return result; +} + +static int mpt_fprintf(FILE *fp, const char *format, ...) { + int result; + va_list ap; + + if (quiet_mode) + return 0; + va_start(ap, format); + result = vfprintf(fp, format, ap); + va_end(ap); + return result; +} + static void print_usage(const char *progname) { - printf(usage_template, progname); + mpt_printf(usage_template, progname); } static void print_version(void) { - printf("Version: %s\n", VERSION); + mpt_printf("Version: %s\n", VERSION); } -/* -// 32bit version -static void *read_page(U8 pagetype, U8 pagewhich, U8 pagenumber, - U32 address, U8 version) { -*/ -// original static void *read_page(unsigned int pagetype, unsigned int pagewhich, unsigned int pagenumber, unsigned int address, unsigned int version) { -/* -// 64bit version -static void *read_page(uint8_t pagetype, uint8_t pagewhich, - uint8_t pagenumber, uint32_t address, - uint8_t version) { -*/ char command[REALLYBIG]; char reply[REALLYBIG]; char sense[REALLYBIG]; char *in; unsigned int warnings; - struct mpt_ioctl_command *cmd; + struct mpt_ioctl_command *cmd = NULL; Config_t *config_request; ConfigReply_t *config_reply; +#ifdef VAR_DIV unsigned short div = sizeof(char *); /* this is fishy */ +#else + unsigned short div = 4; +#endif // VAR_DIV if (NULL == (in = calloc(REALLYBIG, 1))) { perror("calloc"); - exit(EXIT_FAILURE); + mpt_exit(MPT_EXIT_UNKNOWN); } warnings = 0; @@ -139,11 +285,6 @@ cmd->timeout = 10; cmd->dataSgeOffset = (((char *)&config_request->PageBufferSGE) - ((char *)config_request)) / div; - /* - printf("SGE ptr: %p\n", (char *)&config_request->PageBufferSGE); - printf("conf ptr: %p\n", (char *)config_request); - printf("dataSgeOffset: %d\n", cmd->dataSgeOffset); - */ cmd->senseDataPtr = (void *)sense; cmd->replyFrameBufPtr = (void *)config_reply; cmd->dataInBufPtr = (void *)in; @@ -159,17 +300,18 @@ config_request->Header.PageVersion = 0; config_request->PageAddress = address; - if (-1 == ioctl(m, MPTCOMMAND, cmd)) { + if (-1 == ioctl(m, MPTCOMMAND, (char *) cmd)) { perror("MPI_FUNCTION_CONFIG (get page header)"); - exit(EXIT_FAILURE); + mpt_exit(MPT_EXIT_UNKNOWN); } if (version != config_reply->Header.PageVersion) { if (verbose_mode > 0) { - fprintf(stderr, - "Version mismatch on pagetype %u, page number %u: expected %d, got %d\n", - pagetype, pagenumber, version, - config_reply->Header.PageVersion); + mpt_fprintf(stderr, + "Version mismatch on pagetype %u," + " page number %u: expected %d, got %d\n", + pagetype, pagenumber, version, + config_reply->Header.PageVersion); } /* Enable the following to automatically output a warning */ //warnings++; @@ -178,38 +320,28 @@ config_request->Action = pagewhich; config_request->Header.PageLength = config_reply->Header.PageLength; - /* - * Is this check really necessary (255 is max anyway)? --ratz - * config_reply->Header.PageLength is U8. - if (config_reply->Header.PageLength > UINT8_MAX) { - fprintf(stderr, "reply too big\n"); - exit(EXIT_FAILURE); - } - */ - if (-1 == ioctl(m, MPTCOMMAND, cmd)) { perror("MPI_FUNCTION_CONFIG (get page)"); - exit(EXIT_FAILURE); + mpt_exit(MPT_EXIT_UNKNOWN); } - if (warnings > 0 && quiet_mode == 0 && verbose_mode != 0) { - fprintf(stderr, "\nHouston, we have got a problem!" - " If you're interested in the warnings or you" - " were asked to send verbose information, add" - " the '-v' switch to your command line\n"); + if (warnings > 0 && verbose_mode != 0) { + mpt_fprintf(stderr, + "\nHouston, we have got a problem!" + " If you're interested in the warnings or you" + " were asked to send verbose information, add" + " the '-v' switch to your command line\n"); } return in; } - -static int __probe_scsi_id() { +static int __probe_scsi_id(void) { int scsi_id; - int ioc = 0; RaidVolumePage0_t *page; for (scsi_id = 0; scsi_id < 16; scsi_id++) { page = read_page(MPI_CONFIG_PAGETYPE_RAID_VOLUME, MPI_CONFIG_ACTION_PAGE_READ_CURRENT, - ioc, + ioc_unit, scsi_id, MPI_RAIDVOLPAGE0_PAGEVERSION); if (0 != page->NumPhysDisks) { @@ -221,170 +353,595 @@ return -1; } -static void print_information() { +static int read_page2(uint flags) { + // this is the IssueMptCommand + MPIDefaultReply_t *pReply = NULL; + int CmdBlkSize; + int status = -1; + + CmdBlkSize = sizeof(mpiIoctlBlk_t) + ((mpiBlkPtr->dataSgeOffset)*4) + 8; + mpiBlkPtr->hdr.iocnum = ioc_unit; + mpiBlkPtr->hdr.port = 0; + + if (ioctl(m, (unsigned long) MPTCOMMAND, (char *) mpiBlkPtr) != 0) { + perror("IOCTL failed"); + mpt_exit(MPT_EXIT_UNKNOWN); + } else { + pReply = (MPIDefaultReply_t *) mpiBlkPtr->replyFrameBufPtr; + if ((pReply) && (pReply->MsgLength > 0)) { + pReply->IOCStatus = le16_to_cpu(pReply->IOCStatus); + status = pReply->IOCStatus & MPI_IOCSTATUS_MASK; + } else { + status = 0; + } + } + + if ((flags & MPT_FLAGS_KEEP_MEM) == 0) { + freeMem(); + } + + return status; +} + +static void GetVolumeInfo(void) { + Config_t *ConfigRequest; + ConfigReply_t *pReply = NULL; + RaidVolumePage0_t *pRVP0 = NULL; + RaidVol0PhysDisk_t disk_num[16]; + unsigned char pdisk_vol[16]; + uint numBytes; + int status; + int ii, id; + uint vol_count = 0; + int pdisk_cnt = 0; + int resync_on = 0; + unsigned bus = 0; + unsigned char tmp; + + numBytes = (sizeof(Config_t) - sizeof(SGE_IO_UNION)) + + sizeof(SGESimple64_t); + if ((mpiBlkPtr = allocIoctlBlk(numBytes)) == NULL) { + return; + } + + ConfigRequest = (Config_t *) mpiBlkPtr->MF; + mpiBlkPtr->dataInSize = mpiBlkPtr->dataOutSize = 0; + mpiBlkPtr->dataInBufPtr = mpiBlkPtr->dataOutBufPtr = NULL; + mpiBlkPtr->dataSgeOffset = (sizeof (Config_t) - sizeof(SGE_IO_UNION))/4; + + pReply = (ConfigReply_t *)mpiBlkPtr->replyFrameBufPtr; + + /* Populate the Config Request + */ + ConfigRequest->Action = MPI_CONFIG_ACTION_PAGE_HEADER; + ConfigRequest->Function = MPI_FUNCTION_CONFIG; + ConfigRequest->MsgContext = -1; + ConfigRequest->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME; + ConfigRequest->PageAddress = cpu_to_le32((bus << 8) | 0); + + status = read_page2(MPT_FLAGS_KEEP_MEM); + printf("Logical Volume Information:\n"); + if (status != 0) { + printf("\tUnsupported.\n"); + freeMem(); + return; + } else if (pReply->Header.PageLength == 0) { + printf("\tNone.\n"); + freeMem(); + return; + } + + mpiBlkPtr->dataInSize = pReply->Header.PageLength * 4; + if (allocDataFrame(DATA_DIR_IN)) { + printf("Config: Unable to allocate data buffer."); + freeMem(); + return; + } + + ConfigRequest->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; + ConfigRequest->Header.PageVersion = pReply->Header.PageVersion; + ConfigRequest->Header.PageLength = pReply->Header.PageLength; + + id = 0; // volume id: only one volume for now (vol_ids) + ConfigRequest->PageAddress = cpu_to_le32((bus << 8) | id); + status = read_page2(MPT_FLAGS_KEEP_MEM); + + /* Kludge - IO FW 1.1.60 returns IOCSTATUS of GOOD to + * this call resulting in bad information. + * IM FW returns a status of 0x0022 - INVALID PAGE + */ + pRVP0 = (RaidVolumePage0_t *) mpiBlkPtr->dataInBufPtr; + if ((status == 0) && (pRVP0->NumPhysDisks > 0)){ + vol_count++; + printf("\tID=0x%x, Bus=0x%x, IOC=0x%x, %s(0x%x)", + pRVP0->VolumeID,pRVP0->VolumeBus, pRVP0->VolumeIOC, + VolumeTypes[pRVP0->VolumeType], pRVP0->VolumeType); + if (pRVP0->VolumeType == MPI_RAID_VOL_TYPE_IS) + printf(", Stripe Size=0x%x", pRVP0->StripeSize); + printf(", %d Physical Disks", pRVP0->NumPhysDisks); + printf("\n"); + + printf("\tStatus: "); + tmp = pRVP0->VolumeStatus.Flags; + printf("%s", tmp & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ? "Not Active" : "Active"); + + printf(", %s", tmp & MPI_RAIDVOL0_STATUS_FLAG_ENABLED ? "Enabled" : "Disabled"); + if (tmp & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED) + printf(", Quiesced Phys Disk IOs"); + + if (tmp & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) { + printf(", Resync In Progress"); + resync_on = 1; + } + printf("\n"); + + /* + tmp = (pRVP0->VolumeStatus.State) & 0x03; + printf("\tState: %s\n", raid_status[tmp]); + */ + if (pRVP0->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL) { + mpt_exit_mask |= MPT_EXIT_VOL_OPTIMAL; + mpt_printf(" OPTIMAL"); + } else if (pRVP0->VolumeStatus.State == + MPI_RAIDVOL0_STATUS_STATE_DEGRADED) { + mpt_exit_mask |= MPT_EXIT_VOL_DEGRADED; + mpt_printf(" DEGRADED"); + } else if (pRVP0->VolumeStatus.State == + MPI_RAIDVOL0_STATUS_STATE_FAILED) { + mpt_exit_mask |= MPT_EXIT_VOL_FAILED; + mpt_printf(" FAILED"); + } else { + mpt_exit_mask |= MPT_EXIT_UNKNOWN; + mpt_printf(" UNKNOWN"); + } + + for (ii = pdisk_cnt; ii < pdisk_cnt + pRVP0->NumPhysDisks; ii++) { + disk_num[ii].PhysDiskNum = pRVP0->PhysDisk[ii].PhysDiskNum; + disk_num[ii].PhysDiskMap = pRVP0->PhysDisk[ii].PhysDiskMap; + pdisk_vol[ii] = pRVP0->VolumeID; + } + pdisk_cnt += pRVP0->NumPhysDisks; + } + freeMem(); + if (pdisk_cnt > 0) { + GetPhysDiskInfo((RaidVol0PhysDisk_t *) &disk_num, pdisk_cnt); + } + if (resync_on) + GetResyncPercentage((RaidVol0PhysDisk_t *) &disk_num, + (unsigned char *) &pdisk_vol, pdisk_cnt); + if (vol_count == 0) { + printf("\tNo Logical Volumes Found.\n"); + } + + return; +} + +static void GetPhysDiskInfo(RaidVol0PhysDisk_t *pDisk, int count) { + Config_t *ConfigRequest; + ConfigReply_t *pReply = NULL; + uint numBytes; + int status; + int ii; + unsigned char tmp; + + printf("\tPhysical Disk Information:\n"); + + numBytes = (sizeof(Config_t) - sizeof(SGE_IO_UNION)) + sizeof (SGESimple64_t); + if ((mpiBlkPtr = allocIoctlBlk(numBytes)) == NULL) + return; + + ConfigRequest = (Config_t *) mpiBlkPtr->MF; + mpiBlkPtr->dataInSize = mpiBlkPtr->dataOutSize = 0; + mpiBlkPtr->dataInBufPtr = mpiBlkPtr->dataOutBufPtr = NULL; + mpiBlkPtr->dataSgeOffset = (sizeof (Config_t) - sizeof(SGE_IO_UNION))/4; + pReply = (ConfigReply_t *)mpiBlkPtr->replyFrameBufPtr; + + ConfigRequest->Action = MPI_CONFIG_ACTION_PAGE_HEADER; + ConfigRequest->Function = MPI_FUNCTION_CONFIG; + ConfigRequest->MsgContext = -1; + ConfigRequest->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; + ConfigRequest->PageAddress = cpu_to_le32((uint)pDisk[0].PhysDiskNum); + + status = read_page2(MPT_FLAGS_KEEP_MEM); + if ((status == 0) && (pReply->Header.PageLength > 0)) { + mpiBlkPtr->dataInSize = pReply->Header.PageLength * 4; + if (allocDataFrame(DATA_DIR_IN)) { + printf ("Config: Unable to allocate data buffer."); + freeMem(); + return; + } + } + + ConfigRequest->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; + ConfigRequest->Header.PageVersion = pReply->Header.PageVersion; + ConfigRequest->Header.PageLength = pReply->Header.PageLength; + for (ii = 0; ii < count; ii++){ + ConfigRequest->PageAddress = cpu_to_le32((uint)pDisk[ii].PhysDiskNum); + + status = read_page2(MPT_FLAGS_KEEP_MEM); + if (status == 0) { + RaidPhysDiskPage0_t *pRPD0 = (RaidPhysDiskPage0_t *) + mpiBlkPtr->dataInBufPtr; + + printf("\t\tPhys Disk Num=%d at ID=%d", + pRPD0->PhysDiskNum, pRPD0->PhysDiskID); + tmp = pRPD0->PhysDiskStatus.Flags; + if (tmp & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC) + printf(", Out of Sync"); + if (tmp & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED) + printf(", Quiesced"); + tmp = pRPD0->PhysDiskStatus.State; + if (tmp & MPI_PHYSDISK0_STATUS_ONLINE) + printf(", Online"); + if (tmp & MPI_PHYSDISK0_STATUS_MISSING) + printf(", Missing"); + if (tmp & MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE) + printf(", Not Compatible"); + if (tmp & MPI_PHYSDISK0_STATUS_FAILED) + printf(", Failed"); + if (tmp & MPI_PHYSDISK0_STATUS_INITIALIZING) + printf(", Initializing"); + if (tmp & MPI_PHYSDISK0_STATUS_FAILED_REQUESTED) + printf(", Failed Requested"); + printf("\n"); + } else + printf("\t\tNot Available.\n"); + } + freeMem(); + return; +} + +static void GetHotSpareInfo(void) { + Config_t *ConfigRequest; + ConfigReply_t *pReply = NULL; + IOCPage5_t *pPg5 = NULL; + uint numBytes; + int status; + uint num_spares = 0; + u8 tmp; + + numBytes = (sizeof(Config_t) - sizeof(SGE_IO_UNION)) + sizeof (SGESimple64_t); + if ((mpiBlkPtr = allocIoctlBlk(numBytes)) == NULL) + return; + + ConfigRequest = (Config_t *) mpiBlkPtr->MF; + mpiBlkPtr->dataInSize = mpiBlkPtr->dataOutSize = 0; + mpiBlkPtr->dataInBufPtr = mpiBlkPtr->dataOutBufPtr = NULL; + mpiBlkPtr->dataSgeOffset = (sizeof (Config_t) - sizeof(SGE_IO_UNION))/4; + + pReply = (ConfigReply_t *)mpiBlkPtr->replyFrameBufPtr; + + ConfigRequest->Action = MPI_CONFIG_ACTION_PAGE_HEADER; + ConfigRequest->Function = MPI_FUNCTION_CONFIG; + ConfigRequest->MsgContext = -1; + ConfigRequest->Header.PageNumber = 5; + ConfigRequest->Header.PageType = MPI_CONFIG_PAGETYPE_IOC; + ConfigRequest->PageAddress = cpu_to_le32(0); + + status = read_page2(MPT_FLAGS_KEEP_MEM); + printf("Hot Spare Information:\n"); + if (status != 0) { + printf("\tUnsupported.\n"); + freeMem(); + return; + } else if (pReply->Header.PageLength == 0 ) { + printf("\tNone.\n"); + freeMem(); + return; + } + + mpiBlkPtr->dataInSize = pReply->Header.PageLength * 4; + if (allocDataFrame(DATA_DIR_IN)) { + printf ("Config: Unable to allocate data buffer."); + freeMem(); + return; + } + + ConfigRequest->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; + ConfigRequest->Header.PageVersion = pReply->Header.PageVersion; + ConfigRequest->Header.PageLength = pReply->Header.PageLength; + status = read_page2(MPT_FLAGS_KEEP_MEM); + pPg5 = (IOCPage5_t *) mpiBlkPtr->dataInBufPtr; + + if ((status == 0) && (pPg5->NumHotSpares > 0)){ + num_spares = pPg5->NumHotSpares; + { + // Get Phys Disk Information + Ioc5HotSpare_t disk_num[num_spares]; + unsigned int ii; + + for (ii = 0; ii < num_spares; ii++) { + disk_num[ii].PhysDiskNum = pPg5->HotSpare[ii].PhysDiskNum; + disk_num[ii].HotSparePool = pPg5->HotSpare[ii].HotSparePool; + } + + freeMem(); /* Do not reference pPg5 any more */ + + numBytes = (sizeof(Config_t) - sizeof(SGE_IO_UNION)) + sizeof (SGESimple64_t); + if ((mpiBlkPtr = allocIoctlBlk(numBytes)) == NULL) + return; + + ConfigRequest = (Config_t *) mpiBlkPtr->MF; + mpiBlkPtr->dataInSize = mpiBlkPtr->dataOutSize = 0; + mpiBlkPtr->dataInBufPtr = mpiBlkPtr->dataOutBufPtr = NULL; + mpiBlkPtr->dataSgeOffset = (sizeof (Config_t) - sizeof(SGE_IO_UNION))/4; + + pReply = (ConfigReply_t *)mpiBlkPtr->replyFrameBufPtr; + + ConfigRequest->Action = MPI_CONFIG_ACTION_PAGE_HEADER; + ConfigRequest->Function = MPI_FUNCTION_CONFIG; + ConfigRequest->MsgContext = -1; + ConfigRequest->Header.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; + ConfigRequest->PageAddress = cpu_to_le32((uint)disk_num[0].PhysDiskNum); + + status = read_page2(MPT_FLAGS_KEEP_MEM); + if ((status == 0) && (pReply->Header.PageLength > 0)) { + mpiBlkPtr->dataInSize = pReply->Header.PageLength * 4; + if (allocDataFrame(DATA_DIR_IN)) { + printf ("Config: Unable to allocate data buffer."); + freeMem(); + return; + } + } + + ConfigRequest->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; + ConfigRequest->Header.PageVersion = pReply->Header.PageVersion; + ConfigRequest->Header.PageLength = pReply->Header.PageLength; + for (ii = 0; ii < num_spares; ii++){ + ConfigRequest->PageAddress = cpu_to_le32((uint)disk_num[ii].PhysDiskNum); + + status = read_page2(MPT_FLAGS_KEEP_MEM); + if (status == 0) { + RaidPhysDiskPage0_t *pRPD0 = (RaidPhysDiskPage0_t *) mpiBlkPtr->dataInBufPtr; + printf("\tNum=%d ID=%d", pRPD0->PhysDiskNum, pRPD0->PhysDiskID); + tmp=pRPD0->PhysDiskStatus.Flags; + if (tmp & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC) + printf(", Out of Sync"); + if (tmp & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED) + printf(", Quiesced"); + tmp=pRPD0->PhysDiskStatus.State; + if (tmp & MPI_PHYSDISK0_STATUS_ONLINE) + printf(", Online"); + if (tmp & MPI_PHYSDISK0_STATUS_MISSING) + printf(", Missing"); + if (tmp & MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE) + printf(", Not Compatible"); + if (tmp & MPI_PHYSDISK0_STATUS_FAILED) + printf(", Failed"); + if (tmp & MPI_PHYSDISK0_STATUS_INITIALIZING) + printf(", Initializing"); + if (tmp & MPI_PHYSDISK0_STATUS_FAILED_REQUESTED) + printf(", Failed Requested"); + printf("\n"); + } else + printf("\t\tNot Available.\n"); + } + } + } else if (status == 0) + printf("Not Available.\n"); + else + printf("No Hot Spare Disks.\n"); + + freeMem(); + return; +} + +static void GetResyncPercentage(RaidVol0PhysDisk_t *pDisk, unsigned char *pVol, int count) { + MpiRaidActionRequest_t *pRequest; + uint blks_done; + uint numBytes; + int ii; + uint tot_blks, blks_left; + int status; + + numBytes = (sizeof(MpiRaidActionRequest_t) - sizeof(SGE_IO_UNION)) + + sizeof (SGESimple64_t); + + if ((mpiBlkPtr = allocIoctlBlk(numBytes)) == NULL) + return; + + pRequest = (MpiRaidActionRequest_t *) mpiBlkPtr->MF; + mpiBlkPtr->dataSgeOffset = (sizeof (MpiRaidActionRequest_t) - sizeof(SGE_IO_UNION))/4; + + /* Initialize data in/data out sizes: Change below if need to */ + mpiBlkPtr->dataInSize = mpiBlkPtr->dataOutSize = 0; + + pRequest->Action = MPI_RAID_ACTION_INDICATOR_STRUCT; + pRequest->Function = MPI_FUNCTION_RAID_ACTION; + pRequest->MsgContext = -1; + pRequest->ActionDataWord = cpu_to_le32(0); /* action data is 0 */ + + printf("Resync Information:\n"); + for (ii = 0; ii < count; ii++ ) { + pRequest->VolumeID = (u8) pVol[ii]; + pRequest->PhysDiskNum = pDisk[ii].PhysDiskNum; + + status = read_page2(MPT_FLAGS_KEEP_MEM); + if (status == 0) { + uint *pdata = (uint *) mpiBlkPtr->replyFrameBufPtr; + pdata += 6; + tot_blks = cpu_to_le32(*pdata); + pdata++; + pdata++; + blks_left = cpu_to_le32(*pdata); + pdata++; + blks_done = tot_blks - blks_left; + printf("\tPhys Disk %d on Volume %d:\n\t\t0x%x of 0x%x Remaining,", + pDisk[ii].PhysDiskNum, pVol[ii], + blks_left, tot_blks ); + + printf(" Done 0x%x, (%d%%) Complete \n", + blks_done, ((blks_done >> 6) * 100) / (tot_blks >> 6)); + } + } + freeMem(); + return; +} + +static void print_information(void) { RaidVolumePage0_t *page; RaidPhysDiskPage0_t *phys; - //IOCPage5_t *ioc_hotspare; - char *VolumeTypes[] = { "IS", "IME", "IM" }; int i; - int ioc = 0; page = read_page(MPI_CONFIG_PAGETYPE_RAID_VOLUME, MPI_CONFIG_ACTION_PAGE_READ_CURRENT, - ioc, + ioc_unit, id_of_primary_device, MPI_RAIDVOLPAGE0_PAGEVERSION); if (0 == page->NumPhysDisks) { if (probe_id > 0) { id_of_primary_device = __probe_scsi_id(); if (-1 == id_of_primary_device) { - printf("Nothing found, contact the author\n"); - exit(EXIT_FAILURE); + mpt_printf("Nothing found, contact the author\n"); + mpt_exit(MPT_EXIT_UNKNOWN); } else { - printf("Found SCSI id=%d, use ''mpt-status " + mpt_printf("Found SCSI id=%d, use ''mpt-status " "-i %d`` to get more information.\n", id_of_primary_device, id_of_primary_device); - exit(EXIT_SUCCESS); + mpt_exit(MPT_EXIT_OKAY); } } else { - printf("%s\n", wrong_scsi_id); - exit(EXIT_FAILURE); + mpt_printf("%s\n", wrong_scsi_id); + mpt_exit(MPT_EXIT_UNKNOWN); } } if (1 == print_status_only) { - printf("vol_id %d", page->VolumeID); + mpt_printf("vol_id:%d", page->VolumeID); } else { - printf("ioc%d vol_id %d type %s, %d phy, %d GB", - page->VolumeIOC, - page->VolumeID, - page->VolumeType < sizeof(VolumeTypes) ? + mpt_printf("ioc:%d vol_id:%d type:%s raidlevel:%s num_disks:%d" + " size(GB):%d", + page->VolumeIOC, + page->VolumeID, + page->VolumeType < sizeof(VolumeTypes) ? VolumeTypes[page->VolumeType] : "unknown", - page->NumPhysDisks, - page->MaxLBA / (2 * 1024 * 1024)); - printf(", state"); - } - if (page->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL) - printf(" OPTIMAL"); - if (page->VolumeStatus.State & MPI_RAIDVOL0_STATUS_STATE_DEGRADED) - printf(" DEGRADED"); - if (page->VolumeStatus.State & MPI_RAIDVOL0_STATUS_STATE_FAILED) - printf(" FAILED"); + page->VolumeType < sizeof(VolumeTypes) ? + VolumeTypesHuman[page->VolumeType] : "", + page->NumPhysDisks, + page->MaxLBA / (2 * 1024 * 1024)); + mpt_printf(" state:"); + } + if (page->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL) { + mpt_exit_mask |= MPT_EXIT_VOL_OPTIMAL; + mpt_printf(" OPTIMAL"); + } else if (page->VolumeStatus.State == + MPI_RAIDVOL0_STATUS_STATE_DEGRADED) { + mpt_exit_mask |= MPT_EXIT_VOL_DEGRADED; + mpt_printf(" DEGRADED"); + } else if (page->VolumeStatus.State == + MPI_RAIDVOL0_STATUS_STATE_FAILED) { + mpt_exit_mask |= MPT_EXIT_VOL_FAILED; + mpt_printf(" FAILED"); + } else { + mpt_exit_mask |= MPT_EXIT_UNKNOWN; + mpt_printf(" UNKNOWN"); + } if (1 != print_status_only) { - printf(", flags"); + mpt_printf(" flags:"); if (page->VolumeStatus.Flags != 0) { if (page->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) - printf(" ENABLED"); + mpt_printf(" ENABLED"); if (page->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED) - printf(" QUIESCED"); + mpt_printf(" QUIESCED"); if (page->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) - printf(" RESYNC_IN_PROGRESS"); + mpt_printf(" RESYNC_IN_PROGRESS"); if (page->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE) - printf(" VOLUME_INACTIVE"); + mpt_printf(" VOLUME_INACTIVE"); } else { - printf(" NONE"); + mpt_printf(" NONE"); } } - printf("\n"); + mpt_printf("\n"); /* go through all physical disk of a found array */ for (i = 0; i < page->NumPhysDisks; ++i) { - char vendor[BIG]; - char productid[BIG]; - char rev[BIG]; + int ret; + char *vendor = NULL; + char *productid = NULL; + char *rev = NULL; phys = read_page(MPI_CONFIG_PAGETYPE_RAID_PHYSDISK, MPI_CONFIG_ACTION_PAGE_READ_CURRENT, - 0, + ioc_unit, page->PhysDisk[i].PhysDiskNum, MPI_RAIDPHYSDISKPAGE0_PAGEVERSION); - memset(vendor, 0, sizeof(vendor)); - memset(productid, 0, sizeof(productid)); - memset(rev, 0, sizeof(rev)); - /* the cast to char * is new for 1.1.5, maybe this breaks - something subtle since I haven't sanitized the headers yet - */ - strncpy(vendor, (char *) phys->InquiryData.VendorID, - sizeof(phys->InquiryData.VendorID)); - strncpy(productid, (char *) phys->InquiryData.ProductID, - sizeof(phys->InquiryData.ProductID)); - strncpy(rev, (char *) phys->InquiryData.ProductRevLevel, - sizeof(phys->InquiryData.ProductRevLevel)); - + ret = asprintf(&vendor, (void *)phys->InquiryData.VendorID); + if (ret > 0) vendor[ret-1] = '\0'; + ret = asprintf(&productid, (void *)phys->InquiryData.ProductID); + if (ret > 0) productid[ret-1] = '\0'; + ret = asprintf(&rev, (void *)phys->InquiryData.ProductRevLevel); + if (ret > 0) rev[ret-1] = '\0'; if (1 == print_status_only) { - printf("phys_id %d", phys->PhysDiskNum); + printf("phys_id:%d", phys->PhysDiskNum); } else { - printf("ioc%d phy %d scsi_id %d %s %s %s, %d GB", + printf("ioc:%d phys_id:%d scsi_id:%d vendor:%s " + "product_id:%s revision:%s size(GB):%d", phys->PhysDiskIOC, phys->PhysDiskNum, phys->PhysDiskID, vendor, productid, - rev, phys->MaxLBA / (2 * 1024 * 1024)); - printf(", state"); + rev, + phys->MaxLBA / (2 * 1024 * 1024)); + printf(" state:"); } - if (phys->PhysDiskStatus.State == MPI_PHYSDISK0_STATUS_ONLINE) + if (phys->PhysDiskStatus.State == + MPI_PHYSDISK0_STATUS_ONLINE) { + mpt_exit_mask |= MPT_EXIT_OKAY; printf(" ONLINE"); - if (phys->PhysDiskStatus.State == MPI_PHYSDISK0_STATUS_MISSING) + } else if (phys->PhysDiskStatus.State == + MPI_PHYSDISK0_STATUS_MISSING) { + mpt_exit_mask |= MPT_EXIT_PHYSDISK_ERROR; printf(" MISSING"); - if (phys->PhysDiskStatus.State == - MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE) + } else if (phys->PhysDiskStatus.State == + MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE) { + mpt_exit_mask |= MPT_EXIT_PHYSDISK_ERROR; printf(" NOT_COMPATIBLE"); - if (phys->PhysDiskStatus.State == MPI_PHYSDISK0_STATUS_FAILED) + } else if (phys->PhysDiskStatus.State == + MPI_PHYSDISK0_STATUS_FAILED) { + mpt_exit_mask |= MPT_EXIT_PHYSDISK_ERROR; printf(" FAILED"); - if (phys->PhysDiskStatus.State == - MPI_PHYSDISK0_STATUS_INITIALIZING) + } else if (phys->PhysDiskStatus.State == + MPI_PHYSDISK0_STATUS_INITIALIZING) { + mpt_exit_mask |= MPT_EXIT_PHYSDISK_WARN; printf(" INITIALIZING"); - if (phys->PhysDiskStatus.State == - MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED) + } else if (phys->PhysDiskStatus.State == + MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED) { + mpt_exit_mask |= MPT_EXIT_PHYSDISK_WARN; printf(" OFFLINE_REQUESTED"); - if (phys->PhysDiskStatus.State == - MPI_PHYSDISK0_STATUS_FAILED_REQUESTED) + } else if (phys->PhysDiskStatus.State == + MPI_PHYSDISK0_STATUS_FAILED_REQUESTED) { + mpt_exit_mask |= MPT_EXIT_PHYSDISK_ERROR; printf(" FAILED_REQUESTED"); - if (phys->PhysDiskStatus.State == - MPI_PHYSDISK0_STATUS_OTHER_OFFLINE) + } else if (phys->PhysDiskStatus.State == + MPI_PHYSDISK0_STATUS_OTHER_OFFLINE) { + mpt_exit_mask |= MPT_EXIT_PHYSDISK_WARN; printf(" OTHER_OFFLINE"); + } else { + mpt_exit_mask |= MPT_EXIT_UNKNOWN; + mpt_printf(" UNKNOWN"); + } if (1 != print_status_only) { - printf(", flags"); + mpt_printf(" flags:"); if (phys->PhysDiskStatus.Flags) { if (phys->PhysDiskStatus.Flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC) - printf(" OUT_OF_SYNC"); + mpt_printf(" OUT_OF_SYNC"); if (phys->PhysDiskStatus.Flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED) - printf(" QUIESCED"); + mpt_printf(" QUIESCED"); } else { - printf(" NONE"); + mpt_printf(" NONE"); } } - printf("\n"); - } - - /* go through all hotspares - ioc_hotspare = read_page(MPI_CONFIG_PAGETYPE_RAID_VOLUME, - MPI_CONFIG_ACTION_PAGE_READ_CURRENT, - 0, - id_of_primary_device, - MPI_IOCPAGE5_PAGEVERSION); - - //printf("Number of hotspares: %d\n", ioc_hotspare->NumHotSpares); - for (i = 0; i < ioc_hotspare->NumHotSpares; ++i) { - Ioc5HotSpare_t *hotspare; - - hotspare = read_page(MPI_CONFIG_PAGETYPE_RAID_PHYSDISK, - MPI_CONFIG_ACTION_PAGE_READ_CURRENT, - 0, - ioc_hotspare->HotSpare[i].PhysDiskNum, - MPI_IOCPAGE5_PAGEVERSION); - printf("Hotspare: phys_id %d state: %s\n", - hotspare->PhysDiskNum, - hotspare->Flags == MPI_IOC_PAGE_5_HOT_SPARE_ACTIVE ? - "ACTIVE" : "INACTIVE"); + mpt_printf("\n"); + free(vendor); + free(productid); + free(rev); } - */ } static void do_init(void) { @@ -398,16 +955,20 @@ save_errno = errno; perror("open /dev/mptctl"); if (save_errno == EACCES) { - fprintf(stderr, - " You need to be root to run this program\n"); + mpt_fprintf(stderr, + " You need to be root" + " to run this program\n"); } else if (save_errno == ENOENT) { - fprintf(stderr, " Try: mknod /dev/mptctl c 10 220\n"); + mpt_fprintf(stderr, + " Try: mknod /dev/mptctl c 10 220\n"); } else if (save_errno == ENODEV) { - fprintf(stderr, - " Are you sure your controller is supported by mptlinux?\n"); + mpt_fprintf(stderr, + " Are you sure your controller" + " is supported by mptlinux?\n"); } - fprintf(stderr, "Also make sure mptctl is loaded into the kernel\n"); - exit(EXIT_FAILURE); + mpt_fprintf(stderr, + "Make sure mptctl is loaded into the kernel\n"); + mpt_exit(MPT_EXIT_UNKNOWN|MPT_EXIT_NOCLOSE); } } @@ -429,7 +990,7 @@ break; case 'h': print_usage(progname); - exit(EXIT_SUCCESS); + mpt_exit(MPT_EXIT_OKAY); break; case 'p': probe_id = 1; @@ -448,7 +1009,7 @@ break; case 'V': print_version(); - exit(EXIT_SUCCESS); + mpt_exit(MPT_EXIT_OKAY); break; case 0: if (sel == ARG_M_A) { @@ -460,12 +1021,18 @@ break; default: print_usage(progname); - exit(EXIT_SUCCESS); + mpt_exit(MPT_EXIT_UNKNOWN); break; } } while (next_option != -1); do_init(); +#ifdef NEWSTYLE + __check_endianess(); + GetVolumeInfo(); + GetHotSpareInfo(); +#else print_information(); - exit(EXIT_SUCCESS); +#endif + return mpt_exit_mask; } diff -Nur mpt-status-1.1.6/mpt-status.h mpt-status-1.2.0-RC4/mpt-status.h --- mpt-status-1.1.6/mpt-status.h 2006-03-06 21:27:28.000000000 +0100 +++ mpt-status-1.2.0-RC4/mpt-status.h 2006-04-23 22:12:00.000000000 +0200 @@ -1,42 +1,71 @@ #ifndef _MPT_STATUS_H #define _MPT_STATUS_H -#ifdef REDHAT -# define __user -# define __kernel +#include +#ifdef __linux__ +#include #endif -/* This is for version 1.2.0 of mpt-status -#ifndef __x86_64__ -#include "pci.h" // config.h and header.h from pciutils package -#include "lsi/mpi_type.h" -#include "lsi/mpi.h" -#include "lsi/mpi_ioc.h" -#include "lsi/mpi_cnfg.h" -#include "mptctl.h" +#ifdef SANITIZED_KERNEL_HEADERS +#include "mpt-sanitized.h" #else -#include -#include "pci.h" // config.h and header.h from pciutils package -#include "sles.h" -#endif // __x86_64__ -*/ - +#ifndef __user +#define __user +#endif +#ifndef __kernel +#define __kernel +#endif #include "pci.h" // config.h and header.h from pciutils package #include "lsi/mpi_type.h" #include "lsi/mpi.h" #include "lsi/mpi_ioc.h" #include "lsi/mpi_cnfg.h" +//#include "lsi/mpi_init.h" +#include "lsi/mpi_raid.h" +//#include "lsi/mpi_tool.h" #include "mptctl.h" +#endif // SANITIZED_KERNEL_HEADERS -#define VERSION "1.1.5" +#define VERSION "1.2.0-RC4" #define BIG 1024 #define REALLYBIG 10240 #define PRINT_STATUS_ONLY 0 +#define REPLY_SIZE 128 +#define MPT_EXIT_OKAY (0) +#define MPT_EXIT_VOL_OPTIMAL (0) +#define MPT_EXIT_VOL_FAILED (1 << 1) +#define MPT_EXIT_VOL_DEGRADED (1 << 2) +#define MPT_EXIT_VOL_RESYNC (1 << 3) +#define MPT_EXIT_PHYSDISK_ERROR (1 << 4) +#define MPT_EXIT_PHYSDISK_WARN (1 << 5) +#define MPT_EXIT_UNKNOWN (1 << 0) + +#define MPT_EXIT_NOCLOSE (1 << 10) +#define MPT_EXIT_FREEMEM (1 << 11) + +#define DATA_DIR_NONE 0 +#define DATA_DIR_IN 1 +#define DATA_DIR_OUT 2 + +#define MPT_FLAGS_FREE_MEM 0x00 +#define MPT_FLAGS_KEEP_MEM 0x01 +#define MPT_FLAGS_DUMP_REPLY 0x02 +#define MPT_FLAGS_DUMP_DATA 0x04 + static char *wrong_scsi_id = "\nYou seem to have no SCSI disks attached to your HBA or you have\n" "them on a different scsi_id. To get your SCSI id, run:\n\n" " mpt-status -p\n"; +typedef struct _test_endianness { + union { + u32 foo; + u8 bar[4]; + } u; +} test_endianess_t; + +typedef struct mpt_ioctl_command mpiIoctlBlk_t; + #endif /* End of mpt-status.h */