Skip to content

Commit

Permalink
Add options to get/set ATA DSN (Device Statistics Notification)
Browse files Browse the repository at this point in the history
feature (ticket #815):
atacmds.h: Add DSN feature subcommand code.
ataprint.cpp, ataprint.h, smartctl.cpp: Add '-g/s dsn' options.
smartd.cpp: Add '-e dsn' directive.
smartctl.8.in, smartd.conf.5.in: Document the new options.

Patch was provided by Jonghwan Choi.

git-svn-id: https://svn.code.sf.net/p/smartmontools/code/trunk/smartmontools@4402 4ea69e1a-61f1-4043-bf83-b5c94c648137
  • Loading branch information
chrfranke committed Mar 9, 2017
1 parent 21c72cf commit 6332f9f
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 12 deletions.
9 changes: 9 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
$Id$

2017-03-09 Jonghwan Choi <[email protected]>

Add options to get/set ATA DSN (Device Statistics Notification)
feature (ticket #815):
atacmds.h: Add DSN feature subcommand code.
ataprint.cpp, ataprint.h, smartctl.cpp: Add '-g/s dsn' options.
smartd.cpp: Add '-e dsn' directive.
smartctl.8.in, smartd.conf.5.in: Document the new options.

2017-03-04 Christian Franke <[email protected]>

smartctl.cpp, smartd.cpp: Fix help text for '-B' option.
Expand Down
1 change: 1 addition & 0 deletions atacmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ typedef enum {
#define ATA_ENABLE_APM 0x05
#define ATA_ENABLE_WRITE_CACHE 0x02
#define ATA_ENABLE_READ_LOOK_AHEAD 0xaa
#define ATA_ENABLE_DISABLE_DSN 0x63

// 48-bit commands
#define ATA_READ_LOG_EXT 0x2F
Expand Down
27 changes: 25 additions & 2 deletions ataprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2795,6 +2795,18 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
!(drive.cfs_enable_1 & 0x0020) ? "Disabled" : "Enabled"); // word085
}

// Print DSN status
unsigned short word120 = drive.words088_255[120-88];
if (options.get_dsn) {
if (!(drive.word086 & 0x8000) // word086
|| ((word120 & 0xc000) != 0x4000)) // word120
pout("DSN feature is: Unavailable\n");
else if (word120 & 0x200) // word120
pout("DSN feature is: Enabled\n");
else
pout("DSN feature is: Disabled\n");
}

// Check for ATA Security LOCK
unsigned short word128 = drive.words088_255[128-88];
bool locked = ((word128 & 0x0007) == 0x0007); // LOCKED|ENABLED|SUPPORTED
Expand Down Expand Up @@ -2866,7 +2878,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
|| options.smart_auto_offl_disable || options.smart_auto_offl_enable
|| options.set_aam || options.set_apm || options.set_lookahead
|| options.set_wcache || options.set_security_freeze || options.set_standby
|| options.sct_wcache_reorder_set || options.sct_wcache_sct_set)
|| options.sct_wcache_reorder_set || options.sct_wcache_sct_set || options.set_dsn)
pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n");

// Enable/Disable AAM
Expand Down Expand Up @@ -2931,6 +2943,17 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
pout("Write cache %sabled\n", (enable ? "en" : "dis"));
}

// Enable/Disable DSN
if (options.set_dsn) {
bool enable = (options.set_dsn > 0);
if (!ata_set_features(device, ATA_ENABLE_DISABLE_DSN, (enable ? 0x1 : 0x2))) {
pout("DSN %sable failed: %s\n", (enable ? "en" : "dis"), device->get_errmsg());
returnval |= FAILSMART;
}
else
pout("DSN %sabled\n", (enable ? "en" : "dis"));
}

// Enable/Disable write cache reordering
if (options.sct_wcache_reorder_set) {
bool enable = (options.sct_wcache_reorder_set > 0);
Expand Down Expand Up @@ -3100,7 +3123,7 @@ int ataPrintMain (ata_device * device, const ata_print_options & options)
|| options.smart_auto_offl_disable || options.smart_auto_offl_enable
|| options.set_aam || options.set_apm || options.set_lookahead
|| options.set_wcache || options.set_security_freeze || options.set_standby
|| options.sct_wcache_reorder_set)
|| options.sct_wcache_reorder_set || options.set_dsn)
pout("\n");

// START OF READ-ONLY OPTIONS APART FROM -V and -i
Expand Down
5 changes: 4 additions & 1 deletion ataprint.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ struct ata_print_options
bool sct_wcache_sct_get; // print SCT Feature Control of write cache status
int sct_wcache_sct_set; // determined by ata set features command(1), force enable(2), force disable(3)
bool sct_wcache_sct_set_pers; // persistent or volatile
bool get_dsn; // print DSN status
int set_dsn; // disable(02h), enable(01h) DSN

ata_print_options()
: drive_info(false),
Expand Down Expand Up @@ -153,7 +155,8 @@ struct ata_print_options
sct_wcache_reorder_get(false), sct_wcache_reorder_set(0),
sct_wcache_reorder_set_pers(false),
sct_wcache_sct_get(false), sct_wcache_sct_set(0),
sct_wcache_sct_set_pers(false)
sct_wcache_sct_set_pers(false),
get_dsn(false), set_dsn(0)
{ }
};

Expand Down
4 changes: 4 additions & 0 deletions smartctl.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,10 @@ commands. If ´,p´ is specified, the setting is preserved across power cycles.
\'Off\' value disables read cache (if supported).
The read cache is usually enabled by default.

.I dsn[,on|off]
\- [ATA only] Gets/sets the DSN feature (if supported).
The dsn is usually disabled by default.

.TP
.B SMART READ AND DISPLAY DATA OPTIONS:
.TP
Expand Down
23 changes: 18 additions & 5 deletions smartctl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ static void Usage()
" --identify[=[w][nvb]]\n"
" Show words and bits from IDENTIFY DEVICE data (ATA)\n\n"
" -g NAME, --get=NAME\n"
" Get device setting: all, aam, apm, lookahead, security, wcache, rcache, wcreorder, wcache-sct\n\n"
" Get device setting: all, aam, apm, dsn, lookahead, security, wcache, rcache, wcreorder, wcache-sct\n\n"
" -a, --all\n"
" Show all SMART information for device\n\n"
" -x, --xall\n"
Expand Down Expand Up @@ -122,7 +122,7 @@ static void Usage()
" Enable/disable Attribute autosave on device (on/off)\n\n"
" -s NAME[,VALUE], --set=NAME[,VALUE]\n"
" Enable/disable/change device setting: aam,[N|off], apm,[N|off],\n"
" lookahead,[on|off], security-freeze, standby,[N|off|now],\n"
" dsn,[on|off], lookahead,[on|off], security-freeze, standby,[N|off|now],\n"
" wcache,[on|off], rcache,[on|off], wcreorder,[on|off[,p]]\n"
" wcache-sct,[ata|on|off[,p]]\n\n"
);
Expand Down Expand Up @@ -224,9 +224,9 @@ static std::string getvalidarglist(int opt)
case 'f':
return "old, brief, hex[,id|val]";
case 'g':
return "aam, apm, lookahead, security, wcache, rcache, wcreorder, wcache-sct";
return "aam, apm, dsn, lookahead, security, wcache, rcache, wcreorder, wcache-sct";
case opt_set:
return "aam,[N|off], apm,[N|off], lookahead,[on|off], security-freeze, "
return "aam,[N|off], apm,[N|off], dsn,[on|off], lookahead,[on|off], security-freeze, "
"standby,[N|off|now], wcache,[on|off], rcache,[on|off], wcreorder,[on|off[,p]], "
"wcache-sct,[ata|on|off[,p]]";
case 's':
Expand Down Expand Up @@ -897,7 +897,7 @@ static const char * parse_options(int argc, char** argv,
if (get && !strcmp(name, "all")) {
ataopts.get_aam = ataopts.get_apm = true;
ataopts.get_security = true;
ataopts.get_lookahead = ataopts.get_wcache = true;
ataopts.get_lookahead = ataopts.get_wcache = ataopts.get_dsn = true;
scsiopts.get_rcd = scsiopts.get_wce = true;
}
else if (!strcmp(name, "aam")) {
Expand Down Expand Up @@ -1006,6 +1006,19 @@ static const char * parse_options(int argc, char** argv,
else
badarg = true;
}
else if (!strcmp(name, "dsn")) {
if (get) {
ataopts.get_dsn = true;
}
else if (off) {
ataopts.set_dsn = -1;
}
else if (on) {
ataopts.set_dsn = 1;
}
else
badarg = true;
}
else
badarg = true;
}
Expand Down
3 changes: 3 additions & 0 deletions smartd.conf.5.in
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,9 @@ IDLE mode.

.I wcache,[on|off]
\- [ATA only] Sets the volatile write cache feature.

.I dsn,[on|off]
\- [ATA only] Sets the DSN feature.
.TP
.B \-s REGEXP
Run Self-Tests or Offline Immediate Tests, at scheduled times. A
Expand Down
21 changes: 17 additions & 4 deletions smartd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ struct dev_config
int set_standby; // set(1..255->0..254) standby timer
bool set_security_freeze; // Freeze ATA security
int set_wcache; // disable(-1), enable(1) write cache
int set_dsn; // disable(0x2), enable(0x1) DSN

bool sct_erc_set; // set SCT ERC to:
unsigned short sct_erc_readtime; // ERC read time (deciseconds)
Expand Down Expand Up @@ -328,7 +329,7 @@ dev_config::dev_config()
set_lookahead(0),
set_standby(0),
set_security_freeze(false),
set_wcache(0),
set_wcache(0), set_dsn(0),
sct_erc_set(false),
sct_erc_readtime(0), sct_erc_writetime(0),
curr_pending_id(0), offl_pending_id(0),
Expand Down Expand Up @@ -1438,8 +1439,8 @@ static void Directives()
" -l TYPE Monitor SMART log or self-test status:\n"
" error, selftest, xerror, offlinests[,ns], selfteststs[,ns]\n"
" -l scterc,R,W Set SCT Error Recovery Control\n"
" -e Change device setting: aam,[N|off], apm,[N|off], lookahead,[on|off],\n"
" security-freeze, standby,[N|off], wcache,[on|off]\n"
" -e Change device setting: aam,[N|off], apm,[N|off], dsn,[on|off],\n"
" lookahead,[on|off], security-freeze, standby,[N|off], wcache,[on|off]\n"
" -f Monitor 'Usage' Attributes, report failures\n"
" -m ADD Send email warning to address ADD\n"
" -M TYPE Modify email warning behavior (see man page)\n"
Expand Down Expand Up @@ -2114,6 +2115,10 @@ static int ATADeviceScan(dev_config & cfg, dev_state & state, ata_device * atade
format_set_result_msg(msg, "Wr-cache", ata_set_features(atadev,
(cfg.set_wcache > 0? ATA_ENABLE_WRITE_CACHE : ATA_DISABLE_WRITE_CACHE)), cfg.set_wcache);

if (cfg.set_dsn)
format_set_result_msg(msg, "DSN", ata_set_features(atadev,
ATA_ENABLE_DISABLE_DSN, (cfg.set_dsn > 0 ? 0x1 : 0x2)));

if (cfg.set_security_freeze)
format_set_result_msg(msg, "Security freeze",
ata_nodata_command(atadev, ATA_SECURITY_FREEZE_LOCK));
Expand Down Expand Up @@ -3843,7 +3848,7 @@ static void printoutvaliddirectiveargs(int priority, char d)
PrintOut(priority, "%s", get_valid_firmwarebug_args());
break;
case 'e':
PrintOut(priority, "aam,[N|off], apm,[N|off], lookahead,[on|off], "
PrintOut(priority, "aam,[N|off], apm,[N|off], lookahead,[on|off], dsn,[on|off] "
"security-freeze, standby,[N|off], wcache,[on|off]");
break;
}
Expand Down Expand Up @@ -4365,6 +4370,14 @@ static int ParseToken(char * token, dev_config & cfg, smart_devtype_list & scan_
else
badarg = true;
}
else if (!strcmp(arg2, "dsn")) {
if (off)
cfg.set_dsn = -1;
else if (on)
cfg.set_dsn = 1;
else
badarg = true;
}
else
badarg = true;
}
Expand Down

0 comments on commit 6332f9f

Please sign in to comment.