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 $