diff -Nur mpt-status-1.2.0-RC3/mpt-status.c mpt-status-1.2.0-RC4/mpt-status.c --- mpt-status-1.2.0-RC3/mpt-status.c 2006-04-23 20:27:12.000000000 +0200 +++ mpt-status-1.2.0-RC4/mpt-status.c 2006-04-23 22:15:36.000000000 +0200 @@ -102,12 +102,39 @@ static char *VolumeTypes[] = { "IS", "IME", "IM" }; static char *VolumeTypesHuman[] = { "0", "1E", "1" }; //Raid levels mpiIoctlBlk_t *mpiBlkPtr = NULL; -unsigned char g_command[1024]; -char g_data[4*1024]; -char g_reply[1024]; -char g_sense[256]; +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; @@ -140,13 +167,13 @@ static int allocDataFrame(int dir) { if (dir == DATA_DIR_OUT) { - if (mpiBlkPtr->dataOutSize > (4*1024)) + 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*1024)) + if (mpiBlkPtr->dataInSize > (4*BIG)) return 1; mpiBlkPtr->dataInBufPtr = (char *)&g_data; memset(mpiBlkPtr->dataInBufPtr, 0, mpiBlkPtr->dataInSize); @@ -164,7 +191,7 @@ mpiIoctlBlk_t *allocIoctlBlk(uint numBytes) { int blksize = sizeof(mpiIoctlBlk_t) + numBytes; - if (blksize >= 1024) { + if (blksize >= BIG) { return NULL; } mpiBlkPtr = (mpiIoctlBlk_t *) &g_command; @@ -220,19 +247,6 @@ mpt_printf("Version: %s\n", VERSION); } -/* -static void checkForLibraryMode(void) { - char *env; - - // Library usage detection - env = getenv("__MPT_STATUS_LIB"); - if (env != NULL) { - printf("Setting library mode: env = %s\n", env); - library_mode = 1; - } -} -*/ - static void *read_page(unsigned int pagetype, unsigned int pagewhich, unsigned int pagenumber, unsigned int address, unsigned int version) { @@ -244,7 +258,6 @@ struct mpt_ioctl_command *cmd = NULL; Config_t *config_request; ConfigReply_t *config_reply; - //MPIDefaultReply_t *config_reply; #ifdef VAR_DIV unsigned short div = sizeof(char *); /* this is fishy */ #else @@ -307,15 +320,6 @@ 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) { - mpt_fprintf(stderr, "reply too big\n"); - mpt_exit(MPT_EXIT_UNKNOWN); - } - */ - if (-1 == ioctl(m, MPTCOMMAND, cmd)) { perror("MPI_FUNCTION_CONFIG (get page)"); mpt_exit(MPT_EXIT_UNKNOWN); @@ -330,7 +334,7 @@ return in; } -static int __probe_scsi_id() { +static int __probe_scsi_id(void) { int scsi_id; RaidVolumePage0_t *page; @@ -499,15 +503,12 @@ pdisk_cnt += pRVP0->NumPhysDisks; } freeMem(); - - /* needs to be done later if (pdisk_cnt > 0) { GetPhysDiskInfo((RaidVol0PhysDisk_t *) &disk_num, pdisk_cnt); } - GetResyncPercentage((RaidVol0PhysDisk_t *) &disk_num, - (unsigned char *) &pdisk_vol, 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"); } @@ -515,10 +516,271 @@ return; } -static void print_information() { +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; int i; page = read_page(MPI_CONFIG_PAGETYPE_RAID_VOLUME, @@ -680,29 +942,6 @@ free(productid); free(rev); } - - /* 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); - - //mpt_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); - mpt_printf("Hotspare: phys_id %d state: %s\n", - hotspare->PhysDiskNum, - hotspare->Flags == MPI_IOC_PAGE_5_HOT_SPARE_ACTIVE ? - "ACTIVE" : "INACTIVE"); - } - */ } static void do_init(void) { @@ -788,9 +1027,10 @@ } while (next_option != -1); do_init(); - //checkForLibraryMode(); #ifdef NEWSTYLE + __check_endianess(); GetVolumeInfo(); + GetHotSpareInfo(); #else print_information(); #endif diff -Nur mpt-status-1.2.0-RC3/mpt-status.h mpt-status-1.2.0-RC4/mpt-status.h --- mpt-status-1.2.0-RC3/mpt-status.h 2006-04-23 19:36:48.000000000 +0200 +++ mpt-status-1.2.0-RC4/mpt-status.h 2006-04-23 22:12:00.000000000 +0200 @@ -21,12 +21,12 @@ #include "lsi/mpi_ioc.h" #include "lsi/mpi_cnfg.h" //#include "lsi/mpi_init.h" -//#include "lsi/mpi_raid.h" +#include "lsi/mpi_raid.h" //#include "lsi/mpi_tool.h" #include "mptctl.h" #endif // SANITIZED_KERNEL_HEADERS -#define VERSION "1.2.0-RC3" +#define VERSION "1.2.0-RC4" #define BIG 1024 #define REALLYBIG 10240 @@ -54,8 +54,6 @@ #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"