diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2018-04-15 01:35:16 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2018-04-15 01:35:16 +0000 |
commit | f65566c3934a9e22335dee20401cc1cc50865d56 (patch) | |
tree | 57d66e8a63006f4d6f4d9bfc589b83159e5f392e /src | |
parent | 040da21637161c189d1d1ca6505cdc1a3794126f (diff) | |
download | sg3_utils-f65566c3934a9e22335dee20401cc1cc50865d56.tar.gz |
sg_wr_mode: add --rtd option for RTD bit; sg_lib: add sg_ll_mode_select6_v2() and sg_ll_mode_select10_v2() for RTD bit
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@768 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r-- | src/sg_modes.c | 33 | ||||
-rw-r--r-- | src/sg_vpd.c | 6 | ||||
-rw-r--r-- | src/sg_wr_mode.c | 92 |
3 files changed, 86 insertions, 45 deletions
diff --git a/src/sg_modes.c b/src/sg_modes.c index 412d6f96..0a839526 100644 --- a/src/sg_modes.c +++ b/src/sg_modes.c @@ -30,7 +30,7 @@ #include "sg_unaligned.h" #include "sg_pr2serr.h" -static const char * version_str = "1.59 20180329"; +static const char * version_str = "1.60 20180414"; #define DEF_ALLOC_LEN (1024 * 4) #define DEF_6_ALLOC_LEN 252 @@ -85,7 +85,7 @@ struct opts_t { int do_hex; int maxlen; int do_raw; - int do_verbose; + int verbose; int page_control; int pg_code; int subpg_code; @@ -300,7 +300,7 @@ new_parse_cmd_line(struct opts_t * op, int argc, char * argv[]) op->do_six = true; break; case 'v': - ++op->do_verbose; + ++op->verbose; break; case 'V': op->do_version = true; @@ -390,7 +390,7 @@ old_parse_cmd_line(struct opts_t * op, int argc, char * argv[]) op->do_raw += 2; break; case 'v': - ++op->do_verbose; + ++op->verbose; break; case 'V': op->do_version = true; @@ -898,7 +898,7 @@ examine_pages(int sg_fd, int inq_pdt, bool encserv, bool mchngr, resid = 0; if (op->do_six) { res = sg_ll_mode_sense6(sg_fd, 0, 0, k, 0, rbuf, mresp_len, - true, op->do_verbose); + true, op->verbose); if (SG_LIB_CAT_INVALID_OP == res) { pr2serr(">>>>>> try again without the '-6' switch for a 10 " "byte MODE SENSE command\n"); @@ -909,7 +909,7 @@ examine_pages(int sg_fd, int inq_pdt, bool encserv, bool mchngr, } } else { res = sg_ll_mode_sense10_v2(sg_fd, 0, 0, 0, k, 0, rbuf, mresp_len, - 0, &resid, true, op->do_verbose); + 0, &resid, true, op->verbose); if (SG_LIB_CAT_INVALID_OP == res) { pr2serr(">>>>>> try again with a '-6' switch for a 6 byte " "MODE SENSE command\n"); @@ -951,10 +951,10 @@ examine_pages(int sg_fd, int inq_pdt, bool encserv, bool mchngr, printf(" [0x%x]\n", k); if (op->do_hex) hex2stdout(rbuf, len, 1); - } else if (op->do_verbose) { + } else if (op->verbose) { char b[80]; - sg_get_category_sense_str(res, sizeof(b), b, op->do_verbose - 1); + sg_get_category_sense_str(res, sizeof(b), b, op->verbose - 1); pr2serr("MODE SENSE (%s) failed: %s\n", (op->do_six ? "6" : "10"), b); } @@ -1069,16 +1069,16 @@ main(int argc, char * argv[]) } if ((sg_fd = sg_cmds_open_device(op->device_name, ! op->o_readwrite, - op->do_verbose)) < 0) { + op->verbose)) < 0) { pr2serr("error opening file: %s: %s\n", op->device_name, safe_strerror(-sg_fd)); ret = sg_convert_errno(-sg_fd); goto fini; } - if (sg_simple_inquiry(sg_fd, &inq_out, true, op->do_verbose)) { + if ((res = sg_simple_inquiry(sg_fd, &inq_out, true, op->verbose))) { pr2serr("%s doesn't respond to a SCSI INQUIRY\n", op->device_name); - ret = SG_LIB_CAT_OTHER; + ret = (res > 0) ? res : sg_convert_errno(-res); goto fini; } inq_pdt = inq_out.peripheral_type; @@ -1123,7 +1123,7 @@ main(int argc, char * argv[]) if (op->do_six) { res = sg_ll_mode_sense6(sg_fd, op->do_dbd, op->page_control, op->pg_code, op->subpg_code, rsp_buff, - rsp_buff_sz, true, op->do_verbose); + rsp_buff_sz, true, op->verbose); if (SG_LIB_CAT_INVALID_OP == res) pr2serr(">>>>>> try again without the '-6' switch for a 10 byte " "MODE SENSE command\n"); @@ -1131,7 +1131,7 @@ main(int argc, char * argv[]) res = sg_ll_mode_sense10_v2(sg_fd, op->do_llbaa, op->do_dbd, op->page_control, op->pg_code, op->subpg_code, rsp_buff, rsp_buff_sz, - 0, &resid, true, op->do_verbose); + 0, &resid, true, op->verbose); if (SG_LIB_CAT_INVALID_OP == res) pr2serr(">>>>>> try again with a '-6' switch for a 6 byte MODE " "SENSE command\n"); @@ -1147,7 +1147,7 @@ main(int argc, char * argv[]) pr2serr("invalid field in cdb (perhaps page 0x%x not " "supported)\n", op->pg_code); } else if (res) { - sg_get_category_sense_str(res, sizeof(b), b, op->do_verbose); + sg_get_category_sense_str(res, sizeof(b), b, op->verbose); pr2serr("%s\n", b); } ret = res; @@ -1364,5 +1364,10 @@ fini: sg_cmds_close_device(sg_fd); if (free_rsp_buff) free(free_rsp_buff); + if (0 == op->verbose) { + if (! sg_if_can2stderr("sg_modes failed: ", ret)) + pr2serr("Some error occurred, try again with '-v' or '-vv' for " + "more information\n"); + } return (ret >= 0) ? ret : SG_LIB_CAT_OTHER; } diff --git a/src/sg_vpd.c b/src/sg_vpd.c index 2a230333..1aad48df 100644 --- a/src/sg_vpd.c +++ b/src/sg_vpd.c @@ -38,7 +38,7 @@ */ -static const char * version_str = "1.43 20180405"; /* spc5r19 + sbc4r15 */ +static const char * version_str = "1.43 20180410"; /* spc5r19 + sbc4r15 */ /* standard VPD pages, in ascending page number order */ #define VPD_SUPPORTED_VPDS 0x0 @@ -3493,7 +3493,7 @@ svpd_decode_all(int sg_fd, struct opts_t * op) if (op->vpd_pn > 0) max_pn = op->vpd_pn; - if (sg_fd >= 0) { + if (sg_fd >= 0) { /* have valid open file descriptor (handle) */ res = vpd_fetch_page(sg_fd, rp, VPD_SUPPORTED_VPDS, op->maxlen, op->do_quiet, op->verbose, &rlen); if (res) { @@ -3522,6 +3522,8 @@ svpd_decode_all(int sg_fd, struct opts_t * op) if (pn > max_pn) continue; op->vpd_pn = pn; + if (k > 0) + printf("\n"); if (op->do_long) printf("[0x%x] ", pn); diff --git a/src/sg_wr_mode.c b/src/sg_wr_mode.c index a5d35461..c6ebf13a 100644 --- a/src/sg_wr_mode.c +++ b/src/sg_wr_mode.c @@ -30,7 +30,7 @@ * mode page on the given device. */ -static const char * version_str = "1.23 20180329"; +static const char * version_str = "1.24 20180414"; #define ME "sg_wr_mode: " @@ -48,7 +48,9 @@ static struct option long_options[] = { {"len", required_argument, 0, 'l'}, {"mask", required_argument, 0, 'm'}, {"page", required_argument, 0, 'p'}, + {"rtd", no_argument, 0, 'R'}, {"save", no_argument, 0, 's'}, + {"six", no_argument, 0, '6'}, {"verbose", no_argument, 0, 'v'}, {"version", no_argument, 0, 'V'}, {0, 0, 0, 0}, @@ -60,7 +62,9 @@ static void usage() "[--help]\n" " [--len=10|6] [--mask=M,M...] " "[--page=PG_H[,SPG_H]]\n" - " [--save] [--verbose] [--version] DEVICE\n" + " [--rtd] [--save] [--six] [--verbose] " + "[--version]\n" + " DEVICE\n" " where:\n" " --contents=H,H... | -c H,H... comma separated string " "of hex numbers\n" @@ -83,9 +87,13 @@ static void usage() " --page=PG_H,SPG_H | -p PG_H,SPG_H page and subpage code " "to be\n" " written (in hex)\n" + " --rtd | -R set RTD bit (revert to defaults) in " + "cdb\n" " --save | -s set 'save page' (SP) bit; default " "don't so\n" " only 'current' values changed\n" + " --six | -6 do SCSI MODE SENSE/SELECT(6) " + "commands\n" " --verbose | -v increase verbosity\n" " --version | -V print version string and exit\n\n" "writes given mode page with SCSI MODE SELECT (10 or 6) " @@ -309,7 +317,8 @@ int main(int argc, char * argv[]) bool force = false; bool got_contents = false; bool got_mask = false; - bool mode_6 = false; + bool mode_6 = false; /* so default is mode_10 */ + bool rtd = false; /* added in spc5r11 */ bool save = false; int sg_fd, res, c, num, alloc_len, off, pdt; int k, md_len, hdr_len, bd_len, mask_in_len; @@ -331,12 +340,15 @@ int main(int argc, char * argv[]) while (1) { int option_index = 0; - c = getopt_long(argc, argv, "c:dfhl:m:p:svV", long_options, + c = getopt_long(argc, argv, "6c:dfhl:m:p:RsvV", long_options, &option_index); if (c == -1) break; switch (c) { + case '6': + mode_6 = true; + break; case 'c': memset(read_in, 0, sizeof(read_in)); if (0 != build_mode_page(optarg, read_in, &read_in_len, @@ -397,6 +409,9 @@ int main(int argc, char * argv[]) return SG_LIB_SYNTAX_ERROR; } break; + case 'R': + rtd = true; + break; case 's': save = true; break; @@ -425,17 +440,17 @@ int main(int argc, char * argv[]) } } if (NULL == device_name) { - pr2serr("missing device name!\n"); + pr2serr("missing device name!\n\n"); usage(); return SG_LIB_SYNTAX_ERROR; } - if (pg_code < 0) { - pr2serr("need page code (see '--page=')\n"); + if ((pg_code < 0) && (! rtd)) { + pr2serr("need page code (see '--page=')\n\n"); usage(); return SG_LIB_SYNTAX_ERROR; } if (got_mask && force) { - pr2serr("cannot use both '--force' and '--mask'\n"); + pr2serr("cannot use both '--force' and '--mask'\n\n"); usage(); return SG_LIB_SYNTAX_ERROR; } @@ -445,6 +460,9 @@ int main(int argc, char * argv[]) pr2serr(ME "open error: %s: %s\n", device_name, safe_strerror(-sg_fd)); return SG_LIB_FILE_ERROR; } + if (rtd) + goto revert_to_defaults; + if (0 == sg_simple_inquiry(sg_fd, &inq_data, false, verbose)) pdt = inq_data.peripheral_type; else @@ -471,23 +489,23 @@ int main(int argc, char * argv[]) sg_get_category_sense_str(res, sizeof(b), b, verbose); pr2serr("%s%s\n", errStr, b); } - goto err_out; + goto fini; } off = sg_mode_page_offset(ref_md, alloc_len, mode_6, ebuff, EBUFF_SZ); if (off < 0) { pr2serr("%s%s\n", errStr, ebuff); - goto err_out; + goto fini; } md_len = sg_msense_calc_length(ref_md, alloc_len, mode_6, &bd_len); if (md_len < 0) { pr2serr("%ssg_msense_calc_length() failed\n", errStr); - goto err_out; + goto fini; } hdr_len = mode_6 ? 4 : 8; if (got_contents) { if (read_in_len < 2) { pr2serr("contents length=%d too short\n", read_in_len); - goto err_out; + goto fini; } ref_md[0] = 0; /* mode data length reserved for mode select */ if (! mode_6) @@ -497,7 +515,7 @@ int main(int argc, char * argv[]) if (md_len > alloc_len) { pr2serr("mode data length=%d exceeds allocation length=%d\n", md_len, alloc_len); - goto err_out; + goto fini; } if (got_mask) { for (k = 0; k < (md_len - off); ++k) { @@ -514,45 +532,42 @@ int main(int argc, char * argv[]) if ((! (ref_md[off] & 0x80)) && save) { pr2serr("PS bit in existing mode page indicates that it is " "not saveable\n but '--save' option given\n"); - goto err_out; + goto fini; } read_in[0] &= 0x7f; /* mask out PS bit, reserved in mode select */ if ((md_len - off) != read_in_len) { pr2serr("contents length=%d but reference mode page " "length=%d\n", read_in_len, md_len - off); - goto err_out; + goto fini; } if (pg_code != (read_in[0] & 0x3f)) { pr2serr("contents page_code=0x%x but reference " "page_code=0x%x\n", (read_in[0] & 0x3f), pg_code); - goto err_out; + goto fini; } if ((read_in[0] & 0x40) != (ref_md[off] & 0x40)) { pr2serr("contents flags subpage but reference page does not " "(or vice versa)\n"); - goto err_out; + goto fini; } if ((read_in[0] & 0x40) && (read_in[1] != sub_pg_code)) { pr2serr("contents subpage_code=0x%x but reference " "sub_page_code=0x%x\n", read_in[1], sub_pg_code); - goto err_out; + goto fini; } } else md_len = off + read_in_len; /* force length */ memcpy(ref_md + off, read_in, read_in_len); if (mode_6) - res = sg_ll_mode_select6(sg_fd, true /* PF */, save, ref_md, - md_len, true, verbose); + res = sg_ll_mode_select6_v2(sg_fd, true /* PF */, rtd, save, + ref_md, md_len, true, verbose); else - res = sg_ll_mode_select10(sg_fd, true /* PF */, save, ref_md, - md_len, true, verbose); + res = sg_ll_mode_select10_v2(sg_fd, true /* PF */, rtd, save, + ref_md, md_len, true, verbose); ret = res; - if (res) { - sg_get_category_sense_str(res, sizeof(b), b, verbose); - pr2serr("MODE SELECT (%d): %s\n", (mode_6 ? 6 : 10), b); - goto err_out; - } + if (res) + goto fini; } else { printf(">>> No contents given, so show current mode page data:\n"); printf(" header:\n"); @@ -565,12 +580,31 @@ int main(int argc, char * argv[]) printf(" mode page:\n"); hex2stdout(ref_md + off, md_len - off, -1); } -err_out: + ret = 0; + goto fini; + +revert_to_defaults: + if (verbose) + pr2serr("Doing MODE SELECT(%d) with revert to defaults (RTD) set " + "and SP=%d\n", mode_6 ? 6 : 10, !! save); + if (mode_6) + res = sg_ll_mode_select6_v2(sg_fd, false /* PF */, true /* rtd */, + save, NULL, 0, true, verbose); + else + res = sg_ll_mode_select10_v2(sg_fd, false /* PF */, true /* rtd */, + save, NULL, 0, true, verbose); + ret = res; +fini: res = sg_cmds_close_device(sg_fd); if (res < 0) { pr2serr("close error: %s\n", safe_strerror(-res)); if (0 == ret) - return SG_LIB_FILE_ERROR; + ret = SG_LIB_FILE_ERROR; + } + if (0 == verbose) { + if (! sg_if_can2stderr("sg_wr_mode failed: ", ret)) + pr2serr("Some error occurred, try again with '-v' or '-vv' for " + "more information\n"); } return (ret >= 0) ? ret : SG_LIB_CAT_OTHER; } |