Search
j0ke.net Open Build Service
>
Projects
>
GFS
>
scsi
> sg3_utils-inq-add-len-option
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File sg3_utils-inq-add-len-option of Package scsi
Index: sg3_utils-1.19/sg_inq.c =================================================================== --- sg3_utils-1.19.orig/sg_inq.c +++ sg3_utils-1.19/sg_inq.c @@ -111,7 +111,7 @@ static void usage() "Usage: sg_inq [-a] [-A] [-b] [-c] [-cl] [-d] [-e] [-h] [-H] " "[-i] [-m] [-M]\n" " [-o=<opcode_page>] [-p=<vpd_page>] [-P] [-r] " - "[-s] [-v]\n" + "[-s] [-v] [-l=<len>]\n" " [-V] [-x] [-36] [-?] <device>\n" " where -a decode ATA information VPD page (0x89)\n" " -A treat <device> as (directly attached) ATA device\n"); @@ -141,6 +141,7 @@ static void usage() " -p=<vpd_page> vpd page code in hex (def: 0)\n" " -P decode Unit Path Report VPD page (0xc0) (EMC)\n" " -r output raw binary data ('-rr': output for hdparm)\n" + " -l=<len> requested response length\n" " -s decode SCSI Ports VPD page (0x88)\n" " -v verbose (output cdb and, if non-zero, resid)\n" " -V output version string\n" @@ -1118,18 +1119,19 @@ static const char * get_ansi_version_str /* Returns 0 if successful */ -static int process_std_inq(int sg_fd, const char * file_name, int do_36, +static int process_std_inq(int sg_fd, const char * file_name, int resp_len, int do_vdescriptors, int do_hex, int do_raw, int do_verbose) { - int res, len, act_len, pqual, peri_type, ansi_version, ret, k, j; + int res, len, rlen, act_len, pqual, peri_type, ansi_version, ret, k, j; const char * cp; int vdesc_arr[8]; char buff[48]; memset(vdesc_arr, 0, sizeof(vdesc_arr)); + rlen = (resp_len > 0)? resp_len : SAFE_STD_INQ_RESP_LEN; res = sg_ll_inquiry(sg_fd, 0, 0, 0, rsp_buff, - SAFE_STD_INQ_RESP_LEN, 0, do_verbose); + rlen, 0, do_verbose); if (0 == res) { pqual = (rsp_buff[0] & 0xe0) >> 5; if (! do_raw) { @@ -1148,8 +1150,10 @@ static int process_std_inq(int sg_fd, co len = rsp_buff[4] + 5; ansi_version = rsp_buff[2] & 0x7; peri_type = rsp_buff[0] & 0x1f; - if ((len > SAFE_STD_INQ_RESP_LEN) && (len < 256) && (! do_36)) { - if (sg_ll_inquiry(sg_fd, 0, 0, 0, rsp_buff, len, 1, do_verbose)) { + if ((len > SAFE_STD_INQ_RESP_LEN) && (len < 256) && (0 == resp_len)) { + rlen = len; + memset(rsp_buff, 0, rlen); + if (sg_ll_inquiry(sg_fd, 0, 0, 0, rsp_buff, rlen, 1, do_verbose)) { fprintf(stderr, "second INQUIRY (%d byte) failed\n", len); return 1; } @@ -1160,16 +1164,14 @@ static int process_std_inq(int sg_fd, co ret = 2; } } - if (do_36) { - act_len = len; - len = SAFE_STD_INQ_RESP_LEN; - } + if (resp_len > 0) + act_len = rlen; else - act_len = len; + act_len = (rlen < len) ? rlen : len; if (do_hex) - dStrHex((const char *)rsp_buff, len, 0); + dStrHex((const char *)rsp_buff, act_len, 0); else if (do_raw) - dStrRaw((const char *)rsp_buff, len); + dStrRaw((const char *)rsp_buff, act_len); else { printf(" PQual=%d Device_type=%d RMB=%d version=0x%02x ", pqual, peri_type, !!(rsp_buff[1] & 0x80), @@ -1197,38 +1199,38 @@ static int process_std_inq(int sg_fd, co !!(rsp_buff[7] & 0x20), !!(rsp_buff[7] & 0x10), !!(rsp_buff[7] & 0x08), !!(rsp_buff[7] & 0x04)); printf("CmdQue=%d\n", !!(rsp_buff[7] & 0x02)); - if (len > 56) + if (act_len > 56) printf(" Clocking=0x%x QAS=%d IUS=%d\n", (rsp_buff[56] & 0x0c) >> 2, !!(rsp_buff[56] & 0x2), !!(rsp_buff[56] & 0x1)); - if (act_len == len) + if (act_len >= len) printf(" length=%d (0x%x)", len, len); else - printf(" length=%d (0x%x), but only read 36 bytes", - len, len); + printf(" length=%d (0x%x), but only fetched %d bytes", + len, len, act_len); if ((ansi_version >= 2) && (len < SAFE_STD_INQ_RESP_LEN)) printf(" [for SCSI>=2, len>=36 is expected]"); cp = sg_get_pdt_str(peri_type, sizeof(buff), buff); if (strlen(cp) > 0) printf(" Peripheral device type: %s\n", cp); - if (len <= 8) + if (act_len <= 8) printf(" Inquiry response length=%d, no vendor, " - "product or revision data\n", len); + "product or revision data\n", act_len); else { - if (len < SAFE_STD_INQ_RESP_LEN) - rsp_buff[len] = '\0'; + if (act_len < SAFE_STD_INQ_RESP_LEN) + rsp_buff[act_len] = '\0'; memcpy(xtra_buff, &rsp_buff[8], 8); xtra_buff[8] = '\0'; printf(" Vendor identification: %s\n", xtra_buff); - if (len <= 16) + if (act_len <= 16) printf(" Product identification: <none>\n"); else { memcpy(xtra_buff, &rsp_buff[16], 16); xtra_buff[16] = '\0'; printf(" Product identification: %s\n", xtra_buff); } - if (len <= 32) + if (act_len <= 32) printf(" Product revision level: <none>\n"); else { memcpy(xtra_buff, &rsp_buff[32], 4); @@ -1236,17 +1238,19 @@ static int process_std_inq(int sg_fd, co printf(" Product revision level: %s\n", xtra_buff); } if (do_vdescriptors) { - for (j = 0, k = 58; ((j < 8) && ((k + 1) < len)); + for (j = 0, k = 58; ((j < 8) && ((k + 1) < act_len)); k +=2, ++j) vdesc_arr[j] = ((rsp_buff[k] << 8) + rsp_buff[k + 1]); } } } - if (! (do_raw || do_hex || do_36)) { - if (0 == fetch_unit_serial_num(sg_fd, xtra_buff, - sizeof(xtra_buff), do_verbose)) - printf(" Unit serial number: %s\n", xtra_buff); + if (! (do_raw || do_hex )) { + if (0 == resp_len) { + if (0 == fetch_unit_serial_num(sg_fd, xtra_buff, + sizeof(xtra_buff), do_verbose)) + printf(" Unit serial number: %s\n", xtra_buff); + } if (do_vdescriptors) { if (0 == vdesc_arr[0]) printf("\n No version descriptors available\n"); @@ -1279,8 +1283,8 @@ static int process_std_inq(int sg_fd, co fprintf(stderr, "SCSI INQUIRY failed on %s\n", file_name); return 1; #endif - } else { /* SCSI device not supporting 36 byte INQUIRY?? */ - printf("36 byte INQUIRY failed\n"); + } else { + printf("INQUIRY failed requesting %d byte response\n", rlen); return 1; } return 0; @@ -1830,10 +1834,10 @@ int main(int argc, char * argv[]) int do_cmdlst = 0; int do_hex = 0; int do_raw = 0; - int do_36 = 0; int do_vdescriptors = 0; int do_verbose = 0; int num_pages = 0; + int resp_len = 0; int ret = 0; @@ -1847,7 +1851,7 @@ int main(int argc, char * argv[]) switch (*cp) { case '3': if ('6' == *(cp + 1)) { - do_36 = 1; + resp_len = 36; --plen; ++cp; } else @@ -1956,6 +1960,13 @@ int main(int argc, char * argv[]) num_opcode_given = 1; p_switch_given = 1; ++num_pages; + } else if (0 == strncmp("l=", cp, 2)) { + num = sscanf(cp + 2, "%d", &resp_len); + if ((1 != num) || (resp_len < 0) || (resp_len > 65532)) { + fprintf(stderr, "Bad number after '-l' switch\n"); + usage(); + return 1; + } } else if (jmp_out) { fprintf(stderr, "Unrecognized option: %s\n", cp); usage(); @@ -1991,7 +2002,7 @@ int main(int argc, char * argv[]) num_opcode_given = 0; else { do_vdescriptors = 1; - if (do_36) { + if (resp_len == 36) { fprintf(stderr, "version descriptors need > 36 byte " "INQUIRY\n"); usage(); @@ -2048,7 +2059,7 @@ int main(int argc, char * argv[]) ret = 1; if ((! do_cmddt) && (! do_evpd)) { /* So it's a Standard INQUIRY, try ATA IDENTIFY if that fails */ - if (process_std_inq(sg_fd, file_name, do_36, do_vdescriptors, + if (process_std_inq(sg_fd, file_name, resp_len, do_vdescriptors, do_hex, do_raw, do_verbose)) goto err_out; } else if (do_cmddt) { Index: sg3_utils-1.19/sg_inq.8 =================================================================== --- sg3_utils-1.19.orig/sg_inq.8 +++ sg3_utils-1.19/sg_inq.8 @@ -6,7 +6,7 @@ ATA IDENTIFY (PACKET) DEVICE command .B sg_inq [\fI-a\fR] [\fI-A\fR] [\fI-b\fR] [\fI-c\fR] [\fI-cl\fR] [\fI-d\fR] [\fI-e\fR] [\fI-h\fR] [\fI-H\fR] [\fI-i\fR] [\fI-m\fR] [\fI-m\fR] -[\fI-o=<opcode_page>\fR] [\fI-p=<vpd_page>\fR] [\fI-P\fR] [\fI-r\fR] +[\fI-o=<opcode_page>\fR] [\fI-p=<vpd_page>\fR] [\fI-l=<len>\fR] [\fI-P\fR] [\fI-r\fR] [\fI-s\fR] [\fI-v\fR] [\fI-V\fR] [\fI-x\fR] [\fI-36\fR] [\fI-?\fR] \fI<device>\fR .SH DESCRIPTION @@ -116,6 +116,15 @@ is output in hex. To see the whole VPD 0 use '-p=83 -h'. Since SPC-3, support for the device identification VPD page is mandatory. .TP +-l=<len> +the number \fIlen\fR is the "allocation length" field in the INQUIRY cdb. +This is the (maximum) length of the response to be sent by the device. +The default value of \fIlen\fR is 0 which is interpreted as: first request +is for 36 bytes and if necessary execute another INQUIRY if the "additional +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 -m decodes the Management network addresses Vital Product Data (VPD) page [0x85]. This page is made up of several "network service descriptors". @@ -187,6 +196,7 @@ using '-p=86 -h'. only requests 36 bytes of response data for an INQUIRY. Furthermore even if the device indicates in its response it can supply more data, a second (longer) INQUIRY is not performed. This is a paranoid setting. +Equivalent to '\-\-len=36' in the main description. .TP -? output usage message and exit. Ignore all other parameters.