]> git.proxmox.com Git - mirror_smartmontools-debian.git/blobdiff - os_solaris.cpp
Fix FTBFS[kfreebsd]
[mirror_smartmontools-debian.git] / os_solaris.cpp
index 980ed161476a0bb571caf223fde6f9940a9ea46a..793aec7fe52f7706e34880f97d49259030e6de75 100644 (file)
@@ -3,8 +3,8 @@
  *
  * Home page of code is: http://smartmontools.sourceforge.net
  *
- * Copyright (C) 2003-6 SAWADA Keiji <smartmontools-support@lists.sourceforge.net>
- * Copyright (C) 2003-6 Casper Dik <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2003-8 SAWADA Keiji <smartmontools-support@lists.sourceforge.net>
+ * Copyright (C) 2003-8 Casper Dik <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
@@ -12,8 +12,8 @@
  * 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.
  *
  */
 
@@ -39,9 +39,9 @@
 
 extern long long bytes;
 
-static const char *filenameandversion="$Id: os_solaris.cpp,v 1.28 2006/08/25 06:06:25 sxzzsf Exp $";
+static const char *filenameandversion="$Id: os_solaris.cpp 3806 2013-03-29 20:17:03Z chrfranke $";
 
-const char *os_XXXX_c_cvsid="$Id: os_solaris.cpp,v 1.28 2006/08/25 06:06:25 sxzzsf Exp $" \
+const char *os_XXXX_c_cvsid="$Id: os_solaris.cpp 3806 2013-03-29 20:17:03Z chrfranke $" \
 ATACMDS_H_CVSID CONFIG_H_CVSID INT64_H_CVSID OS_SOLARIS_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID;
 
 // The printwarning() function warns about unimplemented functions
@@ -285,17 +285,6 @@ static void swap_sector(void *p)
 #endif
 
 // Interface to ATA devices.  See os_linux.c
-int marvell_command_interface(int fd, smart_command_set command, int select, char *data){
-    ARGUSED(fd); ARGUSED(command); ARGUSED(select); ARGUSED(data);
-    return -1;
-}
-
-int highpoint_command_interface(int fd, smart_command_set command, int select, char *data)
-{
-    ARGUSED(fd); ARGUSED(command); ARGUSED(select); ARGUSED(data);
-    return -1;
-}
-
 int ata_command_interface(int fd, smart_command_set command, int select, char *data){
 #if defined(__sparc)
     int err;
@@ -336,7 +325,7 @@ int ata_command_interface(int fd, smart_command_set command, int select, char *d
        return smart_status_check(fd);
     default:
        pout("Unrecognized command %d in ata_command_interface() of os_solaris.c\n", command);
-       exit(1);
+       EXIT(1);
        break;
     }
 #else /* __sparc */
@@ -352,16 +341,6 @@ int ata_command_interface(int fd, smart_command_set command, int select, char *d
     return -1;
 }
 
-// Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
-int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data){
-  ARGUSED(fd);  ARGUSED(disknum);  ARGUSED(escalade_type);
-  ARGUSED(command);  ARGUSED(select);  ARGUSED(data); 
-
-  if (printwarning(1))
-    return -1;
-  return -1;
-}
-
 #include <errno.h>
 #include <sys/scsi/generic/commands.h>
 #include <sys/scsi/generic/status.h>
@@ -369,37 +348,35 @@ int escalade_command_interface(int fd, int disknum, int escalade_type, smart_com
 #include <sys/scsi/impl/uscsi.h>
 
 // Interface to SCSI devices.  See os_linux.c
-int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
+int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report)
+{
   struct uscsi_cmd uscsi;
 
-    if (report > 0) {
-        int k;
-        const unsigned char * ucp = iop->cmnd;
-        const char * np;
-
-        np = scsi_get_opcode_name(ucp[0]);
-        pout(" [%s: ", np ? np : "<unknown opcode>");
-        for (k = 0; k < (int)iop->cmnd_len; ++k)
-            pout("%02x ", ucp[k]);
-        if ((report > 1) && 
-            (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
-            int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-
-            pout("]\n  Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
-                 (trunc ? " [only first 256 bytes shown]" : ""));
-            dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
-        }
-        else
-            pout("]");
+  if (report > 0) {
+    int k;
+    const unsigned char * ucp = iop->cmnd;
+    const char * np;
+
+    np = scsi_get_opcode_name(ucp[0]);
+    pout(" [%s: ", np ? np : "<unknown opcode>");
+    for (k = 0; k < (int)iop->cmnd_len; ++k)
+      pout("%02x ", ucp[k]);
+    pout("]\n");
+    if ((report > 1) && 
+        (DXFER_TO_DEVICE == iop->dxfer_dir) && (iop->dxferp)) {
+      int trunc = (iop->dxfer_len > 256) ? 1 : 0;
+
+      pout("  Outgoing data, len=%d%s:\n", (int)iop->dxfer_len,
+           (trunc ? " [only first 256 bytes shown]" : ""));
+      dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
     }
-
-
+  }
   memset(&uscsi, 0, sizeof (uscsi));
 
   uscsi.uscsi_cdb = reinterpret_cast<char*>(iop->cmnd);
   uscsi.uscsi_cdblen = iop->cmnd_len;
   if (iop->timeout == 0)
-    uscsi.uscsi_timeout = 60; /* XXX */
+    uscsi.uscsi_timeout = 60; /* 60 seconds */
   else
     uscsi.uscsi_timeout = iop->timeout;
   uscsi.uscsi_bufaddr = reinterpret_cast<char*>(iop->dxferp);
@@ -418,23 +395,51 @@ int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) {
   default:
     return -EINVAL;
   }
-  uscsi.uscsi_flags |= USCSI_ISOLATE;
+  uscsi.uscsi_flags |= (USCSI_ISOLATE | USCSI_RQENABLE);
+
+  if (ioctl(fd, USCSICMD, &uscsi)) {
+    int err = errno;
 
-  if (ioctl(fd, USCSICMD, &uscsi))
-    return -errno;
+    if (! ((EIO == err) && uscsi.uscsi_status))
+      return -err;
+    /* errno is set to EIO when a non-zero SCSI completion status given */
+  }
 
   iop->scsi_status = uscsi.uscsi_status;
   iop->resid = uscsi.uscsi_resid;
   iop->resp_sense_len = iop->max_sense_len - uscsi.uscsi_rqresid;
 
   if (report > 0) {
-    int trunc = (iop->dxfer_len > 256) ? 1 : 0;
-    pout("  status=0\n");
-    
-    pout("  Incoming data, len=%d%s:\n", (int)iop->dxfer_len,
-         (trunc ? " [only first 256 bytes shown]" : ""));
-    dStrHex((char *)iop->dxferp, (trunc ? 256 : iop->dxfer_len) , 1);
+    int trunc;
+    int len = iop->resp_sense_len;
+
+    if ((SCSI_STATUS_CHECK_CONDITION == iop->scsi_status) &&
+        iop->sensep && (len > 3)) {
+      if ((iop->sensep[0] & 0x7f) > 0x71)
+        pout("  status=%x: [desc] sense_key=%x asc=%x ascq=%x\n",
+             iop->scsi_status, iop->sensep[1] & 0xf,
+             iop->sensep[2], iop->sensep[3]);
+      else
+        pout("  status=%x: sense_key=%x asc=%x ascq=%x\n",
+             iop->scsi_status, iop->sensep[2] & 0xf,
+             iop->sensep[12], iop->sensep[13]);
+      if (report > 1) {
+          pout("  >>> Sense buffer, len=%d:\n", len);
+          dStrHex((const char *)iop->sensep, ((len > 252) ? 252 : len) , 1);
+      }
+    } else if (iop->scsi_status)
+      pout("  status=%x\n", iop->scsi_status);
+    if (iop->resid)
+      pout("  dxfer_len=%d, resid=%d\n", iop->dxfer_len, iop->resid);
+    if (report > 1) {
+      len = iop->dxfer_len - iop->resid;
+      if (len > 0) {
+        trunc = (len > 256) ? 1 : 0;
+        pout("  Incoming data, len=%d%s:\n", len,
+             (trunc ? " [only first 256 bytes shown]" : ""));
+        dStrHex((char *)iop->dxferp, (trunc ? 256 : len) , 1);
+      }
+    }
   }
-
-  return (0);
+  return 0;
 }