aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2020-12-24 19:45:03 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2020-12-24 19:45:03 +0000
commit2f7e361640305f7bfa1addb5c8419562a45676a7 (patch)
treeafa75ef95e3eedeb649fa01e57bddff444437b9e
parente7df8f7726025d0738fb931cabd64cbbe1633ed0 (diff)
downloadsg3_utils-2f7e361640305f7bfa1addb5c8419562a45676a7.tar.gz
sg_sanitize + sg_format: when --verbose given once report probable success; without --verbose 'no news is good news'
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@871 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog4
-rw-r--r--doc/sg_format.89
-rw-r--r--doc/sg_read_attr.88
-rw-r--r--doc/sg_sanitize.835
-rw-r--r--src/sg_format.c160
-rw-r--r--src/sg_modes.c2
-rw-r--r--src/sg_sanitize.c13
7 files changed, 158 insertions, 73 deletions
diff --git a/ChangeLog b/ChangeLog
index b5bfcd43..228e13df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for sg3_utils-1.46 [20201216] [svn: r870]
+Changelog for sg3_utils-1.46 [20201224] [svn: r871]
- sg_rep_pip: report new provisioning initialization pattern cmd
- sg_turs: estimated time-to-ready [20-061r2]
- add --delay=MS option
@@ -21,6 +21,8 @@ Changelog for sg3_utils-1.46 [20201216] [svn: r870]
- sg_ses: use fan speed factor field for calculation [ses4r04]
- sg_compare_and_write: add examples section to its manpage
- sg_modes: document '-s' option (same as '-6')
+ - sg_sanitize + sg_format: when --verbose given once report
+ probable success; without --verbose 'no news is good news'
- sg_raw: increase maximum data-in and data-out buffer size
from 64 KB to 1 MB
- fix --cmdfile= handling
diff --git a/doc/sg_format.8 b/doc/sg_format.8
index 84ae8f54..e642fa8c 100644
--- a/doc/sg_format.8
+++ b/doc/sg_format.8
@@ -671,18 +671,25 @@ Now /dev/sdd should have 512 byte logical block size. And to switch it back:
Since fast formats can be very quick (a matter of seconds) using the
\-\-wait option may be appropriate.
.PP
-And tu use Format with preset this invocation might be used:
+And to use the Format with preset command this invocation could be used:
.PP
# sg_format \-\-preset=1 \-\-fmtmaxlba /dev/sdd
.PP
The FORMAT PRESETS VPD page (0xb8) should be consulted to check that Preset
identifier 0x1 is there and has the expected format (i.e. "default host aware
zoned block device model with 512 bytes of user data in each logical block").
+That VPD page can be viewed with the sg_vpd utility.
.SH EXIT STATUS
The exit status of sg_format is 0 when it is successful. Otherwise see
the sg3_utils(8) man page. Unless the \fI\-\-wait\fR option is given, the
exit status may not reflect the success of otherwise of the format.
Using sg_turs(8) and sg_readcap(8) after the format operation may be wise.
+.PP
+The Unix convention is that "no news is good news" but that can be a bit
+unnerving after an operation like format, especially if it finishes
+quickly (i.e. before the first progress poll is sent). Giving the
+\fI\-\-verbose\fR option once should supply enough additional output to
+settle those nerves.
.SH AUTHORS
Written by Grant Grundler, James Bottomley and Douglas Gilbert.
.SH "REPORTING BUGS"
diff --git a/doc/sg_read_attr.8 b/doc/sg_read_attr.8
index b7c4d09e..85b459eb 100644
--- a/doc/sg_read_attr.8
+++ b/doc/sg_read_attr.8
@@ -1,4 +1,4 @@
-.TH SG_READ_ATTR "8" "November 2017" "sg3_utils\-1.43" SG3_UTILS
+.TH SG_READ_ATTR "8" "December 2020" "sg3_utils\-1.46" SG3_UTILS
.SH NAME
sg_read_attr \- send SCSI READ ATTRIBUTE command
.SH SYNOPSIS
@@ -133,8 +133,8 @@ Much of the information provided by READ ATTRIBUTE can also be found in
pages returned by LOG SENSE (see the sg_logs utility) and in the VPD
pages returned by the INQUIRY command.
.SH EXAMPLES
-To list the attributes of a tape drive whose xxxx is /dev/sg1 the following
-could be used:
+To list the attributes of a tape drive whose \fIDEVICE\fR is /dev/sg1 ,
+the following could be used:
.PP
# sg_read_attr \-s al /dev/sg1
.br
@@ -206,7 +206,7 @@ Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2016\-2017 Douglas Gilbert
+Copyright \(co 2016\-2020 Douglas Gilbert
.br
This software is distributed under a FreeBSD license. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/doc/sg_sanitize.8 b/doc/sg_sanitize.8
index 5bc7cb61..db8b74ca 100644
--- a/doc/sg_sanitize.8
+++ b/doc/sg_sanitize.8
@@ -1,4 +1,4 @@
-.TH SG_SANITIZE "8" "May 2018" "sg3_utils\-1.43" SG3_UTILS
+.TH SG_SANITIZE "8" "December 2020" "sg3_utils\-1.46" SG3_UTILS
.SH NAME
sg_sanitize \- remove all user data from disk with SCSI SANITIZE command
.SH SYNOPSIS
@@ -41,10 +41,13 @@ command every 30 seconds. Otherwise if the \fI\-\-wait\fR option is given
then this utility will wait until the SANITIZE command completes (or fails)
and that can be many hours.
.PP
-If neither the \fI\-\-early\fR nor \fI\-\-wait\fR option is given then
-the SANITIZE command is started with the IMMED bit set. After that this
-utility sends a REQUEST SENSE command every 60 seconds until there are
-no more progress indications.
+If the \fI\-\-wait\fR option is not given then the SANITIZE command is
+started with the IMMED bit set. If neither the \fI\-\-early\fR nor the
+\fI\-\-wait\fR options are given then this utility sends a REQUEST SENSE
+command after every 60 seconds until there are no more progress indications
+in which case this utility exits silently. If additionally the
+\fI\-\-verbose\fR option is given the exit will be marked by a short
+message that the sanitize seems to have succeeded.
.SH OPTIONS
Arguments to long options are mandatory for short options as well.
The options are arranged in alphabetical order based on the long
@@ -63,7 +66,12 @@ sanitize operation. \fIOC\fR can be a value between 1 and 31 and 1 is
the default.
.TP
\fB\-C\fR, \fB\-\-crypto\fR
-perform a "cryptographic erase" sanitize operation.
+perform a "cryptographic erase" sanitize operation. Note that this erase is
+often very quick as it simply overwrites an internal cryptographic key with
+a new value. Those keys are not accessible to users and encrypt all data
+written then decrypt all data read from the media. The primary reason for
+doing that is to make this operation fast. This operation can not be
+reversed.
.TP
\fB\-d\fR, \fB\-\-desc\fR
sets the DESC field in the REQUEST SENSE command used for polling. By
@@ -190,6 +198,13 @@ variant of this utility should have no effect unless it follows an already
failed sanitize operation. If the SCSI REPORT SUPPORTED OPERATION CODES
command (see sg_opcodes) is supported then using it would be a better
approach for finding if sanitize is supported.
+.PP
+If using the dd command to check the before and after data of a particular
+block (i.e. check the erase actually worked) it is a good idea to use
+the 'iflag=direct' operand. Otherwise the first read might be cached and
+returned when the same LBA is read a little later. Obviously this utility
+should only be used to sanitize data on a disk whose mounted file
+systems (if any) have been unmounted prior to the erase!
.SH EXAMPLES
These examples use Linux device names. For suitable device names in
other supported Operating Systems see the sg3_utils(8) man page.
@@ -233,12 +248,18 @@ To overwrite with zeros use:
The exit status of sg_sanitize is 0 when it is successful. Otherwise see
the sg3_utils(8) man page. Unless the \fI\-\-wait\fR option is given, the
exit status may not reflect the success of otherwise of the format.
+.PP
+The Unix convention is that "no news is good news" but that can be a bit
+unnerving after an operation like sanitize, especially if it finishes
+quickly (i.e. before the first progress poll is sent). Giving the
+\fI\-\-verbose\fR option once should supply enough additional output to
+settle those nerves.
.SH AUTHORS
Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2011\-2018 Douglas Gilbert
+Copyright \(co 2011\-2020 Douglas Gilbert
.br
This software is distributed under a FreeBSD license. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/src/sg_format.c b/src/sg_format.c
index 24f94bf6..4c7e154d 100644
--- a/src/sg_format.c
+++ b/src/sg_format.c
@@ -40,7 +40,7 @@
#include "sg_pr2serr.h"
#include "sg_pt.h"
-static const char * version_str = "1.61 20200123";
+static const char * version_str = "1.62 20201223";
#define RW_ERROR_RECOVERY_PAGE 1 /* can give alternate with --mode=MP */
@@ -156,6 +156,10 @@ static struct option long_options[] = {
{0, 0, 0, 0},
};
+static const char * fu_s = "Format unit";
+static const char * fm_s = "Format medium";
+static const char * fwp_s = "Format with preset";
+
static void
usage()
@@ -288,7 +292,7 @@ sg_ll_format_medium(int sg_fd, bool verify, bool immed, int format,
if (verbose) {
char b[128];
- pr2serr(" Format medium cdb: %s\n",
+ pr2serr(" %s cdb: %s\n", fm_s,
sg_get_command_str(fm_cdb, SG_FORMAT_MEDIUM_CMDLEN,
false, sizeof(b), b));
}
@@ -302,8 +306,8 @@ sg_ll_format_medium(int sg_fd, bool verify, bool immed, int format,
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
set_scsi_pt_data_out(ptvp, (uint8_t *)paramp, transfer_len);
res = do_scsi_pt(ptvp, sg_fd, timeout, verbose);
- ret = sg_cmds_process_resp(ptvp, "format medium", res, noisy,
- verbose, &sense_cat);
+ ret = sg_cmds_process_resp(ptvp, fm_s, res, noisy, verbose,
+ &sense_cat);
if (-1 == ret)
ret = sg_convert_errno(get_scsi_pt_os_err(ptvp));
else if (-2 == ret) {
@@ -316,8 +320,12 @@ sg_ll_format_medium(int sg_fd, bool verify, bool immed, int format,
ret = sense_cat;
break;
}
- } else
+ } else {
ret = 0;
+ if (verbose)
+ pr2serr("%s command %s without error\n", fm_s,
+ (immed ? "launched" : "completed"));
+ }
destruct_scsi_pt_obj(ptvp);
return ret;
}
@@ -344,7 +352,7 @@ sg_ll_format_with_preset(int sg_fd, bool immed, bool fmtmaxlba,
if (verbose) {
char b[128];
- pr2serr(" Format with preset cdb: %s\n",
+ pr2serr(" %s cdb: %s\n", fwp_s,
sg_get_command_str(fwp_cdb,
SG_FORMAT_WITH_PRESET_CMDLEN,
false, sizeof(b), b));
@@ -357,8 +365,8 @@ sg_ll_format_with_preset(int sg_fd, bool immed, bool fmtmaxlba,
set_scsi_pt_cdb(ptvp, fwp_cdb, sizeof(fwp_cdb));
set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
res = do_scsi_pt(ptvp, sg_fd, timeout, verbose);
- ret = sg_cmds_process_resp(ptvp, "format with preset", res, noisy,
- verbose, &sense_cat);
+ ret = sg_cmds_process_resp(ptvp, fwp_s, res, noisy, verbose,
+ &sense_cat);
if (-1 == ret)
ret = sg_convert_errno(get_scsi_pt_os_err(ptvp));
else if (-2 == ret) {
@@ -371,8 +379,12 @@ sg_ll_format_with_preset(int sg_fd, bool immed, bool fmtmaxlba,
ret = sense_cat;
break;
}
- } else
+ } else {
ret = 0;
+ if (verbose)
+ pr2serr("%s command %s without error\n", fwp_s,
+ (immed ? "launched" : "completed"));
+ }
destruct_scsi_pt_obj(ptvp);
return ret;
}
@@ -381,7 +393,7 @@ sg_ll_format_with_preset(int sg_fd, bool immed, bool fmtmaxlba,
static int
scsi_format_unit(int fd, const struct opts_t * op)
{
- bool need_param_lst, longlist, ip_desc;
+ bool need_param_lst, longlist, ip_desc, first;
bool immed = ! op->fwait;
int res, progress, pr, rem, param_sz, off, resp_len, tmout;
int poll_wait_secs;
@@ -441,15 +453,15 @@ scsi_format_unit(int fd, const struct opts_t * op)
"command\n");
if (vb) {
if (need_param_lst) {
- pr2serr(" FU would have received parameter "
- "list: ");
+ pr2serr(" %s would have received parameter "
+ "list: ", fu_s);
hex2stderr(param, max_param_sz, -1);
} else
- pr2serr(" FU would not have received a "
- "parameter list\n");
- pr2serr(" FU cdb fields: fmtpinfo=0x%x, "
+ pr2serr(" %s would not have received a "
+ "parameter list\n", fu_s);
+ pr2serr(" %s cdb fields: fmtpinfo=0x%x, "
"longlist=%d, fmtdata=%d, cmplst=%d, "
- "ffmt=%d [timeout=%d secs]\n",
+ "ffmt=%d [timeout=%d secs]\n", fu_s,
op->fmtpinfo, longlist, need_param_lst,
op->cmplst, op->ffmt, tmout);
}
@@ -463,20 +475,22 @@ scsi_format_unit(int fd, const struct opts_t * op)
if (res) {
sg_get_category_sense_str(res, sizeof(b), b, vb);
- pr2serr("Format unit command: %s\n", b);
+ pr2serr("%s command: %s\n", fu_s, b);
return res;
- }
+ } else if (op->verbose)
+ pr2serr("%s command %s without error\n", fu_s,
+ (immed ? "launched" : "completed"));
if (! immed)
return 0;
if (! op->dry_run)
- printf("\nFormat unit has started\n");
+ printf("\n%s has started\n", fu_s);
if (op->early) {
if (immed)
- printf("Format continuing,\n request sense or "
+ printf("%s continuing,\n request sense or "
"test unit ready can be used to monitor "
- "progress\n");
+ "progress\n", fu_s);
return 0;
}
@@ -487,7 +501,7 @@ scsi_format_unit(int fd, const struct opts_t * op)
poll_wait_secs = op->ffmt ? POLL_DURATION_FFMT_SECS :
POLL_DURATION_SECS;
if (! op->poll_type) {
- for(;;) {
+ for(first = true; ; first = false) {
sleep_for(poll_wait_secs);
progress = -1;
res = sg_ll_test_unit_ready_progress(fd, 0, &progress,
@@ -495,10 +509,15 @@ scsi_format_unit(int fd, const struct opts_t * op)
if (progress >= 0) {
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
- printf("Format in progress, %d.%02d%% done\n",
- pr, rem);
- } else
+ printf("%s in progress, %d.%02d%% done\n",
+ fu_s, pr, rem);
+ } else {
+ if (first && op->verbose)
+ pr2serr("%s seems to be successful "
+ "and finished quickly\n",
+ fu_s);
break;
+ }
}
}
if (op->poll_type || (SG_LIB_CAT_NOT_READY == res)) {
@@ -511,7 +530,7 @@ scsi_format_unit(int fd, const struct opts_t * op)
"Sense\n", __func__);
return sg_convert_errno(ENOMEM);
}
- for(;;) {
+ for(first = true; ; first = false) {
sleep_for(poll_wait_secs);
memset(reqSense, 0x0, MAX_BUFF_SZ);
res = sg_ll_request_sense(fd, false, reqSense,
@@ -533,10 +552,15 @@ scsi_format_unit(int fd, const struct opts_t * op)
if (progress >= 0) {
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
- printf("Format in progress, %d.%02d%% done\n",
- pr, rem);
- } else
+ printf("%s in progress, %d.%02d%% done\n",
+ fu_s, pr, rem);
+ } else {
+ if (first && op->verbose)
+ pr2serr("%s seems to be successful "
+ "and finished quickly\n",
+ fu_s);
break;
+ }
}
if (free_reqSense)
free(free_reqSense);
@@ -549,9 +573,10 @@ scsi_format_unit(int fd, const struct opts_t * op)
static int
scsi_format_medium(int fd, const struct opts_t * op)
{
+ bool first;
+ bool immed = ! op->fwait;
int res, progress, pr, rem, resp_len, tmout;
int vb = op->verbose;
- bool immed = ! op->fwait;
char b[80];
if (immed)
@@ -568,27 +593,27 @@ scsi_format_medium(int fd, const struct opts_t * op)
tmout = op->timeout;
if (op->dry_run) {
res = 0;
- pr2serr("Due to --dry-run option bypassing FORMAT MEDIUM "
- "command\n");
+ pr2serr("Due to --dry-run option bypassing %s command\n",
+ fm_s);
} else
res = sg_ll_format_medium(fd, op->verify, immed,
0xf & op->tape, NULL, 0, tmout,
true, vb);
if (res) {
sg_get_category_sense_str(res, sizeof(b), b, vb);
- pr2serr("Format medium command: %s\n", b);
+ pr2serr("%s command: %s\n", fm_s, b);
return res;
}
if (! immed)
return 0;
if (! op->dry_run)
- printf("\nFormat medium has started\n");
+ printf("\n%s has started\n", fm_s);
if (op->early) {
if (immed)
- printf("Format continuing,\n request sense or "
+ printf("%s continuing,\n request sense or "
"test unit ready can be used to monitor "
- "progress\n");
+ "progress\n", fm_s);
return 0;
}
@@ -597,7 +622,7 @@ scsi_format_medium(int fd, const struct opts_t * op)
return 0;
}
if (! op->poll_type) {
- for(;;) {
+ for(first = true; ; first = false) {
sleep_for(POLL_DURATION_SECS);
progress = -1;
res = sg_ll_test_unit_ready_progress(fd, 0, &progress,
@@ -605,10 +630,15 @@ scsi_format_medium(int fd, const struct opts_t * op)
if (progress >= 0) {
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
- printf("Format in progress, %d.%02d%% done\n",
- pr, rem);
- } else
+ printf("%s in progress, %d.%02d%% done\n",
+ fm_s, pr, rem);
+ } else {
+ if (first && op->verbose)
+ pr2serr("%s seems to be successful "
+ "and finished quickly\n",
+ fm_s);
break;
+ }
}
}
if (op->poll_type || (SG_LIB_CAT_NOT_READY == res)) {
@@ -621,7 +651,7 @@ scsi_format_medium(int fd, const struct opts_t * op)
"Sense\n", __func__);
return sg_convert_errno(ENOMEM);
}
- for(;;) {
+ for(first = true; ; first = false) {
sleep_for(POLL_DURATION_SECS);
memset(reqSense, 0x0, MAX_BUFF_SZ);
res = sg_ll_request_sense(fd, false, reqSense,
@@ -643,10 +673,15 @@ scsi_format_medium(int fd, const struct opts_t * op)
if (progress >= 0) {
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
- printf("Format in progress, %d.%02d%% done\n",
- pr, rem);
- } else
+ printf("%s in progress, %d.%02d%% done\n",
+ fm_s, pr, rem);
+ } else {
+ if (first && op->verbose)
+ pr2serr("%s seems to be successful "
+ "and finished quickly\n",
+ fm_s);
break;
+ }
}
if (free_reqSense)
free(free_reqSense);
@@ -659,9 +694,10 @@ scsi_format_medium(int fd, const struct opts_t * op)
static int
scsi_format_with_preset(int fd, const struct opts_t * op)
{
+ bool first;
+ bool immed = ! op->fwait;
int res, progress, pr, rem, resp_len, tmout;
int vb = op->verbose;
- bool immed = ! op->fwait;
char b[80];
if (immed)
@@ -685,18 +721,18 @@ scsi_format_with_preset(int fd, const struct opts_t * op)
op->p_id, tmout, true, vb);
if (res) {
sg_get_category_sense_str(res, sizeof(b), b, vb);
- pr2serr("Format with preset command: %s\n", b);
+ pr2serr("%s command: %s\n", fwp_s, b);
return res;
}
if (! immed)
return 0;
if (! op->dry_run)
- printf("\nFormat with preset has started\n");
+ printf("\n%s has started\n", fwp_s);
if (op->early) {
if (immed)
- printf("Format continuing,\n Request sense can "
- "be used to monitor progress\n");
+ printf("%s continuing,\n Request sense can "
+ "be used to monitor progress\n", fwp_s);
return 0;
}
@@ -705,7 +741,7 @@ scsi_format_with_preset(int fd, const struct opts_t * op)
return 0;
}
if (! op->poll_type) {
- for(;;) {
+ for(first = true; ; first = false) {
sleep_for(POLL_DURATION_SECS);
progress = -1;
res = sg_ll_test_unit_ready_progress(fd, 0, &progress,
@@ -713,10 +749,15 @@ scsi_format_with_preset(int fd, const struct opts_t * op)
if (progress >= 0) {
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
- printf("Format in progress, %d.%02d%% done\n",
- pr, rem);
- } else
+ printf("%s in progress, %d.%02d%% done\n",
+ fwp_s, pr, rem);
+ } else {
+ if (first && op->verbose)
+ pr2serr("%s seems to be successful "
+ "and finished quickly\n",
+ fwp_s);
break;
+ }
}
}
if (op->poll_type || (SG_LIB_CAT_NOT_READY == res)) {
@@ -729,7 +770,7 @@ scsi_format_with_preset(int fd, const struct opts_t * op)
"Sense\n", __func__);
return sg_convert_errno(ENOMEM);
}
- for(;;) {
+ for(first = true; ; first = false) {
sleep_for(POLL_DURATION_SECS);
memset(reqSense, 0x0, MAX_BUFF_SZ);
res = sg_ll_request_sense(fd, false, reqSense,
@@ -751,10 +792,15 @@ scsi_format_with_preset(int fd, const struct opts_t * op)
if (progress >= 0) {
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
- printf("Format in progress, %d.%02d%% done\n",
- pr, rem);
- } else
+ printf("%s in progress, %d.%02d%% done\n",
+ fwp_s, pr, rem);
+ } else {
+ if (first && op->verbose)
+ pr2serr("%s seems to be successful "
+ "and finished quickly\n",
+ fwp_s);
break;
+ }
}
if (free_reqSense)
free(free_reqSense);
diff --git a/src/sg_modes.c b/src/sg_modes.c
index 6218a31b..3e6c9b85 100644
--- a/src/sg_modes.c
+++ b/src/sg_modes.c
@@ -110,6 +110,7 @@ static struct option long_options[] = {
{0, 0, 0, 0},
};
+/* Common to all SCSI devices (found in SPCx). In numerical order */
static struct page_code_desc pc_desc_common[] = {
{0x0, 0x0, "ua", "Unit Attention condition [vendor specific format]"},
{0x2, 0x0, "dr", "Disconnect-Reconnect"},
@@ -144,6 +145,7 @@ static struct page_code_desc pc_desc_disk[] = {
{0xa, 0x5, "ioad", "IO advice hints grouping"}, /* added sbc4r06 */
{0xa, 0x6, "bop", "Background operation control"}, /* added sbc4r07 */
{0xa, 0xf1, "pat", "Parallel ATA control (SAT)"},
+ {0xa, 0xf2, "afc", "ATA feature control (SAT)"}, /* added 20-085r2 */
{0xb, 0x0, "mts", "Medium types supported (obsolete)"},
{0xc, 0x0, "not", "Notch and partition (obsolete)"},
{0xd, 0x0, "pco", "Power condition (obsolete, moved to 0x1a)"},
diff --git a/src/sg_sanitize.c b/src/sg_sanitize.c
index 00d6b59d..04a8ee90 100644
--- a/src/sg_sanitize.c
+++ b/src/sg_sanitize.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2019 Douglas Gilbert.
+ * Copyright (c) 2011-2020 Douglas Gilbert.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -33,7 +33,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.14 20191220";
+static const char * version_str = "1.15 20201223";
/* Not all environments support the Unix sleep() */
#if defined(MSC_VER) || defined(__MINGW32__)
@@ -271,8 +271,12 @@ do_sanitize(int sg_fd, const struct opts_t * op, const void * param_lstp,
ret = sense_cat;
break;
}
- } else
+ } else {
ret = 0;
+ if (op->verbose)
+ pr2serr("Sanitize command %s without error\n",
+ (immed ? "launched" : "completed"));
+ }
destruct_scsi_pt_obj(ptvp);
return ret;
@@ -778,6 +782,9 @@ main(int argc, char * argv[])
if (vb > 1)
pr2serr("No progress indication found, iteration %d\n",
k + 1);
+ if ((0 == k) && vb)
+ pr2serr("Sanitize seems to be successful and finished "
+ "quickly\n");
/* N.B. exits first time there isn't a progress indication */
break;
} else