aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--README2
-rw-r--r--debian/changelog2
-rw-r--r--doc/sg_inq.813
-rw-r--r--doc/sg_vpd.820
-rw-r--r--sg3_utils.spec2
-rw-r--r--src/sg_inq.c130
-rw-r--r--src/sg_vpd.c451
-rw-r--r--src/sg_vpd_vendor.c184
9 files changed, 513 insertions, 295 deletions
diff --git a/ChangeLog b/ChangeLog
index dedf769c..a9e7a3a6 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.26 [20080204]
+Changelog for sg3_utils-1.26 [20080207]
- sg_ses: sync with ses2r19a
- sg_get_config: sync with mmc6r01
- allow Microcode upgrade and DVD read feature descriptors
@@ -11,6 +11,8 @@ Changelog for sg3_utils-1.26 [20080204]
- add sg_ll_get_performance() and sg_ll_set_cd_speed()
- sg_verify: add --vrprotect= option
- sg_vpd: add nominal form factor to block dev. char. VPD page
+ - add --maxlen= option to set allocation length in cdb
+ - sg_inq: add --maxlen= option that does same as --len=
- sg_write_long: add examples section to man page
- sg_sat_phy_event: copied from examples directory and enhanced,
rename original to sg__sat_phy_event
diff --git a/README b/README
index 04dade9a..cc869f42 100644
--- a/README
+++ b/README
@@ -328,4 +328,4 @@ See http://www.torque.net/sg/tools.html
Doug Gilbert
-29th January 2008
+7th February 2008
diff --git a/debian/changelog b/debian/changelog
index 29644d53..05758198 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,7 +2,7 @@ sg3-utils (1.26-0.1) unstable; urgency=low
* New upstream version
- -- Doug Gilbert <dgilbert@interlog.com> Tue, 29 Jan 2008 16:00:00 +0100
+ -- Doug Gilbert <dgilbert@interlog.com> Thu, 07 Feb 2008 22:00:00 -0500
sg3-utils (1.25-0.1) unstable; urgency=low
diff --git a/doc/sg_inq.8 b/doc/sg_inq.8
index 88e157e2..945fc50b 100644
--- a/doc/sg_inq.8
+++ b/doc/sg_inq.8
@@ -1,4 +1,4 @@
-.TH SG_INQ "8" "August 2007" "sg3_utils\-1.25" SG3_UTILS
+.TH SG_INQ "8" "February 2008" "sg3_utils\-1.26" SG3_UTILS
.SH NAME
sg_inq \- sends a SCSI INQUIRY or ATA IDENTIFY (PACKET) DEVICE command
and outputs the response
@@ -6,8 +6,8 @@ and outputs the response
.B sg_inq
[\fI\-\-ata\fR] [\fI\-\-cmddt\fR] [\fI\-\-descriptors\fR] [\fI\-\-extended\fR]
[\fI\-\-help\fR] [\fI\-\-hex\fR] [\fI\-\-id\fR] [\fI\-\-len=LEN\fR]
-[\fI\-\-page=PG\fR] [\fI\-\-raw\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR]
-[\fI\-\-vpd\fR] \fIDEVICE\fR
+[\fI\-\-maxlen=LEN\fR] [\fI\-\-page=PG\fR] [\fI\-\-raw\fR] [\fI\-\-verbose\fR]
+[\fI\-\-version\fR] [\fI\-\-vpd\fR] \fIDEVICE\fR
.PP
.B sg_inq
[\fI\-36\fR] [\fI\-a\fR] [\fI\-A\fR] [\fI\-b\fR] [\fI\-c\fR] [\fI\-cl\fR]
@@ -110,6 +110,11 @@ length" field in the response indicates that more than 36 bytes is available.
If \fILEN\fR is greater than 0 then only one INQUIRY command is performed.
See paragraph below about "36 byte INQUIRYs".
.TP
+\fB\-m\fR, \fB\-\-maxlen\fR=\fILEN\fR
+this option has the same action as the \fI\-\-len=LEN\fR option. It has
+been added for compatibility with the sg_vpd, sg_modes and sg_logs
+utilities.
+.TP
\fB\-O\fR, \fB\-\-old\fR
switch to older style options.
.TP
@@ -324,7 +329,7 @@ Written by Doug Gilbert
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2001\-2007 Douglas Gilbert
+Copyright \(co 2001\-2008 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_vpd.8 b/doc/sg_vpd.8
index bdb1fd17..11f60174 100644
--- a/doc/sg_vpd.8
+++ b/doc/sg_vpd.8
@@ -1,11 +1,12 @@
-.TH SG_VPD "8" "April 2007" "sg3_utils\-1.24" SG3_UTILS
+.TH SG_VPD "8" "February 2008" "sg3_utils\-1.26" SG3_UTILS
.SH NAME
sg_vpd \- fetches Vital Product Data (VPD) pages using a SCSI INQUIRY command
.SH SYNOPSIS
.B sg_vpd
[\fI\-\-enumerate\fR] [\fI\-\-help\fR] [\fI\-\-hex\fR] [\fI\-\-ident\fR]
-[\fI\-\-long\fR] [\fI\-\-page=PG\fR] [\fI\-\-quiet\fR] [\fI\-\-raw\fR]
-[\fI\-\-verbose\fR] [\fI\-\-version\fR] \fIDEVICE\fR
+[\fI\-\-long\fR] [\fI\-\-maxlen=LEN\fR] [\fI\-\-page=PG\fR]
+[\fI\-\-quiet\fR] [\fI\-\-raw\fR] [\fI\-\-verbose\fR] [\fI\-\-version\fR]
+\fIDEVICE\fR
.SH DESCRIPTION
.\" Add any additional description here
.PP
@@ -50,6 +51,17 @@ when decoding some VPD pages, give a little more output. For example the ATA
Information VPD page only shows the signature (in hex) and the IDENTIFY
(PACKET) DEVICE (in hex) when this option is given.
.TP
+\fB\-m\fR, \fB\-\-maxlen\fR=\fILEN\fR
+where \fILEN\fR is the (maximum) response length in bytes. It is placed in the
+cdb's "allocation length" field. If not given (or \fILEN\fR is zero) then
+252 is used (apart from the ATA Information VPD page which defaults to 572)
+and, if the response indicates this value is insufficient, another INQUIRY
+command is sent with a larger value in the cdb's "allocation length" field.
+If this option is given and \fILEN\fR is greater than 0 then only one INQUIRY
+command is sent. Since many simple devices implement the INQUIRY command
+badly (and do not support VPD pages) then the safest value to use for
+\fILEN\fR is 36. See the sg_inq man page for the more information.
+.TP
\fB\-p\fR, \fB\-\-page\fR=\fIPG\fR
where \fIPG\fR is the VPD page to be decoded or output. The \fIPG\fR argument
can either be an abbreviation, a number or a pair or numbers separated by a
@@ -107,7 +119,7 @@ Written by Doug Gilbert
.SH "REPORTING BUGS"
Report bugs to <dgilbert at interlog dot com>.
.SH COPYRIGHT
-Copyright \(co 2006\-2007 Douglas Gilbert
+Copyright \(co 2006\-2008 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 a5f3c29f..ffecf3a3 100644
--- a/sg3_utils.spec
+++ b/sg3_utils.spec
@@ -79,7 +79,7 @@ fi
%{_libdir}/*.la
%changelog
-* Tue Jan 29 2008 - dgilbert at interlog dot com
+* Thu Feb 07 2008 - dgilbert at interlog dot com
- sg_get_config sync with mmc6r01, add sg_sat_phy_event
* sg3_utils-1.26
diff --git a/src/sg_inq.c b/src/sg_inq.c
index 806fb564..b35f0908 100644
--- a/src/sg_inq.c
+++ b/src/sg_inq.c
@@ -168,6 +168,7 @@ static struct option long_options[] = {
{"hex", 0, 0, 'H'},
{"id", 0, 0, 'i'},
{"len", 1, 0, 'l'},
+ {"maxlen", 1, 0, 'm'},
{"new", 0, 0, 'N'},
{"old", 0, 0, 'O'},
{"page", 1, 0, 'p'},
@@ -199,15 +200,16 @@ struct opts_t {
int opt_new;
};
-static void usage()
+static void
+usage()
{
#ifdef SG3_UTILS_LINUX
fprintf(stderr,
"Usage: sg_inq [--ata] [--cmddt] [--descriptors] [--extended] "
"[--help] [--hex]\n"
- " [--id] [--len=LEN] [--page=PG] [--raw] "
- "[--verbose] [--version]\n"
- " [--vpd] DEVICE\n"
+ " [--id] [--len=LEN] [--maxlen=LEN] [--page=PG] "
+ "[--raw]\n"
+ " [--verbose] [--version] [--vpd] DEVICE\n"
" where:\n"
" --ata|-a treat DEVICE as (directly attached) ATA "
"device\n");
@@ -215,9 +217,9 @@ static void usage()
fprintf(stderr,
"Usage: sg_inq [--cmddt] [--descriptors] [--extended] [--help] "
"[--hex] [--id]\n"
- " [--len=LEN] [--page=PG] [--raw] [--verbose] "
- "[--version] [--vpd]\n"
- " DEVICE\n"
+ " [--len=LEN] [--maxlen=LEN] [--page=PG] [--raw] "
+ "[--verbose]\n"
+ " [--version] [--vpd] DEVICE\n"
" where:\n");
#endif
fprintf(stderr,
@@ -236,6 +238,7 @@ static void usage()
"-> fetch 36\n"
" bytes first, then fetch again as "
"indicated)\n"
+ " --maxlen=LEN|-m LEN same as '--len='\n"
" --page=PG|-p PG Vital Product Data (VPD) page number "
"or\n"
" abbreviation (opcode number if "
@@ -249,7 +252,8 @@ static void usage()
"If no options given then does a 'standard' INQUIRY.\n");
}
-static void usage_old()
+static void
+usage_old()
{
#ifdef SG3_UTILS_LINUX
fprintf(stderr,
@@ -303,7 +307,8 @@ static void usage_old()
"If no options given then does a standard SCSI INQUIRY\n");
}
-static void usage_for(const struct opts_t * optsp)
+static void
+usage_for(const struct opts_t * optsp)
{
if (optsp->opt_new)
usage();
@@ -311,7 +316,8 @@ static void usage_for(const struct opts_t * optsp)
usage_old();
}
-static int process_cl_new(struct opts_t * optsp, int argc, char * argv[])
+static int
+process_cl_new(struct opts_t * optsp, int argc, char * argv[])
{
int c, n;
@@ -319,10 +325,10 @@ static int process_cl_new(struct opts_t * optsp, int argc, char * argv[])
int option_index = 0;
#ifdef SG3_UTILS_LINUX
- c = getopt_long(argc, argv, "acdeEhHil:NOp:rvVx", long_options,
+ c = getopt_long(argc, argv, "acdeEhHil:m:NOp:rvVx", long_options,
&option_index);
#else
- c = getopt_long(argc, argv, "cdeEhHil:NOp:rvVx", long_options,
+ c = getopt_long(argc, argv, "cdeEhHil:m:NOp:rvVx", long_options,
&option_index);
#endif
if (c == -1)
@@ -365,6 +371,7 @@ static int process_cl_new(struct opts_t * optsp, int argc, char * argv[])
optsp->page_num = VPD_DEVICE_ID;
break;
case 'l':
+ case 'm':
n = sg_get_num(optarg);
if ((n < 0) || (n > 65532)) {
fprintf(stderr, "bad argument to '--len='\n");
@@ -414,7 +421,8 @@ static int process_cl_new(struct opts_t * optsp, int argc, char * argv[])
return 0;
}
-static int process_cl_old(struct opts_t * optsp, int argc, char * argv[])
+static int
+process_cl_old(struct opts_t * optsp, int argc, char * argv[])
{
int k, jmp_out, plen, num, n;
const char * cp;
@@ -564,7 +572,8 @@ static int process_cl_old(struct opts_t * optsp, int argc, char * argv[])
return 0;
}
-static int process_cl(struct opts_t * optsp, int argc, char * argv[])
+static int
+process_cl(struct opts_t * optsp, int argc, char * argv[])
{
int res;
char * cp;
@@ -585,7 +594,7 @@ static int process_cl(struct opts_t * optsp, int argc, char * argv[])
}
static const struct svpd_values_name_t *
- sdp_find_vpd_by_acron(const char * ap)
+sdp_find_vpd_by_acron(const char * ap)
{
const struct svpd_values_name_t * vnp;
@@ -596,7 +605,8 @@ static const struct svpd_values_name_t *
return NULL;
}
-static void enumerate_vpds()
+static void
+enumerate_vpds()
{
const struct svpd_values_name_t * vnp;
@@ -607,7 +617,8 @@ static void enumerate_vpds()
}
}
-static void dStrRaw(const char* str, int len)
+static void
+dStrRaw(const char* str, int len)
{
int k;
@@ -646,7 +657,8 @@ static struct vpd_name vpd_name_arr[] = {
{0xc9, 0, "Volume Access Control (RDAC)"},
};
-const char * get_vpd_page_str(int vpd_page_num, int scsi_ptype)
+static const char *
+get_vpd_page_str(int vpd_page_num, int scsi_ptype)
{
int k;
int vpd_name_arr_sz =
@@ -683,7 +695,8 @@ const char * get_vpd_page_str(int vpd_page_num, int scsi_ptype)
}
}
-static void decode_id_vpd(unsigned char * buff, int len, int do_hex)
+static void
+decode_id_vpd(unsigned char * buff, int len, int do_hex)
{
if (len < 4) {
fprintf(stderr, "Device identification VPD page length too "
@@ -718,7 +731,8 @@ static const char * network_service_type_arr[] =
"reserved[0x1e]", "reserved[0x1f]",
};
-static void decode_net_man_vpd(unsigned char * buff, int len, int do_hex)
+static void
+decode_net_man_vpd(unsigned char * buff, int len, int do_hex)
{
int k, bump, na_len;
unsigned char * ucp;
@@ -759,7 +773,8 @@ static const char * mode_page_policy_arr[] =
"per I_T nexus",
};
-static void decode_mode_policy_vpd(unsigned char * buff, int len, int do_hex)
+static void
+decode_mode_policy_vpd(unsigned char * buff, int len, int do_hex)
{
int k, bump;
unsigned char * ucp;
@@ -792,7 +807,8 @@ static void decode_mode_policy_vpd(unsigned char * buff, int len, int do_hex)
}
}
-static void decode_scsi_ports_vpd(unsigned char * buff, int len, int do_hex)
+static void
+decode_scsi_ports_vpd(unsigned char * buff, int len, int do_hex)
{
int k, bump, rel_port, ip_tid_len, tpd_len;
unsigned char * ucp;
@@ -864,13 +880,9 @@ static const char * id_type_arr[] =
"Reserved [0xc]", "Reserved [0xd]", "Reserved [0xe]", "Reserved [0xf]",
};
-extern int sg_vpd_dev_id_iter(const unsigned char * initial_desig_desc,
- int page_len, int * off, int m_assoc,
- int m_desig_type, int m_code_set);
-
/* These are target port, device server (i.e. target) and lu identifiers */
-static void decode_dev_ids(const char * leadin, unsigned char * buff,
- int len, int do_hex)
+static void
+decode_dev_ids(const char * leadin, unsigned char * buff, int len, int do_hex)
{
int u, j, m, id_len, p_id, c_set, piv, assoc, id_type, i_len;
int off, ci_off, c_id, d_id, naa, vsi;
@@ -1112,8 +1124,8 @@ static void decode_dev_ids(const char * leadin, unsigned char * buff,
/* Transport IDs are initiator port identifiers, typically other than the
initiator port issuing a SCSI command. Code borrowed from sg_persist.c */
-static void decode_transport_id(const char * leadin, unsigned char * ucp,
- int len)
+static void
+decode_transport_id(const char * leadin, unsigned char * ucp, int len)
{
int format_code, proto_id, num, j, k;
uint64_t ull;
@@ -1217,7 +1229,8 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
}
}
-static void decode_x_inq_vpd(unsigned char * buff, int len, int do_hex)
+static void
+decode_x_inq_vpd(unsigned char * buff, int len, int do_hex)
{
if (len < 7) {
fprintf(stderr, "Extended INQUIRY data VPD page length too "
@@ -1239,7 +1252,8 @@ static void decode_x_inq_vpd(unsigned char * buff, int len, int do_hex)
!!(buff[7] & 0x1));
}
-static void decode_softw_inf_id(unsigned char * buff, int len, int do_hex)
+static void
+decode_softw_inf_id(unsigned char * buff, int len, int do_hex)
{
int k;
@@ -1257,7 +1271,8 @@ static void decode_softw_inf_id(unsigned char * buff, int len, int do_hex)
}
}
-static void decode_ata_info_vpd(unsigned char * buff, int len, int do_hex)
+static void
+decode_ata_info_vpd(unsigned char * buff, int len, int do_hex)
{
char b[80];
int is_be, num;
@@ -1315,7 +1330,8 @@ static void decode_ata_info_vpd(unsigned char * buff, int len, int do_hex)
sg_is_big_endian());
}
-static void decode_b0_vpd(unsigned char * buff, int len, int do_hex, int pdt)
+static void
+decode_b0_vpd(unsigned char * buff, int len, int do_hex, int pdt)
{
unsigned int u;
@@ -1356,7 +1372,8 @@ static void decode_b0_vpd(unsigned char * buff, int len, int do_hex, int pdt)
}
}
-static void decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt)
+static void
+decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt)
{
unsigned int u;
@@ -1419,7 +1436,8 @@ static const char * lun_op_arr[] =
"I/O Operations being rejected, SP reboot or NDU in progress",
};
-static void decode_upr_vpd_c0_emc(unsigned char * buff, int len)
+static void
+decode_upr_vpd_c0_emc(unsigned char * buff, int len)
{
int k, ip_mgmt, failover_mode, vpp80, lun_z;
@@ -1495,7 +1513,8 @@ static void decode_upr_vpd_c0_emc(unsigned char * buff, int len)
return;
}
-static void decode_rdac_vpd_c2(unsigned char * buff, int len)
+static void
+decode_rdac_vpd_c2(unsigned char * buff, int len)
{
if (len < 3) {
fprintf(stderr, "Software Version VPD page length too "
@@ -1525,7 +1544,8 @@ static void decode_rdac_vpd_c2(unsigned char * buff, int len)
return;
}
-static void decode_rdac_vpd_c9(unsigned char * buff, int len)
+static void
+decode_rdac_vpd_c9(unsigned char * buff, int len)
{
if (len < 3) {
fprintf(stderr, "Volume Access Control VPD page length too "
@@ -1574,8 +1594,8 @@ static void decode_rdac_vpd_c9(unsigned char * buff, int len)
/* Returns 0 if Unit Serial Number VPD page contents found, else see
sg_ll_inquiry() */
-static int fetch_unit_serial_num(int sg_fd, char * obuff, int obuff_len,
- int verbose)
+static int
+fetch_unit_serial_num(int sg_fd, char * obuff, int obuff_len, int verbose)
{
int sz, len, k, res;
unsigned char b[DEF_ALLOC_LEN];
@@ -1638,8 +1658,8 @@ static const char * ansi_version_arr[] =
"ANSI version: 7",
};
-static const char * get_ansi_version_str(int version, char * buff,
- int buff_len)
+static const char *
+get_ansi_version_str(int version, char * buff, int buff_len)
{
version &= 0x7;
buff[buff_len - 1] = '\0';
@@ -1649,7 +1669,8 @@ static const char * get_ansi_version_str(int version, char * buff,
/* Returns 0 if successful */
-static int process_std_inq(int sg_fd, const struct opts_t * optsp)
+static int
+process_std_inq(int sg_fd, const struct opts_t * optsp)
{
int res, len, rlen, act_len, pqual, peri_type, ansi_version, k, j;
const char * cp;
@@ -1835,7 +1856,8 @@ static int process_std_inq(int sg_fd, const struct opts_t * optsp)
}
/* Returns 0 if successful */
-static int process_cmddt(int sg_fd, const struct opts_t * optsp)
+static int
+process_cmddt(int sg_fd, const struct opts_t * optsp)
{
int k, j, num, len, peri_type, reserved_cmddt, support_num, res;
char op_name[128];
@@ -1946,7 +1968,8 @@ static int process_cmddt(int sg_fd, const struct opts_t * optsp)
}
/* Returns 0 if successful */
-static int process_evpd(int sg_fd, const struct opts_t * optsp)
+static int
+process_evpd(int sg_fd, const struct opts_t * optsp)
{
int res, len, num, k, peri_type, vpd;
const char * cp;
@@ -2015,7 +2038,8 @@ static int process_evpd(int sg_fd, const struct opts_t * optsp)
}
/* Returns 0 if successful */
-static int decode_vpd(int sg_fd, const struct opts_t * optsp)
+static int
+decode_vpd(int sg_fd, const struct opts_t * optsp)
{
int len, pdt;
int res = 0;
@@ -2436,7 +2460,8 @@ static int decode_vpd(int sg_fd, const struct opts_t * optsp)
}
-int main(int argc, char * argv[])
+int
+main(int argc, char * argv[])
{
int sg_fd, num, res, n;
unsigned int u;
@@ -2649,8 +2674,8 @@ struct ata_identify_device {
#define ATA_IDENTIFY_BUFF_SZ sizeof(struct ata_identify_device)
#define HDIO_DRIVE_CMD_OFFSET 4
-static int ata_command_interface(int device, char *data, int * atapi_flag,
- int verbose)
+static int
+ata_command_interface(int device, char *data, int * atapi_flag, int verbose)
{
unsigned char buff[ATA_IDENTIFY_BUFF_SZ + HDIO_DRIVE_CMD_OFFSET];
unsigned short get_ident[256];
@@ -2726,8 +2751,8 @@ static int ata_command_interface(int device, char *data, int * atapi_flag,
}
/* Returns 0 if successful, else errno of error */
-static int try_ata_identify(int ata_fd, int do_hex, int do_raw,
- int verbose)
+static int
+try_ata_identify(int ata_fd, int do_hex, int do_raw, int verbose)
{
struct ata_identify_device ata_ident;
char model[64];
@@ -3085,7 +3110,8 @@ static struct version_descriptor version_descriptor_arr[] = {
static int version_descriptor_arr_sz = (sizeof(version_descriptor_arr) /
sizeof(version_descriptor_arr[0]));
-static const char * find_version_descriptor_str(int value)
+static const char *
+find_version_descriptor_str(int value)
{
int k;
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index 1b25c389..9061e7a7 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2007 Douglas Gilbert.
+ * Copyright (c) 2006-2008 Douglas Gilbert.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -52,12 +52,12 @@
*/
-static char * version_str = "0.25 20071114"; /* spc4r11 + 07-153r1 */
+static char * version_str = "0.26 20080207"; /* spc4r12 */
extern void svpd_enumerate_vendor(void);
extern int svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue,
- int do_hex, int do_raw, int do_long,
- int do_quiet, int verbose);
+ int maxlen, int do_hex, int do_raw,
+ int do_long, int do_quiet, int verbose);
extern const struct svpd_values_name_t *
svpd_find_vendor_by_acron(const char * ap);
@@ -124,16 +124,17 @@ static void decode_transport_id(const char * leadin, unsigned char * ucp,
int len);
static struct option long_options[] = {
- {"enumerate", 0, 0, 'e'},
- {"help", 0, 0, 'h'},
- {"hex", 0, 0, 'H'},
- {"ident", 0, 0, 'i'},
- {"long", 0, 0, 'l'},
- {"page", 1, 0, 'p'},
- {"quiet", 0, 0, 'q'},
- {"raw", 0, 0, 'r'},
- {"verbose", 0, 0, 'v'},
- {"version", 0, 0, 'V'},
+ {"enumerate", no_argument, 0, 'e'},
+ {"help", no_argument, 0, 'h'},
+ {"hex", no_argument, 0, 'H'},
+ {"ident", no_argument, 0, 'i'},
+ {"long", no_argument, 0, 'l'},
+ {"maxlen", required_argument, 0, 'm'},
+ {"page", required_argument, 0, 'p'},
+ {"quiet", no_argument, 0, 'q'},
+ {"raw", no_argument, 0, 'r'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
{0, 0, 0, 0},
};
@@ -184,9 +185,10 @@ usage()
{
fprintf(stderr,
"Usage: sg_vpd [--enumerate] [--help] [--hex] [--ident] "
- "[--long] [--page=PG]\n"
- " [--quiet] [--raw] [--verbose] [--version] "
- "DEVICE\n");
+ "[--long]\n"
+ " [--maxlen=LEN] [--page=PG] [--quiet] [--raw] "
+ "[--verbose]\n"
+ " [--version] DEVICE\n");
fprintf(stderr,
" where:\n"
" --enumerate|-e enumerate known VPD pages names then "
@@ -198,6 +200,9 @@ usage()
" short logical unit designator (equiv: "
"'-qp di_lu')\n"
" --long|-l perform extra decoding\n"
+ " --maxlen=LEN|-m LEN max response length (allocation "
+ "length in cdb)\n"
+ " (def: 0 -> 252 bytes)\n"
" --page=PG|-p PG fetch VPD page where PG is an "
"acronym, or a decimal\n"
" number unless hex indicator "
@@ -1345,10 +1350,12 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt)
/* Returns 0 if successful */
static int
-svpd_unable_to_decode(int sg_fd, int num_vpd, int subvalue, int do_hex,
- int do_raw, int do_long, int do_quiet, int verbose)
+svpd_unable_to_decode(int sg_fd, int num_vpd, int subvalue, int maxlen,
+ int do_hex, int do_raw, int do_long, int do_quiet,
+ int verbose)
{
int len, t, res;
+ int alloc_len = maxlen;
t = do_quiet; /* suppress warning */
if ((! do_hex) && (! do_raw))
@@ -1360,7 +1367,9 @@ svpd_unable_to_decode(int sg_fd, int num_vpd, int subvalue, int do_hex,
else
printf("VPD page code=0x%.2x:\n", num_vpd);
}
- res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, DEF_ALLOC_LEN,
+ if (0 == alloc_len)
+ alloc_len = DEF_ALLOC_LEN;
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len,
1, verbose);
if (0 == res) {
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
@@ -1373,17 +1382,19 @@ svpd_unable_to_decode(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len, 1,
- verbose);
- if (res) {
- fprintf(stderr, "fetching VPD page (2) code=0x%.2x: "
- "failed\n", num_vpd);
- return res;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len, 1,
+ verbose);
+ if (res) {
+ fprintf(stderr, "fetching VPD page (2) code=0x%.2x "
+ " (alloc_len=%d) failed\n", num_vpd, len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, "warning: response length (%d) longer than "
+ "requested (%d)\n", len, maxlen);
+ len = alloc_len;
}
}
if (do_raw)
@@ -1400,23 +1411,28 @@ svpd_unable_to_decode(int sg_fd, int num_vpd, int subvalue, int do_hex,
/* Returns 0 if successful, else see sg_ll_inquiry() */
static int
-svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
- int do_raw, int do_long, int do_quiet, int verbose)
+svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int maxlen,
+ int do_hex, int do_raw, int do_long, int do_quiet,
+ int verbose)
{
int len, pdt, num, k;
char buff[48];
const struct svpd_values_name_t * vnp;
int res = 0;
+ int alloc_len = maxlen;
+ if (0 == alloc_len)
+ alloc_len = (VPD_ATA_INFO == num_vpd) ?
+ VPD_ATA_INFO_LEN : DEF_ALLOC_LEN;
switch(num_vpd) {
case VPD_SUPPORTED_VPDS: /* 0x0 */
if ((! do_raw) && (! do_quiet))
printf("Supported VPD pages VPD page:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_SUPPORTED_VPDS, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = rsp_buff[3] + 4;
- if (VPD_SUPPORTED_VPDS != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1425,6 +1441,21 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching Supported VPD pages "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
+ }
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
else if (do_hex)
@@ -1436,6 +1467,8 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
(rsp_buff[0] & 0xe0) >> 5,
sg_get_pdt_str(pdt, sizeof(buff), buff));
num = rsp_buff[3];
+ if (num > (len - 4))
+ num = (len - 4);
for (k = 0; k < num; ++k) {
vnp = sdp_get_vpd_detail(rsp_buff[4 + k], -1, pdt);
if (vnp)
@@ -1450,11 +1483,11 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_UNIT_SERIAL_NUM: /* 0x80 */
if ((! do_raw) && (! do_quiet))
printf("Unit serial number VPD page:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_UNIT_SERIAL_NUM, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = rsp_buff[3] + 4;
- if (VPD_UNIT_SERIAL_NUM != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1463,6 +1496,21 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching Unit serial number page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
+ }
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
else if (do_hex)
@@ -1488,11 +1536,11 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_DEVICE_ID: /* 0x83 */
if ((! do_raw) && (! do_quiet))
printf("Device Identification VPD page:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_DEVICE_ID, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (VPD_DEVICE_ID != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1501,14 +1549,20 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_DEVICE_ID, rsp_buff, len,
- 1, verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching Device Identification page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -1528,11 +1582,11 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_SOFTW_INF_ID: /* 0x84 */
if ((! do_raw) && (! do_quiet))
printf("Software interface identification VPD page:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_SOFTW_INF_ID, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = rsp_buff[3] + 4;
- if (VPD_SOFTW_INF_ID != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1541,6 +1595,21 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching Software interface id page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
+ }
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
else {
@@ -1557,11 +1626,11 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_MAN_NET_ADDR: /* 0x85 */
if ((! do_raw) && (! do_quiet))
printf("Management network addresses VPD page:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_MAN_NET_ADDR, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (VPD_MAN_NET_ADDR != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1570,14 +1639,21 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_MAN_NET_ADDR, rsp_buff,
- len, 1, verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching Management network "
+ "addresses page (alloc_len=%d) failed\n",
+ len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -1589,11 +1665,11 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_EXT_INQ: /* 0x86 */
if ((! do_raw) && (! do_quiet))
printf("extended INQUIRY data VPD page:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_EXT_INQ, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (VPD_EXT_INQ != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1602,14 +1678,20 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_EXT_INQ, rsp_buff, len,
- 1, verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching Extended INQUIRY data page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -1627,11 +1709,11 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_MODE_PG_POLICY: /* 0x87 */
if ((! do_raw) && (! do_quiet))
printf("Mode page VPD policy:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_MODE_PG_POLICY, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (VPD_MODE_PG_POLICY != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1640,14 +1722,20 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_MODE_PG_POLICY, rsp_buff,
- len, 1, verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching Mode page policy page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -1665,11 +1753,11 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_SCSI_PORTS: /* 0x88 */
if ((! do_raw) && (! do_quiet))
printf("SCSI Ports VPD page:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_SCSI_PORTS, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, maxlen, 1,
+ verbose);
if (0 == res) {
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (VPD_SCSI_PORTS != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1678,14 +1766,20 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_SCSI_PORTS, rsp_buff, len,
- 1, verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching SCSI ports page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -1703,11 +1797,11 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_ATA_INFO: /* 0x89 */
if ((! do_raw) && (3 != do_hex) && (! do_quiet))
printf("ATA information VPD page:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_ATA_INFO, rsp_buff,
- VPD_ATA_INFO_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (VPD_ATA_INFO != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1716,14 +1810,20 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > VPD_ATA_INFO_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_ATA_INFO, rsp_buff, len,
- 1, verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching ATA info page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if ((2 == do_raw) || (3 == do_hex)) /* special for hdparm */
dWordHex((const unsigned short *)(rsp_buff + 60),
@@ -1744,11 +1844,11 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_PROTO_LU: /* 0x90 */
if ((! do_raw) && (! do_quiet))
printf("Protocol-specific logical unit information:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_PROTO_LU, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (VPD_PROTO_LU != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1757,14 +1857,20 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_PROTO_LU, rsp_buff,
- len, 1, verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching Protocol-specific LU page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -1782,11 +1888,11 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_PROTO_PORT: /* 0x91 */
if ((! do_raw) && (! do_quiet))
printf("Protocol-specific port information:\n");
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_PROTO_PORT, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (VPD_PROTO_PORT != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1795,14 +1901,20 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_PROTO_PORT, rsp_buff,
- len, 1, verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching Protocol-specific port page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -1818,8 +1930,8 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
break;
case 0xb0: /* depends on pdt */
- res = sg_ll_inquiry(sg_fd, 0, 1, 0xb0, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
pdt = rsp_buff[0] & 0x1f;
if ((! do_raw) && (! do_quiet)) {
@@ -1840,7 +1952,7 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
}
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (0xb0 != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1849,14 +1961,20 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, 0xb0, rsp_buff,
- len, 1, verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching 0xb0 page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -1873,8 +1991,8 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
printf("VPD page=0xb0\n");
break;
case 0xb1: /* depends on pdt */
- res = sg_ll_inquiry(sg_fd, 0, 1, 0xb1, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
pdt = rsp_buff[0] & 0x1f;
if ((! do_raw) && (! do_quiet)) {
@@ -1899,7 +2017,7 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
}
len = ((rsp_buff[2] << 8) + rsp_buff[3]) + 4;
- if (0xb1 != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably a STANDARD "
"INQUIRY response\n");
if (verbose) {
@@ -1908,14 +2026,20 @@ svpd_decode_standard(int sg_fd, int num_vpd, int subvalue, int do_hex,
}
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, 0xb1, rsp_buff,
- len, 1, verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching 0xb1 page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -1950,6 +2074,7 @@ main(int argc, char * argv[])
int do_hex = 0;
int do_ident = 0;
int do_long = 0;
+ int maxlen = 0;
int do_quiet = 0;
int do_raw = 0;
int do_verbose = 0;
@@ -1960,7 +2085,7 @@ main(int argc, char * argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "ehHilp:qrvV", long_options,
+ c = getopt_long(argc, argv, "ehHilm:p:qrvV", long_options,
&option_index);
if (c == -1)
break;
@@ -1983,6 +2108,14 @@ main(int argc, char * argv[])
case 'l':
++do_long;
break;
+ case 'm':
+ maxlen = sg_get_num(optarg);
+ if ((maxlen < 0) || (maxlen > MX_ALLOC_LEN)) {
+ fprintf(stderr, "argument to '--maxlen' should be %d or "
+ "less\n", MX_ALLOC_LEN);
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ break;
case 'p':
if (page_str) {
fprintf(stderr, "only one '--page=' option permitted\n");
@@ -2087,14 +2220,14 @@ main(int argc, char * argv[])
}
memset(rsp_buff, 0, sizeof(rsp_buff));
- res = svpd_decode_standard(sg_fd, num_vpd, subvalue, do_hex, do_raw,
- do_long, do_quiet, do_verbose);
+ res = svpd_decode_standard(sg_fd, num_vpd, subvalue, maxlen, do_hex,
+ do_raw, do_long, do_quiet, do_verbose);
if (SG_LIB_SYNTAX_ERROR == res) {
- res = svpd_decode_vendor(sg_fd, num_vpd, subvalue, do_hex, do_raw,
- do_long, do_quiet, do_verbose);
+ res = svpd_decode_vendor(sg_fd, num_vpd, subvalue, maxlen, do_hex,
+ do_raw, do_long, do_quiet, do_verbose);
if (SG_LIB_SYNTAX_ERROR == res)
- res = svpd_unable_to_decode(sg_fd, num_vpd, subvalue, do_hex,
- do_raw, do_long, do_quiet,
+ res = svpd_unable_to_decode(sg_fd, num_vpd, subvalue, maxlen,
+ do_hex, do_raw, do_long, do_quiet,
do_verbose);
}
if (SG_LIB_CAT_ABORTED_COMMAND == res)
diff --git a/src/sg_vpd_vendor.c b/src/sg_vpd_vendor.c
index 31845f25..20c179d2 100644
--- a/src/sg_vpd_vendor.c
+++ b/src/sg_vpd_vendor.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006-2007 Douglas Gilbert.
+ * Copyright (c) 2006-2008 Douglas Gilbert.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -74,7 +74,6 @@
#define DEF_ALLOC_LEN 252
#define MX_ALLOC_LEN (0xc000 + 0x80)
-#define VPD_ATA_INFO_LEN 572
/* This structure is a duplicate of one of the same name in sg_vpd.c .
Take care that both have the same fields (and types). */
@@ -90,7 +89,8 @@ struct svpd_values_name_t {
};
-static unsigned char rsp_buff[MX_ALLOC_LEN + 2];
+/* Size of this array must match the array of the same name in sg_vpd.c */
+static unsigned char rsp_buff[MX_ALLOC_LEN + 2];
/* Supported vendor specific VPD pages */
@@ -563,12 +563,14 @@ decode_rdac_vpd_c9(unsigned char * buff, int len)
/* Returns 0 if successful, see sg_ll_inquiry() plus SG_LIB_SYNTAX_ERROR for
unsupported page */
int
-svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue, int do_hex,
- int do_raw, int do_long, int do_quiet, int verbose)
+svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue, int maxlen,
+ int do_hex, int do_raw, int do_long, int do_quiet,
+ int verbose)
{
int len, t, res;
char name[64];
const struct svpd_values_name_t * vnp;
+ int alloc_len = maxlen;
t = do_long; /* suppress warning */
vnp = svpd_get_v_detail(num_vpd, subvalue, -1);
@@ -576,27 +578,35 @@ svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue, int do_hex,
strcpy(name, vnp->name);
else
snprintf(name, sizeof(name) - 1, "Vendor VPD page=0x%x", num_vpd);
+ if (0 == alloc_len)
+ alloc_len = DEF_ALLOC_LEN;
switch(num_vpd) {
- case 0xc0:
+ case VPD_V_UPR_EMC:
if ((! do_raw) && (! do_quiet))
printf("%s VPD Page:\n", name);
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_V_UPR_EMC, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = rsp_buff[3] + 4;
- if (VPD_V_UPR_EMC != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably not "
"supported\n");
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_V_UPR_EMC, rsp_buff, len, 1,
- verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching 0xc0 page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -614,23 +624,29 @@ svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_V_SVER_RDAC:
if ((! do_raw) && (! do_quiet))
printf("%s VPD Page:\n", name);
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_V_SVER_RDAC, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = rsp_buff[3] + 4;
- if (VPD_V_SVER_RDAC != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably not "
"supported\n");
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_V_SVER_RDAC, rsp_buff, len, 1,
- verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching 0xc2 page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -646,23 +662,29 @@ svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_V_FEAT_RDAC:
if ((! do_raw) && (! do_quiet))
printf("%s VPD Page:\n", name);
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_V_FEAT_RDAC, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = rsp_buff[3] + 4;
- if (VPD_V_FEAT_RDAC != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably not "
"supported\n");
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_V_FEAT_RDAC, rsp_buff, len, 1,
- verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching 0xc3 page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -678,23 +700,29 @@ svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_V_SUBS_RDAC:
if ((! do_raw) && (! do_quiet))
printf("%s VPD Page:\n", name);
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_V_SUBS_RDAC, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = rsp_buff[3] + 4;
- if (VPD_V_SUBS_RDAC != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably not "
"supported\n");
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_V_SUBS_RDAC, rsp_buff, len, 1,
- verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching 0xc4 page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -710,23 +738,29 @@ svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_V_EDID_RDAC:
if ((! do_raw) && (! do_quiet))
printf("%s VPD Page:\n", name);
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_V_EDID_RDAC, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = rsp_buff[3] + 4;
- if (VPD_V_EDID_RDAC != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably not "
"supported\n");
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_V_VAC_RDAC, rsp_buff, len, 1,
- verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching 0xc8 page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);
@@ -742,23 +776,29 @@ svpd_decode_vendor(int sg_fd, int num_vpd, int subvalue, int do_hex,
case VPD_V_VAC_RDAC:
if ((! do_raw) && (! do_quiet))
printf("%s VPD Page:\n", name);
- res = sg_ll_inquiry(sg_fd, 0, 1, VPD_V_VAC_RDAC, rsp_buff,
- DEF_ALLOC_LEN, 1, verbose);
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, alloc_len, 1,
+ verbose);
if (0 == res) {
len = rsp_buff[3] + 4;
- if (VPD_V_VAC_RDAC != rsp_buff[1]) {
+ if (num_vpd != rsp_buff[1]) {
fprintf(stderr, "invalid VPD response; probably not "
"supported\n");
return SG_LIB_CAT_MALFORMED;
}
- if (len > MX_ALLOC_LEN) {
- fprintf(stderr, "response length too long: %d > %d\n", len,
- MX_ALLOC_LEN);
- return SG_LIB_CAT_MALFORMED;
- } else if (len > DEF_ALLOC_LEN) {
- if (sg_ll_inquiry(sg_fd, 0, 1, VPD_V_VAC_RDAC, rsp_buff, len, 1,
- verbose))
- return SG_LIB_CAT_OTHER;
+ if (len > alloc_len) {
+ if ((0 == maxlen) && (len < MX_ALLOC_LEN)) {
+ res = sg_ll_inquiry(sg_fd, 0, 1, num_vpd, rsp_buff, len,
+ 1, verbose);
+ if (res) {
+ fprintf(stderr, "fetching 0xc9 page "
+ "(alloc_len=%d) failed\n", len);
+ return res;
+ }
+ } else {
+ fprintf(stderr, ">>> warning: response length (%d) "
+ "longer than requested (%d)\n", len, alloc_len);
+ len = alloc_len;
+ }
}
if (do_raw)
dStrRaw((const char *)rsp_buff, len);