aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2016-01-27 15:13:35 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2016-01-27 15:13:35 +0000
commit572d431816271830cc321c2c7b596236e5708ea0 (patch)
treefc4216b9e9af787d73423029acfd9632f214db4a
parent92f622b977ac1f47099c4092b816e11f531f47c2 (diff)
downloadsg3_utils-572d431816271830cc321c2c7b596236e5708ea0.tar.gz
sg_logs: LPS misalignment lpage; sg_format: add ffmt option; sg_lib: big sense reporting rework
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@657 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog13
-rw-r--r--README2
-rw-r--r--debian/changelog2
-rw-r--r--doc/sg_format.831
-rw-r--r--doc/sg_read_long.84
-rw-r--r--doc/sg_write_long.84
-rw-r--r--examples/bsg_queue_tst.c6
-rw-r--r--examples/sg_sense_test.c29
-rw-r--r--include/sg_cmds_extra.h6
-rw-r--r--include/sg_lib.h50
-rw-r--r--include/sg_lib_data.h4
-rw-r--r--lib/sg_cmds_basic.c8
-rw-r--r--lib/sg_cmds_extra.c19
-rw-r--r--lib/sg_lib.c985
-rw-r--r--lib/sg_lib_data.c14
-rw-r--r--sg3_utils.spec2
-rw-r--r--src/sg_compare_and_write.c6
-rw-r--r--src/sg_dd.c4
-rw-r--r--src/sg_format.c384
-rw-r--r--src/sg_inq.c40
-rw-r--r--src/sg_logs.c532
-rw-r--r--src/sg_map.c2
-rw-r--r--src/sg_map26.c6
-rw-r--r--src/sg_rbuf.c6
-rw-r--r--src/sg_read.c6
-rw-r--r--src/sg_read_long.c8
-rw-r--r--src/sg_sat_identify.c10
-rw-r--r--src/sg_sat_phy_event.c10
-rw-r--r--src/sg_sat_read_gplog.c10
-rw-r--r--src/sg_sat_set_features.c10
-rw-r--r--src/sg_scan_linux.c6
-rw-r--r--src/sg_timestamp.c17
-rw-r--r--src/sg_vpd.c75
-rw-r--r--src/sg_write_long.c6
-rw-r--r--src/sg_xcopy.c227
-rw-r--r--src/sginfo.c2
-rw-r--r--src/sgm_dd.c4
-rw-r--r--src/sgp_dd.c6
-rw-r--r--utils/tst_sg_lib.c148
39 files changed, 1596 insertions, 1108 deletions
diff --git a/ChangeLog b/ChangeLog
index 3165d7f4..8b4baf10 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.42 [20160109] [svn: r656]
+Changelog for sg3_utils-1.42 [20160127] [svn: r657]
- sg_timestamp: new, to report or set timestamp
- sg_stpg: fix truncation of target port field
- sg_inq: cope with unicode strings, udev fixes
@@ -11,6 +11,7 @@ Changelog for sg3_utils-1.42 [20160109] [svn: r656]
- sg_logs: add Utilization lpage (sbc4r07)
- add Background operation lpage
- add Pending defects lpage
+ - add LPS misalignment lpage (sbc4r10)
- sg_vpd: add Block limits extension VPD page
- add Device constituents VPD page
- LB provisioning VPD page: expand LBPRZ, add
@@ -19,6 +20,7 @@ Changelog for sg3_utils-1.42 [20160109] [svn: r656]
assigned UUIDs in VPD page 0x83 (15-267r2)
- sg_sanitize: add --znr option (sbc4r07)
- sg_rep_zones: add --partial option (zbc-r04)
+ - sg_format: add ffmt option (sbc4r10)
- sg_raw: document length relationships
- rescan-scsi-bus.sh: updates from Suse
- sg_lib_data: sync asc/ascq codes with T10 20151126
@@ -26,6 +28,15 @@ Changelog for sg3_utils-1.42 [20160109] [svn: r656]
condition met, busy, task set full, ACA active and
task aborted
- add pr2serr() extern
+ - change sg_get_sense_str() and dStrHexStr(), return
+ chars written (returned void previously)
+ - add sg_get_sense_descriptors_str() function
+ - add sg_get_designation_descriptor_str() function
+ - sg_get_desig_type_str()+sg_get_desig_assoc_str()
+ and sg_get_desig_code_set_str() added
+ - sg_get_opcode_sa_name() break out zoning in/out
+ and read attribute service actions
+ - sg_cmds_extra: add sg_ll_format_unit2() for FFMT
- sg_pr2serr.h: new, to shorten fprintf(stderr, ...)
- sg_io_linux, sg_pt_linux: drop SUGGEST_* decoding
- sg_unaligned.h: add 48 bit support
diff --git a/README b/README
index 5d91fd71..a9e6c28c 100644
--- a/README
+++ b/README
@@ -413,4 +413,4 @@ See http://sg.danny.cz/sg/tools.html
Douglas Gilbert
-3rd January 2016
+27th January 2016
diff --git a/debian/changelog b/debian/changelog
index e125edfb..c6767692 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, 03 Jan 2016 13:00:00 -0500
+ -- Douglas Gilbert <dgilbert@interlog.com> Wed, 27 Jan 2016 10: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 a62f5def..6dc5141e 100644
--- a/doc/sg_format.8
+++ b/doc/sg_format.8
@@ -1,15 +1,15 @@
-.TH SG_FORMAT "8" "July 2014" "sg3_utils\-1.40" SG3_UTILS
+.TH SG_FORMAT "8" "January 2016" "sg3_utils\-1.42" SG3_UTILS
.SH NAME
sg_format \- format, resize or modify protection information of a SCSI disk
.SH SYNOPSIS
.B sg_format
[\fI\-\-cmplst=\fR{0|1}] [\fI\-\-count=COUNT\fR] [\fI\-\-dcrt\fR]
-[\fI\-\-early\fR] [\fI\-\-fmtpinfo=FPI\fR] [\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\-\-early\fR] [\fI\-\-ffmy=FFMT\fR] [\fI\-\-fmtpinfo=FPI\fR]
+[\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
.SH DESCRIPTION
.\" Add any additional description here
.PP
@@ -118,6 +118,21 @@ monitor the progress of the ongoing format operation with other
utilities (e.g. sg_turs(8) or sg_requests(8)). This option and \fI\-\-wait\fR
are mutually exclusive.
.TP
+\fB\-t\fR, \fB\-\-ffmt\fR=\fIFFMT\fR
+\fIFFMT\fR is placed in a field of the same name in the FORMAT UNIT cdb.
+The field was introduced in SBC\-4 revision 10. The default value is 0 which
+implies the former action to typically write to all blocks on the
+\fIDEVICE\fR and that can take a long time.
+.br
+\fIFFMT\fR has values 1 and 2 for fast format with 3 being reserved
+currently. The difference between 1 and 2 concerns read operations on LBAs to
+which no data has been written to, since the fast format. When \fIFFMT\fR
+is 1 the read operation should return "unspecified logical block data" and
+complete without error. When \fIFFMT\fR is 2 the read operation should
+yield check condition status with a sense key set to hardware error, medium
+error or command aborted. See SBC\-4 revsion 10 section 4.35 for more
+details.
+.TP
\fB\-f\fR, \fB\-\-fmtpinfo\fR=\fIFPI\fR
sets the FMTPINFO field in the FORMAT UNIT cdb to a value between 0 and 3.
The default value is 0. The FMTPINFO field from SBC\-3 revision 16 is a 2
@@ -498,7 +513,7 @@ Written by Grant Grundler, James Bottomley and Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2005\-2014 Grant Grundler, James Bottomley and Douglas Gilbert
+Copyright \(co 2005\-2016 Grant Grundler, James Bottomley and Douglas Gilbert
.br
This software is distributed under the GPL version 2. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/doc/sg_read_long.8 b/doc/sg_read_long.8
index 50bf795d..e1b1591a 100644
--- a/doc/sg_read_long.8
+++ b/doc/sg_read_long.8
@@ -13,7 +13,7 @@ Send SCSI READ LONG command to \fIDEVICE\fR. The read buffer is output in hex
and ASCII to stdout or placed in a file. Note that the data returned includes
the logical block data (typically 512 bytes for a disk) plus ECC
information (whose format is proprietary) plus optionally other proprietary
-data.
+data. Note that the logical block data may be encoded or encrypted.
.PP
In SBC\-4 revision 7 the SCSI READ LONG (10 and 16 byte) commands were made
obsolete. In the same revision all uses of SCSI WRITE LONG (10 and 16 byte)
@@ -94,7 +94,7 @@ Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2004\-2015 Douglas Gilbert
+Copyright \(co 2004\-2016 Douglas Gilbert
.br
This software is distributed under the GPL version 2. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/doc/sg_write_long.8 b/doc/sg_write_long.8
index 51f31f39..2d5560d7 100644
--- a/doc/sg_write_long.8
+++ b/doc/sg_write_long.8
@@ -1,4 +1,4 @@
-.TH SG_WRITE_LONG "8" "November 2015" "sg3_utils\-1.42" SG3_UTILS
+.TH SG_WRITE_LONG "8" "January 2016" "sg3_utils\-1.42" SG3_UTILS
.SH NAME
sg_write_long \- send SCSI WRITE LONG command
.SH SYNOPSIS
@@ -168,7 +168,7 @@ Written by Saeed Bishara. Further work by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2004\-2013 Douglas Gilbert
+Copyright \(co 2004\-2016 Douglas Gilbert
.br
This software is distributed under the GPL version 2. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/examples/bsg_queue_tst.c b/examples/bsg_queue_tst.c
index b376dc8a..ae7e3d00 100644
--- a/examples/bsg_queue_tst.c
+++ b/examples/bsg_queue_tst.c
@@ -20,7 +20,7 @@
The default behaviour is to "queue at head" which is useful for
error processing but not for streaming READ and WRITE commands.
-* Copyright (C) 2010 D. Gilbert
+* Copyright (C) 2010-2016 D. Gilbert
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -148,8 +148,8 @@ int main(int argc, char * argv[])
ok = 1;
break;
default: /* won't bother decoding other categories */
- sg_print_sense("command error",
- (unsigned char *)(long)rio_hdr.response,
+ fprintf(stderr, "command error:\n");
+ sg_print_sense(NULL, (unsigned char *)(long)rio_hdr.response,
rio_hdr.response_len, 1);
break;
}
diff --git a/examples/sg_sense_test.c b/examples/sg_sense_test.c
index d18d2214..42b33e43 100644
--- a/examples/sg_sense_test.c
+++ b/examples/sg_sense_test.c
@@ -63,19 +63,26 @@ int main(/* int argc, char * argv[] */)
char b[2048];
int k, prev_len;
- sg_print_sense("err1 test", err1, sizeof(err1), 1 /* raw_info */);
- sg_print_sense("\nerr2 test", err2, sizeof(err2), 1);
- sg_print_sense("\nerr3 test", err3, sizeof(err3), 1);
- sg_print_sense("\nerr4 test", err4, sizeof(err4), 1);
- sg_print_sense("\nerr5 test", err5, sizeof(err5), 1);
- sg_print_sense("\nerr6 test", err6, sizeof(err6), 1);
- sg_print_sense("\nerr7 test", err7, sizeof(err7), 1);
+ fprintf(stderr, "err1 test:\n");
+ sg_print_sense(NULL, err1, sizeof(err1), 1 /* raw_info */);
+ fprintf(stderr, "err2 test:\n");
+ sg_print_sense(" ", err2, sizeof(err2), 1);
+ fprintf(stderr, "err3 test:\n");
+ sg_print_sense(" ", err3, sizeof(err3), 1);
+ fprintf(stderr, "err4 test:\n");
+ sg_print_sense("> ", err4, sizeof(err4), 1);
+ fprintf(stderr, "err5 test:\n");
+ sg_print_sense(">> ", err5, sizeof(err5), 1);
+ fprintf(stderr, "err6 test:\n");
+ sg_print_sense(">> ", err6, sizeof(err6), 1);
+ fprintf(stderr, "err7 test:\n");
+ sg_print_sense(">> ", err7, sizeof(err7), 1);
printf("\n\nTry different output string sizes with "
"sg_get_sense_str(err2):\n");
for (k = 1, prev_len = -1; k < 512; ++k) {
- snprintf(leadin, sizeof(leadin), "blen=%d", k);
- sg_get_sense_str(leadin, err2, sizeof(err2), 0, k, b);
+ /* snprintf(leadin, sizeof(leadin), "blen=%d", k); */
+ sg_get_sense_str(NULL, err2, sizeof(err2), 0, k, b);
printf("%s\n", b);
if (prev_len == (int)strlen(b))
break;
@@ -86,8 +93,8 @@ int main(/* int argc, char * argv[] */)
printf("\n\nTry different output string sizes with "
"sg_get_sense_str(err4):\n");
for (k = 1, prev_len = -1; k < 512; ++k) {
- snprintf(leadin, sizeof(leadin), "blen=%d", k);
- sg_get_sense_str(leadin, err4, sizeof(err4), 0, k, b);
+ /* snprintf(leadin, sizeof(leadin), "blen=%d", k); */
+ sg_get_sense_str(NULL, err4, sizeof(err4), 0, k, b);
printf("%s\n", b);
if (prev_len == (int)strlen(b))
break;
diff --git a/include/sg_cmds_extra.h b/include/sg_cmds_extra.h
index 3dc4ae39..534fe386 100644
--- a/include/sg_cmds_extra.h
+++ b/include/sg_cmds_extra.h
@@ -2,7 +2,7 @@
#define SG_CMDS_EXTRA_H
/*
- * Copyright (c) 2004-2014 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.
@@ -52,6 +52,10 @@ int sg_ll_ata_pt(int sg_fd, const unsigned char * cdbp, int cdb_len,
int sg_ll_format_unit(int sg_fd, int fmtpinfo, int longlist, int fmtdata,
int cmplist, int dlist_format, int timeout_secs,
void * paramp, int param_len, int noisy, int verbose);
+int sg_ll_format_unit2(int sg_fd, int fmtpinfo, int longlist, int fmtdata,
+ int cmplist, int dlist_format, int ffmt,
+ int timeout_secs, void * paramp, int param_len,
+ int noisy, int verbose);
/* Invokes a SCSI GET LBA STATUS command (SBC). Returns 0 -> success,
* SG_LIB_CAT_INVALID_OP -> GET LBA STATUS not supported,
diff --git a/include/sg_lib.h b/include/sg_lib.h
index 49deb88b..e75afd96 100644
--- a/include/sg_lib.h
+++ b/include/sg_lib.h
@@ -2,7 +2,7 @@
#define SG_LIB_H
/*
- * 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.
@@ -203,9 +203,29 @@ int sg_get_sense_progress_fld(const unsigned char * sensep, int sb_len,
/* Closely related to sg_print_sense(). Puts decoded sense data in 'buff'.
* Usually multiline with multiple '\n' including one trailing. If
- * 'raw_sinfo' set appends sense buffer in hex. */
-void sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
- int sb_len, int raw_sinfo, int buff_len, char * buff);
+ * 'raw_sinfo' set appends sense buffer in hex. 'leadin' is string prepended
+ * to each line written to 'buff', NULL treated as "". Returns the number of
+ * bytes written to 'buff' excluding the trailing '\0'. */
+int sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
+ int sb_len, int raw_sinfo, int buff_len, char * buff);
+
+/* Decode descriptor format sense descriptors (assumes sense buffer is
+ * in descriptor format). 'leadin' is string prepended to each line written
+ * to 'b', NULL treated as "". Returns the number of bytes written to 'b'
+ * excluding the trailing '\0'. */
+int sg_get_sense_descriptors_str(const char * leadin,
+ const unsigned char * sense_buffer,
+ int sb_len, int blen, char * b);
+
+/* Decodes a designation descriptor (e.g. as found in the Device
+ * Identification VPD page (0x83)) into string 'b' whose maximum length is
+ * blen. 'leadin' is string prepended to each line written to 'b', NULL
+ * treated as "". Returns the number of bytes written to 'b' excluding the
+ * trailing '\0'. */
+int sg_get_designation_descriptor_str(const char * leadin,
+ const unsigned char * ddp, int dd_len,
+ int print_assoc, int do_long, int blen,
+ char * b);
/* Yield string associated with peripheral device type (pdt). Returns
* 'buff'. If 'pdt' out of range yields "bad pdt" string. */
@@ -222,12 +242,25 @@ int sg_lib_pdt_decay(int pdt);
* 'buff'. If 'tpi' out of range yields "bad tpi" string. */
char * sg_get_trans_proto_str(int tpi, int buff_len, char * buff);
+/* Returns a designator's type string given 'val' (0 to 15 inclusive),
+ * otherwise returns NULL. */
+const char * sg_get_desig_type_str(int val);
+
+/* Returns a designator's code_set string given 'val' (0 to 15 inclusive),
+ * otherwise returns NULL. */
+const char * sg_get_desig_code_set_str(int val);
+
+/* Returns a designator's association string given 'val' (0 to 3 inclusive),
+ * otherwise returns NULL. */
+const char * sg_get_desig_assoc_str(int val);
+
extern FILE * sg_warnings_strm;
void sg_set_warnings_strm(FILE * warnings_strm);
/* The following "print" functions send ACSII to 'sg_warnings_strm' file
- * descriptor (default value is stderr) */
+ * descriptor (default value is stderr). 'leadin' is string prepended to
+ * each line printed out, NULL treated as "". */
void sg_print_command(const unsigned char * command);
void sg_print_sense(const char * leadin, const unsigned char * sense_buffer,
int sb_len, int raw_info);
@@ -347,9 +380,10 @@ void dStrHexErr(const char* str, int len, int no_ascii);
* separated) to 'b' not to exceed 'b_len' characters. Each line
* starts with 'leadin' (NULL for no leadin) and there are 16 bytes
* per line with an extra space between the 8th and 9th bytes. 'format'
- * is unused, set to 0 . */
-void dStrHexStr(const char* str, int len, const char * leadin, int format,
- int b_len, char * b);
+ * is unused, set to 0 . Returns number of bytes written to 'b' excluding
+ * the trailing '\0'.*/
+int dStrHexStr(const char* str, int len, const char * leadin, int format,
+ int b_len, char * b);
/* Returns 1 when executed on big endian machine; else returns 0.
* Useful for displaying ATA identify words (which need swapping on a
diff --git a/include/sg_lib_data.h b/include/sg_lib_data.h
index b33ed394..98523141 100644
--- a/include/sg_lib_data.h
+++ b/include/sg_lib_data.h
@@ -2,7 +2,7 @@
#define SG_LIB_DATA_H
/*
- * Copyright (c) 2007-2014 Douglas Gilbert.
+ * Copyright (c) 2007-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.
@@ -31,6 +31,7 @@ extern "C" {
#define SG_MAINTENANCE_OUT 0xa4
#define SG_PERSISTENT_RESERVE_IN 0x5e
#define SG_PERSISTENT_RESERVE_OUT 0x5f
+#define SG_READ_ATTRIBUTE 0x8c
#define SG_READ_BUFFER 0x3c
#define SG_SANITIZE 0x48
#define SG_SERVICE_ACTION_BIDI 0x9d
@@ -85,6 +86,7 @@ extern struct sg_lib_value_name_t sg_lib_rec_copy_sa_arr[];
extern struct sg_lib_value_name_t sg_lib_variable_length_arr[];
extern struct sg_lib_value_name_t sg_lib_zoning_out_arr[];
extern struct sg_lib_value_name_t sg_lib_zoning_in_arr[];
+extern struct sg_lib_value_name_t sg_lib_read_attr_arr[];
extern struct sg_lib_asc_ascq_range_t sg_lib_asc_ascq_range[];
extern struct sg_lib_asc_ascq_t sg_lib_asc_ascq[];
extern const char * sg_lib_sense_key_desc[];
diff --git a/lib/sg_cmds_basic.c b/lib/sg_cmds_basic.c
index 2083913a..7a56d516 100644
--- a/lib/sg_cmds_basic.c
+++ b/lib/sg_cmds_basic.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2015 Douglas Gilbert.
+ * Copyright (c) 1999-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.
@@ -34,7 +34,7 @@
#endif
-static const char * version_str = "1.71 20151130";
+static const char * version_str = "1.72 20160126";
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
@@ -145,7 +145,9 @@ sg_cmds_process_helper(const char * leadin, int mx_di_len, int resid,
break;
}
if (verbose || n) {
- sg_get_sense_str(leadin, sbp, slen, (verbose > 1),
+ if (leadin && (strlen(leadin) > 0))
+ pr2ws("%s:\n", leadin);
+ sg_get_sense_str(NULL, sbp, slen, (verbose > 1),
sizeof(b), b);
pr2ws("%s", b);
if ((mx_di_len > 0) && (resid > 0)) {
diff --git a/lib/sg_cmds_extra.c b/lib/sg_cmds_extra.c
index 23ed1f60..5ccf3707 100644
--- a/lib/sg_cmds_extra.c
+++ b/lib/sg_cmds_extra.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2015 Douglas Gilbert.
+ * Copyright (c) 1999-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.
@@ -719,6 +719,19 @@ sg_ll_format_unit(int sg_fd, int fmtpinfo, int longlist, int fmtdata,
int cmplst, int dlist_format, int timeout_secs,
void * paramp, int param_len, int noisy, int verbose)
{
+ return sg_ll_format_unit2(sg_fd, fmtpinfo, longlist, fmtdata, cmplst,
+ dlist_format, 0, timeout_secs, paramp,
+ param_len, noisy, verbose);
+}
+
+/* Invokes a FORMAT UNIT (SBC-4) command. Return of 0 -> success,
+ * various SG_LIB_CAT_* positive values or -1 -> other errors.
+ * FFMT field added in sbc4r10 [20160121] */
+int
+sg_ll_format_unit2(int sg_fd, int fmtpinfo, int longlist, int fmtdata,
+ int cmplst, int dlist_format, int ffmt, int timeout_secs,
+ void * paramp, int param_len, int noisy, int verbose)
+{
int k, res, ret, sense_cat, tmout;
unsigned char fuCmdBlk[FORMAT_UNIT_CMDLEN] =
{FORMAT_UNIT_CMD, 0, 0, 0, 0, 0};
@@ -735,9 +748,11 @@ sg_ll_format_unit(int sg_fd, int fmtpinfo, int longlist, int fmtdata,
fuCmdBlk[1] |= 0x8;
if (dlist_format)
fuCmdBlk[1] |= (dlist_format & 0x7);
+ if (ffmt)
+ fuCmdBlk[4] |= (ffmt & 0x3);
tmout = (timeout_secs > 0) ? timeout_secs : DEF_PT_TIMEOUT;
if (verbose) {
- pr2ws(" format cdb: ");
+ pr2ws(" format unit cdb: ");
for (k = 0; k < 6; ++k)
pr2ws("%02x ", fuCmdBlk[k]);
pr2ws("\n");
diff --git a/lib/sg_lib.c b/lib/sg_lib.c
index 0f9aad39..d7e5575a 100644
--- a/lib/sg_lib.c
+++ b/lib/sg_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999-2015 Douglas Gilbert.
+ * Copyright (c) 1999-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.
@@ -470,6 +470,547 @@ sg_get_trans_proto_str(int tpi, int buff_len, char * buff)
return buff;
}
+static const char * desig_code_set_str_arr[] =
+{
+ "Reserved [0x0]",
+ "Binary",
+ "ASCII",
+ "UTF-8",
+ "Reserved [0x4]", "Reserved [0x5]", "Reserved [0x6]", "Reserved [0x7]",
+ "Reserved [0x8]", "Reserved [0x9]", "Reserved [0xa]", "Reserved [0xb]",
+ "Reserved [0xc]", "Reserved [0xd]", "Reserved [0xe]", "Reserved [0xf]",
+};
+
+const char *
+sg_get_desig_code_set_str(int val)
+{
+ if ((val >= 0) && (val < 16))
+ return desig_code_set_str_arr[val];
+ else
+ return NULL;
+}
+
+static const char * desig_assoc_str_arr[] =
+{
+ "Addressed logical unit",
+ "Target port", /* that received request; unless SCSI ports VPD */
+ "Target device that contains addressed lu",
+ "Reserved [0x3]",
+};
+
+const char *
+sg_get_desig_assoc_str(int val)
+{
+ if ((val >= 0) && (val < 4))
+ return desig_assoc_str_arr[val];
+ else
+ return NULL;
+}
+
+static const char * desig_type_str_arr[] =
+{
+ "vendor specific [0x0]",
+ "T10 vendor identification",
+ "EUI-64 based",
+ "NAA",
+ "Relative target port",
+ "Target port group", /* spc4r09: _primary_ target port group */
+ "Logical unit group",
+ "MD5 logical unit identifier",
+ "SCSI name string",
+ "Protocol specific port identifier", /* spc4r36 */
+ "UUID identifier", /* spc5r08 */
+ "Reserved [0xb]",
+ "Reserved [0xc]", "Reserved [0xd]", "Reserved [0xe]", "Reserved [0xf]",
+};
+
+const char *
+sg_get_desig_type_str(int val)
+{
+ if ((val >= 0) && (val < 16))
+ return desig_type_str_arr[val];
+ else
+ return NULL;
+}
+
+int
+sg_get_designation_descriptor_str(const char * leadin,
+ const unsigned char * ddp, int dd_len,
+ int print_assoc, int do_long, int blen,
+ char * b)
+{
+ int m, p_id, piv, c_set, assoc, desig_type, ci_off, c_id, d_id, naa;
+ int vsi, k, n, dlen;
+ const unsigned char * ip;
+ uint64_t vsei;
+ uint64_t id_ext;
+ char e[64];
+ const char * cp;
+ const char * lip = "";
+
+ n = 0;
+ if (leadin)
+ lip = leadin;
+ if (dd_len < 4) {
+ n += my_snprintf(b + n, blen - n, "%sdesignator desc too short: "
+ "got length of %d want 4 or more\n", lip, dd_len);
+ return n;
+ }
+ dlen = ddp[3];
+ if (dlen > (dd_len - 4)) {
+ n += my_snprintf(b + n, blen - n, "%sdesignator too long: says it "
+ "is %d bytes, but given %d bytes\n", lip, dlen,
+ dd_len - 4);
+ return n;
+ }
+ ip = ddp + 4;
+ p_id = ((ddp[0] >> 4) & 0xf);
+ c_set = (ddp[0] & 0xf);
+ piv = ((ddp[1] & 0x80) ? 1 : 0);
+ assoc = ((ddp[1] >> 4) & 0x3);
+ desig_type = (ddp[1] & 0xf);
+ if (print_assoc && ((cp = sg_get_desig_assoc_str(assoc))))
+ n += my_snprintf(b + n, blen - n, "%s %s:\n", lip, cp);
+ n += my_snprintf(b + n, blen - n, "%s designator type: ", lip);
+ cp = sg_get_desig_type_str(desig_type);
+ if (cp)
+ n += my_snprintf(b + n, blen - n, "%s", cp);
+ n += my_snprintf(b + n, blen - n, ", code set: ");
+ cp = sg_get_desig_code_set_str(c_set);
+ if (cp)
+ n += my_snprintf(b + n, blen - n, "%s", cp);
+ n += my_snprintf(b + n, blen - n, "\n");
+ if (piv && ((1 == assoc) || (2 == assoc)))
+ n += my_snprintf(b + n, blen - n, "%s transport: %s\n", lip,
+ sg_get_trans_proto_str(p_id, sizeof(e), e));
+ /* printf(" associated with the %s\n", sdparm_assoc_arr[assoc]); */
+ switch (desig_type) {
+ case 0: /* vendor specific */
+ k = 0;
+ if ((1 == c_set) || (2 == c_set)) { /* ASCII or UTF-8 */
+ for (k = 0; (k < dlen) && isprint(ip[k]); ++k)
+ ;
+ if (k >= dlen)
+ k = 1;
+ }
+ if (k)
+ n += my_snprintf(b + n, blen - n, "%s vendor specific: "
+ "%.*s\n", lip, dlen, ip);
+ else {
+ n += my_snprintf(b + n, blen - n, "%s vendor specific:\n",
+ lip);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ }
+ break;
+ case 1: /* T10 vendor identification */
+ n += my_snprintf(b + n, blen - n, "%s vendor id: %.8s\n", lip,
+ ip);
+ if (dlen > 8) {
+ if ((2 == c_set) || (3 == c_set)) { /* ASCII or UTF-8 */
+ n += my_snprintf(b + n, blen - n, "%s vendor specific: "
+ "%.*s\n", lip, dlen - 8, ip + 8);
+ } else {
+ n += my_snprintf(b + n, blen - n, "%s vendor specific: "
+ "0x", lip);
+ for (m = 8; m < dlen; ++m)
+ n += my_snprintf(b + n, blen - n, "%02x",
+ (unsigned int)ip[m]);
+ n += my_snprintf(b + n, blen - n, "\n");
+ }
+ }
+ break;
+ case 2: /* EUI-64 based */
+ if (! do_long) {
+ if ((8 != dlen) && (12 != dlen) && (16 != dlen)) {
+ n += my_snprintf(b + n, blen - n, "%s << expect 8, 12 "
+ "and 16 byte EUI, got %d >>\n", lip, dlen);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n,
+ b + n);
+ break;
+ }
+ n += my_snprintf(b + n, blen - n, "%s 0x", lip);
+ for (m = 0; m < dlen; ++m)
+ n += my_snprintf(b + n, blen - n, "%02x", (unsigned int)ip[m]);
+ n += my_snprintf(b + n, blen - n, "\n");
+ break;
+ }
+ n += my_snprintf(b + n, blen - n, "%s EUI-64 based %d byte "
+ "identifier\n", lip, dlen);
+ if (1 != c_set) {
+ n += my_snprintf(b + n, blen - n, "%s << expected binary "
+ "code_set (1) >>\n", lip);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ }
+ ci_off = 0;
+ if (16 == dlen) {
+ ci_off = 8;
+ id_ext = sg_get_unaligned_be64(ip);
+ n += my_snprintf(b + n, blen - n, "%s Identifier extension: "
+ "0x%" PRIx64 "\n", lip, id_ext);
+ } else if ((8 != dlen) && (12 != dlen)) {
+ n += my_snprintf(b + n, blen - n, "%s << can only decode 8, "
+ "12 and 16 byte ids >>\n", lip);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ }
+ c_id = sg_get_unaligned_be24(ip + ci_off);
+ n += my_snprintf(b + n, blen - n, "%s IEEE Company_id: 0x%x\n",
+ lip, c_id);
+ vsei = 0;
+ for (m = 0; m < 5; ++m) {
+ if (m > 0)
+ vsei <<= 8;
+ vsei |= ip[ci_off + 3 + m];
+ }
+ n += my_snprintf(b + n, blen - n, "%s Vendor Specific Extension "
+ "Identifier: 0x%" PRIx64 "\n", lip, vsei);
+ if (12 == dlen) {
+ d_id = sg_get_unaligned_be32(ip + 8);
+ n += my_snprintf(b + n, blen - n, "%s Directory ID: 0x%x\n",
+ lip, d_id);
+ }
+ break;
+ case 3: /* NAA <n> */
+ if (1 != c_set) {
+ n += my_snprintf(b + n, blen - n, "%s << unexpected code "
+ "set %d for NAA >>\n", lip, c_set);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ }
+ naa = (ip[0] >> 4) & 0xff;
+ switch (naa) {
+ case 2: /* NAA 2: IEEE Extended */
+ if (8 != dlen) {
+ n += my_snprintf(b + n, blen - n, "%s << unexpected NAA "
+ "2 identifier length: 0x%x >>\n", lip, dlen);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n,
+ b + n);
+ break;
+ }
+ d_id = (((ip[0] & 0xf) << 8) | ip[1]);
+ c_id = sg_get_unaligned_be24(ip + 2);
+ vsi = sg_get_unaligned_be24(ip + 5);
+ if (do_long) {
+ n += my_snprintf(b + n, blen - n, "%s NAA 2, vendor "
+ "specific identifier A: 0x%x\n", lip, d_id);
+ n += my_snprintf(b + n, blen - n, "%s IEEE Company_id: "
+ "0x%x\n", lip, c_id);
+ n += my_snprintf(b + n, blen - n, "%s vendor specific "
+ "identifier B: 0x%x\n", lip, vsi);
+ n += my_snprintf(b + n, blen - n, "%s [0x", lip);
+ for (m = 0; m < 8; ++m)
+ n += my_snprintf(b + n, blen - n, "%02x",
+ (unsigned int)ip[m]);
+ n += my_snprintf(b + n, blen - n, "]\n");
+ }
+ n += my_snprintf(b + n, blen - n, "%s 0x", lip);
+ for (m = 0; m < 8; ++m)
+ n += my_snprintf(b + n, blen - n, "%02x", (unsigned int)ip[m]);
+ n += my_snprintf(b + n, blen - n, "\n");
+ break;
+ case 3: /* NAA 3: Locally assigned */
+ if (8 != dlen) {
+ n += my_snprintf(b + n, blen - n, "%s << unexpected NAA "
+ "3 identifier length: 0x%x >>\n", lip, dlen);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n,
+ b + n);
+ break;
+ }
+ if (do_long)
+ n += my_snprintf(b + n, blen - n, "%s NAA 3, Locally "
+ "assigned:\n", lip);
+ n += my_snprintf(b + n, blen - n, "%s 0x", lip);
+ for (m = 0; m < 8; ++m)
+ n += my_snprintf(b + n, blen - n, "%02x", (unsigned int)ip[m]);
+ n += my_snprintf(b + n, blen - n, "\n");
+ break;
+ case 5: /* NAA 5: IEEE Registered */
+ if (8 != dlen) {
+ n += my_snprintf(b + n, blen - n, "%s << unexpected NAA "
+ "5 identifier length: 0x%x >>\n", lip, dlen);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n,
+ b + n);
+ break;
+ }
+ c_id = (((ip[0] & 0xf) << 20) | (ip[1] << 12) |
+ (ip[2] << 4) | ((ip[3] & 0xf0) >> 4));
+ vsei = ip[3] & 0xf;
+ for (m = 1; m < 5; ++m) {
+ vsei <<= 8;
+ vsei |= ip[3 + m];
+ }
+ if (do_long) {
+ n += my_snprintf(b + n, blen - n, "%s NAA 5, IEEE "
+ "Company_id: 0x%x\n", lip, c_id);
+ n += my_snprintf(b + n, blen - n, "%s Vendor Specific "
+ "Identifier: 0x%" PRIx64 "\n", lip, vsei);
+ n += my_snprintf(b + n, blen - n, "%s [0x", lip);
+ for (m = 0; m < 8; ++m)
+ n += my_snprintf(b + n, blen - n, "%02x",
+ (unsigned int)ip[m]);
+ n += my_snprintf(b + n, blen - n, "]\n");
+ } else {
+ n += my_snprintf(b + n, blen - n, "%s 0x", lip);
+ for (m = 0; m < 8; ++m)
+ n += my_snprintf(b + n, blen - n, "%02x",
+ (unsigned int)ip[m]);
+ n += my_snprintf(b + n, blen - n, "\n");
+ }
+ break;
+ case 6: /* NAA 6: IEEE Registered extended */
+ if (16 != dlen) {
+ n += my_snprintf(b + n, blen - n, "%s << unexpected NAA "
+ "6 identifier length: 0x%x >>\n", lip, dlen);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n,
+ b + n);
+ break;
+ }
+ c_id = (((ip[0] & 0xf) << 20) | (ip[1] << 12) |
+ (ip[2] << 4) | ((ip[3] & 0xf0) >> 4));
+ vsei = ip[3] & 0xf;
+ for (m = 1; m < 5; ++m) {
+ vsei <<= 8;
+ vsei |= ip[3 + m];
+ }
+ if (do_long) {
+ n += my_snprintf(b + n, blen - n, "%s NAA 6, IEEE "
+ "Company_id: 0x%x\n", lip, c_id);
+ n += my_snprintf(b + n, blen - n, "%s Vendor Specific "
+ "Identifier: 0x%" PRIx64 "\n", lip, vsei);
+ vsei = sg_get_unaligned_be64(ip + 8);
+ n += my_snprintf(b + n, blen - n, "%s Vendor Specific "
+ "Identifier Extension: 0x%" PRIx64 "\n", lip,
+ vsei);
+ n += my_snprintf(b + n, blen - n, "%s [0x", lip);
+ for (m = 0; m < 16; ++m)
+ n += my_snprintf(b + n, blen - n, "%02x",
+ (unsigned int)ip[m]);
+ n += my_snprintf(b + n, blen - n, "]\n");
+ } else {
+ n += my_snprintf(b + n, blen - n, "%s 0x", lip);
+ for (m = 0; m < 16; ++m)
+ n += my_snprintf(b + n, blen - n, "%02x",
+ (unsigned int)ip[m]);
+ n += my_snprintf(b + n, blen - n, "\n");
+ }
+ break;
+ default:
+ n += my_snprintf(b + n, blen - n, "%s << unexpected NAA "
+ "[0x%x] >>\n", lip, naa);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ }
+ break;
+ case 4: /* Relative target port */
+ if ((1 != c_set) || (1 != assoc) || (4 != dlen)) {
+ n += my_snprintf(b + n, blen - n, "%s << expected binary "
+ "code_set, target port association, length 4 "
+ ">>\n", lip);
+ n += dStrHexStr((const char *)ip, dlen, "", 0, blen - n, b + n);
+ break;
+ }
+ d_id = sg_get_unaligned_be16(ip + 2);
+ n += my_snprintf(b + n, blen - n, "%s Relative target port: "
+ "0x%x\n", lip, d_id);
+ break;
+ case 5: /* (primary) Target port group */
+ if ((1 != c_set) || (1 != assoc) || (4 != dlen)) {
+ n += my_snprintf(b + n, blen - n, "%s << expected binary "
+ "code_set, target port association, length 4 "
+ ">>\n", lip);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ }
+ d_id = sg_get_unaligned_be16(ip + 2);
+ n += my_snprintf(b + n, blen - n, "%s Target port group: 0x%x\n",
+ lip, d_id);
+ break;
+ case 6: /* Logical unit group */
+ if ((1 != c_set) || (0 != assoc) || (4 != dlen)) {
+ n += my_snprintf(b + n, blen - n, "%s << expected binary "
+ "code_set, logical unit association, length "
+ "4 >>\n", lip);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ }
+ d_id = sg_get_unaligned_be16(ip + 2);
+ n += my_snprintf(b + n, blen - n, "%s Logical unit group: "
+ "0x%x\n", lip, d_id);
+ break;
+ case 7: /* MD5 logical unit identifier */
+ if ((1 != c_set) || (0 != assoc)) {
+ n += my_snprintf(b + n, blen - n, "%s << expected binary "
+ "code_set, logical unit association >>\n", lip);
+ n += dStrHexStr((const char *)ip, dlen, "", 0, blen - n, b + n);
+ break;
+ }
+ n += my_snprintf(b + n, blen - n, "%s MD5 logical unit "
+ "identifier:\n", lip);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ case 8: /* SCSI name string */
+ if (3 != c_set) {
+ n += my_snprintf(b + n, blen - n, "%s << expected UTF-8 "
+ "code_set >>\n", lip);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ }
+ n += my_snprintf(b + n, blen - n, "%s SCSI name string:\n", lip);
+ /* does %s print out UTF-8 ok??
+ * Seems to depend on the locale. Looks ok here with my
+ * locale setting: en_AU.UTF-8
+ */
+ n += my_snprintf(b + n, blen - n, "%s %s\n", lip,
+ (const char *)ip);
+ break;
+ case 9: /* Protocol specific port identifier */
+ /* added in spc4r36, PIV must be set, proto_id indicates */
+ /* whether UAS (USB) or SOP (PCIe) or ... */
+ if (! piv)
+ n += my_snprintf(b + n, blen - n, " %s >>>> Protocol "
+ "specific port identifier expects protocol\n"
+ "%s identifier to be valid and it is "
+ "not\n", lip, lip);
+ if (TPROTO_UAS == p_id) {
+ n += my_snprintf(b + n, blen - n, "%s USB device address: "
+ "0x%x\n", lip, 0x7f & ip[0]);
+ n += my_snprintf(b + n, blen - n, "%s USB interface number: "
+ "0x%x\n", lip, ip[2]);
+ } else if (TPROTO_SOP == p_id) {
+ n += my_snprintf(b + n, blen - n, "%s PCIe routing ID, bus "
+ "number: 0x%x\n", lip, ip[0]);
+ n += my_snprintf(b + n, blen - n, "%s function number: "
+ "0x%x\n", lip, ip[1]);
+ n += my_snprintf(b + n, blen - n, "%s [or device "
+ "number: 0x%x, function number: 0x%x]\n", lip,
+ (0x1f & (ip[1] >> 3)), 0x7 & ip[1]);
+ } else
+ n += my_snprintf(b + n, blen - n, "%s >>>> unexpected "
+ "protocol indentifier: %s\n%s with "
+ "Protocol specific port identifier\n", lip,
+ sg_get_trans_proto_str(p_id, sizeof(e), e), lip);
+ break;
+ case 0xa: /* UUID identifier */
+ if (1 != c_set) {
+ n += my_snprintf(b + n, blen - n, "%s << expected binary "
+ "code_set >>\n", lip);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ }
+ if ((1 != ((ip[0] >> 4) & 0xf)) || (18 != dlen)) {
+ n += my_snprintf(b + n, blen - n, "%s << expected locally "
+ "assigned UUID, 16 bytes long >>\n", lip);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ }
+ n += my_snprintf(b + n, blen - n, "%s Locally assigned UUID: ",
+ lip);
+ for (m = 0; m < 16; ++m) {
+ if ((4 == m) || (6 == m) || (8 == m) || (10 == m))
+ n += my_snprintf(b + n, blen - n, "-");
+ n += my_snprintf(b + n, blen - n, "%02x", (unsigned int)ip[2 + m]);
+ }
+ n += my_snprintf(b + n, blen - n, "\n");
+ if (do_long) {
+ n += my_snprintf(b + n, blen - n, "%s [0x", lip);
+ for (m = 0; m < 16; ++m)
+ n += my_snprintf(b + n, blen - n, "%02x",
+ (unsigned int)ip[2 + m]);
+ n += my_snprintf(b + n, blen - n, "]\n");
+ }
+ break;
+ default: /* reserved */
+ n += my_snprintf(b + n, blen - n, "%s reserved "
+ "designator=0x%x\n", lip, desig_type);
+ n += dStrHexStr((const char *)ip, dlen, lip, 0, blen - n, b + n);
+ break;
+ }
+ return n;
+}
+
+static int
+decode_sks(const char * leadin, const unsigned char * descp, int add_d_len,
+ int sense_key, int * processedp, int blen, char * b)
+{
+ int progress, pr, rem, n;
+ const char * lip = "";
+
+ n = 0;
+ if (leadin)
+ lip = leadin;
+ switch (sense_key) {
+ case SPC_SK_ILLEGAL_REQUEST:
+ if (add_d_len < 6) {
+ n += my_snprintf(b + n, blen - n, "Field pointer: ");
+ goto too_short;
+ }
+ /* abbreviate to fit on one line */
+ n += my_snprintf(b + n, blen - n, "Field pointer:\n");
+ n += my_snprintf(b + n, blen - n, "%s Error in %s: byte %d",
+ lip, (descp[4] & 0x40) ? "Command" :
+ "Data parameters",
+ sg_get_unaligned_be16(descp + 5));
+ if (descp[4] & 0x08) {
+ n += my_snprintf(b + n, blen - n, " bit %d\n",
+ descp[4] & 0x07);
+ } else
+ n += my_snprintf(b + n, blen - n, "\n");
+ break;
+ case SPC_SK_HARDWARE_ERROR:
+ case SPC_SK_MEDIUM_ERROR:
+ case SPC_SK_RECOVERED_ERROR:
+ n += my_snprintf(b + n, blen - n, "Actual retry count: ");
+ if (add_d_len < 6)
+ goto too_short;
+ n += my_snprintf(b + n, blen - n,"%u\n",
+ sg_get_unaligned_be16(descp + 5));
+ break;
+ case SPC_SK_NO_SENSE:
+ case SPC_SK_NOT_READY:
+ n += my_snprintf(b + n, blen - n, "Progress indication: ");
+ if (add_d_len < 6)
+ goto too_short;
+ progress = sg_get_unaligned_be16(descp + 5);
+ pr = (progress * 100) / 65536;
+ rem = ((progress * 100) % 65536) / 656;
+ n += my_snprintf(b + n, blen - n, "%d.%02d%%\n", pr, rem);
+ break;
+ case SPC_SK_COPY_ABORTED:
+ n += my_snprintf(b + n, blen - n, "Segment pointer:\n");
+ if (add_d_len < 6)
+ goto too_short;
+ n += my_snprintf(b + n, blen - n, "%s Relative to start of "
+ "%s, byte %d", lip,
+ (descp[4] & 0x20) ? "segment descriptor" :
+ "parameter list",
+ sg_get_unaligned_be16(descp + 5));
+ if (descp[4] & 0x08)
+ n += my_snprintf(b + n, blen - n, " bit %d\n",
+ descp[4] & 0x07);
+ else
+ n += my_snprintf(b + n, blen - n, "\n");
+ break;
+ case SPC_SK_UNIT_ATTENTION:
+ n += my_snprintf(b + n, blen - n, "Unit attention condition "
+ "queue:\n");
+ n += my_snprintf(b + n, blen - n, "%s overflow flag is %d\n",
+ lip, !!(descp[4] & 0x1));
+ break;
+ default:
+ n += my_snprintf(b + n, blen - n, "Sense_key: 0x%x "
+ "unexpected\n", sense_key);
+ *processedp = 0;
+ break;
+ }
+ return n;
+
+too_short:
+ n += my_snprintf(b + n, blen - n, "%s\n", " >> descriptor too short");
+ *processedp = 0;
+ return n;
+}
+
#define TPGS_STATE_OPTIMIZED 0x0
#define TPGS_STATE_NONOPTIMIZED 0x1
#define TPGS_STATE_STANDBY 0x2
@@ -500,7 +1041,7 @@ decode_tpgs_state(int st, char * b, int blen)
static int
uds_referral_descriptor_str(char * b, int blen, const unsigned char * dp,
- int alen)
+ int alen, const char * leadin)
{
int n = 0;
int dlen = alen - 2;
@@ -508,58 +1049,73 @@ uds_referral_descriptor_str(char * b, int blen, const unsigned char * dp,
const unsigned char * tp;
uint64_t ull;
char c[40];
+ const char * lip = "";
- n += my_snprintf(b + n, blen - n, " Not all referrals: %d\n",
+ if (leadin)
+ lip = leadin;
+ n += my_snprintf(b + n, blen - n, "%s Not all referrals: %d\n", lip,
!!(dp[2] & 0x1));
dp += 4;
for (k = 0, f = 1; (k + 4) < dlen; k += g, dp += g, ++f) {
tpgd = dp[3];
g = (tpgd * 4) + 20;
- n += my_snprintf(b + n, blen - n, " Descriptor %d\n", f);
+ n += my_snprintf(b + n, blen - n, "%s Descriptor %d\n", lip, f);
if ((k + g) > dlen) {
- n += my_snprintf(b + n, blen - n, " truncated descriptor, "
- "stop\n");
+ n += my_snprintf(b + n, blen - n, "%s truncated descriptor, "
+ "stop\n", lip);
return n;
}
ull = sg_get_unaligned_be64(dp + 4);
- n += my_snprintf(b + n, blen - n, " first uds LBA: 0x%" PRIx64
- "\n", ull);
+ n += my_snprintf(b + n, blen - n, "%s first uds LBA: 0x%" PRIx64
+ "\n", lip, ull);
ull = sg_get_unaligned_be64(dp + 12);
- n += my_snprintf(b + n, blen - n, " last uds LBA: 0x%" PRIx64
- "\n", ull);
+ n += my_snprintf(b + n, blen - n, "%s last uds LBA: 0x%" PRIx64
+ "\n", lip, ull);
for (j = 0; j < tpgd; ++j) {
tp = dp + 20 + (j * 4);
decode_tpgs_state(tp[0] & 0xf, c, sizeof(c));
- n += my_snprintf(b + n, blen - n, " tpg: %d state: %s\n",
- sg_get_unaligned_be16(tp + 2), c);
+ n += my_snprintf(b + n, blen - n, "%s tpg: %d state: "
+ "%s\n", lip, sg_get_unaligned_be16(tp + 2), c);
}
}
return n;
}
-static const char * sdata_src[] = {
- "unknown",
- "Extended Copy command source device",
- "Extended Copy command destination device",
- };
+static const char * dd_usage_reason_str_arr[] = {
+ "Unknown",
+ "resend this and further commands to:",
+ "resend this command to:",
+ "new subsiduary lu added to this administrative lu:",
+ "administrative lu associated with a preferred binding:",
+ };
/* Decode descriptor format sense descriptors (assumes sense buffer is
* in descriptor format) */
-static void
-sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
+int
+sg_get_sense_descriptors_str(const char * leadin,
+ const unsigned char * sense_buffer, int sb_len,
int blen, char * b)
{
int add_sb_len, add_d_len, desc_len, k, j, sense_key, processed;
int n, progress, pr, rem;
const unsigned char * descp;
+ const char * lip = "";
const char * dtsp = " >> descriptor too short";
+ const char * eccp = "Extended copy command";
+ const char * ddp = "destination device";
+ char z[64];
if ((NULL == b) || (blen <= 0))
- return;
+ return 0;
b[0] = '\0';
+ if (leadin) {
+ lip = leadin;
+ snprintf(z, sizeof(z), "%.60s ", lip);
+ } else
+ snprintf(z, sizeof(z), " ");
if ((sb_len < 8) || (0 == (add_sb_len = sense_buffer[7])))
- return;
+ return 0;
add_sb_len = (add_sb_len < (sb_len - 8)) ? add_sb_len : (sb_len - 8);
sense_key = (sense_buffer[1] & 0xf);
@@ -570,13 +1126,13 @@ sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
if ((k + add_d_len + 2) > add_sb_len)
add_d_len = add_sb_len - k - 2;
desc_len = add_d_len + 2;
- n += my_snprintf(b + n, blen - n, " Descriptor type: ");
+ n += my_snprintf(b + n, blen - n, "%s Descriptor type: ", lip);
processed = 1;
switch (descp[0]) {
case 0:
- n += my_snprintf(b + n, blen - n, "Information\n");
+ n += my_snprintf(b + n, blen - n, "Information: ");
if ((add_d_len >= 10) && (0x80 & descp[2])) {
- n += my_snprintf(b + n, blen - n, " 0x");
+ n += my_snprintf(b + n, blen - n, "0x");
for (j = 0; j < 8; ++j)
n += my_snprintf(b + n, blen - n, "%02x", descp[4 + j]);
n += my_snprintf(b + n, blen - n, "\n");
@@ -586,9 +1142,9 @@ sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
}
break;
case 1:
- n += my_snprintf(b + n, blen - n, "Command specific\n");
+ n += my_snprintf(b + n, blen - n, "Command specific: ");
if (add_d_len >= 10) {
- n += my_snprintf(b + n, blen - n, " 0x");
+ n += my_snprintf(b + n, blen - n, "0x");
for (j = 0; j < 8; ++j)
n += my_snprintf(b + n, blen - n, "%02x", descp[4 + j]);
n += my_snprintf(b + n, blen - n, "\n");
@@ -597,102 +1153,29 @@ sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
processed = 0;
}
break;
- case 2:
- n += my_snprintf(b + n, blen - n, "Sense key specific:");
- switch (sense_key) {
- case SPC_SK_ILLEGAL_REQUEST:
- n += my_snprintf(b + n, blen - n, " Field pointer\n");
- if (add_d_len < 6) {
- n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
- processed = 0;
- break;
- }
- n += my_snprintf(b + n, blen - n, " Error in %s: byte %d",
- (descp[4] & 0x40) ? "Command" :
- "Data parameters",
- sg_get_unaligned_be16(descp + 5));
- if (descp[4] & 0x08) {
- n += my_snprintf(b + n, blen - n, " bit %d\n",
- descp[4] & 0x07);
- } else
- n += my_snprintf(b + n, blen - n, "\n");
- break;
- case SPC_SK_HARDWARE_ERROR:
- case SPC_SK_MEDIUM_ERROR:
- case SPC_SK_RECOVERED_ERROR:
- n += my_snprintf(b + n, blen - n, " Actual retry count\n");
- if (add_d_len < 6) {
- n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
- processed = 0;
- break;
- }
- n += my_snprintf(b + n, blen - n," 0x%02x%02x\n", descp[5],
- descp[6]);
- break;
- case SPC_SK_NO_SENSE:
- case SPC_SK_NOT_READY:
- n += my_snprintf(b + n, blen - n, " Progress indication: ");
- if (add_d_len < 6) {
- n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
- processed = 0;
- break;
- }
- progress = sg_get_unaligned_be16(descp + 5);
- pr = (progress * 100) / 65536;
- rem = ((progress * 100) % 65536) / 656;
- n += my_snprintf(b + n, blen - n, "%d.%02d%%\n", pr, rem);
- break;
- case SPC_SK_COPY_ABORTED:
- n += my_snprintf(b + n, blen - n, " Segment pointer\n");
- if (add_d_len < 6) {
- n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
- processed = 0;
- break;
- }
- n += my_snprintf(b + n, blen - n, " Relative to start of %s, "
- "byte %d",
- (descp[4] & 0x20) ? "segment descriptor" :
- "parameter list",
- sg_get_unaligned_be16(descp + 5));
- if (descp[4] & 0x08)
- n += my_snprintf(b + n, blen - n, " bit %d\n",
- descp[4] & 0x07);
- else
- n += my_snprintf(b + n, blen - n, "\n");
- break;
- case SPC_SK_UNIT_ATTENTION:
- n += my_snprintf(b + n, blen - n, " Unit attention condition "
- "queue: ");
- n += my_snprintf(b + n, blen - n, "overflow flag is %d\n",
- !!(descp[4] & 0x1));
- break;
- default:
- n += my_snprintf(b + n, blen - n, " Sense_key: 0x%x "
- "unexpected\n", sense_key);
- processed = 0;
- break;
- }
+ case 2: /* Sense Key Specific */
+ n += my_snprintf(b + n, blen - n, "Sense key specific: ");
+ n += decode_sks(lip, descp, add_d_len, sense_key, &processed,
+ blen - n, b + n);
break;
case 3:
- n += my_snprintf(b + n, blen - n, "Field replaceable unit\n");
+ n += my_snprintf(b + n, blen - n, "Field replaceable unit code: ");
if (add_d_len >= 2)
- n += my_snprintf(b + n, blen - n, " code=0x%x\n",
- descp[3]);
+ n += my_snprintf(b + n, blen - n, "0x%x\n", descp[3]);
else {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
}
break;
case 4:
- n += my_snprintf(b + n, blen - n, "Stream commands\n");
+ n += my_snprintf(b + n, blen - n, "Stream commands: ");
if (add_d_len >= 2) {
if (descp[3] & 0x80)
- n += my_snprintf(b + n, blen - n, " FILEMARK");
+ n += my_snprintf(b + n, blen - n, "FILEMARK");
if (descp[3] & 0x40)
- n += my_snprintf(b + n, blen - n, " End Of Medium "
- "(EOM)");
+ n += my_snprintf(b + n, blen - n, "End Of Medium (EOM)");
if (descp[3] & 0x20)
- n += my_snprintf(b + n, blen - n, " Incorrect Length "
+ n += my_snprintf(b + n, blen - n, "Incorrect Length "
"Indicator (ILI)");
n += my_snprintf(b + n, blen - n, "\n");
} else {
@@ -701,9 +1184,9 @@ sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
}
break;
case 5:
- n += my_snprintf(b + n, blen - n, "Block commands\n");
+ n += my_snprintf(b + n, blen - n, "Block commands: ");
if (add_d_len >= 2)
- n += my_snprintf(b + n, blen - n, " Incorrect Length "
+ n += my_snprintf(b + n, blen - n, "Incorrect Length "
"Indicator (ILI) %s\n",
(descp[3] & 0x20) ? "set" : "clear");
else {
@@ -725,27 +1208,27 @@ sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
"identification\n");
processed = 0;
break;
- case 9: /* this is defined in SAT (and SAT-2) */
- n += my_snprintf(b + n, blen - n, "ATA Status Return\n");
+ case 9: /* this is defined in SAT (SAT-2) */
+ n += my_snprintf(b + n, blen - n, "ATA Status Return: ");
if (add_d_len >= 12) {
- int extend, sector_count;
+ int extend, count;
extend = descp[2] & 1;
- sector_count = descp[5] + (extend ? (descp[4] << 8) : 0);
- n += my_snprintf(b + n, blen - n, " extend=%d error=0x%x "
- " sector_count=0x%x\n", extend, descp[3],
- sector_count);
+ count = descp[5] + (extend ? (descp[4] << 8) : 0);
+ n += my_snprintf(b + n, blen - n, "extend=%d error=0x%x "
+ "\n%s count=0x%x ", extend,
+ descp[3], lip, count);
if (extend)
- n += my_snprintf(b + n, blen - n, " "
- "lba=0x%02x%02x%02x%02x%02x%02x\n",
+ n += my_snprintf(b + n, blen - n,
+ "lba=0x%02x%02x%02x%02x%02x%02x ",
descp[10], descp[8], descp[6],
descp[11], descp[9], descp[7]);
else
- n += my_snprintf(b + n, blen - n, " "
- "lba=0x%02x%02x%02x\n",
+ n += my_snprintf(b + n, blen - n,
+ "lba=0x%02x%02x%02x ",
descp[11], descp[9], descp[7]);
- n += my_snprintf(b + n, blen - n, " device=0x%x "
- "status=0x%x\n", descp[12], descp[13]);
+ n += my_snprintf(b + n, blen - n, "device=0x%x status=0x%x\n",
+ descp[12], descp[13]);
} else {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
@@ -754,7 +1237,7 @@ sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
case 0xa:
/* Added in SPC-4 rev 17, became 'Another ...' in rev 34 */
n += my_snprintf(b + n, blen - n, "Another progress "
- "indication\n");
+ "indication: ");
if (add_d_len < 6) {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
@@ -763,20 +1246,21 @@ sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
progress = sg_get_unaligned_be16(descp + 6);
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
- n += my_snprintf(b + n, blen - n, " %d.02%d%%", pr, rem);
- n += my_snprintf(b + n, blen - n, " [sense_key=0x%x "
- "asc,ascq=0x%x,0x%x]\n",
- descp[2], descp[3], descp[4]);
+ n += my_snprintf(b + n, blen - n, "%d.02%d%%\n", pr, rem);
+ n += my_snprintf(b + n, blen - n, "%s [sense_key=0x%x "
+ "asc,ascq=0x%x,0x%x]\n", lip, descp[2], descp[3],
+ descp[4]);
break;
case 0xb: /* Added in SPC-4 rev 23, defined in SBC-3 rev 22 */
- n += my_snprintf(b + n, blen - n, "User data segment referral\n");
+ n += my_snprintf(b + n, blen - n, "User data segment referral: ");
if (add_d_len < 2) {
n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
processed = 0;
break;
}
+ n += my_snprintf(b + n, blen - n, "\n");
n += uds_referral_descriptor_str(b + n, blen - n, descp,
- add_d_len);
+ add_d_len, lip);
break;
case 0xc: /* Added in SPC-4 rev 28 */
n += my_snprintf(b + n, blen - n, "Forwarded sense data\n");
@@ -785,32 +1269,92 @@ sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
processed = 0;
break;
}
- n += my_snprintf(b + n, blen - n, " FSDT: %s\n",
+ n += my_snprintf(b + n, blen - n, "%s FSDT: %s\n", lip,
(descp[2] & 0x80) ? "set" : "clear");
j = descp[2] & 0xf;
- if (j < 3)
- n += my_snprintf(b + n, blen - n, " Sense data source: "
- "%s\n", sdata_src[j]);
- else
- n += my_snprintf(b + n, blen - n, " Sense data source: "
- "reserved [%d]\n", j);
+ n += my_snprintf(b + n, blen - n, "%s Sense data source: ",
+ lip);
+ switch (j) {
+ case 0:
+ n += my_snprintf(b + n, blen - n, "%s source device\n", eccp);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ n += my_snprintf(b + n, blen - n, "%s %s %d\n", eccp, ddp,
+ j - 1);
+ break;
+ default:
+ n += my_snprintf(b + n, blen - n, "unknown [%d]\n", j);
+ }
{
- char c[200];
+ char c[480];
sg_get_scsi_status_str(descp[3], sizeof(c) - 1, c);
c[sizeof(c) - 1] = '\0';
- n += my_snprintf(b + n, blen - n, " Forwarded status: "
- "%s\n", c);
+ n += my_snprintf(b + n, blen - n, "%s Forwarded status: "
+ "%s\n", lip, c);
if (add_d_len > 2) {
/* recursing; hope not to get carried away */
- n += my_snprintf(b + n, blen - n, " vvvvvvvvvvvvvvvv\n");
- sg_get_sense_str(NULL, descp + 4, add_d_len - 2, 0,
+ n += my_snprintf(b + n, blen - n, "%s vvvvvvvvvvvvvvvv\n",
+ lip);
+ sg_get_sense_str(lip, descp + 4, add_d_len - 2, 0,
sizeof(c), c);
n += my_snprintf(b + n, blen - n, "%s", c);
- n += my_snprintf(b + n, blen - n, " ^^^^^^^^^^^^^^^^\n");
+ n += my_snprintf(b + n, blen - n, "%s ^^^^^^^^^^^^^^^^\n",
+ lip);
}
}
break;
+ case 0xd: /* Added in SBC-3 rev 36d */
+ /* this descriptor combines descriptors 0, 1, 2 and 3 */
+ n += my_snprintf(b + n, blen - n, "Direct-access block device\n");
+ if (add_d_len < 28) {
+ n += my_snprintf(b + n, blen - n, "%s\n", dtsp);
+ processed = 0;
+ break;
+ }
+ if (0x20 & descp[2])
+ n += my_snprintf(b + n, blen - n, "%s ILI (incorrect "
+ "length indication) set\n", lip);
+ if (0x80 & descp[4]) {
+ n += my_snprintf(b + n, blen - n, "%s Sense key "
+ "specific: ", lip);
+ n += decode_sks(lip, descp, add_d_len, sense_key, &processed,
+ blen - n, b + n);
+ }
+ n += my_snprintf(b + n, blen - n, "%s Field replaceable unit "
+ "code: 0x%x\n", lip, descp[7]);
+ if (0x80 & descp[2]) {
+ n += my_snprintf(b + n, blen - n, "%s Information: 0x",
+ lip);
+ for (j = 0; j < 8; ++j)
+ n += my_snprintf(b + n, blen - n, "%02x", descp[8 + j]);
+ n += my_snprintf(b + n, blen - n, "\n");
+ }
+ n += my_snprintf(b + n, blen - n, "%s Command specific: 0x",
+ lip);
+ for (j = 0; j < 8; ++j)
+ n += my_snprintf(b + n, blen - n, "%02x", descp[16 + j]);
+ n += my_snprintf(b + n, blen - n, "\n");
+ break;
+ case 0xe: /* Added in SPC-5 rev 6 (for bind/unbind) */
+ n += my_snprintf(b + n, blen - n, "Device designation\n");
+ j = (int)(sizeof(dd_usage_reason_str_arr) /
+ sizeof(dd_usage_reason_str_arr[0]));
+ if (descp[3] < j)
+ n += my_snprintf(b + n, blen - n, "%s Usage reason: %s\n",
+ lip, dd_usage_reason_str_arr[descp[3]]);
+ else
+ n += my_snprintf(b + n, blen - n, "%s Usage reason: "
+ "reserved[%d]\n", lip, descp[3]);
+ n += sg_get_designation_descriptor_str(z, descp + 4, descp[1] - 2,
+ 1, 0, blen - n, b + n);
+ break;
default:
if (descp[0] >= 0x80)
n += my_snprintf(b + n, blen - n, "Vendor specific [0x%x]\n",
@@ -823,43 +1367,48 @@ sg_get_sense_descriptors_str(const unsigned char * sense_buffer, int sb_len,
}
if (! processed) {
if (add_d_len > 0) {
- n += my_snprintf(b + n, blen - n, " ");
+ n += my_snprintf(b + n, blen - n, "%s ", lip);
for (j = 0; j < add_d_len; ++j) {
if ((j > 0) && (0 == (j % 24)))
- n += my_snprintf(b + n, blen - n, "\n ");
+ n += my_snprintf(b + n, blen - n, "\n%s ", lip);
n += my_snprintf(b + n, blen - n, "%02x ", descp[j + 2]);
}
n += my_snprintf(b + n, blen - n, "\n");
}
}
if (add_d_len < 0)
- n += my_snprintf(b + n, blen - n, " short descriptor\n");
+ n += my_snprintf(b + n, blen - n, "%s short descriptor\n", lip);
}
+ return n;
}
/* Decode SAT ATA PASS-THROUGH fixed format sense */
-static void
-sg_get_sense_sat_pt_fixed_str(const unsigned char * sp, int slen, int blen,
- char * b)
+static int
+sg_get_sense_sat_pt_fixed_str(const char * leadin, const unsigned char * sp,
+ int slen, int blen, char * b)
{
int n = 0;
+ const char * lip = "";
if ((blen < 1) || (slen < 12))
- return;
+ return n;
+ if (leadin)
+ lip = leadin;
if (SPC_SK_RECOVERED_ERROR != (0xf & sp[2]))
- n += my_snprintf(b + n, blen - n, " >> expected Sense key: "
- "Recovered Error ??\n");
- n += my_snprintf(b + n, blen - n, " error=0x%x, status=0x%x, "
- "device=0x%x, sector_count(7:0)=0x%x%c\n", sp[3], sp[4],
- sp[5], sp[6], ((0x40 & sp[8]) ? '+' : ' '));
- n += my_snprintf(b + n, blen - n, " extend=%d, log_index=0x%x, "
- "lba_high,mid,low(7:0)=0x%x,0x%x,0x%x%c\n",
+ n += my_snprintf(b + n, blen - n, "%s >> expected Sense key: "
+ "Recovered Error ??\n", lip);
+ n += my_snprintf(b + n, blen - n, "%s error=0x%x, status=0x%x, "
+ "device=0x%x, sector_count(7:0)=0x%x%c\n", lip, sp[3],
+ sp[4], sp[5], sp[6], ((0x40 & sp[8]) ? '+' : ' '));
+ n += my_snprintf(b + n, blen - n, "%s extend=%d, log_index=0x%x, "
+ "lba_high,mid,low(7:0)=0x%x,0x%x,0x%x%c\n", lip,
(!!(0x80 & sp[8])), (0xf & sp[8]), sp[9], sp[10], sp[11],
((0x20 & sp[8]) ? '+' : ' '));
+ return n;
}
/* Fetch sense information */
-void
+int
sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
int sb_len, int raw_sinfo, int buff_len, char * buff)
{
@@ -871,21 +1420,23 @@ sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
char error_buff[64];
char b[256];
struct sg_scsi_sense_hdr ssh;
+ const char * lip = "";
if ((NULL == buff) || (buff_len <= 0))
- return;
+ return 0;
else if (1 == buff_len) {
buff[0] = '\0';
- return;
+ return 0;
}
blen = sizeof(b);
n = 0;
+ if (leadin)
+ lip = leadin;
if ((NULL == sense_buffer) || (sb_len < 1)) {
- my_snprintf(buff, buff_len, "sense buffer empty\n");
- return;
+ n += my_snprintf(buff, buff_len, "%s >>> sense buffer empty\n",
+ lip);
+ return n;
}
- if (leadin)
- n += my_snprintf(buff + n, buff_len - n, "%s: ", leadin);
len = sb_len;
if (sg_scsi_normalize_sense(sense_buffer, sb_len, &ssh)) {
switch (ssh.response_code) {
@@ -921,34 +1472,34 @@ sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
ebp = error_buff;
break;
}
- n += my_snprintf(buff + n, buff_len - n, " %s; Sense key: %s\n ",
- ebp, sg_lib_sense_key_desc[ssh.sense_key]);
+ n += my_snprintf(buff + n, buff_len - n, "%s%s; Sense key: %s\n",
+ lip, ebp, sg_lib_sense_key_desc[ssh.sense_key]);
if (sdat_ovfl)
- n += my_snprintf(buff + n, buff_len - n, "<<<Sense data "
- "overflow>>>\n");
+ n += my_snprintf(buff + n, buff_len - n, "%s<<<Sense data "
+ "overflow>>>\n", lip);
if (descriptor_format) {
- n += my_snprintf(buff + n, buff_len - n, "%s\n",
+ n += my_snprintf(buff + n, buff_len - n, "%s%s\n", lip,
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
sizeof(b), b));
- sg_get_sense_descriptors_str(sense_buffer, len, buff_len - n,
- buff + n);
- n = strlen(buff);
+ n += sg_get_sense_descriptors_str(lip, sense_buffer, len,
+ buff_len - n, buff + n);
} else if ((len > 12) && (0 == ssh.asc) &&
(ASCQ_ATA_PT_INFO_AVAILABLE == ssh.ascq)) {
/* SAT ATA PASS-THROUGH fixed format */
- n += my_snprintf(buff + n, buff_len - n, "%s\n",
+ n += my_snprintf(buff + n, buff_len - n, "%s%s\n", lip,
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
sizeof(b), b));
- sg_get_sense_sat_pt_fixed_str(sense_buffer, len, buff_len - n,
- buff + n);
- n = strlen(buff);
+ n += sg_get_sense_sat_pt_fixed_str(lip, sense_buffer, len,
+ buff_len - n, buff + n);
} else if (len > 2) { /* fixed format */
if (len > 12)
- n += my_snprintf(buff + n, buff_len - n, "%s\n",
+ n += my_snprintf(buff + n, buff_len - n, "%s%s\n", lip,
sg_get_asc_ascq_str(ssh.asc, ssh.ascq,
sizeof(b), b));
r = 0;
valid = sense_buffer[0] & 0x80;
+ if (strlen(lip) > 0)
+ r += my_snprintf(b + r, blen - r, "%s", lip);
if (len > 6) {
info = sg_get_unaligned_be32(sense_buffer + 3);
if (valid)
@@ -973,14 +1524,14 @@ sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
} else if (valid || (info > 0))
r += my_snprintf(b + r, blen - r, "\n");
if ((len >= 14) && sense_buffer[14])
- r += my_snprintf(b + r, blen - r, " Field replaceable unit "
- "code: %d\n", sense_buffer[14]);
+ r += my_snprintf(b + r, blen - r, "%s Field replaceable unit "
+ "code: %d\n", lip, sense_buffer[14]);
if ((len >= 18) && (sense_buffer[15] & 0x80)) {
/* sense key specific decoding */
switch (ssh.sense_key) {
case SPC_SK_ILLEGAL_REQUEST:
- r += my_snprintf(b + r, blen - r, " Sense Key Specific: "
- "Error in %s: byte %d",
+ r += my_snprintf(b + r, blen - r, "%s Sense Key "
+ "Specific: Error in %s: byte %d", lip,
((sense_buffer[15] & 0x40) ? "Command" :
"Data parameters"),
sg_get_unaligned_be16(sense_buffer + 16));
@@ -995,18 +1546,19 @@ sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
progress = sg_get_unaligned_be16(sense_buffer + 16);
pr = (progress * 100) / 65536;
rem = ((progress * 100) % 65536) / 656;
- r += my_snprintf(b + r, blen - r, " Progress "
- "indication: %d.%02d%%\n", pr, rem);
+ r += my_snprintf(b + r, blen - r, "%s Progress "
+ "indication: %d.%02d%%\n", lip, pr, rem);
break;
case SPC_SK_HARDWARE_ERROR:
case SPC_SK_MEDIUM_ERROR:
case SPC_SK_RECOVERED_ERROR:
- r += my_snprintf(b + r, blen - r, " Actual retry count: "
- "0x%02x%02x\n", sense_buffer[16],
- sense_buffer[17]);
+ r += my_snprintf(b + r, blen - r, "%s Actual retry "
+ "count: " "0x%02x%02x\n", lip,
+ sense_buffer[16], sense_buffer[17]);
break;
case SPC_SK_COPY_ABORTED:
- r += my_snprintf(b + r, blen - r, " Segment pointer: ");
+ r += my_snprintf(b + r, blen - r, "%s Segment pointer: ",
+ lip);
r += my_snprintf(b + r, blen - r, "Relative to start of "
"%s, byte %d",
((sense_buffer[15] & 0x20) ?
@@ -1019,37 +1571,39 @@ sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
r += my_snprintf(b + r, blen - r, "\n");
break;
case SPC_SK_UNIT_ATTENTION:
- r += my_snprintf(b + r, blen - r, " Unit attention "
- "condition queue: ");
+ r += my_snprintf(b + r, blen - r, "%s Unit attention "
+ "condition queue: ", lip);
r += my_snprintf(b + r, blen - r, "overflow flag is %d\n",
!!(sense_buffer[15] & 0x1));
break;
default:
- r += my_snprintf(b + r, blen - r, " Sense_key: 0x%x "
- "unexpected\n", ssh.sense_key);
+ r += my_snprintf(b + r, blen - r, "%s Sense_key: 0x%x "
+ "unexpected\n", lip, ssh.sense_key);
break;
}
}
if (r > 0)
n += my_snprintf(buff + n, buff_len - n, "%s", b);
} else
- n += my_snprintf(buff + n, buff_len - n, " fixed descriptor "
- "length too short, len=%d\n", len);
+ n += my_snprintf(buff + n, buff_len - n, "%s fixed descriptor "
+ "length too short, len=%d\n", lip, len);
} else { /* non-extended SCSI-1 sense data ?? */
if (sb_len < 4) {
- n += my_snprintf(buff + n, buff_len - n, "sense buffer too short "
- "(4 byte minimum)\n");
- return;
+ n += my_snprintf(buff + n, buff_len - n, "%ssense buffer too "
+ "short (4 byte minimum)\n", lip);
+ return n;
}
r = 0;
- r += my_snprintf(b + r, blen - r, "Probably uninitialized data.\n "
- "Try to view as SCSI-1 non-extended sense:\n");
+ if (strlen(lip) > 0)
+ r += my_snprintf(b + r, blen - r, "%s", lip);
+ r += my_snprintf(b + r, blen - r, "Probably uninitialized data.\n%s "
+ "Try to view as SCSI-1 non-extended sense:\n", lip);
r += my_snprintf(b + r, blen - r, " AdValid=%d Error class=%d "
"Error code=%d\n", !!(sense_buffer[0] & 0x80),
((sense_buffer[0] >> 4) & 0x7),
(sense_buffer[0] & 0xf));
if (sense_buffer[0] & 0x80)
- r += my_snprintf(b + r, blen - r, " lba=0x%x\n",
+ r += my_snprintf(b + r, blen - r, "%s lba=0x%x\n", lip,
sg_get_unaligned_be24(sense_buffer + 1) & 0x1fffff);
n += my_snprintf(buff + n, buff_len - n, "%s\n", b);
len = sb_len;
@@ -1057,13 +1611,17 @@ sg_get_sense_str(const char * leadin, const unsigned char * sense_buffer,
len = 32; /* trim in case there is a lot of rubbish */
}
if (raw_sinfo) {
- n += my_snprintf(buff + n, buff_len - n, " Raw sense data (in hex):"
- "\n");
+ char z[64];
+
+ n += my_snprintf(buff + n, buff_len - n, "%s Raw sense data (in hex):"
+ "\n", lip);
if (n >= (buff_len - 1))
- return;
- dStrHexStr((const char *)sense_buffer, len, " ", 0,
- buff_len - n, buff + n);
+ return n;
+ snprintf(z, sizeof(z), "%.50s ", lip);
+ n += dStrHexStr((const char *)sense_buffer, len, z, 0,
+ buff_len - n, buff + n);
}
+ return n;
}
/* Print sense information */
@@ -1223,12 +1781,14 @@ static struct op_code2sa_t op_code2sa_arr[] = {
{SG_3PARTY_COPY_OUT, sg_lib_xcopy_sa_arr, NULL},
{SG_3PARTY_COPY_IN, sg_lib_rec_copy_sa_arr, NULL},
{SG_READ_BUFFER, sg_lib_read_buff_arr, "Read buffer"},
- {SG_WRITE_BUFFER, sg_lib_write_buff_arr, "Write buffer"},
+ {SG_READ_ATTRIBUTE, sg_lib_read_attr_arr, "Read attribute"},
{SG_SANITIZE, sg_lib_sanitize_sa_arr, "Sanitize"},
+ {SG_WRITE_BUFFER, sg_lib_write_buff_arr, "Write buffer"},
+ {SG_ZONING_IN, sg_lib_zoning_in_arr, NULL},
+ {SG_ZONING_OUT, sg_lib_zoning_out_arr, NULL},
{0xffff, NULL, NULL},
};
-
void
sg_get_opcode_sa_name(unsigned char cmd_byte0, int service_action,
int peri_type, int buff_len, char * buff)
@@ -1653,8 +2213,9 @@ dStrHexErr(const char* str, int len, int no_ascii)
* separated) to 'b' not to exceed 'b_len' characters. Each line
* starts with 'leadin' (NULL for no leadin) and there are 16 bytes
* per line with an extra space between the 8th and 9th bytes. 'format'
- * is unused (currently), set to 0 . */
-void
+ * is unused (currently), set to 0 . Returns number of bytes written
+ * to 'b' excluding the trailing '\0'. */
+int
dStrHexStr(const char* str, int len, const char * leadin, int format,
int b_len, char * b)
{
@@ -1666,7 +2227,7 @@ dStrHexStr(const char* str, int len, const char * leadin, int format,
if (len <= 0) {
if (b_len > 0)
b[0] = '\0';
- return;
+ return 0;
}
if (0 != format) {
; /* do nothing different for now */
@@ -1695,7 +2256,7 @@ dStrHexStr(const char* str, int len, const char * leadin, int format,
trimTrailingSpaces(buff);
n += my_snprintf(b + n, b_len - n, "%s\n", buff);
if (n >= (b_len - 1))
- return;
+ return n;
bpos = bpstart;
memset(buff, ' ', 120);
if (bpstart > 0)
@@ -1707,7 +2268,7 @@ dStrHexStr(const char* str, int len, const char * leadin, int format,
trimTrailingSpaces(buff);
n += my_snprintf(b + n, b_len - n, "%s\n", buff);
}
- return;
+ return n;
}
/* Returns 1 when executed on big endian machine; else returns 0.
diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c
index 99a34e23..e83f7095 100644
--- a/lib/sg_lib_data.c
+++ b/lib/sg_lib_data.c
@@ -477,6 +477,16 @@ struct sg_lib_value_name_t sg_lib_zoning_in_arr[] = {
{0xffff, 0, NULL},
};
+/* Read attribute [0x8c] service actions */
+struct sg_lib_value_name_t sg_lib_read_attr_arr[] = {
+ {0x0, 0, "attribute values"},
+ {0x1, 0, "attribute list"},
+ {0x2, 0, "logical volume list"},
+ {0x3, 0, "partition list"},
+ {0x5, 0, "supported attributes"},
+ {0xffff, 0, NULL},
+};
+
#else /* SG_SCSI_STRINGS */
struct sg_lib_value_name_t sg_lib_normal_opcodes[] = {
@@ -551,6 +561,10 @@ struct sg_lib_value_name_t sg_lib_zoning_in_arr[] = {
{0xffff, 0, NULL},
};
+struct sg_lib_value_name_t sg_lib_read_attr_arr[] = {
+ {0xffff, 0, NULL},
+};
+
#endif /* SG_SCSI_STRINGS */
/* A conveniently formatted list of SCSI ASC/ASCQ codes and their
diff --git a/sg3_utils.spec b/sg3_utils.spec
index 792c49cd..ed320385 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,7 +79,7 @@ fi
%{_libdir}/*.la
%changelog
-* Sun Jan 03 2016 - dgilbert at interlog dot com
+* Wed Jan 27 2016 - dgilbert at interlog dot com
- track t10 changes
* sg3_utils-1.42
diff --git a/src/sg_compare_and_write.c b/src/sg_compare_and_write.c
index e36a18ba..c274403f 100644
--- a/src/sg_compare_and_write.c
+++ b/src/sg_compare_and_write.c
@@ -1,5 +1,5 @@
/*
-* Copyright (c) 2012-2015, Kaminario Technologies LTD
+* Copyright (c) 2012-2016, Kaminario Technologies LTD
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
@@ -31,7 +31,7 @@
#ifndef __sun
#define _XOPEN_SOURCE 500
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#endif
@@ -53,7 +53,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.13 20151219";
+static const char * version_str = "1.14 20160121";
#define DEF_BLOCK_SIZE 512
#define DEF_NUM_BLOCKS (1)
diff --git a/src/sg_dd.c b/src/sg_dd.c
index d1880048..b0370a5a 100644
--- a/src/sg_dd.c
+++ b/src/sg_dd.c
@@ -1,7 +1,7 @@
/* A utility program for copying files. Specialised for "files" that
* represent devices that understand the SCSI command set.
*
- * Copyright (C) 1999 - 2015 D. Gilbert and P. Allworth
+ * Copyright (C) 1999 - 2016 D. Gilbert and P. Allworth
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -27,7 +27,7 @@
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE /* resolves u_char typedef in scsi/scsi.h [lk 2.4] */
+#define _GNU_SOURCE 1
#endif
#include <unistd.h>
diff --git a/src/sg_format.c b/src/sg_format.c
index f4b653b8..f8b84fef 100644
--- a/src/sg_format.c
+++ b/src/sg_format.c
@@ -6,7 +6,7 @@
*
* Copyright (C) 2003 Grant Grundler grundler at parisc-linux dot org
* Copyright (C) 2003 James Bottomley jejb at parisc-linux dot org
- * Copyright (C) 2005-2015 Douglas Gilbert dgilbert at interlog dot com
+ * Copyright (C) 2005-2016 Douglas Gilbert dgilbert at interlog dot com
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
@@ -34,7 +35,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.32 20151219";
+static const char * version_str = "1.33 20160123";
#define RW_ERROR_RECOVERY_PAGE 1 /* can give alternate with --mode=MP */
@@ -57,6 +58,31 @@ static const char * version_str = "1.32 20151219";
#define sleep_for(seconds) sleep(seconds)
#endif
+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 fmtpinfo;
+ int format; /* -F */
+ bool fwait; /* -w (negate for immed) */
+ bool ip_def; /* -I */
+ bool long_lba; /* -l */
+ int mode_page; /* -M value */
+ bool mode6; /* -6 */
+ int pfu; /* -P value */
+ int pie; /* -q value */
+ bool pinfo; /* -p, deprecated, prefer fmtpinfo */
+ int pollt; /* -x value */
+ bool do_rcap16; /* -l */
+ bool resize; /* -r */
+ bool rto_req; /* -R, deprecated, prefer fmtpinfo */
+ int sec_init; /* -S */
+ int verbose; /* -v */
+ const char * device_name;
+};
#define MAX_BUFF_SZ 252
static unsigned char dbuff[MAX_BUFF_SZ];
@@ -67,6 +93,7 @@ static struct option long_options[] = {
{"cmplst", required_argument, 0, 'C'},
{"dcrt", no_argument, 0, 'D'},
{"early", no_argument, 0, 'e'},
+ {"ffmt", required_argument, 0, 't'},
{"fmtpinfo", required_argument, 0, 'f'},
{"format", no_argument, 0, 'F'},
{"help", no_argument, 0, 'h'},
@@ -94,13 +121,14 @@ usage()
{
printf("usage: sg_format [--cmplst=0|1] [--count=COUNT] [--dcrt] "
"[--early]\n"
- " [--fmtpinfo=FPI] [--format] [--help] "
- "[--ip_def] [--long]\n"
- " [--mode=MP] [--pfu=PFU] [--pie=PIE] "
- "[--pinfo] [--poll=PT]\n"
- " [--resize] [--rto_req] [--security] "
- "[--six] [--size=SIZE]\n"
- " [--verbose] [--version] [--wait] DEVICE\n"
+ " [--ffmt] [--fmtpinfo=FPI] [--format] "
+ "[--help] [--ip_def]\n"
+ " [--long] [--mode=MP] [--pfu=PFU] "
+ "[--pie=PIE] [--pinfo]\n"
+ " [--poll=PT] [--resize] [--rto_req] "
+ "[--security] [--six]\n"
+ " [--size=SIZE] [--verbose] [--version] "
+ "[--wait] DEVICE\n"
" where:\n"
" --cmplst=0|1\n"
" -C 0|1 sets CMPLST bit in format cdb "
@@ -113,6 +141,9 @@ usage()
"verify media)\n"
" --early|-e exit once format started (user can "
"monitor progress)\n"
+ " --ffmt=FFMT|-t FFMT fast format (def: 0 -> "
+ "possibly write\n"
+ " to whole medium\n"
" --fmtpinfo=FPI|-f FPI FMTPINFO field value "
"(default: 0)\n"
" --format|-F format unit (default: report current "
@@ -162,14 +193,13 @@ usage()
"have the correct DEVICE.\n");
}
-/* Return 0 on success, else see sg_ll_format_unit() */
+/* Return 0 on success, else see sg_ll_format_unit2() */
static int
-scsi_format(int fd, int fmtpinfo, int cmplst, int pf_usage, int immed,
- int dcrt, int pie, int ip_def, int sec_init, int early, int pt,
- int verbose)
+scsi_format(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;
+ int immed = ! op->fwait;
const int SH_FORMAT_HEADER_SZ = 4;
const int LO_FORMAT_HEADER_SZ = 8;
const char INIT_PATTERN_DESC_SZ = 4;
@@ -178,34 +208,35 @@ scsi_format(int fd, int fmtpinfo, int cmplst, int pf_usage, int immed,
char b[80];
memset(fmt_pl, 0, sizeof(fmt_pl));
- longlist = (pie > 0);
- ip_desc = (ip_def || sec_init);
+ longlist = (op->pie > 0);
+ ip_desc = (op->ip_def || op->sec_init);
off = longlist ? LO_FORMAT_HEADER_SZ : SH_FORMAT_HEADER_SZ;
- fmt_pl[0] = pf_usage & 0x7; /* PROTECTION_FIELD_USAGE (bits 2-0) */
+ fmt_pl[0] = op->pfu & 0x7; /* PROTECTION_FIELD_USAGE (bits 2-0) */
fmt_pl[1] = (immed ? 0x2 : 0); /* FOV=0, [DPRY,DCRT,STPF,IP=0] */
- if (dcrt)
+ if (op->dcrt)
fmt_pl[1] |= 0xa0; /* FOV=1, DCRT=1 */
if (ip_desc) {
fmt_pl[1] |= 0x88; /* FOV=1, IP=1 */
- if (sec_init)
+ if (op->sec_init)
fmt_pl[off + 0] = 0x20; /* SI=1 in IP desc */
}
if (longlist)
- fmt_pl[3] = (pie & 0xf); /* PROTECTION_INTERVAL_EXPONENT */
+ fmt_pl[3] = (op->pie & 0xf);/* PROTECTION_INTERVAL_EXPONENT */
/* with the long parameter list header, P_I_INFORMATION is always 0 */
- need_hdr = (immed || cmplst || dcrt || ip_desc || (pf_usage > 0) ||
- (pie > 0));
+ need_hdr = (immed || op->cmplst || op->dcrt || ip_desc ||
+ (op->pfu > 0) || (op->pie > 0));
fmt_pl_sz = 0;
if (need_hdr)
fmt_pl_sz = off + (ip_desc ? INIT_PATTERN_DESC_SZ : 0);
- res = sg_ll_format_unit(fd, fmtpinfo, longlist, need_hdr /* FMTDATA*/,
- cmplst, 0 /* DEFECT_LIST_FORMAT */,
- (immed ? SHORT_TIMEOUT : FORMAT_TIMEOUT),
- fmt_pl, fmt_pl_sz, 1, verbose);
+ res = sg_ll_format_unit2(fd, op->fmtpinfo, longlist,
+ need_hdr/* FMTDATA*/, op->cmplst,
+ 0 /* DEFECT_LIST_FORMAT */, op->ffmt,
+ (immed ? SHORT_TIMEOUT : FORMAT_TIMEOUT),
+ fmt_pl, fmt_pl_sz, 1, op->verbose);
if (res) {
- sg_get_category_sense_str(res, sizeof(b), b, verbose);
+ sg_get_category_sense_str(res, sizeof(b), b, op->verbose);
pr2serr("Format command: %s\n", b);
return res;
}
@@ -213,7 +244,7 @@ scsi_format(int fd, int fmtpinfo, int cmplst, int pf_usage, int immed,
return 0;
printf("\nFormat has started\n");
- if (early) {
+ if (op->early) {
if (immed)
printf("Format continuing,\n request sense or "
"test unit ready can be used to monitor "
@@ -221,8 +252,8 @@ scsi_format(int fd, int fmtpinfo, int cmplst, int pf_usage, int immed,
return 0;
}
- verb = (verbose > 1) ? (verbose - 1) : 0;
- if (0 == pt) {
+ verb = (op->verbose > 1) ? (op->verbose - 1) : 0;
+ if (0 == op->pollt) {
for(;;) {
sleep_for(POLL_DURATION_SECS);
progress = -1;
@@ -237,7 +268,7 @@ scsi_format(int fd, int fmtpinfo, int cmplst, int pf_usage, int immed,
break;
}
}
- if (pt || (SG_LIB_CAT_NOT_READY == res)) {
+ if (op->pollt || (SG_LIB_CAT_NOT_READY == res)) {
for(;;) {
sleep_for(POLL_DURATION_SECS);
memset(reqSense, 0x0, sizeof(reqSense));
@@ -272,16 +303,16 @@ scsi_format(int fd, int fmtpinfo, int cmplst, int pf_usage, int immed,
sleep_for(30);
memset(requestSenseBuff, 0x0, sizeof(requestSenseBuff));
res = sg_ll_request_sense(sg_fd, desc, requestSenseBuff, maxlen,
- 1, verbose);
+ 1, op->verbose);
if (res) {
ret = res;
- sg_get_category_sense_str(res, sizeof(b), b, verbose);
+ sg_get_category_sense_str(res, sizeof(b), b, op->verbose);
pr2serr("Request Sense command: %s\n", b);
break;
}
/* "Additional sense length" same in descriptor and fixed */
resp_len = requestSenseBuff[7] + 8;
- if (verbose > 1) {
+ if (op->verbose > 1) {
pr2serr("Parameter data in hex\n");
dStrHexErr((const char *)requestSenseBuff, resp_len, 1);
}
@@ -290,7 +321,7 @@ scsi_format(int fd, int fmtpinfo, int cmplst, int pf_usage, int immed,
&progress);
if (progress < 0) {
ret = res;
- if (verbose > 1)
+ if (op->verbose > 1)
pr2serr("No progress indication found, iteration %d\n",
k + 1);
/* N.B. exits first time there isn't a progress indication */
@@ -371,14 +402,15 @@ get_lu_name(const unsigned char * ucp, int u_len, char * b, int b_len)
#define VPD_DEVICE_ID 0x83
static int
-print_dev_id(int fd, unsigned char * sinq_resp, int max_rlen, int verbose)
+print_dev_id(int fd, unsigned char * sinq_resp, int max_rlen,
+ const struct opts_t * op)
{
int res, k, n, verb, pdt, has_sn, has_di;
unsigned char b[256];
char a[256];
char pdt_name[64];
- verb = (verbose > 1) ? verbose - 1 : 0;
+ verb = (op->verbose > 1) ? op->verbose - 1 : 0;
memset(sinq_resp, 0, max_rlen);
res = sg_ll_inquiry(fd, 0, 0 /* evpd */, 0 /* pg_op */, b,
SAFE_STD_INQ_RESP_LEN, 1, verb);
@@ -394,7 +426,7 @@ print_dev_id(int fd, unsigned char * sinq_resp, int max_rlen, int verbose)
(const char *)(b + 8), (const char *)(b + 16),
(const char *)(b + 32),
sg_get_pdt_str(pdt, sizeof(pdt_name), pdt_name), pdt);
- if (verbose)
+ if (op->verbose)
printf(" PROTECT=%d\n", !!(b[5] & 1));
if (b[5] & 1)
printf(" << supports protection information>>"
@@ -407,12 +439,12 @@ print_dev_id(int fd, unsigned char * sinq_resp, int max_rlen, int verbose)
res = sg_ll_inquiry(fd, 0, 1 /* evpd */, VPD_SUPPORTED_VPDS, b,
SAFE_STD_INQ_RESP_LEN, 1, verb);
if (res) {
- if (verbose)
+ if (op->verbose)
pr2serr("VPD_SUPPORTED_VPDS gave res=%d\n", res);
return 0;
}
if (VPD_SUPPORTED_VPDS != b[1]) {
- if (verbose)
+ if (op->verbose)
pr2serr("VPD_SUPPORTED_VPDS corrupted\n");
return 0;
}
@@ -422,7 +454,7 @@ print_dev_id(int fd, unsigned char * sinq_resp, int max_rlen, int verbose)
for (k = 0, has_sn = 0, has_di = 0; k < n; ++k) {
if (VPD_UNIT_SERIAL_NUM == b[4 + k]) {
if (has_di) {
- if (verbose)
+ if (op->verbose)
pr2serr("VPD_SUPPORTED_VPDS "
"dis-ordered\n");
return 0;
@@ -437,13 +469,13 @@ print_dev_id(int fd, unsigned char * sinq_resp, int max_rlen, int verbose)
res = sg_ll_inquiry(fd, 0, 1 /* evpd */, VPD_UNIT_SERIAL_NUM,
b, sizeof(b), 1, verb);
if (res) {
- if (verbose)
+ if (op->verbose)
pr2serr("VPD_UNIT_SERIAL_NUM gave res=%d\n",
res);
return 0;
}
if (VPD_UNIT_SERIAL_NUM != b[1]) {
- if (verbose)
+ if (op->verbose)
pr2serr("VPD_UNIT_SERIAL_NUM corrupted\n");
return 0;
}
@@ -457,12 +489,12 @@ print_dev_id(int fd, unsigned char * sinq_resp, int max_rlen, int verbose)
res = sg_ll_inquiry(fd, 0, 1 /* evpd */, VPD_DEVICE_ID, b,
sizeof(b), 1, verb);
if (res) {
- if (verbose)
+ if (op->verbose)
pr2serr("VPD_DEVICE_ID gave res=%d\n", res);
return 0;
}
if (VPD_DEVICE_ID != b[1]) {
- if (verbose)
+ if (op->verbose)
pr2serr("VPD_DEVICE_ID corrupted\n");
return 0;
}
@@ -481,7 +513,7 @@ print_dev_id(int fd, unsigned char * sinq_resp, int max_rlen, int verbose)
/* Returns block size or -2 if do_16==0 and the number of blocks is too
* big, or returns -1 for other error. */
static int
-print_read_cap(int fd, int do_16, int verbose)
+print_read_cap(int fd, const struct opts_t * op)
{
int res;
unsigned char resp_buff[RCAP_REPLY_LEN];
@@ -489,9 +521,9 @@ print_read_cap(int fd, int do_16, int verbose)
uint64_t llast_blk_addr;
char b[80];
- if (do_16) {
+ if (op->do_rcap16) {
res = sg_ll_readcap_16(fd, 0 /* pmi */, 0 /* llba */,
- resp_buff, 32, 1, verbose);
+ resp_buff, 32, 1, op->verbose);
if (0 == res) {
llast_blk_addr = sg_get_unaligned_be64(resp_buff + 0);
block_size = sg_get_unaligned_be32(resp_buff + 8);
@@ -517,12 +549,12 @@ print_read_cap(int fd, int do_16, int verbose)
}
} else {
res = sg_ll_readcap_10(fd, 0 /* pmi */, 0 /* lba */,
- resp_buff, 8, 1, verbose);
+ resp_buff, 8, 1, op->verbose);
if (0 == res) {
last_blk_addr = sg_get_unaligned_be32(resp_buff + 0);
block_size = sg_get_unaligned_be32(resp_buff + 4);
if (0xffffffff == last_blk_addr) {
- if (verbose)
+ if (op->verbose)
printf("Read Capacity (10) reponse "
"indicates that Read Capacity (16) "
"is required\n");
@@ -536,8 +568,8 @@ print_read_cap(int fd, int do_16, int verbose)
return (int)block_size;
}
}
- sg_get_category_sense_str(res, sizeof(b), b, verbose);
- pr2serr("READ CAPACITY (%d): %s\n", (do_16 ? 16 : 10), b);
+ sg_get_category_sense_str(res, sizeof(b), b, op->verbose);
+ pr2serr("READ CAPACITY (%d): %s\n", (op->do_rcap16 ? 16 : 10), b);
return -1;
}
@@ -545,40 +577,25 @@ print_read_cap(int fd, int do_16, int verbose)
int
main(int argc, char **argv)
{
- int mode_page = RW_ERROR_RECOVERY_PAGE;
int fd, res, calc_len, bd_len, dev_specific_param;
- int offset, j, bd_blk_len, prob, len, pdt;
+ int offset, j, n, bd_blk_len, prob, len, pdt;
uint64_t ull;
- int64_t blk_count = 0; /* -c value */
- int blk_size = 0; /* -s value */
- int format = 0; /* -F */
- int ip_def = 0; /* -I */
- int resize = 0; /* -r */
- int verbose = 0; /* -v */
- int fwait = 0; /* -w */
- int mode6 = 0;
- int fmtpinfo = 0;
- int pinfo = 0; /* deprecated, prefer fmtpinfo */
- int pie = 0;
- int pfu = 0;
- int pt = DEF_POLL_TYPE;
- int rto_req = 0; /* deprecated, prefer fmtpinfo */
- int cmplst = 1;
- int do_rcap16 = 0;
- int long_lba = 0;
- int dcrt = 0;
- int do_si = 0;
- int early = 0;
- const char * device_name = NULL;
char b[80];
unsigned char inq_resp[SAFE_STD_INQ_RESP_LEN];
int ret = 0;
+ struct opts_t opts;
+ struct opts_t * op;
+ op = &opts;
+ memset(op, 0, sizeof(opts));
+ op->cmplst = 1;
+ op->mode_page = RW_ERROR_RECOVERY_PAGE;
+ op->pollt = DEF_POLL_TYPE;
while (1) {
int option_index = 0;
int c;
- c = getopt_long(argc, argv, "c:C:Def:FhIlM:pP:q:rRs:SvVwx:6",
+ c = getopt_long(argc, argv, "c:C:Def:FhIlM:pP:q:rRs:St:vVwx:6",
long_options, &option_index);
if (c == -1)
break;
@@ -586,108 +603,116 @@ main(int argc, char **argv)
switch (c) {
case 'c':
if (0 == strcmp("-1", optarg))
- blk_count = -1;
+ op->blk_count = -1;
else {
- blk_count = sg_get_llnum(optarg);
- if (-1 == blk_count) {
+ op->blk_count = sg_get_llnum(optarg);
+ if (-1 == op->blk_count) {
pr2serr("bad argument to '--count'\n");
return SG_LIB_SYNTAX_ERROR;
}
}
break;
case 'C':
- cmplst = sg_get_num(optarg);
- if ((cmplst < 0) || ( cmplst > 1)) {
+ op->cmplst = sg_get_num(optarg);
+ if ((op->cmplst < 0) || (op->cmplst > 1)) {
pr2serr("bad argument to '--cmplst', want 0 "
"or 1\n");
return SG_LIB_SYNTAX_ERROR;
}
break;
case 'D':
- dcrt = 1;
+ op->dcrt = 1;
break;
case 'e':
- early = 1;
+ op->early = true;
break;
case 'f':
- fmtpinfo = sg_get_num(optarg);
- if ((fmtpinfo < 0) || ( fmtpinfo > 3)) {
+ op->fmtpinfo = sg_get_num(optarg);
+ if ((op->fmtpinfo < 0) || ( op->fmtpinfo > 3)) {
pr2serr("bad argument to '--fmtpinfo', "
"accepts 0 to 3 inclusive\n");
return SG_LIB_SYNTAX_ERROR;
}
break;
case 'F':
- ++format;
+ ++op->format;
break;
case 'h':
usage();
return 0;
case 'I':
- ip_def = 1;
+ op->ip_def = true;
break;
case 'l':
- long_lba = 1;
- do_rcap16 = 1;
+ op->long_lba = true;
+ op->do_rcap16 = true;
break;
case 'M':
- mode_page = sg_get_num(optarg);
- if ((mode_page < 0) || ( mode_page > 62)) {
+ op->mode_page = sg_get_num(optarg);
+ if ((op->mode_page < 0) || ( op->mode_page > 62)) {
pr2serr("bad argument to '--mode', accepts "
"0 to 62 inclusive\n");
return SG_LIB_SYNTAX_ERROR;
}
break;
case 'p':
- pinfo = 1;
+ op->pinfo = true;
break;
case 'P':
- pfu = sg_get_num(optarg);
- if ((pfu < 0) || ( pfu > 7)) {
+ op->pfu = sg_get_num(optarg);
+ if ((op->pfu < 0) || ( op->pfu > 7)) {
pr2serr("bad argument to '--pfu', accepts 0 "
"to 7 inclusive\n");
return SG_LIB_SYNTAX_ERROR;
}
break;
case 'q':
- pie = sg_get_num(optarg);
- if ((pie < 0) || ( pie > 15)) {
+ op->pie = sg_get_num(optarg);
+ if ((op->pie < 0) || (op->pie > 15)) {
pr2serr("bad argument to '--pie', accepts 0 "
"to 15 inclusive\n");
return SG_LIB_SYNTAX_ERROR;
}
break;
case 'r':
- resize = 1;
+ op->resize = true;
break;
case 'R':
- rto_req = 1;
+ op->rto_req = true;
break;
case 's':
- blk_size = sg_get_num(optarg);
- if (blk_size <= 0) {
+ op->blk_size = sg_get_num(optarg);
+ if (op->blk_size <= 0) {
pr2serr("bad argument to '--size', want arg "
"> 0\n");
return SG_LIB_SYNTAX_ERROR;
}
break;
case 'S':
- do_si = 1;
+ op->sec_init = true;
+ break;
+ case 't':
+ op->ffmt = sg_get_num(optarg);
+ if ((op->ffmt < 0) || ( op->ffmt > 3)) {
+ pr2serr("bad argument to '--ffmt', "
+ "accepts 0 to 3 inclusive\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
break;
case 'v':
- verbose++;
+ op->verbose++;
break;
case 'V':
pr2serr("sg_format version: %s\n", version_str);
return 0;
case 'w':
- fwait = 1;
+ op->fwait = true;
break;
case 'x':
- pt = !!sg_get_num(optarg);
+ op->pollt = !!sg_get_num(optarg);
break;
case '6':
- mode6 = 1;
+ op->mode6 = true;
break;
default:
usage();
@@ -695,8 +720,8 @@ main(int argc, char **argv)
}
}
if (optind < argc) {
- if (NULL == device_name) {
- device_name = argv[optind];
+ if (NULL == op->device_name) {
+ op->device_name = argv[optind];
++optind;
}
}
@@ -707,57 +732,58 @@ main(int argc, char **argv)
usage();
return SG_LIB_SYNTAX_ERROR;
}
- if (NULL == device_name) {
+ if (NULL == op->device_name) {
pr2serr("no DEVICE name given\n");
usage();
return SG_LIB_SYNTAX_ERROR;
}
- if (ip_def && do_si) {
+ if (op->ip_def && op->sec_init) {
pr2serr("'--ip_def' and '--security' contradict, choose "
"one\n");
return SG_LIB_SYNTAX_ERROR;
}
- if (resize) {
- if (format) {
+ if (op->resize) {
+ if (op->format) {
pr2serr("both '--format' and '--resize' not "
"permitted\n");
usage();
return SG_LIB_SYNTAX_ERROR;
- } else if (0 == blk_count) {
+ } else if (0 == op->blk_count) {
pr2serr("'--resize' needs a '--count' (other than "
"0)\n");
usage();
return SG_LIB_SYNTAX_ERROR;
- } else if (0 != blk_size) {
+ } else if (0 != op->blk_size) {
pr2serr("'--resize' not compatible with '--size'\n");
usage();
return SG_LIB_SYNTAX_ERROR;
}
}
- if ((pinfo > 0) || (rto_req > 0) || (fmtpinfo > 0)) {
- if ((pinfo || rto_req) && fmtpinfo) {
+ if ((op->pinfo > 0) || (op->rto_req > 0) || (op->fmtpinfo > 0)) {
+ if ((op->pinfo || op->rto_req) && op->fmtpinfo) {
pr2serr("confusing with both '--pinfo' or "
"'--rto_req' together with\n'--fmtpinfo', "
"best use '--fmtpinfo' only\n");
usage();
return SG_LIB_SYNTAX_ERROR;
}
- if (pinfo)
- fmtpinfo |= 2;
- if (rto_req)
- fmtpinfo |= 1;
+ if (op->pinfo)
+ op->fmtpinfo |= 2;
+ if (op->rto_req)
+ op->fmtpinfo |= 1;
}
- if ((fd = sg_cmds_open_device(device_name, 0 /* rw */, verbose)) < 0) {
- pr2serr("error opening device file: %s: %s\n", device_name,
- safe_strerror(-fd));
+ if ((fd = sg_cmds_open_device(op->device_name, 0 /* read write */,
+ op->verbose)) < 0) {
+ pr2serr("error opening device file: %s: %s\n",
+ op->device_name, safe_strerror(-fd));
return SG_LIB_FILE_ERROR;
}
- if (format > 2)
+ if (op->format > 2)
goto format_only;
- ret = print_dev_id(fd, inq_resp, sizeof(inq_resp), verbose);
+ ret = print_dev_id(fd, inq_resp, sizeof(inq_resp), op);
if (ret)
goto out;
pdt = 0x1f & inq_resp[0];
@@ -770,40 +796,41 @@ main(int argc, char **argv)
again_with_long_lba:
memset(dbuff, 0, MAX_BUFF_SZ);
- if (mode6)
+ if (op->mode6)
res = sg_ll_mode_sense6(fd, 0 /* DBD */, 0 /* current */,
- mode_page, 0 /* subpage */, dbuff,
- MAX_BUFF_SZ, 1, verbose);
+ op->mode_page, 0 /* subpage */, dbuff,
+ MAX_BUFF_SZ, 1, op->verbose);
else
- res = sg_ll_mode_sense10(fd, long_lba, 0 /* DBD */,
- 0 /* current */, mode_page,
+ res = sg_ll_mode_sense10(fd, op->long_lba, 0 /* DBD */,
+ 0 /* current */, op->mode_page,
0 /* subpage */, dbuff,
- MAX_BUFF_SZ, 1, verbose);
+ MAX_BUFF_SZ, 1, op->verbose);
ret = res;
if (res) {
if (SG_LIB_CAT_ILLEGAL_REQ == res) {
- if (long_lba && (! mode6))
+ if (op->long_lba && (! op->mode6))
pr2serr("bad field in MODE SENSE (%d) "
"[longlba flag not supported?]\n",
- (mode6 ? 6 : 10));
+ (op->mode6 ? 6 : 10));
else
pr2serr("bad field in MODE SENSE (%d) "
"[mode_page %d not supported?]\n",
- (mode6 ? 6 : 10), mode_page);
+ (op->mode6 ? 6 : 10), op->mode_page);
} else {
- sg_get_category_sense_str(res, sizeof(b), b, verbose);
+ sg_get_category_sense_str(res, sizeof(b), b,
+ op->verbose);
pr2serr("MODE SENSE (%d) command: %s\n",
- (mode6 ? 6 : 10), b);
+ (op->mode6 ? 6 : 10), b);
}
- if (0 == verbose)
+ if (0 == op->verbose)
pr2serr(" try '-v' for more information\n");
goto out;
}
- if (mode6) {
+ if (op->mode6) {
calc_len = dbuff[0] + 1;
dev_specific_param = dbuff[2];
bd_len = dbuff[3];
- long_lba = 0;
+ op->long_lba = 0;
offset = 4;
/* prepare for mode select */
dbuff[0] = 0;
@@ -813,7 +840,7 @@ again_with_long_lba:
calc_len = sg_get_unaligned_be16(dbuff + 0);
dev_specific_param = dbuff[3];
bd_len = sg_get_unaligned_be16(dbuff + 6);
- long_lba = (dbuff[4] & 1);
+ op->long_lba = (dbuff[4] & 1);
offset = 8;
/* prepare for mode select */
dbuff[0] = 0;
@@ -829,21 +856,21 @@ again_with_long_lba:
if (dev_specific_param & 0x40)
printf(" <<< Write Protect (WP) bit set >>>\n");
if (bd_len > 0) {
- ull = long_lba ? sg_get_unaligned_be64(dbuff + offset) :
+ ull = op->long_lba ? sg_get_unaligned_be64(dbuff + offset) :
sg_get_unaligned_be32(dbuff + offset);
- if ((0 == long_lba) && (0xffffffff == ull)) {
- if (verbose)
+ if ((0 == op->long_lba) && (0xffffffff == ull)) {
+ if (op->verbose)
pr2serr("Mode sense number of blocks maxed "
"out, set longlba\n");
- long_lba = 1;
- mode6 = 0;
- do_rcap16 = 1;
+ op->long_lba = 1;
+ op->mode6 = 0;
+ op->do_rcap16 = 1;
goto again_with_long_lba;
}
- bd_blk_len = long_lba ?
+ bd_blk_len = op->long_lba ?
sg_get_unaligned_be32(dbuff + offset + 12) :
sg_get_unaligned_be24(dbuff + offset + 5);
- if (long_lba) {
+ if (op->long_lba) {
printf(" <<< longlba flag set (64 bit lba) >>>\n");
if (bd_len != 16)
prob = 1;
@@ -856,9 +883,8 @@ again_with_long_lba:
printf(" No block descriptors present\n");
prob = 1;
}
- if (resize ||
- (format && ((blk_count != 0) ||
- ((blk_size > 0) && (blk_size != bd_blk_len))))) {
+ if (op->resize || (op->format && ((op->blk_count != 0) ||
+ ((op->blk_size > 0) && (op->blk_size != bd_blk_len))))) {
/* want to run MODE SELECT */
/* Working Draft SCSI Primary Commands - 3 (SPC-3) pg 255
@@ -902,48 +928,52 @@ again_with_long_lba:
ret = SG_LIB_CAT_MALFORMED;
goto out;
}
- if (blk_count != 0) {
- len = (long_lba ? 8 : 4);
- for (j = 0; j < len; ++j)
+ if (op->blk_count != 0) {
+ len = (op->long_lba ? 8 : 4);
+ for (j = 0; j < len; ++j) {
+ n = (len - j - 1) * 8;
dbuff[offset + j] =
- (blk_count >> ((len - j - 1) * 8)) & 0xff;
- } else if ((blk_size > 0) && (blk_size != bd_blk_len)) {
- len = (long_lba ? 8 : 4);
+ (op->blk_count >> n) & 0xff;
+ }
+ } else if ((op->blk_size > 0) &&
+ (op->blk_size != bd_blk_len)) {
+ len = (op->long_lba ? 8 : 4);
for (j = 0; j < len; ++j)
dbuff[offset + j] = 0;
}
- if ((blk_size > 0) && (blk_size != bd_blk_len)) {
- if (long_lba)
- sg_put_unaligned_be32((uint32_t)blk_size,
+ if ((op->blk_size > 0) && (op->blk_size != bd_blk_len)) {
+ if (op->long_lba)
+ sg_put_unaligned_be32((uint32_t)op->blk_size,
dbuff + offset + 12);
else
- sg_put_unaligned_be24((uint32_t)blk_size,
+ sg_put_unaligned_be24((uint32_t)op->blk_size,
dbuff + offset + 5);
}
- if (mode6)
+ if (op->mode6)
res = sg_ll_mode_select6(fd, 1 /* PF */, 1 /* SP */,
- dbuff, calc_len, 1, verbose);
+ dbuff, calc_len, 1, op->verbose);
else
res = sg_ll_mode_select10(fd, 1 /* PF */, 1 /* SP */,
- dbuff, calc_len, 1, verbose);
+ dbuff, calc_len, 1, op->verbose);
ret = res;
if (res) {
- sg_get_category_sense_str(res, sizeof(b), b, verbose);
+ sg_get_category_sense_str(res, sizeof(b), b,
+ op->verbose);
pr2serr("MODE SELECT command: %s\n", b);
- if (0 == verbose)
+ if (0 == op->verbose)
pr2serr(" try '-v' for more information\n");
goto out;
}
}
- if (resize) {
+ if (op->resize) {
printf("Resize operation seems to have been successful\n");
goto out;
}
- else if (! format) {
- res = print_read_cap(fd, do_rcap16, verbose);
+ else if (! op->format) {
+ res = print_read_cap(fd, op);
if (-2 == res) {
- do_rcap16 = 1;
- res = print_read_cap(fd, do_rcap16, verbose);
+ op->do_rcap16 = 1;
+ res = print_read_cap(fd, op);
}
if (res < 0)
ret = -1;
@@ -959,27 +989,29 @@ again_with_long_lba:
goto out;
}
- if (format) {
+ if (op->format) {
format_only:
#if 1
printf("\nA FORMAT will commence in 15 seconds\n");
- printf(" ALL data on %s will be DESTROYED\n", device_name);
+ 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(" ALL data on %s will be DESTROYED\n", device_name);
+ 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(" ALL data on %s will be DESTROYED\n", device_name);
+ 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, fmtpinfo, cmplst, pfu, ! fwait, dcrt,
- pie, ip_def, do_si, early, pt, verbose);
+ res = scsi_format(fd, op);
ret = res;
if (res) {
pr2serr("FORMAT failed\n");
- if (0 == verbose)
+ if (0 == op->verbose)
pr2serr(" try '-v' for more "
"information\n");
}
diff --git a/src/sg_inq.c b/src/sg_inq.c
index bb878fff..11b7badc 100644
--- a/src/sg_inq.c
+++ b/src/sg_inq.c
@@ -42,7 +42,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.54 20160104"; /* SPC-5 rev 07 */
+static const char * version_str = "1.55 20160126"; /* SPC-5 rev 08 */
/* INQUIRY notes:
* It is recommended that the initial allocation length given to a
@@ -1443,32 +1443,6 @@ decode_scsi_ports_vpd(unsigned char * buff, int len, int do_hex)
}
}
-static const char * code_set_arr[] =
-{
- "Reserved [0x0]",
- "Binary",
- "ASCII",
- "UTF-8",
- "[0x4]", "[0x5]", "[0x6]", "[0x7]", "[0x8]", "[0x9]", "[0xa]", "[0xb]",
- "[0xc]", "[0xd]", "[0xe]", "[0xf]",
-};
-
-static const char * desig_type_arr[] =
-{
- "vendor specific [0x0]", /* SCSI_IDENT_DEVICE_VENDOR */
- "T10 vendor identification", /* SCSI_IDENT_DEVICE_T10 */
- "EUI-64 based", /* SCSI_IDENT_DEVICE_EUI64 */
- "NAA", /* SCSI_IDENT_DEVICE_NAA */
- "Relative target port", /* SCSI_IDENT_PORT_RELATIVE */
- "Target port group", /* SCSI_IDENT_PORT_TP_GROUP */
- "Logical unit group", /* SCSI_IDENT_PORT_LU_GROUP */
- "MD5 logical unit identifier", /* SCSI_IDENT_DEVICE_MD5 */
- "SCSI name string", /* SCSI_IDENT_DEVICE_SCSINAME */
- "Protocol specific port identifier", /* spc4r36 */
- "UUID identifier", /* 15-267r2 */
- "[0xb]", "[0xc]", "[0xd]", "[0xe]", "[0xf]",
-};
-
/* These are target port, device server (i.e. target) and LU identifiers */
static void
decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex)
@@ -1480,6 +1454,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex)
const unsigned char * ucp;
const unsigned char * ip;
char b[64];
+ const char * cp;
if (buff[2] != 0) {
/*
@@ -1529,9 +1504,12 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex)
if (piv && ((1 == assoc) || (2 == assoc)))
printf(" transport: %s\n",
sg_get_trans_proto_str(p_id, sizeof(b), b));
- printf(" designator_type: %s, code_set: %s\n",
- desig_type_arr[desig_type], code_set_arr[c_set]);
- printf(" associated with the %s\n", assoc_arr[assoc]);
+ cp = sg_get_desig_type_str(desig_type);
+ printf(" designator_type: %s, ", cp ? cp : "-");
+ cp = sg_get_desig_code_set_str(c_set);
+ printf("code_set: %s\n", cp ? cp : "-");
+ cp = sg_get_desig_assoc_str(assoc);
+ printf(" associated with the %s\n", cp ? cp : "-");
if (do_hex) {
printf(" designator header(hex): %.2x %.2x %.2x %.2x\n",
ucp[0], ucp[1], ucp[2], ucp[3]);
@@ -1769,7 +1747,7 @@ decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex)
"identifier\n",
sg_get_trans_proto_str(p_id, sizeof(b), b));
break;
- case 0xa: /* UUID identifier [15-267r2] */
+ case 0xa: /* UUID identifier [spc5r08] */
if (1 != c_set) {
pr2serr(" << expected binary code_set >>\n");
dStrHexErr((const char *)ip, i_len, 0);
diff --git a/src/sg_logs.c b/src/sg_logs.c
index 76888f3f..204b0f81 100644
--- a/src/sg_logs.c
+++ b/src/sg_logs.c
@@ -1,5 +1,5 @@
/* A utility program originally written for the Linux OS SCSI subsystem.
- * Copyright (C) 2000-2015 D. Gilbert
+ * Copyright (C) 2000-2016 D. Gilbert
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -31,7 +31,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.36 20151219"; /* spc5r07 + sbc4r05 */
+static const char * version_str = "1.37 20160124"; /* spc5r07 + sbc4r10 */
#define MX_ALLOC_LEN (0xfffc)
#define SHORT_RESP_LEN 128
@@ -69,6 +69,7 @@ static const char * version_str = "1.36 20151219"; /* spc5r07 + sbc4r05 */
#define ENV_REPORTING_SUBPG 0x1
#define UTILIZATION_SUBPG 0x1
#define ENV_LIMITS_SUBPG 0x2
+#define LPS_MISALIGNMENT_SUBPG 0x3
#define VENDOR_M 0x1000
@@ -202,6 +203,8 @@ static bool show_pending_defects_page(const uint8_t * resp, int len,
const struct opts_t * op);
static bool show_background_op_page(const uint8_t * resp, int len,
const struct opts_t * op);
+static bool show_lps_misalignment_page(const uint8_t * resp, int len,
+ const struct opts_t * op);
static bool show_element_stats_page(const uint8_t * resp, int len,
const struct opts_t * op);
static bool show_ata_pt_results_page(const uint8_t * resp, int len,
@@ -300,6 +303,9 @@ static struct log_elem log_arr[] = {
{BACKGROUND_SCAN_LPAGE, BACKGROUND_OP_SUBPG, 0, 0, 0,
"Background operation", "bop", show_background_op_page},
/* 0x15, 0x2 SBC */
+ {BACKGROUND_SCAN_LPAGE, LPS_MISALIGNMENT_SUBPG, 0, 0, 0,
+ "LPS misalignment", "lps", show_lps_misalignment_page},
+ /* 0x15, 0x3 SBC-4 */
{0x15, 0, 0, PDT_MCHANGER, 0, "Element statistics", "els",
show_element_stats_page}, /* 0x15, 0x0 SMC */
{0x15, 0, 0, PDT_ADC, 0, "Service buffers information", "sbi",
@@ -329,7 +335,7 @@ static struct log_elem log_arr[] = {
{0x1b, 0, 0, PDT_TAPE, 0, "Data compression", "dc",
show_data_compression_page}, /* 0x1b, 0 SSC */
{0x2d, 0, 0, PDT_TAPE, 0, "Current service information", "csi",
- NULL}, /* 0x2d, 0 SSC */
+ NULL}, /* 0x2d, 0 SSC */
{TAPE_ALERT_LPAGE, 0, 0, PDT_TAPE, 0, "Tape alert", "ta",
show_tape_alert_ssc_page}, /* 0x2e, 0 SSC */
{IE_LPAGE, 0, 0, -1, 0, "Informational exceptions", "ie",
@@ -1089,20 +1095,11 @@ dStrRaw(const char* str, int len)
static uint64_t
decode_count(const uint8_t * xp, int len)
{
- int j;
- uint64_t ull;
-
- if (len > (int)sizeof(ull)) {
- xp += (len - sizeof(ull));
- len = sizeof(ull);
- }
- ull = 0;
- for (j = 0; j < len; ++j) {
- if (j > 0)
- ull <<= 8;
- ull |= xp[j];
+ if (len > (int)sizeof(uint64_t)) {
+ xp += (len - sizeof(uint64_t));
+ len = sizeof(uint64_t);
}
- return ull;
+ return sg_get_unaligned_be64(xp + 0);
}
/* Read ASCII hex bytes or binary from fname (a file named '-' taken as
@@ -1194,8 +1191,8 @@ f2hex_arr(const char * fname, int as_binary, int no_space,
if (1 == sscanf(carry_over, "%4x", &h))
mp_arr[off - 1] = h; /* back up and overwrite */
else {
- pr2serr("f2hex_arr: carry_over error ['%s'] around line "
- "%d\n", carry_over, j + 1);
+ pr2serr("%s: carry_over error ['%s'] around line %d\n",
+ __func__, carry_over, j + 1);
goto bad;
}
lcp = line + 1;
@@ -1215,7 +1212,7 @@ f2hex_arr(const char * fname, int as_binary, int no_space,
continue;
k = strspn(lcp, "0123456789aAbBcCdDeEfF ,\t");
if ((k < in_len) && ('#' != lcp[k]) && ('\r' != lcp[k])) {
- pr2serr("f2hex_arr: syntax error at line %d, pos %d\n",
+ pr2serr("%s: syntax error at line %d, pos %d\n", __func__,
j + 1, m + k + 1);
goto bad;
}
@@ -1223,12 +1220,12 @@ f2hex_arr(const char * fname, int as_binary, int no_space,
for (k = 0; isxdigit(*lcp) && isxdigit(*(lcp + 1));
++k, lcp += 2) {
if (1 != sscanf(lcp, "%2x", &h)) {
- pr2serr("f2hex_arr: bad hex number in line %d, "
- "pos %d\n", j + 1, (int)(lcp - line + 1));
+ pr2serr("%s: bad hex number in line %d, pos %d\n",
+ __func__, j + 1, (int)(lcp - line + 1));
goto bad;
}
if ((off + k) >= max_arr_len) {
- pr2serr("f2hex_arr: array length exceeded\n");
+ pr2serr("%s: array length exceeded\n", __func__);
goto bad;
}
mp_arr[off + k] = h;
@@ -1240,8 +1237,8 @@ f2hex_arr(const char * fname, int as_binary, int no_space,
for (k = 0; k < 1024; ++k) {
if (1 == sscanf(lcp, "%4x", &h)) {
if (h > 0xff) {
- pr2serr("f2hex_arr: hex number larger than "
- "0xff in line %d, pos %d\n", j + 1,
+ pr2serr("%s: hex number larger than 0xff in line %d, "
+ "pos %d\n", __func__, j + 1,
(int)(lcp - line + 1));
goto bad;
}
@@ -1250,7 +1247,7 @@ f2hex_arr(const char * fname, int as_binary, int no_space,
carry_over[0] = *lcp;
}
if ((off + k) >= max_arr_len) {
- pr2serr("f2hex_arr: array length exceeded\n");
+ pr2serr("%s: array length exceeded\n", __func__);
goto bad;
}
mp_arr[off + k] = h;
@@ -1265,8 +1262,8 @@ f2hex_arr(const char * fname, int as_binary, int no_space,
--k;
break;
}
- pr2serr("f2hex_arr: error in line %d, at pos %d\n", j + 1,
- (int)(lcp - line + 1));
+ pr2serr("%s: error in line %d, at pos %d\n", __func__,
+ j + 1, (int)(lcp - line + 1));
goto bad;
}
}
@@ -1326,7 +1323,7 @@ do_logs(int sg_fd, uint8_t * resp, int mx_resp_len,
resp, LOG_SENSE_PROBE_ALLOC_LEN,
1 /* noisy */, vb)))
return res;
- actual_len = (resp[2] << 8) + resp[3] + 4;
+ actual_len = sg_get_unaligned_be16(resp + 2) + 4;
if ((0 == op->do_raw) && (vb > 1)) {
pr2serr(" Log sense (find length) response:\n");
dStrHexErr((const char *)resp, LOG_SENSE_PROBE_ALLOC_LEN, 1);
@@ -1479,7 +1476,7 @@ show_buffer_over_under_run_page(const uint8_t * resp, int len,
cp = NULL;
pl = ucp[3] + 4;
count = (pl > 4) ? decode_count(ucp + 4, pl - 4) : 0;
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
if (op->filter_given) {
if (pc != op->filter)
goto skip;
@@ -1622,7 +1619,7 @@ show_error_counter_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -1677,7 +1674,7 @@ show_non_medium_error_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -1731,7 +1728,7 @@ show_power_condition_transitions_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -1820,7 +1817,7 @@ show_environmental_reporting_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -1893,7 +1890,7 @@ show_environmental_limits_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -1981,7 +1978,7 @@ show_tape_usage_page(const uint8_t * resp, int len, const struct opts_t * op)
if (op->verbose || ((0 == op->do_raw) && (0 == op->do_hex)))
printf("Tape usage page (LTO-5 and LTO-6 specific) [0x30]\n");
for (k = num; k > 0; k -= extra, ucp += extra) {
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
extra = ucp[3] + 4;
if (op->filter_given) {
@@ -1999,15 +1996,13 @@ show_tape_usage_page(const uint8_t * resp, int len, const struct opts_t * op)
ull = n = 0;
switch (ucp[3]) {
case 2:
- n = (ucp[4] << 8) | ucp[5];
+ n = sg_get_unaligned_be16(ucp + 4);
break;
case 4:
- n = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7];
+ n = sg_get_unaligned_be32(ucp + 4);
break;
case 8:
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
break;
}
switch (pc) {
@@ -2091,7 +2086,7 @@ show_tape_capacity_page(const uint8_t * resp, int len,
if (op->verbose || ((0 == op->do_raw) && (0 == op->do_hex)))
printf("Tape capacity page (IBM specific) [0x31]\n");
for (k = num; k > 0; k -= extra, ucp += extra) {
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
extra = ucp[3] + 4;
if (op->filter_given) {
@@ -2108,7 +2103,7 @@ show_tape_capacity_page(const uint8_t * resp, int len,
}
if (extra != 8)
continue;
- n = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7];
+ n = sg_get_unaligned_be32(ucp + 4);
switch (pc) {
case 0x01:
printf(" Main partition remaining capacity (in MiB): %u", n);
@@ -2165,7 +2160,7 @@ show_data_compression_page(const uint8_t * resp, int len,
pg_code);
}
for (k = num; k > 0; k -= extra, ucp += extra) {
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3];
extra = pl + 4;
@@ -2187,6 +2182,7 @@ show_data_compression_page(const uint8_t * resp, int len,
dStrHex((const char *)ucp, extra, 1);
goto skip_para;
}
+ /* variable length integer, max length 8 bytes */
for (j = 0, n = 0; j < pl; ++j) {
if (j > 0)
n <<= 8;
@@ -2267,7 +2263,7 @@ show_last_n_error_page(const uint8_t * resp, int len,
return false;
}
pl = ucp[3] + 4;
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
if (op->filter_given) {
if (pc != op->filter)
@@ -2325,7 +2321,7 @@ show_last_n_deferred_error_page(const uint8_t * resp, int len,
return true;
}
pl = ucp[3] + 4;
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
if (op->filter_given) {
if (pc != op->filter)
@@ -2390,7 +2386,7 @@ show_self_test_page(const uint8_t * resp, int len, const struct opts_t * op)
for (k = 0, ucp = resp + 4; k < 20; ++k, ucp += 20 ) {
pcb = ucp[2];
pl = ucp[3] + 4;
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
if (op->filter_given) {
if (pc != op->filter)
continue;
@@ -2402,7 +2398,7 @@ show_self_test_page(const uint8_t * resp, int len, const struct opts_t * op)
break;
}
}
- n = (ucp[6] << 8) | ucp[7];
+ n = sg_get_unaligned_be16(ucp + 6);
if ((0 == n) && (0 == ucp[4]))
break;
printf(" Parameter code = %d, accumulated power-on hours = %d\n",
@@ -2413,10 +2409,7 @@ show_self_test_page(const uint8_t * resp, int len, const struct opts_t * op)
printf(" self-test result: %s [%d]\n", self_test_result[res], res);
if (ucp[5])
printf(" self-test number = %d\n", (int)ucp[5]);
- ull = ucp[8]; ull <<= 8; ull |= ucp[9]; ull <<= 8; ull |= ucp[10];
- ull <<= 8; ull |= ucp[11]; ull <<= 8; ull |= ucp[12];
- ull <<= 8; ull |= ucp[13]; ull <<= 8; ull |= ucp[14];
- ull <<= 8; ull |= ucp[15];
+ ull = sg_get_unaligned_be64(ucp + 8);
if ((0xffffffffffffffffULL != ull) && (res > 0) && ( res < 0xf))
printf(" address of first error = 0x%" PRIx64 "\n", ull);
v = ucp[16] & 0xf;
@@ -2463,7 +2456,7 @@ show_temperature_page(const uint8_t * resp, int len, const struct opts_t * op)
return true;
}
extra = ucp[3] + 4;
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
if (op->filter_given) {
if (pc != op->filter)
@@ -2537,7 +2530,7 @@ show_start_stop_page(const uint8_t * resp, int len, const struct opts_t * op)
return true;
}
extra = ucp[3] + 4;
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
if (op->filter_given) {
if (pc != op->filter)
@@ -2574,7 +2567,7 @@ show_start_stop_page(const uint8_t * resp, int len, const struct opts_t * op)
break;
case 3:
if (extra > 7) {
- n = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7];
+ n = sg_get_unaligned_be32(ucp + 4);
if (0xffffffff == n)
printf(" Specified cycle count over device lifetime "
"= -1");
@@ -2585,7 +2578,7 @@ show_start_stop_page(const uint8_t * resp, int len, const struct opts_t * op)
break;
case 4:
if (extra > 7) {
- n = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7];
+ n = sg_get_unaligned_be32(ucp + 4);
if (0xffffffff == n)
printf(" Accumulated start-stop cycles = -1");
else
@@ -2594,7 +2587,7 @@ show_start_stop_page(const uint8_t * resp, int len, const struct opts_t * op)
break;
case 5:
if (extra > 7) {
- n = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7];
+ n = sg_get_unaligned_be32(ucp + 4);
if (0xffffffff == n)
printf(" Specified load-unload count over device "
"lifetime = -1");
@@ -2605,7 +2598,7 @@ show_start_stop_page(const uint8_t * resp, int len, const struct opts_t * op)
break;
case 6:
if (extra > 7) {
- n = (ucp[4] << 24) | (ucp[5] << 16) | (ucp[6] << 8) | ucp[7];
+ n = sg_get_unaligned_be32(ucp + 4);
if (0xffffffff == n)
printf(" Accumulated load-unload cycles = -1");
else
@@ -2662,7 +2655,7 @@ show_app_client_page(const uint8_t * resp, int len, const struct opts_t * op)
return true;
}
extra = ucp[3] + 4;
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
if (op->filter != pc)
continue;
@@ -2711,7 +2704,7 @@ show_ie_page(const uint8_t * resp, int len, const struct opts_t * op)
return false;
}
extra = ucp[3] + 4;
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
if (op->filter_given) {
if (pc != op->filter)
@@ -2916,7 +2909,7 @@ static void
show_sas_port_param(const uint8_t * ucp, int param_len,
const struct opts_t * op)
{
- int j, m, n, nphys, pcb, t, sz, spld_len;
+ int j, m, nphys, pcb, t, sz, spld_len;
const uint8_t * vcp;
uint64_t ull;
unsigned int ui;
@@ -2925,7 +2918,7 @@ show_sas_port_param(const uint8_t * ucp, int param_len,
sz = sizeof(s);
pcb = ucp[2];
- t = (ucp[0] << 8) | ucp[1];
+ t = sg_get_unaligned_be16(ucp + 0);
if (op->do_name)
printf("rel_target_port=%d\n", t);
else
@@ -2963,24 +2956,20 @@ show_sas_port_param(const uint8_t * ucp, int param_len,
printf(" att_iport_mask=0x%x\n", vcp[6]);
printf(" att_phy_id=%d\n", vcp[24]);
printf(" att_reason=0x%x\n", (vcp[4] & 0xf));
- for (n = 0, ull = vcp[16]; n < 8; ++n) {
- ull <<= 8; ull |= vcp[16 + n];
- }
+ ull = sg_get_unaligned_be64(vcp + 16);
printf(" att_sas_addr=0x%" PRIx64 "\n", ull);
printf(" att_tport_mask=0x%x\n", vcp[7]);
- ui = (vcp[32] << 24) | (vcp[33] << 16) | (vcp[34] << 8) | vcp[35];
+ ui = sg_get_unaligned_be32(vcp + 32);
printf(" inv_dwords=%u\n", ui);
- ui = (vcp[40] << 24) | (vcp[41] << 16) | (vcp[42] << 8) | vcp[43];
+ ui = sg_get_unaligned_be32(vcp + 40);
printf(" loss_dword_sync=%u\n", ui);
printf(" neg_log_lrate=%d\n", 0xf & vcp[5]);
- ui = (vcp[44] << 24) | (vcp[45] << 16) | (vcp[46] << 8) | vcp[47];
+ ui = sg_get_unaligned_be32(vcp + 44);
printf(" phy_reset_probs=%u\n", ui);
- ui = (vcp[36] << 24) | (vcp[37] << 16) | (vcp[38] << 8) | vcp[39];
+ ui = sg_get_unaligned_be32(vcp + 36);
printf(" running_disparity=%u\n", ui);
printf(" reason=0x%x\n", (vcp[5] & 0xf0) >> 4);
- for (n = 0, ull = vcp[8]; n < 8; ++n) {
- ull <<= 8; ull |= vcp[8 + n];
- }
+ ull = sg_get_unaligned_be64(vcp + 8);
printf(" sas_addr=0x%" PRIx64 "\n", ull);
} else {
t = ((0x70 & vcp[4]) >> 4);
@@ -3076,22 +3065,18 @@ show_sas_port_param(const uint8_t * ucp, int param_len,
!! (vcp[6] & 8), !! (vcp[6] & 4), !! (vcp[6] & 2));
printf(" attached target port: ssp=%d stp=%d smp=%d\n",
!! (vcp[7] & 8), !! (vcp[7] & 4), !! (vcp[7] & 2));
- for (n = 0, ull = vcp[8]; n < 8; ++n) {
- ull <<= 8; ull |= vcp[8 + n];
- }
+ ull = sg_get_unaligned_be64(vcp + 8);
printf(" SAS address = 0x%" PRIx64 "\n", ull);
- for (n = 0, ull = vcp[16]; n < 8; ++n) {
- ull <<= 8; ull |= vcp[16 + n];
- }
+ ull = sg_get_unaligned_be64(vcp + 16);
printf(" attached SAS address = 0x%" PRIx64 "\n", ull);
printf(" attached phy identifier = %d\n", vcp[24]);
- ui = (vcp[32] << 24) | (vcp[33] << 16) | (vcp[34] << 8) | vcp[35];
+ ui = sg_get_unaligned_be32(vcp + 32);
printf(" Invalid DWORD count = %u\n", ui);
- ui = (vcp[36] << 24) | (vcp[37] << 16) | (vcp[38] << 8) | vcp[39];
+ ui = sg_get_unaligned_be32(vcp + 36);
printf(" Running disparity error count = %u\n", ui);
- ui = (vcp[40] << 24) | (vcp[41] << 16) | (vcp[42] << 8) | vcp[43];
+ ui = sg_get_unaligned_be32(vcp + 40);
printf(" Loss of DWORD synchronization = %u\n", ui);
- ui = (vcp[44] << 24) | (vcp[45] << 16) | (vcp[46] << 8) | vcp[47];
+ ui = sg_get_unaligned_be32(vcp + 44);
printf(" Phy reset problem = %u\n", ui);
}
if (spld_len > 51) {
@@ -3114,10 +3099,8 @@ show_sas_port_param(const uint8_t * ucp, int param_len,
xcp = vcp + 52;
for (m = 0; m < (num_ped * 12); m += 12, xcp += 12) {
pes = xcp[3];
- ui = (xcp[4] << 24) | (xcp[5] << 16) | (xcp[6] << 8) |
- xcp[7];
- pvdt = (xcp[8] << 24) | (xcp[9] << 16) | (xcp[10] << 8) |
- xcp[11];
+ ui = sg_get_unaligned_be32(xcp + 4);
+ pvdt = sg_get_unaligned_be32(xcp + 8);
show_sas_phy_event_info(pes, ui, pvdt);
}
} else if (op->verbose)
@@ -3139,7 +3122,7 @@ show_protocol_specific_page(const uint8_t * resp, int len,
printf("log_page=0x%x\n", PROTO_SPECIFIC_LPAGE);
}
for (k = 0, ucp = resp + 4; k < num; ) {
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pl = ucp[3] + 4;
if (op->filter_given) {
if (pc != op->filter)
@@ -3177,8 +3160,9 @@ static bool
show_stats_perform_page(const uint8_t * resp, int len,
const struct opts_t * op)
{
- int k, num, n, param_len, param_code, spf, subpg_code, extra;
+ int k, num, param_len, param_code, spf, subpg_code, extra;
int pcb, nam;
+ unsigned int ui;
const uint8_t * ucp;
const char * ccp;
uint64_t ull;
@@ -3212,7 +3196,7 @@ show_stats_perform_page(const uint8_t * resp, int len,
return false;
param_len = ucp[3];
extra = param_len + 4;
- param_code = (ucp[0] << 8) + ucp[1];
+ param_code = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
if (op->filter_given) {
if (param_code != op->filter)
@@ -3231,49 +3215,33 @@ show_stats_perform_page(const uint8_t * resp, int len,
ccp = nam ? "parameter_code=1" : "Statistics and performance "
"log parameter";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "read_commands=" : "number of read commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[12]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[12 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 12);
ccp = nam ? "write_commands=" : "number of write commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[20]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[20 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 20);
ccp = nam ? "lb_received="
: "number of logical blocks received = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[28]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[28 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 28);
ccp = nam ? "lb_transmitted="
: "number of logical blocks transmitted = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[36]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[36 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 36);
ccp = nam ? "read_proc_intervals="
: "read command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[44]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[44 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 44);
ccp = nam ? "write_proc_intervals="
: "write command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[52]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[52 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 52);
ccp = nam ? "weight_rw_commands=" : "weighted number of "
"read commands plus write commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[60]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[60 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 60);
ccp = nam ? "weight_rw_processing=" : "weighted read command "
"processing plus write command processing = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3281,9 +3249,7 @@ show_stats_perform_page(const uint8_t * resp, int len,
case 2: /* Idle time log parameter */
ccp = nam ? "parameter_code=2" : "Idle time log parameter";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "idle_time_intervals=" : "idle time "
"intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3292,68 +3258,48 @@ show_stats_perform_page(const uint8_t * resp, int len,
ccp = nam ? "parameter_code=3" : "Time interval log "
"parameter for general stats";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 4; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ui = sg_get_unaligned_be32(ucp + 4);
ccp = nam ? "time_interval_neg_exp=" : "time interval "
"negative exponent = ";
- printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[8]; n < 4; ++n) {
- ull <<= 8; ull |= ucp[8 + n];
- }
+ printf(" %s%u\n", ccp, ui);
+ ui = sg_get_unaligned_be32(ucp + 8);
ccp = nam ? "time_interval_int=" : "time interval "
"integer = ";
- printf(" %s%" PRIu64 "\n", ccp, ull);
+ printf(" %s%u\n", ccp, ui);
break;
case 4: /* FUA statistics and performance log parameter */
ccp = nam ? "parameter_code=4" : "Force unit access "
"statistics and performance log parameter ";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "read_fua_commands=" : "number of read FUA "
"commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[12]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[12 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 12);
ccp = nam ? "write_fua_commands=" : "number of write FUA "
"commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[20]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[20 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 20);
ccp = nam ? "read_fua_nv_commands="
: "number of read FUA_NV commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[28]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[28 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 28);
ccp = nam ? "write_fua_nv_commands="
: "number of write FUA_NV commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[36]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[36 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 36);
ccp = nam ? "read_fua_proc_intervals="
: "read FUA command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[44]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[44 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 44);
ccp = nam ? "write_fua_proc_intervals="
: "write FUA command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[52]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[52 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 52);
ccp = nam ? "read_fua_nv_proc_intervals="
: "read FUA_NV command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[60]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[60 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 60);
ccp = nam ? "write_fua_nv_proc_intervals="
: "write FUA_NV command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3362,15 +3308,11 @@ show_stats_perform_page(const uint8_t * resp, int len,
ccp = nam ? "parameter_code=6" : "Time interval log "
"parameter for cache stats";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 4; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "time_interval_neg_exp=" : "time interval "
"negative exponent = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[8]; n < 4; ++n) {
- ull <<= 8; ull |= ucp[8 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 8);
ccp = nam ? "time_interval_int=" : "time interval "
"integer = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3401,7 +3343,7 @@ show_stats_perform_page(const uint8_t * resp, int len,
return false;
param_len = ucp[3];
extra = param_len + 4;
- param_code = (ucp[0] << 8) + ucp[1];
+ param_code = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
if (op->filter_given) {
if (param_code != op->filter)
@@ -3422,39 +3364,27 @@ show_stats_perform_page(const uint8_t * resp, int len,
else
printf("Group %d Statistics and performance log "
"parameter\n", subpg_code);
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "gn_read_commands=" : "group n number of read "
"commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[12]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[12 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 12);
ccp = nam ? "gn_write_commands=" : "group n number of write "
"commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[20]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[20 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 20);
ccp = nam ? "gn_lb_received="
: "group n number of logical blocks received = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[28]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[28 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 28);
ccp = nam ? "gn_lb_transmitted="
: "group n number of logical blocks transmitted = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[36]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[36 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 36);
ccp = nam ? "gn_read_proc_intervals="
: "group n read command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[44]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[44 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 44);
ccp = nam ? "gn_write_proc_intervals="
: "group n write command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3463,51 +3393,35 @@ show_stats_perform_page(const uint8_t * resp, int len,
ccp = nam ? "parameter_code=4" : "Group n force unit access "
"statistics and performance log parameter";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "gn_read_fua_commands="
: "group n number of read FUA commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[12]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[12 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 12);
ccp = nam ? "gn_write_fua_commands="
: "group n number of write FUA commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[20]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[20 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 20);
ccp = nam ? "gn_read_fua_nv_commands="
: "group n number of read FUA_NV commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[28]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[28 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 28);
ccp = nam ? "gn_write_fua_nv_commands="
: "group n number of write FUA_NV commands = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[36]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[36 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 36);
ccp = nam ? "gn_read_fua_proc_intervals="
: "group n read FUA command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[44]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[44 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 44);
ccp = nam ? "gn_write_fua_proc_intervals=" : "group n write "
"FUA command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[52]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[52 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 52);
ccp = nam ? "gn_read_fua_nv_proc_intervals=" : "group n "
"read FUA_NV command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[60]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[60 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 60);
ccp = nam ? "gn_write_fua_nv_proc_intervals=" : "group n "
"write FUA_NV command processing intervals = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3539,8 +3453,9 @@ show_stats_perform_page(const uint8_t * resp, int len,
static bool
show_cache_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
{
- int k, num, n, pc, spf, subpg_code, extra;
+ int k, num, pc, spf, subpg_code, extra;
int pcb, nam;
+ unsigned int ui;
const uint8_t * ucp;
const char * ccp;
uint64_t ull;
@@ -3575,7 +3490,7 @@ show_cache_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
return false;
}
extra = ucp[3] + 4;
- pc = (ucp[0] << 8) + ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
if (op->filter_given) {
if (pc != op->filter)
@@ -3594,9 +3509,7 @@ show_cache_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
ccp = nam ? "parameter_code=1" :
"Read cache memory hits log parameter";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "read_cache_memory_hits=" :
"read cache memory hits = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3605,9 +3518,7 @@ show_cache_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
ccp = nam ? "parameter_code=2" :
"Reads to cache memory log parameter";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "reads_to_cache_memory=" :
"reads to cache memory = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3616,9 +3527,7 @@ show_cache_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
ccp = nam ? "parameter_code=3" :
"Write cache memory hits log parameter";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "write_cache_memory_hits=" :
"write cache memory hits = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3627,9 +3536,7 @@ show_cache_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
ccp = nam ? "parameter_code=4" :
"Writes from cache memory log parameter";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "writes_from_cache_memory=" :
"writes from cache memory = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3638,9 +3545,7 @@ show_cache_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
ccp = nam ? "parameter_code=5" :
"Time from last hard reset log parameter";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 8; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ull = sg_get_unaligned_be64(ucp + 4);
ccp = nam ? "time_from_last_hard_reset=" :
"time from last hard reset = ";
printf(" %s%" PRIu64 "\n", ccp, ull);
@@ -3649,18 +3554,14 @@ show_cache_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
ccp = nam ? "parameter_code=6" :
"Time interval log parameter";
printf("%s\n", ccp);
- for (n = 0, ull = ucp[4]; n < 4; ++n) {
- ull <<= 8; ull |= ucp[4 + n];
- }
+ ui = sg_get_unaligned_be32(ucp + 4);
ccp = nam ? "time_interval_neg_exp=" : "time interval "
"negative exponent = ";
- printf(" %s%" PRIu64 "\n", ccp, ull);
- for (n = 0, ull = ucp[8]; n < 4; ++n) {
- ull <<= 8; ull |= ucp[8 + n];
- }
+ printf(" %s%u\n", ccp, ui);
+ ui = sg_get_unaligned_be32(ucp + 8);
ccp = nam ? "time_interval_int=" : "time interval "
"integer = ";
- printf(" %s%" PRIu64 "\n", ccp, ull);
+ printf(" %s%u\n", ccp, ui);
break;
default:
if (nam) {
@@ -3699,7 +3600,7 @@ show_format_status_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -3807,7 +3708,7 @@ show_non_volatile_cache_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -3825,7 +3726,7 @@ show_non_volatile_cache_page(const uint8_t * resp, int len,
case 0:
printf(" Remaining non-volatile time: ");
if (3 == ucp[4]) {
- j = (ucp[5] << 16) + (ucp[6] << 8) + ucp[7];
+ j = sg_get_unaligned_be24(ucp + 5);
switch (j) {
case 0:
printf("0 (i.e. it is now volatile)\n");
@@ -3846,7 +3747,7 @@ show_non_volatile_cache_page(const uint8_t * resp, int len,
case 1:
printf(" Maximum non-volatile time: ");
if (3 == ucp[4]) {
- j = (ucp[5] << 16) + (ucp[6] << 8) + ucp[7];
+ j = sg_get_unaligned_be24(ucp + 5);
switch (j) {
case 0:
printf("0 (i.e. it is now volatile)\n");
@@ -3897,7 +3798,7 @@ show_lb_provisioning_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -3992,7 +3893,7 @@ show_utilization_page(const uint8_t * resp, int len, const struct opts_t * op)
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4066,7 +3967,7 @@ show_solid_state_media_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4146,7 +4047,7 @@ show_dt_device_status_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4205,7 +4106,7 @@ show_dt_device_status_page(const uint8_t * resp, int len,
pl);
break;
}
- printf(" %d milliseconds\n", (ucp[4] << 8) + ucp[5]);
+ printf(" %d milliseconds\n", sg_get_unaligned_be16(ucp + 4));
break;
case 0x2:
printf(" DT device ADC data encryption control status (hex "
@@ -4268,7 +4169,7 @@ show_ata_pt_results_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4355,7 +4256,7 @@ show_background_scan_results_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4382,7 +4283,7 @@ show_background_scan_results_page(const uint8_t * resp, int len,
break;
}
printf(" Accumulated power on minutes: ");
- j = (ucp[4] << 24) + (ucp[5] << 16) + (ucp[6] << 8) + ucp[7];
+ j = sg_get_unaligned_be32(ucp + 4);
printf("%d [h:m %d:%d]\n", j, (j / 60), (j % 60));
printf(" Status: ");
j = ucp[9];
@@ -4390,9 +4291,9 @@ show_background_scan_results_page(const uint8_t * resp, int len,
printf("%s\n", bms_status[j]);
else
printf("unknown [0x%x] background scan status value\n", j);
- j = (ucp[10] << 8) + ucp[11];
+ j = sg_get_unaligned_be16(ucp + 10);
printf(" Number of background scans performed: %d\n", j);
- j = (ucp[12] << 8) + ucp[13];
+ j = sg_get_unaligned_be16(ucp + 12);
#ifdef SG_LIB_MINGW
printf(" Background medium scan progress: %g %%\n",
(double)(j * 100.0 / 65536.0));
@@ -4400,7 +4301,7 @@ show_background_scan_results_page(const uint8_t * resp, int len,
printf(" Background medium scan progress: %.2f %%\n",
(double)(j * 100.0 / 65536.0));
#endif
- j = (ucp[14] << 8) + ucp[15];
+ j = sg_get_unaligned_be16(ucp + 14);
if (0 == j)
printf(" Number of background medium scans performed: 0 "
"[not reported]\n");
@@ -4430,7 +4331,7 @@ show_background_scan_results_page(const uint8_t * resp, int len,
break;
}
printf(" Power on minutes when error detected: ");
- j = (ucp[4] << 24) + (ucp[5] << 16) + (ucp[6] << 8) + ucp[7];
+ j = sg_get_unaligned_be32(ucp + 4);
printf("%d [%d:%d]\n", j, (j / 60), (j % 60));
j = (ucp[8] >> 4) & 0xf;
if (j <
@@ -4483,7 +4384,7 @@ show_pending_defects_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4554,7 +4455,7 @@ show_background_op_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4600,6 +4501,72 @@ skip:
return true;
}
+/* LPS misalignment page [0x15,0x3] introduced: SBC-4 rev 10 */
+static bool
+show_lps_misalignment_page(const uint8_t * resp, int len,
+ const struct opts_t * op)
+{
+ int num, pl, pc, pcb;
+ const uint8_t * ucp;
+ char pcb_str[PCB_STR_LEN];
+
+ if (op->verbose || ((0 == op->do_raw) && (0 == op->do_hex)))
+ printf("LPS misalignment page [0x15,0x3]\n");
+ num = len - 4;
+ ucp = &resp[0] + 4;
+ while (num > 3) {
+ pc = sg_get_unaligned_be16(ucp + 0);
+ pcb = ucp[2];
+ pl = ucp[3] + 4;
+ if (op->filter_given) {
+ if (pc != op->filter)
+ goto skip;
+ if (op->do_raw) {
+ dStrRaw((const char *)ucp, pl);
+ break;
+ } else if (op->do_hex) {
+ dStrHex((const char *)ucp, pl, ((1 == op->do_hex) ? 1 : -1));
+ break;
+ }
+ }
+ switch (pc) {
+ case 0x0:
+ printf(" LPS misalignment count: ");
+ if (4 == ucp[3])
+ printf("max lpsm: %" PRIu16 ", count=%" PRIu16 "\n",
+ sg_get_unaligned_be16(ucp + 4),
+ sg_get_unaligned_be16(ucp + 6));
+ else
+ printf("<unexpected pc=0 parameter length=%d>\n", ucp[4]);
+ break;
+ default:
+ if (pc <= 0xf000) {
+ if (8 == ucp[3])
+ printf(" LBA of misaligned block: 0x%" PRIx64 "\n",
+ sg_get_unaligned_be64(ucp + 8));
+ else
+ printf("<unexpected pc=0x%x parameter length=%d>\n",
+ pc, ucp[4]);
+ } else {
+ printf("<unexpected pc=0x%x>\n", pc);
+ dStrHex((const char *)ucp, pl, 0);
+ }
+ break;
+ }
+ if (op->do_pcb) {
+ get_pcb_str(pcb, pcb_str, sizeof(pcb_str));
+ printf(" <%s>\n", pcb_str);
+ }
+ if (op->filter_given)
+ break;
+skip:
+ num -= pl;
+ ucp += pl;
+ }
+ return true;
+}
+
+
/* Sequential access device page [0xc] for tape */
static bool
show_sequential_access_page(const uint8_t * resp, int len,
@@ -4615,7 +4582,7 @@ show_sequential_access_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4725,7 +4692,7 @@ show_device_stats_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4834,7 +4801,7 @@ show_media_stats_page(const uint8_t * resp, int len, const struct opts_t * op)
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4973,7 +4940,7 @@ show_element_stats_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -4988,17 +4955,17 @@ show_element_stats_page(const uint8_t * resp, int len,
}
}
printf(" Element address: %d\n", pc);
- v = (ucp[4] << 24) + (ucp[5] << 16) + (ucp[6] << 8) + ucp[7];
+ v = sg_get_unaligned_be32(ucp + 4);
printf(" Number of places: %u\n", v);
- v = (ucp[8] << 24) + (ucp[9] << 16) + (ucp[10] << 8) + ucp[11];
+ v = sg_get_unaligned_be32(ucp + 8);
printf(" Number of place retries: %u\n", v);
- v = (ucp[12] << 24) + (ucp[13] << 16) + (ucp[14] << 8) + ucp[15];
+ v = sg_get_unaligned_be32(ucp + 12);
printf(" Number of picks: %u\n", v);
- v = (ucp[16] << 24) + (ucp[17] << 16) + (ucp[18] << 8) + ucp[19];
+ v = sg_get_unaligned_be32(ucp + 16);
printf(" Number of pick retries: %u\n", v);
- v = (ucp[20] << 24) + (ucp[21] << 16) + (ucp[22] << 8) + ucp[23];
+ v = sg_get_unaligned_be32(ucp + 20);
printf(" Number of determined volume identifiers: %u\n", v);
- v = (ucp[24] << 24) + (ucp[25] << 16) + (ucp[26] << 8) + ucp[27];
+ v = sg_get_unaligned_be32(ucp + 24);
printf(" Number of unreadable volume identifiers: %u\n", v);
if (op->do_pcb) {
get_pcb_str(pcb, str, sizeof(str));
@@ -5029,7 +4996,7 @@ show_tape_diag_data_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -5046,7 +5013,7 @@ show_tape_diag_data_page(const uint8_t * resp, int len,
printf(" Parameter code: %d\n", pc);
printf(" Density code: 0x%x\n", ucp[6]);
printf(" Medium type: 0x%x\n", ucp[7]);
- v = (ucp[8] << 24) + (ucp[9] << 16) + (ucp[10] << 8) + ucp[11];
+ v = sg_get_unaligned_be32(ucp + 8);
printf(" Lifetime media motion hours: %u\n", v);
printf(" Repeat: %d\n", !!(ucp[13] & 0x80));
v = ucp[13] & 0xf;
@@ -5057,11 +5024,11 @@ show_tape_diag_data_page(const uint8_t * resp, int len,
if (ucp[14] || ucp[15])
printf(" [%s]\n", sg_get_asc_ascq_str(ucp[14], ucp[15],
sizeof(b), b));
- v = (ucp[16] << 24) + (ucp[17] << 16) + (ucp[18] << 8) + ucp[19];
+ v = sg_get_unaligned_be32(ucp + 16);
printf(" Vendor specific code qualifier: 0x%x\n", v);
- v = (ucp[20] << 24) + (ucp[21] << 16) + (ucp[22] << 8) + ucp[23];
+ v = sg_get_unaligned_be32(ucp + 20);
printf(" Product revision level: %u\n", v);
- v = (ucp[24] << 24) + (ucp[25] << 16) + (ucp[26] << 8) + ucp[27];
+ v = sg_get_unaligned_be32(ucp + 24);
printf(" Hours since last clean: %u\n", v);
printf(" Operation code: 0x%x\n", ucp[28]);
printf(" Service action: 0x%x\n", ucp[29] & 0xf);
@@ -5122,7 +5089,7 @@ show_mchanger_diag_data_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -5146,23 +5113,23 @@ show_mchanger_diag_data_page(const uint8_t * resp, int len,
if (ucp[6] || ucp[7])
printf(" [%s]\n", sg_get_asc_ascq_str(ucp[6], ucp[7],
sizeof(b), b));
- v = (ucp[8] << 24) + (ucp[9] << 16) + (ucp[10] << 8) + ucp[11];
+ v = sg_get_unaligned_be32(ucp + 8);
printf(" Vendor specific code qualifier: 0x%x\n", v);
- v = (ucp[12] << 24) + (ucp[13] << 16) + (ucp[14] << 8) + ucp[15];
+ v = sg_get_unaligned_be32(ucp + 12);
printf(" Product revision level: %u\n", v);
- v = (ucp[16] << 24) + (ucp[17] << 16) + (ucp[18] << 8) + ucp[19];
+ v = sg_get_unaligned_be32(ucp + 16);
printf(" Number of moves: %u\n", v);
- v = (ucp[20] << 24) + (ucp[21] << 16) + (ucp[22] << 8) + ucp[23];
+ v = sg_get_unaligned_be32(ucp + 20);
printf(" Number of pick: %u\n", v);
- v = (ucp[24] << 24) + (ucp[25] << 16) + (ucp[26] << 8) + ucp[27];
+ v = sg_get_unaligned_be32(ucp + 24);
printf(" Number of pick retries: %u\n", v);
- v = (ucp[28] << 24) + (ucp[29] << 16) + (ucp[30] << 8) + ucp[31];
+ v = sg_get_unaligned_be32(ucp + 28);
printf(" Number of places: %u\n", v);
- v = (ucp[32] << 24) + (ucp[33] << 16) + (ucp[34] << 8) + ucp[35];
+ v = sg_get_unaligned_be32(ucp + 32);
printf(" Number of place retries: %u\n", v);
- v = (ucp[36] << 24) + (ucp[37] << 16) + (ucp[38] << 8) + ucp[39];
+ v = sg_get_unaligned_be32(ucp + 36);
printf(" Number of determined volume identifiers: %u\n", v);
- v = (ucp[40] << 24) + (ucp[41] << 16) + (ucp[42] << 8) + ucp[43];
+ v = sg_get_unaligned_be32(ucp + 40);
printf(" Number of unreadable volume identifiers: %u\n", v);
printf(" Operation code: 0x%x\n", ucp[44]);
printf(" Service action: 0x%x\n", ucp[45] & 0xf);
@@ -5171,13 +5138,13 @@ show_mchanger_diag_data_page(const uint8_t * resp, int len,
printf(" IAV: %d\n", !!(ucp[47] & 0x4));
printf(" LSAV: %d\n", !!(ucp[47] & 0x2));
printf(" DAV: %d\n", !!(ucp[47] & 0x1));
- v = (ucp[48] << 8) + ucp[49];
+ v = sg_get_unaligned_be16(ucp + 48);
printf(" Medium transport address: 0x%x\n", v);
- v = (ucp[50] << 8) + ucp[51];
+ v = sg_get_unaligned_be16(ucp + 50);
printf(" Intial address: 0x%x\n", v);
- v = (ucp[52] << 8) + ucp[53];
+ v = sg_get_unaligned_be16(ucp + 52);
printf(" Last successful address: 0x%x\n", v);
- v = (ucp[54] << 8) + ucp[55];
+ v = sg_get_unaligned_be16(ucp + 54);
printf(" Destination address: 0x%x\n", v);
if (pl > 91) {
printf(" Volume tag information:\n");
@@ -5205,15 +5172,16 @@ skip:
static void
volume_stats_partition(const uint8_t * xp, int len, int hex)
{
- int dl;
+ int dl, pn;
while (len > 3) {
dl = xp[0] + 1;
if (dl < 3)
return;
+ pn = sg_get_unaligned_be16(xp + 2);
if (hex)
printf(" partition number: %d, partition record data "
- "counter: 0x%" PRIx64 "\n", (xp[2] << 8) + xp[3],
+ "counter: 0x%" PRIx64 "\n", pn,
decode_count(xp + 4, dl - 4));
else {
int k;
@@ -5237,15 +5205,15 @@ volume_stats_partition(const uint8_t * xp, int len, int hex)
if (0 == (all_ffs + ffs_last_fe))
printf(" partition number: %d, partition record data "
- "counter: %" PRIu64 "\n", (xp[2] << 8) + xp[3],
+ "counter: %" PRIu64 "\n", pn,
decode_count(xp + 4, dl - 4));
else if (all_ffs)
printf(" partition number: %d, partition record data "
- "counter is all 0xFFs\n", (xp[2] << 8) + xp[3]);
+ "counter is all 0xFFs\n", pn);
else
printf(" partition number: %d, partition record data "
"counter is all 0xFFs apart\n from a trailing "
- "0xFE\n", (xp[2] << 8) + xp[3]);
+ "0xFE\n", pn);
}
xp += dl;
len -= dl;
@@ -5279,7 +5247,7 @@ show_volume_stats_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -5562,7 +5530,7 @@ show_tape_alert_ssc_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -5614,7 +5582,7 @@ show_seagate_cache_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -5673,7 +5641,7 @@ show_seagate_factory_page(const uint8_t * resp, int len,
num = len - 4;
ucp = &resp[0] + 4;
while (num > 3) {
- pc = (ucp[0] << 8) | ucp[1];
+ pc = sg_get_unaligned_be16(ucp + 0);
pcb = ucp[2];
pl = ucp[3] + 4;
if (op->filter_given) {
@@ -5768,20 +5736,20 @@ fetchTemperature(int sg_fd, uint8_t * resp, int max_len, struct opts_t * op)
op->subpg_code = NOT_SPG_SUBPG;
res = do_logs(sg_fd, resp, max_len, op);
if (0 == res) {
- len = (resp[2] << 8) + resp[3] + 4;
+ len = sg_get_unaligned_be16(resp + 2) + 4;
if (op->do_raw)
dStrRaw((const char *)resp, len);
else if (op->do_hex)
dStrHex((const char *)resp, len, (1 == op->do_hex));
else
show_temperature_page(resp, len, op);
- }else if (SG_LIB_CAT_NOT_READY == res)
+ } else if (SG_LIB_CAT_NOT_READY == res)
pr2serr("Device not ready\n");
else {
op->pg_code = IE_LPAGE;
res = do_logs(sg_fd, resp, max_len, op);
if (0 == res) {
- len = (resp[2] << 8) + resp[3] + 4;
+ len = sg_get_unaligned_be16(resp + 2) + 4;
if (op->do_raw)
dStrRaw((const char *)resp, len);
else if (op->do_hex)
@@ -6074,7 +6042,7 @@ main(int argc, char * argv[])
resp_len = (op->maxlen > 0) ? op->maxlen : MX_ALLOC_LEN;
res = do_logs(sg_fd, rsp_buff, resp_len, op);
if (0 == res) {
- pg_len = (rsp_buff[2] << 8) + rsp_buff[3];
+ pg_len = sg_get_unaligned_be16(rsp_buff + 2);
if ((pg_len + 4) > resp_len) {
pr2serr("Only fetched %d bytes of response (available: %d "
"bytes)\n truncate output\n",
@@ -6143,7 +6111,7 @@ main(int argc, char * argv[])
res = do_logs(sg_fd, rsp_buff, resp_len, op);
if (0 == res) {
- pg_len = (rsp_buff[2] << 8) + rsp_buff[3];
+ pg_len = sg_get_unaligned_be16(rsp_buff + 2);
if ((pg_len + 4) > resp_len) {
pr2serr("Only fetched %d bytes of response, truncate "
"output\n", resp_len);
diff --git a/src/sg_map.c b/src/sg_map.c
index f1e9ca93..6a156755 100644
--- a/src/sg_map.c
+++ b/src/sg_map.c
@@ -19,7 +19,7 @@
*/
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#include <unistd.h>
diff --git a/src/sg_map26.c b/src/sg_map26.c
index ff79aae5..1a1301aa 100644
--- a/src/sg_map26.c
+++ b/src/sg_map26.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005-2015 Douglas Gilbert.
+ * Copyright (c) 2005-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.
@@ -16,7 +16,7 @@
/* #define _XOPEN_SOURCE 500 */
/* needed to see DT_REG and friends when compiled with: c99 pedantic */
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#include <unistd.h>
@@ -40,7 +40,7 @@
#endif
#include "sg_lib.h"
-static const char * version_str = "1.10 20151219";
+static const char * version_str = "1.11 20160121";
#define ME "sg_map26: "
diff --git a/src/sg_rbuf.c b/src/sg_rbuf.c
index 41090bdc..2d201b66 100644
--- a/src/sg_rbuf.c
+++ b/src/sg_rbuf.c
@@ -1,5 +1,5 @@
/* A utility program originally written for the Linux OS SCSI subsystem.
- * Copyright (C) 1999-2015 D. Gilbert
+ * Copyright (C) 1999-2016 D. Gilbert
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -13,7 +13,7 @@
#define _XOPEN_SOURCE 500
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#include <unistd.h>
@@ -55,7 +55,7 @@
#endif
-static const char * version_str = "4.94 20151219";
+static const char * version_str = "4.95 20160121";
static struct option long_options[] = {
{"buffer", required_argument, 0, 'b'},
diff --git a/src/sg_read.c b/src/sg_read.c
index 5b005e21..7b0b989a 100644
--- a/src/sg_read.c
+++ b/src/sg_read.c
@@ -1,5 +1,5 @@
/* A utility program for the Linux OS SCSI generic ("sg") device driver.
-* Copyright (C) 2001 - 2015 D. Gilbert
+* Copyright (C) 2001 - 2016 D. Gilbert
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -20,7 +20,7 @@
#define _XOPEN_SOURCE 500
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#include <unistd.h>
@@ -50,7 +50,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "1.24 20151219";
+static const char * version_str = "1.25 20160121";
#define DEF_BLOCK_SIZE 512
#define DEF_BLOCKS_PER_TRANSFER 128
diff --git a/src/sg_read_long.c b/src/sg_read_long.c
index 4c5bc643..95147876 100644
--- a/src/sg_read_long.c
+++ b/src/sg_read_long.c
@@ -1,5 +1,5 @@
/* A utility program for the Linux OS SCSI subsystem.
- * Copyright (C) 2004-2015 D. Gilbert
+ * Copyright (C) 2004-2016 D. Gilbert
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -30,7 +30,7 @@
#include "sg_cmds_extra.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.20 20151219";
+static const char * version_str = "1.21 20160121";
#define MAX_XFER_LEN 10000
@@ -79,8 +79,8 @@ usage()
" --xfer_len=BTL|-x BTL byte transfer length (< 10000)"
" default 520\n\n"
"Perform a SCSI READ LONG (10 or 16) command. Reads a single "
- "block with\nassociated ECC data. User data could be "
- "scrambled.\n");
+ "block with\nassociated ECC data. The user data could be "
+ "encoded or encrypted.\n");
}
/* Returns 0 if successful */
diff --git a/src/sg_sat_identify.c b/src/sg_sat_identify.c
index 338c894a..f5f4de4c 100644
--- a/src/sg_sat_identify.c
+++ b/src/sg_sat_identify.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2015 Douglas Gilbert.
+ * Copyright (c) 2006-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.
@@ -46,7 +46,7 @@
#define EBUFF_SZ 256
-static const char * version_str = "1.11 20141110";
+static const char * version_str = "1.12 20160126";
static struct option long_options[] = {
{"ck_cond", no_argument, 0, 'c'},
@@ -161,9 +161,11 @@ static int do_identify_dev(int sg_fd, int do_packet, int cdb_len,
if (verbose > 2)
pr2serr("command completed with SCSI GOOD status\n");
} else if ((res > 0) && (res & SAM_STAT_CHECK_CONDITION)) {
- if (verbose > 1)
- sg_print_sense("ATA pass through", sense_buffer, sb_sz,
+ if (verbose > 1) {
+ pr2serr("ATA pass through:\n");
+ sg_print_sense(NULL, sense_buffer, sb_sz,
((verbose > 2) ? 1 : 0));
+ }
if (sg_scsi_normalize_sense(sense_buffer, sb_sz, &ssh)) {
switch (ssh.sense_key) {
case SPC_SK_ILLEGAL_REQUEST:
diff --git a/src/sg_sat_phy_event.c b/src/sg_sat_phy_event.c
index f294a72a..fcece2d0 100644
--- a/src/sg_sat_phy_event.c
+++ b/src/sg_sat_phy_event.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2015 Douglas Gilbert.
+ * Copyright (c) 2006-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.
@@ -22,7 +22,7 @@
#include "sg_cmds_extra.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.06 20151219";
+static const char * version_str = "1.07 20160126";
/* This program uses a ATA PASS-THROUGH SCSI command. This usage is
* defined in the SCSI to ATA Translation (SAT) drafts and standards.
@@ -215,9 +215,11 @@ do_read_log_ext(int sg_fd, int log_addr, int page_in_log, int feature,
if (verbose > 2)
pr2serr("command completed with SCSI GOOD status\n");
} else if ((res > 0) && (res & SAM_STAT_CHECK_CONDITION)) {
- if (verbose > 1)
- sg_print_sense("ATA pass through", sense_buffer, sb_sz,
+ if (verbose > 1) {
+ pr2serr("ATA pass through:\n");
+ sg_print_sense(NULL, sense_buffer, sb_sz,
((verbose > 2) ? 1 : 0));
+ }
if (sg_scsi_normalize_sense(sense_buffer, sb_sz, &ssh)) {
switch (ssh.sense_key) {
case SPC_SK_ILLEGAL_REQUEST:
diff --git a/src/sg_sat_read_gplog.c b/src/sg_sat_read_gplog.c
index 6c992aa8..df34de28 100644
--- a/src/sg_sat_read_gplog.c
+++ b/src/sg_sat_read_gplog.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015 Hannes Reinecke, SUSE Linux GmbH.
+ * Copyright (c) 2014-2016 Hannes Reinecke, SUSE Linux GmbH.
* All rights reserved.
* Use of this source code is governed by a BSD-style
* license that can be found in the BSD_LICENSE file.
@@ -49,7 +49,7 @@
#define DEF_TIMEOUT 20
-static const char * version_str = "1.12 20151207";
+static const char * version_str = "1.13 20160126";
struct opts_t {
int cdb_len;
@@ -200,9 +200,11 @@ do_read_gplog(int sg_fd, int ata_cmd, unsigned char *inbuff,
else /* '-HHHH' hex bytes only */
dStrHex((const char *)inbuff, 512, -1);
} else if ((res > 0) && (res & SAM_STAT_CHECK_CONDITION)) {
- if (op->verbose > 1)
- sg_print_sense("ATA pass through", sense_buffer, sb_sz,
+ if (op->verbose > 1) {
+ pr2serr("ATA pass through:\n");
+ sg_print_sense(NULL, sense_buffer, sb_sz,
((op->verbose > 2) ? 1 : 0));
+ }
if (sg_scsi_normalize_sense(sense_buffer, sb_sz, &ssh)) {
switch (ssh.sense_key) {
case SPC_SK_ILLEGAL_REQUEST:
diff --git a/src/sg_sat_set_features.c b/src/sg_sat_set_features.c
index 1a969372..9f315039 100644
--- a/src/sg_sat_set_features.c
+++ b/src/sg_sat_set_features.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2015 Douglas Gilbert.
+ * Copyright (c) 2006-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.
@@ -47,7 +47,7 @@
#define DEF_TIMEOUT 20
-static const char * version_str = "1.11 20151219";
+static const char * version_str = "1.12 20160126";
static struct option long_options[] = {
{"count", required_argument, 0, 'c'},
@@ -167,9 +167,11 @@ do_set_features(int sg_fd, int feature, int count, uint64_t lba,
if (verbose > 2)
pr2serr("command completed with SCSI GOOD status\n");
} else if ((res > 0) && (res & SAM_STAT_CHECK_CONDITION)) {
- if (verbose > 1)
- sg_print_sense("ATA pass through", sense_buffer, sb_sz,
+ if (verbose > 1) {
+ pr2serr("ATA pass through:\n");
+ sg_print_sense(NULL, sense_buffer, sb_sz,
((verbose > 2) ? 1 : 0));
+ }
if (sg_scsi_normalize_sense(sense_buffer, sb_sz, &ssh)) {
switch (ssh.sense_key) {
case SPC_SK_ILLEGAL_REQUEST:
diff --git a/src/sg_scan_linux.c b/src/sg_scan_linux.c
index 9c52737e..3d405e17 100644
--- a/src/sg_scan_linux.c
+++ b/src/sg_scan_linux.c
@@ -1,5 +1,5 @@
/* A utility program originally written for the Linux OS SCSI subsystem.
- * Copyright (C) 1999 - 2015 D. Gilbert
+ * Copyright (C) 1999 - 2016 D. Gilbert
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -29,7 +29,7 @@
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#include <unistd.h>
@@ -51,7 +51,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "4.11 20151219";
+static const char * version_str = "4.12 20160121";
#define ME "sg_scan: "
diff --git a/src/sg_timestamp.c b/src/sg_timestamp.c
index 2de784b5..72c141f0 100644
--- a/src/sg_timestamp.c
+++ b/src/sg_timestamp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 Douglas Gilbert.
+ * Copyright (c) 2015-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.
@@ -33,7 +33,7 @@
* to the given SCSI device. Based on spc5r07.pdf .
*/
-static const char * version_str = "1.01 20151219";
+static const char * version_str = "1.02 20160126";
#define REP_TIMESTAMP_CMDLEN 12
#define SET_TIMESTAMP_CMDLEN 12
@@ -108,12 +108,13 @@ usage()
"The timestamp\nis SET if either the --milliseconds=MS or "
"--seconds=SEC option is given,\notherwise the existing "
"timestamp is reported. The DEVICE stores the\ntimestamp as "
- "the number of milliseconds since 1970-01-01 00:00:00 UTC\n"
- "which also happens to be the time 'epoch' of Unix "
- "machines. The 'date +%%s'\ncommand in Unix returns the "
- "number of seconds since the epoch. To\nconvert a reported "
- "timestamp (in seconds since the epoch) to a more\nreadable "
- "form use 'date --date='@<secs_since_epoch>' .\n");
+ "the number of milliseconds since power up (or reset) or\n"
+ "since 1970-01-01 00:00:00 UTC which also happens to be the "
+ "time 'epoch'\nof Unix machines. The 'date +%%s' command in "
+ "Unix returns the number of\nseconds since the epoch. To "
+ "convert a reported timestamp (in seconds since\nthe epoch) "
+ "to a more readable form use "
+ "'date --date='@<secs_since_epoch>' .\n");
}
/* Invokes a SCSI REPORT TIMESTAMP command. Return of 0 -> success,
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index c9b8886a..d7591054 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -36,7 +36,7 @@
*/
-static const char * version_str = "1.11 20160104"; /* spc5r07 + sbc4r07 */
+static const char * version_str = "1.12 20160126"; /* spc5r08 + sbc4r10 */
/* These structures are duplicates of those of the same name in
@@ -776,14 +776,6 @@ decode_std_inq(unsigned char * b, int len, int verbose)
printf(" Product_revision_level: %.4s\n", b + 32);
}
-static const char * assoc_arr[] =
-{
- "Addressed logical unit",
- "Target port", /* that received request; unless SCSI ports VPD */
- "Target device that contains addressed lu",
- "Reserved [0x3]",
-};
-
static void
decode_id_vpd(unsigned char * buff, int len, int subvalue,
const struct opts_t * op)
@@ -798,24 +790,25 @@ decode_id_vpd(unsigned char * buff, int len, int subvalue,
m_d = -1;
m_cs = -1;
if (0 == subvalue) {
- decode_dev_ids(assoc_arr[VPD_ASSOC_LU], buff + 4, len - 4,
- VPD_ASSOC_LU, m_d, m_cs, op);
- decode_dev_ids(assoc_arr[VPD_ASSOC_TPORT], buff + 4, len - 4,
- VPD_ASSOC_TPORT, m_d, m_cs, op);
- decode_dev_ids(assoc_arr[VPD_ASSOC_TDEVICE], buff + 4, len - 4,
- VPD_ASSOC_TDEVICE, m_d, m_cs, op);
+ decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_LU), buff + 4,
+ len - 4, VPD_ASSOC_LU, m_d, m_cs, op);
+ decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TPORT), buff + 4,
+ len - 4, VPD_ASSOC_TPORT, m_d, m_cs, op);
+ decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TDEVICE), buff + 4,
+ len - 4, VPD_ASSOC_TDEVICE, m_d, m_cs, op);
} else if (VPD_DI_SEL_AS_IS == subvalue)
decode_dev_ids(NULL, buff + 4, len - 4, m_a, m_d, m_cs, op);
else {
if (VPD_DI_SEL_LU & subvalue)
- decode_dev_ids(assoc_arr[VPD_ASSOC_LU], buff + 4, len - 4,
- VPD_ASSOC_LU, m_d, m_cs, op);
+ decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_LU), buff + 4,
+ len - 4, VPD_ASSOC_LU, m_d, m_cs, op);
if (VPD_DI_SEL_TPORT & subvalue)
- decode_dev_ids(assoc_arr[VPD_ASSOC_TPORT], buff + 4, len - 4,
- VPD_ASSOC_TPORT, m_d, m_cs, op);
+ decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TPORT), buff + 4,
+ len - 4, VPD_ASSOC_TPORT, m_d, m_cs, op);
if (VPD_DI_SEL_TARGET & subvalue)
- decode_dev_ids(assoc_arr[VPD_ASSOC_TDEVICE], buff + 4, len - 4,
- VPD_ASSOC_TDEVICE, m_d, m_cs, op);
+ decode_dev_ids(sg_get_desig_assoc_str(VPD_ASSOC_TDEVICE),
+ buff + 4, len - 4, VPD_ASSOC_TDEVICE, m_d, m_cs,
+ op);
}
}
@@ -858,7 +851,7 @@ decode_net_man_vpd(unsigned char * buff, int len, int do_hex)
ucp = buff + 4;
for (k = 0; k < len; k += bump, ucp += bump) {
printf(" %s, Service type: %s\n",
- assoc_arr[(ucp[0] >> 5) & 0x3],
+ sg_get_desig_assoc_str((ucp[0] >> 5) & 0x3),
network_service_type_arr[ucp[0] & 0x1f]);
na_len = sg_get_unaligned_be16(ucp + 2);
bump = 4 + na_len;
@@ -978,35 +971,6 @@ decode_scsi_ports_vpd(unsigned char * buff, int len, const struct opts_t * op)
}
}
-static const char * code_set_arr[] =
-{
- "Reserved [0x0]",
- "Binary",
- "ASCII",
- "UTF-8",
- "Reserved [0x4]", "Reserved [0x5]", "Reserved [0x6]", "Reserved [0x7]",
- "Reserved [0x8]", "Reserved [0x9]", "Reserved [0xa]", "Reserved [0xb]",
- "Reserved [0xc]", "Reserved [0xd]", "Reserved [0xe]", "Reserved [0xf]",
-};
-
-static const char * desig_type_arr[] =
-{
- "vendor specific [0x0]",
- "T10 vendor identification",
- "EUI-64 based",
- "NAA",
- "Relative target port",
- "Target port group", /* spc4r09: _primary_ target port group */
- "Logical unit group",
- "MD5 logical unit identifier",
- "SCSI name string",
- "Protocol specific port identifier", /* spc4r36 */
- "UUID identifier", /* 15-267r2 */
- "Reserved [0xb]",
- "Reserved [0xc]", "Reserved [0xd]", "Reserved [0xe]", "Reserved [0xf]",
-};
-
-
/* Prints outs an abridged set of device identification designators
selected by association, designator type and/or code set. */
static int
@@ -1218,13 +1182,14 @@ decode_designation_descriptor(const unsigned char * ip, int i_len,
char b[64];
if (print_assoc)
- printf(" %s:\n", assoc_arr[assoc]);
+ printf(" %s:\n", sg_get_desig_assoc_str(assoc & 3));
printf(" designator type: %s, code set: %s\n",
- desig_type_arr[desig_type], code_set_arr[c_set]);
+ sg_get_desig_type_str(desig_type & 0xf),
+ sg_get_desig_code_set_str(c_set & 0xf));
if (piv && ((1 == assoc) || (2 == assoc)))
printf(" transport: %s\n",
sg_get_trans_proto_str(p_id, sizeof(b), b));
- /* printf(" associated with the %s\n", assoc_arr[assoc]); */
+/* printf(" associated with the %s\n", sg_get_desig_assoc_str(assoc)); */
switch (desig_type) {
case 0: /* vendor specific */
k = 0;
@@ -1562,7 +1527,7 @@ decode_dev_ids(const char * print_if_found, unsigned char * buff, int len,
printf(" %s:\n", print_if_found);
}
if (NULL == print_if_found)
- printf(" %s:\n", assoc_arr[assoc]);
+ printf(" %s:\n", sg_get_desig_assoc_str(assoc));
p_id = ((ucp[0] >> 4) & 0xf);
c_set = (ucp[0] & 0xf);
piv = ((ucp[1] & 0x80) ? 1 : 0);
diff --git a/src/sg_write_long.c b/src/sg_write_long.c
index 3f92a9da..f5a32293 100644
--- a/src/sg_write_long.c
+++ b/src/sg_write_long.c
@@ -1,5 +1,5 @@
/* A utility program for the Linux OS SCSI subsystem.
- * Copyright (C) 2004-2015 D. Gilbert
+ * Copyright (C) 2004-2016 D. Gilbert
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -32,7 +32,7 @@
#include "sg_cmds_extra.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.11 20151220";
+static const char * version_str = "1.12 20160121";
#define MAX_XFER_LEN 10000
@@ -86,7 +86,7 @@ usage()
"(default:\n"
" 520 bytes)\n\n"
"Performs a SCSI WRITE LONG (10 or 16) command. Writes a single "
- "block\nincluding associated ECC data. Valid data can be obtained "
+ "block\nincluding associated ECC data. That data may be obtained "
"from the\nSCSI READ LONG command. See the sg_read_long utility.\n"
);
}
diff --git a/src/sg_xcopy.c b/src/sg_xcopy.c
index 9ac5d69f..57369bc8 100644
--- a/src/sg_xcopy.c
+++ b/src/sg_xcopy.c
@@ -30,7 +30,7 @@
#define _XOPEN_SOURCE 600
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE /* resolves u_char typedef in scsi/scsi.h [lk 2.4] */
+#define _GNU_SOURCE 1
#endif
#include <unistd.h>
@@ -63,7 +63,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "0.51 20160104";
+static const char * version_str = "0.53 20160126";
#define ME "sg_xcopy: "
@@ -989,224 +989,11 @@ scsi_operating_parameter(struct xcopy_fp_t *xfp, int is_target)
static void
decode_designation_descriptor(const unsigned char * ucp, int i_len)
{
- int m, p_id, piv, c_set, assoc, desig_type, d_id, naa;
- int k;
- const unsigned char * ip;
- uint64_t vsei;
- char b[64];
-
- ip = ucp + 4;
- p_id = ((ucp[0] >> 4) & 0xf);
- c_set = (ucp[0] & 0xf);
- piv = ((ucp[1] & 0x80) ? 1 : 0);
- assoc = ((ucp[1] >> 4) & 0x3);
- desig_type = (ucp[1] & 0xf);
- pr2serr(" designator type: %d, code set: %d\n", desig_type, c_set);
- if (piv && ((1 == assoc) || (2 == assoc)))
- pr2serr(" transport: %s\n",
- sg_get_trans_proto_str(p_id, sizeof(b), b));
-
- switch (desig_type) {
- case 0: /* vendor specific */
- k = 0;
- if ((1 == c_set) || (2 == c_set)) { /* ASCII or UTF-8 */
- for (k = 0; (k < i_len) && isprint(ip[k]); ++k)
- ;
- if (k >= i_len)
- k = 1;
- }
- if (k)
- pr2serr(" vendor specific: %.*s\n", i_len, ip);
- else {
- pr2serr(" vendor specific:\n");
- dStrHexErr((const char *)ip, i_len, 0);
- }
- break;
- case 1: /* T10 vendor identification */
- pr2serr(" vendor id: %.8s\n", ip);
- if (i_len > 8)
- pr2serr(" vendor specific: %.*s\n", i_len - 8, ip + 8);
- break;
- case 2: /* EUI-64 based */
- if ((8 != i_len) && (12 != i_len) && (16 != i_len)) {
- pr2serr(" << expect 8, 12 and 16 byte EUI, got %d>>\n",
- i_len);
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- pr2serr(" 0x");
- for (m = 0; m < i_len; ++m)
- pr2serr("%02x", (unsigned int)ip[m]);
- pr2serr("\n");
- break;
- case 3: /* NAA */
- if (1 != c_set) {
- pr2serr(" << unexpected code set %d for NAA>>\n", c_set);
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- naa = (ip[0] >> 4) & 0xff;
- if (! ((2 == naa) || (5 == naa) || (6 == naa))) {
- pr2serr(" << unexpected NAA [0x%x]>>\n", naa);
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- if ((5 == naa) && (0x10 == i_len)) {
- if (verbose > 2)
- pr2serr(" << unexpected NAA 5 len 16, assuming NAA 6 "
- ">>\n");
- naa = 6;
- }
- if (2 == naa) {
- if (8 != i_len) {
- pr2serr(" << unexpected NAA 2 identifier length: "
- "0x%x>>\n", i_len);
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- d_id = (((ip[0] & 0xf) << 8) | ip[1]);
- /* c_id = ((ip[2] << 16) | (ip[3] << 8) | ip[4]); */
- /* vsi = ((ip[5] << 16) | (ip[6] << 8) | ip[7]); */
- pr2serr(" 0x");
- for (m = 0; m < 8; ++m)
- pr2serr("%02x", (unsigned int)ip[m]);
- pr2serr("\n");
- } else if (5 == naa) {
- if (8 != i_len) {
- pr2serr(" << unexpected NAA 5 identifier length: "
- "0x%x>>\n", i_len);
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- /* c_id = (((ip[0] & 0xf) << 20) | (ip[1] << 12) | */
- /* (ip[2] << 4) | ((ip[3] & 0xf0) >> 4)); */
- vsei = ip[3] & 0xf;
- for (m = 1; m < 5; ++m) {
- vsei <<= 8;
- vsei |= ip[3 + m];
- }
- pr2serr(" 0x");
- for (m = 0; m < 8; ++m)
- pr2serr("%02x", (unsigned int)ip[m]);
- pr2serr("\n");
- } else if (6 == naa) {
- if (16 != i_len) {
- pr2serr(" << unexpected NAA 6 identifier length: "
- "0x%x>>\n", i_len);
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- /* c_id = (((ip[0] & 0xf) << 20) | (ip[1] << 12) | */
- /* (ip[2] << 4) | ((ip[3] & 0xf0) >> 4)); */
- vsei = ip[3] & 0xf;
- for (m = 1; m < 5; ++m) {
- vsei <<= 8;
- vsei |= ip[3 + m];
- }
- pr2serr(" 0x");
- for (m = 0; m < 16; ++m)
- pr2serr("%02x", (unsigned int)ip[m]);
- pr2serr("\n");
- }
- break;
- case 4: /* Relative target port */
- if ((1 != c_set) || (1 != assoc) || (4 != i_len)) {
- pr2serr(" << expected binary code_set, target port "
- "association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- d_id = sg_get_unaligned_be16(ip + 2);
- pr2serr(" Relative target port: 0x%x\n", d_id);
- break;
- case 5: /* (primary) Target port group */
- if ((1 != c_set) || (1 != assoc) || (4 != i_len)) {
- pr2serr(" << expected binary code_set, target port "
- "association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- d_id = sg_get_unaligned_be16(ip + 2);
- pr2serr(" Target port group: 0x%x\n", d_id);
- break;
- case 6: /* Logical unit group */
- if ((1 != c_set) || (0 != assoc) || (4 != i_len)) {
- pr2serr(" << expected binary code_set, logical unit "
- "association, length 4>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- d_id = sg_get_unaligned_be16(ip + 2);
- pr2serr(" Logical unit group: 0x%x\n", d_id);
- break;
- case 7: /* MD5 logical unit identifier */
- if ((1 != c_set) || (0 != assoc)) {
- pr2serr(" << expected binary code_set, logical unit "
- "association>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- pr2serr(" MD5 logical unit identifier:\n");
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- case 8: /* SCSI name string */
- if (3 != c_set) {
- pr2serr(" << expected UTF-8 code_set>>\n");
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- pr2serr(" SCSI name string:\n");
- /* does %s print out UTF-8 ok??
- * Seems to depend on the locale. Looks ok here with my
- * locale setting: en_AU.UTF-8
- */
- pr2serr(" %s\n", (const char *)ip);
- break;
- case 9: /* Protocol specific port identifier */
- /* added in spc4r36, PIV must be set, proto_id indicates */
- /* whether UAS (USB) or SOP (PCIe) or ... */
- if (! piv)
- pr2serr(" >>>> Protocol specific port identifier "
- "expects protocol\n"
- " identifier to be valid and it is not\n");
- if (TPROTO_UAS == p_id) {
- pr2serr(" USB device address: 0x%x\n", 0x7f & ip[0]);
- pr2serr(" USB interface number: 0x%x\n", ip[2]);
- } else if (TPROTO_SOP == p_id) {
- pr2serr(" PCIe routing ID, bus number: 0x%x\n", ip[0]);
- pr2serr(" function number: 0x%x\n", ip[1]);
- pr2serr(" [or device number: 0x%x, function number: "
- "0x%x]\n", (0x1f & (ip[1] >> 3)), 0x7 & ip[1]);
- } else
- pr2serr(" >>>> unexpected protocol indentifier: 0x%x\n"
- " with Protocol specific port "
- "identifier\n", p_id);
- break;
- case 0xa: /* UUID identifier */
- if (1 != c_set) {
- pr2serr(" << expected binary code_set >>\n");
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- if ((1 != ((ip[0] >> 4) & 0xf)) || (18 != i_len)) {
- pr2serr(" << expected locally assigned UUID, 16 bytes long "
- ">>\n");
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
- printf(" Locally assigned UUID: ");
- for (m = 0; m < 16; ++m) {
- if ((4 == m) || (6 == m) || (8 == m) || (10 == m))
- printf("-");
- printf("%02x", (unsigned int)ip[2 + m]);
- }
- printf("\n");
- break;
- default: /* reserved */
- pr2serr(" reserved designator=0x%x\n", desig_type);
- dStrHexErr((const char *)ip, i_len, 0);
- break;
- }
+ char c[2048];
+
+ sg_get_designation_descriptor_str(NULL, ucp, i_len, 1, verbose,
+ sizeof(c), c);
+ pr2serr("%s", c);
}
static int
diff --git a/src/sginfo.c b/src/sginfo.c
index 3597847d..60edb666 100644
--- a/src/sginfo.c
+++ b/src/sginfo.c
@@ -119,7 +119,7 @@
#define _XOPEN_SOURCE 500
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
static const char * version_str = "2.35 [20140403]";
diff --git a/src/sgm_dd.c b/src/sgm_dd.c
index 8a0a76f5..90f2938f 100644
--- a/src/sgm_dd.c
+++ b/src/sgm_dd.c
@@ -1,7 +1,7 @@
/* A utility program for copying files. Specialised for "files" that
* represent devices that understand the SCSI command set.
*
- * Copyright (C) 1999 - 2015 D. Gilbert and P. Allworth
+ * Copyright (C) 1999 - 2016 D. Gilbert and P. Allworth
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -31,7 +31,7 @@
#define _XOPEN_SOURCE 500
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#include <unistd.h>
diff --git a/src/sgp_dd.c b/src/sgp_dd.c
index 9aa653e1..661925d5 100644
--- a/src/sgp_dd.c
+++ b/src/sgp_dd.c
@@ -1,7 +1,7 @@
/* A utility program for copying files. Specialised for "files" that
* represent devices that understand the SCSI command set.
*
- * Copyright (C) 1999 - 2015 D. Gilbert and P. Allworth
+ * Copyright (C) 1999 - 2016 D. Gilbert and P. Allworth
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -25,7 +25,7 @@
#define _XOPEN_SOURCE 500
#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
+#define _GNU_SOURCE 1
#endif
#include <unistd.h>
@@ -58,7 +58,7 @@
#include "sg_pr2serr.h"
-static const char * version_str = "5.51 20151219";
+static const char * version_str = "5.52 20160121";
#define DEF_BLOCK_SIZE 512
#define DEF_BLOCKS_PER_TRANSFER 128
diff --git a/utils/tst_sg_lib.c b/utils/tst_sg_lib.c
index f1c20d91..4755c806 100644
--- a/utils/tst_sg_lib.c
+++ b/utils/tst_sg_lib.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 Douglas Gilbert.
+ * Copyright (c) 2013-2015 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.
@@ -25,24 +25,25 @@
*
*/
-static char * version_str = "1.02 20151127";
+static char * version_str = "1.03 20160126";
#define MAX_LINE_LEN 1024
static struct option long_options[] = {
- {"dtsrhex", 0, 0, 'd'},
- {"help", 0, 0, 'h'},
- {"printf", 0, 0, 'p'},
- {"sense", 0, 0, 's'},
- {"unaligned", 0, 0, 'u'},
- {"verbose", 0, 0, 'v'},
- {"version", 0, 0, 'V'},
- {0, 0, 0, 0},
+ {"dtsrhex", no_argument, 0, 'd'},
+ {"help", no_argument, 0, 'h'},
+ {"leadin", required_argument, 0, 'l'},
+ {"printf", no_argument, 0, 'p'},
+ {"sense", no_argument, 0, 's'},
+ {"unaligned", no_argument, 0, 'u'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
+ {0, 0, 0, 0}, /* sentinel */
};
-const unsigned char desc_sense_data1[] = {
+static const unsigned char desc_sense_data1[] = {
/* unrec_err, excessive_writes, sdat_ovfl, additional_len=? */
0x72, 0x1, 0x3, 0x2, 0x80, 0x0, 0x0, 12+12+8+4+8+4+28,
/* Information: 0x11223344556677bb */
@@ -64,7 +65,7 @@ const unsigned char desc_sense_data1[] = {
2,0,0x12,0x34,
};
-const unsigned char desc_sense_data2[] = {
+static const unsigned char desc_sense_data2[] = {
/* ill_req, inv fld in para list, additional_len=? */
0x72, 0x5, 0x26, 0x0, 0x0, 0x0, 0x0, 8+4,
/* sense key specific: SKSV=1, C/D*=0, bitp=7 bytep=34 */
@@ -73,23 +74,83 @@ const unsigned char desc_sense_data2[] = {
0x3, 0x2, 0x0, 0x45,
};
+static const unsigned char desc_sense_data3[] = {
+ /* medium err, vibration induced ..., additional_len=? */
+ 0x72, 0x3, 0x9, 0x5, 0x0, 0x0, 0x0, 32+16,
+ /* 0xd: block dev: sense key specific: SKSV=1, retry_count=257, fru=0x45
+ * info=0x1122334455, command_specific=0x1 */
+ 0xd, 0x1e, 0xa0, 0x0, 0x80, 0x1, 0x1, 0x45,
+ 0x0, 0x0, 0x0, 0x11, 0x22, 0x33, 0x44, 0x55,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
+ /* following sbc3 (standard) and sbc4r10 inconsistency; add padding */
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ /* 0xe: reason: send_to_given+henceforth, lu, naa-5, 0x5333333000001f40 */
+ 0xe, 0xe, 0x0, 0x1, 0x1, 0x3, 0x0, 0x8,
+ 0x53, 0x33, 0x33, 0x30, 0x0, 0x0, 0x1f, 0x40,
+ };
+
+static const unsigned char desc_sense_data4[] = {
+ /* ill_req, inv fld in para list, additional_len=? */
+ 0x72, 0x5, 0x26, 0x0, 0x0, 0x0, 0x0, 24,
+ /* Forwarded sense data, FSDT=0, sd_src=7, f_status=2 */
+ 0xc, 22, 0x7, 0x2,
+ /* ill_req, inv fld in para list, additional_len=? */
+ 0x72, 0x5, 0x26, 0x0, 0x0, 0x0, 0x0, 8+4,
+ /* sense key specific: SKSV=1, C/D*=0, bitp=7 bytep=34 */
+ 0x2, 0x6, 0x0, 0x0, 0x8f, 0x0, 0x34, 0x0,
+ /* field replaceable code=0x45 */
+ 0x3, 0x2, 0x0, 0x45,
+ };
+
+static const unsigned char desc_sense_data5[] = {
+ /* no_sense, ATA info available */
+ 0x72, 0x0, 0x0, 0x1d, 0x0, 0x0, 0x0, 14+14,
+ /* ATA descriptor extend=1 */
+ 0x9, 0xc, 0x1, 0x0, 0x34, 0x12, 0x44, 0x11,
+ 0x55, 0x22, 0x66, 0x33, 0x1, 0x0,
+ /* ATA descriptor extend=0 */
+ 0x9, 0xc, 0x0, 0x0, 0x34, 0x12, 0x44, 0x11,
+ 0x55, 0x22, 0x66, 0x33, 0x1, 0x0,
+ };
+
+static const unsigned char desc_sense_data6[] = {
+ /* UA, req, subsidiary bindinganged */
+ 0x72, 0x6, 0x3f, 0x1a, 0x0, 0x0, 0x0, 26+12+12,
+ /* 0xe: designator, reason: preferred admin lu, uuid */
+ 0xe, 0x18, 0x0, 0x4, 0x1, 0xa, 0x0, 0x12,
+ 0x10, 0x0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
+ 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
+ 0xfe, 0xdc,
+ /* 0x0: Information(valid): lun */
+ 0x0, 0xa, 0x80, 0x0,
+ 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+ /* 0x1: Command specific: 0x1 */
+ 0x1, 0xa, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1,
+ };
+
+static const char * leadin = NULL;
+
static void
usage()
{
- fprintf(stderr, "Usage: "
- "tst_sg_lib [--dstrhex] [--help] [--printf] [--sense] "
- "[--unaligned]\n"
- " [--verbose] [--version]\n"
- " where: --dstrhex|-d test dStrHex* variants\n"
- " --help|-h print out usage message\n"
- " --printf|-p test library printf variants\n"
- " --sense|-s test sense data handling\n"
- " --unaligned|-u test unaligned data handling\n"
- " --verbose|-v increase verbosity\n"
- " --version|-V print version string and exit\n\n"
- "Test various parts of sg_lib, see options\n"
- );
+ fprintf(stderr,
+ "Usage: tst_sg_lib [--dstrhex] [--help] [--leadin=STR] "
+ "[--printf] [--sense]\n"
+ " [--unaligned] [--verbose] [--version]\n"
+ " where: --dstrhex|-d test dStrHex* variants\n"
+ " --help|-h print out usage message\n"
+ " --leadin=STR|-l STR every line output by --sense "
+ "should\n"
+ " be prefixed by STR\n"
+ " --printf|-p test library printf variants\n"
+ " --sense|-s test sense data handling\n"
+ " --unaligned|-u test unaligned data handling\n"
+ " --verbose|-v increase verbosity\n"
+ " --version|-V print version string and exit\n\n"
+ "Test various parts of sg_lib, see options\n"
+ );
}
@@ -130,7 +191,7 @@ main(int argc, char * argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "dhpsuvV", long_options,
+ c = getopt_long(argc, argv, "dhl:psuvV", long_options,
&option_index);
if (c == -1)
break;
@@ -143,6 +204,9 @@ main(int argc, char * argv[])
case '?':
usage();
return 0;
+ case 'l':
+ leadin = optarg;
+ break;
case 'p':
++do_printf;
break;
@@ -176,18 +240,38 @@ main(int argc, char * argv[])
if (do_sense ) {
++did_something;
- sg_print_sense("desc_sense_data test1", desc_sense_data1,
- (int)sizeof(desc_sense_data1), 1);
+ printf("desc_sense_data test1:\n");
+ sg_print_sense(leadin, desc_sense_data1,
+ (int)sizeof(desc_sense_data1), verbose);
printf("\n");
#if 1
- sg_get_sense_str("sg_get_sense_str(ds_data1)", desc_sense_data1,
- sizeof(desc_sense_data1), 1, sizeof(b), b);
+ printf("sg_get_sense_str(ds_data1):\n");
+ sg_get_sense_str(leadin, desc_sense_data1,
+ sizeof(desc_sense_data1), verbose, sizeof(b), b);
printf("sg_get_sense_str: strlen(b)->%zd\n", strlen(b));
printf("%s", b);
printf("\n");
#endif
- sg_print_sense("desc_sense_data test2", desc_sense_data2,
- (int)sizeof(desc_sense_data2), 1);
+ printf("desc_sense_data test2\n");
+ sg_print_sense(leadin, desc_sense_data2,
+ (int)sizeof(desc_sense_data2), verbose);
+ printf("\n");
+ printf("desc_sense block dev combo plus designator test3\n");
+ sg_print_sense(leadin, desc_sense_data3,
+ (int)sizeof(desc_sense_data3), verbose);
+ printf("\n");
+ printf("desc_sense forwarded sense test4\n");
+ sg_print_sense(leadin, desc_sense_data4,
+ (int)sizeof(desc_sense_data4), verbose);
+ printf("\n");
+ printf("desc_sense ATA Info test5\n");
+ sg_print_sense(leadin, desc_sense_data5,
+ (int)sizeof(desc_sense_data5), verbose);
+ printf("\n");
+ printf("desc_sense UA subsidiary binfing changed test6\n");
+ sg_print_sense(leadin, desc_sense_data6,
+ (int)sizeof(desc_sense_data6), verbose);
+ printf("\n");
printf("\n");
}