aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--doc/sg_decode_sense.84
-rw-r--r--doc/sg_format.82
-rw-r--r--doc/sg_inq.82
-rw-r--r--doc/sg_luns.88
-rw-r--r--doc/sg_persist.88
-rw-r--r--doc/sg_rtpg.82
-rw-r--r--doc/sg_vpd.827
-rw-r--r--lib/sg_lib_data.c12
-rw-r--r--src/sg_inq.c2
-rw-r--r--src/sg_inq_data.c7
-rw-r--r--src/sg_logs.c33
-rw-r--r--src/sg_opcodes.c2
-rw-r--r--src/sg_vpd.c87
-rw-r--r--src/sg_vpd_vendor.c140
-rw-r--r--src/sg_wr_mode.c10
-rw-r--r--src/sg_write_buffer.c2
17 files changed, 274 insertions, 80 deletions
diff --git a/ChangeLog b/ChangeLog
index 2e0fe5f5..2b2ebdcc 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.39 [20140517] [svn: r578]
+Changelog for sg3_utils-1.39 [20140519] [svn: r579]
- sg_ses: add --eiioe=auto|force option
- fix AES dpage element indexing problems
- add --readonly option
@@ -16,6 +16,8 @@ Changelog for sg3_utils-1.39 [20140517] [svn: r578]
- add --readonly option
- sg_persist: add --readonly option, environment
variable SG_PERSIST_IN_RDONLY sets ro on prin cmds
+ - sg_inq: sync version descriptors dated 20105176
+ - sg_vpd: add --vendor=VP option
- sg_copy_results, sg_get_lba_status, sg_luns,
sg_read_buffer, sg_readcap, sg_referrals, sg_rtpg,
sg_sat_set_features, sg_sat_identify:
@@ -28,6 +30,8 @@ Changelog for sg3_utils-1.39 [20140517] [svn: r578]
- add sg_get_category_sense_str() to API
- add initial zbc service actions
- dStrHex(Err): fix output truncation error
+ - sg_lib_data: sync asc/ascq codes with T10 20140516
+ - sync operation code with T10 20140515
- win32: sg_scan, sg_ses and sg_log fixes
- examples/sgq_dd: re-add old utility as example
diff --git a/doc/sg_decode_sense.8 b/doc/sg_decode_sense.8
index 47817d80..63fe4152 100644
--- a/doc/sg_decode_sense.8
+++ b/doc/sg_decode_sense.8
@@ -1,4 +1,4 @@
-.TH SG_DECODE_SENSE "8" "March 2014" "sg3_utils\-1.38" SG3_UTILS
+.TH SG_DECODE_SENSE "8" "May 2014" "sg3_utils\-1.39" SG3_UTILS
.SH NAME
sg_decode_sense \- decode SCSI sense data
.SH SYNOPSIS
@@ -12,7 +12,7 @@ sg_decode_sense \- decode SCSI sense data
This utility takes SCSI sense data in binary or as a sequence of
ASCII hexadecimal bytes and decodes it. The primary reference for the
decoding is SPC\-3 ANSI INCITS 408-2005 and the most recent draft
-SPC\-4 revision 36s which can be found at http://www.t10.org and other
+SPC\-4 revision 37 which can be found at http://www.t10.org and other
locations on the internet.
.PP
SCSI sense data is often found in kernel log files as a result of
diff --git a/doc/sg_format.8 b/doc/sg_format.8
index f2d00801..13e07475 100644
--- a/doc/sg_format.8
+++ b/doc/sg_format.8
@@ -1,4 +1,4 @@
-.TH SG_FORMAT "8" "April 2014" "sg3_utils\-1.39" SG3_UTILS
+.TH SG_FORMAT "8" "May 2014" "sg3_utils\-1.39" SG3_UTILS
.SH NAME
sg_format \- format, resize or modify protection information of a SCSI disk
.SH SYNOPSIS
diff --git a/doc/sg_inq.8 b/doc/sg_inq.8
index 30e1fd97..504298ea 100644
--- a/doc/sg_inq.8
+++ b/doc/sg_inq.8
@@ -48,7 +48,7 @@ If the \fI\-\-ata\fR option is given then the SCSI INQUIRY is not performed
and the \fIDEVICE\fR is assumed to be ATA (or ATAPI).
.PP
The reference document used for interpreting an INQUIRY is T10/1713\-D
-Revision 36q (SPC\-4, 12 February 2014) found at http://www.t10.org .
+Revision 37 (SPC\-4, 17 May 2014) found at http://www.t10.org .
Obsolete and reserved items in the standard INQUIRY response output are
displayed in brackets. The reference document for the ATA IDENTIFY (PACKET)
DEVICE command is ATA8\-ACS found at http://www.t13.org .
diff --git a/doc/sg_luns.8 b/doc/sg_luns.8
index 529b38a0..45f0befe 100644
--- a/doc/sg_luns.8
+++ b/doc/sg_luns.8
@@ -73,7 +73,7 @@ The default is to open it read\-write.
this option sets the SELECT REPORT field (\fISR\fR) in the SCSI REPORT
LUNS command. The default value is 0. Hexadecimal values may be given with
a leading "0x" or a trailing "h". For detailed information see the
-REPORT LUNS command in SPC (most recent is SPC\-4 revision 36s in section
+REPORT LUNS command in SPC (most recent is SPC\-4 revision 37 in section
6.33). To simplify, for the I_T nexus associated with the \fIDEVICE\fR, the
meanings of the \fISR\fR values defined to date for SPC\-4 are:
.br
@@ -91,9 +91,9 @@ meanings of the \fISR\fR values defined to date for SPC\-4 are:
.br
subsidiary LUs
.br
-Values between 0xf8 and 0xff (inclusive) are vendor specific (SPC\-4 rev
-36e), other values greater than 2 are reserved. This utility will accept
-any value between 0 and 255 (0xff) for \fISR\fR .
+Values between 0xf8 and 0xff (inclusive) are vendor specific (added
+SPC\-4 rev 36e), other values greater than 2 are reserved. This utility
+will accept any value between 0 and 255 (0xff) for \fISR\fR .
.TP
\fB\-t\fR, \fB\-\-test\fR=\fIALUN\fR
\fIALUN\fR is assumed to be a hexadecimal number in ASCII hex or the
diff --git a/doc/sg_persist.8 b/doc/sg_persist.8
index 03904525..af11edea 100644
--- a/doc/sg_persist.8
+++ b/doc/sg_persist.8
@@ -36,7 +36,7 @@ READ RESERVATION, REPORT CAPABILITIES and READ FULL STATUS.
Before trying to change Persistent reservations and registrations users
should be aware of what they are doing. The relevant sections of the SCSI
Primary Commands document (i.e. SPC\-4 whose most recent draft is revision
-36s dated 21 March 2014) are sections 5.12 (titled "Reservations"),
+37 dated 17 May 2014) are sections 5.12 (titled "Reservations"),
6.15 (for the PRIN command) and 6.16 (for the PROUT command). To safeguard
against accidental use, the \fI\-\-out\fR option must be given when a
PROUT sub\-command (e.g. \fI\-\-register\fR) is used.
@@ -149,7 +149,7 @@ exclusive access \- registrants only, 7\-> write exclusive \- all registrants,
8\-> exclusive access \- all registrants. Default value is 0 (which is
an invalid type). Each "persistent reservation type" is explained in more
detail in a subsection of that name in the read reservation section of
-the PRIN command (section 6.15.3.3 of SPC\-4 revision 36s).
+the PRIN command (section 6.15.3.3 of SPC\-4 revision 37).
.TP
\fB\-s\fR, \fB\-\-read\-full\-status\fR
Read Full Status is a sub\-command of the PRIN command. For each registration
@@ -263,8 +263,8 @@ output usage message. Ignore all other parameters.
.SH TRANSPORT IDs
TransportIDs are used in persistent reservations to identify initiators.
The format of a TransportID differs depending on the type of transport
-being used. Their format is described in SPC\-4 (in draft revision
-36s see section 7.6.4).
+being used. Their format is described in SPC\-4 (in draft revision 37 see
+section 7.6.4).
.PP
A TransportID is required for the PROUT 'register and move' sub\-command and
the PROUT 'register' sub\-command can have zero, one or more TransportIDs.
diff --git a/doc/sg_rtpg.8 b/doc/sg_rtpg.8
index 3cd95929..c4b8d5b1 100644
--- a/doc/sg_rtpg.8
+++ b/doc/sg_rtpg.8
@@ -12,7 +12,7 @@ Send a SCSI REPORT TARGET PORT GROUPS command to \fIDEVICE\fR and
outputs the response.
.PP
Target port group access is described in SPC\-3 and SPC\-4 found at
-www.t10.org . The most recent draft of SPC\-4 is revision 36t in which
+www.t10.org . The most recent draft of SPC\-4 is revision 37 in which
target port groups are described in section 5.15 .
.SH OPTIONS
Arguments to long options are mandatory for short options as well.
diff --git a/doc/sg_vpd.8 b/doc/sg_vpd.8
index 5c51cdf9..6281adb8 100644
--- a/doc/sg_vpd.8
+++ b/doc/sg_vpd.8
@@ -5,8 +5,8 @@ sg_vpd \- fetch SCSI VPD page and/or decode its response
.B sg_vpd
[\fI\-\-enumerate\fR] [\fI\-\-help\fR] [\fI\-\-hex\fR] [\fI\-\-ident\fR]
[\fI\-\-inhex=FN\fR] [\fI\-\-long\fR] [\fI\-\-maxlen=LEN\fR]
-[\fI\-\-page=PG\fR] [\fI\-\-quiet\fR] [\fI\-\-raw\fR] [\fI\-\-verbose\fR]
-[\fI\-\-version\fR] \fIDEVICE\fR
+[\fI\-\-page=PG\fR] [\fI\-\-quiet\fR] [\fI\-\-raw\fR] [\fI\-\-vendor=VP\fR]
+[\fI\-\-verbose\fR] [\fI\-\-version\fR] \fIDEVICE\fR
.SH DESCRIPTION
.\" Add any additional description here
.PP
@@ -24,7 +24,7 @@ has been flagged as mandatory. This page can be fetched by
using the \fI\-\-ident\fR option.
.PP
The reference document used for interpreting VPD pages (and the INQUIRY
-standard response) is T10/1713\-D Revision 36q (SPC\-4, 12 February 2014)
+standard response) is T10/1713\-D Revision 37 (SPC\-4, 17 May 2014)
found at http://www.t10.org .
.PP
When no options are given, other than a \fIDEVICE\fR, then the "Supported
@@ -89,13 +89,13 @@ badly (and do not support VPD pages) then the safest value to use for
.TP
\fB\-p\fR, \fB\-\-page\fR=\fIPG\fR
where \fIPG\fR is the VPD page to be decoded or output. The \fIPG\fR argument
-can either be an abbreviation, a number or a pair or numbers separated by a
-comma. The VPD page abbreviations can be seen by using the \fI\-\-enumerate\fR
-option. If a number is given it is assumed to be decimal unless it has a
-hexadecimal indicator which is either a leading '0x' or a trailing 'h'. If
-one number is given then it is assumed to be a VPD page number. If two
-numbers are given the second number indicates which vendor specific VPD page
-to decode when several pages share the same VPD page number. If this option
+can either be an abbreviation, a number or a pair or numbers/abbreviations
+separated by a comma. The VPD page abbreviations can be seen by using the
+\fI\-\-enumerate\fR option. If a number is given it is assumed to be decimal
+unless it has a hexadecimal indicator which is either a leading '0x' or a
+trailing 'h'. If one number is given then it is assumed to be a VPD page
+number. If two numbers (or abbreviations) are given then the second one is
+the same as \fIVP\fR (see the \fI\-\-vendor=VP\fR option). If this option
is not given (nor '\-i', '\-l' nor '\-V') then the "Supported VPD pages" (0x0)
VPD page is fetched and decoded. If \fIPG\fR is '\-1' or 'sinq' then the
standard INQUIRY response is output. This option may also be used with the
@@ -112,6 +112,13 @@ used. The binary is sent to stdout, and errors are sent to stderr.
if used with \fI\-\-inhex=FN\fR then the contents of \fIFN\fR is treated as
binary.
.TP
+\fB\-M\fR, \fB\-\-vendor\fR=\fIVP\fR
+where \fIVP\fR is a vendor (e.g. "sea" for Seagate) or vendor/product
+acronym (e.g. "hp3par" for the 3PAR array from HP). Many vendors have re-used
+the numbers at the beginning of the vendor specific VPD page range (e.g.
+page 0xc0) and this option is a way of selecting only those which are of
+interest. Using a \fIVP\fR of "xxx" will list the available acronyms.
+.TP
\fB\-v\fR, \fB\-\-verbose\fR
increases the level or verbosity.
.TP
diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c
index a7968094..34c4c6fc 100644
--- a/lib/sg_lib_data.c
+++ b/lib/sg_lib_data.c
@@ -17,7 +17,7 @@
#endif
-const char * sg_lib_version_str = "1.99 20140514"; /* spc4r36s, sbc4r01 */
+const char * sg_lib_version_str = "2.00 20140518"; /* spc4r36u, sbc4r01 */
#ifdef SG_SCSI_STRINGS
struct sg_lib_value_name_t sg_lib_normal_opcodes[] = {
@@ -158,6 +158,7 @@ struct sg_lib_value_name_t sg_lib_normal_opcodes[] = {
{0x92, PDT_TAPE, "Locate(16)"},
{0x93, 0, "Write same(16)"},
{0x93, PDT_TAPE, "Erase(16)"},
+ {0x9c, 0, "Write atomic(16)"},
{0x9d, 0, "Service action bidirectional"}, /* added spc4r35 */
{0x9e, 0, "Service action in(16)"},
{0x9f, 0, "Service action out(16)"},
@@ -492,7 +493,7 @@ struct sg_lib_value_name_t sg_lib_variable_length_arr[] = {
/* A conveniently formatted list of SCSI ASC/ASCQ codes and their
* corresponding text can be found at: www.t10.org/lists/asc-num.txt
- * The following should match asc-num.txt dated 20140320 */
+ * The following should match asc-num.txt dated 20140516 */
#ifdef SG_SCSI_STRINGS
struct sg_lib_asc_ascq_range_t sg_lib_asc_ascq_range[] =
@@ -532,6 +533,7 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x00,0x1e,"Conflicting SA creation request"},
{0x00,0x1f,"Logical unit transitioning to another power condition"},
{0x00,0x20,"Extended copy information available"},
+ {0x00,0x21,"Atomic command aborted due to ACA"},
{0x01,0x00,"No index/sector signal"},
{0x02,0x00,"No seek complete"},
{0x03,0x00,"Peripheral device write fault"},
@@ -556,6 +558,7 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x04,0x0c,"Logical unit "
"not accessible, target port in unavailable state"},
{0x04,0x0d,"Logical unit not ready, structure check required"},
+ {0x04,0x0e,"Logical unit not ready, security session in progress"},
{0x04,0x10,"Logical unit not ready, "
"auxiliary memory not accessible"},
{0x04,0x11,"Logical unit not ready, "
@@ -723,6 +726,10 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x21,0x01,"Invalid element address"},
{0x21,0x02,"Invalid address for write"},
{0x21,0x03,"Invalid write crossing layer jump"},
+ {0x21,0x04,"Unaligned write command"},
+ {0x21,0x05,"Write boundary violation"},
+ {0x21,0x06,"Attempt to read invalid data"},
+ {0x21,0x07,"Read boundary violation"},
{0x22,0x00,"Illegal function (use 20 00, 24 00, or 26 00)"},
{0x23,0x00,"Invalid token operation, cause not reportable"},
{0x23,0x01,"Invalid token operation, unsupported token type"},
@@ -773,6 +780,7 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x27,0x05,"Permanent write protect"},
{0x27,0x06,"Conditional write protect"},
{0x27,0x07,"Space allocation failed write protect"},
+ {0x27,0x08,"Zone is read only"},
{0x28,0x00,"Not ready to ready change, medium may have changed"},
{0x28,0x01,"Import or export element accessed"},
{0x28,0x02,"Format-layer may have changed"},
diff --git a/src/sg_inq.c b/src/sg_inq.c
index 7665384a..642d75d5 100644
--- a/src/sg_inq.c
+++ b/src/sg_inq.c
@@ -41,7 +41,7 @@
#include "sg_cmds_basic.h"
#include "sg_pt.h"
-static const char * version_str = "1.37 20140514"; /* SPC-4 rev 36t */
+static const char * version_str = "1.38 20140518"; /* SPC-4 rev 37 */
/* INQUIRY notes:
* It is recommended that the initial allocation length given to a
diff --git a/src/sg_inq_data.c b/src/sg_inq_data.c
index 5af8864e..2dc08a7f 100644
--- a/src/sg_inq_data.c
+++ b/src/sg_inq_data.c
@@ -49,7 +49,8 @@ struct sg_version_descriptor {
};
/* table from SPC-4 revision 36 [sorted numerically (from Annex E.9)] */
-/* Can also be obtained from : http://www.t10.org/lists/stds.txt 20140320 */
+/* Can also be obtained from : http://www.t10.org/lists/stds.txt 20140517 */
+
#ifdef SG_SCSI_STRINGS
struct sg_version_descriptor sg_version_descriptor_arr[] = {
@@ -188,6 +189,7 @@ struct sg_version_descriptor sg_version_descriptor_arr[] = {
{0x462, "SPC-4 T10/BSR INCITS 513 revision 18"},
{0x463, "SPC-4 T10/BSR INCITS 513 revision 23"},
{0x466, "SPC-4 T10/BSR INCITS 513 revision 36"},
+ {0x468, "SPC-4 T10/BSR INCITS 513 revision 37"},
{0x480, "SMC-3 (no version claimed)"},
{0x482, "SMC-3 T10/1730-D revision 15"},
{0x482, "SMC-3 T10/1730-D revision 16"},
@@ -337,6 +339,8 @@ struct sg_version_descriptor sg_version_descriptor_arr[] = {
{0xc4a, "SAS-2.1 T10/2125-D revision 06"},
{0xc4b, "SAS-2.1 T10/2125-D revision 07"},
{0xc4e, "SAS-2.1 ANSI INCITS 478-2011"},
+ {0xc4f, "SAS-2.1 ANSI INCITS 478-2011 w/ Amnd 1 ANSI INCITS "
+ "478/AM1-2014"},
{0xc60, "SAS-3 (no version claimed)"},
{0xc63, "SAS-3 T10/BSR INCITS 519 revision 05a"},
{0xc65, "SAS-3 T10/BSR INCITS 519 revision 06"},
@@ -486,6 +490,7 @@ struct sg_version_descriptor sg_version_descriptor_arr[] = {
{0x20c8, "SPL-2 ANSI INCITS 505-2013"},
{0x20e0, "SPL-3 (no version claimed)"},
{0x20e4, "SPL-3 T10/BSR INCITS 492 revision 6"},
+ {0x20e6, "SPL-3 T10/BSR INCITS 492 revision 7"},
{0x2100, "SPL-4 (no version claimed)"},
{0x21e0, "SOP (no version claimed)"},
{0x21e4, "SOP T10/BSR INCITS 489 revision 4"},
diff --git a/src/sg_logs.c b/src/sg_logs.c
index 841c8a13..ee539116 100644
--- a/src/sg_logs.c
+++ b/src/sg_logs.c
@@ -28,7 +28,7 @@
#include "sg_cmds_basic.h"
#include "sg_pt.h" /* needed for scsi_pt_win32_direct() */
-static const char * version_str = "1.22 20140514"; /* spc4r36t + sbc4r01 */
+static const char * version_str = "1.23 20140518"; /* spc4r37 + sbc4r01 */
#define MX_ALLOC_LEN (0xfffc)
#define SHORT_RESP_LEN 128
@@ -908,7 +908,7 @@ do_logs(int sg_fd, unsigned char * resp, int mx_resp_len,
op->subpg_code, op->paramp,
resp, LOG_SENSE_PROBE_ALLOC_LEN,
1 /* noisy */, vb)))
- return res;
+ return res;
actual_len = (resp[2] << 8) + resp[3] + 4;
if ((0 == op->do_raw) && (vb > 1)) {
pr2serr(" Log sense (find length) response:\n");
@@ -936,7 +936,7 @@ do_logs(int sg_fd, unsigned char * resp, int mx_resp_len,
op->page_control, op->pg_code,
op->subpg_code, op->paramp,
resp, actual_len, 1 /* noisy */, vb)))
- return res;
+ return res;
if ((0 == op->do_raw) && (vb > 1)) {
pr2serr(" Log sense response:\n");
dStrHexErr((const char *)resp, actual_len, 1);
@@ -1115,6 +1115,33 @@ show_page_name(int pg_code, int subpg_code,
case 0x32:
printf("%sData compression (IBM specific)\n", b);
break;
+ case 0x33:
+ printf("%sWrite errors (IBM specific)\n", b);
+ break;
+ case 0x34:
+ printf("%sRead forward errors (IBM specific)\n", b);
+ break;
+ case 0x37:
+ printf("%sPerformance characteristics (IBM specific)\n", b);
+ break;
+ case 0x38:
+ printf("%sBlocks/bytes transferred (IBM specific)\n", b);
+ break;
+ case 0x39:
+ printf("%sHost port 0 interface errors (IBM specific)\n", b);
+ break;
+ case 0x3a:
+ printf("%sDrive control verification (IBM specific)\n", b);
+ break;
+ case 0x3b:
+ printf("%sHost port 1 interface errors (IBM specific)\n", b);
+ break;
+ case 0x3c:
+ printf("%sDrive usage information (IBM specific)\n", b);
+ break;
+ case 0x3d:
+ printf("%sSubsystem statistics (IBM specific)\n", b);
+ break;
default:
done = 0;
break;
diff --git a/src/sg_opcodes.c b/src/sg_opcodes.c
index 9aac9fff..4c8fe51f 100644
--- a/src/sg_opcodes.c
+++ b/src/sg_opcodes.c
@@ -26,7 +26,7 @@
#include "sg_pt.h"
-static const char * version_str = "0.39 20140515"; /* spc4r36t */
+static const char * version_str = "0.40 20140518"; /* spc4r37 */
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index 1f2aa1c1..18ef28f8 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -33,15 +33,18 @@
*/
-static const char * version_str = "0.82 20140514"; /* spc4r36s + sbc4r01 */
+static const char * version_str = "0.83 20140519"; /* spc4r37 + sbc4r01 */
/* And with sbc3r35, vale Mark Evans */
void svpd_enumerate_vendor(void);
-int svpd_search_vendor_vpds(int num_vpd);
+int svpd_count_vendor_vpds(int num_vpd, int vp_num);
int svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue, int maxlen,
int do_hex, int do_raw, int do_long, int do_quiet,
int verbose);
const struct svpd_values_name_t * svpd_find_vendor_by_acron(const char * ap);
+int svpd_find_vp_num_by_acron(const char * vp_ap);
+const struct svpd_values_name_t * svpd_find_vendor_by_num(int page_num,
+ int vp_num);
/* standard VPD pages, in ascending page number order */
@@ -129,6 +132,7 @@ static struct option long_options[] = {
{"page", required_argument, 0, 'p'},
{"quiet", no_argument, 0, 'q'},
{"raw", no_argument, 0, 'r'},
+ {"vendor", required_argument, 0, 'M'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{0, 0, 0, 0},
@@ -217,7 +221,7 @@ usage()
"[--inhex=fn]\n"
" [--long] [--maxlen=LEN] [--page=PG] [--quiet] "
"[--raw]\n"
- " [--verbose] [--version] DEVICE\n");
+ " [--vendor=VP] [--verbose] [--version] DEVICE\n");
pr2serr(" where:\n"
" --enumerate|-e enumerate known VPD pages names (ignore "
"DEVICE),\n"
@@ -242,6 +246,8 @@ usage()
"is given (e.g. '0x83')\n"
" --quiet|-q suppress some output when decoding\n"
" --raw|-r output page in binary\n"
+ " --vendor=VP | -M VP vendor/product abbreviation [or "
+ "number]\n"
" --verbose|-v increase verbosity\n"
" --version|-V print version string and exit\n\n"
"Fetch Vital Product Data (VPD) page using SCSI INQUIRY or "
@@ -613,7 +619,7 @@ enumerate_vpds(int standard, int vendor)
}
static int
-search_standard_vpds(int num_vpd)
+count_standard_vpds(int num_vpd)
{
const struct svpd_values_name_t * vnp;
int matches;
@@ -2669,7 +2675,17 @@ svpd_decode_t10(int sg_fd, int pn, int subvalue, int maxlen, int do_hex,
vnp->acron);
else
printf(" %s [%s]\n", vnp->name, vnp->acron);
- } else
+ } else if (subvalue >= 0) {
+ vnp = svpd_find_vendor_by_num(pn, subvalue);
+ if (vnp) {
+ if (do_long)
+ printf(" 0x%02x %s [%s]\n", pn, vnp->name,
+ vnp->acron);
+ else
+ printf(" %s [%s]\n", vnp->name, vnp->acron);
+ } else
+ printf(" 0x%x\n", pn);
+ } else
printf(" 0x%x\n", pn);
}
}
@@ -3099,6 +3115,7 @@ main(int argc, char * argv[])
const struct svpd_values_name_t * vnp;
const char * page_str = NULL;
const char * inhex_fn = NULL;
+ const char * vp_str = NULL;
const char * cp;
int num_vpd = 0;
int do_enum = 0;
@@ -3113,11 +3130,12 @@ main(int argc, char * argv[])
int ret = 0;
int subvalue = 0;
int page_pdt = -1;
+ int vp_num = -1;
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "ehHiI:lm:p:qrvV", long_options,
+ c = getopt_long(argc, argv, "ehHiI:lm:M:p:qrvV", long_options,
&option_index);
if (c == -1)
break;
@@ -3155,6 +3173,14 @@ main(int argc, char * argv[])
return SG_LIB_SYNTAX_ERROR;
}
break;
+ case 'M':
+ if (vp_str) {
+ pr2serr("only one '--vendor=' option permitted\n");
+ usage();
+ return SG_LIB_SYNTAX_ERROR;
+ } else
+ vp_str = optarg;
+ break;
case 'p':
if (page_str) {
pr2serr("only one '--page=' option permitted\n");
@@ -3197,6 +3223,23 @@ main(int argc, char * argv[])
if (device_name)
pr2serr("Device name %s ignored when --enumerate given\n",
device_name);
+ if (vp_str) {
+ if (isdigit(vp_str[0])) {
+ vp_num = sg_get_num_nomult(vp_str);
+ if ((vp_num < 0) || (vp_num > 10)) {
+ pr2serr("Bad vendor/product number after '--vendor=' "
+ "option\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ } else {
+ vp_num = svpd_find_vp_num_by_acron(vp_str);
+ if (vp_num < 0) {
+ pr2serr("Bad vendor/product acronym after '--vendor=' "
+ "option\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ }
+ }
if (page_str) {
if ((0 == strcmp("-1", page_str)) ||
(0 == strcmp("-2", page_str)))
@@ -3212,9 +3255,9 @@ main(int argc, char * argv[])
"numbers\n");
return SG_LIB_SYNTAX_ERROR;
}
- matches = search_standard_vpds(num_vpd);
+ matches = count_standard_vpds(num_vpd);
if (0 == matches)
- matches = svpd_search_vendor_vpds(num_vpd);
+ matches = svpd_count_vendor_vpds(num_vpd, vp_num);
if (0 == matches)
printf("No matches found for VPD page number 0x%x\n",
num_vpd);
@@ -3243,6 +3286,11 @@ main(int argc, char * argv[])
page_pdt = vnp->pdt;
} else {
cp = strchr(page_str, ',');
+ if (cp && vp_str) {
+ pr2serr("the --page=pg,vp and the --vendor=vp forms overlap, "
+ "choose one or the other\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
num_vpd = sg_get_num_nomult(page_str);
if ((num_vpd < 0) || (num_vpd > 255)) {
pr2serr("Bad page code value after '-p' option\n");
@@ -3251,13 +3299,34 @@ main(int argc, char * argv[])
return SG_LIB_SYNTAX_ERROR;
}
if (cp) {
- subvalue = sg_get_num_nomult(cp + 1);
+ if (isdigit(*(cp + 1)))
+ subvalue = sg_get_num_nomult(cp + 1);
+ else
+ subvalue = svpd_find_vp_num_by_acron(cp + 1);
if ((subvalue < 0) || (subvalue > 255)) {
pr2serr("Bad subvalue code value after '-p' option\n");
return SG_LIB_SYNTAX_ERROR;
}
+ } else if (vp_str) {
+ vp_num = svpd_find_vp_num_by_acron(vp_str);
+ if (vp_num < 0) {
+ pr2serr("Bad vendor/product acronym after '--vendor=' "
+ "option\n");
+ enumerate_vpds(0, 1);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ subvalue = vp_num;
}
}
+ } else if (vp_str) {
+ vp_num = svpd_find_vp_num_by_acron(vp_str);
+ if (vp_num < 0) {
+ pr2serr("Bad vendor/product acronym after '--vendor=' "
+ "option\n");
+ enumerate_vpds(0, 1);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ subvalue = vp_num;
}
if (inhex_fn) {
if (device_name) {
diff --git a/src/sg_vpd_vendor.c b/src/sg_vpd_vendor.c
index 67500cbc..6b4513c8 100644
--- a/src/sg_vpd_vendor.c
+++ b/src/sg_vpd_vendor.c
@@ -42,6 +42,14 @@
*/
+/* vendor/product identifiers */
+#define VPD_VP_SEAGATE 0
+#define VPD_VP_RDAC 1
+#define VPD_VP_EMC 2
+#define VPD_VP_DDS 3
+#define VPD_VP_LTO 4
+#define VPD_VP_HP3PAR 5
+
/* vendor VPD pages */
#define VPD_V_HP3PAR 0xc0
@@ -71,11 +79,17 @@
#define DEF_ALLOC_LEN 252
#define MX_ALLOC_LEN (0xc000 + 0x80)
+struct svpd_vp_name_t {
+ int vp_num; /* vendor/product identifier */
+ const char * acron;
+ const char * name;
+};
+
/* This structure is a duplicate of one of the same name in sg_vpd.c .
Take care that both have the same fields (and types). */
struct svpd_values_name_t {
int value; /* VPD number */
- int subvalue; /* used to disambiguate when different vendors use */
+ int subvalue; /* vendor/product identifier used to disambiguate */
/* the same VPD number */
int pdt; /* peripheral device type id, -1 is the default */
/* (all or not applicable) value */
@@ -92,34 +106,52 @@ static unsigned char rsp_buff[MX_ALLOC_LEN + 2];
/* Supported vendor specific VPD pages */
-/* 'subvalue' used to disambiguate; 'vendor' flag should be set */
+/* Arrange in alphabetical order by acronym */
+static struct svpd_vp_name_t vp_arr[] = {
+ {VPD_VP_DDS, "dds", "DDS tape family from IBM"},
+ {VPD_VP_EMC, "emc", "EMC (company)"},
+ {VPD_VP_HP3PAR, "hp3par", "3PAR array (HP was Left Hand)"},
+ {VPD_VP_LTO, "lto", "LTO tape drive/system (IBM and others)"},
+ {VPD_VP_RDAC, "rdac", "RDAC array (EMC Clariion)"},
+ {VPD_VP_SEAGATE, "sea", "Seagate disk"},
+ {0, NULL, NULL},
+};
+
+
+/* Supported vendor specific VPD pages */
+/* 'subvalue' holds vendor/product number to disambiguate */
/* Arrange in alphabetical order by acronym */
static struct svpd_values_name_t vendor_vpd_pg[] = {
- {VPD_V_ACI_LTO, 0, -1, "aci", "ACI revision level (LTO)"},
- {VPD_V_DATC_SEA, 0, -1, "datc", "Date code (Seagate)"},
- {VPD_V_FVER_DDS, 4, -1, "ddsver", "Firmware revision (DDS)"},
- {VPD_V_DEV_BEH_SEA, 0, -1, "devb", "Device behavior (Seagate)"},
- {VPD_V_EDID_RDAC, 0, -1, "edid", "Extended device identification "
- "(RDAC)"},
- {VPD_V_FEAT_RDAC, 1, -1, "feat", "Feature Parameters (RDAC)"},
- {VPD_V_FIRM_SEA, 0, -1, "firm", "Firmware numbers (Seagate)"},
- {VPD_V_FVER_LTO, 5, -1, "frl" , "Firmware revision level (LTO)"},
- {VPD_V_FVER_RDAC, 1, -1, "fver", "Firmware version (RDAC)"},
- {VPD_V_HEAD_LTO, 1, -1, "head", "Head Assy revision level (LTO)"},
- {VPD_V_HP3PAR, 2, -1, "hp3par", "Volume information (HP/3PAR)"},
- {VPD_V_HVER_LTO, 2, -1, "hrl", "Hardware revision level (LTO)"},
- {VPD_V_HVER_RDAC, 3, -1, "hver", "Hardware version (RDAC)"},
- {VPD_V_JUMP_SEA, 0, -1, "jump", "Jump setting (Seagate)"},
- {VPD_V_MECH_LTO, 2, -1, "mech", "Mechanism revision level (LTO)"},
- {VPD_V_PCA_LTO, 2, -1, "pca", "PCA revision level (LTO)"},
- {VPD_V_RVSI_RDAC, 0, -1, "rvsi", "Replicated volume source "
+ {VPD_V_ACI_LTO, VPD_VP_LTO, -1, "aci", "ACI revision level (LTO)"},
+ {VPD_V_DATC_SEA, VPD_VP_SEAGATE, -1, "datc", "Date code (Seagate)"},
+ {VPD_V_FVER_DDS, VPD_VP_DDS, -1, "ddsver", "Firmware revision (DDS)"},
+ {VPD_V_DEV_BEH_SEA, VPD_VP_SEAGATE, -1, "devb", "Device behavior "
+ "(Seagate)"},
+ {VPD_V_EDID_RDAC, VPD_VP_RDAC, -1, "edid", "Extended device "
+ "identification (RDAC)"},
+ {VPD_V_FEAT_RDAC, VPD_VP_RDAC, -1, "feat", "Feature Parameters (RDAC)"},
+ {VPD_V_FIRM_SEA, VPD_VP_SEAGATE, -1, "firm", "Firmware numbers "
+ "(Seagate)"},
+ {VPD_V_FVER_LTO, VPD_VP_LTO, -1, "frl" , "Firmware revision level (LTO)"},
+ {VPD_V_FVER_RDAC, VPD_VP_RDAC, -1, "fver", "Firmware version (RDAC)"},
+ {VPD_V_HEAD_LTO, VPD_VP_LTO, -1, "head", "Head Assy revision level "
+ "(LTO)"},
+ {VPD_V_HP3PAR, VPD_VP_HP3PAR, -1, "hp3par", "Volume information "
+ "(HP/3PAR)"},
+ {VPD_V_HVER_LTO, VPD_VP_LTO, -1, "hrl", "Hardware revision level (LTO)"},
+ {VPD_V_HVER_RDAC, VPD_VP_RDAC, -1, "hver", "Hardware version (RDAC)"},
+ {VPD_V_JUMP_SEA, VPD_VP_SEAGATE, -1, "jump", "Jump setting (Seagate)"},
+ {VPD_V_MECH_LTO, VPD_VP_LTO, -1, "mech", "Mechanism revision level "
+ "(LTO)"},
+ {VPD_V_PCA_LTO, VPD_VP_LTO, -1, "pca", "PCA revision level (LTO)"},
+ {VPD_V_RVSI_RDAC, VPD_VP_RDAC, -1, "rvsi", "Replicated volume source "
"identifier (RDAC)"},
- {VPD_V_SAID_RDAC, 0, -1, "said", "Storage array world wide name "
- "(RDAC)"},
- {VPD_V_SUBS_RDAC, 0, -1, "sub", "Subsystem identifier (RDAC)"},
- {VPD_V_SVER_RDAC, 1, -1, "sver", "Software version (RDAC)"},
- {VPD_V_UPR_EMC, 1, -1, "upr", "Unit path report (EMC)"},
- {VPD_V_VAC_RDAC, 0, -1, "vac", "Volume access control (RDAC)"},
+ {VPD_V_SAID_RDAC, VPD_VP_RDAC, -1, "said", "Storage array world wide "
+ "name (RDAC)"},
+ {VPD_V_SUBS_RDAC, VPD_VP_RDAC, -1, "sub", "Subsystem identifier (RDAC)"},
+ {VPD_V_SVER_RDAC, VPD_VP_RDAC, -1, "sver", "Software version (RDAC)"},
+ {VPD_V_UPR_EMC, VPD_VP_EMC, -1, "upr", "Unit path report (EMC)"},
+ {VPD_V_VAC_RDAC, VPD_VP_RDAC, -1, "vac", "Volume access control (RDAC)"},
{0, 0, 0, NULL, NULL},
};
@@ -144,7 +176,7 @@ pr2serr(const char * fmt, ...)
return n;
}
-static const struct svpd_values_name_t *
+const struct svpd_values_name_t *
svpd_get_v_detail(int page_num, int subvalue, int pdt)
{
const struct svpd_values_name_t * vnp;
@@ -166,6 +198,35 @@ svpd_get_v_detail(int page_num, int subvalue, int pdt)
}
const struct svpd_values_name_t *
+svpd_find_vendor_by_num(int page_num, int vp_num)
+{
+ const struct svpd_values_name_t * vnp;
+
+ for (vnp = vendor_vpd_pg; vnp->acron; ++vnp) {
+ if ((page_num == vnp->value) &&
+ ((vp_num < 0) || (vp_num == vnp->subvalue)))
+ return vnp;
+ }
+ return NULL;
+}
+
+
+int
+svpd_find_vp_num_by_acron(const char * vp_ap)
+{
+ size_t len;
+ const struct svpd_vp_name_t * vpp;
+
+ for (vpp = vp_arr; vpp->acron; ++vpp) {
+ len = strlen(vpp->acron);
+ if (0 == strncmp(vpp->acron, vp_ap, len))
+ return vpp->vp_num;
+ }
+ return -1;
+}
+
+
+const struct svpd_values_name_t *
svpd_find_vendor_by_acron(const char * ap)
{
const struct svpd_values_name_t * vnp;
@@ -180,9 +241,20 @@ svpd_find_vendor_by_acron(const char * ap)
void
svpd_enumerate_vendor()
{
+ const struct svpd_vp_name_t * vpp;
const struct svpd_values_name_t * vnp;
int seen;
+ for (seen = 0, vpp = vp_arr; vpp->acron; ++vpp) {
+ if (vpp->name) {
+ if (! seen) {
+ printf("\nVendor/product identifiers:\n");
+ seen = 1;
+ }
+ printf(" %-10s %d %s\n", vpp->acron,
+ vpp->vp_num, vpp->name);
+ }
+ }
for (seen = 0, vnp = vendor_vpd_pg; vnp->acron; ++vnp) {
if (vnp->name) {
if (! seen) {
@@ -196,18 +268,20 @@ svpd_enumerate_vendor()
}
int
-svpd_search_vendor_vpds(int num_vpd)
+svpd_count_vendor_vpds(int num_vpd, int vp_num)
{
const struct svpd_values_name_t * vnp;
int matches;
for (vnp = vendor_vpd_pg, matches = 0; vnp->acron; ++vnp) {
if ((num_vpd == vnp->value) && vnp->name) {
- if (0 == matches)
- printf("Matching vendor specific VPD pages:\n");
- ++matches;
- printf(" %-10s 0x%02x,%d %s\n", vnp->acron,
- vnp->value, vnp->subvalue, vnp->name);
+ if ((vp_num < 0) || (vp_num == vnp->subvalue)) {
+ if (0 == matches)
+ printf("Matching vendor specific VPD pages:\n");
+ ++matches;
+ printf(" %-10s 0x%02x,%d %s\n", vnp->acron,
+ vnp->value, vnp->subvalue, vnp->name);
+ }
}
}
return matches;
diff --git a/src/sg_wr_mode.c b/src/sg_wr_mode.c
index 54de3224..58ed4c86 100644
--- a/src/sg_wr_mode.c
+++ b/src/sg_wr_mode.c
@@ -25,7 +25,7 @@
* mode page on the given device.
*/
-static const char * version_str = "1.13 20140517";
+static const char * version_str = "1.14 20140518";
#define ME "sg_wr_mode: "
@@ -542,11 +542,11 @@ int main(int argc, char * argv[])
memcpy(ref_md + off, read_in, read_in_len);
if (mode_6)
- res = sg_ll_mode_select6(sg_fd, 1, save, ref_md, md_len, 1,
- verbose);
+ res = sg_ll_mode_select6(sg_fd, 1 /* PF */, save, ref_md, md_len,
+ 1, verbose);
else
- res = sg_ll_mode_select10(sg_fd, 1, save, ref_md, md_len, 1,
- verbose);
+ res = sg_ll_mode_select10(sg_fd, 1 /* PF */, save, ref_md,
+ md_len, 1, verbose);
ret = res;
if (res) {
sg_get_category_sense_str(res, sizeof(b), b, verbose);
diff --git a/src/sg_write_buffer.c b/src/sg_write_buffer.c
index 93908c08..fc14b1cb 100644
--- a/src/sg_write_buffer.c
+++ b/src/sg_write_buffer.c
@@ -26,7 +26,7 @@
* This utility issues the SCSI WRITE BUFFER command to the given device.
*/
-static const char * version_str = "1.14 20140515"; /* spc4r36s */
+static const char * version_str = "1.15 20140518"; /* spc4r37 */
#define ME "sg_write_buffer: "
#define DEF_XFER_LEN (8 * 1024 * 1024)