aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--examples/sg_sat_chk_power.c40
-rw-r--r--include/sg_lib_data.h2
-rw-r--r--lib/sg_lib_data.c18
-rw-r--r--src/sg_inq_data.c4
-rw-r--r--src/sg_luns.c36
-rw-r--r--src/sg_sat_identify.c40
-rw-r--r--utils/sg_chk_asc.c11
8 files changed, 123 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog
index 014b076d..5a0cf4e8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,13 +2,14 @@ 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.34 [20120312] [svn: r444]
+Changelog for sg3_utils-1.34 [20120314] [svn: r445]
- sg_verify: add 16 byte cdb, bytchk (data-out buffer)
and group number support
- - sync to spc4r34 and sbc3r30
+ - sync to spc4r35 and sbc3r30
- sg_inq: add --export to experiment with udev
- sg_ses: increase max dpage response size to 64 KB
- sg_sanitize: add --ause, --fail and --test=
+ - sg_luns: add long extended flat space addressing format
- sg_pt_linux: expand DID_ (host_byte) codes
- sg_lib: fix sg_get_command_name() service actions
- report sdat_ovfl bit (if set) in sense data
diff --git a/examples/sg_sat_chk_power.c b/examples/sg_sat_chk_power.c
index d6d09286..60d7307d 100644
--- a/examples/sg_sat_chk_power.c
+++ b/examples/sg_sat_chk_power.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2007 Douglas Gilbert.
+ * Copyright (c) 2006-2012 Douglas Gilbert.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -50,12 +50,48 @@
#define SAT_ATA_PASS_THROUGH16 0x85
#define SAT_ATA_PASS_THROUGH16_LEN 16
#define SAT_ATA_RETURN_DESC 9 /* ATA Return (sense) Descriptor */
+#define ASCQ_ATA_PT_INFO_AVAILABLE 0x1d
#define ATA_CHECK_POWER_MODE 0xe5
#define EBUFF_SZ 256
-static char * version_str = "1.03 20070129";
+static char * version_str = "1.04 20120315";
+
+
+/* Returns length of decoded fixed format sense for SAT ATA pass-through
+ * command, else returns 0. If returns 0 (expected sense data not found)
+ * then '\0' placed in first byte of bp. */
+static int
+sg_sat_decode_fixed_sense(const unsigned char * sp, int slen, char * bp,
+ int max_blen, int verbose)
+{
+ int k, n;
+
+ if ((NULL == bp) || (NULL == sp) || (max_blen < 1) || (slen < 14))
+ return 0;
+ bp[0] = '\0';
+ if ((0x70 != (0x7f & sp[0])) ||
+ (SPC_SK_RECOVERED_ERROR != (0xf & sp[2])) ||
+ (0 != sp[12]) || (ASCQ_ATA_PT_INFO_AVAILABLE != sp[13]))
+ return 0;
+ n = snprintf(bp, max_blen, "error=0x%x, status=0x%x, device=0x%x, "
+ "scount(7:0)=0x%x%c\n", sp[3], sp[4], sp[5], sp[6],
+ ((0x40 & sp[8]) ? '+' : ' '));
+ if (n >= max_blen)
+ return max_blen - 1;
+ n += snprintf(bp + n, max_blen - n, "extend=%d, log_index=0x%x, "
+ "lba_high(7:0)=0x%x, _mid(7:0)=0x%x, _low(7:0)=0x%x%c\n",
+ (!!(0x80 & sp[8])), (0xf & sp[8]), sp[9], sp[10], sp[11],
+ ((0x20 & sp[8]) ? '+' : ' '));
+ if (n >= max_blen)
+ return max_blen - 1;
+ if (verbose)
+ n += snprintf(bp + n, max_blen - n, " sector_count_upper_nonzero="
+ "%d, lba_upper_nonzero=%d\n", !!(0x40 & sp[8]),
+ !!(0x20 & sp[8]));
+ return (n >= max_blen) ? max_blen - 1 : n;
+}
int main(int argc, char * argv[])
{
diff --git a/include/sg_lib_data.h b/include/sg_lib_data.h
index fcd7c52d..57611318 100644
--- a/include/sg_lib_data.h
+++ b/include/sg_lib_data.h
@@ -30,6 +30,7 @@ extern "C" {
#define SG_RECEIVE_COPY 0x84
#define SG_SERVICE_ACTION_IN_12 0xab
#define SG_SERVICE_ACTION_OUT_12 0xa9
+#define SG_SERVICE_ACTION_BIDI 0x9d
#define SG_SERVICE_ACTION_IN_16 0x9e
#define SG_SERVICE_ACTION_OUT_16 0x9f
#define SG_READ_BUFFER 0x3c
@@ -71,6 +72,7 @@ extern struct sg_lib_value_name_t sg_lib_serv_in12_arr[];
extern struct sg_lib_value_name_t sg_lib_serv_out12_arr[];
extern struct sg_lib_value_name_t sg_lib_serv_in16_arr[];
extern struct sg_lib_value_name_t sg_lib_serv_out16_arr[];
+extern struct sg_lib_value_name_t sg_lib_serv_bidi_arr[];
extern struct sg_lib_value_name_t sg_lib_xcopy_sa_arr[];
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[];
diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c
index 0251ca4e..55bb61d8 100644
--- a/lib/sg_lib_data.c
+++ b/lib/sg_lib_data.c
@@ -15,7 +15,7 @@
#endif
-const char * sg_lib_version_str = "1.76 20120312"; /* spc4r34, sbc3r30 */
+const char * sg_lib_version_str = "1.77 20120313"; /* spc4r35, sbc3r30 */
#ifdef SG_SCSI_STRINGS
struct sg_lib_value_name_t sg_lib_normal_opcodes[] = {
@@ -151,6 +151,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)"},
+ {0x9d, 0, "Service action bidirectional"}, /* added spc4r35 */
{0x9e, 0, "Service action in(16)"},
{0x9f, 0, "Service action out(16)"},
{0xa0, 0, "Report luns"},
@@ -241,7 +242,7 @@ struct sg_lib_value_name_t sg_lib_maint_in_arr[] = { /* opcode 0xa3 */
{0xd, 0, "Report supported task management functions"},
{0xe, 0, "Report priority"},
{0xf, 0, "Report timestamp"},
- {0x10, 0, "Maintenance in"},
+ {0x10, 0, "Management protocol in"},
{0xffff, 0, NULL},
};
@@ -250,9 +251,10 @@ struct sg_lib_value_name_t sg_lib_maint_out_arr[] = { /* opcode 0xa4 */
/* was "Set device identifier" prior to spc4r07 */
{0xa, 0, "Set target port groups"},
{0xb, 0, "Change aliases"},
+ {0xc, 0, "Remove I_T nexus"},
{0xe, 0, "Set priority"},
{0xf, 0, "Set timestamp"},
- {0x10, 0, "Maintenance out"},
+ {0x10, 0, "Management protocol out"},
{0xffff, 0, NULL},
};
@@ -280,6 +282,10 @@ struct sg_lib_value_name_t sg_lib_serv_out16_arr[] = { /* opcode 0x9f */
{0xffff, 0, NULL},
};
+struct sg_lib_value_name_t sg_lib_serv_bidi_arr[] = { /* opcode 0x9d */
+ {0xffff, 0, NULL},
+};
+
struct sg_lib_value_name_t sg_lib_pr_in_arr[] = { /* opcode 0x5e */
{0x0, 0, "Persistent reserve in, read keys"},
{0x1, 0, "Persistent reserve in, read reservation"},
@@ -431,6 +437,10 @@ struct sg_lib_value_name_t sg_lib_serv_out16_arr[] = { /* opcode 0x9f */
{0xffff, 0, NULL},
};
+struct sg_lib_value_name_t sg_lib_serv_bidi_arr[] = { /* opcode 0x9d */
+ {0xffff, 0, NULL},
+};
+
struct sg_lib_value_name_t sg_lib_pr_in_arr[] = { /* opcode 0x5e */
{0xffff, 0, NULL},
};
@@ -558,6 +568,7 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x0B,0x06,"Warning - non-volatile cache now volatile"},
{0x0B,0x07,"Warning - degraded power to non-volatile cache"},
{0x0B,0x08,"Warning - power loss expected"},
+ {0x0B,0x09,"Warning - device statistics notification active"},
{0x0C,0x00,"Write error"},
{0x0C,0x01,"Write error - recovered with auto reallocation"},
{0x0C,0x02,"Write error - auto reallocation failed"},
@@ -850,6 +861,7 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x3B,0x19,"Element enabled"},
{0x3B,0x1a,"Data transfer device removed"},
{0x3B,0x1b,"Data transfer device inserted"},
+ {0x3B,0x1c,"Too many logical objects on partition to support operation"},
{0x3D,0x00,"Invalid bits in identify message"},
{0x3E,0x00,"Logical unit has not self-configured yet"},
{0x3E,0x01,"Logical unit failure"},
diff --git a/src/sg_inq_data.c b/src/sg_inq_data.c
index fb4e875a..aa9e12d2 100644
--- a/src/sg_inq_data.c
+++ b/src/sg_inq_data.c
@@ -48,7 +48,7 @@ struct sg_version_descriptor {
const char * name;
};
-/* table from SPC-4 revision 34 [sorted numerically (from Annex E.9)] */
+/* table from SPC-4 revision 35 [sorted numerically (from Annex E.9)] */
/* Can also be obtained from : http://www.t10.org/lists/stds.txt */
#ifdef SG_SCSI_STRINGS
struct sg_version_descriptor sg_version_descriptor_arr[] = {
@@ -201,6 +201,7 @@ struct sg_version_descriptor sg_version_descriptor_arr[] = {
{0x500, "ADC-3 (no version claimed)"},
{0x502, "ADC-3 T10/1895-D revision 04"},
{0x504, "ADC-3 T10/1895-D revision 05"},
+ {0x506, "ADC-3 T10/1895-D revision 05a"},
{0x520, "SSC-4 (no version claimed)"},
{0x523, "SSC-4 T10/2123-D revision 2"},
{0x560, "OSD-3 (no version claimed)"},
@@ -445,6 +446,7 @@ struct sg_version_descriptor sg_version_descriptor_arr[] = {
{0x1ec8, "SAT-2 T10/1826-D revision 09"},
{0x1eca, "SAT-2 ANSI INCITS 465-2010"},
{0x1ee0, "SAT-3 (no version claimed)"},
+ {0x1ee2, "SAT-3 T10/2126-D revision 4"},
{0x1f00, "SAT-4 (no version claimed)"},
{0x20a0, "SPL (no version claimed)"},
{0x20a3, "SPL T10/2124-D revision 6a"},
diff --git a/src/sg_luns.c b/src/sg_luns.c
index bc330512..0870577f 100644
--- a/src/sg_luns.c
+++ b/src/sg_luns.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2011 Douglas Gilbert.
+ * Copyright (c) 2004-2012 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.
@@ -23,10 +23,11 @@
/* A utility program originally written for the Linux OS SCSI subsystem.
*
*
- * This program issues the SCSI REPORT LUNS command to the given SCSI device.
+ * This program issues the SCSI REPORT LUNS command to the given SCSI device
+ * and decodes the response.
*/
-static char * version_str = "1.16 20110825";
+static char * version_str = "1.17 20120314";
#define MAX_RLUNS_BUFF_LEN (1024 * 64)
#define DEF_RLUNS_BUFF_LEN (1024 * 8)
@@ -77,13 +78,15 @@ usage()
);
}
-/* Decoded according to SAM-4 rev 4. Note that one draft: BCC rev 0,
+/* Decoded according to SAM-5 rev 10. Note that one draft: BCC rev 0,
* defines its own "bridge addressing method" in place of the SAM-3
* "logical addressing method". */
static void
decode_lun(const char * leadin, unsigned char * lunp)
{
- int k, j, x, a_method, bus_id, target, lun, len, e_a_method, next_level;
+ int k, j, x, a_method, bus_id, target, lun, len_fld, e_a_method;
+ int next_level;
+ unsigned int u;
unsigned char not_spec[8] = {0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff};
char l_leadin[128];
@@ -127,10 +130,10 @@ decode_lun(const char * leadin, unsigned char * lunp)
"lun=%d\n", l_leadin, bus_id, target, lun);
break;
case 3: /* extended logical unit addressing method */
- len = (lunp[0] & 0x30) >> 4;
+ len_fld = (lunp[0] & 0x30) >> 4;
e_a_method = lunp[0] & 0xf;
x = lunp[1];
- if ((0 == len) && (1 == e_a_method)) {
+ if ((0 == len_fld) && (1 == e_a_method)) {
switch (x) {
case 1:
printf("%sREPORT LUNS well known logical unit\n",
@@ -152,23 +155,28 @@ decode_lun(const char * leadin, unsigned char * lunp)
printf("%swell known logical unit %d\n", l_leadin, x);
break;
}
- } else if ((1 == len) && (2 == e_a_method)) {
+ } else if ((1 == len_fld) && (2 == e_a_method)) {
x = (lunp[1] << 16) + (lunp[2] << 8) + lunp[3];
printf("%sExtended flat space logical unit addressing: "
"value=0x%x\n", l_leadin, x);
- } else if ((3 == len) && (0xf == e_a_method))
+ } else if ((2 == len_fld) && (2 == e_a_method)) {
+ u = (lunp[1] << 24) + (lunp[2] << 16) + (lunp[3] << 8) +
+ lunp[4];
+ printf("%sLong extended flat space logical unit addressing: "
+ "value=0x%x\n", l_leadin, u);
+ } else if ((3 == len_fld) && (0xf == e_a_method))
printf("%sLogical unit _not_ specified addressing\n",
l_leadin);
else {
- if (len < 2) {
- if (1 == len)
+ if (len_fld < 2) {
+ if (1 == len_fld)
x = (lunp[1] << 16) + (lunp[2] << 8) + lunp[3];
printf("%sExtended logical unit addressing: length=%d, "
- "e.a. method=%d, value=0x%x\n", l_leadin, len,
+ "e.a. method=%d, value=0x%x\n", l_leadin, len_fld,
e_a_method, x);
} else {
ull = 0;
- x = (2 == len) ? 5 : 7;
+ x = (2 == len_fld) ? 5 : 7;
for (j = 0; j < x; ++j) {
if (j > 0)
ull <<= 8;
@@ -176,7 +184,7 @@ decode_lun(const char * leadin, unsigned char * lunp)
}
printf("%sExtended logical unit addressing: length=%d, "
"e. a. method=%d, value=0x%" PRIx64 "\n",
- l_leadin, len, e_a_method, ull);
+ l_leadin, len_fld, e_a_method, ull);
}
}
break;
diff --git a/src/sg_sat_identify.c b/src/sg_sat_identify.c
index 31d6d9d0..c7c2ba16 100644
--- a/src/sg_sat_identify.c
+++ b/src/sg_sat_identify.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2011 Douglas Gilbert.
+ * Copyright (c) 2006-2012 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.
@@ -45,7 +45,7 @@
#define EBUFF_SZ 256
-static char * version_str = "1.08 20110513";
+static char * version_str = "1.09 20120314";
static struct option long_options[] = {
{"ck_cond", no_argument, 0, 'c'},
@@ -107,6 +107,7 @@ static int do_identify_dev(int sg_fd, int do_packet, int cdb_len,
int t_length = 2; /* 0 -> no data transferred, 2 -> sector count */
int resid = 0;
int got_ard = 0; /* got ATA result descriptor */
+ int got_fixsense = 0; /* got ATA result in fixed format sense */
int sb_sz;
struct sg_scsi_sense_hdr ssh;
unsigned char inBuff[ID_RESPONSE_LEN];
@@ -177,14 +178,25 @@ static int do_identify_dev(int sg_fd, int do_packet, int cdb_len,
case SPC_SK_RECOVERED_ERROR:
if ((0x0 == ssh.asc) &&
(ASCQ_ATA_PT_INFO_AVAILABLE == ssh.ascq)) {
- if (SAT_ATA_RETURN_DESC != ata_return_desc[0]) {
- if (verbose)
- fprintf(stderr, "did not find ATA Return "
- "(sense) Descriptor\n");
- return SG_LIB_CAT_RECOVERED;
+ if (0x72 == ssh.response_code) {
+ if (SAT_ATA_RETURN_DESC != ata_return_desc[0]) {
+ if (verbose)
+ fprintf(stderr, "did not find ATA Return "
+ "(sense) Descriptor\n");
+ return SG_LIB_CAT_RECOVERED;
+ }
+ got_ard = 1;
+ break;
+ } else if (0x70 == ssh.response_code) {
+ got_fixsense = 1;
+ break;
+ } else {
+ if (verbose < 2)
+ fprintf(stderr, "ATA PASS-THROUGH (%d), "
+ "unexpected response_code=0x%x\n",
+ ssh.response_code, cdb_len);
+ return SG_LIB_CAT_RECOVERED;
}
- got_ard = 1;
- break;
} else if (SPC_SK_RECOVERED_ERROR == ssh.sense_key)
return SG_LIB_CAT_RECOVERED;
else {
@@ -250,6 +262,16 @@ static int do_identify_dev(int sg_fd, int do_packet, int cdb_len,
}
ok = 1;
}
+ if (got_fixsense) {
+ if (0x4 & sense_buffer[3]) { /* Error is MSB of Info field */
+ fprintf(stderr, "error indication in returned FIS: aborted "
+ "command\n");
+ fprintf(stderr, " try again with%s '-p' option\n",
+ (do_packet ? "out" : ""));
+ return SG_LIB_CAT_ABORTED_COMMAND;
+ }
+ ok = 1;
+ }
if (ok) { /* output result if it is available */
if (do_raw)
diff --git a/utils/sg_chk_asc.c b/utils/sg_chk_asc.c
index fb1a9be8..46ff8608 100644
--- a/utils/sg_chk_asc.c
+++ b/utils/sg_chk_asc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2010 Douglas Gilbert.
+ * Copyright (c) 2006-2012 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,7 +25,7 @@
* http://www.t10.org/lists/asc-num.txt
*/
-static char * version_str = "1.03 20100312";
+static char * version_str = "1.04 20120313";
#define MAX_LINE_LEN 1024
@@ -166,6 +166,13 @@ printf("\"%s\",\n", b);
// fprintf(stderr, "file: asc=%x acsq=%x strlen=%d %s\n", asc, ascq, num, cp);
// if (num < 20)
// continue;
+ if ((num > 6) &&
+ ((0 == memcmp("ASC", cp, 3)) ||
+ (0 == memcmp("vendor", cp, 6)))) {
+ fprintf(stderr, "%x,%x differ, ref: %s, sg_lib: "
+ "<missing>\n", asc, ascq, b);
+ continue;
+ }
if (num > 20) {
cp += 18;
num -= 18;