aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2016-03-14 01:10:45 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2016-03-14 01:10:45 +0000
commitb798bfc6514f9dfff87da36456fe15d7e1b53e6f (patch)
treeff2a7c90888a1f7d1ab21c92f3d3c6af05f1a8fb /src
parent70cacd5629374ab1a56c4d372aac986f1de09207 (diff)
downloadsg3_utils-b798bfc6514f9dfff87da36456fe15d7e1b53e6f.tar.gz
sg_logs: fix volume statistics; add Requested recovery, TapeAlert response, and Service buffer information; sg_opcode: add '--enumerate' and '--pdt=' options; sg_lib: add SSC maintenance in/out sa names
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@685 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'src')
-rw-r--r--src/sg_logs.c296
-rw-r--r--src/sg_opcodes.c267
-rw-r--r--src/sg_read_attr.c4
-rw-r--r--src/sg_vpd.c67
4 files changed, 465 insertions, 169 deletions
diff --git a/src/sg_logs.c b/src/sg_logs.c
index 74bea70d..ba5f82f8 100644
--- a/src/sg_logs.c
+++ b/src/sg_logs.c
@@ -31,7 +31,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "1.40 20160303"; /* spc5r08 + sbc4r10 */
+static const char * version_str = "1.40 20160313"; /* spc5r08 + sbc4r10 */
#define MX_ALLOC_LEN (0xfffc)
#define SHORT_RESP_LEN 128
@@ -101,6 +101,7 @@ static struct option long_options[] = {
{"paramp", required_argument, 0, 'P'},
{"pcb", no_argument, 0, 'q'},
{"ppc", no_argument, 0, 'Q'},
+ {"pdt", required_argument, 0, 'D'},
{"raw", no_argument, 0, 'r'},
{"readonly", no_argument, 0, 'X'},
{"reset", no_argument, 0, 'R'},
@@ -142,7 +143,7 @@ struct opts_t {
int paramp;
int opt_new;
int no_inq;
- int dev_pdt;
+ int dev_pdt; /* from device or --pdt=DT */
const char * device_name;
const char * in_fn;
const char * pg_arg;
@@ -201,6 +202,10 @@ static bool show_media_stats_page(const uint8_t * resp, int len,
const struct opts_t * op);
static bool show_dt_device_status_page(const uint8_t * resp, int len,
const struct opts_t * op);
+static bool show_tapealert_response_page(const uint8_t * resp, int len,
+ const struct opts_t * op);
+static bool show_requested_recovery_page(const uint8_t * resp, int len,
+ const struct opts_t * op);
static bool show_background_scan_results_page(const uint8_t * resp, int len,
const struct opts_t * op);
static bool show_pending_defects_page(const uint8_t * resp, int len,
@@ -211,6 +216,8 @@ static bool show_lps_misalignment_page(const uint8_t * resp, int len,
const struct opts_t * op);
static bool show_element_stats_page(const uint8_t * resp, int len,
const struct opts_t * op);
+static bool show_service_buffer_info_page(const uint8_t * resp, int len,
+ const struct opts_t * op);
static bool show_ata_pt_results_page(const uint8_t * resp, int len,
const struct opts_t * op);
static bool show_tape_diag_data_page(const uint8_t * resp, int len,
@@ -295,9 +302,9 @@ static struct log_elem log_arr[] = {
{0x11, 0, 0, PDT_TAPE, 0, "DT Device status", "dtds",
show_dt_device_status_page}, /* 0x11, 0x0 SSC,ADC */
{0x12, 0, 0, PDT_TAPE, 0, "Tape alert response", "tar",
- NULL}, /* 0x12, 0x0 SSC,ADC */
+ show_tapealert_response_page}, /* 0x12, 0x0 SSC,ADC */
{0x13, 0, 0, PDT_TAPE, 0, "Requested recovery", "rr",
- NULL}, /* 0x13, 0x0 SSC,ADC */
+ show_requested_recovery_page}, /* 0x13, 0x0 SSC,ADC */
{0x14, 0, 0, PDT_TAPE, 0, "Device statistics", "ds",
show_device_stats_page}, /* 0x14, 0x0 SSC,ADC */
{0x14, 0, 0, PDT_MCHANGER, 0, "Media changer statistics", "mcs",
@@ -313,7 +320,7 @@ static struct log_elem log_arr[] = {
{0x15, 0, 0, PDT_MCHANGER, 0, "Element statistics", "els",
show_element_stats_page}, /* 0x15, 0x0 SMC */
{0x15, 0, 0, PDT_ADC, 0, "Service buffers information", "sbi",
- NULL}, /* 0x15, 0x0 ADC */
+ show_service_buffer_info_page}, /* 0x15, 0x0 ADC */
{BACKGROUND_SCAN_LPAGE, PENDING_DEFECTS_SUBPG, 0, 0, 0,
"Pending defects", "pd", show_pending_defects_page}, /* 0x15, 0x1 SBC */
{SAT_ATA_RESULTS_LPAGE, 0, 0, 0, 0, "ATA pass-through results", "aptr",
@@ -404,11 +411,11 @@ usage(int hval)
"[--in=FN]\n"
" [--list] [--no_inq] [--maxlen=LEN] [--name] "
"[--page=PG]\n"
- " [--paramp=PP] [--pcb] [--ppc] [--raw] "
- "[--readonly]\n"
- " [--reset] [--select] [--sp] [--temperature] "
- "[--transport]\n"
- " [--verbose] [--version] DEVICE\n"
+ " [--paramp=PP] [--pcb] [--ppc] [--pdt=DT] "
+ "[--raw]\n"
+ " [--readonly] [--reset] [--select] [--sp] "
+ "[--temperature]\n"
+ " [--transport] [--verbose] [--version] DEVICE\n"
" where the main options are:\n"
" --All|-A fetch and decode all log pages and "
"subpages\n"
@@ -479,6 +486,9 @@ usage(int hval)
"output\n"
" --ppc|-Q set the Parameter Pointer Control (PPC) bit "
"(def: 0)\n"
+ " --pdt=DT|-D DT DT is peripheral device type to use with "
+ "'--in=FN'\n"
+ " or when '--no_inq' is used\n"
" --readonly|-X open DEVICE read-only (def: first "
"read-write then if\n"
" fails try open again read-only)\n"
@@ -491,17 +501,19 @@ usage(int hval)
" --version|-V output version string then exit\n\n"
"If DEVICE and --select are given, a LOG SELECT command will be "
"issued. If\nDEVICE is not given and '--in=FN' is given then FN "
- "will decoded as if it\nwere a log page. Pages defined in SPC "
- "are common to all device types.\n");
+ "will decoded as if it\nwere a log page. The contents of FN "
+ "typically generated by a prior\n"
+ "'sg_logs -HHH ...' invocation.\nPages defined in SPC are common "
+ "to all device types.\n");
}
}
static void
usage_old()
{
- printf("Usage: sg_logs [-a] [-A] [-b] [-c=PC] [-e] [-E] [-f=FL] [-h] "
- "[-H]\n"
- " [-i=FN] [-l] [-L] [-m=LEN] [-n] [-p=PG] "
+ printf("Usage: sg_logs [-a] [-A] [-b] [-c=PC] [-D=DT] [-e] [-E] [-f=FL] "
+ "[-h]\n"
+ " [-H] [-i=FN] [-l] [-L] [-m=LEN] [-n] [-p=PG] "
"[-paramp=PP]\n"
" [-pcb] [-ppc] [-r] [-select] [-sp] [-t] [-T] "
"[-v] [-V]\n"
@@ -711,7 +723,7 @@ process_cl_new(struct opts_t * op, int argc, char * argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "aAbc:eEf:hHi:lLm:nNOp:P:qQrRsStTvVxX",
+ c = getopt_long(argc, argv, "aAbc:D:eEf:hHi:lLm:nNOp:P:qQrRsStTvVxX",
long_options, &option_index);
if (c == -1)
break;
@@ -735,6 +747,14 @@ process_cl_new(struct opts_t * op, int argc, char * argv[])
}
op->page_control = n;
break;
+ case 'D':
+ n = sg_get_num(optarg);
+ if ((n < 0) || (n > 31)) {
+ pr2serr("bad argument to '--pdt='\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ op->dev_pdt = n;
+ break;
case 'e':
++op->do_enumerate;
break;
@@ -962,6 +982,14 @@ process_cl_old(struct opts_t * op, int argc, char * argv[])
return SG_LIB_SYNTAX_ERROR;
}
op->page_control = u;
+ } else if (0 == strncmp("D=", cp, 2)) {
+ n = sg_get_num(cp + 2);
+ if ((n < 0) || (n > 31)) {
+ pr2serr("Bad argument after '-D=' option\n");
+ usage_old();
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ op->dev_pdt = n;
} else if (0 == strncmp("f=", cp, 2)) {
n = sg_get_num(cp + 2);
if ((n < 0) || (n > 0xffff)) {
@@ -4210,6 +4238,162 @@ skip:
return true;
}
+/* TapeAlert response [0x12] (adc,ssc) */
+static bool
+show_tapealert_response_page(const uint8_t * resp, int len,
+ const struct opts_t * op)
+{
+ int num, pl, pc, pcb, k, mod, div;
+ const uint8_t * ucp;
+ char str[PCB_STR_LEN];
+
+ if (op->verbose || ((0 == op->do_raw) && (0 == op->do_hex)))
+ printf("TapeAlert response page (ssc-3, adc-3) [0x12]\n");
+ num = len - 4;
+ ucp = &resp[0] + 4;
+ while (num > 3) {
+ pc = sg_get_unaligned_be16(ucp + 0);
+ pcb = ucp[2];
+ pl = ucp[3] + 4;
+ if (op->filter_given) {
+ if (pc != op->filter)
+ goto skip;
+ if (op->do_raw) {
+ dStrRaw((const char *)ucp, pl);
+ break;
+ } else if (op->do_hex) {
+ dStrHex((const char *)ucp, pl, ((1 == op->do_hex) ? 1 : -1));
+ break;
+ }
+ }
+ switch (pc) {
+ case 0x0:
+ if (pl < 12) {
+
+ }
+ for (k = 1; k < 0x41; ++k) {
+ mod = ((k - 1) % 8);
+ div = (k - 1) / 8;
+ if (0 == mod) {
+ if (div > 0)
+ printf("\n");
+ printf(" Flag%02Xh: %d", k, !! (ucp[4 + div] & 0x80));
+ } else
+ printf(" %02Xh: %d", k,
+ !! (ucp[4 + div] & (1 << (7 - mod))));
+ }
+ printf("\n");
+ break;
+ default:
+ if (pc <= 0x8000) {
+ printf(" Reserved [parameter_code=0x%x]:\n", pc);
+ dStrHex((const char *)ucp, ((pl < num) ? pl : num), 0);
+ } else {
+ printf(" Vendor specific [parameter_code=0x%x]:\n", pc);
+ dStrHex((const char *)ucp, ((pl < num) ? pl : num), 0);
+ }
+ break;
+ }
+ if (op->do_pcb) {
+ get_pcb_str(pcb, str, sizeof(str));
+ printf(" <%s>\n", str);
+ }
+ if (op->filter_given)
+ break;
+skip:
+ num -= pl;
+ ucp += pl;
+ }
+ return true;
+}
+
+#define NUM_REQ_REC_ARR_ELEMS 16
+static const char * req_rec_arr[NUM_REQ_REC_ARR_ELEMS] = {
+ "Recovery not requested",
+ "Recovery requested, no recovery procedure defined",
+ "Instruct operator to push volume",
+ "Instruct operator to remove and re-insert volume",
+ "Issue UNLOAD command. Instruct operator to remove and re-insert volume",
+ "Instruct operator to power cycle target device",
+ "Issue LOAD command",
+ "Issue UNLOAD command",
+ "Issue LOGICAL UNIT RESET task management function", /* 0x8 */
+ "No recovery procedure defined. Contact service organization",
+ "Issue UNLOAD command. Instruct operator to remove and quarantine "
+ "volume",
+ "Instruct operator to not insert a volume. Contact service organization",
+ "Issue UNLOAD command. Instruct operator to remove volume. Contact "
+ "service organization",
+ "Request creation of target device error log",
+ "Retrieve a target device error log",
+ "Modify configuration to all microcode update and instruct operator to "
+ "re-insert volume", /* 0xf */
+};
+
+/* Requested recovery [0x13] (ssc) */
+static bool
+show_requested_recovery_page(const uint8_t * resp, int len,
+ const struct opts_t * op)
+{
+ int num, pl, pc, pcb, j, k;
+ const uint8_t * ucp;
+ char str[PCB_STR_LEN];
+
+ if (op->verbose || ((0 == op->do_raw) && (0 == op->do_hex)))
+ printf("Requested recovery page (ssc-3) [0x13]\n");
+ num = len - 4;
+ ucp = &resp[0] + 4;
+ while (num > 3) {
+ pc = sg_get_unaligned_be16(ucp + 0);
+ pcb = ucp[2];
+ pl = ucp[3] + 4;
+ if (op->filter_given) {
+ if (pc != op->filter)
+ goto skip;
+ if (op->do_raw) {
+ dStrRaw((const char *)ucp, pl);
+ break;
+ } else if (op->do_hex) {
+ dStrHex((const char *)ucp, pl, ((1 == op->do_hex) ? 1 : -1));
+ break;
+ }
+ }
+ switch (pc) {
+ case 0x0:
+ printf(" Recovery procedures:\n");
+ for (k = 4; k < pl; ++ k) {
+ j = ucp[k];
+ if (j < NUM_REQ_REC_ARR_ELEMS)
+ printf(" %s\n", req_rec_arr[j]);
+ else if (j < 0x80)
+ printf(" Reserved [0x%x]\n", j);
+ else
+ printf(" Vendor specific [0x%x]\n", j);
+ }
+ break;
+ default:
+ if (pc <= 0x8000) {
+ printf(" Reserved [parameter_code=0x%x]:\n", pc);
+ dStrHex((const char *)ucp, ((pl < num) ? pl : num), 0);
+ } else {
+ printf(" Vendor specific [parameter_code=0x%x]:\n", pc);
+ dStrHex((const char *)ucp, ((pl < num) ? pl : num), 0);
+ }
+ break;
+ }
+ if (op->do_pcb) {
+ get_pcb_str(pcb, str, sizeof(str));
+ printf(" <%s>\n", str);
+ }
+ if (op->filter_given)
+ break;
+skip:
+ num -= pl;
+ ucp += pl;
+ }
+ return true;
+}
+
/* SAT_ATA_RESULTS_LPAGE (SAT-2) [0x16] */
static bool
show_ata_pt_results_page(const uint8_t * resp, int len,
@@ -4240,23 +4424,28 @@ show_ata_pt_results_page(const uint8_t * resp, int len,
}
}
if ((pc < 0xf) && (pl > 17)) {
- int extend, sector_count;
+ int extend, count;
- dp = ucp + 4;
printf(" Log_index=0x%x (parameter_code=0x%x)\n", pc + 1, pc);
+ dp = ucp + 4; /* dp is start of ATA Return descriptor
+ * which is 14 bytes long */
extend = dp[2] & 1;
- sector_count = dp[5] + (extend ? (dp[4] << 8) : 0);
- printf(" extend=%d error=0x%x sector_count=0x%x\n", extend,
- dp[3], sector_count);
+ count = dp[5] + (extend ? (dp[4] << 8) : 0);
+ printf(" extend=%d error=0x%x count=0x%x\n", extend,
+ dp[3], count);
if (extend)
printf(" lba=0x%02x%02x%02x%02x%02x%02x\n", dp[10], dp[8],
dp[6], dp[11], dp[9], dp[7]);
else
printf(" lba=0x%02x%02x%02x\n", dp[11], dp[9], dp[7]);
printf(" device=0x%x status=0x%x\n", dp[12], dp[13]);
- } else {
+ } else if (pl > 17) {
printf(" Reserved [parameter_code=0x%x]:\n", pc);
dStrHex((const char *)ucp, ((pl < num) ? pl : num), 0);
+ } else {
+ printf(" short parameter length: %d [parameter_code=0x%x]:\n",
+ pl, pc);
+ dStrHex((const char *)ucp, ((pl < num) ? pl : num), 0);
}
if (op->do_pcb) {
get_pcb_str(pcb, str, sizeof(str));
@@ -4622,6 +4811,63 @@ skip:
return true;
}
+/* Service buffer information [0x15] (adc) */
+static bool
+show_service_buffer_info_page(const uint8_t * resp, int len,
+ const struct opts_t * op)
+{
+ int num, pl, pc, pcb;
+ const uint8_t * ucp;
+ char str[PCB_STR_LEN];
+
+ if (op->verbose || ((0 == op->do_raw) && (0 == op->do_hex)))
+ printf("Service buffer information page (adc-3) [0x15]\n");
+ num = len - 4;
+ ucp = &resp[0] + 4;
+ while (num > 3) {
+ pc = sg_get_unaligned_be16(ucp + 0);
+ pcb = ucp[2];
+ pl = ucp[3] + 4;
+ if (op->filter_given) {
+ if (pc != op->filter)
+ goto skip;
+ if (op->do_raw) {
+ dStrRaw((const char *)ucp, pl);
+ break;
+ } else if (op->do_hex) {
+ dStrHex((const char *)ucp, pl, ((1 == op->do_hex) ? 1 : -1));
+ break;
+ }
+ }
+ if (pc < 0x100) {
+ printf(" Service buffer identifier: 0x%x\n", pc);
+ printf(" Buffer id: 0x%x, tu=%d, nmp=%d, nmm=%d, "
+ "offline=%d\n", ucp[4], !!(0x10 & ucp[5]),
+ !!(0x8 & ucp[5]), !!(0x4 & ucp[5]), !!(0x2 & ucp[5]));
+ printf(" pd=%d, code_set: %s, Service buffer title:\n",
+ !!(0x1 & ucp[5]), sg_get_desig_code_set_str(0xf & ucp[6]));
+ printf(" %*s\n", pl - 8, ucp + 8);
+ } else if (pc < 0x8000) {
+ printf(" parameter_code=0x%x, Reserved, parameter in hex:\n",
+ pc);
+ dStrHex((const char *)ucp + 4, pl - 4, 0);
+ } else {
+ printf(" parameter_code=0x%x, Vendor-specific, parameter in "
+ "hex:\n", pc);
+ dStrHex((const char *)ucp + 4, pl - 4, 0);
+ }
+ if (op->do_pcb) {
+ get_pcb_str(pcb, str, sizeof(str));
+ printf(" <%s>\n", str);
+ }
+ if (op->filter_given)
+ break;
+skip:
+ num -= pl;
+ ucp += pl;
+ }
+ return true;
+}
/* Sequential access device page [0xc] for tape */
static bool
@@ -5055,7 +5301,7 @@ skip:
return true;
}
-/* 0x15 for media changer */
+/* Element statistics page, 0x15 for SMC */
static bool
show_element_stats_page(const uint8_t * resp, int len,
const struct opts_t * op)
@@ -6039,9 +6285,7 @@ main(int argc, char * argv[])
n);
n = in_len - k;
}
- pdt = (op->filter_given && (op->filter >= 0)) ?
- op->filter : -1;
- op->dev_pdt = pdt;
+ pdt = op->dev_pdt;
lep = pg_subpg_pdt_search(pg_code, subpg_code, pdt);
if (lep) {
if (lep->show_pagep)
diff --git a/src/sg_opcodes.c b/src/sg_opcodes.c
index 1b42f172..eddf65a3 100644
--- a/src/sg_opcodes.c
+++ b/src/sg_opcodes.c
@@ -1,5 +1,5 @@
/* A utility program originally written for the Linux OS SCSI subsystem.
- * Copyright (C) 2004-2015 D. Gilbert
+ * Copyright (C) 2004-2016 D. Gilbert
* 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)
@@ -15,6 +15,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <getopt.h>
#ifdef HAVE_CONFIG_H
@@ -28,7 +29,7 @@
#include "sg_pt.h"
-static const char * version_str = "0.45 20151219"; /* spc5r07 */
+static const char * version_str = "0.46 20160313"; /* spc5r08 */
#define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */
@@ -44,7 +45,7 @@ static const char * version_str = "0.45 20151219"; /* spc5r07 */
#define NAME_BUFF_SZ 128
-static int peri_type = 0; /* ugly but not easy to pass to alpha compare */
+static int peri_dtype = -1; /* ugly but not easy to pass to alpha compare */
static int do_rsoc(int sg_fd, int rctd, int rep_opts, int rq_opcode,
int rq_servact, void * resp, int mx_resp_len, int noisy,
@@ -56,6 +57,7 @@ static int do_rstmf(int sg_fd, int repd, void * resp, int mx_resp_len,
static struct option long_options[] = {
{"alpha", 0, 0, 'a'},
{"compact", 0, 0, 'c'},
+ {"enumerate", 0, 0, 'e'},
{"help", 0, 0, 'h'},
{"hex", 0, 0, 'H'},
{"mask", 0, 0, 'm'},
@@ -77,16 +79,17 @@ static struct option long_options[] = {
struct opts_t {
int do_alpha;
int do_compact;
+ int do_enumerate;
int do_help;
int do_hex;
int no_inquiry;
int do_mask;
- int do_opcode;
+ int opcode;
int do_raw;
int do_rctd;
int do_repd;
- int do_servact;
- int do_verbose;
+ int servact;
+ int verbose;
int do_version;
int do_unsorted;
int do_taskman;
@@ -98,17 +101,20 @@ struct opts_t {
static void
usage()
{
- pr2serr("Usage: sg_opcodes [--alpha] [--compact] [--help] [--hex] "
- "[--mask]\n"
- " [--no-inquiry] [--opcode=OP[,SA]] [--raw] "
- "[--rctd]\n"
- " [--repd] [--sa=SA] [--tmf] [--unsorted] "
- "[--verbose]\n"
- " [--version] DEVICE\n"
+ pr2serr("Usage: sg_opcodes [--alpha] [--compact] [--enumerate] "
+ "[--help] [--hex]\n"
+ " [--mask] [--no-inquiry] [--opcode=OP[,SA]] "
+ "[--pdt=DT]\n"
+ " [--raw] [--rctd] [--repd] [--sa=SA] [--tmf] "
+ "[--unsorted]\n"
+ " [--verbose] [--version] DEVICE\n"
" where:\n"
" --alpha|-a output list of operation codes sorted "
"alphabetically\n"
" --compact|-c more compact output\n"
+ " --enumerate|-e use '--opcode=' and '--pdt=' to look up "
+ "name,\n"
+ " ignore DEVICE\n"
" --help|-h print usage message then exit\n"
" --hex|-H output response in hex\n"
" --mask|-m and show cdb usage data (a mask) when "
@@ -120,6 +126,9 @@ usage()
"(SA)\n"
" (decimal, each prefix with '0x' for "
"hex)\n"
+ " --pdt=DT|-p DT give peripheral device type for "
+ "'--no-inquiry'\n"
+ " '--enumerate'\n"
" --raw|-r output response in binary to stdout\n"
" --rctd|-R set RCTD (return command timeout "
"descriptor) bit\n"
@@ -141,17 +150,22 @@ usage()
static void
usage_old()
{
- pr2serr("Usage: sg_opcodes [-a] [-c] [-H] [-m] [-n] [-o=OP] [-q] [-r] "
- "[-R] [-s=SA]\n"
- " [-t] [-u] [-v] [-V] DEVICE\n"
+ pr2serr("Usage: sg_opcodes [-a] [-c] [-e] [-H] [-m] [-n] [-o=OP] "
+ "[-p=DT] [-q]\n"
+ " [-r] [-R] [-s=SA] [-t] [-u] [-v] [-V] "
+ "DEVICE\n"
" where:\n"
" -a output list of operation codes sorted "
"alphabetically\n"
" -c more compact output\n"
+ " -e use '--opcode=' and '--pdt=' to look up name, "
+ "ignore DEVICE\n"
" -H print response in hex\n"
" -m and show cdb usage data (a mask) when all listed\n"
" -n don't output INQUIRY information\n"
" -o=OP first byte of command to query (in hex)\n"
+ " -p=DT alternate source of pdt (normally obtained from "
+ "inquiry)\n"
" -q set REPD bit for tmf_s\n"
" -r output response in binary to stdout\n"
" -R set RCTD (return command timeout "
@@ -167,7 +181,7 @@ usage_old()
}
static int
-process_cl_new(struct opts_t * optsp, int argc, char * argv[])
+process_cl_new(struct opts_t * op, int argc, char * argv[])
{
int c, n;
char * cp;
@@ -176,30 +190,33 @@ process_cl_new(struct opts_t * optsp, int argc, char * argv[])
while (1) {
int option_index = 0;
- c = getopt_long(argc, argv, "achHmnNo:OqrRs:tuvV", long_options,
+ c = getopt_long(argc, argv, "acehHmnNo:Op:qrRs:tuvV", long_options,
&option_index);
if (c == -1)
break;
switch (c) {
case 'a':
- ++optsp->do_alpha;
+ ++op->do_alpha;
break;
case 'c':
- ++optsp->do_compact;
+ ++op->do_compact;
+ break;
+ case 'e':
+ ++op->do_enumerate;
break;
case 'h':
case '?':
- ++optsp->do_help;
+ ++op->do_help;
break;
case 'H':
- ++optsp->do_hex;
+ ++op->do_hex;
break;
case 'm':
- ++optsp->do_mask;
+ ++op->do_mask;
break;
case 'n':
- ++optsp->no_inquiry;
+ ++op->no_inquiry;
break;
case 'N':
break; /* ignore */
@@ -217,14 +234,14 @@ process_cl_new(struct opts_t * optsp, int argc, char * argv[])
pr2serr("bad OP argument to '--opcode'\n");
return SG_LIB_SYNTAX_ERROR;
}
- optsp->do_opcode = n;
+ op->opcode = n;
n = sg_get_num(cp + 1);
if ((n < 0) || (n > 0xffff)) {
pr2serr("bad SA argument to '--opcode'\n");
usage();
return SG_LIB_SYNTAX_ERROR;
}
- optsp->do_servact = n;
+ op->servact = n;
} else {
n = sg_get_num(optarg);
if ((n < 0) || (n > 255)) {
@@ -232,20 +249,32 @@ process_cl_new(struct opts_t * optsp, int argc, char * argv[])
usage();
return SG_LIB_SYNTAX_ERROR;
}
- optsp->do_opcode = n;
+ op->opcode = n;
}
break;
case 'O':
- optsp->opt_new = 0;
+ op->opt_new = 0;
return 0;
+ case 'p':
+ n = -2;
+ if (isdigit(optarg[0]))
+ n = sg_get_num(optarg);
+ else if ((2 == strlen(optarg)) && (0 == strcmp("-1", optarg)))
+ n = -1;
+ if ((n < -1) || (n > 0x1f)) {
+ pr2serr("bad argument to '--pdt=DT', expect -1 to 31\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ peri_dtype = n;
+ break;
case 'q':
- ++optsp->do_repd;
+ ++op->do_repd;
break;
case 'r':
- ++optsp->do_raw;
+ ++op->do_raw;
break;
case 'R':
- ++optsp->do_rctd;
+ ++op->do_rctd;
break;
case 's':
n = sg_get_num(optarg);
@@ -254,31 +283,31 @@ process_cl_new(struct opts_t * optsp, int argc, char * argv[])
usage();
return SG_LIB_SYNTAX_ERROR;
}
- optsp->do_servact = n;
+ op->servact = n;
break;
case 't':
- ++optsp->do_taskman;
+ ++op->do_taskman;
break;
case 'u':
- ++optsp->do_unsorted;
+ ++op->do_unsorted;
break;
case 'v':
- ++optsp->do_verbose;
+ ++op->verbose;
break;
case 'V':
- ++optsp->do_version;
+ ++op->do_version;
break;
default:
pr2serr("unrecognised option code %c [0x%x]\n", c, c);
- if (optsp->do_help)
+ if (op->do_help)
break;
usage();
return SG_LIB_SYNTAX_ERROR;
}
}
if (optind < argc) {
- if (NULL == optsp->device_name) {
- optsp->device_name = argv[optind];
+ if (NULL == op->device_name) {
+ op->device_name = argv[optind];
++optind;
}
if (optind < argc) {
@@ -292,7 +321,7 @@ process_cl_new(struct opts_t * optsp, int argc, char * argv[])
}
static int
-process_cl_old(struct opts_t * optsp, int argc, char * argv[])
+process_cl_old(struct opts_t * op, int argc, char * argv[])
{
int k, jmp_out, plen, n, num;
const char * cp;
@@ -306,46 +335,49 @@ process_cl_old(struct opts_t * optsp, int argc, char * argv[])
for (--plen, ++cp, jmp_out = 0; plen > 0; --plen, ++cp) {
switch (*cp) {
case 'a':
- ++optsp->do_alpha;
+ ++op->do_alpha;
break;
case 'c':
- ++optsp->do_compact;
+ ++op->do_compact;
+ break;
+ case 'e':
+ ++op->do_enumerate;
break;
case 'H':
- ++optsp->do_hex;
+ ++op->do_hex;
break;
case 'm':
- ++optsp->do_mask;
+ ++op->do_mask;
break;
case 'n':
- ++optsp->no_inquiry;
+ ++op->no_inquiry;
break;
case 'N':
- optsp->opt_new = 1;
+ op->opt_new = 1;
return 0;
case 'O':
break;
case 'q':
- ++optsp->do_repd;
+ ++op->do_repd;
break;
case 'R':
- ++optsp->do_rctd;
+ ++op->do_rctd;
break;
case 't':
- ++optsp->do_taskman;
+ ++op->do_taskman;
break;
case 'u':
- ++optsp->do_unsorted;
+ ++op->do_unsorted;
break;
case 'v':
- ++optsp->do_verbose;
+ ++op->verbose;
break;
case 'V':
- ++optsp->do_version;
+ ++op->do_version;
break;
case 'h':
case '?':
- ++optsp->do_help;
+ ++op->do_help;
break;
default:
jmp_out = 1;
@@ -363,7 +395,15 @@ process_cl_old(struct opts_t * optsp, int argc, char * argv[])
usage_old();
return SG_LIB_SYNTAX_ERROR;
}
- optsp->do_opcode = n;
+ op->opcode = n;
+ } else if (0 == strncmp("p=", cp, 2)) {
+ num = sscanf(cp + 2, "%d", &n);
+ if ((1 != num) || (n > 0x1f) || (n < -1)) {
+ pr2serr("Bad number after 'p=' option, expect -1 to "
+ "31\n");
+ return SG_LIB_SYNTAX_ERROR;
+ }
+ peri_dtype = n;
} else if (0 == strncmp("s=", cp, 2)) {
num = sscanf(cp + 2, "%x", (unsigned int *)&n);
if (1 != num) {
@@ -371,7 +411,7 @@ process_cl_old(struct opts_t * optsp, int argc, char * argv[])
usage_old();
return SG_LIB_SYNTAX_ERROR;
}
- optsp->do_servact = n;
+ op->servact = n;
} else if (0 == strncmp("-old", cp, 4))
;
else if (jmp_out) {
@@ -379,11 +419,11 @@ process_cl_old(struct opts_t * optsp, int argc, char * argv[])
usage_old();
return SG_LIB_SYNTAX_ERROR;
}
- } else if (NULL == optsp->device_name)
- optsp->device_name = cp;
+ } else if (NULL == op->device_name)
+ op->device_name = cp;
else {
pr2serr("too many arguments, got: %s, not expecting: %s\n",
- optsp->device_name, cp);
+ op->device_name, cp);
usage_old();
return SG_LIB_SYNTAX_ERROR;
}
@@ -392,22 +432,22 @@ process_cl_old(struct opts_t * optsp, int argc, char * argv[])
}
static int
-process_cl(struct opts_t * optsp, int argc, char * argv[])
+process_cl(struct opts_t * op, int argc, char * argv[])
{
int res;
char * cp;
cp = getenv("SG3_UTILS_OLD_OPTS");
if (cp) {
- optsp->opt_new = 0;
- res = process_cl_old(optsp, argc, argv);
- if ((0 == res) && optsp->opt_new)
- res = process_cl_new(optsp, argc, argv);
+ op->opt_new = 0;
+ res = process_cl_old(op, argc, argv);
+ if ((0 == res) && op->opt_new)
+ res = process_cl_new(op, argc, argv);
} else {
- optsp->opt_new = 1;
- res = process_cl_new(optsp, argc, argv);
- if ((0 == res) && (0 == optsp->opt_new))
- res = process_cl_old(optsp, argc, argv);
+ op->opt_new = 1;
+ res = process_cl_new(op, argc, argv);
+ if ((0 == res) && (0 == op->opt_new))
+ res = process_cl_old(op, argc, argv);
}
return res;
}
@@ -472,13 +512,13 @@ opcode_alpha_compare(const void * left, const void * right)
if (ll[5] & 1)
l_serv_act = sg_get_unaligned_be16(ll + 2);
l_name_buff[0] = '\0';
- sg_get_opcode_sa_name(l_opc, l_serv_act, peri_type,
+ sg_get_opcode_sa_name(l_opc, l_serv_act, peri_dtype,
NAME_BUFF_SZ, l_name_buff);
r_opc = rr[0];
if (rr[5] & 1)
r_serv_act = sg_get_unaligned_be16(rr + 2);
r_name_buff[0] = '\0';
- sg_get_opcode_sa_name(r_opc, r_serv_act, peri_type,
+ sg_get_opcode_sa_name(r_opc, r_serv_act, peri_dtype,
NAME_BUFF_SZ, r_name_buff);
return strncmp(l_name_buff, r_name_buff, NAME_BUFF_SZ);
}
@@ -552,14 +592,14 @@ list_all_codes(unsigned char * rsoc_buff, int rsoc_len, struct opts_t * op,
serv_act = 0;
if (sa_v) {
serv_act = sg_get_unaligned_be16(ucp + 2);
- sg_get_opcode_sa_name(opcode, serv_act, peri_type, NAME_BUFF_SZ,
+ sg_get_opcode_sa_name(opcode, serv_act, peri_dtype, NAME_BUFF_SZ,
name_buff);
if (op->do_compact)
snprintf(sa_buff, sizeof(sa_buff), "%-4x", serv_act);
else
snprintf(sa_buff, sizeof(sa_buff), "%4x", serv_act);
} else {
- sg_get_opcode_name(opcode, peri_type, NAME_BUFF_SZ, name_buff);
+ sg_get_opcode_name(opcode, peri_dtype, NAME_BUFF_SZ, name_buff);
memset(sa_buff, ' ', sizeof(sa_buff));
}
if (op->do_rctd) {
@@ -602,7 +642,7 @@ list_all_codes(unsigned char * rsoc_buff, int rsoc_len, struct opts_t * op,
memset(b, 0, sizeof(b));
res = do_rsoc(sg_fd, 0, (sa_v ? 2 : 1), opcode, serv_act,
- b, sizeof(b), 1, op->do_verbose);
+ b, sizeof(b), 1, op->verbose);
if (0 == res) {
cdb_sz = sg_get_unaligned_be16(b + 2);
if ((cdb_sz > 0) && (cdb_sz <= 80)) {
@@ -664,13 +704,13 @@ list_one(unsigned char * rsoc_buff, int cd_len, int rep_opts,
int v = 0;
- printf("\n Opcode=0x%.2x", op->do_opcode);
+ printf("\n Opcode=0x%.2x", op->opcode);
if (rep_opts > 1)
- printf(" Service_action=0x%.4x", op->do_servact);
+ printf(" Service_action=0x%.4x", op->servact);
printf("\n");
- sg_get_opcode_sa_name(((op->do_opcode > 0) ? op->do_opcode : 0),
- ((op->do_servact > 0) ? op->do_servact : 0),
- peri_type, NAME_BUFF_SZ, name_buff);
+ sg_get_opcode_sa_name(((op->opcode > 0) ? op->opcode : 0),
+ ((op->servact > 0) ? op->servact : 0),
+ peri_dtype, NAME_BUFF_SZ, name_buff);
printf(" Command_name: %s\n", name_buff);
switch((int)(rsoc_buff[1] & 7)) {
case 0:
@@ -725,8 +765,8 @@ main(int argc, char * argv[])
op = &opts;
memset(op, 0, sizeof(opts));
- op->do_opcode = -1;
- op->do_servact = -1;
+ op->opcode = -1;
+ op->servact = -1;
res = process_cl(op, argc, argv);
if (res)
return SG_LIB_SYNTAX_ERROR;
@@ -742,7 +782,7 @@ main(int argc, char * argv[])
return 0;
}
- if (NULL == op->device_name) {
+ if ((NULL == op->device_name) && (0 == op->do_enumerate)) {
pr2serr("No DEVICE argument given\n");
if (op->opt_new)
usage();
@@ -750,7 +790,7 @@ main(int argc, char * argv[])
usage_old();
return SG_LIB_SYNTAX_ERROR;
}
- if ((-1 != op->do_servact) && (-1 == op->do_opcode)) {
+ if ((-1 != op->servact) && (-1 == op->opcode)) {
pr2serr("When '-s' is chosen, so must '-o' be chosen\n");
if (op->opt_new)
usage();
@@ -761,32 +801,59 @@ main(int argc, char * argv[])
if (op->do_unsorted && op->do_alpha)
pr2serr("warning: unsorted ('-u') and alpha ('-a') options chosen, "
"ignoring alpha\n");
- if (op->do_taskman && ((-1 != op->do_opcode) || op->do_alpha ||
+ if (op->do_taskman && ((-1 != op->opcode) || op->do_alpha ||
op->do_unsorted)) {
pr2serr("warning: task management functions ('-t') chosen so alpha "
"('-a'),\n unsorted ('-u') and opcode ('-o') "
"options ignored\n");
}
+ if (op->do_enumerate) {
+ char name_buff[NAME_BUFF_SZ];
+
+ if (op->do_taskman)
+ printf("enumerate not supported with task management "
+ "functions\n");
+ else { /* SCSI command */
+ if (op->opcode < 0)
+ op->opcode = 0;
+ if (op->servact < 0)
+ op->servact = 0;
+ if (peri_dtype < 0)
+ peri_dtype = 0;
+ printf("SCSI command:");
+ if (op->verbose)
+ printf(" [opcode=0x%x, sa=0x%x, pdt=0x%x]\n", op->opcode,
+ op->servact, peri_dtype);
+ else
+ printf("\n");
+ sg_get_opcode_sa_name(op->opcode, op->servact, peri_dtype,
+ NAME_BUFF_SZ, name_buff);
+ printf(" %s\n", name_buff);
+ }
+ return 0;
+ }
op_name = op->do_taskman ? "Report supported task management functions" :
"Report supported operation codes";
- if (op->do_opcode < 0) {
+ if (op->opcode < 0) {
if ((sg_fd = scsi_pt_open_device(op->device_name, 1 /* RO */,
- op->do_verbose)) < 0) {
+ op->verbose)) < 0) {
pr2serr("sg_opcodes: error opening file (ro): %s: %s\n",
op->device_name, safe_strerror(-sg_fd));
return SG_LIB_FILE_ERROR;
}
- if (0 == sg_simple_inquiry(sg_fd, &inq_resp, 1, op->do_verbose)) {
- peri_type = inq_resp.peripheral_type;
+ if (op->no_inquiry && (peri_dtype >= 0))
+ ;
+ else if (0 == sg_simple_inquiry(sg_fd, &inq_resp, 1, op->verbose)) {
+ peri_dtype = inq_resp.peripheral_type;
if (! (op->do_raw || op->no_inquiry)) {
printf(" %.8s %.16s %.4s\n", inq_resp.vendor,
inq_resp.product, inq_resp.revision);
- cp = sg_get_pdt_str(peri_type, sizeof(buff), buff);
+ cp = sg_get_pdt_str(peri_dtype, sizeof(buff), buff);
if (strlen(cp) > 0)
printf(" Peripheral device type: %s\n", cp);
else
- printf(" Peripheral device type: 0x%x\n", peri_type);
+ printf(" Peripheral device type: 0x%x\n", peri_dtype);
}
} else {
pr2serr("sg_opcodes: %s doesn't respond to a SCSI INQUIRY\n",
@@ -801,23 +868,23 @@ main(int argc, char * argv[])
}
if ((sg_fd = scsi_pt_open_device(op->device_name, 0 /* RW */,
- op->do_verbose)) < 0) {
+ op->verbose)) < 0) {
pr2serr("sg_opcodes: error opening file (rw): %s: %s\n",
op->device_name, safe_strerror(-sg_fd));
return SG_LIB_FILE_ERROR;
}
- if (op->do_opcode >= 0)
- rep_opts = ((op->do_servact >= 0) ? 2 : 1);
+ if (op->opcode >= 0)
+ rep_opts = ((op->servact >= 0) ? 2 : 1);
memset(rsoc_buff, 0, sizeof(rsoc_buff));
if (op->do_taskman)
res = do_rstmf(sg_fd, op->do_repd, rsoc_buff,
- (op->do_repd ? 16 : 4), 1, op->do_verbose);
+ (op->do_repd ? 16 : 4), 1, op->verbose);
else
- res = do_rsoc(sg_fd, op->do_rctd, rep_opts, op->do_opcode,
- op->do_servact, rsoc_buff, sizeof(rsoc_buff), 1,
- op->do_verbose);
+ res = do_rsoc(sg_fd, op->do_rctd, rep_opts, op->opcode,
+ op->servact, rsoc_buff, sizeof(rsoc_buff), 1,
+ op->verbose);
if (res) {
- sg_get_category_sense_str(res, sizeof(b), b, op->do_verbose);
+ sg_get_category_sense_str(res, sizeof(b), b, op->verbose);
pr2serr("%s: %s\n", op_name, b);
goto err_out;
}
@@ -844,9 +911,9 @@ main(int argc, char * argv[])
if (rsoc_buff[0] & 0x4)
printf(" Query task\n");
if (rsoc_buff[0] & 0x2)
- printf(" Target reset\n");
+ printf(" Target reset (obsolete)\n");
if (rsoc_buff[0] & 0x1)
- printf(" Wakeup\n");
+ printf(" Wakeup (obsolete)\n");
if (rsoc_buff[1] & 0x4)
printf(" Query asynchronous event\n");
if (rsoc_buff[1] & 0x2)
@@ -871,9 +938,9 @@ main(int argc, char * argv[])
printf(" QAETS=%d\n", !!(rsoc_buff[7] & 0x4));
printf(" QTSTS=%d\n", !!(rsoc_buff[7] & 0x2));
printf(" ITNRTS=%d\n", !!(rsoc_buff[7] & 0x1));
- printf(" tmf long timeout: %d (100 ms units)\n",
+ printf(" tmf long timeout: %u (100 ms units)\n",
sg_get_unaligned_be32(rsoc_buff + 8));
- printf(" tmf short timeout: %d (100 ms units)\n",
+ printf(" tmf short timeout: %u (100 ms units)\n",
sg_get_unaligned_be32(rsoc_buff + 12));
}
} else if (0 == rep_opts) { /* list all supported operation codes */
diff --git a/src/sg_read_attr.c b/src/sg_read_attr.c
index bd02a493..5083674b 100644
--- a/src/sg_read_attr.c
+++ b/src/sg_read_attr.c
@@ -34,7 +34,7 @@
* and decodes the response. Based on spc5r08.pdf
*/
-static const char * version_str = "1.00 20160207";
+static const char * version_str = "1.01 20160311";
#define MAX_RATTR_BUFF_LEN (1024 * 1024)
#define DEF_RATTR_BUFF_LEN (1024 * 8)
@@ -189,7 +189,7 @@ usage()
pr2serr("Usage: sg_read_attr [--cache] [--element=EA] [--enumerate] "
"[--filter=FL]\n"
" [--first=FAI] [--help] [--hex] [--in=FN] "
- "[--lvn-LVN]\n"
+ "[--lvn=LVN]\n"
" [--maxlen=LEN] [--partition=PN] [--quiet] "
"[--raw]\n"
" [--readonly] [--sa=SA] [--verbose] "
diff --git a/src/sg_vpd.c b/src/sg_vpd.c
index 831b0aaf..3a3cb68b 100644
--- a/src/sg_vpd.c
+++ b/src/sg_vpd.c
@@ -37,7 +37,7 @@
*/
-static const char * version_str = "1.14 20160217"; /* spc5r08 + sbc4r10 */
+static const char * version_str = "1.15 20160312"; /* spc5r08 + sbc4r10 */
/* These structures are duplicates of those of the same name in
@@ -2166,6 +2166,10 @@ decode_3party_copy_vpd(unsigned char * buff, int len, int do_hex, int verbose)
pr2serr("Third-party Copy VPD page length too short=%d\n", len);
return;
}
+ if (3 == do_hex) {
+ dStrHex((const char *)buff, len, -1);
+ return;
+ }
len -= 4;
ucp = buff + 4;
for (k = 0; k < len; k += bump, ucp += bump) {
@@ -2318,8 +2322,8 @@ decode_proto_lu_vpd(unsigned char * buff, int len, int do_hex)
int k, bump, rel_port, desc_len, proto;
unsigned char * ucp;
- if (1 == do_hex) {
- dStrHex((const char *)buff, len, 0);
+ if ((1 == do_hex) || (do_hex > 2)) {
+ dStrHex((const char *)buff, len, (1 == do_hex) ? 1 : -1);
return;
}
if (len < 4) {
@@ -2369,8 +2373,8 @@ decode_proto_port_vpd(unsigned char * buff, int len, int do_hex)
unsigned char * ucp;
unsigned char * pidp;
- if (1 == do_hex) {
- dStrHex((const char *)buff, len, 0);
+ if ((1 == do_hex) || (do_hex > 2)) {
+ dStrHex((const char *)buff, len, (1 == do_hex) ? 1 : -1);
return;
}
if (len < 4) {
@@ -2586,7 +2590,7 @@ decode_b1_vpd(unsigned char * buff, int len, int do_hex, int pdt)
}
}
-/* VPD_LB_PROVISIONING */
+/* VPD_LB_PROVISIONING 0xb2 */
static int
decode_block_lb_prov_vpd(unsigned char * b, int len, const struct opts_t * op)
{
@@ -2727,7 +2731,7 @@ decode_block_dev_char_ext_vpd(unsigned char * b, int len)
printf(" Utilization A: %u\n", sg_get_unaligned_be32(b + 12));
}
-/* VPD_LB_PROTECTION (SSC) [added in ssc5r02a] */
+/* VPD_LB_PROTECTION 0xb5 (SSC) [added in ssc5r02a] */
static void
decode_lb_protection_vpd(unsigned char * buff, int len, int do_hex)
{
@@ -2758,46 +2762,27 @@ decode_lb_protection_vpd(unsigned char * buff, int len, int do_hex)
}
}
-/* VPD_TA_SUPPORTED */
+/* VPD_TA_SUPPORTED 0xb2 */
static int
decode_tapealert_supported_vpd(unsigned char * b, int len)
{
+ int k, mod, div;
+
if (len < 12) {
pr2serr("TapeAlert supported flags length too short=%d\n", len);
return SG_LIB_CAT_MALFORMED;
}
- printf(" Flag01h: %d 02h: %d 03h: %d 04h: %d 05h: %d 06h: %d "
- "07h: %d 08h: %d\n", !!(b[4] & 0x80), !!(b[4] & 0x40),
- !!(b[4] & 0x20), !!(b[4] & 0x10), !!(b[4] & 0x8), !!(b[4] & 0x4),
- !!(b[4] & 0x2), !!(b[4] & 0x1));
- printf(" Flag09h: %d 0ah: %d 0bh: %d 0ch: %d 0dh: %d 0eh: %d "
- "0fh: %d 10h: %d\n", !!(b[5] & 0x80), !!(b[5] & 0x40),
- !!(b[5] & 0x20), !!(b[5] & 0x10), !!(b[5] & 0x8), !!(b[5] & 0x4),
- !!(b[5] & 0x2), !!(b[5] & 0x1));
- printf(" Flag11h: %d 12h: %d 13h: %d 14h: %d 15h: %d 16h: %d "
- "17h: %d 18h: %d\n", !!(b[6] & 0x80), !!(b[6] & 0x40),
- !!(b[6] & 0x20), !!(b[6] & 0x10), !!(b[6] & 0x8), !!(b[6] & 0x4),
- !!(b[6] & 0x2), !!(b[6] & 0x1));
- printf(" Flag19h: %d 1ah: %d 1bh: %d 1ch: %d 1dh: %d 1eh: %d "
- "1fh: %d 20h: %d\n", !!(b[7] & 0x80), !!(b[7] & 0x40),
- !!(b[7] & 0x20), !!(b[7] & 0x10), !!(b[7] & 0x8), !!(b[7] & 0x4),
- !!(b[7] & 0x2), !!(b[7] & 0x1));
- printf(" Flag21h: %d 22h: %d 23h: %d 24h: %d 25h: %d 26h: %d "
- "27h: %d 28h: %d\n", !!(b[8] & 0x80), !!(b[8] & 0x40),
- !!(b[8] & 0x20), !!(b[8] & 0x10), !!(b[8] & 0x8), !!(b[8] & 0x4),
- !!(b[8] & 0x2), !!(b[8] & 0x1));
- printf(" Flag29h: %d 2ah: %d 2bh: %d 2ch: %d 2dh: %d 2eh: %d "
- "2fh: %d 30h: %d\n", !!(b[9] & 0x80), !!(b[9] & 0x40),
- !!(b[9] & 0x20), !!(b[9] & 0x10), !!(b[9] & 0x8), !!(b[9] & 0x4),
- !!(b[9] & 0x2), !!(b[9] & 0x1));
- printf(" Flag31h: %d 32h: %d 33h: %d 34h: %d 35h: %d 36h: %d "
- "37h: %d 38h: %d\n", !!(b[10] & 0x80), !!(b[10] & 0x40),
- !!(b[10] & 0x20), !!(b[10] & 0x10), !!(b[10] & 0x8),
- !!(b[10] & 0x4), !!(b[10] & 0x2), !!(b[10] & 0x1));
- printf(" Flag39h: %d 3ah: %d 3bh: %d 3ch: %d 3dh: %d 3eh: %d "
- "3fh: %d 40h: %d\n", !!(b[11] & 0x80), !!(b[11] & 0x40),
- !!(b[11] & 0x20), !!(b[11] & 0x10), !!(b[11] & 0x8),
- !!(b[11] & 0x4), !!(b[11] & 0x2), !!(b[11] & 0x1));
+ for (k = 1; k < 0x41; ++k) {
+ mod = ((k - 1) % 8);
+ div = (k - 1) / 8;
+ if (0 == mod) {
+ if (div > 0)
+ printf("\n");
+ printf(" Flag%02Xh: %d", k, !! (b[4 + div] & 0x80));
+ } else
+ printf(" %02Xh: %d", k, !! (b[4 + div] & (1 << (7 - mod))));
+ }
+ printf("\n");
return 0;
}
@@ -2913,7 +2898,7 @@ decode_b5_vpd(unsigned char * b, int len, int do_hex, int pdt)
}
}
-/* VPD_ZBC_DEV_CHARS sbc or zbc */
+/* VPD_ZBC_DEV_CHARS 0xb6 sbc or zbc */
static void
decode_zbdc_vpd(unsigned char * b, int len, int do_hex)
{