diff --git a/smartmontools/CHANGELOG b/smartmontools/CHANGELOG index 53fa8b14369222b6fdf716c2abd80782f7f2fa07..107c228cc89d86e90515c227f37baa4ed5f7c1ed 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 973705ff70b9eebb5eeef75e6a6a685ef79fa528..bc5265940f1d33ea7e0b2f67c833cbd07681efef 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 5921e00463b1743548ca0cb0a60268d8dd3b43b0..1278e87112fa9f4968ec71ec9de5506e2b9de323 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(); };