Skip to content
Snippets Groups Projects
Commit d3893d06 authored by shattered's avatar shattered
Browse files

Major bugfixes:

- handle actual SCSI and ATA errors and not only ioctl() errors;
- use ATACMD_READREG I/O request flag if ATA command does not perform I/O and/or
  returns data in ATA registers;
- set up I/O request properly for AUTO_OFFLINE and AUTOSAVE commands (inspired by
  similar changes in os_freebsd.cpp);
- handle AUTO_OFFLINE and AUTOSAVE like STATUS_CHECK (like os_linux.cpp does).


git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@2466 4ea69e1a-61f1-4043-bf83-b5c94c648137
parent 291f8eee
No related branches found
No related tags found
No related merge requests found
CHANGELOG for smartmontools CHANGELOG for smartmontools
$Id: CHANGELOG,v 1.656 2008/02/26 13:47:58 guidog Exp $ $Id: CHANGELOG,v 1.657 2008/03/03 22:29:02 shattered Exp $
The most recent version of this file is: The most recent version of this file is:
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup
...@@ -38,6 +38,12 @@ NOTES FOR FUTURE RELEASES: see TODO file. ...@@ -38,6 +38,12 @@ NOTES FOR FUTURE RELEASES: see TODO file.
SMARTMONTOOLS STABLE RELEASE 5.38 2008/02/24 SMARTMONTOOLS STABLE RELEASE 5.38 2008/02/24
[SS] Major NetBSD-specific bugfixes:
- handle actual SCSI and ATA errors and not only ioctl() errors;
- set up I/O request properly for AUTO_OFFLINE and AUTOSAVE commands (inspired by
similar change in os_freebsd.cpp);
- handle AUTO_OFFLINE and AUTOSAVE like STATUS_CHECK (like os_linux.cpp does).
[GG] add kfreebsd gnu support to configure.in [GG] add kfreebsd gnu support to configure.in
[BA] Fix auto-offline support in FreeBSD. Thanks to [BA] Fix auto-offline support in FreeBSD. Thanks to
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include "os_netbsd.h" #include "os_netbsd.h"
#include <unistd.h> #include <unistd.h>
const char *os_XXXX_c_cvsid = "$Id: os_netbsd.cpp,v 1.19 2006/09/20 16:17:31 shattered Exp $" \ const char *os_XXXX_c_cvsid = "$Id: os_netbsd.cpp,v 1.20 2008/03/03 22:29:02 shattered Exp $" \
ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_NETBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_NETBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
/* global variable holding byte count of allocated memory */ /* global variable holding byte count of allocated memory */
...@@ -171,10 +171,9 @@ int ...@@ -171,10 +171,9 @@ int
marvell_command_interface(int fd, smart_command_set command, int select, char *data) marvell_command_interface(int fd, smart_command_set command, int select, char *data)
{ return -1; } { return -1; }
int highpoint_command_interface(int fd, smart_command_set command, int select, char *data) int
{ highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
return -1; { return -1; }
}
int int
ata_command_interface(int fd, smart_command_set command, int select, char *data) ata_command_interface(int fd, smart_command_set command, int select, char *data)
...@@ -248,14 +247,14 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data) ...@@ -248,14 +247,14 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
copydata = 1; copydata = 1;
break; break;
case ENABLE: case ENABLE:
req.flags = ATACMD_READ; req.flags = ATACMD_READREG;
req.features = WDSM_ENABLE_OPS; req.features = WDSM_ENABLE_OPS;
req.command = WDCC_SMART; req.command = WDCC_SMART;
req.cylinder = WDSMART_CYL; req.cylinder = WDSMART_CYL;
req.timeout = 1000; req.timeout = 1000;
break; break;
case DISABLE: case DISABLE:
req.flags = ATACMD_READ; req.flags = ATACMD_READREG;
req.features = WDSM_DISABLE_OPS; req.features = WDSM_DISABLE_OPS;
req.command = WDCC_SMART; req.command = WDCC_SMART;
req.cylinder = WDSMART_CYL; req.cylinder = WDSMART_CYL;
...@@ -263,28 +262,24 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data) ...@@ -263,28 +262,24 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
break; break;
case AUTO_OFFLINE: case AUTO_OFFLINE:
/* NOTE: According to ATAPI 4 and UP, this command is obsolete */ /* NOTE: According to ATAPI 4 and UP, this command is obsolete */
req.flags = ATACMD_READ; req.flags = ATACMD_READREG;
req.features = ATA_SMART_AUTO_OFFLINE; /* XXX missing from wdcreg.h */ req.features = ATA_SMART_AUTO_OFFLINE; /* XXX missing from wdcreg.h */
req.command = WDCC_SMART; req.command = WDCC_SMART;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL; req.cylinder = WDSMART_CYL;
req.sec_num = select; req.sec_count = select;
req.sec_count = 1;
req.timeout = 1000; req.timeout = 1000;
break; break;
case AUTOSAVE: case AUTOSAVE:
req.flags = ATACMD_READ; req.flags = ATACMD_READREG;
req.features = ATA_SMART_AUTOSAVE; /* XXX missing from wdcreg.h */ req.features = ATA_SMART_AUTOSAVE; /* XXX missing from wdcreg.h */
req.command = WDCC_SMART; req.command = WDCC_SMART;
req.cylinder = WDSMART_CYL; req.cylinder = WDSMART_CYL;
req.sec_count = 0xf1; req.sec_count = select;
/* to enable autosave */
req.timeout = 1000; req.timeout = 1000;
break; break;
case IMMEDIATE_OFFLINE: case IMMEDIATE_OFFLINE:
/* NOTE: According to ATAPI 4 and UP, this command is obsolete */ /* NOTE: According to ATAPI 4 and UP, this command is obsolete */
req.flags = ATACMD_READ; req.flags = ATACMD_READREG;
req.features = ATA_SMART_IMMEDIATE_OFFLINE; /* XXX missing from wdcreg.h */ req.features = ATA_SMART_IMMEDIATE_OFFLINE; /* XXX missing from wdcreg.h */
req.command = WDCC_SMART; req.command = WDCC_SMART;
req.databuf = (char *)inbuf; req.databuf = (char *)inbuf;
...@@ -294,10 +289,9 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data) ...@@ -294,10 +289,9 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
req.sec_count = 1; req.sec_count = 1;
req.timeout = 1000; req.timeout = 1000;
break; break;
case STATUS_CHECK: case STATUS: /* should return 0 if SMART is enabled at all */
/* same command, no HDIO in NetBSD */ case STATUS_CHECK: /* should return 0 if disk's health is ok */
case STATUS: req.flags = ATACMD_READREG;
req.flags = ATACMD_READ;
req.features = WDSM_STATUS; req.features = WDSM_STATUS;
req.command = WDCC_SMART; req.command = WDCC_SMART;
req.cylinder = WDSMART_CYL; req.cylinder = WDSMART_CYL;
...@@ -314,7 +308,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data) ...@@ -314,7 +308,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
return -1; return -1;
} }
if (command == STATUS_CHECK) { if (command == STATUS_CHECK || command == AUTOSAVE || command == AUTO_OFFLINE) {
char buf[512]; char buf[512];
unsigned const short normal = WDSMART_CYL, failed = 0x2cf4; unsigned const short normal = WDSMART_CYL, failed = 0x2cf4;
...@@ -323,6 +317,9 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data) ...@@ -323,6 +317,9 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
perror("Failed command"); perror("Failed command");
return -1; return -1;
} }
if (req.retsts != ATACMD_OK) {
return -1;
}
/* Cyl low and Cyl high unchanged means "Good SMART status" */ /* Cyl low and Cyl high unchanged means "Good SMART status" */
if (req.cylinder == normal) if (req.cylinder == normal)
return 0; return 0;
...@@ -341,10 +338,15 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data) ...@@ -341,10 +338,15 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
printwarning(BAD_SMART, buf); printwarning(BAD_SMART, buf);
return 0; return 0;
} }
if ((retval = ioctl(fd, ATAIOCCOMMAND, &req))) { if ((retval = ioctl(fd, ATAIOCCOMMAND, &req))) {
perror("Failed command"); perror("Failed command");
return -1; return -1;
} }
if (req.retsts != ATACMD_OK) {
return -1;
}
if (command == CHECK_POWER_MODE) if (command == CHECK_POWER_MODE)
data[0] = req.sec_count; data[0] = req.sec_count;
...@@ -417,7 +419,16 @@ do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) ...@@ -417,7 +419,16 @@ do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
(trunc ? " [only first 256 bytes shown]" : "")); (trunc ? " [only first 256 bytes shown]" : ""));
dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len), 1); dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len), 1);
} }
switch (sc.retsts) {
case SCCMD_OK:
return 0; return 0;
case SCCMD_TIMEOUT:
return -ETIMEDOUT;
case SCCMD_BUSY:
return -EBUSY;
default:
return -EIO;
}
} }
/* print examples for smartctl */ /* print examples for smartctl */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment