Skip to content
Snippets Groups Projects
Commit 2cb52ff3 authored by dpgilbert's avatar dpgilbert
Browse files

pass in mode sense cmd length (so it can be remembered), trip temperature

from IBM IE lpage extension


git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@1229 4ea69e1a-61f1-4043-bf83-b5c94c648137
parent 59d510e5
No related branches found
No related tags found
No related merge requests found
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#include "utility.h" #include "utility.h"
#include "extern.h" #include "extern.h"
const char *scsicmds_c_cvsid="$Id: scsicmds.c,v 1.57 2003/11/13 07:40:43 dpgilbert Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID; 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;
/* for passing global control variables */ /* for passing global control variables */
extern smartmonctrl *con; extern smartmonctrl *con;
...@@ -695,13 +695,13 @@ int scsiTestUnitReady(int device) ...@@ -695,13 +695,13 @@ int scsiTestUnitReady(int device)
/* Offset into mode sense (6 or 10 byte) response that actual mode page /* Offset into mode sense (6 or 10 byte) response that actual mode page
* starts at (relative to resp[0]). Returns -1 if problem */ * starts at (relative to resp[0]). Returns -1 if problem */
int scsiModePageOffset(const UINT8 * resp, int len, int modese_10) int scsiModePageOffset(const UINT8 * resp, int len, int modese_len)
{ {
int resp_len, bd_len; int resp_len, bd_len;
int offset = -1; int offset = -1;
if (resp) { if (resp) {
if (modese_10) { if (10 == modese_len) {
resp_len = (resp[0] << 8) + resp[1] + 2; resp_len = (resp[0] << 8) + resp[1] + 2;
bd_len = (resp[6] << 8) + resp[7]; bd_len = (resp[6] << 8) + resp[7];
offset = bd_len + 8; offset = bd_len + 8;
...@@ -735,33 +735,41 @@ int scsiModePageOffset(const UINT8 * resp, int len, int modese_10) ...@@ -735,33 +735,41 @@ int scsiModePageOffset(const UINT8 * resp, int len, int modese_10)
* tries a 10 byte MODE SENSE command. Returns 0 if successful, a positive * tries a 10 byte MODE SENSE command. Returns 0 if successful, a positive
* number if a known error (see SIMPLE_ERR_ ...) or a negative errno * number if a known error (see SIMPLE_ERR_ ...) or a negative errno
* value. */ * value. */
int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp) int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp, int modese_len)
{ {
int err; int err = 0;
memset(iecp, 0, sizeof(*iecp)); memset(iecp, 0, sizeof(*iecp));
iecp->modese_len = modese_len;
iecp->requestedCurrent = 1; iecp->requestedCurrent = 1;
if (iecp->modese_len <= 6) {
if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL, if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
MODE_PAGE_CONTROL_CURRENT, MODE_PAGE_CONTROL_CURRENT,
iecp->raw_curr, sizeof(iecp->raw_curr)))) { iecp->raw_curr, sizeof(iecp->raw_curr)))) {
if (SIMPLE_ERR_BAD_OPCODE == err) { /* so try 10 byte mode sense */
err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
MODE_PAGE_CONTROL_CURRENT,
iecp->raw_curr, sizeof(iecp->raw_curr));
if (0 == err) if (0 == err)
iecp->modese_10 = 1; iecp->modese_len = 6;
else if (SIMPLE_ERR_BAD_OPCODE == err)
iecp->modese_len = 10;
else else
return err; return err;
} else }
}
if (10 == iecp->modese_len) {
err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
MODE_PAGE_CONTROL_CURRENT,
iecp->raw_curr, sizeof(iecp->raw_curr));
if (err) {
iecp->modese_len = 0;
return err; return err;
} }
}
iecp->gotCurrent = 1; iecp->gotCurrent = 1;
iecp->requestedChangeable = 1; iecp->requestedChangeable = 1;
if (iecp->modese_10) if (10 == iecp->modese_len)
err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL, err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
MODE_PAGE_CONTROL_CHANGEABLE, MODE_PAGE_CONTROL_CHANGEABLE,
iecp->raw_chg, sizeof(iecp->raw_chg)); iecp->raw_chg, sizeof(iecp->raw_chg));
else else if (6 == iecp->modese_len)
err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL, err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
MODE_PAGE_CONTROL_CHANGEABLE, MODE_PAGE_CONTROL_CHANGEABLE,
iecp->raw_chg, sizeof(iecp->raw_chg)); iecp->raw_chg, sizeof(iecp->raw_chg));
...@@ -777,7 +785,7 @@ int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp) ...@@ -777,7 +785,7 @@ int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp)
if (iecp && iecp->gotCurrent) { if (iecp && iecp->gotCurrent) {
offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr), offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
iecp->modese_10); iecp->modese_len);
if (offset >= 0) if (offset >= 0)
return (iecp->raw_curr[offset + 2] & DEXCPT_ENABLE) ? 0 : 1; return (iecp->raw_curr[offset + 2] & DEXCPT_ENABLE) ? 0 : 1;
else else
...@@ -792,7 +800,7 @@ int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp) ...@@ -792,7 +800,7 @@ int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp)
if (iecp && iecp->gotCurrent) { if (iecp && iecp->gotCurrent) {
offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr), offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
iecp->modese_10); iecp->modese_len);
if (offset >= 0) if (offset >= 0)
return (iecp->raw_curr[offset + 2] & EWASC_ENABLE) ? 1 : 0; return (iecp->raw_curr[offset + 2] & EWASC_ENABLE) ? 1 : 0;
else else
...@@ -819,19 +827,20 @@ int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp) ...@@ -819,19 +827,20 @@ int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp)
int scsiSetExceptionControlAndWarning(int device, int enabled, int scsiSetExceptionControlAndWarning(int device, int enabled,
const struct scsi_iec_mode_page *iecp) const struct scsi_iec_mode_page *iecp)
{ {
int k, offset, err; int k, offset;
int err = 0;
UINT8 rout[SCSI_IECMP_RAW_LEN]; UINT8 rout[SCSI_IECMP_RAW_LEN];
int sp, eCEnabled, wEnabled; int sp, eCEnabled, wEnabled;
if ((! iecp) || (! iecp->gotCurrent)) if ((! iecp) || (! iecp->gotCurrent))
return -EINVAL; return -EINVAL;
offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr), offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
iecp->modese_10); iecp->modese_len);
if (offset < 0) if (offset < 0)
return -EINVAL; return -EINVAL;
memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN); memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);
rout[0] = 0; /* Mode Data Length reserved in MODE SELECTs */ rout[0] = 0; /* Mode Data Length reserved in MODE SELECTs */
if (iecp->modese_10) if (10 == iecp->modese_len)
rout[1] = 0; rout[1] = 0;
sp = (rout[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */ sp = (rout[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */
rout[offset] &= 0x7f; /* mask off PS bit */ rout[offset] &= 0x7f; /* mask off PS bit */
...@@ -880,10 +889,10 @@ int scsiSetExceptionControlAndWarning(int device, int enabled, ...@@ -880,10 +889,10 @@ int scsiSetExceptionControlAndWarning(int device, int enabled,
rout[offset + 2] &= TEST_DISABLE;/* clear TEST bit for spec */ rout[offset + 2] &= TEST_DISABLE;/* clear TEST bit for spec */
} }
} }
if (iecp->modese_10) if (10 == iecp->modese_len)
err = scsiModeSelect10(device, INFORMATIONAL_EXCEPTIONS_CONTROL, err = scsiModeSelect10(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
sp, rout, sizeof(rout)); sp, rout, sizeof(rout));
else else if (6 == iecp->modese_len)
err = scsiModeSelect(device, INFORMATIONAL_EXCEPTIONS_CONTROL, err = scsiModeSelect(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
sp, rout, sizeof(rout)); sp, rout, sizeof(rout));
return err; return err;
...@@ -912,18 +921,20 @@ int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp) ...@@ -912,18 +921,20 @@ int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp)
* Returns 0 if ok, else error number. A current temperature of 255 * Returns 0 if ok, else error number. A current temperature of 255
* (Celsius) implies that the temperature not available. */ * (Celsius) implies that the temperature not available. */
int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage, int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp) UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp,
UINT8 *triptemp)
{ {
UINT8 tBuf[252]; UINT8 tBuf[252];
struct scsi_sense_disect sense_info; struct scsi_sense_disect sense_info;
int err; int err;
int temperatureSet = 0; int temperatureSet = 0;
unsigned short pagesize; unsigned short pagesize;
UINT8 currTemp, tripTemp; UINT8 currTemp, trTemp;
*asc = 0; *asc = 0;
*ascq = 0; *ascq = 0;
*currenttemp = 0; *currenttemp = 0;
*triptemp = 0;
memset(tBuf,0,sizeof(tBuf)); // need to clear stack space of junk memset(tBuf,0,sizeof(tBuf)); // need to clear stack space of junk
memset(&sense_info, 0, sizeof(sense_info)); memset(&sense_info, 0, sizeof(sense_info));
if (hasIELogPage) { if (hasIELogPage) {
...@@ -941,9 +952,11 @@ int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage, ...@@ -941,9 +952,11 @@ int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
if (tBuf[7] > 1) { if (tBuf[7] > 1) {
sense_info.asc = tBuf[8]; sense_info.asc = tBuf[8];
sense_info.ascq = tBuf[9]; sense_info.ascq = tBuf[9];
if (tBuf[7] > 2) { if (! hasTempLogPage) {
if (tBuf[7] > 2)
*currenttemp = tBuf[10]; *currenttemp = tBuf[10];
temperatureSet = 1; if (tBuf[7] > 3) /* IBM extension in SMART (IE) lpage */
*triptemp = tBuf[11];
} }
} }
} }
...@@ -957,8 +970,10 @@ int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage, ...@@ -957,8 +970,10 @@ int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
*asc = sense_info.asc; *asc = sense_info.asc;
*ascq = sense_info.ascq; *ascq = sense_info.ascq;
if ((! temperatureSet) && hasTempLogPage) { if ((! temperatureSet) && hasTempLogPage) {
if (0 == scsiGetTemp(device, &currTemp, &tripTemp)) if (0 == scsiGetTemp(device, &currTemp, &trTemp)) {
*currenttemp = currTemp; *currenttemp = currTemp;
*triptemp = trTemp;
}
} }
return 0; return 0;
} }
...@@ -1537,28 +1552,32 @@ int scsiSmartSelfTestAbort(int device) ...@@ -1537,28 +1552,32 @@ int scsiSmartSelfTestAbort(int device)
return scsiSendDiagnostic(device, SCSI_DIAG_ABORT_SELF_TEST, NULL, 0); return scsiSendDiagnostic(device, SCSI_DIAG_ABORT_SELF_TEST, NULL, 0);
} }
int scsiFetchExtendedSelfTestTime(int device, int * durationSec) int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len)
{ {
int err, offset, res; int err, offset, res;
UINT8 buff[64]; UINT8 buff[64];
int modese_10 = 0;
memset(buff, 0, sizeof(buff)); memset(buff, 0, sizeof(buff));
if (modese_len <= 6) {
if ((err = scsiModeSense(device, CONTROL_MODE_PAGE_PARAMETERS, if ((err = scsiModeSense(device, CONTROL_MODE_PAGE_PARAMETERS,
MODE_PAGE_CONTROL_CURRENT, MODE_PAGE_CONTROL_CURRENT,
buff, sizeof(buff)))) { buff, sizeof(buff)))) {
if (2 == err) { /* opcode no good so try 10 byte mode sense */
err = scsiModeSense10(device, CONTROL_MODE_PAGE_PARAMETERS,
MODE_PAGE_CONTROL_CURRENT,
buff, sizeof(buff));
if (0 == err) if (0 == err)
modese_10 = 1; modese_len = 6;
else if (SIMPLE_ERR_BAD_OPCODE == err)
modese_len = 10;
else else
return err; return err;
} else }
}
if (10 == modese_len) {
err = scsiModeSense10(device, CONTROL_MODE_PAGE_PARAMETERS,
MODE_PAGE_CONTROL_CURRENT,
buff, sizeof(buff));
if (err)
return err; return err;
} }
offset = scsiModePageOffset(buff, sizeof(buff), modese_10); offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
if (offset < 0) if (offset < 0)
return -EINVAL; return -EINVAL;
if (buff[offset + 1] >= 0xa) { if (buff[offset + 1] >= 0xa) {
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#include "utility.h" #include "utility.h"
#include "extern.h" #include "extern.h"
const char *scsicmds_c_cvsid="$Id: scsicmds.cpp,v 1.57 2003/11/13 07:40:43 dpgilbert Exp $" EXTERN_H_CVSID SCSICMDS_H_CVSID; 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;
/* for passing global control variables */ /* for passing global control variables */
extern smartmonctrl *con; extern smartmonctrl *con;
...@@ -695,13 +695,13 @@ int scsiTestUnitReady(int device) ...@@ -695,13 +695,13 @@ int scsiTestUnitReady(int device)
/* Offset into mode sense (6 or 10 byte) response that actual mode page /* Offset into mode sense (6 or 10 byte) response that actual mode page
* starts at (relative to resp[0]). Returns -1 if problem */ * starts at (relative to resp[0]). Returns -1 if problem */
int scsiModePageOffset(const UINT8 * resp, int len, int modese_10) int scsiModePageOffset(const UINT8 * resp, int len, int modese_len)
{ {
int resp_len, bd_len; int resp_len, bd_len;
int offset = -1; int offset = -1;
if (resp) { if (resp) {
if (modese_10) { if (10 == modese_len) {
resp_len = (resp[0] << 8) + resp[1] + 2; resp_len = (resp[0] << 8) + resp[1] + 2;
bd_len = (resp[6] << 8) + resp[7]; bd_len = (resp[6] << 8) + resp[7];
offset = bd_len + 8; offset = bd_len + 8;
...@@ -735,33 +735,41 @@ int scsiModePageOffset(const UINT8 * resp, int len, int modese_10) ...@@ -735,33 +735,41 @@ int scsiModePageOffset(const UINT8 * resp, int len, int modese_10)
* tries a 10 byte MODE SENSE command. Returns 0 if successful, a positive * tries a 10 byte MODE SENSE command. Returns 0 if successful, a positive
* number if a known error (see SIMPLE_ERR_ ...) or a negative errno * number if a known error (see SIMPLE_ERR_ ...) or a negative errno
* value. */ * value. */
int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp) int scsiFetchIECmpage(int device, struct scsi_iec_mode_page *iecp, int modese_len)
{ {
int err; int err = 0;
memset(iecp, 0, sizeof(*iecp)); memset(iecp, 0, sizeof(*iecp));
iecp->modese_len = modese_len;
iecp->requestedCurrent = 1; iecp->requestedCurrent = 1;
if (iecp->modese_len <= 6) {
if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL, if ((err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
MODE_PAGE_CONTROL_CURRENT, MODE_PAGE_CONTROL_CURRENT,
iecp->raw_curr, sizeof(iecp->raw_curr)))) { iecp->raw_curr, sizeof(iecp->raw_curr)))) {
if (SIMPLE_ERR_BAD_OPCODE == err) { /* so try 10 byte mode sense */
err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
MODE_PAGE_CONTROL_CURRENT,
iecp->raw_curr, sizeof(iecp->raw_curr));
if (0 == err) if (0 == err)
iecp->modese_10 = 1; iecp->modese_len = 6;
else if (SIMPLE_ERR_BAD_OPCODE == err)
iecp->modese_len = 10;
else else
return err; return err;
} else }
}
if (10 == iecp->modese_len) {
err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
MODE_PAGE_CONTROL_CURRENT,
iecp->raw_curr, sizeof(iecp->raw_curr));
if (err) {
iecp->modese_len = 0;
return err; return err;
} }
}
iecp->gotCurrent = 1; iecp->gotCurrent = 1;
iecp->requestedChangeable = 1; iecp->requestedChangeable = 1;
if (iecp->modese_10) if (10 == iecp->modese_len)
err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL, err = scsiModeSense10(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
MODE_PAGE_CONTROL_CHANGEABLE, MODE_PAGE_CONTROL_CHANGEABLE,
iecp->raw_chg, sizeof(iecp->raw_chg)); iecp->raw_chg, sizeof(iecp->raw_chg));
else else if (6 == iecp->modese_len)
err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL, err = scsiModeSense(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
MODE_PAGE_CONTROL_CHANGEABLE, MODE_PAGE_CONTROL_CHANGEABLE,
iecp->raw_chg, sizeof(iecp->raw_chg)); iecp->raw_chg, sizeof(iecp->raw_chg));
...@@ -777,7 +785,7 @@ int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp) ...@@ -777,7 +785,7 @@ int scsi_IsExceptionControlEnabled(const struct scsi_iec_mode_page *iecp)
if (iecp && iecp->gotCurrent) { if (iecp && iecp->gotCurrent) {
offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr), offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
iecp->modese_10); iecp->modese_len);
if (offset >= 0) if (offset >= 0)
return (iecp->raw_curr[offset + 2] & DEXCPT_ENABLE) ? 0 : 1; return (iecp->raw_curr[offset + 2] & DEXCPT_ENABLE) ? 0 : 1;
else else
...@@ -792,7 +800,7 @@ int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp) ...@@ -792,7 +800,7 @@ int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp)
if (iecp && iecp->gotCurrent) { if (iecp && iecp->gotCurrent) {
offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr), offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
iecp->modese_10); iecp->modese_len);
if (offset >= 0) if (offset >= 0)
return (iecp->raw_curr[offset + 2] & EWASC_ENABLE) ? 1 : 0; return (iecp->raw_curr[offset + 2] & EWASC_ENABLE) ? 1 : 0;
else else
...@@ -819,19 +827,20 @@ int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp) ...@@ -819,19 +827,20 @@ int scsi_IsWarningEnabled(const struct scsi_iec_mode_page *iecp)
int scsiSetExceptionControlAndWarning(int device, int enabled, int scsiSetExceptionControlAndWarning(int device, int enabled,
const struct scsi_iec_mode_page *iecp) const struct scsi_iec_mode_page *iecp)
{ {
int k, offset, err; int k, offset;
int err = 0;
UINT8 rout[SCSI_IECMP_RAW_LEN]; UINT8 rout[SCSI_IECMP_RAW_LEN];
int sp, eCEnabled, wEnabled; int sp, eCEnabled, wEnabled;
if ((! iecp) || (! iecp->gotCurrent)) if ((! iecp) || (! iecp->gotCurrent))
return -EINVAL; return -EINVAL;
offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr), offset = scsiModePageOffset(iecp->raw_curr, sizeof(iecp->raw_curr),
iecp->modese_10); iecp->modese_len);
if (offset < 0) if (offset < 0)
return -EINVAL; return -EINVAL;
memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN); memcpy(rout, iecp->raw_curr, SCSI_IECMP_RAW_LEN);
rout[0] = 0; /* Mode Data Length reserved in MODE SELECTs */ rout[0] = 0; /* Mode Data Length reserved in MODE SELECTs */
if (iecp->modese_10) if (10 == iecp->modese_len)
rout[1] = 0; rout[1] = 0;
sp = (rout[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */ sp = (rout[offset] & 0x80) ? 1 : 0; /* PS bit becomes 'SELECT's SP bit */
rout[offset] &= 0x7f; /* mask off PS bit */ rout[offset] &= 0x7f; /* mask off PS bit */
...@@ -880,10 +889,10 @@ int scsiSetExceptionControlAndWarning(int device, int enabled, ...@@ -880,10 +889,10 @@ int scsiSetExceptionControlAndWarning(int device, int enabled,
rout[offset + 2] &= TEST_DISABLE;/* clear TEST bit for spec */ rout[offset + 2] &= TEST_DISABLE;/* clear TEST bit for spec */
} }
} }
if (iecp->modese_10) if (10 == iecp->modese_len)
err = scsiModeSelect10(device, INFORMATIONAL_EXCEPTIONS_CONTROL, err = scsiModeSelect10(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
sp, rout, sizeof(rout)); sp, rout, sizeof(rout));
else else if (6 == iecp->modese_len)
err = scsiModeSelect(device, INFORMATIONAL_EXCEPTIONS_CONTROL, err = scsiModeSelect(device, INFORMATIONAL_EXCEPTIONS_CONTROL,
sp, rout, sizeof(rout)); sp, rout, sizeof(rout));
return err; return err;
...@@ -912,18 +921,20 @@ int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp) ...@@ -912,18 +921,20 @@ int scsiGetTemp(int device, UINT8 *currenttemp, UINT8 *triptemp)
* Returns 0 if ok, else error number. A current temperature of 255 * Returns 0 if ok, else error number. A current temperature of 255
* (Celsius) implies that the temperature not available. */ * (Celsius) implies that the temperature not available. */
int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage, int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp) UINT8 *asc, UINT8 *ascq, UINT8 *currenttemp,
UINT8 *triptemp)
{ {
UINT8 tBuf[252]; UINT8 tBuf[252];
struct scsi_sense_disect sense_info; struct scsi_sense_disect sense_info;
int err; int err;
int temperatureSet = 0; int temperatureSet = 0;
unsigned short pagesize; unsigned short pagesize;
UINT8 currTemp, tripTemp; UINT8 currTemp, trTemp;
*asc = 0; *asc = 0;
*ascq = 0; *ascq = 0;
*currenttemp = 0; *currenttemp = 0;
*triptemp = 0;
memset(tBuf,0,sizeof(tBuf)); // need to clear stack space of junk memset(tBuf,0,sizeof(tBuf)); // need to clear stack space of junk
memset(&sense_info, 0, sizeof(sense_info)); memset(&sense_info, 0, sizeof(sense_info));
if (hasIELogPage) { if (hasIELogPage) {
...@@ -941,9 +952,11 @@ int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage, ...@@ -941,9 +952,11 @@ int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
if (tBuf[7] > 1) { if (tBuf[7] > 1) {
sense_info.asc = tBuf[8]; sense_info.asc = tBuf[8];
sense_info.ascq = tBuf[9]; sense_info.ascq = tBuf[9];
if (tBuf[7] > 2) { if (! hasTempLogPage) {
if (tBuf[7] > 2)
*currenttemp = tBuf[10]; *currenttemp = tBuf[10];
temperatureSet = 1; if (tBuf[7] > 3) /* IBM extension in SMART (IE) lpage */
*triptemp = tBuf[11];
} }
} }
} }
...@@ -957,8 +970,10 @@ int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage, ...@@ -957,8 +970,10 @@ int scsiCheckIE(int device, int hasIELogPage, int hasTempLogPage,
*asc = sense_info.asc; *asc = sense_info.asc;
*ascq = sense_info.ascq; *ascq = sense_info.ascq;
if ((! temperatureSet) && hasTempLogPage) { if ((! temperatureSet) && hasTempLogPage) {
if (0 == scsiGetTemp(device, &currTemp, &tripTemp)) if (0 == scsiGetTemp(device, &currTemp, &trTemp)) {
*currenttemp = currTemp; *currenttemp = currTemp;
*triptemp = trTemp;
}
} }
return 0; return 0;
} }
...@@ -1537,28 +1552,32 @@ int scsiSmartSelfTestAbort(int device) ...@@ -1537,28 +1552,32 @@ int scsiSmartSelfTestAbort(int device)
return scsiSendDiagnostic(device, SCSI_DIAG_ABORT_SELF_TEST, NULL, 0); return scsiSendDiagnostic(device, SCSI_DIAG_ABORT_SELF_TEST, NULL, 0);
} }
int scsiFetchExtendedSelfTestTime(int device, int * durationSec) int scsiFetchExtendedSelfTestTime(int device, int * durationSec, int modese_len)
{ {
int err, offset, res; int err, offset, res;
UINT8 buff[64]; UINT8 buff[64];
int modese_10 = 0;
memset(buff, 0, sizeof(buff)); memset(buff, 0, sizeof(buff));
if (modese_len <= 6) {
if ((err = scsiModeSense(device, CONTROL_MODE_PAGE_PARAMETERS, if ((err = scsiModeSense(device, CONTROL_MODE_PAGE_PARAMETERS,
MODE_PAGE_CONTROL_CURRENT, MODE_PAGE_CONTROL_CURRENT,
buff, sizeof(buff)))) { buff, sizeof(buff)))) {
if (2 == err) { /* opcode no good so try 10 byte mode sense */
err = scsiModeSense10(device, CONTROL_MODE_PAGE_PARAMETERS,
MODE_PAGE_CONTROL_CURRENT,
buff, sizeof(buff));
if (0 == err) if (0 == err)
modese_10 = 1; modese_len = 6;
else if (SIMPLE_ERR_BAD_OPCODE == err)
modese_len = 10;
else else
return err; return err;
} else }
}
if (10 == modese_len) {
err = scsiModeSense10(device, CONTROL_MODE_PAGE_PARAMETERS,
MODE_PAGE_CONTROL_CURRENT,
buff, sizeof(buff));
if (err)
return err; return err;
} }
offset = scsiModePageOffset(buff, sizeof(buff), modese_10); offset = scsiModePageOffset(buff, sizeof(buff), modese_len);
if (offset < 0) if (offset < 0)
return -EINVAL; return -EINVAL;
if (buff[offset + 1] >= 0xa) { if (buff[offset + 1] >= 0xa) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment