From 5a408e22519cb3361032f896b8050f7ec01ebefb Mon Sep 17 00:00:00 2001
From: chrfranke <chrfranke@4ea69e1a-61f1-4043-bf83-b5c94c648137>
Date: Wed, 30 Dec 2009 16:25:59 +0000
Subject: [PATCH] Add direct access to 48-bit LBA register in
 'ata_in/out_regs_48bit'.

git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@3015 4ea69e1a-61f1-4043-bf83-b5c94c648137
---
 smartmontools/CHANGELOG         |  2 ++
 smartmontools/dev_interface.cpp |  8 ++++--
 smartmontools/dev_interface.h   | 50 +++++++++++++++++++++++++++++++++
 3 files changed, 58 insertions(+), 2 deletions(-)

diff --git a/smartmontools/CHANGELOG b/smartmontools/CHANGELOG
index 53fa8b143..107c228cc 100644
--- a/smartmontools/CHANGELOG
+++ b/smartmontools/CHANGELOG
@@ -43,6 +43,8 @@ NOTES FOR FUTURE RELEASES: see TODO file.
 
 <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE>
 
+  [CF] Add direct access to 48-bit LBA register in 'ata_in/out_regs_48bit'.
+
   [DL] drivedb.h updates:
        - WDC My Passport Essential/USB (capacity 250GB, 400GB & 500GB)
 
diff --git a/smartmontools/dev_interface.cpp b/smartmontools/dev_interface.cpp
index 973705ff7..bc5265940 100644
--- a/smartmontools/dev_interface.cpp
+++ b/smartmontools/dev_interface.cpp
@@ -89,7 +89,9 @@ ata_in_regs_48bit::ata_in_regs_48bit()
   sector_count_16(sector_count, prev.sector_count),
   lba_low_16(lba_low, prev.lba_low),
   lba_mid_16(lba_mid, prev.lba_mid),
-  lba_high_16(lba_high, prev.lba_high)
+  lba_high_16(lba_high, prev.lba_high),
+  lba_48(     lba_low,      lba_mid,      lba_high,
+         prev.lba_low, prev.lba_mid, prev.lba_high)
 {
 }
 
@@ -97,7 +99,9 @@ ata_out_regs_48bit::ata_out_regs_48bit()
 : sector_count_16(sector_count, prev.sector_count),
   lba_low_16(lba_low, prev.lba_low),
   lba_mid_16(lba_mid, prev.lba_mid),
-  lba_high_16(lba_high, prev.lba_high)
+  lba_high_16(lba_high, prev.lba_high),
+  lba_48(     lba_low,      lba_mid,      lba_high,
+         prev.lba_low, prev.lba_mid, prev.lba_high)
 {
 }
 
diff --git a/smartmontools/dev_interface.h b/smartmontools/dev_interface.h
index 5921e0046..1278e8711 100644
--- a/smartmontools/dev_interface.h
+++ b/smartmontools/dev_interface.h
@@ -325,6 +325,50 @@ private:
 };
 
 
+/// 48-bit alias to six 8-bit ATA registers (for LBA).
+class ata_reg_alias_48
+{
+public:
+  ata_reg_alias_48(ata_register & ll, ata_register & lm, ata_register & lh,
+                   ata_register & hl, ata_register & hm, ata_register & hh)
+    : m_ll(ll), m_lm(lm), m_lh(lh),
+      m_hl(hl), m_hm(hm), m_hh(hh)
+    { }
+
+  ata_reg_alias_48 & operator=(uint64_t val)
+    {
+      m_ll = (unsigned char) val;
+      m_lm = (unsigned char)(val >>  8);
+      m_lh = (unsigned char)(val >> 16);
+      m_hl = (unsigned char)(val >> 24);
+      m_hm = (unsigned char)(val >> 32);
+      m_hh = (unsigned char)(val >> 40);
+      return * this;
+    }
+
+  uint64_t val() const
+    {
+      return (   (unsigned)m_ll
+              | ((unsigned)m_lm <<  8)
+              | ((unsigned)m_lh << 16)
+              | ((unsigned)m_hl << 24)
+              | ((uint64_t)m_hm << 32)
+              | ((uint64_t)m_hh << 40));
+    }
+
+  operator uint64_t() const
+    { return val(); }
+
+private:
+  ata_register & m_ll, & m_lm, & m_lh,
+               & m_hl, & m_hm, & m_hh;
+
+  // References must not be copied.
+  ata_reg_alias_48(const ata_reg_alias_48 &);
+  void operator=(const ata_reg_alias_48 &);
+};
+
+
 /// ATA Input registers for 48-bit commands
 // See section 4.14 of T13/1532D Volume 1 Revision 4b
 //
@@ -348,6 +392,9 @@ struct ata_in_regs_48bit
   ata_reg_alias_16 lba_mid_16;
   ata_reg_alias_16 lba_high_16;
 
+  // 48-bit alias to all 8-bit LBA registers.
+  ata_reg_alias_48 lba_48;
+
   /// Return true if 48-bit command
   bool is_48bit_cmd() const
     { return prev.is_set(); }
@@ -373,6 +420,9 @@ struct ata_out_regs_48bit
   ata_reg_alias_16 lba_mid_16;
   ata_reg_alias_16 lba_high_16;
 
+  // 48-bit alias to all 8-bit LBA registers.
+  ata_reg_alias_48 lba_48;
+
   ata_out_regs_48bit();
 };
 
-- 
GitLab