aboutsummaryrefslogtreecommitdiff
path: root/src/sg_format.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2018-07-25 15:00:20 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2018-07-25 15:00:20 +0000
commit9236f11e7389ec4658b06b3835ad4a6cceca9d50 (patch)
tree16ac647678dd531cd550bf29b4290e3361b4930d /src/sg_format.c
parent519744574345fd358009dc5a167d83715c3f4813 (diff)
downloadsg3_utils-9236f11e7389ec4658b06b3835ad4a6cceca9d50.tar.gz
sg_format: when changing block size allow for Mode Select rejecting SP=1 (Save Page): repeat with SP=0; gcc-8 warning cleanups
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@785 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src/sg_format.c')
-rw-r--r--src/sg_format.c115
1 files changed, 46 insertions, 69 deletions
diff --git a/src/sg_format.c b/src/sg_format.c
index f8b90891..7c34b43f 100644
--- a/src/sg_format.c
+++ b/src/sg_format.c
@@ -38,7 +38,7 @@
#include "sg_pr2serr.h"
#include "sg_pt.h"
-static const char * version_str = "1.51 20180626";
+static const char * version_str = "1.52 20180723";
#define RW_ERROR_RECOVERY_PAGE 1 /* can give alternate with --mode=MP */
@@ -821,7 +821,7 @@ main(int argc, char **argv)
{
bool prob = false;
int fd, res, calc_len, bd_len, dev_specific_param;
- int offset, j, n, bd_blk_len, len, pdt, rsp_len;
+ int offset, j, bd_blk_len, pdt, rsp_len, vb;
int resid = 0;
int ret = 0;
uint64_t ull;
@@ -1033,6 +1033,7 @@ main(int argc, char **argv)
pr2serr("sg_format version: %s\n", version_str);
return 0;
}
+ vb = op->verbose;
if (NULL == op->device_name) {
pr2serr("no DEVICE name given\n\n");
usage();
@@ -1080,7 +1081,7 @@ main(int argc, char **argv)
}
if ((fd = sg_cmds_open_device(op->device_name, false /* rw=false */,
- op->verbose)) < 0) {
+ vb)) < 0) {
pr2serr("error opening device file: %s: %s\n",
op->device_name, safe_strerror(-fd));
return sg_convert_errno(-fd);
@@ -1116,13 +1117,13 @@ again_with_long_lba:
if (op->mode6)
res = sg_ll_mode_sense6(fd, false /* DBD */, 0 /* current */,
op->mode_page, 0 /* subpage */, dbuff,
- MAX_BUFF_SZ, true, op->verbose);
+ MAX_BUFF_SZ, true, vb);
else
res = sg_ll_mode_sense10_v2(fd, op->long_lba, false /* DBD */,
0 /* current */, op->mode_page,
0 /* subpage */, dbuff,
MAX_BUFF_SZ, 0, &resid, true,
- op->verbose);
+ vb);
ret = res;
if (res) {
if (SG_LIB_CAT_ILLEGAL_REQ == res) {
@@ -1135,12 +1136,11 @@ again_with_long_lba:
"[mode_page %d not supported?]\n",
(op->mode6 ? 6 : 10), op->mode_page);
} else {
- sg_get_category_sense_str(res, sizeof(b), b,
- op->verbose);
+ sg_get_category_sense_str(res, sizeof(b), b, vb);
pr2serr("MODE SENSE (%d) command: %s\n",
(op->mode6 ? 6 : 10), b);
}
- if (0 == op->verbose)
+ if (0 == vb)
pr2serr(" try '-v' for more information\n");
goto out;
}
@@ -1198,7 +1198,7 @@ again_with_long_lba:
ull = op->long_lba ? sg_get_unaligned_be64(dbuff + offset) :
sg_get_unaligned_be32(dbuff + offset);
if ((! op->long_lba) && (0xffffffff == ull)) {
- if (op->verbose)
+ if (vb)
pr2serr("Mode sense number of blocks maxed "
"out, set longlba\n");
op->long_lba = true;
@@ -1229,39 +1229,6 @@ again_with_long_lba:
((op->blk_size > 0) && (op->blk_size != bd_blk_len))))) {
/* want to run MODE SELECT */
-/* Working Draft SCSI Primary Commands - 3 (SPC-3) pg 255
-**
-** If the SCSI device doesn't support changing its capacity by changing
-** the NUMBER OF BLOCKS field using the MODE SELECT command, the value
-** in the NUMBER OF BLOCKS field is ignored. If the device supports changing
-** its capacity by changing the NUMBER OF BLOCKS field, then the
-** NUMBER OF BLOCKS field is interpreted as follows:
-** a) If the number of blocks is set to zero, the device shall retain
-** its current capacity if the block size has not changed. If the
-** number of blocks is set to zero and the block size has changed,
-** the device shall be set to its maximum capacity when the new
-** block size takes effect;
-**
-** b) If the number of blocks is greater than zero and less than or
-** equal to its maximum capacity, the device shall be set to that
-** number of blocks. If the block size has not changed, the device
-** shall not become format corrupted. This capacity setting shall be
-** retained through power cycles, hard resets, logical unit resets,
-** and I_T nexus losses;
-**
-** c) If the number of blocks field is set to a value greater than the
-** maximum capacity of the device and less than FFFF FFFFh, then the
-** command is terminated with a CHECK CONDITION status. The sense key
-** is set to ILLEGAL REQUEST. The device shall retain its previous
-** block descriptor settings; or
-**
-** d) If the number of blocks is set to FFFF FFFFh, the device shall be
-** set to its maximum capacity. If the block size has not changed,
-** the device shall not become format corrupted. This capacity setting
-** shall be retained through power cycles, hard resets, logical unit
-** resets, and I_T nexus losses.
-*/
-
if (prob) {
pr2serr("Need to perform MODE SELECT (to change "
"number or blocks or block length)\n");
@@ -1270,19 +1237,18 @@ again_with_long_lba:
ret = SG_LIB_CAT_MALFORMED;
goto out;
}
- if (op->blk_count != 0) {
- len = (op->long_lba ? 8 : 4);
- for (j = 0; j < len; ++j) {
- n = (len - j - 1) * 8;
- dbuff[offset + j] =
- (op->blk_count >> n) & 0xff;
- }
+ if (op->blk_count != 0) { /* user supplied blk count */
+ if (op->long_lba)
+ sg_put_unaligned_be64(op->blk_count,
+ dbuff + offset);
+ else
+ sg_put_unaligned_be32(op->blk_count,
+ dbuff + offset);
} else if ((op->blk_size > 0) &&
- (op->blk_size != bd_blk_len)) {
- len = (op->long_lba ? 8 : 4);
- for (j = 0; j < len; ++j)
- dbuff[offset + j] = 0;
- }
+ (op->blk_size != bd_blk_len))
+ /* 0 implies max capacity with new LB size */
+ memset(dbuff + offset, 0, op->long_lba ? 8 : 4);
+
if ((op->blk_size > 0) && (op->blk_size != bd_blk_len)) {
if (op->long_lba)
sg_put_unaligned_be32((uint32_t)op->blk_size,
@@ -1291,23 +1257,34 @@ again_with_long_lba:
sg_put_unaligned_be24((uint32_t)op->blk_size,
dbuff + offset + 5);
}
- if (op->dry_run)
+ if (op->dry_run) {
pr2serr("Due to --dry-run option bypass MODE "
"SELECT(%d)command\n", (op->mode6 ? 6 : 10));
- else if (op->mode6)
- res = sg_ll_mode_select6(fd, true /* PF */,
- true /* SP */, dbuff,
- calc_len, true, op->verbose);
- else
- res = sg_ll_mode_select10(fd, true /* PF */,
- true /* SP */, dbuff,
- calc_len, true, op->verbose);
+ res = 0;
+ } else {
+ bool sp = true; /* may not be able to save pages */
+
+again_sp_false:
+ if (op->mode6)
+ res = sg_ll_mode_select6(fd, true /* PF */,
+ sp, dbuff, calc_len,
+ true, vb);
+ else
+ res = sg_ll_mode_select10(fd, true /* PF */,
+ sp, dbuff, calc_len,
+ true, vb);
+ if ((SG_LIB_CAT_ILLEGAL_REQ == res) && sp) {
+ pr2serr("Try MODE SELECT again with SP=0 "
+ "this time\n");
+ sp = false;
+ goto again_sp_false;
+ }
+ }
ret = res;
if (res) {
- sg_get_category_sense_str(res, sizeof(b), b,
- op->verbose);
+ sg_get_category_sense_str(res, sizeof(b), b, vb);
pr2serr("MODE SELECT command: %s\n", b);
- if (0 == op->verbose)
+ if (0 == vb)
pr2serr(" try '-v' for more information\n");
goto out;
}
@@ -1364,7 +1341,7 @@ skip_f_unit_reconsider:
ret = res;
if (res) {
pr2serr("FORMAT UNIT failed\n");
- if (0 == op->verbose)
+ if (0 == vb)
pr2serr(" try '-v' for more "
"information\n");
}
@@ -1399,7 +1376,7 @@ skip_f_med_reconsider:
ret = res;
if (res) {
pr2serr("FORMAT MEDIUM failed\n");
- if (0 == op->verbose)
+ if (0 == vb)
pr2serr(" try '-v' for more "
"information\n");
}
@@ -1411,7 +1388,7 @@ out:
if (0 == ret)
ret = sg_convert_errno(-res);
}
- if (0 == op->verbose) {
+ if (0 == vb) {
if (! sg_if_can2stderr("sg_format failed: ", ret))
pr2serr("Some error occurred, try again with '-v' "
"or '-vv' for more information\n");