diff --git a/sm5/scsicmds.c b/sm5/scsicmds.c index 5a650d8b9ba8f1e38fea8a680202259e846f4007..cd26820ca24a47ebda2fbe0d5128b57ee1c6922b 100644 --- a/sm5/scsicmds.c +++ b/sm5/scsicmds.c @@ -46,7 +46,7 @@ #include "utility.h" #include "extern.h" -const char *scsicmds_c_cvsid="$Id: scsicmds.c,v 1.58 2003/11/14 11:43:17 dpgilbert Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID; +const char *scsicmds_c_cvsid="$Id: scsicmds.c,v 1.59 2003/11/15 02:27:45 dpgilbert Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID; /* for passing global control variables */ extern smartmonctrl *con; @@ -1552,6 +1552,8 @@ int scsiSmartSelfTestAbort(int device) return scsiSendDiagnostic(device, SCSI_DIAG_ABORT_SELF_TEST, NULL, 0); } +/* Returns 0 and the expected duration of an extended self test (in seconds) + if successful; any other return value indicates a failure. */ int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len) { int err, offset, res; @@ -1559,7 +1561,7 @@ int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len) memset(buff, 0, sizeof(buff)); if (modese_len <= 6) { - if ((err = scsiModeSense(device, CONTROL_MODE_PAGE_PARAMETERS, + if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, MODE_PAGE_CONTROL_CURRENT, buff, sizeof(buff)))) { if (0 == err) @@ -1571,7 +1573,7 @@ int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len) } } if (10 == modese_len) { - err = scsiModeSense10(device, CONTROL_MODE_PAGE_PARAMETERS, + err = scsiModeSense10(device, CONTROL_MODE_PAGE, MODE_PAGE_CONTROL_CURRENT, buff, sizeof(buff)); if (err) @@ -1679,10 +1681,10 @@ void scsiDecodeNonMediumErrPage(unsigned char *resp, of the most recent failed self-test. Return value is negative if this function has a problem (typically -1), otherwise the bottom 8 bits are the number of failed self tests and the 16 bits above that - are the poweron hour of the most recent failure. Note aborted self - tests (typically by the user) are not considered failures. - See Working Draft SCSI Primary Commands - 3 (SPC-3) section 7.2.10 - T10/1416-D Rev 15 */ + are the poweron hour of the most recent failure. Note: aborted self + tests (typically by the user) and self tests in progress are not + considered failures. See Working Draft SCSI Primary Commands - 3 + (SPC-3) section 7.2.10 T10/1416-D Rev 15 */ int scsiCountFailedSelfTests(int fd, int noisy) { int num, k, n, err, res, fails, fail_hour; @@ -1730,3 +1732,37 @@ int scsiCountFailedSelfTests(int fd, int noisy) return (fail_hour << 8) + fails; } + +/* Returns a negative value if failed to fetch Contol mode page or it was + malformed. Returns 0 if GLTSD bit is zero and returns 1 if the GLTSD + bit is set. */ +int scsiFetchControlGLTSD(int device, int modese_len) +{ + int err, offset; + UINT8 buff[64]; + + memset(buff, 0, sizeof(buff)); + if (modese_len <= 6) { + if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, + MODE_PAGE_CONTROL_CURRENT, + buff, sizeof(buff)))) { + if (0 == err) + modese_len = 6; + else if (SIMPLE_ERR_BAD_OPCODE == err) + modese_len = 10; + else + return err; + } + } + if (10 == modese_len) { + err = scsiModeSense10(device, CONTROL_MODE_PAGE, + MODE_PAGE_CONTROL_CURRENT, + buff, sizeof(buff)); + if (err) + return err; + } + offset = scsiModePageOffset(buff, sizeof(buff), modese_len); + if ((offset >= 0) && (buff[offset + 1] >= 0xa)) + return (buff[offset + 2] & 2) ? 1 : 0; + return -EINVAL; +} diff --git a/sm5/scsicmds.cpp b/sm5/scsicmds.cpp index eb50f1b5b6ce66a05fd14803df132d9c1478f884..b60d8958869cded983f05d5989ebb7c626e5be22 100644 --- a/sm5/scsicmds.cpp +++ b/sm5/scsicmds.cpp @@ -46,7 +46,7 @@ #include "utility.h" #include "extern.h" -const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.58 2003/11/14 11:43:17 dpgilbert Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID; +const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.59 2003/11/15 02:27:45 dpgilbert Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID; /* for passing global control variables */ extern smartmonctrl *con; @@ -1552,6 +1552,8 @@ int scsiSmartSelfTestAbort(int device) return scsiSendDiagnostic(device, SCSI_DIAG_ABORT_SELF_TEST, NULL, 0); } +/* Returns 0 and the expected duration of an extended self test (in seconds) + if successful; any other return value indicates a failure. */ int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len) { int err, offset, res; @@ -1559,7 +1561,7 @@ int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len) memset(buff, 0, sizeof(buff)); if (modese_len <= 6) { - if ((err = scsiModeSense(device, CONTROL_MODE_PAGE_PARAMETERS, + if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, MODE_PAGE_CONTROL_CURRENT, buff, sizeof(buff)))) { if (0 == err) @@ -1571,7 +1573,7 @@ int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len) } } if (10 == modese_len) { - err = scsiModeSense10(device, CONTROL_MODE_PAGE_PARAMETERS, + err = scsiModeSense10(device, CONTROL_MODE_PAGE, MODE_PAGE_CONTROL_CURRENT, buff, sizeof(buff)); if (err) @@ -1679,10 +1681,10 @@ void scsiDecodeNonMediumErrPage(unsigned char *resp, of the most recent failed self-test. Return value is negative if this function has a problem (typically -1), otherwise the bottom 8 bits are the number of failed self tests and the 16 bits above that - are the poweron hour of the most recent failure. Note aborted self - tests (typically by the user) are not considered failures. - See Working Draft SCSI Primary Commands - 3 (SPC-3) section 7.2.10 - T10/1416-D Rev 15 */ + are the poweron hour of the most recent failure. Note: aborted self + tests (typically by the user) and self tests in progress are not + considered failures. See Working Draft SCSI Primary Commands - 3 + (SPC-3) section 7.2.10 T10/1416-D Rev 15 */ int scsiCountFailedSelfTests(int fd, int noisy) { int num, k, n, err, res, fails, fail_hour; @@ -1730,3 +1732,37 @@ int scsiCountFailedSelfTests(int fd, int noisy) return (fail_hour << 8) + fails; } + +/* Returns a negative value if failed to fetch Contol mode page or it was + malformed. Returns 0 if GLTSD bit is zero and returns 1 if the GLTSD + bit is set. */ +int scsiFetchControlGLTSD(int device, int modese_len) +{ + int err, offset; + UINT8 buff[64]; + + memset(buff, 0, sizeof(buff)); + if (modese_len <= 6) { + if ((err = scsiModeSense(device, CONTROL_MODE_PAGE, + MODE_PAGE_CONTROL_CURRENT, + buff, sizeof(buff)))) { + if (0 == err) + modese_len = 6; + else if (SIMPLE_ERR_BAD_OPCODE == err) + modese_len = 10; + else + return err; + } + } + if (10 == modese_len) { + err = scsiModeSense10(device, CONTROL_MODE_PAGE, + MODE_PAGE_CONTROL_CURRENT, + buff, sizeof(buff)); + if (err) + return err; + } + offset = scsiModePageOffset(buff, sizeof(buff), modese_len); + if ((offset >= 0) && (buff[offset + 1] >= 0xa)) + return (buff[offset + 2] & 2) ? 1 : 0; + return -EINVAL; +} diff --git a/sm5/scsicmds.h b/sm5/scsicmds.h index 83533772c8da835d44bb098e59eeba4e2d58e146..823bc75b8163ae8338323fa63ae749c1436bc0d7 100644 --- a/sm5/scsicmds.h +++ b/sm5/scsicmds.h @@ -32,7 +32,7 @@ #ifndef SCSICMDS_H_ #define SCSICMDS_H_ -#define SCSICMDS_H_CVSID "$Id: scsicmds.h,v 1.37 2003/11/14 11:40:59 dpgilbert Exp $\n" +#define SCSICMDS_H_CVSID "$Id: scsicmds.h,v 1.38 2003/11/15 02:26:26 dpgilbert Exp $\n" #include <stdio.h> #include <stdlib.h> @@ -184,7 +184,7 @@ Documentation, see http://www.storage.ibm.com/techsup/hddtech/prodspecs.htm */ #define CACHING_PARAMETERS 0x08 #define PERIPHERAL_DEVICE 0x09 #define XOR_CONTROL_MODE_PARAMETERS 0x10 -#define CONTROL_MODE_PAGE_PARAMETERS 0x0a +#define CONTROL_MODE_PAGE 0x0a #define MEDIUM_TYPES_SUPPORTED 0x0b #define NOTCH_PARAMETERS 0x0c #define POWER_CONDITION_PARAMETERS 0x0d @@ -298,8 +298,10 @@ void scsiDecodeErrCounterPage(unsigned char * resp, struct scsiErrorCounter *ecp); void scsiDecodeNonMediumErrPage(unsigned char * resp, struct scsiNonMediumError *nmep); -int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len); +int scsiFetchExtendedSelfTestTime(int device, int * durationSec, + int modese_len); int scsiCountFailedSelfTests(int fd, int noisy); +int scsiFetchControlGLTSD(int device, int modese_len); /* T10 Standard IE Additional Sense Code strings taken from t10.org */ diff --git a/sm5/scsiprint.c b/sm5/scsiprint.c index fe2a810b80eb49819d87dc58fd7d3b01d2193a69..8203f1cef80931959b9717a8ee9b6a895e64e9c4 100644 --- a/sm5/scsiprint.c +++ b/sm5/scsiprint.c @@ -40,7 +40,7 @@ #define GBUF_SIZE 65535 -const char* scsiprint_c_cvsid="$Id: scsiprint.c,v 1.57 2003/11/14 11:44:26 dpgilbert Exp $" +const char* scsiprint_c_cvsid="$Id: scsiprint.c,v 1.58 2003/11/15 02:29:16 dpgilbert Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID; // control block which points to external global control variables @@ -855,8 +855,13 @@ int scsiPrintMain(const char *dev_name, int fd) if (gSeagateFactoryLPage) scsiPrintSeagateFactoryLPage(fd); } - if (con->smarterrorlog) + if (con->smarterrorlog) { scsiPrintErrorCounterLog(fd); + if (1 == scsiFetchControlGLTSD(fd, modese_len)) + pout("Warning: log page contents are potentially being reset" + " at each power up\n [Control mode page, GLTSD " + "(global logging target save disable) set]\n"); + } if (con->smartselftestlog) { if (! checkedSupportedLogPages) scsiGetSupportedLogPages(fd); diff --git a/sm5/scsiprint.cpp b/sm5/scsiprint.cpp index 3b6e9ce02857ab3615f62dd41174bb8db3a7b8f0..800020644086e79524a3e062b7635734c5890c8e 100644 --- a/sm5/scsiprint.cpp +++ b/sm5/scsiprint.cpp @@ -40,7 +40,7 @@ #define GBUF_SIZE 65535 -const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.57 2003/11/14 11:44:26 dpgilbert Exp $" +const char* scsiprint_c_cvsid="$Id: scsiprint.cpp,v 1.58 2003/11/15 02:29:16 dpgilbert Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID SCSIPRINT_H_CVSID SMARTCTL_H_CVSID UTILITY_H_CVSID; // control block which points to external global control variables @@ -855,8 +855,13 @@ int scsiPrintMain(const char *dev_name, int fd) if (gSeagateFactoryLPage) scsiPrintSeagateFactoryLPage(fd); } - if (con->smarterrorlog) + if (con->smarterrorlog) { scsiPrintErrorCounterLog(fd); + if (1 == scsiFetchControlGLTSD(fd, modese_len)) + pout("Warning: log page contents are potentially being reset" + " at each power up\n [Control mode page, GLTSD " + "(global logging target save disable) set]\n"); + } if (con->smartselftestlog) { if (! checkedSupportedLogPages) scsiGetSupportedLogPages(fd);