From c1617f14340ddfc5868202f703541707ce9690c4 Mon Sep 17 00:00:00 2001 From: ballen4705 <ballen4705@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Mon, 21 Oct 2002 15:07:48 +0000 Subject: [PATCH] Fixed possible error in determining ATA version if no minor_version field in DEVICE ID. Detect -EIO if sending a captive self-test command and do not generate error message. git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@72 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- sm5/CHANGELOG | 11 +++++++++-- sm5/atacmds.c | 26 +++++++++++++++++--------- sm5/atacmds.cpp | 26 +++++++++++++++++--------- 3 files changed, 43 insertions(+), 20 deletions(-) diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index 8f3699c7a..1cb6e4c26 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.10 2002/10/21 08:49:23 ballen4705 Exp $ +$Id: CHANGELOG,v 1.11 2002/10/21 15:07:47 ballen4705 Exp $ Copyright (C) 2002 Bruce Allen <smartmontools-support@lists.sourceforge.net> @@ -29,8 +29,15 @@ NOTES FOR NEXT RELEASE: smartmontools-5.0-11 + when starting self-tests in captive mode ioctl returns EIO because + the drive has been busied out. Detect this and don't return an eror + in this case. Check this this is correct (or how to fix it?) + + fixed possible error in how to determine ATA standard support + for devices with no ATA minor revision number. + device opened only in read-only not read-write mode. Don't need R/W - access to get smart data. + access to get smart data. Check this with Andre. smartctl now handles all possible choices of "multiple options" gracefully. It goes through the following phases of operation, diff --git a/sm5/atacmds.c b/sm5/atacmds.c index 75e030550..72a2cc03a 100644 --- a/sm5/atacmds.c +++ b/sm5/atacmds.c @@ -1,4 +1,4 @@ -// $Id: atacmds.c,v 1.11 2002/10/21 08:49:23 ballen4705 Exp $ +// $Id: atacmds.c,v 1.12 2002/10/21 15:07:48 ballen4705 Exp $ /* * atacmds.c * @@ -28,6 +28,7 @@ #include <stdio.h> #include <string.h> #include <syslog.h> +#include <errno.h> #include "atacmds.h" // These Drive Identity tables are taken from hdparm 5.2, and are also @@ -140,7 +141,8 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){ unsigned char parms[HDIO_DRIVE_CMD_HDR_SIZE+sizeof(*buf)]= {WIN_IDENTIFY, 0, 0, 1,}; - if (ioctl(device ,HDIO_DRIVE_CMD,parms)){ + if (ioctl(device ,HDIO_DRIVE_CMD,parms)){ + // See if device responds to packet command... parms[0]=WIN_PIDENTIFY; if (ioctl(device ,HDIO_DRIVE_CMD,parms)){ perror ("ATA GET HD Identity Failed"); @@ -176,7 +178,7 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){ // the version number. See notes above. int ataVersionInfo (const char** description, struct hd_driveid drive){ unsigned short major,minor; - int i,atavalue=0; + int i; // get major and minor ATA revision numbers #ifdef __NEW_HD_DRIVE_ID @@ -205,11 +207,15 @@ int ataVersionInfo (const char** description, struct hd_driveid drive){ // HDPARM has a very complicated algorithm from here on. Since SMART only // exists on ATA-3 and later standards, let's punt on this. If you don't // like it, please fix it. The code's in CVS. - for (i=1; i<16;i++ ) + for (i=15; i>0; i--) if (major & (0x1<<i)) - atavalue = i; - *description=NULL; - return atavalue; + break; + + *description=NULL; + if (i==0) + return 1; + else + return i;; } // returns 1 if SMART supported, 0 if not supported or can't tell @@ -512,6 +518,7 @@ int ataSmartStatus2(int device){ int ataSmartTest(int device, int testtype){ unsigned char parms[4] = {WIN_SMART, 0, SMART_IMMEDIATE_OFFLINE}; char cmdmsg[128],*type,*captive; + int errornum; parms[1]=testtype; @@ -536,10 +543,11 @@ int ataSmartTest(int device, int testtype){ printf("Sending command: \"%s\".\n",cmdmsg); // Now send the command to test - if (ioctl(device , HDIO_DRIVE_CMD, parms)){ + if ((errornum=ioctl(device , HDIO_DRIVE_CMD, parms)) && errornum!=EIO){ char errormsg[128]; - sprintf(errormsg,"Command \"%s\" failed.\n\n",cmdmsg); + sprintf(errormsg,"Command \"%s\" failed.",cmdmsg); perror (errormsg); + fprintf(stderr,"\n"); return -1; } diff --git a/sm5/atacmds.cpp b/sm5/atacmds.cpp index 58ed944fa..2baefc106 100644 --- a/sm5/atacmds.cpp +++ b/sm5/atacmds.cpp @@ -1,4 +1,4 @@ -// $Id: atacmds.cpp,v 1.11 2002/10/21 08:49:23 ballen4705 Exp $ +// $Id: atacmds.cpp,v 1.12 2002/10/21 15:07:48 ballen4705 Exp $ /* * atacmds.c * @@ -28,6 +28,7 @@ #include <stdio.h> #include <string.h> #include <syslog.h> +#include <errno.h> #include "atacmds.h" // These Drive Identity tables are taken from hdparm 5.2, and are also @@ -140,7 +141,8 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){ unsigned char parms[HDIO_DRIVE_CMD_HDR_SIZE+sizeof(*buf)]= {WIN_IDENTIFY, 0, 0, 1,}; - if (ioctl(device ,HDIO_DRIVE_CMD,parms)){ + if (ioctl(device ,HDIO_DRIVE_CMD,parms)){ + // See if device responds to packet command... parms[0]=WIN_PIDENTIFY; if (ioctl(device ,HDIO_DRIVE_CMD,parms)){ perror ("ATA GET HD Identity Failed"); @@ -176,7 +178,7 @@ int ataReadHDIdentity (int device, struct hd_driveid *buf){ // the version number. See notes above. int ataVersionInfo (const char** description, struct hd_driveid drive){ unsigned short major,minor; - int i,atavalue=0; + int i; // get major and minor ATA revision numbers #ifdef __NEW_HD_DRIVE_ID @@ -205,11 +207,15 @@ int ataVersionInfo (const char** description, struct hd_driveid drive){ // HDPARM has a very complicated algorithm from here on. Since SMART only // exists on ATA-3 and later standards, let's punt on this. If you don't // like it, please fix it. The code's in CVS. - for (i=1; i<16;i++ ) + for (i=15; i>0; i--) if (major & (0x1<<i)) - atavalue = i; - *description=NULL; - return atavalue; + break; + + *description=NULL; + if (i==0) + return 1; + else + return i;; } // returns 1 if SMART supported, 0 if not supported or can't tell @@ -512,6 +518,7 @@ int ataSmartStatus2(int device){ int ataSmartTest(int device, int testtype){ unsigned char parms[4] = {WIN_SMART, 0, SMART_IMMEDIATE_OFFLINE}; char cmdmsg[128],*type,*captive; + int errornum; parms[1]=testtype; @@ -536,10 +543,11 @@ int ataSmartTest(int device, int testtype){ printf("Sending command: \"%s\".\n",cmdmsg); // Now send the command to test - if (ioctl(device , HDIO_DRIVE_CMD, parms)){ + if ((errornum=ioctl(device , HDIO_DRIVE_CMD, parms)) && errornum!=EIO){ char errormsg[128]; - sprintf(errormsg,"Command \"%s\" failed.\n\n",cmdmsg); + sprintf(errormsg,"Command \"%s\" failed.",cmdmsg); perror (errormsg); + fprintf(stderr,"\n"); return -1; } -- GitLab