diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2017-11-03 17:25:54 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2017-11-03 17:25:54 +0000 |
commit | 3d464ff0b558af456cd4baa79b609a0940489487 (patch) | |
tree | 34269449e8b110a32dcf76143f415c00d5e16efa /src | |
parent | d0cecdd78328bc0e43786c418e9cb1fde563decf (diff) | |
download | sg3_utils-3d464ff0b558af456cd4baa79b609a0940489487.tar.gz |
sg_opcode: check resid and trim response if necessary; sg_rep_zones: expand --help option information
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@728 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r-- | src/sg_opcodes.c | 48 | ||||
-rw-r--r-- | src/sg_read_buffer.c | 25 | ||||
-rw-r--r-- | src/sg_rep_zones.c | 50 | ||||
-rw-r--r-- | src/sg_sync.c | 12 |
4 files changed, 87 insertions, 48 deletions
diff --git a/src/sg_opcodes.c b/src/sg_opcodes.c index 2d2dc5f5..9b8aa8d7 100644 --- a/src/sg_opcodes.c +++ b/src/sg_opcodes.c @@ -30,7 +30,7 @@ #include "sg_pt.h" -static const char * version_str = "0.52 20171011"; /* spc5r10 */ +static const char * version_str = "0.53 20171102"; /* spc5r14 */ #define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */ @@ -181,7 +181,8 @@ static const char * const rsoc_s = "Report supported operation codes"; static int do_rsoc(int sg_fd, bool rctd, int rep_opts, int rq_opcode, int rq_servact, - void * resp, int mx_resp_len, bool noisy, int verbose) + void * resp, int mx_resp_len, int * act_resp_lenp, bool noisy, + int verbose) { int k, ret, res, sense_cat; unsigned char rsoc_cdb[RSOC_CMD_LEN] = {SG_MAINTENANCE_IN, RSOC_SA, 0, @@ -229,6 +230,8 @@ do_rsoc(int sg_fd, bool rctd, int rep_opts, int rq_opcode, int rq_servact, break; } } else { + if (act_resp_lenp) + *act_resp_lenp = ret; if ((verbose > 2) && (ret > 0)) { pr2serr("%s response:\n", rsoc_s); dStrHexErr((const char *)resp, ret, 1); @@ -244,8 +247,8 @@ static const char * const rstmf_s = "Report supported task management " "functions"; static int -do_rstmf(int sg_fd, bool repd, void * resp, int mx_resp_len, bool noisy, - int verbose) +do_rstmf(int sg_fd, bool repd, void * resp, int mx_resp_len, + int * act_resp_lenp, bool noisy, int verbose) { int k, ret, res, sense_cat; unsigned char rstmf_cdb[RSTMF_CMD_LEN] = {SG_MAINTENANCE_IN, RSTMF_SA, @@ -287,6 +290,8 @@ do_rstmf(int sg_fd, bool repd, void * resp, int mx_resp_len, bool noisy, break; } } else { + if (act_resp_lenp) + *act_resp_lenp = ret; if ((verbose > 2) && (ret > 0)) { pr2serr("%s response:\n", rstmf_s); dStrHexErr((const char *)resp, ret, 1); @@ -650,7 +655,7 @@ list_all_codes(unsigned char * rsoc_buff, int rsoc_len, struct opts_t * op, int sg_fd) { bool sa_v; - int k, j, m, cd_len, serv_act, len, opcode, res; + int k, j, m, cd_len, serv_act, len, act_len, opcode, res; unsigned int timeout; unsigned char * bp; unsigned char ** sort_arr = NULL; @@ -768,9 +773,10 @@ list_all_codes(unsigned char * rsoc_buff, int rsoc_len, struct opts_t * op, memset(b, 0, sizeof(b)); res = do_rsoc(sg_fd, false, (sa_v ? 2 : 1), opcode, serv_act, - b, sizeof(b), 1, op->verbose); + b, sizeof(b), &act_len, true, op->verbose); if (0 == res) { cdb_sz = sg_get_unaligned_be16(b + 2); + cdb_sz = (cdb_sz < act_len) ? cdb_sz : act_len; if ((cdb_sz > 0) && (cdb_sz <= 80)) { if (op->do_compact) printf(" usage: "); @@ -895,7 +901,7 @@ list_one(unsigned char * rsoc_buff, int cd_len, int rep_opts, int main(int argc, char * argv[]) { - int sg_fd, cd_len, res, len; + int sg_fd, cd_len, res, len, act_len, rq_len; int rep_opts = 0; const char * cp; struct opts_t * op; @@ -1019,26 +1025,29 @@ main(int argc, char * argv[]) if (op->opcode >= 0) rep_opts = ((op->servact >= 0) ? 2 : 1); memset(rsoc_buff, 0, sizeof(rsoc_buff)); - if (op->do_taskman) + if (op->do_taskman) { + rq_len = (op->do_repd ? 16 : 4); res = do_rstmf(sg_fd, op->do_repd, rsoc_buff, - (op->do_repd ? 16 : 4), 1, op->verbose); - else - res = do_rsoc(sg_fd, op->do_rctd, rep_opts, op->opcode, - op->servact, rsoc_buff, sizeof(rsoc_buff), 1, - op->verbose); + rq_len, &act_len, true, op->verbose); + } else { + rq_len = sizeof(rsoc_buff); + res = do_rsoc(sg_fd, op->do_rctd, rep_opts, op->opcode, op->servact, + rsoc_buff, rq_len, &act_len, true, op->verbose); + } if (res) { sg_get_category_sense_str(res, sizeof(b), b, op->verbose); pr2serr("%s: %s\n", op_name, b); goto err_out; } + act_len = (rq_len < act_len) ? rq_len : act_len; if (op->do_taskman) { if (op->do_raw) { - dStrRaw((const char *)rsoc_buff, (op->do_repd ? 16 : 4)); + dStrRaw((const char *)rsoc_buff, act_len); goto err_out; } printf("\nTask Management Functions supported by device:\n"); if (op->do_hex) { - dStrHex((const char *)rsoc_buff, (op->do_repd ? 16 : 4), 1); + dStrHex((const char *)rsoc_buff, act_len, 1); goto err_out; } if (rsoc_buff[0] & 0x80) @@ -1088,8 +1097,7 @@ main(int argc, char * argv[]) } } else if (0 == rep_opts) { /* list all supported operation codes */ len = sg_get_unaligned_be32(rsoc_buff + 0) + 4; - if (len > (int)sizeof(rsoc_buff)) - len = sizeof(rsoc_buff); + len = (len < act_len) ? len : act_len; if (op->do_raw) { dStrRaw((const char *)rsoc_buff, len); goto err_out; @@ -1098,12 +1106,12 @@ main(int argc, char * argv[]) dStrHex((const char *)rsoc_buff, len, 1); goto err_out; } - list_all_codes(rsoc_buff, sizeof(rsoc_buff), op, sg_fd); + list_all_codes(rsoc_buff, len, op, sg_fd); } else { /* asked about specific command */ cd_len = sg_get_unaligned_be16(rsoc_buff + 2); len = cd_len + 4; - if (len > (int)sizeof(rsoc_buff)) - len = sizeof(rsoc_buff); + len = (len < act_len) ? len : act_len; + cd_len = (cd_len < act_len) ? cd_len : act_len; if (op->do_raw) { dStrRaw((const char *)rsoc_buff, len); goto err_out; diff --git a/src/sg_read_buffer.c b/src/sg_read_buffer.c index afa945b0..13e1117a 100644 --- a/src/sg_read_buffer.c +++ b/src/sg_read_buffer.c @@ -32,7 +32,7 @@ * device. */ -static const char * version_str = "1.19 20171005"; +static const char * version_str = "1.20 20171103"; #ifndef SG_READ_BUFFER_10_CMD @@ -143,9 +143,9 @@ print_modes(void) /* Invokes a SCSI READ BUFFER(10) command (spc5r02). Return of 0 -> success, * various SG_LIB_CAT_* positive values or -1 -> other errors */ static int -ll_read_buffer_10(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id, - uint32_t rb_offset, void * resp, int mx_resp_len, - int * residp, bool noisy, int verbose) +sg_ll_read_buffer_10(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id, + uint32_t rb_offset, void * resp, int mx_resp_len, + int * residp, bool noisy, int verbose) { int k, ret, res, sense_cat; uint8_t rb10_cb[SG_READ_BUFFER_10_CMDLEN] = @@ -206,9 +206,9 @@ ll_read_buffer_10(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id, /* Invokes a SCSI READ BUFFER(16) command (spc5r02). Return of 0 -> success, * various SG_LIB_CAT_* positive values or -1 -> other errors */ static int -ll_read_buffer_16(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id, - uint64_t rb_offset, void * resp, int mx_resp_len, - int * residp, bool noisy, int verbose) +sg_ll_read_buffer_16(int sg_fd, int rb_mode, int rb_mode_sp, int rb_id, + uint64_t rb_offset, void * resp, int mx_resp_len, + int * residp, bool noisy, int verbose) { int k, ret, res, sense_cat; uint8_t rb16_cb[SG_READ_BUFFER_16_CMDLEN] = @@ -453,17 +453,18 @@ main(int argc, char * argv[]) } if (do_long) - res = ll_read_buffer_16(sg_fd, rb_mode, rb_mode_sp, rb_id, rb_offset, - resp, rb_len, &resid, true, verbose); + res = sg_ll_read_buffer_16(sg_fd, rb_mode, rb_mode_sp, rb_id, + rb_offset, resp, rb_len, &resid, true, + verbose); else if (rb_offset > 0xffffff) { pr2serr("--offset value is too large for READ BUFFER(10), try " "--16\n"); ret = SG_LIB_SYNTAX_ERROR; goto fini; } else - res = ll_read_buffer_10(sg_fd, rb_mode, rb_mode_sp, rb_id, - (uint32_t)rb_offset, resp, rb_len, &resid, - true, verbose); + res = sg_ll_read_buffer_10(sg_fd, rb_mode, rb_mode_sp, rb_id, + (uint32_t)rb_offset, resp, rb_len, &resid, + true, verbose); if (0 != res) { char b[80]; diff --git a/src/sg_rep_zones.c b/src/sg_rep_zones.c index ed074116..3319fc25 100644 --- a/src/sg_rep_zones.c +++ b/src/sg_rep_zones.c @@ -34,7 +34,7 @@ * and decodes the response. Based on zbc-r02.pdf */ -static const char * version_str = "1.11 20171006"; +static const char * version_str = "1.12 20171103"; #define MAX_RZONES_BUFF_LEN (1024 * 1024) #define DEF_RZONES_BUFF_LEN (1024 * 8) @@ -63,22 +63,27 @@ static struct option long_options[] = { static void -usage() +usage(int h) { + if (h > 1) goto h_twoormore; pr2serr("Usage: " "sg_rep_zones [--help] [--hex] [--maxlen=LEN] [--partial]\n" " [--raw] [--readonly] [--report=OPT] " "[--start=LBA]\n" " [--verbose] [--version] DEVICE\n"); pr2serr(" where:\n" - " --help|-h print out usage message\n" + " --help|-h print out usage message, use twice for " + "more help\n" " --hex|-H output response in hexadecimal; used " "twice\n" " shows decoded values in hex\n" " --maxlen=LEN|-m LEN max response length (allocation " "length in cdb)\n" " (def: 0 -> 8192 bytes)\n" - " --partial|-p sets PARTIAL bit in cdb\n" + " --partial|-p sets PARTIAL bit in cdb (def: 0 -> " + "zone list\n" + " length not altered by allocation length " + "in cdb)\n" " --raw|-r output response in binary\n" " --readonly|-R open DEVICE read-only (def: read-write)\n" " --report=OPT|-o OP reporting options (def: 0: all " @@ -87,7 +92,27 @@ usage() " need not be a zone starting LBA\n" " --verbose|-v increase verbosity\n" " --version|-V print version string and exit\n\n" - "Performs a SCSI REPORT ZONES command.\n"); + "Sends a SCSI REPORT ZONES command and decodes the response. " + "Give\nhelp option twice (e.g. '-hh') to see reporting options " + "enumerated.\n"); + return; +h_twoormore: + pr2serr("Reporting options:\n" + " 0x0 list all zones\n" + " 0x1 list zones with a zone condition of EMPTY\n" + " 0x2 list zones with a zone condition of IMPLICITLY " + "OPENED\n" + " 0x3 list zones with a zone condition of EXPLICITLY " + "OPENED\n" + " 0x4 list zones with a zone condition of CLOSED\n" + " 0x5 list zones with a zone condition of FULL\n" + " 0x6 list zones with a zone condition of READ ONLY\n" + " 0x7 list zones with a zone condition of OFFLINE\n" + " 0x10 list zones with RWP Recommended set to true\n" + " 0x11 list zones with Non-sequential write resources " + "active set to true\n" + " 0x3f list zones with a zone condition of NOT WRITE " + "POINTER\n"); } /* Invokes a SCSI REPORT ZONES command (ZBC). Return of 0 -> success, @@ -251,6 +276,7 @@ main(int argc, char * argv[]) bool do_raw = false; bool o_readonly = false; int sg_fd, k, res, c, zl_len, len, zones, resid, rlen, zt, zc, same; + int do_help = 0; int do_hex = 0; int maxlen = 0; int reporting_opt = 0; @@ -274,8 +300,8 @@ main(int argc, char * argv[]) switch (c) { case 'h': case '?': - usage(); - return 0; + ++do_help; + break; case 'H': ++do_hex; break; @@ -320,7 +346,7 @@ main(int argc, char * argv[]) return 0; default: pr2serr("unrecognised option code 0x%x ??\n", c); - usage(); + usage(1); return SG_LIB_SYNTAX_ERROR; } } @@ -332,14 +358,18 @@ main(int argc, char * argv[]) if (optind < argc) { for (; optind < argc; ++optind) pr2serr("Unexpected extra argument: %s\n", argv[optind]); - usage(); + usage(1); return SG_LIB_SYNTAX_ERROR; } } + if (do_help) { + usage(do_help); + return 0; + } if (NULL == device_name) { pr2serr("missing device name!\n"); - usage(); + usage(1); return SG_LIB_SYNTAX_ERROR; } diff --git a/src/sg_sync.c b/src/sg_sync.c index f0be178a..30b12eb6 100644 --- a/src/sg_sync.c +++ b/src/sg_sync.c @@ -29,7 +29,7 @@ * (e.g. disks). */ -static const char * version_str = "1.17 20171005"; +static const char * version_str = "1.18 20171103"; #define SYNCHRONIZE_CACHE16_CMD 0x91 #define SYNCHRONIZE_CACHE16_CMDLEN 16 @@ -85,9 +85,9 @@ static void usage() } static int -ll_sync_cache_16(int sg_fd, bool sync_nv, bool immed, int group, - uint64_t lba, unsigned int num_lb, int to_secs, - bool noisy, int verbose) +sg_ll_sync_cache_16(int sg_fd, bool sync_nv, bool immed, int group, + uint64_t lba, unsigned int num_lb, int to_secs, + bool noisy, int verbose) { int res, ret, k, sense_cat; unsigned char sc_cdb[SYNCHRONIZE_CACHE16_CMDLEN] = @@ -245,8 +245,8 @@ int main(int argc, char * argv[]) } if (do_16) - res = ll_sync_cache_16(sg_fd, sync_nv, immed, group, lba, num_lb, - to_secs, true, verbose); + res = sg_ll_sync_cache_16(sg_fd, sync_nv, immed, group, lba, num_lb, + to_secs, true, verbose); else res = sg_ll_sync_cache_10(sg_fd, sync_nv, immed, group, (unsigned int)lba, num_lb, true, verbose); |