aboutsummaryrefslogtreecommitdiff
path: root/src/sg_raw.c
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2015-11-28 03:38:06 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2015-11-28 03:38:06 +0000
commitb83bf2f2e6adfd2431017963365f3dd13f21757d (patch)
treebdca693649c362a27b618d7c23a70e6b9eb0334c /src/sg_raw.c
parent1a66c384bcfd9e8e0368f371e636beb4bd5aa890 (diff)
downloadsg3_utils-b83bf2f2e6adfd2431017963365f3dd13f21757d.tar.gz
sg_lib_data: sync asc/ascq codes with T10 20151126; sg_unaligned.h: add 48 bit support; sg_raw: document length relationships
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@649 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src/sg_raw.c')
-rw-r--r--src/sg_raw.c145
1 files changed, 90 insertions, 55 deletions
diff --git a/src/sg_raw.c b/src/sg_raw.c
index 510684fa..3b950d57 100644
--- a/src/sg_raw.c
+++ b/src/sg_raw.c
@@ -15,6 +15,7 @@
#define _XOPEN_SOURCE 600 /* clear up posix_memalign() warning */
#include <stdlib.h>
+#include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
@@ -28,7 +29,7 @@
#include "sg_lib.h"
#include "sg_pt.h"
-#define SG_RAW_VERSION "0.4.12 (2014-12-27)"
+#define SG_RAW_VERSION "0.4.13 (2015-11-27)"
#ifdef SG_LIB_WIN32
#ifndef HAVE_SYSCONF
@@ -86,11 +87,31 @@ struct opts_t {
int do_version;
};
+
+#ifdef __GNUC__
+static int pr2serr(const char * fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+#else
+static int pr2serr(const char * fmt, ...);
+#endif
+
+
+static int
+pr2serr(const char * fmt, ...)
+{
+ va_list args;
+ int n;
+
+ va_start(args, fmt);
+ n = vfprintf(stderr, fmt, args);
+ va_end(args);
+ return n;
+}
+
static void
version()
{
- fprintf(stderr,
- "sg_raw " SG_RAW_VERSION "\n"
+ pr2serr("sg_raw " SG_RAW_VERSION "\n"
"Copyright (C) 2007-2012 Ingo van Lil <inguin@gmx.de>\n"
"This is free software. You may redistribute copies of it "
"under the terms of\n"
@@ -102,8 +123,7 @@ version()
static void
usage()
{
- fprintf(stderr,
- "Usage: sg_raw [OPTION]* DEVICE CDB0 CDB1 ...\n"
+ pr2serr("Usage: sg_raw [OPTION]* DEVICE CDB0 CDB1 ...\n"
"\n"
"Options:\n"
" -b, --binary Dump data in binary form, even when "
@@ -126,8 +146,8 @@ usage()
" -V, --version Show version information and exit\n"
"\n"
"Between 6 and 256 command bytes (two hex digits each) can be "
- "specified\nand will be sent to DEVICE. Bidirectional commands "
- "accepted.\n\n"
+ "specified\nand will be sent to DEVICE. Lengths RLEN and SLEN "
+ "are decimal by\ndefault. Bidirectional commands accepted.\n\n"
"Simple example: Perform INQUIRY on /dev/sg0:\n"
" sg_raw -r 1k /dev/sg0 12 00 00 00 60 00\n");
}
@@ -152,7 +172,7 @@ process_cl(struct opts_t * op, int argc, char *argv[])
return 0;
case 'i':
if (op->dataout_file) {
- fprintf(stderr, "Too many '--infile=' options\n");
+ pr2serr("Too many '--infile=' options\n");
return SG_LIB_SYNTAX_ERROR;
}
op->dataout_file = optarg;
@@ -160,7 +180,7 @@ process_cl(struct opts_t * op, int argc, char *argv[])
case 'k':
n = sg_get_num(optarg);
if (n < 0) {
- fprintf(stderr, "Invalid argument to '--skip'\n");
+ pr2serr("Invalid argument to '--skip'\n");
return SG_LIB_SYNTAX_ERROR;
}
op->dataout_offset = n;
@@ -170,7 +190,7 @@ process_cl(struct opts_t * op, int argc, char *argv[])
break;
case 'o':
if (op->datain_file) {
- fprintf(stderr, "Too many '--outfile=' options\n");
+ pr2serr("Too many '--outfile=' options\n");
return SG_LIB_SYNTAX_ERROR;
}
op->datain_file = optarg;
@@ -179,7 +199,7 @@ process_cl(struct opts_t * op, int argc, char *argv[])
op->do_datain = 1;
n = sg_get_num(optarg);
if (n < 0 || n > MAX_SCSI_DXLEN) {
- fprintf(stderr, "Invalid argument to '--request'\n");
+ pr2serr("Invalid argument to '--request'\n");
return SG_LIB_SYNTAX_ERROR;
}
op->datain_len = n;
@@ -191,7 +211,7 @@ process_cl(struct opts_t * op, int argc, char *argv[])
op->do_dataout = 1;
n = sg_get_num(optarg);
if (n < 0 || n > MAX_SCSI_DXLEN) {
- fprintf(stderr, "Invalid argument to '--send'\n");
+ pr2serr("Invalid argument to '--send'\n");
return SG_LIB_SYNTAX_ERROR;
}
op->dataout_len = n;
@@ -199,7 +219,7 @@ process_cl(struct opts_t * op, int argc, char *argv[])
case 't':
n = sg_get_num(optarg);
if (n < 0) {
- fprintf(stderr, "Invalid argument to '--timeout'\n");
+ pr2serr("Invalid argument to '--timeout'\n");
return SG_LIB_SYNTAX_ERROR;
}
op->timeout = n;
@@ -216,7 +236,7 @@ process_cl(struct opts_t * op, int argc, char *argv[])
}
if (optind >= argc) {
- fprintf(stderr, "No device specified\n");
+ pr2serr("No device specified\n");
return SG_LIB_SYNTAX_ERROR;
}
op->device_name = argv[optind];
@@ -227,12 +247,12 @@ process_cl(struct opts_t * op, int argc, char *argv[])
char *endptr;
int cmd = strtol(opt, &endptr, 16);
if (*opt == '\0' || *endptr != '\0' || cmd < 0x00 || cmd > 0xff) {
- fprintf(stderr, "Invalid command byte '%s'\n", opt);
+ pr2serr("Invalid command byte '%s'\n", opt);
return SG_LIB_SYNTAX_ERROR;
}
if (op->cdb_length > MAX_SCSI_CDBSZ) {
- fprintf(stderr, "CDB too long (max. %d bytes)\n", MAX_SCSI_CDBSZ);
+ pr2serr("CDB too long (max. %d bytes)\n", MAX_SCSI_CDBSZ);
return SG_LIB_SYNTAX_ERROR;
}
op->cdb[op->cdb_length] = cmd;
@@ -240,10 +260,10 @@ process_cl(struct opts_t * op, int argc, char *argv[])
}
if (op->cdb_length < MIN_SCSI_CDBSZ) {
- fprintf(stderr, "CDB too short (min. %d bytes)\n", MIN_SCSI_CDBSZ);
+ pr2serr("CDB too short (min. %d bytes)\n", MIN_SCSI_CDBSZ);
return SG_LIB_SYNTAX_ERROR;
}
- if (op->do_verbose > 2) {
+ if (op->do_verbose > 1) {
int sa;
char b[80];
@@ -262,9 +282,10 @@ process_cl(struct opts_t * op, int argc, char *argv[])
/* Allocate aligned memory (heap) starting on page boundary */
static unsigned char *
-my_memalign(int length, unsigned char ** wrkBuffp)
+my_memalign(int length, unsigned char ** wrkBuffp, const struct opts_t * op)
{
size_t psz;
+ unsigned char * res;
#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
psz = sysconf(_SC_PAGESIZE); /* POSIX.1 (was getpagesize()) */
@@ -281,14 +302,17 @@ my_memalign(int length, unsigned char ** wrkBuffp)
err = posix_memalign(&wp, psz, length);
if (err || (NULL == wp)) {
- fprintf(stderr, "posix_memalign: error [%d], out of memory?\n",
- err);
+ pr2serr("posix_memalign: error [%d], out of memory?\n", err);
return NULL;
}
memset(wp, 0, length);
if (wrkBuffp)
*wrkBuffp = (unsigned char *)wp;
- return (unsigned char *)wp;
+ res = (unsigned char *)wp;
+ if (op->do_verbose > 3)
+ pr2serr("%s: posix, len=%d, wrkBuffp=%p, psz=%d, rp=%p\n",
+ __func__, length, *wrkBuffp, (int)psz, res);
+ return res;
}
#else
{
@@ -301,8 +325,12 @@ my_memalign(int length, unsigned char ** wrkBuffp)
return NULL;
} else if (wrkBuffp)
*wrkBuffp = wrkBuff;
- return (unsigned char *)(((uintptr_t)wrkBuff + psz - 1) &
- (~(psz - 1)));
+ res = (unsigned char *)(((uintptr_t)wrkBuff + psz - 1) &
+ (~(psz - 1)));
+ if (op->do_verbose > 3)
+ pr2serr("%s: hack, len=%d, wrkBuffp=%p, psz=%d, rp=%p\n",
+ __func__, length, *wrkBuffp, (int)psz, res);
+ return res;
}
#endif
}
@@ -328,7 +356,7 @@ skip(int fd, off_t offset)
perror("Error reading input data");
return SG_LIB_FILE_ERROR;
} else if (done == 0) {
- fprintf(stderr, "EOF on input file/stream\n");
+ pr2serr("EOF on input file/stream\n");
return SG_LIB_FILE_ERROR;
} else {
remain -= done;
@@ -367,7 +395,7 @@ fetch_dataout(struct opts_t * op)
}
}
- buf = my_memalign(op->dataout_len, &wrkBuf);
+ buf = my_memalign(op->dataout_len, &wrkBuf, op);
if (buf == NULL) {
perror("malloc");
goto bail;
@@ -378,7 +406,7 @@ fetch_dataout(struct opts_t * op)
perror("Failed to read input data");
goto bail;
} else if (len < op->dataout_len) {
- fprintf(stderr, "EOF on input file/stream\n");
+ pr2serr("EOF on input file/stream\n");
goto bail;
}
@@ -439,7 +467,7 @@ main(int argc, char *argv[])
unsigned char sense_buffer[32];
unsigned char * dxfer_buffer_in = NULL;
unsigned char * dxfer_buffer_out = NULL;
- unsigned char *wrkBuf = NULL;
+ unsigned char * wrkBuf = NULL;
struct opts_t opts;
struct opts_t * op;
char b[128];
@@ -462,29 +490,32 @@ main(int argc, char *argv[])
sg_fd = scsi_pt_open_device(op->device_name, op->readonly,
op->do_verbose);
if (sg_fd < 0) {
- fprintf(stderr, "%s: %s\n", op->device_name, safe_strerror(-sg_fd));
+ pr2serr("%s: %s\n", op->device_name, safe_strerror(-sg_fd));
ret = SG_LIB_FILE_ERROR;
goto done;
}
ptvp = construct_scsi_pt_obj();
if (ptvp == NULL) {
- fprintf(stderr, "out of memory\n");
+ pr2serr("out of memory\n");
ret = SG_LIB_CAT_OTHER;
goto done;
}
if (op->do_verbose) {
- fprintf(stderr, " cdb to send: ");
+ pr2serr(" cdb to send: ");
for (k = 0; k < op->cdb_length; ++k)
- fprintf(stderr, "%02x ", op->cdb[k]);
- fprintf(stderr, "\n");
- if (op->do_verbose > 2) {
+ pr2serr("%02x ", op->cdb[k]);
+ pr2serr("\n");
+ if (op->do_verbose > 1) {
sg_get_command_name(op->cdb, 0, sizeof(b) - 1, b);
b[sizeof(b) - 1] = '\0';
- fprintf(stderr, " Command name: %s\n", b);
+ pr2serr(" Command name: %s\n", b);
}
}
set_scsi_pt_cdb(ptvp, op->cdb, op->cdb_length);
+ if (op->do_verbose > 2)
+ pr2serr("sense_buffer=%p, length=%d\n", sense_buffer,
+ (int)sizeof(sense_buffer));
set_scsi_pt_sense(ptvp, sense_buffer, sizeof(sense_buffer));
if (op->do_dataout) {
@@ -493,31 +524,37 @@ main(int argc, char *argv[])
ret = SG_LIB_CAT_OTHER;
goto done;
}
+ if (op->do_verbose > 2)
+ pr2serr("dxfer_buffer_out=%p, length=%d\n", dxfer_buffer_out,
+ op->dataout_len);
set_scsi_pt_data_out(ptvp, dxfer_buffer_out, op->dataout_len);
}
if (op->do_datain) {
- dxfer_buffer_in = my_memalign(op->datain_len, &wrkBuf);
+ dxfer_buffer_in = my_memalign(op->datain_len, &wrkBuf, op);
if (dxfer_buffer_in == NULL) {
perror("malloc");
ret = SG_LIB_CAT_OTHER;
goto done;
}
+ if (op->do_verbose > 2)
+ pr2serr("dxfer_buffer_in=%p, length=%d\n", dxfer_buffer_in,
+ op->datain_len);
set_scsi_pt_data_in(ptvp, dxfer_buffer_in, op->datain_len);
}
ret = do_scsi_pt(ptvp, sg_fd, op->timeout, op->do_verbose);
if (ret > 0) {
if (SCSI_PT_DO_BAD_PARAMS == ret) {
- fprintf(stderr, "do_scsi_pt: bad pass through setup\n");
+ pr2serr("do_scsi_pt: bad pass through setup\n");
ret = SG_LIB_CAT_OTHER;
} else if (SCSI_PT_DO_TIMEOUT == ret) {
- fprintf(stderr, "do_scsi_pt: timeout\n");
+ pr2serr("do_scsi_pt: timeout\n");
ret = SG_LIB_CAT_TIMEOUT;
} else
ret = SG_LIB_CAT_OTHER;
goto done;
} else if (ret < 0) {
- fprintf(stderr, "do_scsi_pt: %s\n", safe_strerror(-ret));
+ pr2serr("do_scsi_pt: %s\n", safe_strerror(-ret));
ret = SG_LIB_CAT_OTHER;
goto done;
}
@@ -534,35 +571,34 @@ main(int argc, char *argv[])
break;
case SCSI_PT_RESULT_TRANSPORT_ERR:
get_scsi_pt_transport_err_str(ptvp, sizeof(b), b);
- fprintf(stderr, ">>> transport error: %s\n", b);
+ pr2serr(">>> transport error: %s\n", b);
ret = SG_LIB_CAT_OTHER;
break;
case SCSI_PT_RESULT_OS_ERR:
get_scsi_pt_os_err_str(ptvp, sizeof(b), b);
- fprintf(stderr, ">>> os error: %s\n", b);
+ pr2serr(">>> os error: %s\n", b);
ret = SG_LIB_CAT_OTHER;
break;
default:
- fprintf(stderr, ">>> unknown pass through result category (%d)\n",
- res_cat);
+ pr2serr(">>> unknown pass through result category (%d)\n", res_cat);
ret = SG_LIB_CAT_OTHER;
break;
}
status = get_scsi_pt_status_response(ptvp);
- fprintf(stderr, "SCSI Status: ");
+ pr2serr("SCSI Status: ");
sg_print_scsi_status(status);
- fprintf(stderr, "\n\n");
+ pr2serr("\n\n");
if ((SAM_STAT_CHECK_CONDITION == status) && (! op->no_sense)) {
if (SCSI_PT_RESULT_SENSE != res_cat)
slen = get_scsi_pt_sense_len(ptvp);
if (0 == slen)
- fprintf(stderr, ">>> Strange: status is CHECK CONDITION but no "
- "Sense Information\n");
+ pr2serr(">>> Strange: status is CHECK CONDITION but no Sense "
+ "Information\n");
else {
- fprintf(stderr, "Sense Information:\n");
+ pr2serr("Sense Information:\n");
sg_print_sense(NULL, sense_buffer, slen, (op->do_verbose > 0));
- fprintf(stderr, "\n");
+ pr2serr("\n");
}
}
if (SAM_STAT_RESERVATION_CONFLICT == status)
@@ -573,12 +609,12 @@ main(int argc, char *argv[])
if (ret && !(SG_LIB_CAT_RECOVERED == ret ||
SG_LIB_CAT_NO_SENSE == ret))
- fprintf(stderr, "Error %d occurred, no data received\n", ret);
+ pr2serr("Error %d occurred, no data received\n", ret);
else if (data_len == 0) {
- fprintf(stderr, "No data received\n");
+ pr2serr("No data received\n");
} else {
if (op->datain_file == NULL && !op->datain_binary) {
- fprintf(stderr, "Received %d bytes of data:\n", data_len);
+ pr2serr("Received %d bytes of data:\n", data_len);
dStrHexErr((const char *)dxfer_buffer_in, data_len, 0);
} else {
const char * cp = "stdout";
@@ -587,8 +623,7 @@ main(int argc, char *argv[])
! ((1 == strlen(op->datain_file)) &&
('-' == op->datain_file[0])))
cp = op->datain_file;
- fprintf(stderr, "Writing %d bytes of data to %s\n", data_len,
- cp);
+ pr2serr("Writing %d bytes of data to %s\n", data_len, cp);
ret2 = write_dataout(op->datain_file, dxfer_buffer_in,
data_len);
if (0 != ret2) {
@@ -603,7 +638,7 @@ main(int argc, char *argv[])
done:
if (op->do_verbose) {
sg_get_category_sense_str(ret, sizeof(b), b, op->do_verbose - 1);
- fprintf(stderr, "%s\n", b);
+ pr2serr("%s\n", b);
}
if (wrkBuf)
free(wrkBuf);