aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2011-05-11 20:08:30 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2011-05-11 20:08:30 +0000
commitb62a65f06ce42b0351077ebeb3c4c7c9ac66ebc6 (patch)
tree5d63272dfb70b478c55c593e73b203350458a2de
parent660dea81490021d39d0eb4fafea51bb9f77ab1cb (diff)
downloadsg3_utils-b62a65f06ce42b0351077ebeb3c4c7c9ac66ebc6.tar.gz
sg_logs: zero response length field when resid say its invalid; tweaks for SAS-2
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@395 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog5
-rw-r--r--README.iscsi8
-rw-r--r--doc/sg_logs.811
-rw-r--r--doc/sg_write_same.831
-rw-r--r--lib/sg_cmds_basic.c19
-rw-r--r--src/sg_logs.c43
-rw-r--r--src/sg_ses.c8
7 files changed, 91 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 333f7962..5c3ff9e9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,10 +2,13 @@ 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.32 [20110401] [svn: r394]
+Changelog for sg3_utils-1.32 [20110510] [svn: r395]
- sg_raw: exit status corrections
- sg_decode_sense: add --nospace and --hex options
+ - sg_logs: fix bug with large --maxlen
+ - zero response length when resid implies it is invalid
- sg_inq: sync version descriptors with spc4r30
+ - add README.iscsi
Changelog for sg3_utils-1.31 [20110216] [svn: r386]
- sg_decode_sense: new utility to decode sense data
diff --git a/README.iscsi b/README.iscsi
new file mode 100644
index 00000000..39bf92de
--- /dev/null
+++ b/README.iscsi
@@ -0,0 +1,8 @@
+TODO: xxxxxxxx
+
+Expect Ronnie Sahlberg to send me content for this readme ...
+
+
+dpg
+20110425
+
diff --git a/doc/sg_logs.8 b/doc/sg_logs.8
index a1cad0b3..858f975d 100644
--- a/doc/sg_logs.8
+++ b/doc/sg_logs.8
@@ -1,4 +1,4 @@
-.TH SG_LOGS "8" "April 2007" "sg3_utils\-1.24" SG3_UTILS
+.TH SG_LOGS "8" "April 2011" "sg3_utils\-1.26" SG3_UTILS
.SH NAME
sg_logs \- access log pages with SCSI LOG SENSE command
.SH SYNOPSIS
@@ -79,9 +79,10 @@ sets the "allocation length" field in the LOG SENSE cdb. The is the maximum
length in bytes that the response will be. Without this option (or \fILEN\fR
equal to 0) this utility first fetches the 4 byte response then does a second
access with the length indicated in the first (4 byte) response. Negative
-values and 1 for \fILEN\fR are not accepted. Responses can be quite
-large (e.g. the background scan results log page) and this option can be
-used to limit the amount of information returned.
+values and 1 for \fILEN\fR are not accepted. \fILEN\fR cannot exceed
+65535 (0xffff). Responses can be quite large (e.g. the background scan
+results log page) and this option can be used to limit the amount of
+information returned.
.TP
\fB\-n\fR, \fB\-\-name\fR
decode some log pages into 'name=value' entries, one per line. The name
@@ -331,7 +332,7 @@ Written by Doug Gilbert
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2002\-2007 Douglas Gilbert
+Copyright \(co 2002\-2011 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_same.8 b/doc/sg_write_same.8
index 01edfa07..019f1562 100644
--- a/doc/sg_write_same.8
+++ b/doc/sg_write_same.8
@@ -1,4 +1,4 @@
-.TH SG_WRITE_SAME "8" "January 2011" "sg3_utils\-1.31" SG3_UTILS
+.TH SG_WRITE_SAME "8" "May 2011" "sg3_utils\-1.32" SG3_UTILS
.SH NAME
sg_write_same \- send the SCSI WRITE SAME command
.SH SYNOPSIS
@@ -15,8 +15,8 @@ Send the SCSI WRITE SAME (10, 16 or 32 byte) command to \fIDEVICE\fR. This
command writes the given block \fINUM\fR times to consecutive blocks on
the \fIDEVICE\fR starting at logical block address \fILBA\fR.
.PP
-The length of the block to be written multiple times is obtained from
-the \fILEN\fR argument, the length of the given input file \fIIF\fR,
+The length of the block to be written multiple times is obtained from either
+the \fILEN\fR argument, or the length of the given input file \fIIF\fR,
or by calling READ CAPACITY(16) on \fIDEVICE\fR. The contents of the
block to be written are obtained from the input file \fIIF\fR or
zeroes are used. If READ CAPACITY(16) is called (which implies \fIIF\fR
@@ -182,12 +182,35 @@ in the sg3_utils(8) man page.
.SH EXIT STATUS
The exit status of sg_write_same is 0 when it is successful. Otherwise see
the sg3_utils(8) man page.
+.SH EXAMPLES
+One simple usage is to write blocks of zero from (and including) a given LBA:
+.PP
+ sg_write_same \-\-lba=0x1234 \-\-num=63 /dev/sdc
+.PP
+Since \fI\-\-xferlen=LEN\fR has not been given, then this utility will
+call the READ CAPACITY command on /dev/sdc to determine the number
+of bytes in a logical block. Let us assume that is 512 bytes. Since
+\fI\-\-in=IF\fR is not given a block of zeroes is assumed. So 63 blocks
+of zeroes (each block containing 512 bytes) will be written from (and
+including) LBA 0x1234 . Note that only one block of zeroes is passed
+to the SCSI WRITE SAME command in the data out buffer (as required by
+SBC\-3).
+.PP
+A similar example follows but in this case the blocks
+are "unmapped" ("trimmed" in ATA speak) rather than zeroed:
+.PP
+ sg_write_same \-\-unmap \-L 0x1234 \-n 63 /dev/sdc
+.PP
+Note that if the LBPRZ bit in the READ CAPACITY(16) response is set (i.e.
+LPPRZ is an acronym for logical block provisioning read zeroes) then these
+two examples do the same thing, at least seen from the point of view of
+subsequent reads.
.SH AUTHORS
Written by Douglas Gilbert.
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2009\-2010 Douglas Gilbert
+Copyright \(co 2009\-2011 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/lib/sg_cmds_basic.c b/lib/sg_cmds_basic.c
index 05ca1f59..44bc5b23 100644
--- a/lib/sg_cmds_basic.c
+++ b/lib/sg_cmds_basic.c
@@ -27,7 +27,7 @@
#endif
-static char * version_str = "1.51 20110207";
+static char * version_str = "1.52 20110510";
#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
@@ -145,8 +145,9 @@ sg_cmds_process_resp(struct sg_pt_base * ptvp, const char * leadin, int res,
if (mx_di_len > 0) {
got = mx_di_len - resid;
if (verbose && (resid > 0))
- fprintf(sg_warnings_strm, " %s: requested %d bytes but "
- "got %d bytes\n", leadin, mx_di_len, got);
+ fprintf(sg_warnings_strm, " %s: pass-through requested "
+ "%d bytes but got %d bytes\n", leadin, mx_di_len,
+ got);
return got;
} else
return 0;
@@ -183,8 +184,8 @@ sg_cmds_process_resp(struct sg_pt_base * ptvp, const char * leadin, int res,
if ((mx_di_len > 0) && (resid > 0)) {
got = mx_di_len - resid;
if ((verbose > 2) || check_data_in || (got > 0))
- fprintf(sg_warnings_strm, " requested %d bytes but "
- "got %d bytes\n", mx_di_len, got);
+ fprintf(sg_warnings_strm, " pass-through requested "
+ "%d bytes but got %d bytes\n", mx_di_len, got);
}
}
if (o_sense_cat)
@@ -1324,8 +1325,14 @@ sg_ll_log_sense(int sg_fd, int ppc, int sp, int pc, int pg_code,
ret = -1;
break;
}
- } else
+ } else {
+ if ((mx_resp_len > 3) && (ret < 4)) {
+ /* resid indicates LOG SENSE response length bad, so zero it */
+ resp[2] = 0;
+ resp[3] = 0;
+ }
ret = 0;
+ }
destruct_scsi_pt_obj(ptvp);
return ret;
}
diff --git a/src/sg_logs.c b/src/sg_logs.c
index 1870bfe5..5183a6b5 100644
--- a/src/sg_logs.c
+++ b/src/sg_logs.c
@@ -25,7 +25,7 @@
*/
-static char * version_str = "0.99 20110322"; /* spc4r27 + sbc3r25 */
+static char * version_str = "1.02 20110510"; /* spc4r27 + sbc3r25 */
#define MX_ALLOC_LEN (0xfffc)
#define SHORT_RESP_LEN 128
@@ -61,7 +61,7 @@ static char * version_str = "0.99 20110322"; /* spc4r27 + sbc3r25 */
#define LOG_SENSE_PROBE_ALLOC_LEN 4
-static unsigned char rsp_buff[MX_ALLOC_LEN];
+static unsigned char rsp_buff[MX_ALLOC_LEN + 4];
static struct option long_options[] = {
{"all", no_argument, 0, 'a'},
@@ -276,8 +276,9 @@ process_cl_new(struct opts_t * optsp, int argc, char * argv[])
break;
case 'm':
n = sg_get_num(optarg);
- if ((n < 0) || (1 == n)) {
- fprintf(stderr, "bad argument to '--maxlen='\n");
+ if ((n < 0) || (1 == n) || (n > 0xffff)) {
+ fprintf(stderr, "bad argument to '--maxlen=', from 2 to "
+ "65535 (inclusive) expected\n");
usage();
return SG_LIB_SYNTAX_ERROR;
}
@@ -568,10 +569,10 @@ static int
do_logs(int sg_fd, unsigned char * resp, int mx_resp_len, int noisy,
const struct opts_t * optsp)
{
- int actual_len;
- int res;
+ int actual_len, res, vb;
memset(resp, 0, mx_resp_len);
+ vb = optsp->do_verbose;
if (optsp->maxlen > 1)
actual_len = mx_resp_len;
else {
@@ -579,7 +580,7 @@ do_logs(int sg_fd, unsigned char * resp, int mx_resp_len, int noisy,
optsp->page_control, optsp->pg_code,
optsp->subpg_code, optsp->paramp,
resp, LOG_SENSE_PROBE_ALLOC_LEN,
- noisy, optsp->do_verbose))) {
+ noisy, vb))) {
switch (res) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
@@ -592,12 +593,23 @@ do_logs(int sg_fd, unsigned char * resp, int mx_resp_len, int noisy,
}
}
actual_len = (resp[2] << 8) + resp[3] + 4;
- if ((0 == optsp->do_raw) && (optsp->do_verbose > 1)) {
+ if ((0 == optsp->do_raw) && (vb > 1)) {
fprintf(stderr, " Log sense (find length) response:\n");
dStrHex((const char *)resp, LOG_SENSE_PROBE_ALLOC_LEN, 1);
fprintf(stderr, " hence calculated response length=%d\n",
actual_len);
}
+ if (optsp->pg_code != (0x3f & resp[0])) {
+ if (vb)
+ fprintf(stderr, "Page code does not appear in first byte "
+ "of response so it's suspect\n");
+ if (actual_len > 0x40) {
+ actual_len = 0x40;
+ if (vb)
+ fprintf(stderr, "Trim response length to 64 bytes due "
+ "to suspect response format\n");
+ }
+ }
/* Some HBAs don't like odd transfer lengths */
if (actual_len % 2)
actual_len += 1;
@@ -607,7 +619,7 @@ do_logs(int sg_fd, unsigned char * resp, int mx_resp_len, int noisy,
if ((res = sg_ll_log_sense(sg_fd, optsp->do_ppc, optsp->do_sp,
optsp->page_control, optsp->pg_code,
optsp->subpg_code, optsp->paramp,
- resp, actual_len, noisy, optsp->do_verbose))) {
+ resp, actual_len, noisy, vb))) {
switch (res) {
case SG_LIB_CAT_NOT_READY:
case SG_LIB_CAT_INVALID_OP:
@@ -619,7 +631,7 @@ do_logs(int sg_fd, unsigned char * resp, int mx_resp_len, int noisy,
return -1;
}
}
- if ((0 == optsp->do_raw) && (optsp->do_verbose > 1)) {
+ if ((0 == optsp->do_raw) && (vb > 1)) {
fprintf(stderr, " Log sense response:\n");
dStrHex((const char *)resp, actual_len, 1);
}
@@ -1898,6 +1910,8 @@ show_sas_port_param(unsigned char * ucp, int param_len,
printf(" sas_addr=0x%" PRIx64 "\n", ull);
} else {
t = ((0x70 & vcp[4]) >> 4);
+ /* attached device type. In SAS-1.1 case 2 was an edge expander;
+ * in SAS-2 case 3 is marked as obsolete. */
switch (t) {
case 0: snprintf(s, sz, "no device attached"); break;
case 1: snprintf(s, sz, "end device"); break;
@@ -3766,7 +3780,7 @@ fetchTemperature(int sg_fd, unsigned char * resp, int max_len,
if (optsp->do_raw)
dStrRaw((const char *)resp, len);
else if (optsp->do_hex)
- dStrHex((const char *)resp, len, 1);
+ dStrHex((const char *)resp, len, (1 == optsp->do_hex));
else
show_temperature_page(resp, len, optsp->do_pcb, 0, 0);
}else if (SG_LIB_CAT_NOT_READY == res)
@@ -3779,7 +3793,7 @@ fetchTemperature(int sg_fd, unsigned char * resp, int max_len,
if (optsp->do_raw)
dStrRaw((const char *)resp, len);
else if (optsp->do_hex)
- dStrHex((const char *)resp, len, 1);
+ dStrHex((const char *)resp, len, (1 == optsp->do_hex));
else
show_ie_page(resp, len, 0, 0);
} else
@@ -3912,7 +3926,7 @@ main(int argc, char * argv[])
if (opts.do_raw)
dStrRaw((const char *)rsp_buff, pg_len + 4);
else if (opts.do_hex > 1)
- dStrHex((const char *)rsp_buff, pg_len + 4, 1);
+ dStrHex((const char *)rsp_buff, pg_len + 4, (2 == opts.do_hex));
else if (pg_len > 1) {
if (opts.do_hex) {
if (rsp_buff[0] & 0x40)
@@ -3962,7 +3976,8 @@ main(int argc, char * argv[])
if (opts.do_raw)
dStrRaw((const char *)rsp_buff, pg_len + 4);
else if (opts.do_hex > 1)
- dStrHex((const char *)rsp_buff, pg_len + 4, 1);
+ dStrHex((const char *)rsp_buff, pg_len + 4,
+ (2 == opts.do_hex));
else if (opts.do_hex) {
if (rsp_buff[0] & 0x40)
printf("Log page code=0x%x,0x%x, DS=%d, SPF=1, page_"
diff --git a/src/sg_ses.c b/src/sg_ses.c
index 96592dee..72d8be69 100644
--- a/src/sg_ses.c
+++ b/src/sg_ses.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004-2010 Douglas Gilbert.
+ * Copyright (c) 2004-2011 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.
@@ -24,7 +24,7 @@
* commands tailored for SES (enclosure) devices.
*/
-static char * version_str = "1.48 20100610"; /* ses3r02 */
+static char * version_str = "1.49 20110511"; /* ses3r02 */
#define MX_ALLOC_LEN 4096
#define MX_ELEM_HDR 1024
@@ -1151,8 +1151,8 @@ truncated:
static char * sas_device_type[] = {
"no device attached",
"end device",
- "edge expander device",
- "fanout expander device",
+ "expander device", /* in SAS-1.1 this was a "edge expander device */
+ "expander device (fanout, SAS-1.1)", /* marked obsolete in SAS-2 */
"reserved [4]", "reserved [5]", "reserved [6]", "reserved [7]"
};