aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2013-02-25 05:39:19 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2013-02-25 05:39:19 +0000
commitd772abe4e33fdf83d2cb082598df5103965795d5 (patch)
tree8b0c84f97c26e500d425b8fec911102629c81b5a
parent074a673a2d0b1b74337c1a3fc66ab7408a27c6f0 (diff)
downloadsg3_utils-d772abe4e33fdf83d2cb082598df5103965795d5.tar.gz
sg_luns: add --test=LUNHEX for 64 bit lun support
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@482 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog6
-rw-r--r--README2
-rw-r--r--debian/changelog2
-rw-r--r--doc/sg_inq.84
-rw-r--r--doc/sg_luns.838
-rw-r--r--sg3_utils.spec2
-rw-r--r--src/sg_inq.c2
-rw-r--r--src/sg_luns.c157
8 files changed, 163 insertions, 50 deletions
diff --git a/ChangeLog b/ChangeLog
index a6c661fe..7ee2f9dc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,15 +2,17 @@ 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.36 [20130220] [svn: r481]
+Changelog for sg3_utils-1.36 [20130225] [svn: r482]
- sg_lib: improve snprintf handling
- sg_vpd: Protocol-specific port information VPD page for
SAS SSP, persistent connection (spl3r2)
- sg_xcopy: handle more descriptor types; handle zero
maximum segment length; allow list IDs to be disabled;
improve skip/seek handling
- - sg_reset: and '--no-esc' option to stop reset escalation
+ - sg_reset: and --no-esc option to stop reset escalation
- clean up including adding long option names
+ - sg_luns: add --test=LUNHEX option for decoding LUNs
+ - decoded luns output in decimal or hex (if -HH given)
Changelog for sg3_utils-1.35 [20130117] [svn: r476]
- sg_compare_and_write: new utility
diff --git a/README b/README
index 1549c4fb..00e9aab6 100644
--- a/README
+++ b/README
@@ -374,4 +374,4 @@ See http://sg.danny.cz/sg/tools.html
Douglas Gilbert
-20th February 2013
+25th February 2013
diff --git a/debian/changelog b/debian/changelog
index 1cc18f70..16858e4c 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.36-0.1) unstable; urgency=low
* New upstream version
- -- Douglas Gilbert <dgilbert@interlog.com> Wed, 20 Feb 2013 19:00:00 -0500
+ -- Douglas Gilbert <dgilbert@interlog.com> Mon, 25 Feb 2013 01:00:00 -0500
sg3-utils (1.35-0.1) unstable; urgency=low
diff --git a/doc/sg_inq.8 b/doc/sg_inq.8
index 000de373..76780653 100644
--- a/doc/sg_inq.8
+++ b/doc/sg_inq.8
@@ -1,4 +1,4 @@
-.TH SG_INQ "8" "January 2013" "sg3_utils\-1.35" SG3_UTILS
+.TH SG_INQ "8" "February 2013" "sg3_utils\-1.36" SG3_UTILS
.SH NAME
sg_inq \- issue SCSI INQUIRY command, output and decode response
.SH SYNOPSIS
@@ -22,7 +22,7 @@ This utility by default sends a SCSI INQUIRY command to the given
device and then outputs the response. All SCSI devices are meant
to respond to a "standard" INQUIRY command with at least a 36 byte
response (in SCSI 2 and higher). An INQUIRY is termed as "standard"
-when both the EVPD and CmdDt (obsolete) bits are clear.
+when both the EVPD and CmdDt (now obsolete) bits are clear.
.PP
This utility supports two command line syntaxes, the preferred one is
shown first in the synopsis and explained in this section. A later
diff --git a/doc/sg_luns.8 b/doc/sg_luns.8
index d184012d..46bc5d2f 100644
--- a/doc/sg_luns.8
+++ b/doc/sg_luns.8
@@ -1,16 +1,24 @@
-.TH SG_LUNS "8" "November 2012" "sg3_utils\-1.35" SG3_UTILS
+.TH SG_LUNS "8" "February 2013" "sg3_utils\-1.36" SG3_UTILS
.SH NAME
sg_luns \- send SCSI REPORT LUNS command
.SH SYNOPSIS
.B sg_luns
[\fI\-\-decode\fR] [\fI\-\-help\fR] [\fI\-\-hex\fR] [\fI\-\-maxlen=LEN\fR]
-[\fI\-\-quiet\fR] [\fI\-\-raw\fR] [\fI\-\-select=SR\fR] [\fI\-\-verbose\fR]
-[\fI\-\-version\fR] \fIDEVICE\fR
+[\fI\-\-quiet\fR] [\fI\-\-raw\fR] [\fI\-\-select=SR\fR]
+[\fI\-\-verbose\fR] [\fI\-\-version\fR] \fIDEVICE\fR
+.PP
+.B sg_luns
+\fI\-\-test=LUNHEX\fR [\fI\-\-hex\fR] [\fI\-\-verbose\fR]
.SH DESCRIPTION
.\" Add any additional description here
.PP
-Send the SCSI REPORT LUNS command to the \fIDEVICE\fR and outputs the
-response. In the SPC\-3 SCSI standard support for this command is mandatory.
+In the first form shown in the SYNOPSIS this utility sends the SCSI REPORT
+LUNS command to the \fIDEVICE\fR and outputs the response. In the SPC\-3
+SCSI standard support for the REPORT LUNS command is mandatory.
+.PP
+When the \fI\-\-test=LUNHEX\fR option is given (the second form in the
+SYNOPSIS), the \fILUNHEX\fR value (assumed to represent a LUN in hex) is
+decoded as outlined in SAM\-3 and SAM\-4 .
.SH OPTIONS
Arguments to long options are mandatory for short options as well.
.TP
@@ -23,7 +31,10 @@ standard INQUIRY's response.
output the usage message then exit.
.TP
\fB\-H\fR, \fB\-\-hex\fR
-output response to this command in ASCII hex.
+when given once this utility will output response to the REPORT LUNS command
+in ASCII hex then exit. When given twice it causes the decode options to
+output values in hex rather than decimal. When this option is used with
+\fI\-\-test=LUNHEX\fR than decoded values are output in hex.
.TP
\fB\-m\fR, \fB\-\-maxlen\fR=\fILEN\fR
where \fILEN\fR is the (maximum) response length in bytes. It is placed in
@@ -54,9 +65,20 @@ meanings of the \fISR\fR values are:
.br
\fB2\fR : all luns
.br
-Values between 0xf8 and 0xff (inclusive) are vendor specific (SPC\-4 (rev 32),
+Values between 0xf8 and 0xff (inclusive) are vendor specific (SPC\-4 rev 32),
other values greater than 2 are reserved.
.TP
+\fB\-t\fR, \fB\-\-test\fR=\fILUNHEX\fR
+\fILUNHEX\fR is assumed to be a hexadecimal number in ASCII hex. The number
+can be up to 64 bits in size (i.e. 16 hexadecimal digits). All \fILUNHEX\fR
+values are padded to the right if less than 16 hexadecimal digits are
+given (e.g. \fI\-\-test=0122003a\fR becomes 0122003a00000000). \fILUNHEX\fR
+may be prefixed by '0x' or '0X' (e.g. the last example could have been
+\fI\-\-test=0x0122003a\fR). \fILUNHEX\fR may also be given with spaces or
+tabs between each byte (or anywhere else) but then \fILUNHEX\fR would need
+to be surrounded by single or double quotes. The given hexadecimal number is
+decoded as if the \fI\-\-decode\fR had been given.
+.TP
\fB\-v\fR, \fB\-\-verbose\fR
increase the level of verbosity, (i.e. debug output).
.TP
@@ -70,7 +92,7 @@ Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2004\-2012 Douglas Gilbert
+Copyright \(co 2004\-2013 Douglas Gilbert
.br
This software is distributed under a FreeBSD license. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/sg3_utils.spec b/sg3_utils.spec
index d5c3b220..f3cc3920 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,7 +79,7 @@ fi
%{_libdir}/*.la
%changelog
-* Wed Feb 20 2013 - dgilbert at interlog dot com
+* Mon Feb 25 2013 - dgilbert at interlog dot com
- track t10 changes
* sg3_utils-1.36
diff --git a/src/sg_inq.c b/src/sg_inq.c
index 48485747..18d90016 100644
--- a/src/sg_inq.c
+++ b/src/sg_inq.c
@@ -2217,7 +2217,7 @@ get_ansi_version_str(int version, char * buff, int buff_len)
}
-/* Returns 0 if successful */
+/* Process a standard INQUIRY response. Returns 0 if successful */
static int
process_std_inq(int sg_fd, const struct opts_t * optsp)
{
diff --git a/src/sg_luns.c b/src/sg_luns.c
index 0870577f..693ccf4b 100644
--- a/src/sg_luns.c
+++ b/src/sg_luns.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2012 Douglas Gilbert.
+ * Copyright (c) 2004-2013 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.
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <getopt.h>
#define __STDC_FORMAT_MACROS 1
#include <inttypes.h>
@@ -27,7 +28,7 @@
* and decodes the response.
*/
-static char * version_str = "1.17 20120314";
+static char * version_str = "1.18 20130224";
#define MAX_RLUNS_BUFF_LEN (1024 * 64)
#define DEF_RLUNS_BUFF_LEN (1024 * 8)
@@ -43,6 +44,7 @@ static struct option long_options[] = {
{"quiet", no_argument, 0, 'q'},
{"raw", no_argument, 0, 'r'},
{"select", required_argument, 0, 's'},
+ {"test", required_argument, 0, 't'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{0, 0, 0, 0},
@@ -52,26 +54,33 @@ static void
usage()
{
fprintf(stderr, "Usage: "
- "sg_luns [--decode] [--help] [--hex] [--maxlen=LEN] [--quiet] "
- "[--raw]\n"
- " [--select=SR] [--verbose] [--version] DEVICE\n"
+ "sg_luns [--decode] [--help] [--hex] [--maxlen=LEN] "
+ "[--quiet]\n"
+ " [--raw] [--select=SR] [--test=LUNHEX] "
+ "[--verbose]\n"
+ " [--version] DEVICE\n"
" where:\n"
" --decode|-d decode all luns into component parts\n"
" --help|-h print out usage message\n"
- " --hex|-H output in hexadecimal\n"
+ " --hex|-H output response in hexadecimal; used "
+ "twice\n"
+ " shows decoded values in hex\n"
" --maxlen=LEN|-m LEN max response length (allocation "
"length in cdb)\n"
" (def: 0 -> %d bytes)\n",
DEF_RLUNS_BUFF_LEN );
fprintf(stderr, " --quiet|-q output only ASCII hex lun "
"values\n"
- " --raw|-r output in binary\n"
+ " --raw|-r output response in binary\n"
" --select=SR|-s SR select report SR (def: 0)\n"
" 0 -> luns apart from 'well "
"known' lus\n"
" 1 -> only 'well known' "
"logical unit numbers\n"
" 2 -> all luns\n"
+ " --test=LUNHEX|-t LUNHEX decode LUNHEX and ignore "
+ "other options\n"
+ " and DEVICE (apart from '-H')\n"
" --verbose|-v increase verbosity\n"
" --version|-V print version string and exit\n\n"
"Performs a SCSI REPORT LUNS command\n"
@@ -82,11 +91,10 @@ usage()
* 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)
+decode_lun(const char * leadin, const unsigned char * lunp, int do_hex)
{
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];
@@ -109,25 +117,40 @@ decode_lun(const char * leadin, unsigned char * lunp)
switch (a_method) {
case 0: /* peripheral device addressing method */
bus_id = lunp[0] & 0x3f;
- if (0 == bus_id)
- printf("%sPeripheral device addressing: lun=%d\n",
- l_leadin, lunp[1]);
- else {
- printf("%sPeripheral device addressing: bus_id=%d, "
- "target=%d\n", l_leadin, bus_id, lunp[1]);
+ if (0 == bus_id) {
+ if (do_hex)
+ printf("%sPeripheral device addressing: lun=0x%x\n",
+ l_leadin, lunp[1]);
+ else
+ printf("%sPeripheral device addressing: lun=%d\n",
+ l_leadin, lunp[1]);
+ } else {
+ if (do_hex)
+ printf("%sPeripheral device addressing: bus_id=0x%x, "
+ "target=0x%x\n", l_leadin, bus_id, lunp[1]);
+ else
+ printf("%sPeripheral device addressing: bus_id=%d, "
+ "target=%d\n", l_leadin, bus_id, lunp[1]);
next_level = 1;
}
break;
case 1: /* flat space addressing method */
lun = ((lunp[0] & 0x3f) << 8) + lunp[1];
- printf("%sFlat space addressing: lun=%d\n", l_leadin, lun);
+ if (do_hex)
+ printf("%sFlat space addressing: lun=0x%x\n", l_leadin, lun);
+ else
+ printf("%sFlat space addressing: lun=%d\n", l_leadin, lun);
break;
case 2: /* logical unit addressing method */
target = (lunp[0] & 0x3f);
bus_id = (lunp[1] >> 5) & 0x7;
lun = lunp[1] & 0x1f;
- printf("%sLogical unit addressing: bus_id=%d, target=%d, "
- "lun=%d\n", l_leadin, bus_id, target, lun);
+ if (do_hex)
+ printf("%sLogical unit addressing: bus_id=0x%x, target=0x%x, "
+ "lun=0x%x\n", l_leadin, bus_id, target, lun);
+ else
+ printf("%sLogical unit addressing: bus_id=%d, target=%d, "
+ "lun=%d\n", l_leadin, bus_id, target, lun);
break;
case 3: /* extended logical unit addressing method */
len_fld = (lunp[0] & 0x30) >> 4;
@@ -152,18 +175,34 @@ decode_lun(const char * leadin, unsigned char * lunp)
l_leadin);
break;
default:
- printf("%swell known logical unit %d\n", l_leadin, x);
+ if (do_hex)
+ printf("%swell known logical unit 0x%x\n", l_leadin,
+ x);
+ else
+ printf("%swell known logical unit %d\n", l_leadin, x);
break;
}
} 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);
+ if (do_hex)
+ printf("%sExtended flat space addressing: value=0x%x\n",
+ l_leadin, x);
+ else
+ printf("%sExtended flat space addressing: value=%d\n",
+ l_leadin, x);
} 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);
+ ull = 0;
+ for (j = 0; j < 5; ++j) {
+ if (j > 0)
+ ull <<= 8;
+ ull |= lunp[1 + j];
+ }
+ if (do_hex)
+ printf("%sLong extended flat space addressing: "
+ "value=0x%" PRIx64 "\n", l_leadin, ull);
+ else
+ printf("%sLong extended flat space addressing: "
+ "value=%" PRIu64 "\n", l_leadin, ull);
} else if ((3 == len_fld) && (0xf == e_a_method))
printf("%sLogical unit _not_ specified addressing\n",
l_leadin);
@@ -171,9 +210,14 @@ decode_lun(const char * leadin, unsigned char * lunp)
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_fld,
- e_a_method, x);
+ if (do_hex)
+ printf("%sExtended logical unit addressing: "
+ "length=%d, e.a. method=%d, value=0x%x\n",
+ l_leadin, len_fld, e_a_method, x);
+ else
+ printf("%sExtended logical unit addressing: "
+ "length=%d, e.a. method=%d, value=%d\n",
+ l_leadin, len_fld, e_a_method, x);
} else {
ull = 0;
x = (2 == len_fld) ? 5 : 7;
@@ -182,9 +226,14 @@ decode_lun(const char * leadin, unsigned char * lunp)
ull <<= 8;
ull |= lunp[1 + j];
}
- printf("%sExtended logical unit addressing: length=%d, "
- "e. a. method=%d, value=0x%" PRIx64 "\n",
- l_leadin, len_fld, e_a_method, ull);
+ if (do_hex)
+ printf("%sExtended logical unit addressing: "
+ "length=%d, e. a. method=%d, value=0x%" PRIx64
+ "\n", l_leadin, len_fld, e_a_method, ull);
+ else
+ printf("%sExtended logical unit addressing: "
+ "length=%d, e. a. method=%d, value=%" PRIu64
+ "\n", l_leadin, len_fld, e_a_method, ull);
}
}
break;
@@ -221,13 +270,17 @@ main(int argc, char * argv[])
int do_raw = 0;
int select_rep = 0;
int verbose = 0;
+ unsigned int h;
+ const char * test_arg = NULL;
const char * device_name = NULL;
+ const char * cp;
+ unsigned char lun_arr[8];
int ret = 0;
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "dhHm:qrs:vV", long_options,
+ c = getopt_long(argc, argv, "dhHm:qrs:t:vV", long_options,
&option_index);
if (c == -1)
break;
@@ -264,6 +317,9 @@ main(int argc, char * argv[])
return SG_LIB_SYNTAX_ERROR;
}
break;
+ case 't':
+ test_arg = optarg;
+ break;
case 'v':
++verbose;
break;
@@ -290,6 +346,39 @@ main(int argc, char * argv[])
}
}
+ if (test_arg) {
+ memset(lun_arr, 0, sizeof(lun_arr));
+ cp = test_arg;
+ if (('0' == test_arg[0]) && ('X' == toupper(test_arg[1])))
+ cp += 2;
+ if (strchr(cp, ' ') || strchr(cp, '\t')) {
+ for (k = 0; k < 8; ++k, cp += m) {
+ if (1 != sscanf(cp, " %2x%n", &h, &m))
+ break;
+ lun_arr[k] = h & 0xff;
+ }
+ } else {
+ for (k = 0; k < 8; ++k, cp += 2) {
+ if (1 != sscanf(cp, "%2x", &h))
+ break;
+ lun_arr[k] = h & 0xff;
+ }
+ }
+ if (0 == k) {
+ fprintf(stderr, "expected a hex number, optionally prefixed "
+ "by '0x'\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ if (verbose) {
+ printf("64 bit LUN is T10 preferred (hex) format: ");
+ for (k = 0; k < 8; ++k)
+ printf(" %02x", lun_arr[k]);
+ printf("\n");
+ }
+ printf("Decoded LUN:\n");
+ decode_lun(" ", lun_arr, do_hex);
+ return 0;
+ }
if (NULL == device_name) {
fprintf(stderr, "missing device name!\n");
usage();
@@ -324,7 +413,7 @@ main(int argc, char * argv[])
dStrRaw((const char *)reportLunsBuff, list_len + 8);
goto the_end;
}
- if (do_hex) {
+ if (1 == do_hex) {
dStrHex((const char *)reportLunsBuff, list_len + 8, 1);
goto the_end;
}
@@ -353,7 +442,7 @@ main(int argc, char * argv[])
printf("%02x", reportLunsBuff[off]);
printf("\n");
if (decode)
- decode_lun(" ", reportLunsBuff + off - 8);
+ decode_lun(" ", reportLunsBuff + off - 8, do_hex);
}
} else if (SG_LIB_CAT_INVALID_OP == res)
fprintf(stderr, "Report Luns command not supported (support "