From b83bf2f2e6adfd2431017963365f3dd13f21757d Mon Sep 17 00:00:00 2001 From: Douglas Gilbert Date: Sat, 28 Nov 2015 03:38:06 +0000 Subject: 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 --- src/sg_raw.c | 145 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 90 insertions(+), 55 deletions(-) (limited to 'src/sg_raw.c') 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 +#include #include #include #include @@ -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 \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); -- cgit v1.2.3