aboutsummaryrefslogtreecommitdiff
path: root/src/sg_zone.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2018-05-07 05:28:08 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2018-05-07 05:28:08 +0000
commit5a4b80a31b1caeb62fdab8d732582d898b3da9e0 (patch)
treeda413dd462b4945d62a0741ef55edd2733fe6755 /src/sg_zone.c
parenta59b767b38f08c0dafc011a58e8791aa06d4feb0 (diff)
downloadsg3_utils-5a4b80a31b1caeb62fdab8d732582d898b3da9e0.tar.gz
sg_zone: add --sequentialize, --count=ZC options; sg_reset_wp add --count=ZC option [both zbc2r01b]
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@770 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src/sg_zone.c')
-rw-r--r--src/sg_zone.c64
1 files changed, 50 insertions, 14 deletions
diff --git a/src/sg_zone.c b/src/sg_zone.c
index b7511e8f..7b2c616a 100644
--- a/src/sg_zone.c
+++ b/src/sg_zone.c
@@ -35,12 +35,13 @@
* to the given SCSI device. Based on zbc-r04c.pdf .
*/
-static const char * version_str = "1.07 20180219";
+static const char * version_str = "1.08 20180504";
#define SG_ZONING_OUT_CMDLEN 16
#define CLOSE_ZONE_SA 0x1
#define FINISH_ZONE_SA 0x2
#define OPEN_ZONE_SA 0x3
+#define SEQUENTIALIZE_ZONE_SA 0x10
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define DEF_PT_TIMEOUT 60 /* 60 seconds */
@@ -49,11 +50,13 @@ static const char * version_str = "1.07 20180219";
static struct option long_options[] = {
{"all", no_argument, 0, 'a'},
{"close", no_argument, 0, 'c'},
+ {"count", required_argument, 0, 'C'},
{"finish", no_argument, 0, 'f'},
{"help", no_argument, 0, 'h'},
{"open", no_argument, 0, 'o'},
{"reset-all", no_argument, 0, 'R'},
{"reset_all", no_argument, 0, 'R'},
+ {"sequentialize", no_argument, 0, 'S'},
{"verbose", no_argument, 0, 'v'},
{"version", no_argument, 0, 'V'},
{"zone", required_argument, 0, 'z'},
@@ -66,6 +69,13 @@ static const char * sa_name_arr[] = {
"Close zone",
"Finish zone",
"Open zone",
+ "-", "-", "-", "-",
+ "-", /* 0x8 */
+ "-", "-", "-", "-",
+ "-",
+ "-",
+ "-",
+ "Sequentialize zone", /* 0x10 */
};
@@ -73,14 +83,18 @@ static void
usage()
{
pr2serr("Usage: "
- "sg_zone [--all] [--close] [--finish] [--help] [--open]\n"
- " [--verbose] [--version] [--zone=ID] DEVICE\n");
+ "sg_zone [--all] [--close] [--count=ZC] [--finish] [--help]\n"
+ " [--open] [--sequentialize] [--verbose] "
+ "[--version]\n"
+ " [--zone=ID] DEVICE\n");
pr2serr(" where:\n"
" --all|-a sets the ALL flag in the cdb\n"
" --close|-c issue CLOSE ZONE command\n"
+ " --count=ZC|-C ZC set zone count field (def: 0)\n"
" --finish|-f issue FINISH ZONE command\n"
" --help|-h print out usage message\n"
" --open|-o issue OPEN ZONE command\n"
+ " --sequentialize|-S issue SEQUENTIALIZE ZONE command\n"
" --verbose|-v increase verbosity\n"
" --version|-V print version string and exit\n"
" --zone=ID|-z ID ID is the starting LBA of the zone "
@@ -94,8 +108,8 @@ usage()
/* Invokes the zone out command indicated by 'sa' (ZBC). Return of 0
* -> success, various SG_LIB_CAT_* positive values or -1 -> other errors */
static int
-sg_ll_zone_out(int sg_fd, int sa, uint64_t zid, bool all, bool noisy,
- int verbose)
+sg_ll_zone_out(int sg_fd, int sa, uint64_t zid, uint16_t zc, bool all,
+ bool noisy, int verbose)
{
int k, ret, res, sense_cat;
struct sg_pt_base * ptvp;
@@ -106,6 +120,7 @@ sg_ll_zone_out(int sg_fd, int sa, uint64_t zid, bool all, bool noisy,
zo_cdb[1] = 0x1f & sa;
sg_put_unaligned_be64(zid, zo_cdb + 2);
+ sg_put_unaligned_be16(zc, zo_cdb + 12);
if (all)
zo_cdb[14] = 0x1;
sg_get_opcode_sa_name(zo_cdb[0], sa, -1, sizeof(b), b);
@@ -153,10 +168,12 @@ main(int argc, char * argv[])
bool close = false;
bool finish = false;
bool open = false;
- int sg_fd, res, c;
+ bool sequentialize = false;
+ int sg_fd, res, c, n;
int verbose = 0;
int ret = 0;
int sa = 0;
+ uint16_t zc = 0;
uint64_t zid = 0;
int64_t ll;
const char * device_name = NULL;
@@ -165,7 +182,7 @@ main(int argc, char * argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "acfhoRvVz:", long_options,
+ c = getopt_long(argc, argv, "acC:fhoRSvVz:", long_options,
&option_index);
if (c == -1)
break;
@@ -179,6 +196,15 @@ main(int argc, char * argv[])
close = true;
sa = CLOSE_ZONE_SA;
break;
+ case 'C':
+ n = sg_get_num(optarg);
+ if ((n < 0) || (n > 0xffff)) {
+ pr2serr("--count= expects an argument between 0 and 0xffff "
+ "inclusive\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ zc = (uint16_t)n;
+ break;
case 'f':
finish = true;
sa = FINISH_ZONE_SA;
@@ -191,6 +217,10 @@ main(int argc, char * argv[])
open = true;
sa = OPEN_ZONE_SA;
break;
+ case 'S':
+ sequentialize = true;
+ sa = SEQUENTIALIZE_ZONE_SA;
+ break;
case 'v':
++verbose;
break;
@@ -225,9 +255,9 @@ main(int argc, char * argv[])
}
}
- if (1 != ((int)close + (int)finish + (int)open)) {
- pr2serr("one from the --close, --finish and --open options must be "
- "given\n");
+ if (1 != ((int)close + (int)finish + (int)open + (int)sequentialize)) {
+ pr2serr("one from the --close, --finish, --open and --sequentialize "
+ "options must be given\n");
usage();
return SG_LIB_SYNTAX_ERROR;
}
@@ -241,12 +271,13 @@ main(int argc, char * argv[])
sg_fd = sg_cmds_open_device(device_name, false /* rw */, verbose);
if (sg_fd < 0) {
+ int err = -sg_fd;
pr2serr("open error: %s: %s\n", device_name,
- safe_strerror(-sg_fd));
- return SG_LIB_FILE_ERROR;
+ safe_strerror(err));
+ return sg_convert_errno(err);
}
- res = sg_ll_zone_out(sg_fd, sa, zid, all, true, verbose);
+ res = sg_ll_zone_out(sg_fd, sa, zid, zc, all, true, verbose);
ret = res;
if (res) {
if (SG_LIB_CAT_INVALID_OP == res)
@@ -259,11 +290,16 @@ main(int argc, char * argv[])
}
}
+ if (0 == verbose) {
+ if (! sg_if_can2stderr("sg_zone failed: ", ret))
+ pr2serr("Some error occurred, try again with '-v' or '-vv' for "
+ "more information\n");
+ }
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_convert_errno(-res);
}
return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
}