aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2013-05-18 01:50:52 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2013-05-18 01:50:52 +0000
commit69d4248ca767c54623606e505f2d535ba127f927 (patch)
tree772bc21bc3b55425b8a2dba11b86f2c84353a07b /src
parentfaeffd098cd2e1cc79b225b148ef96dd722bcdac (diff)
downloadsg3_utils-69d4248ca767c54623606e505f2d535ba127f927.tar.gz
sg_write_same: add --ndob; sg_sync: add --16; sg_vpd: add FUAB bit
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@496 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r--src/sg_compare_and_write.c4
-rw-r--r--src/sg_dd.c2
-rw-r--r--src/sg_logs.c46
-rw-r--r--src/sg_opcodes.c2
-rw-r--r--src/sg_read.c2
-rw-r--r--src/sg_safte.c2
-rw-r--r--src/sg_sync.c152
-rw-r--r--src/sg_vpd.c3
-rw-r--r--src/sg_write_same.c225
-rw-r--r--src/sg_xcopy.c2
-rw-r--r--src/sginfo.c2
-rw-r--r--src/sgm_dd.c4
-rw-r--r--src/sgp_dd.c2
13 files changed, 291 insertions, 157 deletions
diff --git a/src/sg_compare_and_write.c b/src/sg_compare_and_write.c
index b13d5220..fddcba64 100644
--- a/src/sg_compare_and_write.c
+++ b/src/sg_compare_and_write.c
@@ -48,7 +48,7 @@
*
*/
-static const char * version_str = "1.03 20130507";
+static const char * version_str = "1.04 20130516";
#define DEF_BLOCK_SIZE 512
#define DEF_NUM_BLOCKS (1)
@@ -58,7 +58,7 @@ static const char * version_str = "1.03 20130507";
#define COMPARE_AND_WRITE_OPCODE (0x89)
#define COMPARE_AND_WRITE_CDB_SIZE (16)
-#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define ME "sg_compare_and_write: "
diff --git a/src/sg_dd.c b/src/sg_dd.c
index 10746a09..5f8af5fd 100644
--- a/src/sg_dd.c
+++ b/src/sg_dd.c
@@ -80,7 +80,7 @@ static const char * version_str = "5.77 20130507";
#define CACHING_MP 8
#define CONTROL_MP 0xa
-#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define READ_CAP_REPLY_LEN 8
#define RCAP16_REPLY_LEN 32
#define READ_LONG_OPCODE 0x3E
diff --git a/src/sg_logs.c b/src/sg_logs.c
index 71196c3c..6b04165f 100644
--- a/src/sg_logs.c
+++ b/src/sg_logs.c
@@ -25,7 +25,7 @@
#include "sg_lib.h"
#include "sg_cmds_basic.h"
-static const char * version_str = "1.10 20130507"; /* spc4r35 + sbc3r30 */
+static const char * version_str = "1.11 20130517"; /* spc4r35 + sbc3r30 */
#define MX_ALLOC_LEN (0xfffc)
#define SHORT_RESP_LEN 128
@@ -904,7 +904,7 @@ get_pcb_str(int pcb, char * outp, int maxoutlen)
outp[0] = '\0';
}
-/* BUFF_OVER_UNDER_LPAGE, 0x1 */
+/* BUFF_OVER_UNDER_LPAGE [0x1] */
static void
show_buffer_under_overrun_page(unsigned char * resp, int len, int show_pcb)
{
@@ -971,7 +971,7 @@ show_buffer_under_overrun_page(unsigned char * resp, int len, int show_pcb)
}
/* WRITE_ERR_LPAGE; READ_ERR_LPAGE; READ_REV_ERR_LPAGE; VERIFY_ERR_LPAGE */
-/* 0x2, 0x3, 0x4, 0x5 */
+/* [0x2, 0x3, 0x4, 0x5] */
static void
show_error_counter_page(unsigned char * resp, int len, int show_pcb)
{
@@ -1039,7 +1039,7 @@ show_error_counter_page(unsigned char * resp, int len, int show_pcb)
}
}
-/* NON_MEDIUM_LPAGE, 0x6 */
+/* NON_MEDIUM_LPAGE [0x6] */
static void
show_non_medium_error_page(unsigned char * resp, int len, int show_pcb)
{
@@ -1089,7 +1089,7 @@ show_non_medium_error_page(unsigned char * resp, int len, int show_pcb)
}
}
-/* PCT_LPAGE, 0x1a */
+/* PCT_LPAGE [0x1a] */
static void
show_power_condition_transitions_page(unsigned char * resp, int len,
int show_pcb)
@@ -1368,7 +1368,7 @@ skip_para:
}
}
-/* LAST_N_ERR_LPAGE, 0x7 */
+/* LAST_N_ERR_LPAGE [0x7] */
static void
show_last_n_error_page(unsigned char * resp, int len, int show_pcb)
{
@@ -1410,7 +1410,7 @@ show_last_n_error_page(unsigned char * resp, int len, int show_pcb)
}
}
-/* LAST_N_DEFERRED_LPAGE, 0xb */
+/* LAST_N_DEFERRED_LPAGE [0xb] */
static void
show_last_n_deferred_error_page(unsigned char * resp, int len, int show_pcb)
{
@@ -1460,7 +1460,7 @@ static const char * self_test_result[] = {
"reserved",
"self test in progress"};
-/* SELF_TEST_LPAGE, 0x10 */
+/* SELF_TEST_LPAGE [0x10] */
static void
show_self_test_page(unsigned char * resp, int len, int show_pcb)
{
@@ -1507,7 +1507,7 @@ show_self_test_page(unsigned char * resp, int len, int show_pcb)
}
}
-/* TEMPERATURE_LPAGE, 0xd */
+/* TEMPERATURE_LPAGE [0xd] */
static void
show_temperature_page(unsigned char * resp, int len, int show_pcb, int hdr,
int show_unknown)
@@ -1560,7 +1560,7 @@ show_temperature_page(unsigned char * resp, int len, int show_pcb, int hdr,
}
}
-/* START_STOP_LPAGE, 0xe */
+/* START_STOP_LPAGE [0xe] */
static void
show_start_stop_page(unsigned char * resp, int len, int show_pcb, int verbose)
{
@@ -1658,7 +1658,7 @@ show_start_stop_page(unsigned char * resp, int len, int show_pcb, int verbose)
}
}
-/* IE_LPAGE, 0x2f */
+/* IE_LPAGE [0x2f] */
static void
show_ie_page(unsigned char * resp, int len, int show_pcb, int full)
{
@@ -2063,7 +2063,7 @@ show_sas_port_param(unsigned char * ucp, int param_len,
}
}
-/* PROTO_SPECIFIC_LPAGE, 0x18 */
+/* PROTO_SPECIFIC_LPAGE [0x18] */
static int
show_protocol_specific_page(unsigned char * resp, int len,
const struct opts_t * optsp)
@@ -2088,7 +2088,7 @@ show_protocol_specific_page(unsigned char * resp, int len,
}
/* Returns 1 if processed page, 0 otherwise */
-/* STATS_LPAGE, 0x0 to 0x1f */
+/* STATS_LPAGE [0x19], subpages: 0x0 to 0x1f */
static int
show_stats_perform_page(unsigned char * resp, int len,
const struct opts_t * optsp)
@@ -2415,7 +2415,7 @@ show_stats_perform_page(unsigned char * resp, int len,
}
/* Returns 1 if processed page, 0 otherwise */
-/* STATS_LPAGE [0x16], CACHE_STATS_SUBPG [0x18, 0x20] */
+/* STATS_LPAGE [0x19], CACHE_STATS_SUBPG [0x20] */
static int
show_cache_stats_page(unsigned char * resp, int len,
const struct opts_t * optsp)
@@ -2548,7 +2548,7 @@ show_cache_stats_page(unsigned char * resp, int len,
return 1;
}
-/* FORMAT_STATUS_LPAGE, 0x8 */
+/* FORMAT_STATUS_LPAGE [0x8] */
static void
show_format_status_page(unsigned char * resp, int len, int show_pcb)
{
@@ -2618,7 +2618,7 @@ show_format_status_page(unsigned char * resp, int len, int show_pcb)
}
}
-/* 0x17 */
+/* Non-volatile cache page [0x17] */
static void
show_non_volatile_cache_page(unsigned char * resp, int len, int show_pcb)
{
@@ -2690,7 +2690,7 @@ show_non_volatile_cache_page(unsigned char * resp, int len, int show_pcb)
}
}
-/* LB_PROV_LPAGE, 0xc */
+/* LB_PROV_LPAGE [0xc] */
static void
show_lb_provisioning_page(unsigned char * resp, int len, int show_pcb)
{
@@ -2764,7 +2764,7 @@ show_lb_provisioning_page(unsigned char * resp, int len, int show_pcb)
}
}
-/* SOLID_STATE_MEDIA_LPAGE, 0x11 */
+/* SOLID_STATE_MEDIA_LPAGE [0x11] */
static void
show_solid_state_media_page(unsigned char * resp, int len, int show_pcb)
{
@@ -2804,7 +2804,7 @@ show_solid_state_media_page(unsigned char * resp, int len, int show_pcb)
}
}
-/* SAT_ATA_RESULTS_LPAGE (SAT-2), 0x16 */
+/* SAT_ATA_RESULTS_LPAGE (SAT-2) [0x16] */
static void
show_ata_pt_results_page(unsigned char * resp, int len, int show_pcb)
{
@@ -2859,6 +2859,8 @@ static const char * bms_status[] = {
"background scan halted due to temperature out of range",
"background scan enabled, none active (waiting for BMS interval timer "
"to expire)", /* 8 */
+ "background scan halted - scan results list full",
+ "background scan halted - pre-scan time limit timer expired" /* 10 */,
};
static const char * reassign_status[] = {
@@ -2873,7 +2875,7 @@ static const char * reassign_status[] = {
"Logical block unsuccessfully reassigned by application client", /* 8 */
};
-/* 0x15 for disk */
+/* Background scan results [0x15] for disk */
static void
show_background_scan_results_page(unsigned char * resp, int len, int show_pcb,
int verbose)
@@ -2984,7 +2986,7 @@ show_background_scan_results_page(unsigned char * resp, int len, int show_pcb,
}
}
-/* 0xc for tape */
+/* Sequential access device page [0xc] for tape */
static void
show_sequential_access_page(unsigned char * resp, int len, int show_pcb,
int verbose)
@@ -3505,7 +3507,7 @@ static const char * tape_alert_strs[] = {
"WORM medium - overwrite attempted",
};
-/* TAPE_ALERT_LPAGE, 0x2e */
+/* TAPE_ALERT_LPAGE [0x2e] */
static void
show_tape_alert_ssc_page(unsigned char * resp, int len, int show_pcb,
const struct opts_t * optsp)
diff --git a/src/sg_opcodes.c b/src/sg_opcodes.c
index c9132fad..25f58a6d 100644
--- a/src/sg_opcodes.c
+++ b/src/sg_opcodes.c
@@ -29,7 +29,7 @@
static const char * version_str = "0.38 20130507"; /* spc4r26 */
-#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define DEF_TIMEOUT_SECS 60
#define SG_MAINTENANCE_IN 0xa3
diff --git a/src/sg_read.c b/src/sg_read.c
index d5e5a8bd..9c7dbffb 100644
--- a/src/sg_read.c
+++ b/src/sg_read.c
@@ -61,7 +61,7 @@ static const char * version_str = "1.19 20121211";
#define SG_FLAG_MMAP_IO 4
#endif
-#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define DEF_TIMEOUT 40000 /* 40,000 millisecs == 40 seconds */
#ifndef RAW_MAJOR
diff --git a/src/sg_safte.c b/src/sg_safte.c
index 0eba852d..e8c3446e 100644
--- a/src/sg_safte.c
+++ b/src/sg_safte.c
@@ -29,7 +29,7 @@
static const char * version_str = "0.24 20130507";
-#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define DEF_TIMEOUT 60000 /* 60,000 millisecs == 60 seconds */
#define EBUFF_SZ 256
diff --git a/src/sg_sync.c b/src/sg_sync.c
index 6ba5e018..55f789fd 100644
--- a/src/sg_sync.c
+++ b/src/sg_sync.c
@@ -10,44 +10,58 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h>
#include <getopt.h>
#include "sg_lib.h"
#include "sg_cmds_basic.h"
+#include "sg_pt.h"
/* A utility program for the Linux OS SCSI subsystem.
*
*
- * This program issues the SCSI command SYNCHRONIZE CACHE(10) to the given
- * device. This command is defined for SCSI "direct access" devices
+ * This program issues the SCSI command SYNCHRONIZE CACHE(10 or 16) to the
+ * given device. This command is defined for SCSI "direct access" devices
* (e.g. disks).
*/
-static const char * version_str = "1.09 20130507";
+static const char * version_str = "1.10 20130516";
+
+#define SYNCHRONIZE_CACHE16_CMD 0x91
+#define SYNCHRONIZE_CACHE16_CMDLEN 16
+#define SENSE_BUFF_LEN 64
+#define DEF_PT_TIMEOUT 60 /* 60 seconds */
static struct option long_options[] = {
- {"count", 1, 0, 'c'},
- {"group", 1, 0, 'g'},
- {"help", 0, 0, 'h'},
- {"immed", 0, 0, 'i'},
- {"lba", 1, 0, 'l'},
- {"sync-nv", 0, 0, 's'},
- {"verbose", 0, 0, 'v'},
- {"version", 0, 0, 'V'},
+ {"16", no_argument, 0, 'S'},
+ {"count", required_argument, 0, 'c'},
+ {"group", required_argument, 0, 'g'},
+ {"help", no_argument, 0, 'h'},
+ {"immed", no_argument, 0, 'i'},
+ {"lba", required_argument, 0, 'l'},
+ {"sync-nv", no_argument, 0, 's'},
+ {"timeout", required_argument, 0, 't'},
+ {"verbose", no_argument, 0, 'v'},
+ {"version", no_argument, 0, 'V'},
{0, 0, 0, 0},
};
static void usage()
{
fprintf(stderr, "Usage: "
- "sg_sync [--count=COUNT] [--group=GN] [--help] [--immed]\n"
- " [--lba=LBA] [--sync-nv] [--verbose] [--version] "
- "DEVICE\n"
+ "sg_sync [--16] [--count=COUNT] [--group=GN] [--help] "
+ "[--immed]\n"
+ " [--lba=LBA] [--sync-nv] [--timeout=SECS] "
+ "[--verbose]\n"
+ " [--version] DEVICE\n"
" where:\n"
+ " --16|-S calls SYNCHRONIZE CACHE(16) (def: is "
+ "10 byte\n"
+ " variant)\n"
" --count=COUNT|-c COUNT number of blocks to sync (def: 0 "
- "which implies\n"
- " rest of device)\n"
+ "which\n"
+ " implies rest of device)\n"
" --group=GN|-g GN set group number field to GN (def: 0)\n"
" --help|-h print out usage message\n"
" --immed|-i command returns immediately when set "
@@ -58,22 +72,100 @@ static void usage()
" from (def: 0)\n"
" --sync-nv|-s synchronize to non-volatile storage "
"(if distinct\n"
- " from medium)\n"
+ " from medium). Obsolete in sbc3r35d.\n"
+ " --timeout=SECS|-t SECS command timeout in seconds, only "
+ "active\n"
+ " if '--16' given (def: 60 seconds)\n"
" --verbose|-v increase verbosity\n"
" --version|-V print version string and exit\n\n"
- "Performs a SCSI SYNCHRONIZE CACHE(10) command\n"
+ "Performs a SCSI SYNCHRONIZE CACHE(10 or 16) command\n"
);
}
+static int
+ll_sync_cache_16(int sg_fd, int sync_nv, int immed, int group,
+ uint64_t lba, unsigned int num_lb, int to_secs,
+ int noisy, int verbose)
+{
+ int res, ret, k, sense_cat;
+ unsigned char scCmdBlk[SYNCHRONIZE_CACHE16_CMDLEN] =
+ {SYNCHRONIZE_CACHE16_CMD, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0};
+ unsigned char sense_b[SENSE_BUFF_LEN];
+ struct sg_pt_base * ptvp;
+
+ if (sync_nv)
+ scCmdBlk[1] |= 4; /* obsolete in sbc3r35d */
+ if (immed)
+ scCmdBlk[1] |= 2;
+ scCmdBlk[2] = (lba >> 56) & 0xff;
+ scCmdBlk[3] = (lba >> 48) & 0xff;
+ scCmdBlk[4] = (lba >> 40) & 0xff;
+ scCmdBlk[5] = (lba >> 32) & 0xff;
+ scCmdBlk[6] = (lba >> 24) & 0xff;
+ scCmdBlk[7] = (lba >> 16) & 0xff;
+ scCmdBlk[8] = (lba >> 8) & 0xff;
+ scCmdBlk[9] = lba & 0xff;
+ scCmdBlk[14] = group & 0x1f;
+ scCmdBlk[10] = (num_lb >> 24) & 0xff;
+ scCmdBlk[11] = (num_lb >> 16) & 0xff;
+ scCmdBlk[12] = (num_lb >> 8) & 0xff;
+ scCmdBlk[13] = num_lb & 0xff;
+
+ if (verbose) {
+ fprintf(stderr, " synchronize cache(16) cdb: ");
+ for (k = 0; k < SYNCHRONIZE_CACHE16_CMDLEN; ++k)
+ fprintf(stderr, "%02x ", scCmdBlk[k]);
+ fprintf(sg_warnings_strm, "\n");
+ }
+ ptvp = construct_scsi_pt_obj();
+ if (NULL == ptvp) {
+ fprintf(stderr, "synchronize cache(16): out of memory\n");
+ return -1;
+ }
+ set_scsi_pt_cdb(ptvp, scCmdBlk, sizeof(scCmdBlk));
+ set_scsi_pt_sense(ptvp, sense_b, sizeof(sense_b));
+ res = do_scsi_pt(ptvp, sg_fd, to_secs, verbose);
+ ret = sg_cmds_process_resp(ptvp, "synchronize cache(16)", res, 0,
+ sense_b, noisy, verbose, &sense_cat);
+ if (-1 == ret)
+ ;
+ else if (-2 == ret) {
+ switch (sense_cat) {
+ case SG_LIB_CAT_NOT_READY:
+ case SG_LIB_CAT_UNIT_ATTENTION:
+ case SG_LIB_CAT_INVALID_OP:
+ case SG_LIB_CAT_ILLEGAL_REQ:
+ case SG_LIB_CAT_ABORTED_COMMAND:
+ ret = sense_cat;
+ break;
+ case SG_LIB_CAT_RECOVERED:
+ case SG_LIB_CAT_NO_SENSE:
+ ret = 0;
+ break;
+ default:
+ ret = -1;
+ break;
+ }
+ } else
+ ret = 0;
+
+ destruct_scsi_pt_obj(ptvp);
+ return ret;
+}
+
int main(int argc, char * argv[])
{
int sg_fd, res, c;
int64_t count = 0;
+ unsigned int num_lb = 0;
+ int do_16 = 0;
int group = 0;
int64_t lba = 0;
int immed = 0;
int sync_nv = 0;
+ int to_secs = DEF_PT_TIMEOUT;
int verbose = 0;
const char * device_name = NULL;
int ret = 0;
@@ -81,7 +173,7 @@ int main(int argc, char * argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "c:g:hil:svV", long_options,
+ c = getopt_long(argc, argv, "c:g:hil:sSt:vV", long_options,
&option_index);
if (c == -1)
break;
@@ -89,10 +181,11 @@ int main(int argc, char * argv[])
switch (c) {
case 'c':
count = sg_get_llnum(optarg);
- if (count < 0) {
+ if ((count < 0) || (count > UINT_MAX)) {
fprintf(stderr, "bad argument to '--count'\n");
return SG_LIB_SYNTAX_ERROR;
}
+ num_lb = (unsigned int)count;
break;
case 'g':
group = sg_get_num(optarg);
@@ -118,6 +211,16 @@ int main(int argc, char * argv[])
case 's':
sync_nv = 1;
break;
+ case 'S':
+ do_16 = 1;
+ break;
+ case 't':
+ to_secs = sg_get_num(optarg);
+ if (to_secs < 0) {
+ fprintf(stderr, "bad argument to '--timeout'\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ break;
case 'v':
++verbose;
break;
@@ -156,9 +259,12 @@ int main(int argc, char * argv[])
return SG_LIB_FILE_ERROR;
}
- res = sg_ll_sync_cache_10(sg_fd, sync_nv, immed, group,
- (unsigned int)lba, (unsigned int)count,
- 1, verbose);
+ if (do_16)
+ res = ll_sync_cache_16(sg_fd, sync_nv, immed, group, lba, num_lb,
+ to_secs, 1, verbose);
+ else
+ res = sg_ll_sync_cache_10(sg_fd, sync_nv, immed, group,
+ (unsigned int)lba, num_lb, 1, verbose);
ret = res;
if (0 == res)
;
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index 00547ae7..275b69eb 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -30,7 +30,7 @@
*/
-static const char * version_str = "0.66 20130510"; /* spc4r36 + sbc3r35 */
+static const char * version_str = "0.67 20130517"; /* spc4r36 + sbc3r35 */
/* And with sbc3r35, vale Mark Evans */
extern void svpd_enumerate_vendor(void);
@@ -1723,6 +1723,7 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt)
printf(": reserved\n");
break;
}
+ printf(" FUAB=%d\n", buff[8] & 0x2);
printf(" VBULS=%d\n", buff[8] & 0x1);
break;
case PDT_TAPE: case PDT_MCHANGER: case PDT_ADC:
diff --git a/src/sg_write_same.c b/src/sg_write_same.c
index c0f49463..7f10217b 100644
--- a/src/sg_write_same.c
+++ b/src/sg_write_same.c
@@ -26,7 +26,7 @@
#include "sg_cmds_basic.h"
#include "sg_cmds_extra.h"
-static const char * version_str = "1.01 20130507";
+static const char * version_str = "1.02 20130516";
#define ME "sg_write_same: "
@@ -41,7 +41,7 @@ static const char * version_str = "1.01 20130507";
#define WRITE_SAME32_LEN 32
#define RCAP10_RESP_LEN 8
#define RCAP16_RESP_LEN 32
-#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define DEF_TIMEOUT_SECS 60
#define DEF_WS_CDB_SIZE WRITE_SAME10_LEN
#define DEF_WS_NUMBLOCKS 1
@@ -58,6 +58,7 @@ static struct option long_options[] = {
{"in", required_argument, 0, 'i'},
{"lba", required_argument, 0, 'l'},
{"lbdata", no_argument, 0, 'L'},
+ {"ndob", no_argument, 0, 'N'},
{"num", required_argument, 0, 'n'},
{"pbdata", no_argument, 0, 'P'},
{"timeout", required_argument, 0, 'r'},
@@ -75,6 +76,7 @@ struct opts_t {
char ifilename[256];
uint64_t lba;
int lbdata;
+ int ndob;
int numblocks;
int pbdata;
int timeout;
@@ -95,10 +97,12 @@ usage()
"sg_write_same [--10] [--16] [--32] [--anchor] [--grpnum=GN] "
"[--help]\n"
" [--in=IF] [--lba=LBA] [--lbdata] "
- "[--num=NUM] [--pbdata]\n"
- " [--timeout=TO] [--unmap] [--verbose] "
- "[--version]\n"
- " [--wrprotect=WRP] [xferlen=LEN] DEVICE\n"
+ "[--ndob] [--num=NUM]\n"
+ " [--pbdata] [--timeout=TO] [--unmap] "
+ "[--verbose]\n"
+ " [--version] [--wrprotect=WRP] "
+ "[xferlen=LEN]\n"
+ " DEVICE\n"
" where:\n"
" --10|-R do WRITE SAME(10) (even if '--unmap' "
"is given)\n"
@@ -116,6 +120,7 @@ usage()
" --lba=LBA|-l LBA LBA is the logical block address to "
"start (def: 0)\n"
" --lbdata|-L set LBDATA bit\n"
+ " --ndob|-N set 'no data-out buffer' bit\n"
" --num=NUM|-n NUM NUM is number of logical blocks to "
"write (def: 1)\n"
" [Beware NUM==0 means rest of device]\n"
@@ -149,7 +154,7 @@ do_write_same(int sg_fd, const struct opts_t * optsp, const void * dataoutp,
if (WRITE_SAME10_LEN == cdb_len) {
llba = optsp->lba + optsp->numblocks;
if ((optsp->numblocks > 0xffff) || (llba > ULONG_MAX) ||
- (optsp->unmap && (0 == optsp->want_ws10))) {
+ optsp->ndob || (optsp->unmap && (0 == optsp->want_ws10))) {
cdb_len = WRITE_SAME16_LEN;
if (optsp->verbose)
fprintf(stderr, "do_write_same: use WRITE SAME(16) instead "
@@ -193,6 +198,8 @@ do_write_same(int sg_fd, const struct opts_t * optsp, const void * dataoutp,
wsCmdBlk[1] |= 0x4;
if (optsp->lbdata)
wsCmdBlk[1] |= 0x2;
+ if (optsp->ndob)
+ wsCmdBlk[1] |= 0x1;
llba = optsp->lba;
for (k = 7; k >= 0; --k) {
wsCmdBlk[2 + k] = (llba & 0xff);
@@ -222,6 +229,8 @@ do_write_same(int sg_fd, const struct opts_t * optsp, const void * dataoutp,
wsCmdBlk[10] |= 0x4;
if (optsp->lbdata)
wsCmdBlk[10] |= 0x2;
+ if (optsp->ndob)
+ wsCmdBlk[10] |= 0x1;
llba = optsp->lba;
for (k = 7; k >= 0; --k) {
wsCmdBlk[12 + k] = (llba & 0xff);
@@ -326,8 +335,8 @@ main(int argc, char * argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "ag:hi:l:Ln:PRSt:TUvVw:x:", long_options,
- &option_index);
+ c = getopt_long(argc, argv, "ag:hi:l:Ln:NPRSt:TUvVw:x:",
+ long_options, &option_index);
if (c == -1)
break;
@@ -370,6 +379,9 @@ main(int argc, char * argv[])
}
num_given = 1;
break;
+ case 'N':
+ ++opts.ndob;
+ break;
case 'P':
++opts.pbdata;
break;
@@ -458,10 +470,20 @@ main(int argc, char * argv[])
return SG_LIB_SYNTAX_ERROR;
}
- memset(&a_stat, 0, sizeof(a_stat));
- if (opts.ifilename[0]) {
+ if (opts.ndob) {
+ if (if_given) {
+ fprintf(stderr, "Can't have both --ndob and '--in='\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ if (0 != opts.xfer_len) {
+ fprintf(stderr, "With --ndob only '--xferlen=0' (or not given) "
+ "is acceptable\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ } else if (opts.ifilename[0]) {
got_stdin = (0 == strcmp(opts.ifilename, "-")) ? 1 : 0;
if (! got_stdin) {
+ memset(&a_stat, 0, sizeof(a_stat));
if (stat(opts.ifilename, &a_stat) < 0) {
if (vb)
fprintf(stderr, "unable to stat(%s): %s\n",
@@ -480,105 +502,108 @@ main(int argc, char * argv[])
return SG_LIB_FILE_ERROR;
}
- prot_en = 0;
- if (0 == opts.xfer_len) {
- res = sg_ll_readcap_16(sg_fd, 0 /* pmi */, 0 /* llba */, resp_buff,
- RCAP16_RESP_LEN, 0, (vb ? (vb - 1): 0));
- if (0 == res) {
- if (vb > 3)
- dStrHex((const char *)resp_buff, RCAP16_RESP_LEN, 1);
- block_size = ((resp_buff[8] << 24) |
- (resp_buff[9] << 16) |
- (resp_buff[10] << 8) |
- resp_buff[11]);
- prot_en = !!(resp_buff[12] & 0x1);
- opts.xfer_len = block_size;
- if (prot_en && (opts.wrprotect > 0))
- opts.xfer_len += 8;
- } else if ((SG_LIB_CAT_INVALID_OP == res) ||
- (SG_LIB_CAT_ILLEGAL_REQ == res)) {
- if (vb)
- fprintf(stderr, "Read capacity(16) not supported, try Read "
- "capacity(10)\n");
- res = sg_ll_readcap_10(sg_fd, 0 /* pmi */, 0 /* lba */, resp_buff,
- RCAP10_RESP_LEN, 0, (vb ? (vb - 1): 0));
+ if (! opts.ndob) {
+ prot_en = 0;
+ if (0 == opts.xfer_len) {
+ res = sg_ll_readcap_16(sg_fd, 0 /* pmi */, 0 /* llba */, resp_buff,
+ RCAP16_RESP_LEN, 0, (vb ? (vb - 1): 0));
if (0 == res) {
if (vb > 3)
- dStrHex((const char *)resp_buff, RCAP10_RESP_LEN, 1);
- block_size = ((resp_buff[4] << 24) |
- (resp_buff[5] << 16) |
- (resp_buff[6] << 8) |
- resp_buff[7]);
+ dStrHex((const char *)resp_buff, RCAP16_RESP_LEN, 1);
+ block_size = ((resp_buff[8] << 24) |
+ (resp_buff[9] << 16) |
+ (resp_buff[10] << 8) |
+ resp_buff[11]);
+ prot_en = !!(resp_buff[12] & 0x1);
opts.xfer_len = block_size;
+ if (prot_en && (opts.wrprotect > 0))
+ opts.xfer_len += 8;
+ } else if ((SG_LIB_CAT_INVALID_OP == res) ||
+ (SG_LIB_CAT_ILLEGAL_REQ == res)) {
+ if (vb)
+ fprintf(stderr, "Read capacity(16) not supported, try "
+ "Read capacity(10)\n");
+ res = sg_ll_readcap_10(sg_fd, 0 /* pmi */, 0 /* lba */,
+ resp_buff, RCAP10_RESP_LEN, 0,
+ (vb ? (vb - 1): 0));
+ if (0 == res) {
+ if (vb > 3)
+ dStrHex((const char *)resp_buff, RCAP10_RESP_LEN, 1);
+ block_size = ((resp_buff[4] << 24) |
+ (resp_buff[5] << 16) |
+ (resp_buff[6] << 8) |
+ resp_buff[7]);
+ opts.xfer_len = block_size;
+ }
+ } else if (vb)
+ fprintf(stderr, "Read capacity(16) failed. Unable to "
+ "calculate block size\n");
+ if (res)
+ fprintf(stderr, "Read capacity(10) failed. Unable to "
+ "calculate block size\n");
+ }
+ if (opts.xfer_len < 1) {
+ fprintf(stderr, "unable to deduce block size, please give "
+ "'--xferlen=' argument\n");
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto err_out;
+ }
+ if (opts.xfer_len > MAX_XFER_LEN) {
+ fprintf(stderr, "'--xferlen=%d is out of range ( want <= %d)\n",
+ opts.xfer_len, MAX_XFER_LEN);
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto err_out;
+ }
+ wBuff = (unsigned char*)calloc(opts.xfer_len, 1);
+ if (NULL == wBuff) {
+ fprintf(stderr, "unable to allocate %d bytes of memory with "
+ "calloc()\n", opts.xfer_len);
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto err_out;
+ }
+ if (opts.ifilename[0]) {
+ if (got_stdin) {
+ infd = STDIN_FILENO;
+ if (sg_set_binary_mode(STDIN_FILENO) < 0)
+ perror("sg_set_binary_mode");
+ } else {
+ if ((infd = open(opts.ifilename, O_RDONLY)) < 0) {
+ snprintf(ebuff, EBUFF_SZ, ME "could not open %s for "
+ "reading", opts.ifilename);
+ perror(ebuff);
+ ret = SG_LIB_FILE_ERROR;
+ goto err_out;
+ } else if (sg_set_binary_mode(infd) < 0)
+ perror("sg_set_binary_mode");
}
- } else if (vb)
- fprintf(stderr, "Read capacity(16) failed. Unable to calculate "
- "block size\n");
- if (res)
- fprintf(stderr, "Read capacity(10) failed. Unable to calculate "
- "block size\n");
- }
- if (opts.xfer_len < 1) {
- fprintf(stderr, "unable to deduce block size, please give "
- "'--xferlen=' argument\n");
- ret = SG_LIB_SYNTAX_ERROR;
- goto err_out;
- }
- if (opts.xfer_len > MAX_XFER_LEN) {
- fprintf(stderr, "'--xferlen=%d is out of range ( want <= %d)\n",
- opts.xfer_len, MAX_XFER_LEN);
- ret = SG_LIB_SYNTAX_ERROR;
- goto err_out;
- }
- wBuff = (unsigned char*)calloc(opts.xfer_len, 1);
- if (NULL == wBuff) {
- fprintf(stderr, "unable to allocate %d bytes of memory with "
- "calloc()\n", opts.xfer_len);
- ret = SG_LIB_SYNTAX_ERROR;
- goto err_out;
- }
- if (opts.ifilename[0]) {
- if (got_stdin) {
- infd = STDIN_FILENO;
- if (sg_set_binary_mode(STDIN_FILENO) < 0)
- perror("sg_set_binary_mode");
- } else {
- if ((infd = open(opts.ifilename, O_RDONLY)) < 0) {
- snprintf(ebuff, EBUFF_SZ,
- ME "could not open %s for reading", opts.ifilename);
+ res = read(infd, wBuff, opts.xfer_len);
+ if (res < 0) {
+ snprintf(ebuff, EBUFF_SZ, ME "couldn't read from %s",
+ opts.ifilename);
perror(ebuff);
+ if (! got_stdin)
+ close(infd);
ret = SG_LIB_FILE_ERROR;
goto err_out;
- } else if (sg_set_binary_mode(infd) < 0)
- perror("sg_set_binary_mode");
- }
- res = read(infd, wBuff, opts.xfer_len);
- if (res < 0) {
- snprintf(ebuff, EBUFF_SZ, ME "couldn't read from %s",
- opts.ifilename);
- perror(ebuff);
+ }
+ if (res < opts.xfer_len) {
+ fprintf(stderr, "tried to read %d bytes from %s, got %d "
+ "bytes\n", opts.xfer_len, opts.ifilename, res);
+ fprintf(stderr, " so pad with 0x0 bytes and continue\n");
+ }
if (! got_stdin)
close(infd);
- ret = SG_LIB_FILE_ERROR;
- goto err_out;
- }
- if (res < opts.xfer_len) {
- fprintf(stderr, "tried to read %d bytes from %s, got %d "
- "bytes\n", opts.xfer_len, opts.ifilename, res);
- fprintf(stderr, " so pad with 0x0 bytes and continue\n");
- }
- if (! got_stdin)
- close(infd);
- } else {
- if (vb)
- fprintf(stderr, "Default data-out buffer set to %d zeros\n",
- opts.xfer_len);
- if (prot_en && (opts.wrprotect > 0)) {
- /* default for protection is 0xff, rest get 0x0 */
- memset(wBuff + opts.xfer_len - 8, 0xff, 8);
+ } else {
if (vb)
- fprintf(stderr, " ... apart from last 8 bytes which are set "
- "to 0xff\n");
+ fprintf(stderr, "Default data-out buffer set to %d zeros\n",
+ opts.xfer_len);
+ if (prot_en && (opts.wrprotect > 0)) {
+ /* default for protection is 0xff, rest get 0x0 */
+ memset(wBuff + opts.xfer_len - 8, 0xff, 8);
+ if (vb)
+ fprintf(stderr, " ... apart from last 8 bytes which are "
+ "set to 0xff\n");
+ }
}
}
diff --git a/src/sg_xcopy.c b/src/sg_xcopy.c
index 82c7bd71..b2f3a015 100644
--- a/src/sg_xcopy.c
+++ b/src/sg_xcopy.c
@@ -80,7 +80,7 @@ static const char * version_str = "0.34 20130507";
#define CACHING_MP 8
#define CONTROL_MP 0xa
-#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define READ_CAP_REPLY_LEN 8
#define RCAP16_REPLY_LEN 32
diff --git a/src/sginfo.c b/src/sginfo.c
index b6396793..6a8f0b93 100644
--- a/src/sginfo.c
+++ b/src/sginfo.c
@@ -371,7 +371,7 @@ struct scsi_cmnd_io
size_t dxfer_len; /* bytes to be transferred to/from dxferp */
};
-#define SENSE_BUFF_LEN 32
+#define SENSE_BUFF_LEN 64
#define CMD_TIMEOUT 60000 /* 60,000 milliseconds (60 seconds) */
#define EBUFF_SZ 256
diff --git a/src/sgm_dd.c b/src/sgm_dd.c
index 84bd445b..f6d8e3e4 100644
--- a/src/sgm_dd.c
+++ b/src/sgm_dd.c
@@ -1,7 +1,7 @@
/* A utility program for copying files. Specialised for "files" that
* represent devices that understand the SCSI command set.
*
- * Copyright (C) 1999 - 2012 D. Gilbert and P. Allworth
+ * Copyright (C) 1999 - 2013 D. Gilbert and P. Allworth
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
@@ -84,7 +84,7 @@ static const char * version_str = "1.37 20130507";
#define SG_FLAG_MMAP_IO 4
#endif
-#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define READ_CAP_REPLY_LEN 8
#define RCAP16_REPLY_LEN 32
diff --git a/src/sgp_dd.c b/src/sgp_dd.c
index 96cd7a8a..06a0fa38 100644
--- a/src/sgp_dd.c
+++ b/src/sgp_dd.c
@@ -69,7 +69,7 @@ static const char * version_str = "5.43 20130507";
/* #define SG_DEBUG */
-#define SENSE_BUFF_LEN 32 /* Arbitrary, could be larger */
+#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
#define READ_CAP_REPLY_LEN 8
#define RCAP16_REPLY_LEN 32