]> git.proxmox.com Git - mirror_smartmontools-debian.git/blobdiff - os_win32.cpp
Imported Upstream version 5.41+svn3365
[mirror_smartmontools-debian.git] / os_win32.cpp
index 1989af1de0854a451e965b368db28d34375dc045..06ae4b5522eaa26266fcd31684e0c431d2b5787d 100644 (file)
@@ -85,7 +85,7 @@
 #define SELECT_WIN_32_64(x32, x64) (x64)
 #endif
 
-const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3292 2011-03-09 21:12:03Z chrfranke $";
+const char * os_win32_cpp_cvsid = "$Id: os_win32.cpp 3358 2011-06-06 19:04:20Z chrfranke $";
 
 // Disable Win9x/ME specific code if no longer supported by compiler.
 #ifdef _WIN64
@@ -380,6 +380,7 @@ private:
   bool m_usr_options; // options set by user?
   bool m_admin; // open with admin access?
   bool m_id_is_cached; // ata_identify_is_cached() return value.
+  bool m_is_3ware; // AMCC/3ware controller detected?
   int m_drive, m_port;
   int m_smartver_state;
 };
@@ -2116,6 +2117,9 @@ static int get_identify_from_device_property(HANDLE hdevice, ata_identify_device
   if (data.desc.ProductIdOffset) {
     while (i > 1 && model[i-2] == ' ') // Keep last blank from VendorId
       i--;
+    // Ignore VendorId "ATA"
+    if (i <= 4 && !strncmp(model, "ATA", 3) && (i == 3 || model[3] == ' '))
+      i = 0;
     for (unsigned j = 0; i < sizeof(model)-1 && data.raw[data.desc.ProductIdOffset+j]; i++, j++)
       model[i] = data.raw[data.desc.ProductIdOffset+j];
   }
@@ -2407,6 +2411,7 @@ win_ata_device::win_ata_device(smart_interface * intf, const char * dev_name, co
   m_usr_options(false),
   m_admin(false),
   m_id_is_cached(false),
+  m_is_3ware(false),
   m_drive(0),
   m_port(-1),
   m_smartver_state(0)
@@ -2532,13 +2537,16 @@ bool win_ata_device::open(int phydrive, int logdrive, const char * options, int
   // Win9X/ME: Get drive map
   // RAID: Get port map
   GETVERSIONINPARAMS_EX vers_ex;
-  int devmap = smart_get_version(h, (port >= 0 ? &vers_ex : 0));
+  int devmap = smart_get_version(h, &vers_ex);
+
+  // 3ware RAID if vendor id present
+  m_is_3ware = (vers_ex.wIdentifier == SMART_VENDOR_3WARE);
 
   unsigned long portmap = 0;
   if (port >= 0 && devmap >= 0) {
     // 3ware RAID: check vendor id
-    if (vers_ex.wIdentifier != SMART_VENDOR_3WARE) {
-      pout("SMART_GET_VERSION returns unknown Identifier = %04x\n"
+    if (!m_is_3ware) {
+      pout("SMART_GET_VERSION returns unknown Identifier = 0x%04x\n"
            "This is no 3ware 9000 controller or driver has no SMART support.\n",
            vers_ex.wIdentifier);
       devmap = -1;
@@ -2643,6 +2651,12 @@ bool win_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
   )
     return false;
 
+  // 3ware RAID: SMART DISABLE without port number disables SMART functions
+  if (   m_is_3ware && m_port < 0
+      && in.in_regs.command == ATA_SMART_CMD
+      && in.in_regs.features == ATA_SMART_DISABLE)
+    return set_err(ENOSYS, "SMART DISABLE requires 3ware port number");
+
   // Determine ioctl functions valid for this ATA cmd
   const char * valid_options = 0;
 
@@ -2821,7 +2835,8 @@ bool win_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
         }
         if (!m_smartver_state) {
           assert(m_port == -1);
-          if (smart_get_version(get_fh()) < 0) {
+          GETVERSIONINPARAMS_EX vers_ex;
+          if (smart_get_version(get_fh(), &vers_ex) < 0) {
             if (!failuretest_permissive) {
               m_smartver_state = 2;
               rc = -1; errno = ENOSYS;
@@ -2829,6 +2844,11 @@ bool win_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
             }
             failuretest_permissive--;
           }
+          else  {
+            // 3ware RAID if vendor id present
+            m_is_3ware = (vers_ex.wIdentifier == SMART_VENDOR_3WARE);
+          }
+
           m_smartver_state = 1;
         }
         rc = smart_ioctl(get_fh(), m_drive, &regs, data, datasize, m_port);
@@ -4038,6 +4058,10 @@ bool win_scsi_device::scsi_pass_through(struct scsi_cmnd_io * iop)
     memcpy(iop->sensep, sb.ucSenseBuf, slen);
     iop->resp_sense_len = slen;
     if (report) {
+      if (report > 1) {
+        pout("  >>> Sense buffer, len=%d:\n", slen);
+        dStrHex(iop->sensep, slen , 1);
+      }
       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,