diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2013-02-25 05:39:19 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2013-02-25 05:39:19 +0000 |
commit | d772abe4e33fdf83d2cb082598df5103965795d5 (patch) | |
tree | 8b0c84f97c26e500d425b8fec911102629c81b5a | |
parent | 074a673a2d0b1b74337c1a3fc66ab7408a27c6f0 (diff) | |
download | sg3_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-- | ChangeLog | 6 | ||||
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | debian/changelog | 2 | ||||
-rw-r--r-- | doc/sg_inq.8 | 4 | ||||
-rw-r--r-- | doc/sg_luns.8 | 38 | ||||
-rw-r--r-- | sg3_utils.spec | 2 | ||||
-rw-r--r-- | src/sg_inq.c | 2 | ||||
-rw-r--r-- | src/sg_luns.c | 157 |
8 files changed, 163 insertions, 50 deletions
@@ -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 @@ -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 " |