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
$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:
http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup
......@@ -38,6 +38,12 @@ NOTES FOR FUTURE RELEASES: see TODO file.
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
[BA] Fix auto-offline support in FreeBSD. Thanks to
......
......@@ -24,7 +24,7 @@
#include "os_netbsd.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;
/* global variable holding byte count of allocated memory */
......@@ -171,10 +171,9 @@ int
marvell_command_interface(int fd, smart_command_set command, int select, char *data)
{ return -1; }
int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
{
return -1;
}
int
highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
{ return -1; }
int
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;
break;
case ENABLE:
req.flags = ATACMD_READ;
req.flags = ATACMD_READREG;
req.features = WDSM_ENABLE_OPS;
req.command = WDCC_SMART;
req.cylinder = WDSMART_CYL;
req.timeout = 1000;
break;
case DISABLE:
req.flags = ATACMD_READ;
req.flags = ATACMD_READREG;
req.features = WDSM_DISABLE_OPS;
req.command = WDCC_SMART;
req.cylinder = WDSMART_CYL;
......@@ -263,28 +262,24 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
break;
case AUTO_OFFLINE:
/* 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.command = WDCC_SMART;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL;
req.sec_num = select;
req.sec_count = 1;
req.sec_count = select;
req.timeout = 1000;
break;
case AUTOSAVE:
req.flags = ATACMD_READ;
req.flags = ATACMD_READREG;
req.features = ATA_SMART_AUTOSAVE; /* XXX missing from wdcreg.h */
req.command = WDCC_SMART;
req.cylinder = WDSMART_CYL;
req.sec_count = 0xf1;
/* to enable autosave */
req.sec_count = select;
req.timeout = 1000;
break;
case IMMEDIATE_OFFLINE:
/* 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.command = WDCC_SMART;
req.databuf = (char *)inbuf;
......@@ -294,10 +289,9 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
req.sec_count = 1;
req.timeout = 1000;
break;
case STATUS_CHECK:
/* same command, no HDIO in NetBSD */
case STATUS:
req.flags = ATACMD_READ;
case STATUS: /* should return 0 if SMART is enabled at all */
case STATUS_CHECK: /* should return 0 if disk's health is ok */
req.flags = ATACMD_READREG;
req.features = WDSM_STATUS;
req.command = WDCC_SMART;
req.cylinder = WDSMART_CYL;
......@@ -314,7 +308,7 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
return -1;
}
if (command == STATUS_CHECK) {
if (command == STATUS_CHECK || command == AUTOSAVE || command == AUTO_OFFLINE) {
char buf[512];
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)
perror("Failed command");
return -1;
}
if (req.retsts != ATACMD_OK) {
return -1;
}
/* Cyl low and Cyl high unchanged means "Good SMART status" */
if (req.cylinder == normal)
return 0;
......@@ -341,10 +338,15 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
printwarning(BAD_SMART, buf);
return 0;
}
if ((retval = ioctl(fd, ATAIOCCOMMAND, &req))) {
perror("Failed command");
return -1;
}
if (req.retsts != ATACMD_OK) {
return -1;
}
if (command == CHECK_POWER_MODE)
data[0] = req.sec_count;
......@@ -417,7 +419,16 @@ do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
(trunc ? " [only first 256 bytes shown]" : ""));
dStrHex(iop->dxferp, (trunc ? 256 : iop->dxfer_len), 1);
}
switch (sc.retsts) {
case SCCMD_OK:
return 0;
case SCCMD_TIMEOUT:
return -ETIMEDOUT;
case SCCMD_BUSY:
return -EBUSY;
default:
return -EIO;
}
}
/* 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