*
* Home page of code is: http://smartmontools.sourceforge.net
*
- * Copyright (C) 2003-6 Sergey Svishchev <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2003-8 Sergey Svishchev <smartmontools-support@lists.sourceforge.net>
*
* 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
* any later version.
*
* You should have received a copy of the GNU General Public License
- * (for example COPYING); if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * (for example COPYING); if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include "scsicmds.h"
#include "utility.h"
#include "os_netbsd.h"
+
+#include <errno.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 $" \
-ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_NETBSD_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
+const char * os_netbsd_cpp_cvsid = "$Id: os_netbsd.cpp 3806 2013-03-29 20:17:03Z chrfranke $"
+ OS_NETBSD_H_CVSID;
/* global variable holding byte count of allocated memory */
extern long long bytes;
enum warnings {
- BAD_SMART, NO_3WARE, MAX_MSG
+ BAD_SMART, NO_3WARE, NO_ARECA, MAX_MSG
};
/* Utility function for printing warnings */
static int printed[] = {0, 0};
static const char *message[] = {
"Error: SMART Status command failed.\nPlease get assistance from \n" PACKAGE_HOMEPAGE "\nRegister values returned from SMART Status command are:\n",
- PACKAGE_STRING " does not currentlly support twe(4) devices (3ware Escalade)\n",
+ PACKAGE_STRING " does not currently support twe(4) and twa(4) devices (3ware Escalade, Apache)\n",
};
if (msgNo >= 0 && msgNo <= MAX_MSG) {
static const char *net_dev_scsi_disk = "sd";
static const char *net_dev_scsi_tape = "enrst";
-/* Guess device type(ata or scsi) based on device name */
+/* Guess device type (ATA or SCSI) based on device name */
int
guess_device_type(const char *dev_name)
{
return close(fd);
}
-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
ata_command_interface(int fd, smart_command_set command, int select, char *data)
{
int retval, copydata = 0;
memset(&req, 0, sizeof(req));
+ req.timeout = 1000;
+
memset(&inbuf, 0, sizeof(inbuf));
switch (command) {
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL;
- req.timeout = 1000;
copydata = 1;
break;
case READ_THRESHOLDS:
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL;
- req.timeout = 1000;
copydata = 1;
break;
case READ_LOG:
req.cylinder = WDSMART_CYL;
req.sec_num = select;
req.sec_count = 1;
- req.timeout = 1000;
copydata = 1;
break;
case WRITE_LOG:
req.cylinder = WDSMART_CYL;
req.sec_num = select;
req.sec_count = 1;
- req.timeout = 1000;
break;
case IDENTIFY:
req.flags = ATACMD_READ;
req.command = WDCC_IDENTIFY;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
- req.timeout = 1000;
copydata = 1;
break;
case PIDENTIFY:
req.command = ATAPI_IDENTIFY_DEVICE;
req.databuf = (char *)inbuf;
req.datalen = sizeof(inbuf);
- req.timeout = 1000;
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;
- req.timeout = 1000;
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.timeout = 1000;
+ req.sec_count = select;
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.timeout = 1000;
+ req.sec_count = select;
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;
- req.datalen = sizeof(inbuf);
req.cylinder = WDSMART_CYL;
req.sec_num = select;
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;
- req.timeout = 1000;
break;
case CHECK_POWER_MODE:
req.flags = ATACMD_READREG;
req.command = WDCC_CHECK_PWR;
- req.timeout = 1000;
break;
default:
pout("Unrecognized command %d in ata_command_interface()\n", command);
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;
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;
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;
return 0;
}
-int
-escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data)
-{
- printwarning(NO_3WARE, NULL);
- return -1;
-}
-
int
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);
}
- return 0;
+ 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 */