diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index a8de1fbf5a22b94e8a352730d3730e5d17f572cf..d70db889b86b46505c1eb641553942b55ff446bb 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.79 2003/01/03 17:58:16 ballen4705 Exp $ +$Id: CHANGELOG,v 1.80 2003/01/04 01:37:47 dpgilbert Exp $ Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> @@ -38,6 +38,8 @@ CURRENT RELEASE (see VERSION file in this directory): smartmontools-5.1.1 + [DG] add '-l selftest' capability for SCSI devices (update smartctl.8) + [BA] smartd,smartctl: added additional Attribute modification option -v 220,temp and -v 9,temp. diff --git a/sm5/scsicmds.c b/sm5/scsicmds.c index c26711445ee9464cf5bf013d213c7dca6707432d..114aea7147753d640460453dfb62d02cfcd7e896 100644 --- a/sm5/scsicmds.c +++ b/sm5/scsicmds.c @@ -28,13 +28,33 @@ #include <unistd.h> #include <sys/ioctl.h> #include <linux/hdreg.h> -// We do NOT want to include the kernel SCSI header file, just user space one -#define _LINUX_SCSI_H -#include <scsi/scsi.h> +/* #include <scsi/scsi.h> bypass for now */ +/* #include <scsi/scsi_ioctl.h> bypass for now */ #include "scsicmds.h" -const char *CVSid3="$Id: scsicmds.c,v 1.16 2002/11/21 21:21:48 knan Exp $" CVSID4; +const char *CVSid3="$Id: scsicmds.c,v 1.17 2003/01/04 01:37:48 dpgilbert Exp $" CVSID4; +static int send_scsi_cmd(int device, int cmnd_len, void * io_hdr) +{ + int status; + +#ifdef SCSI_DEBUG + { + int k; + const unsigned char * ucp = io_hdr; + + ucp += 2 * sizeof(int); + fprintf(stderr, "cmnd: ["); + for (k = 0; k < cmnd_len; ++k) + fprintf(stderr, "%02x ", ucp[k]); + } +#endif + status = ioctl(device, SCSI_IOCTL_SEND_COMMAND , io_hdr); +#ifdef SCSI_DEBUG + fprintf(stderr, "] status=0x%x\n", status); +#endif + return status; +} UINT8 logsense (int device, UINT8 pagenum, UINT8 *pBuf) { @@ -61,8 +81,7 @@ UINT8 logsense (int device, UINT8 pagenum, UINT8 *pBuf) ioctlhdr->cdb[8] = 0x00; ioctlhdr->cdb[9] = 0x00; - status = ioctl( device, 1 , &tBuf); - + status = send_scsi_cmd(device, 10, &tBuf); memcpy ( pBuf, &tBuf[8], 1024); @@ -96,8 +115,7 @@ UINT8 modesense (int device, UINT8 pagenum, UINT8 *pBuf) ioctlhdr->cdb[4] = CDB_6_MAX_DATA_SIZE; ioctlhdr->cdb[5] = 0x00; - - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); memcpy ( pBuf, &tBuf[8], 256); @@ -139,7 +157,7 @@ UINT8 modeselect (int device, UINT8 pagenum, UINT8 *pBuf) tBuf[26] &= 0x3f; - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); return status; @@ -173,7 +191,7 @@ UINT8 modesense10 (int device, UINT8 pagenum, UINT8 *pBuf) ioctlhdr->cdb[8] = 0xff; ioctlhdr->cdb[9] = 0x00; - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 10, &tBuf); memcpy ( pBuf, &tBuf[8], 0xff); @@ -218,7 +236,7 @@ UINT8 modeselect10 (int device, UINT8 pagenum, UINT8 *pBuf) tBuf[26] &= 0x3f; - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 10, &tBuf); return status; @@ -251,7 +269,7 @@ UINT8 stdinquiry ( int device, UINT8 *pBuf) ioctlhdr->cdb[5] = 0x00; - status = ioctl( device, 1, &tBuf ); + status = send_scsi_cmd(device, 6, &tBuf); memcpy ( pBuf, &tBuf[8], 255); @@ -286,8 +304,7 @@ UINT8 inquiry ( int device, UINT8 pagenum, UINT8 *pBuf) ioctlhdr->cdb[4] = CDB_6_MAX_DATA_SIZE; ioctlhdr->cdb[5] = 0x00; - - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); memcpy ( pBuf, &tBuf[8], 255); @@ -321,8 +338,7 @@ UINT8 requestsense (int device, UINT8 *pBuf) ioctlhdr->cdb[4] = CDB_6_MAX_DATA_SIZE; ioctlhdr->cdb[5] = 0x00; - - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); memcpy ( pBuf, &tBuf[8], 255); @@ -364,7 +380,7 @@ UINT8 senddiagnostic (int device, UINT8 functioncode, UINT8 *pBuf) pBuf[0]); } - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); if (pBuf != NULL) memcpy ( pBuf, &tBuf[8], 256); @@ -400,7 +416,7 @@ UINT8 receivediagnostic (int device, UINT8 pagenum, UINT8 *pBuf) ioctlhdr->cdb[5] = 0x00; - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); memcpy ( pBuf, &tBuf[8], 256); @@ -411,7 +427,7 @@ UINT8 receivediagnostic (int device, UINT8 pagenum, UINT8 *pBuf) // See if the device accepts IOCTLs at all... UINT8 testunitnotready (int device) { - return ioctl( device, 2 , NULL); + return ioctl( device, SCSI_IOCTL_TEST_UNIT_READY , NULL); } diff --git a/sm5/scsicmds.cpp b/sm5/scsicmds.cpp index 98e5c8e5ac4a198733f6530337bd521d0d9b9db1..b719fcb6251f6d3fc92b14a5ae6727329bbf8dcb 100644 --- a/sm5/scsicmds.cpp +++ b/sm5/scsicmds.cpp @@ -28,13 +28,33 @@ #include <unistd.h> #include <sys/ioctl.h> #include <linux/hdreg.h> -// We do NOT want to include the kernel SCSI header file, just user space one -#define _LINUX_SCSI_H -#include <scsi/scsi.h> +/* #include <scsi/scsi.h> bypass for now */ +/* #include <scsi/scsi_ioctl.h> bypass for now */ #include "scsicmds.h" -const char *CVSid3="$Id: scsicmds.cpp,v 1.16 2002/11/21 21:21:48 knan Exp $" CVSID4; +const char *CVSid3="$Id: scsicmds.cpp,v 1.17 2003/01/04 01:37:48 dpgilbert Exp $" CVSID4; +static int send_scsi_cmd(int device, int cmnd_len, void * io_hdr) +{ + int status; + +#ifdef SCSI_DEBUG + { + int k; + const unsigned char * ucp = io_hdr; + + ucp += 2 * sizeof(int); + fprintf(stderr, "cmnd: ["); + for (k = 0; k < cmnd_len; ++k) + fprintf(stderr, "%02x ", ucp[k]); + } +#endif + status = ioctl(device, SCSI_IOCTL_SEND_COMMAND , io_hdr); +#ifdef SCSI_DEBUG + fprintf(stderr, "] status=0x%x\n", status); +#endif + return status; +} UINT8 logsense (int device, UINT8 pagenum, UINT8 *pBuf) { @@ -61,8 +81,7 @@ UINT8 logsense (int device, UINT8 pagenum, UINT8 *pBuf) ioctlhdr->cdb[8] = 0x00; ioctlhdr->cdb[9] = 0x00; - status = ioctl( device, 1 , &tBuf); - + status = send_scsi_cmd(device, 10, &tBuf); memcpy ( pBuf, &tBuf[8], 1024); @@ -96,8 +115,7 @@ UINT8 modesense (int device, UINT8 pagenum, UINT8 *pBuf) ioctlhdr->cdb[4] = CDB_6_MAX_DATA_SIZE; ioctlhdr->cdb[5] = 0x00; - - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); memcpy ( pBuf, &tBuf[8], 256); @@ -139,7 +157,7 @@ UINT8 modeselect (int device, UINT8 pagenum, UINT8 *pBuf) tBuf[26] &= 0x3f; - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); return status; @@ -173,7 +191,7 @@ UINT8 modesense10 (int device, UINT8 pagenum, UINT8 *pBuf) ioctlhdr->cdb[8] = 0xff; ioctlhdr->cdb[9] = 0x00; - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 10, &tBuf); memcpy ( pBuf, &tBuf[8], 0xff); @@ -218,7 +236,7 @@ UINT8 modeselect10 (int device, UINT8 pagenum, UINT8 *pBuf) tBuf[26] &= 0x3f; - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 10, &tBuf); return status; @@ -251,7 +269,7 @@ UINT8 stdinquiry ( int device, UINT8 *pBuf) ioctlhdr->cdb[5] = 0x00; - status = ioctl( device, 1, &tBuf ); + status = send_scsi_cmd(device, 6, &tBuf); memcpy ( pBuf, &tBuf[8], 255); @@ -286,8 +304,7 @@ UINT8 inquiry ( int device, UINT8 pagenum, UINT8 *pBuf) ioctlhdr->cdb[4] = CDB_6_MAX_DATA_SIZE; ioctlhdr->cdb[5] = 0x00; - - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); memcpy ( pBuf, &tBuf[8], 255); @@ -321,8 +338,7 @@ UINT8 requestsense (int device, UINT8 *pBuf) ioctlhdr->cdb[4] = CDB_6_MAX_DATA_SIZE; ioctlhdr->cdb[5] = 0x00; - - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); memcpy ( pBuf, &tBuf[8], 255); @@ -364,7 +380,7 @@ UINT8 senddiagnostic (int device, UINT8 functioncode, UINT8 *pBuf) pBuf[0]); } - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); if (pBuf != NULL) memcpy ( pBuf, &tBuf[8], 256); @@ -400,7 +416,7 @@ UINT8 receivediagnostic (int device, UINT8 pagenum, UINT8 *pBuf) ioctlhdr->cdb[5] = 0x00; - status = ioctl( device, 1 , &tBuf); + status = send_scsi_cmd(device, 6, &tBuf); memcpy ( pBuf, &tBuf[8], 256); @@ -411,7 +427,7 @@ UINT8 receivediagnostic (int device, UINT8 pagenum, UINT8 *pBuf) // See if the device accepts IOCTLs at all... UINT8 testunitnotready (int device) { - return ioctl( device, 2 , NULL); + return ioctl( device, SCSI_IOCTL_TEST_UNIT_READY , NULL); } diff --git a/sm5/scsicmds.h b/sm5/scsicmds.h index 0960766e61577068cbf387b192f85466ad835a47..ec6ff9cff89ecb5fa2e008df29016d86fc41326f 100644 --- a/sm5/scsicmds.h +++ b/sm5/scsicmds.h @@ -27,9 +27,13 @@ #define SCSICMDS_H_ #ifndef CVSID4 -#define CVSID4 "$Id: scsicmds.h,v 1.8 2002/11/17 05:30:11 ballen4705 Exp $\n" +#define CVSID4 "$Id: scsicmds.h,v 1.9 2003/01/04 01:37:48 dpgilbert Exp $\n" #endif +/* #define SCSI_DEBUG 1 */ /* Comment out to disable command debugging */ + +/* Following conditional defines bypass inclusion of scsi/scsi.h and + * scsi/scsi_ioctl.h . Issue will be resolved later ... */ #ifndef LOG_SENSE #define LOG_SENSE 0x4d #endif @@ -37,6 +41,9 @@ #ifndef MODE_SENSE #define MODE_SENSE 0x1a #endif +#ifndef MODE_SENSE_10 +#define MODE_SENSE_10 0x5a +#endif #ifndef MODE_SELECT #define MODE_SELECT 0x15 @@ -62,6 +69,13 @@ #define SEND_DIAGNOSTIC 0x1d #endif +#ifndef SCSI_IOCTL_SEND_COMMAND +#define SCSI_IOCTL_SEND_COMMAND 1 +#endif +#ifndef SCSI_IOCTL_TEST_UNIT_READY +#define SCSI_IOCTL_TEST_UNIT_READY 2 +#endif + #include <stdio.h> #include <stdlib.h> #include <string.h> diff --git a/sm5/scsiprint.c b/sm5/scsiprint.c index d2107b425faf96686d34d80f0e0d3b8b1f5aa96a..a69e247c1e7f81e499aa2c51adc1427370bd2a9b 100644 --- a/sm5/scsiprint.c +++ b/sm5/scsiprint.c @@ -36,7 +36,7 @@ #define GBUF_SIZE 65535 -const char* CVSid4="$Id: scsiprint.c,v 1.13 2002/12/29 02:14:47 dpgilbert Exp $" +const char* CVSid4="$Id: scsiprint.c,v 1.14 2003/01/04 01:37:48 dpgilbert Exp $" CVSID3 CVSID4 CVSID5 CVSID6; // control block which points to external global control variables @@ -184,6 +184,87 @@ void scsiGetStartStopData ( int device) printf("Recommended start stop count: %u times\n", recommendedStartStop); } +const char * self_test_code[] = { + "Default ", + "Background short", + "Background long ", + "Reserved(3) ", + "Abort background", + "Foreground short", + "Foreground long ", + "Reserved(7) " +}; + +const char * self_test_result[] = { + "Completed ", + "Interrupted ('-X' switch)", + "Interrupted (bus reset ?)", + "Unknown error, incomplete", + "Completed, segment failed", + "Failed in first segment ", + "Failed in second segment ", + "Failed in segment --> ", + "Reserved(8) ", + "Reserved(9) ", + "Reserved(10) ", + "Reserved(11) ", + "Reserved(12) ", + "Reserved(13) ", + "Reserved(14) ", + "Self test in progress ..." +}; + +void scsiPrintSelfTest(int device) +{ + int num, k, n, res; + UINT8 * ucp; + unsigned long long ull; + + if (logsense(device, SELFTEST_RESULTS_PAGE, gBuf) != 0) + { + perror ( "scsiPrintSelfTest Failed"); + exit (1); + } + if (gBuf[0] != SELFTEST_RESULTS_PAGE) + { + printf("Self-test Log Sense Failed\n"); + exit(-1); + } + num = (gBuf[2] << 8) + gBuf[3]; + if (num < 0x190) { + printf("Self-test Log Sense too short\n"); + exit(-1); + } + ucp = &gBuf[0] + 4; + printf(",\nSMART Self-test log\n"); + printf("Num Test Status segment " + "LifeTime LBA_first_err [SK ASC ASQ]\n"); + printf(" Description number " + "(hours)\n"); + for (k = 0, ucp = gBuf + 4; k < 20; ++k, ucp += 20 ) { + n = (ucp[6] << 8) | ucp[7]; + if ((0 == n) && (0 == ucp[4])) + break; + printf("#%2d %s", (ucp[0] << 8) | ucp[1], + self_test_code[(ucp[4] >> 5) & 0x7]); + res = ucp[4] & 0xf; + printf(" %s", self_test_result[res]); + printf(" %3d", (int)ucp[5]); + printf(" %5d", n); + ull = ucp[8]; ull <<= 8; ull |= ucp[9]; ull <<= 8; ull |= ucp[10]; + ull <<= 8; ull |= ucp[11]; ull <<= 8; ull |= ucp[12]; + ull <<= 8; ull |= ucp[13]; ull <<= 8; ull |= ucp[14]; + ull <<= 8; ull |= ucp[14]; ull <<= 8; ull |= ucp[15]; + if ((0xffffffffffffffffULL != ull) && (res > 0) && ( res < 0xf)) + printf(" 0x%10llx", ull); + else + printf(" "); + if (ucp[16] & 0xf) + printf(" [0x%x 0x%x 0x%x]\n", ucp[16] & 0xf, ucp[17], ucp[18]); + else + printf("\n"); + } +} void scsiGetDriveInfo ( int device) { @@ -299,6 +380,7 @@ void scsiPrintStopStart ( int device ) void scsiPrintMain (char *device, int fd) { + int checkedsupportlogpages = 0; // See if unit accepts SCSI commmands from us if (testunitnotready(fd)){ @@ -318,6 +400,7 @@ void scsiPrintMain (char *device, int fd) if (con->checksmart) { scsiGetSupportPages (fd); + checkedsupportlogpages = 1; if(gTapeAlertsPage) scsiGetTapeAlertsData (fd); else @@ -330,6 +413,12 @@ void scsiPrintMain (char *device, int fd) } } + if (con->smartselftestlog) { + if (! checkedsupportlogpages) + scsiGetSupportPages(fd); + if (gSelfTestPage) + scsiPrintSelfTest(fd); + } if ( con->smartexeoffimmediate ) { diff --git a/sm5/scsiprint.cpp b/sm5/scsiprint.cpp index 08038389771cc596e802131da67ad4f36d0bbd1f..16576c958feeba7ec65b1556605f048c7bbdfedf 100644 --- a/sm5/scsiprint.cpp +++ b/sm5/scsiprint.cpp @@ -36,7 +36,7 @@ #define GBUF_SIZE 65535 -const char* CVSid4="$Id: scsiprint.cpp,v 1.13 2002/12/29 02:14:47 dpgilbert Exp $" +const char* CVSid4="$Id: scsiprint.cpp,v 1.14 2003/01/04 01:37:48 dpgilbert Exp $" CVSID3 CVSID4 CVSID5 CVSID6; // control block which points to external global control variables @@ -184,6 +184,87 @@ void scsiGetStartStopData ( int device) printf("Recommended start stop count: %u times\n", recommendedStartStop); } +const char * self_test_code[] = { + "Default ", + "Background short", + "Background long ", + "Reserved(3) ", + "Abort background", + "Foreground short", + "Foreground long ", + "Reserved(7) " +}; + +const char * self_test_result[] = { + "Completed ", + "Interrupted ('-X' switch)", + "Interrupted (bus reset ?)", + "Unknown error, incomplete", + "Completed, segment failed", + "Failed in first segment ", + "Failed in second segment ", + "Failed in segment --> ", + "Reserved(8) ", + "Reserved(9) ", + "Reserved(10) ", + "Reserved(11) ", + "Reserved(12) ", + "Reserved(13) ", + "Reserved(14) ", + "Self test in progress ..." +}; + +void scsiPrintSelfTest(int device) +{ + int num, k, n, res; + UINT8 * ucp; + unsigned long long ull; + + if (logsense(device, SELFTEST_RESULTS_PAGE, gBuf) != 0) + { + perror ( "scsiPrintSelfTest Failed"); + exit (1); + } + if (gBuf[0] != SELFTEST_RESULTS_PAGE) + { + printf("Self-test Log Sense Failed\n"); + exit(-1); + } + num = (gBuf[2] << 8) + gBuf[3]; + if (num < 0x190) { + printf("Self-test Log Sense too short\n"); + exit(-1); + } + ucp = &gBuf[0] + 4; + printf(",\nSMART Self-test log\n"); + printf("Num Test Status segment " + "LifeTime LBA_first_err [SK ASC ASQ]\n"); + printf(" Description number " + "(hours)\n"); + for (k = 0, ucp = gBuf + 4; k < 20; ++k, ucp += 20 ) { + n = (ucp[6] << 8) | ucp[7]; + if ((0 == n) && (0 == ucp[4])) + break; + printf("#%2d %s", (ucp[0] << 8) | ucp[1], + self_test_code[(ucp[4] >> 5) & 0x7]); + res = ucp[4] & 0xf; + printf(" %s", self_test_result[res]); + printf(" %3d", (int)ucp[5]); + printf(" %5d", n); + ull = ucp[8]; ull <<= 8; ull |= ucp[9]; ull <<= 8; ull |= ucp[10]; + ull <<= 8; ull |= ucp[11]; ull <<= 8; ull |= ucp[12]; + ull <<= 8; ull |= ucp[13]; ull <<= 8; ull |= ucp[14]; + ull <<= 8; ull |= ucp[14]; ull <<= 8; ull |= ucp[15]; + if ((0xffffffffffffffffULL != ull) && (res > 0) && ( res < 0xf)) + printf(" 0x%10llx", ull); + else + printf(" "); + if (ucp[16] & 0xf) + printf(" [0x%x 0x%x 0x%x]\n", ucp[16] & 0xf, ucp[17], ucp[18]); + else + printf("\n"); + } +} void scsiGetDriveInfo ( int device) { @@ -299,6 +380,7 @@ void scsiPrintStopStart ( int device ) void scsiPrintMain (char *device, int fd) { + int checkedsupportlogpages = 0; // See if unit accepts SCSI commmands from us if (testunitnotready(fd)){ @@ -318,6 +400,7 @@ void scsiPrintMain (char *device, int fd) if (con->checksmart) { scsiGetSupportPages (fd); + checkedsupportlogpages = 1; if(gTapeAlertsPage) scsiGetTapeAlertsData (fd); else @@ -330,6 +413,12 @@ void scsiPrintMain (char *device, int fd) } } + if (con->smartselftestlog) { + if (! checkedsupportlogpages) + scsiGetSupportPages(fd); + if (gSelfTestPage) + scsiPrintSelfTest(fd); + } if ( con->smartexeoffimmediate ) { diff --git a/sm5/smartctl.8 b/sm5/smartctl.8 index dc43f3513475a7bec6371307ca0e24681ce72ae2..176ed07b9b521818df20a81850fe37bca2ed764f 100644 --- a/sm5/smartctl.8 +++ b/sm5/smartctl.8 @@ -1,6 +1,6 @@ \# Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> \# -\# $Id: smartctl.8,v 1.34 2003/01/03 20:31:11 pjwilliams Exp $ +\# $Id: smartctl.8,v 1.35 2003/01/04 01:37:48 dpgilbert Exp $ \# \# This program is free software; you can redistribute it and/or modify it \# under the terms of the GNU General Public License as published by the Free @@ -16,7 +16,7 @@ \# Research Center), Jack Baskin School of Engineering, University of \# California, Santa Cruz. http://ssrc.soe.ucsc.edu/ \# -.TH SMARTCTL 8 "$Date: 2003/01/03 20:31:11 $" "smartmontools-5.0" +.TH SMARTCTL 8 "$Date: 2003/01/04 01:37:48 $" "smartmontools-5.0" .SH NAME smartctl \- S.M.A.R.T. control and monitor utility .SH SYNOPSIS @@ -74,7 +74,7 @@ will execute the corresponding commands in the order: INFORMATION, ENABLE/DISABLE, DISPLAY DATA, RUN/ABORT TESTS. SCSI devices only accept the options -.B \-h, \-?, \-V, \-i, \-a, \-d, \-s, \-H, \-t, \-C +.B \-h, \-?, \-V, \-i, \-a, \-d, \-s, \-H, \-t, \-C \-l selftest and .B \-X. TapeAlerts devices only accept the options @@ -109,7 +109,7 @@ so, whether S.M.A.R.T. support is currently enabled or disabled. .TP .B \-a, \-\-all Prints all S.M.A.R.T. information about the disk. This is equivalent to '\-H -\-i \-c \-A \-l error \-l selftest' (for SCSI, '\-H \-i'). +\-i \-c \-A \-l error \-l selftest' (for SCSI, '\-H \-i \-l selftest'). .TP .B RUN-TIME BEHAVIOR: .TP @@ -400,6 +400,18 @@ measured in hours of disk lifetime, is shown. If any errors were detected, the Logical Block Address (LBA) of the first error is printed in hexadecimal notation. +.I selftest [SCSI] +\- the self-test log for a SCSI device has a slightly different format. +The log will show, for each of the most recent twenty self-tests, the type +of test and the status (final or in progress) of the test. SCSI standards +use the terms foreground and background (rather than ATA's captive and +off-line); and long (rather ATA's extended). The segment number column is +only relevant when a test fails in the third or later test segment. The +Logical Block Address (LBA) of the first error is printed in hexadecimal +notation. If provided, a SCSI sense key (SK), additional sense code (ASC) +and additional sense qualifier (ASQ) is output. The self tests can be +run using the '\-t' option described below (use ATA's test terminology). + .TP .B \-v N,OPTION, \-\-vendorattribute=N,OPTION Sets a vendor-specific display OPTION for Attribute N. Valid @@ -653,4 +665,4 @@ Please let us know if there is an on\-line source for this document. .SH CVS ID OF THIS PAGE: -$Id: smartctl.8,v 1.34 2003/01/03 20:31:11 pjwilliams Exp $ +$Id: smartctl.8,v 1.35 2003/01/04 01:37:48 dpgilbert Exp $