From fe427fba002b3618f115a5909e4a13e4da2e4c77 Mon Sep 17 00:00:00 2001
From: chrfranke <chrfranke@4ea69e1a-61f1-4043-bf83-b5c94c648137>
Date: Sat, 16 Jan 2010 18:08:45 +0000
Subject: [PATCH] Windows: Set ata_device::ata_identify_is_cached() return
 value according to I/O-control actually used.

git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@3036 4ea69e1a-61f1-4043-bf83-b5c94c648137
---
 smartmontools/CHANGELOG    |  3 +++
 smartmontools/os_win32.cpp | 16 +++++++++++++---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/smartmontools/CHANGELOG b/smartmontools/CHANGELOG
index 50642d9a7..ed48e14c7 100644
--- a/smartmontools/CHANGELOG
+++ b/smartmontools/CHANGELOG
@@ -43,6 +43,9 @@ NOTES FOR FUTURE RELEASES: see TODO file.
 
 <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
 
+  [CF] Windows: Set ata_device::ata_identify_is_cached() return value
+       according to I/O-control actually used.
+
   [CF] Print ATA output registers if SMART status command returns bogus
        register values.
 
diff --git a/smartmontools/os_win32.cpp b/smartmontools/os_win32.cpp
index 5d9d90d3c..ab4aad2cb 100644
--- a/smartmontools/os_win32.cpp
+++ b/smartmontools/os_win32.cpp
@@ -133,6 +133,7 @@ private:
   std::string m_options;
   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.
   int m_drive, m_port;
   int m_smartver_state;
 };
@@ -2275,6 +2276,7 @@ win_ata_device::win_ata_device(smart_interface * intf, const char * dev_name, co
 : smart_device(intf, dev_name, "ata", req_type),
   m_usr_options(false),
   m_admin(false),
+  m_id_is_cached(false),
   m_drive(0),
   m_port(-1),
   m_smartver_state(0)
@@ -2682,6 +2684,7 @@ bool win_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
   // Try all valid ioctls in the order specified in m_options
   bool powered_up = false;
   bool out_regs_set = false;
+  bool id_is_cached = false;
   const char * options = m_options.c_str();
 
   for (int i = 0; ; i++) {
@@ -2729,9 +2732,11 @@ bool win_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
         }
         rc = smart_ioctl(get_fh(), m_drive, &regs, data, datasize, m_port);
         out_regs_set = (in.in_regs.features == ATA_SMART_STATUS);
+        id_is_cached = (m_port < 0 && !win9x); // Not cached by 3ware or Win9x/ME driver
         break;
       case 'm':
         rc = ata_via_scsi_miniport_smart_ioctl(get_fh(), &regs, data, datasize);
+        id_is_cached = (m_port < 0 && !win9x);
         break;
       case 'a':
         rc = ata_pass_through_ioctl(get_fh(), &regs,
@@ -2749,6 +2754,7 @@ bool win_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
       case 'f':
         if (in.in_regs.command == ATA_IDENTIFY_DEVICE) {
             rc = get_identify_from_device_property(get_fh(), (ata_identify_device *)data);
+            id_is_cached = true;
         }
         else if (in.in_regs.command == ATA_SMART_CMD) switch (in.in_regs.features) {
           case ATA_SMART_READ_VALUES:
@@ -2843,15 +2849,19 @@ bool win_ata_device::ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out)
       hi.lba_high     = prev_regs.bCylHighReg;
     }
   }
+
+  if (   in.in_regs.command == ATA_IDENTIFY_DEVICE
+      || in.in_regs.command == ATA_IDENTIFY_PACKET_DEVICE)
+    // Update ata_identify_is_cached() result according to ioctl used.
+    m_id_is_cached = id_is_cached;
+
   return true;
 }
 
 // Return true if OS caches the ATA identify sector
 bool win_ata_device::ata_identify_is_cached() const
 {
-  // Not RAID and WinNT4/2000/XP => true, RAID or Win9x/ME => false
-  // TODO: Set according to ioctl used.
-  return (m_port < 0 && !win9x);
+  return m_id_is_cached;
 }
 
 
-- 
GitLab