aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gilbert <dgilbert@interlog.com>2022-11-04 04:22:18 +0000
committerDouglas Gilbert <dgilbert@interlog.com>2022-11-04 04:22:18 +0000
commit44e90986b1aea4296ba69198130fd37a9ffca082 (patch)
tree15068ccf61fbd3490f3acd8b99bb7bb80c97bdf2
parent6d3bd268768b83b2749c560517c18b88f222df63 (diff)
downloadsg3_utils-44e90986b1aea4296ba69198130fd37a9ffca082.tar.gz
remove archive directory (and its contents) [github.com/doug-gilbert/sg3_utils/pull/31]; more sg_logs JSON work
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@979 6180dd3e-e324-4e3e-922d-17de1ae2f315
-rw-r--r--ChangeLog3
-rw-r--r--archive/README16
-rw-r--r--archive/align_b4_memalign.c24
-rw-r--r--archive/llseek.c128
-rw-r--r--archive/llseek.h14
-rwxr-xr-xarchive/o_scsi_logging_level295
-rw-r--r--archive/sg_json_writer.c360
-rw-r--r--archive/sg_json_writer.h101
-rw-r--r--src/sg_logs.c506
-rw-r--r--src/sg_read_block_limits.c19
10 files changed, 393 insertions, 1073 deletions
diff --git a/ChangeLog b/ChangeLog
index 31fd8ad4..823fd921 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@ Each utility has its own version number, date of last change and
some description at the top of its ".c" file. All utilities in the main
directory have their own "man" pages. There is also a sg3_utils man page.
-Changelog for pre-release sg3_utils-1.48 [20221101] [svn: r978]
+Changelog for pre-release sg3_utils-1.48 [20221103] [svn: r979]
- some utilities: add experimental --json[=JO] option
- sg_z_act_query: new utility for sending either a
Zone activate or Zone query command
@@ -104,6 +104,7 @@ Changelog for pre-release sg3_utils-1.48 [20221101] [svn: r978]
- round of coverity identified issue fixes (and non-issues)
- autoconf: upgrade version 2.70 to 2.71; automake upgrade
to version 1.16.5 (from Fedora 36)
+ - remove archive directory (and its contents)
- codespell fixes
Changelog for released sg3_utils-1.47 [20211110] [svn: r919]
diff --git a/archive/README b/archive/README
deleted file mode 100644
index e0e32205..00000000
--- a/archive/README
+++ /dev/null
@@ -1,16 +0,0 @@
-The code and scripts in this directory may be removed at some later
-date. The last cleanup (i.e. purge of unused files) of this
-directory occurred between sg3_utils version 1.22 and 1.23 .
-No other code or script in this package currently uses the contents
-of this directory. The contents of this directory are not
-maintained by the author.
-
-The rescan-scsi-bus.sh script was copied long ago from
-http://www.garloff.de/kurt/linux (under the "Rescan SCSI bus"
-heading) and was later placed in this directory. Since others
-do use the version of this script found in this package then
-rescan-scsi-bus.sh was updated in sg3_utils version 1.35 and
-was moved to the scripts directory.
-
-Douglas Gilbert
-9th January 2013
diff --git a/archive/align_b4_memalign.c b/archive/align_b4_memalign.c
deleted file mode 100644
index 1cd4032d..00000000
--- a/archive/align_b4_memalign.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Code fragment of how to get a buffer from the heap that has a specific
- * alignment. The typical alignment is to a "page" whose size is often
- * 4096 bytes. */
-
- uint8_t * wrkBuff; /* will get pointer to heap allocation */
- uint8_t * wrkPos; /* will get aligned pointer within wrkBuff */
- uint32_t sz_of_aligned = 1234; /* number of aligned bytes required */
-
- int psz;
-
-#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
- psz = sysconf(_SC_PAGESIZE); /* POSIX.1 (was getpagesize()) */
-#else
- psz = 4096; /* give up, pick likely figure */
-#endif
-
-
- /* perhaps use posix_memalign() instead. Yes but not always available */
- wrkBuff = (uint8_t *)malloc(sz_of_aligned + psz);
- wrkPos = (uint8_t *)(((sg_uintptr_t)wrkBuff + psz - 1) & (~(psz - 1)));
-
-/* The disadvantage of this approach is that it needs both wrkBuff and wrkPos
- * to be held by the application. The wrkBuff is only needed for the
- * corresponding free(), all other uses should be via wrkPos. */
diff --git a/archive/llseek.c b/archive/llseek.c
deleted file mode 100644
index fcc53faa..00000000
--- a/archive/llseek.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * llseek.c -- stub calling the llseek system call
- *
- * Copyright (C) 1994 Remy Card. This file may be redistributed
- * under the terms of the GNU Public License.
- *
- * This file is borrowed from the util-linux-2.11z tarball's implementation
- * of fdisk. It allows seeks to 64 bit offsets, if supported.
- * Changed "ext2_" prefix to "llse".
- */
-
-#include "config.h"
-
-#define _XOPEN_SOURCE 500
-#define _GNU_SOURCE
-
-#include <sys/types.h>
-
-#include <errno.h>
-#include <unistd.h>
-
-#if defined(__GNUC__) || defined(HAS_LONG_LONG)
-typedef int64_t llse_loff_t;
-#else
-typedef long llse_loff_t;
-#endif
-
-extern llse_loff_t llse_llseek (unsigned int, llse_loff_t, unsigned int);
-
-#ifdef __linux__
-
-#ifdef HAVE_LLSEEK
-#include <syscall.h>
-
-#else /* HAVE_LLSEEK */
-
-#if defined(__alpha__) || defined(__ia64__) || defined(__s390x__) || defined (__x86_64__) || defined (__powerpc64__)
-
-#define my_llseek lseek
-
-#else
-#include <linux/unistd.h> /* for __NR__llseek */
-
-static int _llseek (unsigned int, unsigned long,
- unsigned long, llse_loff_t *, unsigned int);
-
-#ifdef __NR__llseek
-
-static _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high,
- unsigned long, offset_low,llse_loff_t *,result,
- unsigned int, origin)
-
-#else
-
-/* no __NR__llseek on compilation machine - might give it explicitly */
-static int _llseek (unsigned int fd, unsigned long oh,
- unsigned long ol, llse_loff_t *result,
- unsigned int origin) {
- errno = ENOSYS;
- return -1;
-}
-
-#endif
-
-static llse_loff_t my_llseek (unsigned int fd, llse_loff_t offset,
- unsigned int origin)
-{
- llse_loff_t result;
- int retval;
-
-#ifdef HAVE_LSEEK64
- return lseek64 (fd, offset, origin);
-#else
- retval = _llseek (fd, ((uint64_t) offset) >> 32,
- ((uint64_t) offset) & 0xffffffff,
- &result, origin);
- return (retval == -1 ? (llse_loff_t) retval : result);
-#endif
-}
-
-#endif /* __alpha__ */
-
-#endif /* HAVE_LLSEEK */
-
-llse_loff_t llse_llseek (unsigned int fd, llse_loff_t offset,
- unsigned int origin)
-{
- llse_loff_t result;
- static int do_compat = 0;
-
- if (!do_compat) {
- result = my_llseek (fd, offset, origin);
- if (!(result == -1 && errno == ENOSYS))
- return result;
-
- /*
- * Just in case this code runs on top of an old kernel
- * which does not support the llseek system call
- */
- do_compat = 1;
- /*
- * Now try ordinary lseek.
- */
- }
-
- if ((sizeof(off_t) >= sizeof(llse_loff_t)) ||
- (offset < ((llse_loff_t) 1 << ((sizeof(off_t)*8) -1))))
- return lseek(fd, (off_t) offset, origin);
-
- errno = EINVAL;
- return -1;
-}
-
-#else /* !linux */
-
-llse_loff_t llse_llseek (unsigned int fd, llse_loff_t offset,
- unsigned int origin)
-{
- if ((sizeof(off_t) < sizeof(llse_loff_t)) &&
- (offset >= ((llse_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
- errno = EINVAL;
- return -1;
- }
- return lseek (fd, (off_t) offset, origin);
-}
-
-#endif /* linux */
-
diff --git a/archive/llseek.h b/archive/llseek.h
deleted file mode 100644
index 61c12e43..00000000
--- a/archive/llseek.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef LLSEEK_H
-#define LLSEEK_H
-
-#if defined(__GNUC__) || defined(HAS_LONG_LONG)
-typedef int64_t llse_loff_t;
-#else
-typedef long llse_loff_t;
-#endif
-
-extern llse_loff_t llse_llseek(unsigned int fd,
- llse_loff_t offset,
- unsigned int origin);
-
-#endif
diff --git a/archive/o_scsi_logging_level b/archive/o_scsi_logging_level
deleted file mode 100755
index ecbc8277..00000000
--- a/archive/o_scsi_logging_level
+++ /dev/null
@@ -1,295 +0,0 @@
-#! /bin/bash
-###############################################################################
-# Conveniently create and set scsi logging level, show SCSI_LOG fields in human
-# readable form.
-#
-# Copyright (C) IBM Corp. 2006
-#
-# 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 of the License, or (at
-# your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-###############################################################################
-
-# Contributed by Andreas Herrmann <aherrman@de.ibm.com> 2006/08/18
-
-SCRIPTNAME="scsi_logging_level"
-
-declare -i LOG_ERROR=0
-declare -i LOG_TIMEOUT=0
-declare -i LOG_SCAN=0
-declare -i LOG_MLQUEUE=0
-declare -i LOG_MLCOMPLETE=0
-declare -i LOG_LLQUEUE=0
-declare -i LOG_LLCOMPLETE=0
-declare -i LOG_HLQUEUE=0
-declare -i LOG_HLCOMPLETE=0
-declare -i LOG_IOCTL=0
-
-declare -i LEVEL=0
-
-_ERROR_SHIFT=0
-_TIMEOUT_SHIFT=3
-_SCAN_SHIFT=6
-_MLQUEUE_SHIFT=9
-_MLCOMPLETE_SHIFT=12
-_LLQUEUE_SHIFT=15
-_LLCOMPLETE_SHIFT=18
-_HLQUEUE_SHIFT=21
-_HLCOMPLETE_SHIFT=24
-_IOCTL_SHIFT=27
-
-SET=0
-GET=0
-CREATE=0
-
-OPTS=`getopt -o hvcgsa:E:T:S:I:M:L:H: --long \
-help,version,create,get,set,all:,error:,timeout:,scan:,ioctl:,\
-midlevel:,mlqueue:,mlcomplete:,lowlevel:,llqueue:,llcomplete:,\
-highlevel:,hlqueue:,hlcomplete: -n \'$SCRIPTNAME\' -- "$@"`
-eval set -- "$OPTS"
-
-# print version info
-printversion()
-{
- cat <<EOF
-$SCRIPTNAME (s390-tools) %S390_TOOLS_VERSION%
-(C) Copyright IBM Corp. 2006
-EOF
-}
-
-# print usage and help
-printhelp()
-{
- cat <<EOF
-Usage: $SCRIPTNAME [OPTIONS]
-
-Create, get or set scsi logging level.
-
-Options:
-
- -h, --help print this help
- -v, --version print version information
- -s, --set create and set logging level as specified on
- command line
- -g, --get get current logging level and display it
- -c, --create create logging level as specified on command line
- -a, --all specify value for all SCSI_LOG fields
- -E, --error specify SCSI_LOG_ERROR
- -T, --timeout specify SCSI_LOG_TIMEOUT
- -S, --scan specify SCSI_LOG_SCAN
- -M, --midlevel specify SCSI_LOG_MLQUEUE and SCSI_LOG_MLCOMPLETE
- --mlqueue specify SCSI_LOG_MLQUEUE
- --mlcomplete specify SCSI_LOG_MLCOMPLETE
- -L, --lowlevel specify SCSI_LOG_LLQUEUE and SCSI_LOG_LLCOMPLETE
- --llqueue specify SCSI_LOG_LLQUEUE
- --llcomplete specify SCSI_LOG_LLCOMPLETE
- -H, --highlevel specify SCSI_LOG_HLQUEUE and SCSI_LOG_HLCOMPLETE
- --hlqueue specify SCSI_LOG_HLQUEUE
- --hlcomplete specify SCSI_LOG_HLCOMPLETE
- -I, --ioctl specify SCSI_LOG_IOCTL
-
-Exactly one of the options "-c", "-g" and "-s" has to be specified.
-Valid values for SCSI_LOG fields are integers from 0 to 7.
-
-Note: Several SCSI_LOG fields can be specified using several options.
-When multiple options specify same SCSI_LOG field the most specific
-option has precedence.
-
-Example: "scsi_logging_level --hlqueue 3 --hlcomplete 2 --all 1 -s" sets
-SCSI_LOG_HLQUEUE=3, SCSI_LOG_HLCOMPLETE=2 and assigns all other SCSI_LOG
-fields the value 1.
-EOF
-}
-
-check_level()
-{
-# something is wrong with the following if ... dpg 20061027
-# if [ `echo -n $1 | tr --complement [:digit:] 'a' | grep -s 'a'` ]
-# then
-# invalid_cmdline "log level '$1' out of range [0, 7]"
-# fi
-
- if [ $1 -lt 0 -o $1 -gt 7 ]
- then
- invalid_cmdline "log level '$1' out of range [0, 7]"
- fi
-}
-
-# check cmd line arguments
-check_cmdline()
-{
- while true ; do
- case "$1" in
- -a|--all) _ALL=$2; check_level $2
- shift 2;;
- -c|--create) CREATE=1;
- shift 1;;
- -g|--get) GET=1
- shift 1;;
- -h|--help) printhelp
- exit 0;;
- -s|--set) SET=1
- shift 1;;
- -v|--version) printversion
- exit 0;;
- -E|--error) _ERROR=$2; check_level $2
- shift 2;;
- -T|--timeout) _TIMEOUT=$2; check_level $2
- shift 2;;
- -S|--scan) _SCAN=$2; check_level $2
- shift 2;;
- -M|--midlevel) _ML=$2; check_level $2
- shift 2;;
- --mlqueue) _MLQUEUE=$2; check_level $2
- shift 2;;
- --mlcomplete) _MLCOMPLETE=$2; check_level $2
- shift 2;;
- -L|--lowlevel) _LL=$2; check_level $2
- shift 2;;
- --llqueue) _LLQUEUE=$2; check_level $2
- shift 2;;
- --llcomplete) _LLCOMPLETE=$2; check_level $2
- shift 2;;
- -H|--highlevel) _HL=$2; check_level $2
- shift 2;;
- --hlqueue) _HLQUEUE=$2; check_level $2
- shift 2;;
- --hlcomplete) _HLCOMPLETE=$2; check_level $2
- shift 2;;
- -I|--ioctl) _IOCTL=$2; check_level $2
- shift 2;;
- --) shift; break;;
- *) echo "Internal error!" ; exit 1;;
- esac
- done
-
- if [ -n "$*" ]
- then
- invalid_cmdline invalid parameter $*
- fi
-
- if [ $GET = "1" -a $SET = "1" ]
- then
- invalid_cmdline options \'-c\', \'-g\' and \'-s\' are mutual exclusive
- elif [ $GET = "1" -a $CREATE = "1" ]
- then
- invalid_cmdline options \'-c\', \'-g\' and \'-s\' are mutual exclusive
- elif [ $SET = "1" -a $CREATE = "1" ]
- then
- invalid_cmdline options \'-c\', \'-g\' and \'-s\' are mutual exclusive
- fi
-
- LOG_ERROR=${_ERROR:-${_ALL:-0}}
- LOG_TIMEOUT=${_TIMEOUT:-${_ALL:-0}}
- LOG_SCAN=${_SCAN:-${_ALL:-0}}
- LOG_MLQUEUE=${_MLQUEUE:-${_ML:-${_ALL:-0}}}
- LOG_MLCOMPLETE=${_MLCOMPLETE:-${_ML:-${_ALL:-0}}}
- LOG_LLQUEUE=${_LLQUEUE:-${_LL:-${_ALL:-0}}}
- LOG_LLCOMPLETE=${_LLCOMPLETE:-${_LL:-${_ALL:-0}}}
- LOG_HLQUEUE=${_HLQUEUE:-${_HL:-${_ALL:-0}}}
- LOG_HLCOMPLETE=${_HLCOMPLETE:-${_HL:-${_ALL:-0}}}
- LOG_IOCTL=${_IOCTL:-${_ALL:-0}}
-}
-
-invalid_cmdline()
-{
- echo "$SCRIPTNAME: $*"
- echo "$SCRIPTNAME: Try '$SCRIPTNAME --help' for more information."
- exit 1
-}
-
-get_logging_level()
-{
- echo "Current scsi logging level:"
- LEVEL=`sysctl -n dev.scsi.logging_level`
- if [ $? != 0 ]
- then
- echo "$SCRIPTNAME: could not read scsi logging level" \
- "(kernel probably without SCSI_LOGGING support)"
- exit 1
- fi
-}
-
-show_logging_level()
-{
- echo "dev.scsi.logging_level = $LEVEL"
-
- LOG_ERROR=$((($LEVEL>>$_ERROR_SHIFT) & 7))
- LOG_TIMEOUT=$((($LEVEL>>$_TIMEOUT_SHIFT) & 7))
- LOG_SCAN=$((($LEVEL>>$_SCAN_SHIFT) & 7))
- LOG_MLQUEUE=$((($LEVEL>>$_MLQUEUE_SHIFT) & 7))
- LOG_MLCOMPLETE=$((($LEVEL>>$_MLCOMPLETE_SHIFT) & 7))
- LOG_LLQUEUE=$((($LEVEL>>$_LLQUEUE_SHIFT) & 7))
- LOG_LLCOMPLETE=$((($LEVEL>>$_LLCOMPLETE_SHIFT) & 7))
- LOG_HLQUEUE=$((($LEVEL>>$_HLQUEUE_SHIFT) & 7))
- LOG_HLCOMPLETE=$((($LEVEL>>$_HLCOMPLETE_SHIFT) & 7))
- LOG_IOCTL=$((($LEVEL>>$_IOCTL_SHIFT) & 7))
-
- echo "SCSI_LOG_ERROR=$LOG_ERROR"
- echo "SCSI_LOG_TIMEOUT=$LOG_TIMEOUT"
- echo "SCSI_LOG_SCAN=$LOG_SCAN"
- echo "SCSI_LOG_MLQUEUE=$LOG_MLQUEUE"
- echo "SCSI_LOG_MLCOMPLETE=$LOG_MLCOMPLETE"
- echo "SCSI_LOG_LLQUEUE=$LOG_LLQUEUE"
- echo "SCSI_LOG_LLCOMPLETE=$LOG_LLCOMPLETE"
- echo "SCSI_LOG_HLQUEUE=$LOG_HLQUEUE"
- echo "SCSI_LOG_HLCOMPLETE=$LOG_HLCOMPLETE"
- echo "SCSI_LOG_IOCTL=$LOG_IOCTL"
-}
-
-set_logging_level()
-{
- echo "New scsi logging level:"
- sysctl -q -w dev.scsi.logging_level=$LEVEL
- if [ $? != 0 ]
- then
- echo "$SCRIPTNAME: could not write scsi logging level" \
- "(kernel probably without SCSI_LOGGING support)"
- exit 1
- fi
-}
-
-create_logging_level()
-{
- LEVEL=$((($LOG_ERROR & 7)<<$_ERROR_SHIFT))
- LEVEL=$(($LEVEL|(($LOG_TIMEOUT & 7)<<$_TIMEOUT_SHIFT)))
- LEVEL=$(($LEVEL|(($LOG_SCAN & 7)<<$_SCAN_SHIFT)))
- LEVEL=$(($LEVEL|(($LOG_MLQUEUE & 7)<<$_MLQUEUE_SHIFT)))
- LEVEL=$(($LEVEL|(($LOG_MLCOMPLETE & 7)<<$_MLCOMPLETE_SHIFT)))
- LEVEL=$(($LEVEL|(($LOG_LLQUEUE & 7)<<$_LLQUEUE_SHIFT)))
- LEVEL=$(($LEVEL|(($LOG_LLCOMPLETE & 7)<<$_LLCOMPLETE_SHIFT)))
- LEVEL=$(($LEVEL|(($LOG_HLQUEUE & 7)<<$_HLQUEUE_SHIFT)))
- LEVEL=$(($LEVEL|(($LOG_HLCOMPLETE & 7)<<$_HLCOMPLETE_SHIFT)))
- LEVEL=$(($LEVEL|(($LOG_IOCTL & 7)<<$_IOCTL_SHIFT)))
-}
-
-check_cmdline $*
-
-if [ $SET = "1" ]
-then
- create_logging_level
- set_logging_level
- show_logging_level
-elif [ $GET = "1" ]
-then
- get_logging_level
- show_logging_level
-elif [ $CREATE = "1" ]
-then
- create_logging_level
- show_logging_level
-else
- invalid_cmdline missing option \'-g\', \'-s\' or \'-c\'
-fi
-
diff --git a/archive/sg_json_writer.c b/archive/sg_json_writer.c
deleted file mode 100644
index bc1c7b16..00000000
--- a/archive/sg_json_writer.c
+++ /dev/null
@@ -1,360 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-2-Clause)
-/*
- * Simple streaming JSON writer
- *
- * This takes care of the annoying bits of JSON syntax like the commas
- * after elements
- *
- * Authors: Stephen Hemminger <stephen@networkplumber.org>
- *
- * Borrowed from Linux kernel [5.17.0]: tools/bpf/bpftool/json_writer.[hc]
- */
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdarg.h>
-#include <assert.h>
-#include <malloc.h>
-#include <inttypes.h>
-#include <stdint.h>
-
-#include "sg_json_writer.h"
-
-struct json_writer {
- FILE *out; /* output file */
- unsigned depth; /* nesting */
- bool pretty; /* optional whitepace */
- char sep; /* either nul or comma */
-};
-
-/* indentation for pretty print */
-static void jsonw_indent(json_writer_t *self)
-{
- unsigned i;
- for (i = 0; i < self->depth; ++i)
- fputs(" ", self->out);
-}
-
-/* end current line and indent if pretty printing */
-static void jsonw_eol(json_writer_t *self)
-{
- if (!self->pretty)
- return;
-
- putc('\n', self->out);
- jsonw_indent(self);
-}
-
-/* If current object is not empty print a comma */
-static void jsonw_eor(json_writer_t *self)
-{
- if (self->sep != '\0')
- putc(self->sep, self->out);
- self->sep = ',';
-}
-
-
-/* Output JSON encoded string */
-/* Handles C escapes, does not do Unicode */
-static void jsonw_puts(json_writer_t *self, const char *str)
-{
- putc('"', self->out);
- for (; *str; ++str)
- switch (*str) {
- case '\t':
- fputs("\\t", self->out);
- break;
- case '\n':
- fputs("\\n", self->out);
- break;
- case '\r':
- fputs("\\r", self->out);
- break;
- case '\f':
- fputs("\\f", self->out);
- break;
- case '\b':
- fputs("\\b", self->out);
- break;
- case '\\':
- fputs("\\n", self->out);
- break;
- case '"':
- fputs("\\\"", self->out);
- break;
- case '\'':
- fputs("\\\'", self->out);
- break;
- default:
- putc(*str, self->out);
- }
- putc('"', self->out);
-}
-
-/* Create a new JSON stream */
-json_writer_t *jsonw_new(FILE *f)
-{
- json_writer_t *self = malloc(sizeof(*self));
- if (self) {
- self->out = f;
- self->depth = 0;
- self->pretty = false;
- self->sep = '\0';
- }
- return self;
-}
-
-/* End output to JSON stream */
-void jsonw_destroy(json_writer_t **self_p)
-{
- json_writer_t *self = *self_p;
-
- assert(self->depth == 0);
- fputs("\n", self->out);
- fflush(self->out);
- free(self);
- *self_p = NULL;
-}
-
-void jsonw_pretty(json_writer_t *self, bool on)
-{
- self->pretty = on;
-}
-
-void jsonw_reset(json_writer_t *self)
-{
- assert(self->depth == 0);
- self->sep = '\0';
-}
-
-/* Basic blocks */
-static void jsonw_begin(json_writer_t *self, int c)
-{
- jsonw_eor(self);
- putc(c, self->out);
- ++self->depth;
- self->sep = '\0';
-}
-
-static void jsonw_end(json_writer_t *self, int c)
-{
- assert(self->depth > 0);
-
- --self->depth;
- if (self->sep != '\0')
- jsonw_eol(self);
- putc(c, self->out);
- self->sep = ',';
-}
-
-
-/* Add a JSON property name */
-void jsonw_name(json_writer_t *self, const char *name)
-{
- jsonw_eor(self);
- jsonw_eol(self);
- self->sep = '\0';
- jsonw_puts(self, name);
- putc(':', self->out);
- if (self->pretty)
- putc(' ', self->out);
-}
-
-void jsonw_vprintf_enquote(json_writer_t *self, const char *fmt, va_list ap)
-{
- jsonw_eor(self);
- putc('"', self->out);
- vfprintf(self->out, fmt, ap);
- putc('"', self->out);
-}
-
-void jsonw_printf(json_writer_t *self, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- jsonw_eor(self);
- vfprintf(self->out, fmt, ap);
- va_end(ap);
-}
-
-/* Collections */
-void jsonw_start_object(json_writer_t *self)
-{
- jsonw_begin(self, '{');
-}
-
-void jsonw_end_object(json_writer_t *self)
-{
- jsonw_end(self, '}');
-}
-
-void jsonw_start_array(json_writer_t *self)
-{
- jsonw_begin(self, '[');
-}
-
-void jsonw_end_array(json_writer_t *self)
-{
- jsonw_end(self, ']');
-}
-
-/* JSON value types */
-void jsonw_string(json_writer_t *self, const char *value)
-{
- jsonw_eor(self);
- jsonw_puts(self, value);
-}
-
-void jsonw_bool(json_writer_t *self, bool val)
-{
- jsonw_printf(self, "%s", val ? "true" : "false");
-}
-
-void jsonw_null(json_writer_t *self)
-{
- jsonw_printf(self, "null");
-}
-
-void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num)
-{
- jsonw_printf(self, fmt, num);
-}
-
-// #ifdef notused
-void jsonw_float(json_writer_t *self, double num)
-{
- jsonw_printf(self, "%g", num);
-}
-// #endif
-
-void jsonw_hu(json_writer_t *self, unsigned short num)
-{
- jsonw_printf(self, "%hu", num);
-}
-
-void jsonw_uint(json_writer_t *self, uint64_t num)
-{
- jsonw_printf(self, "%"PRIu64, num);
-}
-
-void jsonw_lluint(json_writer_t *self, unsigned long long int num)
-{
- jsonw_printf(self, "%llu", num);
-}
-
-void jsonw_int(json_writer_t *self, int64_t num)
-{
- jsonw_printf(self, "%"PRId64, num);
-}
-
-/* Basic name/value objects */
-void jsonw_string_field(json_writer_t *self, const char *prop, const char *val)
-{
- jsonw_name(self, prop);
- jsonw_string(self, val);
-}
-
-void jsonw_bool_field(json_writer_t *self, const char *prop, bool val)
-{
- jsonw_name(self, prop);
- jsonw_bool(self, val);
-}
-
-// #ifdef notused
-void jsonw_float_field(json_writer_t *self, const char *prop, double val)
-{
- jsonw_name(self, prop);
- jsonw_float(self, val);
-}
-// #endif
-
-void jsonw_float_field_fmt(json_writer_t *self,
- const char *prop,
- const char *fmt,
- double val)
-{
- jsonw_name(self, prop);
- jsonw_float_fmt(self, fmt, val);
-}
-
-void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num)
-{
- jsonw_name(self, prop);
- jsonw_uint(self, num);
-}
-
-void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num)
-{
- jsonw_name(self, prop);
- jsonw_hu(self, num);
-}
-
-void jsonw_lluint_field(json_writer_t *self,
- const char *prop,
- unsigned long long int num)
-{
- jsonw_name(self, prop);
- jsonw_lluint(self, num);
-}
-
-void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num)
-{
- jsonw_name(self, prop);
- jsonw_int(self, num);
-}
-
-void jsonw_null_field(json_writer_t *self, const char *prop)
-{
- jsonw_name(self, prop);
- jsonw_null(self);
-}
-
-#ifdef TEST
-int main(int argc, char **argv)
-{
- json_writer_t *wr = jsonw_new(stdout);
-
- jsonw_start_object(wr);
- jsonw_pretty(wr, true);
- jsonw_name(wr, "Vyatta");
- jsonw_start_object(wr);
- jsonw_string_field(wr, "url", "http://vyatta.com");
- jsonw_uint_field(wr, "downloads", 2000000ul);
- jsonw_float_field(wr, "stock", 8.16);
-
- jsonw_name(wr, "ARGV");
- jsonw_start_array(wr);
- while (--argc)
- jsonw_string(wr, *++argv);
- jsonw_end_array(wr);
-
- jsonw_name(wr, "empty");
- jsonw_start_array(wr);
- jsonw_end_array(wr);
-
- jsonw_name(wr, "NIL");
- jsonw_start_object(wr);
- jsonw_end_object(wr);
-
- jsonw_null_field(wr, "my_null");
-
- jsonw_name(wr, "special chars");
- jsonw_start_array(wr);
- jsonw_string_field(wr, "slash", "/");
- jsonw_string_field(wr, "newline", "\n");
- jsonw_string_field(wr, "tab", "\t");
- jsonw_string_field(wr, "ff", "\f");
- jsonw_string_field(wr, "quote", "\"");
- jsonw_string_field(wr, "tick", "\'");
- jsonw_string_field(wr, "backslash", "\\");
- jsonw_end_array(wr);
-
- jsonw_end_object(wr);
-
- jsonw_end_object(wr);
- jsonw_destroy(&wr);
- return 0;
-}
-
-#endif
diff --git a/archive/sg_json_writer.h b/archive/sg_json_writer.h
deleted file mode 100644
index c751ade8..00000000
--- a/archive/sg_json_writer.h
+++ /dev/null
@@ -1,101 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
-/*
- * Simple streaming JSON writer
- *
- * This takes care of the annoying bits of JSON syntax like the commas
- * after elements
- *
- * Authors: Stephen Hemminger <stephen@networkplumber.org>
- *
- * Borrowed from Linux kernel [5.17.0]: tools/bpf/bpftool/json_writer.[hc]
- */
-
-#ifndef SG_JSON_WRITER_H_
-#define SG_JSON_WRITER_H_
-
-#include <stdbool.h>
-#include <stdint.h>
-#include <stdarg.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// Need to resolve __printf(a, b) macro calls
-#if defined(__GNUC__) || defined(__clang__)
-#ifdef SG_LIB_MINGW
-/* MinGW uses Microsoft's printf */
-
-#define __printf(a, b)
-
-#else /* GNU/clang other than MinGW */
-
-#define __printf(a, b) __attribute__ ((format (printf, a, b)))
-
-#endif
-
-#else /* not GNU (and not clang) */
-
-#define __printf(a, b)
-
-#endif
-
-/* Opaque class structure */
-typedef struct json_writer json_writer_t;
-
-/* Create a new JSON stream */
-json_writer_t *jsonw_new(FILE *f);
-/* End output to JSON stream */
-void jsonw_destroy(json_writer_t **self_p);
-
-/* Cause output to have pretty whitespace */
-void jsonw_pretty(json_writer_t *self, bool on);
-
-/* Reset separator to create new JSON */
-void jsonw_reset(json_writer_t *self);
-
-/* Add property name */
-void jsonw_name(json_writer_t *self, const char *name);
-
-/* Add value */
-void __printf(2, 0) jsonw_vprintf_enquote(json_writer_t *self, const char *fmt,
- va_list ap);
-void __printf(2, 3) jsonw_printf(json_writer_t *self, const char *fmt, ...);
-void jsonw_string(json_writer_t *self, const char *value);
-void jsonw_bool(json_writer_t *self, bool value);
-void jsonw_float(json_writer_t *self, double number);
-void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num);
-void jsonw_uint(json_writer_t *self, uint64_t number);
-void jsonw_hu(json_writer_t *self, unsigned short number);
-void jsonw_int(json_writer_t *self, int64_t number);
-void jsonw_null(json_writer_t *self);
-void jsonw_lluint(json_writer_t *self, unsigned long long int num);
-
-/* Useful Combinations of name and value */
-void jsonw_string_field(json_writer_t *self, const char *prop, const char *val);
-void jsonw_bool_field(json_writer_t *self, const char *prop, bool value);
-void jsonw_float_field(json_writer_t *self, const char *prop, double num);
-void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num);
-void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num);
-void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num);
-void jsonw_null_field(json_writer_t *self, const char *prop);
-void jsonw_lluint_field(json_writer_t *self, const char *prop,
- unsigned long long int num);
-void jsonw_float_field_fmt(json_writer_t *self, const char *prop,
- const char *fmt, double val);
-
-/* Collections */
-void jsonw_start_object(json_writer_t *self);
-void jsonw_end_object(json_writer_t *self);
-
-void jsonw_start_array(json_writer_t *self);
-void jsonw_end_array(json_writer_t *self);
-
-/* Override default exception handling */
-typedef void (jsonw_err_handler_fn)(const char *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SG_JSON_WRITER_H_ */
diff --git a/src/sg_logs.c b/src/sg_logs.c
index 0a49671b..9f8f2383 100644
--- a/src/sg_logs.c
+++ b/src/sg_logs.c
@@ -37,7 +37,7 @@
#include "sg_unaligned.h"
#include "sg_pr2serr.h"
-static const char * version_str = "2.02 20221101"; /* spc6r06 + sbc5r03 */
+static const char * version_str = "2.04 20221103"; /* spc6r06 + sbc5r03 */
#define MY_NAME "sg_logs"
@@ -124,9 +124,10 @@ static const int parr_sz = 4096;
static const char * unknown_s = "unknown";
static const char * not_avail = "not available";
-static const char * param_c = "parameter code";
+static const char * param_c = "Parameter code";
static const char * param_c_snake = "parameter_code";
static const char * as_s_s = "as_string";
+static const char * restricted_s = "restricted";
static struct option long_options[] = {
{"All", no_argument, 0, 'A'}, /* equivalent to '-aa' */
@@ -192,6 +193,7 @@ struct opts_t {
int do_hex;
int do_list;
int dstrhex_no_ascii; /* value for dStrHex() no_ascii argument */
+ int hex2str_oformat; /* value for hex2str() oformat argument */
int vend_prod_num; /* one of the VP_* constants or -1 (def) */
int deduced_vpn; /* deduced vendor_prod_num; from INQUIRY, etc */
int verbose;
@@ -953,18 +955,21 @@ pg_subpg_pdt_search(int pg_code, int subpg_code, int pdt, int vpn)
}
static void
-js_snakenv_ihexstr_nex(sgj_state * jsp, sgj_opaque_p jop, const char * name,
- int64_t val_i, bool hex_as_well, const char * str_name,
+js_snakenv_ihexstr_nex(sgj_state * jsp, sgj_opaque_p jop,
+ const char * conv2sname, int64_t val_i,
+ bool hex_as_well, const char * str_name,
const char * val_s, const char * nex_s)
{
- if (sgj_is_snake_name(name))
- sgj_js_nv_ihexstr_nex(jsp, jop, name, val_i, hex_as_well, str_name,
- val_s, nex_s);
+ if ((NULL == jsp) || (NULL == jop))
+ return;
+ if (sgj_is_snake_name(conv2sname))
+ sgj_js_nv_ihexstr_nex(jsp, jop, conv2sname, val_i, hex_as_well,
+ str_name, val_s, nex_s);
else {
char b[128];
- sgj_convert_to_snake_name(name, b, sizeof(b));
+ sgj_convert_to_snake_name(conv2sname, b, sizeof(b));
sgj_js_nv_ihexstr_nex(jsp, jop, b, val_i, hex_as_well, str_name,
val_s, nex_s);
}
@@ -2115,14 +2120,26 @@ show_non_medium_error_page(const uint8_t * resp, int len,
bool skip_out = false;
bool evsm_output = false;
int num, pl, pc;
+ uint64_t count;
const uint8_t * bp;
+ sgj_state * jsp = &op->json_st;
+ sgj_opaque_p jo2p;
+ sgj_opaque_p jo3p = NULL;
+ sgj_opaque_p jap = NULL;
char str[PCB_STR_LEN];
+ char b[128] SG_C_CPP_ZERO_INIT;
+ static const char * nmelp = "Non-medium error log page";
+ static const char * nmec = "Non-medium error count";
-if (jop) { };
if (op->verbose || ((! op->do_raw) && (0 == op->do_hex)))
- printf("Non-medium error page [0x6]\n");
+ sgj_pr_hr(jsp, "%s [0x6]\n", nmelp);
num = len - 4;
bp = &resp[0] + 4;
+ if (jsp->pr_as_json) {
+ jo2p = sg_log_js_hdr(jsp, jop, nmelp, resp);
+ jap = sgj_named_subarray_r(jsp, jo2p,
+ "non_medium_error_log_parameters");
+ }
while (num > 3) {
pc = sg_get_unaligned_be16(bp + 0);
pl = bp[3] + 4;
@@ -2137,35 +2154,47 @@ if (jop) { };
hex2stdout(bp, pl, op->dstrhex_no_ascii);
break;
}
+ if (jsp->pr_as_json) {
+ jo3p = sgj_new_unattached_object_r(jsp);
+ if (op->do_pcb)
+ js_pcb(jsp, jo3p, bp[2]);
+ }
+
switch (pc) {
case 0:
- printf(" Non-medium error count");
+ snprintf(b, sizeof(b), "%s", nmec);
break;
default:
if (pc <= 0x7fff)
- printf(" Reserved [0x%x]", pc);
+ snprintf(b, sizeof(b), " Reserved [0x%x]", pc);
else {
if (op->exclude_vendor) {
skip_out = true;
if ((op->verbose > 0) && (0 == op->do_brief) &&
(! evsm_output)) {
evsm_output = true;
- printf(" Vendor specific parameter(s) being "
- "ignored\n");
+ pr2serr(" Vendor specific parameter(s) being "
+ "ignored\n");
}
} else
- printf(" Vendor specific [0x%x]", pc);
+ snprintf(b, sizeof(b), "Vendor specific [0x%x]", pc);
}
break;
}
if (skip_out)
skip_out = false;
else {
- printf(" = %" PRIu64 "", sg_get_unaligned_be(pl - 4, bp + 4));
- printf("\n");
+ count = sg_get_unaligned_be(pl - 4, bp + 4);
+ sgj_pr_hr(jsp, " %s = %" PRIu64 "\n", b, count);
+ js_snakenv_ihexstr_nex(jsp, jo3p, param_c, pc, true,
+ NULL, b, NULL);
+ sgj_js_nv_ihex(jsp, jo3p, nmec, count);
}
if (op->do_pcb)
- printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
+ sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2],
+ str, sizeof(str)));
+ if (jsp->pr_as_json)
+ sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p);
if (op->filter_given)
break;
skip:
@@ -2181,14 +2210,27 @@ show_power_condition_transitions_page(const uint8_t * resp, int len,
struct opts_t * op, sgj_opaque_p jop)
{
int num, pl, pc;
+ uint64_t count;
const uint8_t * bp;
+ const char * cp;
+ sgj_state * jsp = &op->json_st;
+ sgj_opaque_p jo2p;
+ sgj_opaque_p jo3p = NULL;
+ sgj_opaque_p jap = NULL;
char str[PCB_STR_LEN];
+ char b[80];
+ static const char * pctlp = "Power condition transitions log page";
-if (jop) { };
if (op->verbose || ((! op->do_raw) && (0 == op->do_hex)))
- printf("Power condition transitions page [0x1a]\n");
+ sgj_pr_hr(jsp, "%s [0x1a]\n", pctlp);
num = len - 4;
bp = &resp[0] + 4;
+ if (jsp->pr_as_json) {
+ jo2p = sg_log_js_hdr(jsp, jop, pctlp, resp);
+ jap = sgj_named_subarray_r(jsp, jo2p,
+ "power_condition_transition_log_parameters");
+ }
+
while (num > 3) {
pc = sg_get_unaligned_be16(bp + 0);
pl = bp[3] + 4;
@@ -2203,26 +2245,44 @@ if (jop) { };
hex2stdout(bp, pl, op->dstrhex_no_ascii);
break;
}
+ if (jsp->pr_as_json) {
+ jo3p = sgj_new_unattached_object_r(jsp);
+ if (op->do_pcb)
+ js_pcb(jsp, jo3p, bp[2]);
+ }
+
+ cp = NULL;
switch (pc) {
case 1:
- printf(" Accumulated transitions to active"); break;
+ cp = "Accumulated transitions to active";
+ break;
case 2:
- printf(" Accumulated transitions to idle_a"); break;
+ cp = "Accumulated transitions to idle_a";
+ break;
case 3:
- printf(" Accumulated transitions to idle_b"); break;
+ cp = "Accumulated transitions to idle_b";
+ break;
case 4:
- printf(" Accumulated transitions to idle_c"); break;
+ cp = "Accumulated transitions to idle_c";
+ break;
case 8:
- printf(" Accumulated transitions to standby_z"); break;
+ cp = "Accumulated transitions to standby_z";
+ break;
case 9:
- printf(" Accumulated transitions to standby_y"); break;
+ cp = "Accumulated transitions to standby_y";
+ break;
default:
- printf(" Reserved [0x%x]", pc);
+ snprintf(b, sizeof(b), "Reserved [0x%x]", pc);
+ cp = b;
+ break;
}
- printf(" = %" PRIu64 "", sg_get_unaligned_be(pl - 4, bp + 4));
- printf("\n");
+ count = sg_get_unaligned_be(pl - 4, bp + 4);
+ sgj_pr_hr(jsp, " %s = %" PRIu64 "\n", cp, count);
if (op->do_pcb)
- printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
+ sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2],
+ str, sizeof(str)));
+ if (jsp->pr_as_json)
+ sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p);
if (op->filter_given)
break;
skip:
@@ -2589,20 +2649,45 @@ skip:
return true;
}
-/* CMD_DUR_LIMITS_SUBPG [0x19,0x21] <cdl> introduced: SPC-6 (rev 01) */
+/* CMD_DUR_LIMITS_SUBPG [0x19,0x21] <cdl>
+ * introduced: SPC-6 rev 1, significantly changed rev 6 */
static bool
show_cmd_dur_limits_page(const uint8_t * resp, int len,
struct opts_t * op, sgj_opaque_p jop)
{
int num, pl, pc;
+ uint32_t count, noitmc_v, noatmc_v, noitatmc_v, noc_v;
const uint8_t * bp;
+ const char * cp;
+ const char * thp;
+ sgj_state * jsp = &op->json_st;
+ sgj_opaque_p jo2p;
+ sgj_opaque_p jo3p = NULL;
+ sgj_opaque_p jap = NULL;
char str[PCB_STR_LEN];
+ char b[144];
+ static const char * cdllp = "Command duration limits statistics log page";
+ static const char * t2cdld = "T2 command duration limit descriptor";
+ static const char * cdlt2amp = "CDL T2A mode page";
+ static const char * cdlt2bmp = "CDL T2B mode page";
+ static const char * first_7[] = {"First", "Second", "Third", "Fourth",
+ "Fifth", "Sixth", "Seventh"};
+ static const char * noitmc = "Number of inactive target miss commands";
+ static const char * noatmc = "Number of active target miss commands";
+ static const char * noitatmc =
+ "Number of inactive target and active target miss commands";
+ static const char * noc = "Number of commands";
-if (jop) { };
if (op->verbose || ((! op->do_raw) && (0 == op->do_hex)))
- printf("Command duration limits page [0x19,0x21]\n");
+ sgj_pr_hr(jsp, "%s [0x19,0x21]\n", cdllp);
num = len - 4;
bp = &resp[0] + 4;
+ if (jsp->pr_as_json) {
+ jo2p = sg_log_js_hdr(jsp, jop, cdllp, resp);
+ jap = sgj_named_subarray_r(jsp, jo2p,
+ "command_duration_limits_statistcs_log_parameters");
+ }
+
while (num > 3) {
pc = sg_get_unaligned_be16(bp + 0);
pl = bp[3] + 4; /* parameter length */
@@ -2617,10 +2702,24 @@ if (jop) { };
hex2stdout(bp, pl, op->dstrhex_no_ascii);
break;
}
+ if (jsp->pr_as_json) {
+ jo3p = sgj_new_unattached_object_r(jsp);
+ if (op->do_pcb)
+ js_pcb(jsp, jo3p, bp[2]);
+ }
+
switch (pc) {
case 0x1:
- printf(" Number of READ commands = %" PRIu64 "\n",
- sg_get_unaligned_be64(bp + 4));
+ /* spc6r06: table 349 name "Number of READ commands" seems to
+ * be wrong. Use what surrounding text and table 347 suggest */
+ cp = "Achievable latency target";
+ count = sg_get_unaligned_be32(bp + 4);
+ sgj_pr_hr(jsp, " %s = %" PRIu32 "\n", cp, count);
+ if (jsp->pr_as_json) {
+ sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, cp);
+ js_snakenv_ihexstr_nex(jsp, jop, cp, count, true, NULL, NULL,
+ "unit: microsecond");
+ }
break;
case 0x11:
case 0x12:
@@ -2629,6 +2728,11 @@ if (jop) { };
case 0x15:
case 0x16:
case 0x17:
+ sgj_pr_hr(jsp, " parameter code 0x%x restricted\n", pc);
+ if (jsp->pr_as_json)
+ sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL,
+ restricted_s);
+ break;
case 0x21:
case 0x22:
case 0x23:
@@ -2636,25 +2740,30 @@ if (jop) { };
case 0x25:
case 0x26:
case 0x27:
- printf(" Command duration limit T2%s %d [Parameter code 0x%x]:\n",
- ((pc > 0x20) ? "B" : "A"),
- ((pc > 0x20) ? (pc - 0x20) : (pc - 0x10)), pc);
- printf(" Number of inactive target miss commands = %u\n",
- sg_get_unaligned_be32(bp + 4));
- printf(" Number of active target miss commands = %u\n",
- sg_get_unaligned_be32(bp + 8));
- printf(" Number of latency miss commands = %u\n",
- sg_get_unaligned_be32(bp + 12));
- printf(" Number of nonconforming miss commands = %u\n",
- sg_get_unaligned_be32(bp + 16));
- printf(" Number of predictive latency miss commands = %u\n",
- sg_get_unaligned_be32(bp + 20));
- printf(" Number of latency misses attributable to errors = %u\n",
- sg_get_unaligned_be32(bp + 24));
- printf(" Number of latency misses attributable to deferred "
- "errors = %u\n", sg_get_unaligned_be32(bp + 28));
- printf(" Number of latency misses attributable to background "
- "operations = %u\n", sg_get_unaligned_be32(bp + 32));
+ thp = first_7[pc - 0x21];
+ sgj_pr_hr(jsp, " %s %s for %s [pc=0x%x]:\n", thp, t2cdld,
+ cdlt2amp, pc);
+ noitmc_v = sg_get_unaligned_be32(bp + 4);
+ sgj_pr_hr(jsp, " %s = %u\n", noitmc, noitmc_v);
+ noatmc_v = sg_get_unaligned_be32(bp + 8);
+ sgj_pr_hr(jsp, " %s = %u\n", noatmc, noatmc_v);
+ noitatmc_v = sg_get_unaligned_be32(bp + 12);
+ sgj_pr_hr(jsp, " %s = %u\n", noitatmc, noitatmc_v);
+ noc_v = sg_get_unaligned_be32(bp + 16);
+ sgj_pr_hr(jsp, " %s = %u\n", noc, noc_v);
+ if (jsp->pr_as_json) {
+ snprintf(b, sizeof(b), "%s %s for %s", thp, t2cdld, cdlt2amp);
+ sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, b);
+
+ js_snakenv_ihexstr_nex(jsp, jop, noitmc, noitmc_v, true, NULL,
+ NULL, NULL);
+ js_snakenv_ihexstr_nex(jsp, jop, noatmc, noatmc_v, true, NULL,
+ NULL, NULL);
+ js_snakenv_ihexstr_nex(jsp, jop, noitatmc, noitatmc_v, true,
+ NULL, NULL, NULL);
+ js_snakenv_ihexstr_nex(jsp, jop, noc, noc_v, true, NULL,
+ NULL, NULL);
+ }
break;
case 0x31:
case 0x32:
@@ -2663,6 +2772,11 @@ if (jop) { };
case 0x35:
case 0x36:
case 0x37:
+ sgj_pr_hr(jsp, " parameter code 0x%x restricted\n", pc);
+ if (jsp->pr_as_json)
+ sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL,
+ restricted_s);
+ break;
case 0x41:
case 0x42:
case 0x43:
@@ -2671,24 +2785,41 @@ if (jop) { };
case 0x46:
case 0x47:
/* This short form introduced in draft spc6r06 */
- printf(" Command duration limit T2%s %d [Parameter code 0x%x]:\n",
- ((pc > 0x40) ? "B" : "A"),
- ((pc > 0x40) ? (pc - 0x40) : (pc - 0x30)), pc);
- printf(" Number of inactive target miss commands = %u\n",
- sg_get_unaligned_be32(bp + 4));
- printf(" Number of active target miss commands = %u\n",
- sg_get_unaligned_be32(bp + 8));
- printf(" Number of inactive+active target miss commands = %u\n",
- sg_get_unaligned_be32(bp + 12));
- printf(" Number of commands = %u\n",
- sg_get_unaligned_be32(bp + 16));
+ thp = first_7[pc - 0x41];
+ sgj_pr_hr(jsp, " %s %s for %s [pc=0x%x]:\n", thp, t2cdld,
+ cdlt2bmp, pc);
+ noitmc_v = sg_get_unaligned_be32(bp + 4);
+ sgj_pr_hr(jsp, " %s = %u\n", noitmc, noitmc_v);
+ noatmc_v = sg_get_unaligned_be32(bp + 8);
+ sgj_pr_hr(jsp, " %s = %u\n", noatmc, noatmc_v);
+ noitatmc_v = sg_get_unaligned_be32(bp + 12);
+ sgj_pr_hr(jsp, " %s = %u\n", noitatmc, noitatmc_v);
+ noc_v = sg_get_unaligned_be32(bp + 16);
+ sgj_pr_hr(jsp, " %s = %u\n", noc, noc_v);
+ if (jsp->pr_as_json) {
+ snprintf(b, sizeof(b), "%s %s for %s", thp, t2cdld, cdlt2amp);
+ sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, b);
+
+ js_snakenv_ihexstr_nex(jsp, jop, noitmc, noitmc_v, true, NULL,
+ NULL, NULL);
+ js_snakenv_ihexstr_nex(jsp, jop, noatmc, noatmc_v, true, NULL,
+ NULL, NULL);
+ js_snakenv_ihexstr_nex(jsp, jop, noitatmc, noitatmc_v, true,
+ NULL, NULL, NULL);
+ js_snakenv_ihexstr_nex(jsp, jop, noc, noc_v, true, NULL,
+ NULL, NULL);
+ }
+
break;
default:
- printf(" <<unexpected parameter code 0x%x\n", pc);
+ sgj_pr_hr(jsp, " <<unexpected parameter code 0x%x\n", pc);
break;
}
if (op->do_pcb)
- printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
+ sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2],
+ str, sizeof(str)));
+ if (jsp->pr_as_json)
+ sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p);
if (op->filter_given)
break;
skip:
@@ -3059,22 +3190,33 @@ show_last_n_error_page(const uint8_t * resp, int len,
{
int k, num, pl;
const uint8_t * bp;
+ sgj_state * jsp = &op->json_st;
+ sgj_opaque_p jo2p;
+ sgj_opaque_p jo3p = NULL;
+ sgj_opaque_p jap = NULL;
char str[PCB_STR_LEN];
+ char b[256];
+ static const char * lneelp = "Last n error events log page";
+ static const char * eed = "error_event_data";
-if (jop) { };
num = len - 4;
bp = &resp[0] + 4;
if (num < 4) {
- printf("No error events logged\n");
+ sgj_pr_hr(jsp, "No error events logged\n");
return true;
}
if (op->verbose || ((! op->do_raw) && (0 == op->do_hex)))
- printf("Last n error events page [0x7]\n");
+ sgj_pr_hr(jsp, "%s [0x7]\n", lneelp);
+ if (jsp->pr_as_json) {
+ jo2p = sg_log_js_hdr(jsp, jop, lneelp, resp);
+ jap = sgj_named_subarray_r(jsp, jo2p, "error_event_log_parameters");
+ }
+
for (k = num; k > 0; k -= pl, bp += pl) {
- int pc;
+ uint16_t pc;
if (k < 3) {
- printf("short Last n error events page\n");
+ pr2serr("short %s\n", lneelp);
return false;
}
pl = bp[3] + 4;
@@ -3090,20 +3232,42 @@ if (jop) { };
hex2stdout(bp, pl, op->dstrhex_no_ascii);
break;
}
- printf(" Error event %d:\n", pc);
+ if (jsp->pr_as_json) {
+ jo3p = sgj_new_unattached_object_r(jsp);
+ if (op->do_pcb)
+ js_pcb(jsp, jo3p, bp[2]);
+ sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, NULL);
+ }
+
+ sgj_pr_hr(jsp, " Error event %u [0x%x]:\n", pc, pc);
if (pl > 4) {
if ((bp[2] & 0x1) && (bp[2] & 0x2)) {
- printf(" [binary]:\n");
- hex2stdout(bp + 4, pl - 4, op->dstrhex_no_ascii);
- } else if (0x01 == (bp[2] & 0x3) /* ASCII */)
- printf(" %.*s\n", pl - 4, (const char *)(bp + 4));
- else {
- printf(" [data counter?? (LP bit should be set)]:\n");
- hex2stdout(bp + 4, pl - 4, op->dstrhex_no_ascii);
+ sgj_pr_hr(jsp, " [binary]:\n");
+ hex2str(bp + 4, pl - 4, " ", op->hex2str_oformat,
+ sizeof(b), b);
+ sgj_pr_hr(jsp, "%s\n", b);
+ if (jsp->pr_as_json)
+ sgj_js_nv_hex_bytes(jsp, jo3p, eed, bp + 4, pl - 4);
+ } else if (0x01 == (bp[2] & 0x3)) { /* ASCII */
+ sgj_pr_hr(jsp, " %.*s\n", pl - 4, (const char *)(bp + 4));
+ if (jsp->pr_as_json)
+ sgj_js_nv_s_len(jsp, jo3p, eed,
+ (const char *)(bp + 4), pl - 4);
+ } else {
+ sgj_pr_hr(jsp, " [data counter?? (LP bit should be "
+ "set)]:\n");
+ hex2str(bp + 4, pl - 4, " ", op->hex2str_oformat,
+ sizeof(b), b);
+ sgj_pr_hr(jsp, "%s\n", b);
+ if (jsp->pr_as_json)
+ sgj_js_nv_hex_bytes(jsp, jo3p, eed, bp + 4, pl - 4);
}
}
if (op->do_pcb)
- printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
+ sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2],
+ str, sizeof(str)));
+ if (jsp->pr_as_json)
+ sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p);
if (op->filter_given)
break;
}
@@ -3117,23 +3281,37 @@ show_last_n_deferred_error_page(const uint8_t * resp, int len,
{
int k, n, num, pl;
const uint8_t * bp;
+ sgj_state * jsp = &op->json_st;
+ sgj_opaque_p jo2p, jo4p;
+ sgj_opaque_p jo3p = NULL;
+ sgj_opaque_p jap = NULL;
char str[PCB_STR_LEN];
+ char b[512];
+ static const char * lndeoaelp =
+ "Last n deferred errors or asynchronous events log page";
+ static const char * deoae = "Deferred error or asynchronous event";
+ static const char * sd = "sense_data";
-if (jop) { };
num = len - 4;
bp = &resp[0] + 4;
if (num < 4) {
- printf("No deferred errors logged\n");
+ pr2serr("No deferred errors logged\n");
return true;
}
if (op->verbose || ((! op->do_raw) && (0 == op->do_hex)))
- printf("Last n deferred errors page [0xb]\n");
+ sgj_pr_hr(jsp, "%s [0xb]\n", lndeoaelp);
+ if (jsp->pr_as_json) {
+ jo2p = sg_log_js_hdr(jsp, jop, lndeoaelp, resp);
+ jap = sgj_named_subarray_r(jsp, jo2p,
+ "deferred_error_or_asynchronous_event_log_parameters");
+ }
+
for (k = num; k > 0; k -= pl, bp += pl) {
int pc;
if (k < 3) {
- printf("short Last n deferred errors page\n");
- return true;
+ pr2serr("short %s\n", lndeoaelp);
+ return false;
}
pl = bp[3] + 4;
pc = sg_get_unaligned_be16(bp + 0);
@@ -3148,18 +3326,35 @@ if (jop) { };
hex2stdout(bp, pl, op->dstrhex_no_ascii);
break;
}
- printf(" Deferred error [0x%x]:\n", pc);
- if (op->do_brief > 0)
+ if (jsp->pr_as_json) {
+ jo3p = sgj_new_unattached_object_r(jsp);
+ if (op->do_pcb)
+ js_pcb(jsp, jo3p, bp[2]);
+ sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL, deoae);
+ }
+ sgj_pr_hr(jsp, " %s [0x%x]:\n", deoae, pc);
+ if (op->do_brief > 0) {
hex2stdout(bp + 4, pl - 4, op->dstrhex_no_ascii);
- else {
- char b[512];
+ hex2str(bp + 4, pl - 4, " ", op->hex2str_oformat,
+ sizeof(b), b);
+ sgj_pr_hr(jsp, "%s\n", b);
+ if (jsp->pr_as_json)
+ sgj_js_nv_hex_bytes(jsp, jo3p, sd, bp + 4, pl - 4);
+ } else {
n = sg_get_sense_str(" ", bp + 4, pl - 4, false, sizeof(b),
b);
- printf("%.*s\n", n, b);
+ sgj_pr_hr(jsp, "%.*s\n", n, b);
+ if (jsp->pr_as_json) {
+ jo4p = sgj_named_subobject_r(jsp, jo3p, sd);
+ sgj_js_sense(jsp, jo4p, bp + 4, pl - 4);
+ }
}
if (op->do_pcb)
- printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
+ sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2],
+ str, sizeof(str)));
+ if (jsp->pr_as_json)
+ sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p);
if (op->filter_given)
break;
}
@@ -3171,16 +3366,33 @@ static bool
show_last_n_inq_data_ch_page(const uint8_t * resp, int len,
struct opts_t * op, sgj_opaque_p jop)
{
- int j, num, pl;
- unsigned int k;
+ bool vpd;
+ int j, num, pl, vpd_pg;
+ uint32_t k, n;
const uint8_t * bp;
+ const char * vpd_pg_name = NULL;
+ sgj_state * jsp = &op->json_st;
+ sgj_opaque_p jo2p, jo4p;
+ sgj_opaque_p jo3p = NULL;
+ sgj_opaque_p jap = NULL;
+ sgj_opaque_p ja2p;
char str[PCB_STR_LEN];
+ char b[128];
+ static const char * lnidclp = "Last n inquiry data changed log page";
+ static const char * clgc = "Change list generation code";
+ static const char * idci = "Inquiry data changed indicator";
+ static const char * cgn = "Changed generation number";
-if (jop) { };
if (op->verbose || ((! op->do_raw) && (0 == op->do_hex)))
- printf("Last n Inquiry data changed [0xb,0x1]\n");
+ sgj_pr_hr(jsp, "%s [0xb,0x1]\n", lnidclp);
num = len - 4;
bp = &resp[0] + 4;
+ if (jsp->pr_as_json) {
+ jo2p = sg_log_js_hdr(jsp, jop, lnidclp, resp);
+ jap = sgj_named_subarray_r(jsp, jo2p,
+ "inquiry_data_changed_log_parameters");
+ }
+
while (num > 3) {
int pc = sg_get_unaligned_be16(bp + 0);
@@ -3196,42 +3408,75 @@ if (jop) { };
hex2stdout(bp, pl, op->dstrhex_no_ascii);
break;
}
+ if (jsp->pr_as_json) {
+ jo3p = sgj_new_unattached_object_r(jsp);
+ if (op->do_pcb)
+ js_pcb(jsp, jo3p, bp[2]);
+ sgj_js_nv_ihexstr(jsp, jo3p, param_c_snake, pc, NULL,
+ 0 == pc ? clgc : idci);
+ }
if (0 == pc) {
if (pl < 8) {
- printf(" <<expect parameter 0x%x to be at least 8 bytes "
- "long, got %d, skip>>\n", pc, pl);
+ pr2serr(" <<expect parameter 0x%x to be at least 8 bytes "
+ "long, got %d, skip>>\n", pc, pl);
goto skip;
}
- printf(" Change list generation code [pc=0x0]:\n");
- for (j = 4, k = 1; j < pl; j +=4, ++k)
- printf(" Changed generation number [0x%x]: %u\n", k,
- sg_get_unaligned_be32(bp + j));
+ sgj_pr_hr(jsp, " %s [pc=0x0]:\n", clgc);
+ for (j = 4, k = 1; j < pl; j +=4, ++k) {
+ n = sg_get_unaligned_be32(bp + j);
+ sgj_pr_hr(jsp, " %s [0x%x]: %u\n", cgn, k, n);
+ }
+ if (jsp->pr_as_json) {
+ ja2p = sgj_named_subarray_r(jsp, jo3p,
+ "changed_generation_numbers");
+ for (j = 4, k = 1; j < pl; j +=4, ++k) {
+ jo4p = sgj_new_unattached_object_r(jsp);
+ n = sg_get_unaligned_be32(bp + j);
+ js_snakenv_ihexstr_nex(jsp, jo4p, cgn, n, true, NULL,
+ NULL, NULL);
+ sgj_js_nv_o(jsp, ja2p, NULL /* name */, jo4p);
+ }
+ }
} else {
- printf(" Parameter code 0x%x, ", pc);
- if (1 & *(bp + 4)) { /* VPD bit set */
- int vpd = *(bp + 5);
- printf("VPD page 0x%x changed\n", vpd);
+ int m;
+ const int nn = sg_lib_names_mode_len;
+ struct sg_lib_simple_value_name_t * nvp = sg_lib_names_vpd_arr;
+
+ snprintf(b, sizeof(b), " %s 0x%x, ", param_c, pc);
+ vpd = !! (1 & *(bp + 4));
+ vpd_pg = *(bp + 5);
+ if (vpd) {
+ for (m = 0; m < nn; ++m, ++nvp) {
+ if (nvp->value == vpd_pg)
+ break;
+ }
+ vpd_pg_name = (m < nn) ? nvp->name : NULL;
+ } else
+ vpd_pg_name = "Standard INQUIRY";
+
+ if (jsp->pr_as_json) {
+ sgj_js_nv_i(jsp, jo3p, "vpd", (int)vpd);
+ sgj_js_nv_ihex(jsp, jo3p, "changed_page_code", vpd_pg);
+ if (vpd_pg_name)
+ sgj_js_nv_s(jsp, jo3p, "changed_page_name", vpd_pg_name);
+ }
+ if (vpd) {
+ sgj_pr_hr(jsp, "%sVPD page 0x%x changed\n", b, vpd_pg);
if (0 == op->do_brief) {
- int m;
- const int nn = sg_lib_names_mode_len;
- struct sg_lib_simple_value_name_t * nvp =
- sg_lib_names_vpd_arr;
-
- for (m = 0; m < nn; ++m, ++nvp) {
- if (nvp->value == vpd)
- break;
- }
- if (m < nn)
- printf(" name: %s\n", nvp->name);
+ if (vpd_pg_name)
+ sgj_pr_hr(jsp, " name: %s\n", vpd_pg_name);
}
} else
- printf("Standard Inquiry data changed\n");
+ sgj_pr_hr(jsp, "%sStandard INQUIRY data changed\n", b);
}
if (op->do_pcb)
- printf(" <%s>\n", get_pcb_str(bp[2], str, sizeof(str)));
+ sgj_pr_hr(jsp, " <%s>\n", get_pcb_str(bp[2],
+ str, sizeof(str)));
+skip:
+ if (jsp->pr_as_json)
+ sgj_js_nv_o(jsp, jap, NULL /* name */, jo3p);
if (op->filter_given)
break;
-skip:
num -= pl;
bp += pl;
}
@@ -3247,6 +3492,7 @@ show_last_n_mode_pg_data_ch_page(const uint8_t * resp, int len,
const uint8_t * bp;
char str[PCB_STR_LEN];
+// yyyyyyyyy
if (jop) { };
if (op->verbose || ((! op->do_raw) && (0 == op->do_hex)))
printf("Last n Mode page data changed [0xb,0x2]\n");
@@ -7739,18 +7985,26 @@ main(int argc, char * argv[])
return 0;
}
if (op->do_hex > 0) {
- if (op->do_hex > 2)
+ if (op->do_hex > 2) {
op->dstrhex_no_ascii = -1;
- else
+ op->hex2str_oformat = 1;
+ } else {
op->dstrhex_no_ascii = (1 == op->do_hex);
+ op->hex2str_oformat = (1 == op->do_hex);
+ }
} else {
if (op->undefined_hex > 0) {
- if (op->undefined_hex > 2)
+ if (op->undefined_hex > 2) {
op->dstrhex_no_ascii = -1;
- else
+ op->hex2str_oformat = 1;
+ } else {
op->dstrhex_no_ascii = (1 == op->undefined_hex);
- } else /* default when no --hex nor --undefined */
+ op->hex2str_oformat = (1 == op->undefined_hex);
+ }
+ } else { /* default when no --hex nor --undefined */
op->dstrhex_no_ascii = -1;
+ op->hex2str_oformat = 1;
+ }
}
vb = op->verbose;
if (op->vend_prod) {
@@ -8182,7 +8436,7 @@ err_out:
}
if (as_json) {
if (0 == op->do_hex)
- sgj_js2file(jsp, NULL, res, stdout);
+ sgj_js2file(jsp, NULL, ret, stdout);
sgj_finish(jsp);
}
return (ret >= 0) ? ret : SG_LIB_CAT_OTHER;
diff --git a/src/sg_read_block_limits.c b/src/sg_read_block_limits.c
index 3ffa1dc2..4fc1fae6 100644
--- a/src/sg_read_block_limits.c
+++ b/src/sg_read_block_limits.c
@@ -37,7 +37,9 @@
static const char * version_str = "1.09 20221101";
-#define MAX_READ_BLOCK_LIMITS_LEN 20
+#define DEF_READ_BLOCK_LIMITS_LEN 6
+#define MLIO_READ_BLOCK_LIMITS_LEN 20
+#define MAX_READ_BLOCK_LIMITS_LEN MLIO_READ_BLOCK_LIMITS_LEN
static uint8_t readBlkLmtBuff[MAX_READ_BLOCK_LIMITS_LEN];
@@ -191,7 +193,8 @@ main(int argc, char * argv[])
goto the_end2;
}
- max_resp_len = do_mloi ? 20 : 6;
+ max_resp_len = do_mloi ? MLIO_READ_BLOCK_LIMITS_LEN :
+ DEF_READ_BLOCK_LIMITS_LEN;
memset(readBlkLmtBuff, 0x0, sizeof(readBlkLmtBuff));
res = sg_ll_read_block_limits_v2(sg_fd, do_mloi, readBlkLmtBuff,
max_resp_len, &resid, true, verbose);
@@ -213,9 +216,9 @@ main(int argc, char * argv[])
}
if (do_mloi) {
- if (actual_len < 20) {
- pr2serr("Expected at least 20 bytes in response but only "
- "%d bytes\n", actual_len);
+ if (actual_len < MLIO_READ_BLOCK_LIMITS_LEN) {
+ pr2serr("Expected at least %d bytes in response but only "
+ "%d bytes\n", MLIO_READ_BLOCK_LIMITS_LEN, actual_len);
goto the_end;
}
printf("Read Block Limits (MLOI=1) results:\n");
@@ -223,9 +226,9 @@ main(int argc, char * argv[])
printf(" Maximum logical block identifier: %" PRIu64 "\n",
mloi);
} else { /* MLOI=0 (only case before ssc4r02.pdf) */
- if (actual_len < 6) {
- pr2serr("Expected at least 6 bytes in response but only "
- "%d bytes\n", actual_len);
+ if (actual_len < DEF_READ_BLOCK_LIMITS_LEN) {
+ pr2serr("Expected at least %d bytes in response but only "
+ "%d bytes\n", DEF_READ_BLOCK_LIMITS_LEN, actual_len);
goto the_end;
}
max_block_size = sg_get_unaligned_be32(readBlkLmtBuff + 0);