aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2016-02-09 21:20:08 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2016-02-09 21:20:08 +0000
commit0eb81276d6380fca0ed959efb49f2f9ca0e3661e (patch)
treed4647deb10899066f76b94f7df7a39e92da8f9be
parent2f1a9f5e1171839c853ca0e0d049a489876c90ff (diff)
downloadsg3_utils-0eb81276d6380fca0ed959efb49f2f9ca0e3661e.tar.gz
sg_inq: '--export': new entries for UUID descriptor; sg_format: add support for FORMAT MEDIUM
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@661 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--COVERAGE5
-rw-r--r--ChangeLog4
-rw-r--r--README2
-rw-r--r--debian/changelog2
-rw-r--r--doc/sg_format.869
-rw-r--r--doc/sg_wr_mode.824
-rw-r--r--sg3_utils.spec2
-rw-r--r--src/sg_format.c278
-rw-r--r--src/sg_inq.c27
-rw-r--r--src/sg_wr_mode.c26
10 files changed, 368 insertions, 71 deletions
diff --git a/COVERAGE b/COVERAGE
index 7ddc5e5e..68f516b6 100644
--- a/COVERAGE
+++ b/COVERAGE
@@ -22,7 +22,8 @@ INQUIRY sg_dd, sg_format, sg_inq, sginfo,
sg_logs, sg_map('-i'), sg_modes, sg_opcodes,
sg_persist, sg_scan, sg_ses, sg_vpd ++
FINISH ZONE sg_zone
-FORMAT UNIT sg_format, ++
+FORMAT MEDIUM sg_format, ++ [SSC]
+FORMAT UNIT sg_format, ++ [SBC]
LOG SELECT sg_logs('-r' or '-select'), ++
LOG SENSE sg_logs, ++
MODE SELECT(6) sdparm, sg_wr_mode, sginfo, sg_format,
@@ -132,4 +133,4 @@ THIRD PARTY COPY IN (0x83).
Douglas Gilbert
-3rd February 2016
+8th February 2016
diff --git a/ChangeLog b/ChangeLog
index 777db3fc..e98a498e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,12 +2,13 @@ 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.42 [20160207] [svn: r660]
+Changelog for sg3_utils-1.42 [20160209] [svn: r661]
- sg_timestamp: new, to report or set timestamp
- sg_read_attr: new, supported by tape drives
- sg_stpg: fix truncation of target port field
- sg_inq: cope with unicode strings, udev fixes
- update version descriptor list to 20160125
+ - '--export': new entries for UUID descriptor
- sg_ses: add more field acronyms (ses3r11)
- sg_logs: add Utilization lpage (sbc4r07)
- add Background operation lpage
@@ -25,6 +26,7 @@ Changelog for sg3_utils-1.42 [20160207] [svn: r660]
- sg_sanitize: add --znr option (sbc4r07)
- sg_rep_zones: add --partial option (zbc-r04)
- sg_format: add ffmt option (sbc4r10)
+ - add support for FORMAT MEDIUM (for tape)
- sg_raw: document length relationships
- rescan-scsi-bus.sh: updates from Suse
- sg_lib_data: sync asc/ascq codes with T10 20151126
diff --git a/README b/README
index ed514761..fc062468 100644
--- a/README
+++ b/README
@@ -414,4 +414,4 @@ See http://sg.danny.cz/sg/tools.html
Douglas Gilbert
-7th February 2016
+9th February 2016
diff --git a/debian/changelog b/debian/changelog
index 0265d471..33afce67 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.42-0.1) unstable; urgency=low
* New upstream version
- -- Douglas Gilbert <dgilbert@interlog.com> Sun, 07 Feb 2016 22:00:00 -0500
+ -- Douglas Gilbert <dgilbert@interlog.com> Tue, 09 Feb 2016 14:00:00 -0500
sg3-utils (1.41-0.1) unstable; urgency=low
diff --git a/doc/sg_format.8 b/doc/sg_format.8
index 6dc5141e..2e8cda2d 100644
--- a/doc/sg_format.8
+++ b/doc/sg_format.8
@@ -1,6 +1,6 @@
-.TH SG_FORMAT "8" "January 2016" "sg3_utils\-1.42" SG3_UTILS
+.TH SG_FORMAT "8" "February 2016" "sg3_utils\-1.42" SG3_UTILS
.SH NAME
-sg_format \- format, resize or modify protection information of a SCSI disk
+sg_format \- format, resize a SCSI disk or format a tape
.SH SYNOPSIS
.B sg_format
[\fI\-\-cmplst=\fR{0|1}] [\fI\-\-count=COUNT\fR] [\fI\-\-dcrt\fR]
@@ -8,8 +8,9 @@ sg_format \- format, resize or modify protection information of a SCSI disk
[\fI\-\-format\fR] [\fI\-\-help\fR] [\fI\-\-ip_def\fR] [\fI\-\-long\fR]
[\fI\-\-mode=MP\fR] [\fI\-\-pfu=PFU\fR] [\fI\-\-pie=PIE\fR] [\fI\-\-pinfo\fR]
[\fI\-\-poll=PT\fR] [\fI\-\-resize\fR] [\fI\-\-rto_req\fR]
-[\fI\-\-security\fR] [\fI\-\-six\fR] [\fI\-\-size=SIZE\fR] [\fI\-\-verbose\fR]
-[\fI\-\-version\fR] [\fI\-\-wait\fR] \fIDEVICE\fR
+[\fI\-\-security\fR] [\fI\-\-six\fR] [\fI\-\-size=SIZE\fR] [\fI\-\-tape=FM\fR]
+[\fI\-\-verbose\fR] [\fI\-\-verify\fR] [\fI\-\-version\fR] [\fI\-\-wait\fR]
+\fIDEVICE\fR
.SH DESCRIPTION
.\" Add any additional description here
.PP
@@ -32,12 +33,12 @@ www.t10.org) has obsoleted the "format device" mode page. Many of the low
level details found in that mode page are now left up to the discretion of
the manufacturer.
.PP
-When this utility is used without options (i.e. it is only given a DEVICE
-argument) it prints out the existing block size and block count derived from
-two sources. These two sources are a block descriptor in the response to a
-MODE SENSE command and the response to a READ CAPACITY command. The reason
-for this double check is to detect a "format corrupt" state (see NOTES
-section). This usage will not modify the disk.
+When this utility is used without options (i.e. it is only given a
+\fIDEVICE\fR argument) it prints out the existing block size and block count
+derived from two sources. These two sources are a block descriptor in the
+response to a MODE SENSE command and the response to a READ CAPACITY command.
+The reason for this double check is to detect a "format corrupt" state (see
+the NOTES section). This usage will not modify the disk.
.PP
When this utility is used with the "\-\-format" (or "\-F") option it will
attempt to format the given DEVICE. There is a 15 second pause during which
@@ -49,6 +50,11 @@ Protection information is optional and is made up of one or more protection
intervals, each made up of 8 bytes associated with each logical block. Four
protection types are defined with protection type 0 being no protection
intervals. See the PROTECTION INFORMATION section below for more information.
+.PP
+When the \fI\-\-tape=FM\fR option is given then the SCSI FORMAT MEDIUM
+command is sent to the \fIDEVICE\fR. FORMAT MEDIUM is defined in SSC and
+prepares a volume for use which may include partitioning the medium. See
+the section below on TAPE for more information.
.SH OPTIONS
Arguments to long options are mandatory for short options as well.
The options are arranged in alphabetical order based on the long
@@ -254,10 +260,20 @@ sectors). If the given size in unacceptable with the disk, most likely
an "Invalid field in parameter list" message will appear in sense
data (requires the use of '\-v' to decode sense data).
.TP
+\fB\-T\fR, \fB\-\-tape\fR=\fIFM\fR
+will send a FORMAT MEDIUM command to the \fIDEVICE\fR with the FORMAT field
+set to \fIFM\fR. This option is used to prepare a tape (i.e. the "medium")
+in a tape drive for use. Values for \fIFM\fR include 0 to do the "default"
+format; 1 to partition a volume and 2 to do a default format then partition.
+.TP
\fB\-v\fR, \fB\-\-verbose\fR
increase the level of verbosity, (i.e. debug output). "\-vvv" gives
a lot more debug output.
.TP
+\fB\-y\fR, \fB\-\-verify\fR
+set the VERIFY bit in the FORMAT MEDIUM cdb. The default is that the VERIFY
+bit is clear. This option is only appropriate for tapes.
+.TP
\fB\-V\fR, \fB\-\-version\fR
print the version string and then exit.
.TP
@@ -428,6 +444,37 @@ provisioned formats typically complete faster than fully provisioned ones
on the same disk (see the \fI\-\-ip_def\fR option). In either case format
operations on SSDs tend to be a lot faster than they are on hard disks with
spinning media.
+.SH TAPE
+Tape system use a variant of the FORMAT UNIT command used on disks. Tape
+systems use the FORMAT MEDIUM command which is simpler with only three
+fields in the cdb typically used. Apart from sharing the same opcode the
+cdbs of FORMAT UNIT and FORMAT MEDIUM are quite different. FORMAT MEDIUM's
+fields are VERIFY, IMMED and FORMAT (with TRANSFER LENGTH always set to 0).
+The VERIFY bit field is set with the \fI\-\-verify\fR option. The IMMED bit
+is manipulated by the \fI\-\-wait\fR option in the same way it is for disks;
+one difference is that if the \fI\-\-poll=PT\fR option is not given then it
+defaults to \fIPT\fR of 1 which means the poll is done with REQUEST SENSE
+commands.
+.PP
+The argument given to the \fI\-\-tape=FM\fR option is used to set the FORMAT
+field. \fIFM\fR can take values from "\-1" to "15" where "\-1" (the default)
+means don't do a tape format; value "8" to "15" are for vendor specific
+formats. The \fI\-\-early\fR option may also be used to set the IMMED
+bit and then exit this utility (rather than poll periodically until it is
+finished). In this case the tape drive will still be busy doing the format
+for some time but, according to T10, should still respond in full to the
+INQUIRY and REPORT LUNS commands. Other commands (including REQUEST SENSE)
+should yield a "not ready" sense key with an additional sense code
+of "Logical unit not ready, format in progress". Additionally REQUEST SENSE
+should contain a progress indication in its sense data.
+.PP
+When \fIFM\fR is 1 or 2 then the settings in the Medium partition mode page
+control the partitioning. That mode page can be viewed and modified with the
+sdparm utility.
+.PP
+Prior to invoking this utility the tape may need to be positioned to the
+beginning of partition 0. In Linux that can typically be done with the mt
+utility (e.g. 'mt -f /dev/st0 rewind').
.SH EXAMPLES
These examples use Linux device names. For suitable device names in
other supported Operating Systems see the sg3_utils(8) man page.
@@ -521,4 +568,4 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
.B sg_turs(8), sg_requests(8), sg_inq(8), sg_modes(8), sg_vpd(8),
.B sg_reassign(8), sg_readcap(8), sg3_utils(8),
.B sg_sanitize(8) [all in sg3_utils],
-.B sdparm(8), scsiformat (old), hdparm(8)
+.B mt(mt-st), sdparm(8), scsiformat (old), hdparm(8)
diff --git a/doc/sg_wr_mode.8 b/doc/sg_wr_mode.8
index 58baa4f1..59f83467 100644
--- a/doc/sg_wr_mode.8
+++ b/doc/sg_wr_mode.8
@@ -1,11 +1,11 @@
-.TH SG_WR_MODE "8" "November 2012" "sg3_utils\-1.35" SG3_UTILS
+.TH SG_WR_MODE "8" "February 2016" "sg3_utils\-1.42" SG3_UTILS
.SH NAME
sg_wr_mode \- write (modify) SCSI mode page
.SH SYNOPSIS
.B sg_wr_mode
[\fI\-\-contents=H,H...\fR] [\fI\-\-dbd\fR] [\fI\-\-force\fR]
[\fI\-\-help\fR] [\fI\-\-len=\fR10|6\fR] [\fI\-\-mask=M,M...\fR]
-[\fI\-\-page=PG[,SPG]\fR] [\fI\-\-save\fR] [\fI\-\-verbose\fR]
+[\fI\-\-page=PG_H[,SPG_H]\fR] [\fI\-\-save\fR] [\fI\-\-verbose\fR]
[\fI\-\-version\fR] \fIDEVICE\fR
.SH DESCRIPTION
.\" Add any additional description here
@@ -99,17 +99,17 @@ bytes are taken from the contents string. If the contents string is shorter
than the existing mode page then the remaining bytes are taken from the
existing mode page (i.e. they are left unaltered).
.TP
-\fB\-p\fR, \fB\-\-page\fR=\fIPG\fR
-where \fIPG\fR is the page code value to fetch and modify. The page code is
-in hex and should be between 0 and 3e inclusive. Notice that page code
+\fB\-p\fR, \fB\-\-page\fR=\fIPG_H\fR
+where \fIPG_H\fR is the page code value to fetch and modify. The page code
+is in hex and should be between 0 and 3e inclusive. Notice that page code
3f to fetch all mode pages is disallowed.
.TP
-\fB\-p\fR, \fB\-\-page\fR=\fIPG,SPG\fR
-where \fIPG\fR is the page code value and \fISPG\fR is the subpage code value
-to fetch and modify. Both values are in hex. The subpage code should be
-between 0 and fe inclusive. Notice that subpage code ff to fetch all mode
-subpages (for a given mode page or all mode pages in the case of 3f,ff) is
-disallowed.
+\fB\-p\fR, \fB\-\-page\fR=\fIPG_H,SPG_H\fR
+where \fIPG_H\fR is the page code value and \fISPG_H\fR is the subpage code
+value to fetch and modify. Both values are in hex. The subpage code should
+be between 0 and fe inclusive. Notice that subpage code ff to fetch all
+mode subpages (for a given mode page or all mode pages in the case of 3f,ff)
+is disallowed.
.TP
\fB\-s\fR, \fB\-\-save\fR
changes the "saved" mode page when MODE SELECT is successful. By
@@ -190,7 +190,7 @@ Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2004\-2012 Douglas Gilbert
+Copyright \(co 2004\-2016 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/sg3_utils.spec b/sg3_utils.spec
index 85808cc5..6675a803 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,7 +79,7 @@ fi
%{_libdir}/*.la
%changelog
-* Sun Feb 07 2016 - dgilbert at interlog dot com
+* Tue Feb 09 2016 - dgilbert at interlog dot com
- track t10 changes
* sg3_utils-1.42
diff --git a/src/sg_format.c b/src/sg_format.c
index f8b84fef..9535a867 100644
--- a/src/sg_format.c
+++ b/src/sg_format.c
@@ -34,8 +34,9 @@
#include "sg_cmds_extra.h"
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
+#include "sg_pt.h"
-static const char * version_str = "1.33 20160123";
+static const char * version_str = "1.34 20160209";
#define RW_ERROR_RECOVERY_PAGE 1 /* can give alternate with --mode=MP */
@@ -58,13 +59,18 @@ static const char * version_str = "1.33 20160123";
#define sleep_for(seconds) sleep(seconds)
#endif
+/* FORMAT UNIT (SBC) and FORMAT MEDIUM (SSC) share the same opcode */
+#define SG_FORMAT_MEDIUM_CMD 0x4
+#define SG_FORMAT_MEDIUM_CMDLEN 6
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
+
struct opts_t {
int64_t blk_count; /* -c value */
int blk_size; /* -s value */
int cmplst; /* -C value */
bool dcrt; /* -D */
bool early; /* -e */
- int ffmt; /* -q value */
+ int ffmt; /* -t value */
int fmtpinfo;
int format; /* -F */
bool fwait; /* -w (negate for immed) */
@@ -76,11 +82,14 @@ struct opts_t {
int pie; /* -q value */
bool pinfo; /* -p, deprecated, prefer fmtpinfo */
int pollt; /* -x value */
+ bool pollt_given;
bool do_rcap16; /* -l */
bool resize; /* -r */
bool rto_req; /* -R, deprecated, prefer fmtpinfo */
+ int tape; /* -T <format>, def: -1 */
int sec_init; /* -S */
int verbose; /* -v */
+ int verify; /* -y */
const char * device_name;
};
@@ -109,7 +118,9 @@ static struct option long_options[] = {
{"security", no_argument, 0, 'S'},
{"six", no_argument, 0, '6'},
{"size", required_argument, 0, 's'},
+ {"tape", required_argument, 0, 'T'},
{"verbose", no_argument, 0, 'v'},
+ {"verify", no_argument, 0, 'y'},
{"version", no_argument, 0, 'V'},
{"wait", no_argument, 0, 'w'},
{0, 0, 0, 0},
@@ -127,8 +138,9 @@ usage()
"[--pie=PIE] [--pinfo]\n"
" [--poll=PT] [--resize] [--rto_req] "
"[--security] [--six]\n"
- " [--size=SIZE] [--verbose] [--version] "
- "[--wait] DEVICE\n"
+ " [--size=SIZE] [--tape=FM] [--verbose] "
+ "[--verify]\n"
+ " [--version] [--wait] DEVICE\n"
" where:\n"
" --cmplst=0|1\n"
" -C 0|1 sets CMPLST bit in format cdb "
@@ -146,7 +158,7 @@ usage()
" to whole medium\n"
" --fmtpinfo=FPI|-f FPI FMTPINFO field value "
"(default: 0)\n"
- " --format|-F format unit (default: report current "
+ " --format|-F do FORMAT UNIT (default: report current "
"count and size)\n"
" use thrice for FORMAT UNIT command "
"only\n"
@@ -163,8 +175,8 @@ usage()
"instead)\n"
" --poll=PT|-x PT PT is poll type, 0 for test unit "
"ready\n"
- " 1 for request sense (def: 0 (in "
- "future will be 1))\n");
+ " 1 for request sense (def: 0 (1 "
+ "for tape))\n");
printf(" --resize|-r resize (rather than format) to COUNT "
"value\n"
" --rto_req|-R set lower bit of FMTPINFO field\n"
@@ -180,22 +192,85 @@ usage()
"needed to\n"
" change current logical block "
"size\n"
+ " --tape=FM|-T FM request FORMAT MEDIUM with FORMAT "
+ "field set\n"
+ " to FM (def: 0 --> default format)\n"
" --verbose|-v increase verbosity\n"
+ " --verify|-y sets VERIFY bit in FORMAT MEDIUM (tape)\n"
" --version|-V print version details and exit\n"
" --wait|-w format command waits until format "
"operation completes\n"
" (default: set IMMED=1 and poll with "
"Test Unit Ready)\n\n"
"\tExample: sg_format --format /dev/sdc\n\n"
- "This utility formats or resizes a SCSI disk.\n");
+ "This utility formats a SCSI disk [FORMAT UNIT] or resizes "
+ "it. Alternatively\nif '--tape=FM' is given formats a tape "
+ "[FORMAT MEDIUM].\n");
printf("WARNING: This utility will destroy all the data on "
- "DEVICE when\n\t '--format' is given. Check that you "
- "have the correct DEVICE.\n");
+ "DEVICE when '--format'\n\t or '--tape' is given. Check that "
+ "you have specified the correct\n\t DEVICE.\n");
+}
+
+/* Invokes a SCSI FORMAT MEDIUM command (SSC). Return of 0 -> success,
+ * various SG_LIB_CAT_* positive values or -1 -> other errors */
+static int
+sg_ll_format_medium(int sg_fd, int verify, int immed, int format,
+ void * paramp, int transfer_len, int timeout, int noisy,
+ int verbose)
+{
+ int k, ret, res, sense_cat;
+ unsigned char fmCmdBlk[SG_FORMAT_MEDIUM_CMDLEN] =
+ {SG_FORMAT_MEDIUM_CMD, 0, 0, 0, 0, 0};
+ unsigned char sense_b[SENSE_BUFF_LEN];
+ struct sg_pt_base * ptvp;
+
+ if (verify)
+ fmCmdBlk[1] |= 0x2;
+ if (immed)
+ fmCmdBlk[1] |= 0x1;
+ if (format)
+ fmCmdBlk[2] |= (0xf & format);
+ if (transfer_len > 0)
+ sg_put_unaligned_be16(transfer_len, fmCmdBlk + 3);
+ if (verbose) {
+ pr2serr(" Format medium cdb: ");
+ for (k = 0; k < SG_FORMAT_MEDIUM_CMDLEN; ++k)
+ pr2serr("%02x ", fmCmdBlk[k]);
+ pr2serr("\n");
+ }
+
+ ptvp = construct_scsi_pt_obj();
+ if (NULL == ptvp) {
+ pr2serr("%s: out of memory\n", __func__);
+ return -1;
+ }
+ set_scsi_pt_cdb(ptvp, fmCmdBlk, sizeof(fmCmdBlk));
+ set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
+ set_scsi_pt_data_out(ptvp, (unsigned char *)paramp, transfer_len);
+ res = do_scsi_pt(ptvp, sg_fd, timeout, verbose);
+ ret = sg_cmds_process_resp(ptvp, "format medium", res, transfer_len,
+ sense_b, noisy, verbose, &sense_cat);
+ if (-1 == ret)
+ ;
+ else if (-2 == ret) {
+ switch (sense_cat) {
+ case SG_LIB_CAT_RECOVERED:
+ case SG_LIB_CAT_NO_SENSE:
+ ret = 0;
+ break;
+ default:
+ ret = sense_cat;
+ break;
+ }
+ } else
+ ret = 0;
+ destruct_scsi_pt_obj(ptvp);
+ return ret;
}
/* Return 0 on success, else see sg_ll_format_unit2() */
static int
-scsi_format(int fd, const struct opts_t * op)
+scsi_format_unit(int fd, const struct opts_t * op)
{
int res, need_hdr, progress, pr, rem, verb, fmt_pl_sz, longlist, off;
int resp_len, ip_desc;
@@ -237,13 +312,13 @@ scsi_format(int fd, const struct opts_t * op)
fmt_pl, fmt_pl_sz, 1, op->verbose);
if (res) {
sg_get_category_sense_str(res, sizeof(b), b, op->verbose);
- pr2serr("Format command: %s\n", b);
+ pr2serr("Format unit command: %s\n", b);
return res;
}
if (! immed)
return 0;
- printf("\nFormat has started\n");
+ printf("\nFormat unit has started\n");
if (op->early) {
if (immed)
printf("Format continuing,\n request sense or "
@@ -332,7 +407,85 @@ scsi_format(int fd, const struct opts_t * op)
((progress * 100) % 65536) / 656);
}
#endif
- printf("FORMAT Complete\n");
+ printf("FORMAT UNIT Complete\n");
+ return 0;
+}
+
+/* Return 0 on success, else see sg_ll_format_medium() above */
+static int
+scsi_format_medium(int fd, const struct opts_t * op)
+{
+ int res, progress, pr, rem, verb, resp_len;
+ int immed = ! op->fwait;
+ unsigned char reqSense[MAX_BUFF_SZ];
+ char b[80];
+
+ res = sg_ll_format_medium(fd, op->verify, immed, 0xf & op->tape, NULL,
+ 0, (immed ? SHORT_TIMEOUT : FORMAT_TIMEOUT),
+ 1, op->verbose);
+ if (res) {
+ sg_get_category_sense_str(res, sizeof(b), b, op->verbose);
+ pr2serr("Format medium command: %s\n", b);
+ return res;
+ }
+ if (! immed)
+ return 0;
+
+ printf("\nFormat medium has started\n");
+ if (op->early) {
+ if (immed)
+ printf("Format continuing,\n request sense or "
+ "test unit ready can be used to monitor "
+ "progress\n");
+ return 0;
+ }
+
+ verb = (op->verbose > 1) ? (op->verbose - 1) : 0;
+ if (0 == op->pollt) {
+ for(;;) {
+ sleep_for(POLL_DURATION_SECS);
+ progress = -1;
+ res = sg_ll_test_unit_ready_progress(fd, 0, &progress,
+ 1, verb);
+ if (progress >= 0) {
+ pr = (progress * 100) / 65536;
+ rem = ((progress * 100) % 65536) / 656;
+ printf("Format in progress, %d.%02d%% done\n",
+ pr, rem);
+ } else
+ break;
+ }
+ }
+ if (op->pollt || (SG_LIB_CAT_NOT_READY == res)) {
+ for(;;) {
+ sleep_for(POLL_DURATION_SECS);
+ memset(reqSense, 0x0, sizeof(reqSense));
+ res = sg_ll_request_sense(fd, 0, reqSense,
+ sizeof(reqSense), 0, verb);
+ if (res) {
+ pr2serr("polling with Request Sense command "
+ "failed [res=%d]\n", res);
+ break;
+ }
+ resp_len = reqSense[7] + 8;
+ if (verb) {
+ pr2serr("Parameter data in hex:\n");
+ dStrHexErr((const char *)reqSense, resp_len,
+ 1);
+ }
+ progress = -1;
+ sg_get_sense_progress_fld(reqSense, resp_len,
+ &progress);
+ if (progress >= 0) {
+ pr = (progress * 100) / 65536;
+ rem = ((progress * 100) % 65536) / 656;
+ printf("Format in progress, %d.%02d%% done\n",
+ pr, rem);
+ } else
+ break;
+ }
+ }
+ printf("FORMAT MEDIUM Complete\n");
return 0;
}
@@ -591,11 +744,13 @@ main(int argc, char **argv)
op->cmplst = 1;
op->mode_page = RW_ERROR_RECOVERY_PAGE;
op->pollt = DEF_POLL_TYPE;
+ op->tape = -1;
while (1) {
int option_index = 0;
int c;
- c = getopt_long(argc, argv, "c:C:Def:FhIlM:pP:q:rRs:St:vVwx:6",
+ c = getopt_long(argc, argv,
+ "c:C:Def:FhIlM:pP:q:rRs:St:T:vVwx:y6",
long_options, &option_index);
if (c == -1)
break;
@@ -699,6 +854,19 @@ main(int argc, char **argv)
return SG_LIB_SYNTAX_ERROR;
}
break;
+ case 'T':
+ if (('-' == optarg[0]) && ('1' == optarg[1]) &&
+ ('\0' == optarg[2])) {
+ op->tape = -1;
+ break;
+ }
+ op->tape = sg_get_num(optarg);
+ if ((op->tape < 0) || ( op->tape > 15)) {
+ pr2serr("bad argument to '--tape', accepts "
+ "0 to 15 inclusive\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ break;
case 'v':
op->verbose++;
break;
@@ -710,6 +878,10 @@ main(int argc, char **argv)
break;
case 'x':
op->pollt = !!sg_get_num(optarg);
+ op->pollt_given = true;
+ break;
+ case 'y':
+ op->verify++;
break;
case '6':
op->mode6 = true;
@@ -737,6 +909,11 @@ main(int argc, char **argv)
usage();
return SG_LIB_SYNTAX_ERROR;
}
+ if (op->format && (op->tape >= 0)) {
+ pr2serr("Cannot choose both '--format' and '--tape='; disk "
+ "or tape, choose one only\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
if (op->ip_def && op->sec_init) {
pr2serr("'--ip_def' and '--security' contradict, choose "
"one\n");
@@ -785,13 +962,24 @@ main(int argc, char **argv)
ret = print_dev_id(fd, inq_resp, sizeof(inq_resp), op);
if (ret)
- goto out;
- pdt = 0x1f & inq_resp[0];
- if ((0 != pdt) && (7 != pdt) && (0xe != pdt)) {
- pr2serr("This format is only defined for disks (using SBC-2 "
- "or RBC) and MO media\n");
- ret = SG_LIB_CAT_MALFORMED;
goto out;
+ pdt = 0x1f & inq_resp[0];
+ if (op->format) {
+ if ((PDT_DISK != pdt) && (PDT_OPTICAL != pdt) &&
+ (PDT_RBC != pdt)) {
+ pr2serr("This format is only defined for disks "
+ "(using SBC-2 or RBC) and MO media\n");
+ ret = SG_LIB_CAT_MALFORMED;
+ goto out;
+ }
+ } else if (op->tape >= 0) {
+ if (! ((PDT_TAPE == pdt) || (PDT_MCHANGER == pdt) ||
+ (PDT_ADC == pdt))) {
+ pr2serr("This format is only defined for tapes\n");
+ ret = SG_LIB_CAT_MALFORMED;
+ goto out;
+ }
+ goto format_med;
}
again_with_long_lba:
@@ -984,41 +1172,73 @@ again_with_long_lba:
bd_blk_len, res);
printf(" Probably needs format\n");
}
- printf("No changes made. To format use '--format'. To "
- "resize use '--resize'\n");
+ if ((PDT_TAPE == pdt) || (PDT_MCHANGER == pdt) ||
+ (PDT_ADC == pdt))
+ printf("No changes made. To format use '--tape='.\n");
+ else
+ printf("No changes made. To format use '--format'. To "
+ "resize use '--resize'\n");
goto out;
}
if (op->format) {
format_only:
#if 1
- printf("\nA FORMAT will commence in 15 seconds\n");
+ printf("\nA FORMAT UNIT will commence in 15 seconds\n");
printf(" ALL data on %s will be DESTROYED\n",
op->device_name);
printf(" Press control-C to abort\n");
sleep_for(5);
- printf("\nA FORMAT will commence in 10 seconds\n");
+ printf("\nA FORMAT UNIT will commence in 10 seconds\n");
printf(" ALL data on %s will be DESTROYED\n",
op->device_name);
printf(" Press control-C to abort\n");
sleep_for(5);
- printf("\nA FORMAT will commence in 5 seconds\n");
+ printf("\nA FORMAT UNIT will commence in 5 seconds\n");
printf(" ALL data on %s will be DESTROYED\n",
op->device_name);
printf(" Press control-C to abort\n");
sleep_for(5);
- res = scsi_format(fd, op);
+ res = scsi_format_unit(fd, op);
ret = res;
if (res) {
- pr2serr("FORMAT failed\n");
+ pr2serr("FORMAT UNIT failed\n");
if (0 == op->verbose)
pr2serr(" try '-v' for more "
"information\n");
}
#else
- pr2serr("FORMAT ignored, testing\n");
+ pr2serr("FORMAT UNIT ignored, testing\n");
#endif
}
+ goto out;
+
+format_med:
+ if (! op->pollt_given)
+ op->pollt = 1; /* SSC-5 specifies REQUEST SENSE polling */
+ printf("\nA FORMAT MEDIUM will commence in 15 seconds\n");
+ printf(" ALL data on %s will be DESTROYED\n",
+ op->device_name);
+ printf(" Press control-C to abort\n");
+ sleep_for(5);
+ printf("\nA FORMAT MEDIUM will commence in 10 seconds\n");
+ printf(" ALL data on %s will be DESTROYED\n",
+ op->device_name);
+ printf(" Press control-C to abort\n");
+ sleep_for(5);
+ printf("\nA FORMAT MEDIUM will commence in 5 seconds\n");
+ printf(" ALL data on %s will be DESTROYED\n",
+ op->device_name);
+ printf(" Press control-C to abort\n");
+ sleep_for(5);
+ res = scsi_format_medium(fd, op);
+ ret = res;
+ if (res) {
+ pr2serr("FORMAT MEDIUM failed\n");
+ if (0 == op->verbose)
+ pr2serr(" try '-v' for more "
+ "information\n");
+ }
out:
res = sg_cmds_close_device(fd);
diff --git a/src/sg_inq.c b/src/sg_inq.c
index 7148acec..e4bcfd3d 100644
--- a/src/sg_inq.c
+++ b/src/sg_inq.c
@@ -43,7 +43,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.56 20160201"; /* SPC-5 rev 08 */
+static const char * version_str = "1.57 20160208"; /* SPC-5 rev 08 */
/* INQUIRY notes:
* It is recommended that the initial allocation length given to a
@@ -2073,6 +2073,31 @@ export_dev_ids(unsigned char * buff, int len, int verbose)
"protocol_id=0x%x>>\n", p_id);
}
break;
+ case 0xa: /* UUID based */
+ if (1 != c_set) {
+ if (verbose) {
+ pr2serr(" << expected binary code_set (1)>>\n");
+ dStrHexErr((const char *)ip, i_len, 0);
+ }
+ break;
+ }
+ if (i_len < 18) {
+ if (verbose) {
+ pr2serr(" << short UUID field expected 18 or more, "
+ "got %d >>\n", i_len);
+ dStrHexErr((const char *)ip, i_len, 0);
+ }
+ break;
+ }
+ printf("SCSI_IDENT_%s_UUID=", assoc_str);
+ for (m = 2; m < i_len; ++m) {
+ if ((6 == m) || (8 == m) || (10 == m) || (12 == m))
+ printf("-%02x", (unsigned int)ip[m]);
+ else
+ printf("%02x", (unsigned int)ip[m]);
+ }
+ printf("\n");
+ break;
default: /* reserved */
if (verbose) {
pr2serr(" reserved designator=0x%x\n", desig_type);
diff --git a/src/sg_wr_mode.c b/src/sg_wr_mode.c
index 7f9513bb..04766485 100644
--- a/src/sg_wr_mode.c
+++ b/src/sg_wr_mode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2015 Douglas Gilbert.
+ * Copyright (c) 2004-2016 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.
@@ -27,7 +27,7 @@
* mode page on the given device.
*/
-static const char * version_str = "1.15 20151220";
+static const char * version_str = "1.16 20160208";
#define ME "sg_wr_mode: "
@@ -56,8 +56,8 @@ static void usage()
pr2serr("Usage: sg_wr_mode [--contents=H,H...] [--dbd] [--force] "
"[--help]\n"
" [--len=10|6] [--mask=M,M...] "
- "[--page=PG[,SPG]] [--save]\n"
- " [--verbose] [--version] DEVICE\n"
+ "[--page=PG_H[,SPG_H]]\n"
+ " [--save] [--verbose] [--version] DEVICE\n"
" where:\n"
" --contents=H,H... | -c H,H... comma separated string "
"of hex numbers\n"
@@ -76,10 +76,10 @@ static void usage()
"string of hex\n"
" numbers that mask contents"
" to write\n"
- " --page=PG | -p PG page_code to be written (in hex)\n"
- " --page=PG,SPG | -p PG,SPG page and subpage code to "
- "be\n"
- " written (in hex)\n"
+ " --page=PG_H | -p PG_H page_code to be written (in hex)\n"
+ " --page=PG_H,SPG_H | -p PG_H,SPG_H page and subpage code "
+ "to be\n"
+ " written (in hex)\n"
" --save | -s set 'save page' (SP) bit; default "
"don't so\n"
" only 'current' values changed\n"
@@ -374,20 +374,22 @@ int main(int argc, char * argv[])
if (NULL == strchr(optarg, ',')) {
num = sscanf(optarg, "%x", &u);
if ((1 != num) || (u > 62)) {
- pr2serr("Bad page code value after '--page' switch\n");
+ pr2serr("Bad hex page code value after '--page' "
+ "switch\n");
return SG_LIB_SYNTAX_ERROR;
}
pg_code = u;
} else if (2 == sscanf(optarg, "%x,%x", &u, &uu)) {
if (uu > 254) {
- pr2serr("Bad sub page code value after '--page' switch\n");
+ pr2serr("Bad hex sub page code value after '--page' "
+ "switch\n");
return SG_LIB_SYNTAX_ERROR;
}
pg_code = u;
sub_pg_code = uu;
} else {
- pr2serr("Bad page code, subpage code sequence after '--page' "
- "switch\n");
+ pr2serr("Bad hex page code, subpage code sequence after "
+ "'--page' switch\n");
return SG_LIB_SYNTAX_ERROR;
}
break;