aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2016-05-17 21:43:19 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2016-05-17 21:43:19 +0000
commit8f88e67fae68d46f39da646cf5d069d769e83e93 (patch)
treef43de64cf336bc09b82d35be40334d1cdf7305f9
parent6381973be7964e8c197c33b8669599e24d64cbcc (diff)
downloadsg3_utils-8f88e67fae68d46f39da646cf5d069d769e83e93.tar.gz
sg_cmds_extra: expand sg_ll_ata_pt() with ATA_PT(32); sg_sat_identify: expand to take --len=32
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@705 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog5
-rw-r--r--README2
-rw-r--r--debian/changelog2
-rw-r--r--doc/sg3_utils.837
-rw-r--r--doc/sg_sat_identify.826
-rw-r--r--include/sg_cmds_extra.h34
-rw-r--r--lib/sg_cmds_extra.c94
-rw-r--r--sg3_utils.spec2
-rw-r--r--src/sg_sat_identify.c66
-rw-r--r--src/sg_vpd.c18
10 files changed, 180 insertions, 106 deletions
diff --git a/ChangeLog b/ChangeLog
index 064872bb..5e06c48e 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.43 [20160513] [svn: r704]
+Changelog for sg3_utils-1.43 [20160517] [svn: r705]
- sg_senddiag: add --timeout=SEC option
- sg_sanitize: add --timeout=SEC option
- sg_format: add --timeout=SEC option
@@ -40,6 +40,9 @@ Changelog for sg3_utils-1.43 [20160513] [svn: r704]
- implement 'format' argument in dStrHexStr()
- add Microcode activation sense descriptor spc5r10
- sg_lib_data: sync asc/ascq codes with T10 20160425
+ - sg_cmds_extra: expand sg_ll_ata_pt() to send new
+ Ata pass-through(32) command (sat4r05)
+ - sg_sat_identify: expand to take --len=32
- rescan-scsi-bus.sh: harden code
- fixes from Suse; bump version to: 20160511
- 55-scsi-sg3_id.rules: fixes from Suse
diff --git a/README b/README
index 6b0421f3..bd246e71 100644
--- a/README
+++ b/README
@@ -462,4 +462,4 @@ See http://sg.danny.cz/sg/tools.html
Douglas Gilbert
-4th May 2016
+17th May 2016
diff --git a/debian/changelog b/debian/changelog
index 44b75798..2294e20d 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.43-0.1) unstable; urgency=low
* New upstream version
- -- Douglas Gilbert <dgilbert@interlog.com> Wed, 04 May 2016 19:00:00 -0400
+ -- Douglas Gilbert <dgilbert@interlog.com> Tue, 17 May 2016 22:00:00 +0200
sg3-utils (1.42-0.1) unstable; urgency=low
diff --git a/doc/sg3_utils.8 b/doc/sg3_utils.8
index b2c89db0..b429b1bc 100644
--- a/doc/sg3_utils.8
+++ b/doc/sg3_utils.8
@@ -1,4 +1,4 @@
-.TH SG3_UTILS "8" "April 2016" "sg3_utils\-1.43" SG3_UTILS
+.TH SG3_UTILS "8" "May 2016" "sg3_utils\-1.43" SG3_UTILS
.SH NAME
sg3_utils \- a package of utilities for sending SCSI commands
.SH SYNOPSIS
@@ -30,23 +30,26 @@ SCSI draft standards can be found at http://www.t10.org . The standards
themselves can be purchased from ANSI and other standards organizations.
A good overview of various SCSI standards can be seen in
http://www.t10.org/scsi\-3.htm with the SCSI command sets in the upper part
-of the diagram. SCSI commands in common with all device types can be found
-in SPC of which SPC\-4 is the latest major version. Block device specific
-commands (e.g. as used by disks) are in SBC, those for tape drives in SSC
-and those for CD/DVD/BD drives in MMC.
+of the diagram. The highest level (i.e. most abstract) document is the SCSI
+Architecture Model (SAM) with SAM\-5 being the most recent standard (ANSI
+INCITS 447-2008) although SAM\-5 should be released soon. SCSI commands in
+common with all device types can be found in SPC of which SPC\-5 is the
+latest major version. Block device specific commands (e.g. as used by disks)
+are in SBC, those for tape drives in SSC and those for CD/DVD/BD drives in
+MMC.
.PP
It is becoming more common to control ATA disks with the SCSI command set.
-This involves the translation of SCSI commands to their corresponding
-ATA equivalents (and that is an imperfect mapping in some cases). The
-relevant standard is called SCSI to ATA Translation (SAT and SAT\-2
-are now standards at INCITS(ANSI) and ISO while SAT\-3 is at the draft
-stage). The logic to perform the command translation is often called
-a SAT Layer or SATL and may be within an operating system, in host bus
-adapter firmware or in an external device (e.g. associated with a SAS
-expander). See http://www.t10.org for more information.
+This involves the translation of SCSI commands to their corresponding ATA
+equivalents (and that is an imperfect mapping in some cases). The relevant
+standard is called SCSI to ATA Translation (SAT, SAT\-2 and SAT\-3) are
+now standards at INCITS(ANSI) and ISO while SAT\-4 is at the draft stage.
+The logic to perform the command translation is often called a SAT Layer or
+SATL and may be within an operating system, in host bus adapter firmware or
+in an external device (e.g. associated with a SAS expander). See
+http://www.t10.org for more information.
.PP
There is some support for SCSI tape devices but not for their basic
-commands. The reader is referred to the "mt" utility.
+operation. The reader is referred to the "mt" utility.
.PP
There are two generations of command line option usage. The newer
utilities (written since July 2004) use the getopt_long() function to parse
@@ -281,9 +284,9 @@ the \fIDEVICE\fR reports a SCSI status of "condition met". Currently only
the PRE\-FETCH command (see SBC\-4) yields this status.
.TP
.B 26
-the \fIDEVICE\fR reports a SCSI status of "busy". SAM\-5 defines this
-status as the logical unit is temporarily unable to process a command.
-It is recommended to re-issue the command.
+the \fIDEVICE\fR reports a SCSI status of "busy". SAM\-6 defines this status
+as the logical unit is temporarily unable to process a command. It is
+recommended to re\-issue the command.
.TP
.B 27
the \fIDEVICE\fR reports a SCSI status of "task set full".
diff --git a/doc/sg_sat_identify.8 b/doc/sg_sat_identify.8
index 380e2379..2459e2cb 100644
--- a/doc/sg_sat_identify.8
+++ b/doc/sg_sat_identify.8
@@ -1,11 +1,11 @@
-.TH SG_SAT_IDENTIFY "8" "November 2014" "sg3_utils\-1.40" SG3_UTILS
+.TH SG_SAT_IDENTIFY "8" "May 2016" "sg3_utils\-1.43" SG3_UTILS
.SH NAME
sg_sat_identify \- send ATA IDENTIFY DEVICE command via SCSI to ATA
Translation (SAT) layer
.SH SYNOPSIS
.B sg_sat_identify
[\fI\-\-ck_cond\fR] [\fI\-\-extend\fR] [\fI\-\-help\fR] [\fI\-\-hex\fR]
-[\fI\-\-indent\fR] [\fI\-\-len=\fR{16|12}] [\fI\-\-packet\fR] [\fI\-\-raw\fR]
+[\fI\-\-indent\fR] [\fI\-\-len=CLEN\fR] [\fI\-\-packet\fR] [\fI\-\-raw\fR]
[\fI\-\-readonly\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR] \fIDEVICE\fR
.SH DESCRIPTION
.\" Add any additional description here
@@ -21,9 +21,10 @@ adapter firmware or in some external enclosure.
The SAT standard (SAT ANSI INCITS 431\-2007, prior draft: sat\-r09.pdf at
www.t10.org) defines two SCSI "ATA PASS\-THROUGH" commands: one using a 16
byte "cdb" and the other with a 12 byte cdb. This utility defaults to using
-the 16 byte cdb variant. SAT\-2 is also a standard: SAT\-2 ANSI INCITS
-465\-2010 and the draft prior to that is sat2r09.pdf . The SAT/-3 project
-has started and the most recent draft is sat3r01.pdf .
+the 16 byte cdb variant. SAT\-4 revision 5 added a SCSI "ATA
+PASS\-THROUGH(32)" command. SAT\-2 and SAT\-3 are now also standards: SAT\-2
+ANSI INCITS 465\-2010 and SAT\3 ANSI INCITS 517-2015 . The SAT\-4 project
+is ongiong and the most recent draft is sat4r05c.pdf .
.SH OPTIONS
Arguments to long options are mandatory for short options as well.
.TP
@@ -61,15 +62,16 @@ outputs the World Wide Name (WWN) of the device. This should be a NAA\-5
then "0x0000000000000000" is output. The equivalent for a SCSI disk (i.e. its
logical unit name) can be found with "sg_vpd \-ii".
.TP
-\fB\-l\fR, \fB\-\-len\fR={16|12}
-this is the length of the SCSI cdb used for the ATA PASS\-THROUGH commands.
-The argument can either be 16 or 12. The default is 16. The larger cdb
-size is needed for 48 bit LBA addressing of ATA devices. On the other
-hand some SCSI transports cannot convey SCSI commands longer than 12 bytes.
+\fB\-l\fR, \fB\-\-len\fR=CLEN
+CLEN this is the length of the SCSI cdb used for the ATA PASS\-THROUGH
+command. CLEN can either be 12, 16 or 32. The default is 16. The larger
+cdb sizes are needed for 48 bit LBA addressing of ATA devices. The ATA
+Auxiliary and ICC registers are only conveyed with the 32 byte cdb variant.
.TP
\fB\-p\fR, \fB\-\-packet\fR
send an ATA IDENTIFY PACKET DEVICE command (via the SATL). The default
-action is to send an ATA IDENTIFY DEVICE command.
+action is to send an ATA IDENTIFY DEVICE command. Note that the ATAPI
+specification by T13 (i.e. the PACKET interface) is now obsolete.
.TP
\fB\-r\fR, \fB\-\-raw\fR
output the ATA IDENTIFY (PACKET) DEVICE response in binary. The output
@@ -108,7 +110,7 @@ Written by Douglas Gilbert
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2006\-2014 Douglas Gilbert
+Copyright \(co 2006\-2016 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/include/sg_cmds_extra.h b/include/sg_cmds_extra.h
index 9dd7603a..b348084a 100644
--- a/include/sg_cmds_extra.h
+++ b/include/sg_cmds_extra.h
@@ -23,22 +23,24 @@ extern "C" {
* a lot longer than the default timeout. */
-/* Invokes a ATA PASS-THROUGH (12 or 16) SCSI command (SAT). If cdb_len is
- * 12 then a ATA PASS-THROUGH (12) command is called. If cdb_len is 16 then
- * a ATA PASS-THROUGH (16) command is called. If cdb_len is any other value
- * -1 is returned. After copying from cdbp to an internal buffer, the first
- * byte (i.e. offset 0) is set to 0xa1 if cdb_len is 12; or is set to 0x85
- * if cdb_len is 16. The last byte (offset 11 or offset 15) is set to 0x0 in
- * the internal buffer. For data in or out transfers set dinp or doutp, and
- * dlen to the number of bytes to transfer. If dlen is zero then no data
- * transfer is assumed. If sense buffer obtained then it is written to
- * sensep, else sensep[0] is set to 0x0. If ATA return descriptor is obtained
- * then written to ata_return_dp, else ata_return_dp[0] is set to 0x0. Either
- * sensep or ata_return_dp (or both) may be NULL pointers. Returns SCSI
- * status value (>= 0) or -1 if other error. Users are expected to check the
- * sense buffer themselves. If available the data in resid is written to
- * residp. Note in SAT-2 and later, fixed format sense data may be placed in
- * *sensep in which case sensep[0]==0x70 .
+/* Invokes a ATA PASS-THROUGH (12, 16 or 32) SCSI command (SAT). This is
+ * selected by the cdb_len argument that can take values of 12, 16 or 32
+ * only (else -1 is returned). The byte at offset 0 (and bytes 0 to 9
+ * inclusive for ATA PT(32)) pointed to be cdbp are ignored and apart from
+ * the control byte, the rest is copied into an internal cdb which is then
+ * sent to the device. The control byte is byte 11 for ATA PT(12), byte 15
+ * for ATA PT(16) and byte 1 for ATA PT(32). If timeout_secs <= 0 then the
+ * timeout is set to 60 seconds. For data in or out transfers set dinp or
+ * doutp, and dlen to the number of bytes to transfer. If dlen is zero then
+ * no data transfer is assumed. If sense buffer obtained then it is written
+ * to sensep, else sensep[0] is set to 0x0. If ATA return descriptor is
+ * obtained then written to ata_return_dp, else ata_return_dp[0] is set to
+ * 0x0. Either sensep or ata_return_dp (or both) may be NULL pointers.
+ * Returns SCSI status value (>= 0) or -1 if other error. Users are
+ * expected to check the sense buffer themselves. If available the data in
+ * resid is written to residp. Note in SAT-2 and later, fixed format sense
+ * data may be placed in *sensep in which case sensep[0]==0x70, prior to
+ * SAT-2 descriptor sense format was required (i.e. sensep[0]==0x72).
*/
int sg_ll_ata_pt(int sg_fd, const unsigned char * cdbp, int cdb_len,
int timeout_secs, void * dinp, void * doutp, int dlen,
diff --git a/lib/sg_cmds_extra.c b/lib/sg_cmds_extra.c
index 864a093c..022870f5 100644
--- a/lib/sg_cmds_extra.c
+++ b/lib/sg_cmds_extra.c
@@ -43,6 +43,8 @@
#define ATA_PT_12_CMDLEN 12
#define ATA_PT_16_CMD 0x85
#define ATA_PT_16_CMDLEN 16
+#define ATA_PT_32_SA 0x1ff0
+#define ATA_PT_32_CMDLEN 32
#define FORMAT_UNIT_CMD 0x4
#define FORMAT_UNIT_CMDLEN 6
#define PERSISTENT_RESERVE_IN_CMD 0x5e
@@ -1531,23 +1533,24 @@ sg_ll_verify16(int sg_fd, int vrprotect, int dpo, int bytchk, uint64_t llba,
return ret;
}
-/* Invokes a ATA PASS-THROUGH (12 or 16) SCSI command (SAT). If cdb_len
- * is 12 then a ATA PASS-THROUGH (12) command is called. If cdb_len is 16
- * then a ATA PASS-THROUGH (16) command is called. If cdb_len is any other
- * value -1 is returned. After copying from cdbp to an internal buffer,
- * the first byte (i.e. offset 0) is set to 0xa1 if cdb_len is 12; or is
- * set to 0x85 if cdb_len is 16. The last byte (offset 11 or offset 15) is
- * set to 0x0 in the internal buffer. If timeout_secs <= 0 then the timeout
- * is set to 60 seconds. For data in or out transfers set dinp or doutp,
- * and dlen to the number of bytes to transfer. If dlen is zero then no data
- * transfer is assumed. If sense buffer obtained then it is written to
- * sensep, else sensep[0] is set to 0x0. If ATA return descriptor is obtained
- * then written to ata_return_dp, else ata_return_dp[0] is set to 0x0. Either
- * sensep or ata_return_dp (or both) may be NULL pointers. Returns SCSI
- * status value (>= 0) or -1 if other error. Users are expected to check the
- * sense buffer themselves. If available the data in resid is written to
- * residp. Note in SAT-2 and later, fixed format sense data may be placed in
- * *sensep in which case sensep[0]==0x70 .
+/* Invokes a ATA PASS-THROUGH (12, 16 or 32) SCSI command (SAT). This is
+ * selected by the cdb_len argument that can take values of 12, 16 or 32
+ * only (else -1 is returned). The byte at offset 0 (and bytes 0 to 9
+ * inclusive for ATA PT(32)) pointed to be cdbp are ignored and apart from
+ * the control byte, the rest is copied into an internal cdb which is then
+ * sent to the device. The control byte is byte 11 for ATA PT(12), byte 15
+ * for ATA PT(16) and byte 1 for ATA PT(32). If timeout_secs <= 0 then the
+ * timeout is set to 60 seconds. For data in or out transfers set dinp or
+ * doutp, and dlen to the number of bytes to transfer. If dlen is zero then
+ * no data transfer is assumed. If sense buffer obtained then it is written
+ * to sensep, else sensep[0] is set to 0x0. If ATA return descriptor is
+ * obtained then written to ata_return_dp, else ata_return_dp[0] is set to
+ * 0x0. Either sensep or ata_return_dp (or both) may be NULL pointers.
+ * Returns SCSI status value (>= 0) or -1 if other error. Users are
+ * expected to check the sense buffer themselves. If available the data in
+ * resid is written to residp. Note in SAT-2 and later, fixed format sense
+ * data may be placed in *sensep in which case sensep[0]==0x70, prior to
+ * SAT-2 descriptor sense format was required (i.e. sensep[0]==0x72).
*/
int
sg_ll_ata_pt(int sg_fd, const unsigned char * cdbp, int cdb_len,
@@ -1557,8 +1560,7 @@ sg_ll_ata_pt(int sg_fd, const unsigned char * cdbp, int cdb_len,
int * residp, int verbose)
{
int k, res, slen, duration;
- unsigned char aptCmdBlk[ATA_PT_16_CMDLEN] =
- {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ unsigned char aptCmdBlk[ATA_PT_32_CMDLEN];
unsigned char sense_b[SENSE_BUFF_LEN];
unsigned char * sp;
const unsigned char * bp;
@@ -1567,19 +1569,38 @@ sg_ll_ata_pt(int sg_fd, const unsigned char * cdbp, int cdb_len,
char b[256];
int ret = -1;
+ memset(aptCmdBlk, 0, sizeof(aptCmdBlk));
b[0] = '\0';
- cnamep = (12 == cdb_len) ?
- "ATA pass through (12)" : "ATA pass through (16)";
- if ((NULL == cdbp) || ((12 != cdb_len) && (16 != cdb_len))) {
- if (verbose) {
- if (NULL == cdbp)
- pr2ws("%s NULL cdb pointer\n", cnamep);
- else
- pr2ws("cdb_len must be 12 or 16\n");
- }
+ switch (cdb_len) {
+ case 12:
+ cnamep = "ATA pass-through(12)";
+ aptCmdBlk[0] = ATA_PT_12_CMD;
+ memcpy(aptCmdBlk + 1, cdbp + 1, 10);
+ /* control byte at cdb[11] left at zero */
+ break;
+ case 16:
+ cnamep = "ATA pass-through(16)";
+ aptCmdBlk[0] = ATA_PT_16_CMD;
+ memcpy(aptCmdBlk + 1, cdbp + 1, 14);
+ /* control byte at cdb[15] left at zero */
+ break;
+ case 32:
+ cnamep = "ATA pass-through(32)";
+ aptCmdBlk[0] = SG_VARIABLE_LENGTH_CMD;
+ /* control byte at cdb[1] left at zero */
+ aptCmdBlk[7] = 0x18; /* length starting at next byte */
+ sg_put_unaligned_be16(ATA_PT_32_SA, aptCmdBlk + 8);
+ memcpy(aptCmdBlk + 10, cdbp + 10, 32 - 10);
+ break;
+ default:
+ pr2ws("cdb_len must be 12, 16 or 32\n");
+ return -1;
+ }
+ if (NULL == cdbp) {
+ if (verbose)
+ pr2ws("%s NULL cdb pointer\n", cnamep);
return -1;
}
- aptCmdBlk[0] = (12 == cdb_len) ? ATA_PT_12_CMD : ATA_PT_16_CMD;
if (sensep && (max_sense_len >= (int)sizeof(sense_b))) {
sp = sensep;
slen = max_sense_len;
@@ -1587,15 +1608,16 @@ sg_ll_ata_pt(int sg_fd, const unsigned char * cdbp, int cdb_len,
sp = sense_b;
slen = sizeof(sense_b);
}
- if (12 == cdb_len)
- memcpy(aptCmdBlk + 1, cdbp + 1, ((cdb_len > 11) ? 10 : (cdb_len - 1)));
- else
- memcpy(aptCmdBlk + 1, cdbp + 1, ((cdb_len > 15) ? 14 : (cdb_len - 1)));
if (verbose) {
pr2ws(" %s cdb: ", cnamep);
- for (k = 0; k < cdb_len; ++k)
- pr2ws("%02x ", aptCmdBlk[k]);
- pr2ws("\n");
+ if (cdb_len < 32) {
+ for (k = 0; k < cdb_len; ++k)
+ pr2ws("%02x ", aptCmdBlk[k]);
+ pr2ws("\n");
+ } else {
+ pr2ws("\n");
+ dStrHexErr((const char *)aptCmdBlk, cdb_len, -1);
+ }
}
ptvp = construct_scsi_pt_obj();
if (NULL == ptvp) {
diff --git a/sg3_utils.spec b/sg3_utils.spec
index 90952d84..9d40ec77 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,7 +79,7 @@ fi
%{_libdir}/*.la
%changelog
-* Wed May 04 2016 - dgilbert at interlog dot com
+* Tue May 17 2016 - dgilbert at interlog dot com
- track t10 changes
* sg3_utils-1.43
diff --git a/src/sg_sat_identify.c b/src/sg_sat_identify.c
index f5f4de4c..8524df3d 100644
--- a/src/sg_sat_identify.c
+++ b/src/sg_sat_identify.c
@@ -21,16 +21,19 @@
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
#include "sg_pr2serr.h"
+#include "sg_unaligned.h"
/* This program uses a ATA PASS-THROUGH SCSI command to package an
* ATA IDENTIFY (PACKAGE) DEVICE command. It is based on the SCSI to
* ATA Translation (SAT) drafts and standards. See http://www.t10.org
* for drafts. SAT is a standard: SAT ANSI INCITS 431-2007 (draft prior
* to that is sat-r09.pdf). SAT-2 is also a standard: SAT-2 ANSI INCITS
- * 465-2010 and the draft prior to that is sat2r09.pdf . The SAT-3
- * project has started and the most recent draft is sat3r01.pdf .
+ * 465-2010 and the draft prior to that is sat2r09.pdf . The SAT-3 is
+ * now a standard: SAT-3 ANSI INCITS 517-2015. The most current draft of
+ * SAT-4 is revision 5c (sat4r05c.pdf).
*/
+#define SAT_ATA_PASS_THROUGH32_LEN 32
#define SAT_ATA_PASS_THROUGH16 0x85
#define SAT_ATA_PASS_THROUGH16_LEN 16
#define SAT_ATA_PASS_THROUGH12 0xa1 /* clashes with MMC BLANK comand */
@@ -46,7 +49,7 @@
#define EBUFF_SZ 256
-static const char * version_str = "1.12 20160126";
+static const char * version_str = "1.13 20160517";
static struct option long_options[] = {
{"ck_cond", no_argument, 0, 'c'},
@@ -67,7 +70,7 @@ static void usage()
{
pr2serr("Usage: sg_sat_identify [--ck_cond] [--extend] [--help] [--hex] "
"[--ident]\n"
- " [--len=16|12] [--packet] [--raw] "
+ " [--len=CLEN] [--packet] [--raw] "
"[--readonly]\n"
" [--verbose] [--version] DEVICE\n"
" where:\n"
@@ -78,16 +81,20 @@ static void usage()
" --ident|-i output WWN prefixed by 0x, if not "
"available output\n"
" 0x0000000000000000\n"
- " --len=16|12 | -l 16|12 cdb length: 16 or 12 bytes "
- "(default: 16)\n"
+ " --len=CLEN| -l CLEN CLEN is cdb length: 12, 16 or 32 "
+ "bytes\n"
+ " (default: 16)\n"
" --packet|-p do IDENTIFY PACKET DEVICE (def: IDENTIFY "
- "DEVICE) command\n"
+ "DEVICE)\n"
+ " command\n"
" --raw|-r output response in binary to stdout\n"
" --readonly|-R open DEVICE read-only (def: read-write)\n"
" --verbose|-v increase verbosity\n"
" --version|-V print version string and exit\n\n"
"Performs a ATA IDENTIFY (PACKET) DEVICE command via a SAT "
- "layer\n");
+ "layer using\na SCSI ATA PASS-THROUGH(12), (16) or (32) command. "
+ "Only SAT layers\ncompliant with SAT-4 revision 5 or later will "
+ "support the SCSI ATA\nPASS-THROUGH(32) command.\n");
}
static void dStrRaw(const char* str, int len)
@@ -124,15 +131,32 @@ static int do_identify_dev(int sg_fd, int do_packet, int cdb_len,
unsigned char apt12CmdBlk[SAT_ATA_PASS_THROUGH12_LEN] =
{SAT_ATA_PASS_THROUGH12, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0};
+ unsigned char apt32CmdBlk[SAT_ATA_PASS_THROUGH32_LEN];
const unsigned short * usp;
uint64_t ull;
sb_sz = sizeof(sense_buffer);
memset(sense_buffer, 0, sb_sz);
+ memset(apt32CmdBlk, 0, sizeof(apt32CmdBlk));
memset(ata_return_desc, 0, sizeof(ata_return_desc));
ok = 0;
- if (SAT_ATA_PASS_THROUGH16_LEN == cdb_len) {
- /* Prepare ATA PASS-THROUGH COMMAND (16) command */
+ switch (cdb_len) {
+ case SAT_ATA_PASS_THROUGH32_LEN: /* SAT-4 revision 5 or later */
+ /* Prepare SCSI ATA PASS-THROUGH COMMAND(32) command */
+ sg_put_unaligned_be16(1, apt32CmdBlk + 22); /* count=1 */
+ apt32CmdBlk[25] = (do_packet ? ATA_IDENTIFY_PACKET_DEVICE :
+ ATA_IDENTIFY_DEVICE);
+ apt32CmdBlk[10] = (multiple_count << 5) | (protocol << 1) | extend;
+ apt32CmdBlk[11] = (ck_cond << 5) | (t_type << 4) | (t_dir << 3) |
+ (byte_block << 2) | t_length;
+ /* following call takes care of all bytes below offset 10 in cdb */
+ res = sg_ll_ata_pt(sg_fd, apt32CmdBlk, cdb_len, DEF_TIMEOUT, inBuff,
+ NULL /* doutp */, ID_RESPONSE_LEN, sense_buffer,
+ sb_sz, ata_return_desc,
+ sizeof(ata_return_desc), &resid, verbose);
+ break;
+ case SAT_ATA_PASS_THROUGH16_LEN:
+ /* Prepare SCSI ATA PASS-THROUGH COMMAND(16) command */
aptCmdBlk[6] = 1; /* sector count */
aptCmdBlk[14] = (do_packet ? ATA_IDENTIFY_PACKET_DEVICE :
ATA_IDENTIFY_DEVICE);
@@ -143,8 +167,9 @@ static int do_identify_dev(int sg_fd, int do_packet, int cdb_len,
NULL /* doutp */, ID_RESPONSE_LEN, sense_buffer,
sb_sz, ata_return_desc,
sizeof(ata_return_desc), &resid, verbose);
- } else {
- /* Prepare ATA PASS-THROUGH COMMAND (12) command */
+ break;
+ case SAT_ATA_PASS_THROUGH12_LEN:
+ /* Prepare SCSI ATA PASS-THROUGH COMMAND(12) command */
apt12CmdBlk[4] = 1; /* sector count */
apt12CmdBlk[9] = (do_packet ? ATA_IDENTIFY_PACKET_DEVICE :
ATA_IDENTIFY_DEVICE);
@@ -155,6 +180,10 @@ static int do_identify_dev(int sg_fd, int do_packet, int cdb_len,
NULL /* doutp */, ID_RESPONSE_LEN, sense_buffer,
sb_sz, ata_return_desc,
sizeof(ata_return_desc), &resid, verbose);
+ break;
+ default:
+ pr2serr("%s: bad cdb_len=%d\n", __func__, cdb_len);
+ return -1;
}
if (0 == res) {
ok = 1;
@@ -162,7 +191,7 @@ static int do_identify_dev(int sg_fd, int do_packet, int cdb_len,
pr2serr("command completed with SCSI GOOD status\n");
} else if ((res > 0) && (res & SAM_STAT_CHECK_CONDITION)) {
if (verbose > 1) {
- pr2serr("ATA pass through:\n");
+ pr2serr("ATA pass-through:\n");
sg_print_sense(NULL, sense_buffer, sb_sz,
((verbose > 2) ? 1 : 0));
}
@@ -264,7 +293,7 @@ static int do_identify_dev(int sg_fd, int do_packet, int cdb_len,
return SG_LIB_CAT_MALFORMED;
}
} else {
- pr2serr("ATA pass through (%d) failed\n", cdb_len);
+ pr2serr("ATA pass-through (%d) failed\n", cdb_len);
if (verbose < 2)
pr2serr(" try adding '-v' for more information\n");
return -1;
@@ -367,8 +396,13 @@ int main(int argc, char * argv[])
break;
case 'l':
cdb_len = sg_get_num(optarg);
- if (! ((cdb_len == 12) || (cdb_len == 16))) {
- pr2serr("argument to '--len' should be 12 or 16\n");
+ switch (cdb_len) {
+ case 12:
+ case 16:
+ case 32:
+ break;
+ default:
+ pr2serr("argument to '--len' should be 12, 16 or 32\n");
return SG_LIB_SYNTAX_ERROR;
}
break;
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index 87c43d7f..6bb5cebf 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -37,7 +37,7 @@
*/
-static const char * version_str = "1.21 20160503"; /* spc5r09 + sbc4r10 */
+static const char * version_str = "1.22 20160515"; /* spc5r10 + sbc4r10 */
/* These structures are duplicates of those of the same name in
@@ -1371,7 +1371,7 @@ static void
decode_ata_info_vpd(unsigned char * buff, int len, int do_long, int do_hex)
{
char b[80];
- int num, is_be;
+ int num, is_be, cc;
const char * cp;
const char * ata_transp;
@@ -1400,11 +1400,19 @@ decode_ata_info_vpd(unsigned char * buff, int len, int do_long, int do_hex)
dStrHex((const char *)buff + 36, 20, 0);
} else
printf(" Device signature indicates %s transport\n", ata_transp);
+ cc = buff[56]; /* 0xec for IDENTIFY DEVICE and 0xa1 for IDENTIFY
+ * PACKET DEVICE (obsolete) */
+ printf(" Command code: 0x%x\n", cc);
if (len < 60)
return;
+ if (0xec == cc)
+ cp = "";
+ else if (0xa1 == cc)
+ cp = "PACKET ";
+ else
+ cp = NULL;
is_be = sg_is_big_endian();
- if ((0xec == buff[56]) || (0xa1 == buff[56])) {
- cp = (0xa1 == buff[56]) ? "PACKET " : "";
+ if (cp) {
printf(" ATA command IDENTIFY %sDEVICE response summary:\n", cp);
num = sg_ata_get_chars((const unsigned short *)(buff + 60), 27, 20,
is_be, b);
@@ -1422,7 +1430,7 @@ decode_ata_info_vpd(unsigned char * buff, int len, int do_long, int do_hex)
printf(" ATA command IDENTIFY %sDEVICE response in hex:\n", cp);
} else if (do_long)
printf(" ATA command 0x%x got following response:\n",
- (unsigned int)buff[56]);
+ (unsigned int)cc);
if (len < 572)
return;
if (2 == do_hex)