]> git.proxmox.com Git - mirror_smartmontools-debian.git/blobdiff - os_netbsd.cpp
Updated changelog
[mirror_smartmontools-debian.git] / os_netbsd.cpp
index 8e179b3e285281b37bcb40d44900ce0237163ad8..09d4a7ef88d7a787d0c8252cbcb2c64424331cc3 100644 (file)
@@ -3,7 +3,7 @@
  *
  * 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
 #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 3265 2011-02-21 16:21:14Z 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 */
@@ -41,7 +43,7 @@ printwarning(int msgNo, const char *extra)
   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) {
@@ -60,7 +62,7 @@ static const char *net_dev_ata_disk = "wd";
 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)
 {
@@ -171,10 +173,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)
@@ -184,6 +185,8 @@ 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) {
@@ -194,7 +197,6 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
     req.databuf = (char *)inbuf;
     req.datalen = sizeof(inbuf);
     req.cylinder = WDSMART_CYL;
-    req.timeout = 1000;
     copydata = 1;
     break;
   case READ_THRESHOLDS:
@@ -204,7 +206,6 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
     req.databuf = (char *)inbuf;
     req.datalen = sizeof(inbuf);
     req.cylinder = WDSMART_CYL;
-    req.timeout = 1000;
     copydata = 1;
     break;
   case READ_LOG:
@@ -216,7 +217,6 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
     req.cylinder = WDSMART_CYL;
     req.sec_num = select;
     req.sec_count = 1;
-    req.timeout = 1000;
     copydata = 1;
     break;
   case WRITE_LOG:
@@ -229,14 +229,12 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
     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:
@@ -244,69 +242,54 @@ ata_command_interface(int fd, smart_command_set command, int select, char *data)
     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);
@@ -314,7 +297,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 +306,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 +327,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;
 
@@ -361,6 +352,13 @@ escalade_command_interface(int fd, int disknum, int escalade_type, smart_command
   return -1;
 }
 
+int
+areca_command_interface(int fd, int disknum, smart_command_set command, int select, char *data)
+{
+  printwarning(NO_ARECA, NULL);
+  return -1;
+}
+
 int
 do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
 {
@@ -417,7 +415,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);
   }
-  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 */