aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2017-11-03 17:25:54 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2017-11-03 17:25:54 +0000
commit3d464ff0b558af456cd4baa79b609a0940489487 (patch)
tree34269449e8b110a32dcf76143f415c00d5e16efa /src
parentd0cecdd78328bc0e43786c418e9cb1fde563decf (diff)
downloadsg3_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.c48
-rw-r--r--src/sg_read_buffer.c25
-rw-r--r--src/sg_rep_zones.c50
-rw-r--r--src/sg_sync.c12
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);