From 0469a4b4e7f384b3b72e1fc47839959804b2406f Mon Sep 17 00:00:00 2001
From: Jonwhan Choi <jhbird.choi@gmail.com>
Date: Tue, 21 Mar 2017 02:29:37 +0900
Subject: [PATCH] Enable/Disable the certain device features by specifying
feature value and sector count value.
Signed-off-by: Jonwhan Choi <jhbird.choi@gmail.com>
---
ataprint.cpp | 12 +++++++++++-
ataprint.h | 5 ++++-
smartctl.8.in | 5 +++++
smartctl.cpp | 34 +++++++++++++++++++++++++++-------
4 files changed, 47 insertions(+), 9 deletions(-)
diff --git a/ataprint.cpp b/ataprint.cpp
index 8b27de4..28e6c02 100644
a
|
b
|
int ataPrintMain (ata_device * device, const ata_print_options & options)
|
2898 | 2898 | if ( options.smart_disable || options.smart_enable |
2899 | 2899 | || options.smart_auto_save_disable || options.smart_auto_save_enable |
2900 | 2900 | || options.smart_auto_offl_disable || options.smart_auto_offl_enable |
2901 | | || options.set_aam || options.set_apm || options.set_lookahead |
| 2901 | || options.set_aam || options.set_apm || options.set_features || options.set_lookahead |
2902 | 2902 | || options.set_wcache || options.set_security_freeze || options.set_standby |
2903 | 2903 | || options.sct_wcache_reorder_set || options.sct_wcache_sct_set || options.set_dsn) |
2904 | 2904 | pout("=== START OF ENABLE/DISABLE COMMANDS SECTION ===\n"); |
… |
… |
int ataPrintMain (ata_device * device, const ata_print_options & options)
|
2976 | 2976 | pout("DSN %sabled\n", (enable ? "en" : "dis")); |
2977 | 2977 | } |
2978 | 2978 | |
| 2979 | // Enable/Disable Features |
| 2980 | if (options.set_features) { |
| 2981 | if (!ata_set_features(device, options.set_features_feature, options.set_features_scount)) { |
| 2982 | pout("Features[0x%x] Sector Count[0x%x] failed: %s\n", options.set_features_feature, options.set_features_scount, device->get_errmsg()); |
| 2983 | returnval |= FAILSMART; |
| 2984 | } |
| 2985 | else |
| 2986 | pout("Features[0x%x] Sector Count[0x%x]\n", options.set_features_feature, options.set_features_scount); |
| 2987 | } |
| 2988 | |
2979 | 2989 | // Enable/Disable write cache reordering |
2980 | 2990 | if (options.sct_wcache_reorder_set) { |
2981 | 2991 | bool enable = (options.sct_wcache_reorder_set > 0); |
diff --git a/ataprint.h b/ataprint.h
index b8ccf1f..7722613 100644
a
|
b
|
struct ata_print_options
|
115 | 115 | bool sct_wcache_sct_set_pers; // persistent or volatile |
116 | 116 | bool get_dsn; // print DSN status |
117 | 117 | int set_dsn; // disable(02h), enable(01h) DSN |
| 118 | int set_features; // Enable/Disable the SET FEATRUE command |
| 119 | int set_features_feature; // feature value for the SET FEATURE command |
| 120 | int set_features_scount; // sector count value for the SET FEATURE command |
118 | 121 | |
119 | 122 | ata_print_options() |
120 | 123 | : drive_info(false), |
… |
… |
struct ata_print_options
|
156 | 159 | sct_wcache_reorder_set_pers(false), |
157 | 160 | sct_wcache_sct_get(false), sct_wcache_sct_set(0), |
158 | 161 | sct_wcache_sct_set_pers(false), |
159 | | get_dsn(false), set_dsn(0) |
| 162 | get_dsn(false), set_dsn(0), set_features(0) |
160 | 163 | { } |
161 | 164 | }; |
162 | 165 | |
diff --git a/smartctl.8.in b/smartctl.8.in
index 103fb71..4f755bb 100644
a
|
b
|
The read cache is usually enabled by default.
|
1012 | 1012 | Gets/sets the DSN feature (if supported). |
1013 | 1013 | The dsn is usually disabled by default. |
1014 | 1014 | |
| 1015 | .I features,0xFEATURE[,0xCOUNT] |
| 1016 | \- [ATA only] |
| 1017 | Enable or disable the certain device features by specifying feature value |
| 1018 | and sector count value. Use with care. |
| 1019 | |
1015 | 1020 | .TP |
1016 | 1021 | .B SMART READ AND DISPLAY DATA OPTIONS: |
1017 | 1022 | .TP |
diff --git a/smartctl.cpp b/smartctl.cpp
index 5f663b5..988d1c0 100644
a
|
b
|
static void Usage()
|
87 | 87 | " --identify[=[w][nvb]]\n" |
88 | 88 | " Show words and bits from IDENTIFY DEVICE data (ATA)\n\n" |
89 | 89 | " -g NAME, --get=NAME\n" |
90 | | " Get device setting: all, aam, apm, dsn, lookahead, security, wcache, rcache, wcreorder, wcache-sct\n\n" |
| 90 | " Get device setting: all, aam, apm, dsn, features, lookahead, security, wcache, rcache, wcreorder, wcache-sct\n\n" |
91 | 91 | " -a, --all\n" |
92 | 92 | " Show all SMART information for device\n\n" |
93 | 93 | " -x, --xall\n" |
… |
… |
static void Usage()
|
122 | 122 | " Enable/disable Attribute autosave on device (on/off)\n\n" |
123 | 123 | " -s NAME[,VALUE], --set=NAME[,VALUE]\n" |
124 | 124 | " Enable/disable/change device setting: aam,[N|off], apm,[N|off],\n" |
125 | | " dsn,[on|off], lookahead,[on|off], security-freeze, standby,[N|off|now],\n" |
| 125 | " dsn,[on|off], features,0xFEATURE[,0xCOUNT], lookahead,[on|off], \n" |
| 126 | " security-freeze, standby,[N|off|now],\n" |
126 | 127 | " wcache,[on|off], rcache,[on|off], wcreorder,[on|off[,p]]\n" |
127 | 128 | " wcache-sct,[ata|on|off[,p]]\n\n" |
128 | 129 | ); |
… |
… |
static std::string getvalidarglist(int opt)
|
226 | 227 | case 'g': |
227 | 228 | return "aam, apm, dsn, lookahead, security, wcache, rcache, wcreorder, wcache-sct"; |
228 | 229 | case opt_set: |
229 | | return "aam,[N|off], apm,[N|off], dsn,[on|off], lookahead,[on|off], security-freeze, " |
230 | | "standby,[N|off|now], wcache,[on|off], rcache,[on|off], wcreorder,[on|off[,p]], " |
| 230 | return "aam,[N|off], apm,[N|off], dsn,[on|off], features,0xFEATURE[,0xCOUNT], lookahead,[on|off], " |
| 231 | "security-freeze, standby,[N|off|now], wcache,[on|off], rcache,[on|off], wcreorder,[on|off[,p]], " |
231 | 232 | "wcache-sct,[ata|on|off[,p]]"; |
232 | 233 | case 's': |
233 | 234 | return getvalidarglist(opt_smart)+", "+getvalidarglist(opt_set); |
… |
… |
static const char * parse_options(int argc, char** argv,
|
888 | 889 | strcmp(name, "wcreorder") != 0) |
889 | 890 | badarg = true; |
890 | 891 | } |
891 | | on = !strncmp(optarg+n2, "on", len2); |
892 | | off = !strncmp(optarg+n2, "off", len2); |
893 | | ata = !strncmp(optarg+n2, "ata", len2); |
| 892 | |
| 893 | if (!strcmp(name, "features")) { |
| 894 | int feature, scount; |
| 895 | if (sscanf(optarg + n2, "%x,%x", &feature, &scount) == 2) { |
| 896 | if ((feature < 0 || feature > 0xff) || |
| 897 | (scount < 0 || scount > 0xff)) { |
| 898 | badarg = true; |
| 899 | } else { |
| 900 | ataopts.set_features_feature = feature; |
| 901 | ataopts.set_features_scount = scount; |
| 902 | } |
| 903 | } else { |
| 904 | badarg = true; |
| 905 | } |
| 906 | } else { |
| 907 | on = !strncmp(optarg+n2, "on", len2); |
| 908 | off = !strncmp(optarg+n2, "off", len2); |
| 909 | ata = !strncmp(optarg+n2, "ata", len2); |
| 910 | } |
894 | 911 | } |
895 | 912 | if (n3 != len) |
896 | 913 | val = ~0U; |
… |
… |
static const char * parse_options(int argc, char** argv,
|
1021 | 1038 | else |
1022 | 1039 | badarg = true; |
1023 | 1040 | } |
| 1041 | else if (!strcmp(name, "features")) { |
| 1042 | ataopts.set_features = 1; |
| 1043 | } |
1024 | 1044 | else |
1025 | 1045 | badarg = true; |
1026 | 1046 | } |