aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.in1
-rw-r--r--lib/sg_lib.c78
-rw-r--r--lib/sg_lib_data.c17
3 files changed, 61 insertions, 35 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 957ae211..a8bcf6ca 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -343,6 +343,7 @@ pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
+runstatedir = @runstatedir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
diff --git a/lib/sg_lib.c b/lib/sg_lib.c
index d400abee..d187d8d3 100644
--- a/lib/sg_lib.c
+++ b/lib/sg_lib.c
@@ -913,7 +913,7 @@ sg_get_designation_descriptor_str(const char * lip, const uint8_t * ddp,
break;
}
ci_off = 0;
- if (16 == dlen) {
+ if (16 == dlen) { /* first 8 bytes are 'Identifier Extension' */
ci_off = 8;
id_ext = sg_get_unaligned_be64(ip);
n += sg_scnpr(b + n, blen - n, "%s Identifier extension: 0x%"
@@ -3351,7 +3351,8 @@ sg_get_llnum_nomult(const char * buf)
* line or a comma, space or tab separated list of bytes. If no_space is
* set then a string of ACSII hex digits is expected, 2 per byte. Everything
* from and including a '#' on a line is ignored. Returns 0 if ok, or an
- * error code. */
+ * error code. If the error code is SG_LIB_LBA_OUT_OF_RANGE then mp_arr
+ * would be exceeded and both mp_arr and mp_arr_len are written to. */
int
sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
uint8_t * mp_arr, int * mp_arr_len, int max_arr_len)
@@ -3359,6 +3360,7 @@ sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
bool has_stdin, split_line;
int fn_len, in_len, k, j, m, fd, err;
int off = 0;
+ int ret = 0;
unsigned int h;
const char * lcp;
FILE * fp;
@@ -3386,18 +3388,15 @@ sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
}
k = read(fd, mp_arr, max_arr_len);
if (k <= 0) {
- int ret = SG_LIB_SYNTAX_ERROR;
-
- if (0 == k)
+ if (0 == k) {
+ ret = SG_LIB_SYNTAX_ERROR;
pr2serr("read 0 bytes from binary file %s\n", fname);
- else {
+ } else {
ret = sg_convert_errno(errno);
pr2serr("read from binary file %s: %s\n", fname,
safe_strerror(errno));
}
- if (! has_stdin)
- close(fd);
- return ret;
+ goto bin_fini;
}
if ((0 == fstat(fd, &a_stat)) && S_ISFIFO(a_stat.st_mode)) {
/* pipe; keep reading till error or 0 read */
@@ -3409,30 +3408,32 @@ sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
err = errno;
pr2serr("read from binary pipe %s: %s\n", fname,
safe_strerror(err));
- if (! has_stdin)
- close(fd);
- return sg_convert_errno(err);
+ ret = sg_convert_errno(err);
+ goto bin_fini;
}
k += m;
}
}
*mp_arr_len = k;
+bin_fini:
if (! has_stdin)
close(fd);
- return 0;
- } else { /* So read the file as ASCII hex */
- if (has_stdin)
- fp = stdin;
- else {
- fp = fopen(fname, "r");
- if (NULL == fp) {
- err = errno;
- pr2serr("Unable to open %s for reading: %s\n", fname,
- safe_strerror(err));
- return sg_convert_errno(err);
- }
+ return ret;
+ }
+
+ /* So read the file as ASCII hex */
+ if (has_stdin)
+ fp = stdin;
+ else {
+ fp = fopen(fname, "r");
+ if (NULL == fp) {
+ err = errno;
+ pr2serr("Unable to open %s for reading: %s\n", fname,
+ safe_strerror(err));
+ ret = sg_convert_errno(err);
+ goto fini;
}
- }
+ }
carry_over[0] = 0;
for (j = 0; j < 512; ++j) {
@@ -3460,7 +3461,8 @@ sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
else {
pr2serr("%s: carry_over error ['%s'] around line %d\n",
__func__, carry_over, j + 1);
- goto bad;
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto fini;
}
lcp = line + 1;
--in_len;
@@ -3481,7 +3483,8 @@ sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
if ((k < in_len) && ('#' != lcp[k]) && ('\r' != lcp[k])) {
pr2serr("%s: syntax error at line %d, pos %d\n", __func__,
j + 1, m + k + 1);
- goto bad;
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto fini;
}
if (no_space) {
for (k = 0; isxdigit(*lcp) && isxdigit(*(lcp + 1));
@@ -3489,11 +3492,14 @@ sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
if (1 != sscanf(lcp, "%2x", &h)) {
pr2serr("%s: bad hex number in line %d, pos %d\n",
__func__, j + 1, (int)(lcp - line + 1));
- goto bad;
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto fini;
}
if ((off + k) >= max_arr_len) {
pr2serr("%s: array length exceeded\n", __func__);
- goto bad;
+ *mp_arr_len = max_arr_len;
+ ret = SG_LIB_LBA_OUT_OF_RANGE;
+ goto fini;
}
mp_arr[off + k] = h;
}
@@ -3507,7 +3513,8 @@ sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
pr2serr("%s: hex number larger than 0xff in line "
"%d, pos %d\n", __func__, j + 1,
(int)(lcp - line + 1));
- goto bad;
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto fini;
}
if (split_line && (1 == strlen(lcp))) {
/* single trailing hex digit might be a split pair */
@@ -3515,7 +3522,9 @@ sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
}
if ((off + k) >= max_arr_len) {
pr2serr("%s: array length exceeded\n", __func__);
- goto bad;
+ ret = SG_LIB_LBA_OUT_OF_RANGE;
+ *mp_arr_len = max_arr_len;
+ goto fini;
}
mp_arr[off + k] = h;
lcp = strpbrk(lcp, " ,\t");
@@ -3531,7 +3540,8 @@ sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
}
pr2serr("%s: error in line %d, at pos %d\n", __func__,
j + 1, (int)(lcp - line + 1));
- goto bad;
+ ret = SG_LIB_SYNTAX_ERROR;
+ goto fini;
}
}
off += (k + 1);
@@ -3541,10 +3551,10 @@ sg_f2hex_arr(const char * fname, bool as_binary, bool no_space,
if (stdin != fp)
fclose(fp);
return 0;
-bad:
+fini:
if (stdin != fp)
fclose(fp);
- return SG_LIB_SYNTAX_ERROR;
+ return ret;
}
/* Extract character sequence from ATA words as in the model string
diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c
index ba0a431f..2ab80e6b 100644
--- a/lib/sg_lib_data.c
+++ b/lib/sg_lib_data.c
@@ -19,7 +19,7 @@
#include "sg_lib_data.h"
-const char * sg_lib_version_str = "2.63 20190716";/* spc5r22, sbc4r17 */
+const char * sg_lib_version_str = "2.67 20190822";/* spc5r22, sbc4r17 */
/* indexed by pdt; those that map to own index do not decay */
@@ -529,6 +529,10 @@ struct sg_lib_value_name_t sg_lib_zoning_out_arr[] = {
/* Zoning in [0x95] service actions */
struct sg_lib_value_name_t sg_lib_zoning_in_arr[] = {
{0x0, PDT_ZBC, "Report zones"},
+ {0x6, PDT_ZBC, "Report realms"}, /* 19-032r3 */
+ {0x7, PDT_ZBC, "Report zone domains"}, /* 19-032r3 */
+ {0x8, PDT_ZBC, "Zone activate"}, /* 19-032r3 */
+ {0x9, PDT_ZBC, "Zone query"}, /* 19-032r3 */
{0xffff, 0, NULL},
};
@@ -718,6 +722,7 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x04,0x21,"Logical unit not ready, hard reset required"},
{0x04,0x22,"Logical unit not ready, power cycle required"},
{0x04,0x23,"Logical unit not ready, affiliation required"},
+ {0x04,0x24,"Depopulation in progress"}, /* spc5r15 */
{0x05,0x00,"Logical unit does not respond to selection"},
{0x06,0x00,"No reference position found"},
{0x07,0x00,"Multiple peripheral devices selected"},
@@ -753,6 +758,7 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x0B,0x11,"Warning - low operating humidity limit exceeded"},
{0x0B,0x12,"Warning - microcode security at risk"},
{0x0B,0x13,"Warning - microcode digital signature validation failure"},
+ {0x0B,0x14,"Warning - physical element status change"}, /* spc5r15 */
{0x0C,0x00,"Write error"},
{0x0C,0x01,"Write error - recovered with auto reallocation"},
{0x0C,0x02,"Write error - auto reallocation failed"},
@@ -1026,6 +1032,7 @@ struct sg_lib_asc_ascq_t sg_lib_asc_ascq[] =
{0x31,0x01,"Format command failed"},
{0x31,0x02,"Zoned formatting failed due to spare linking"},
{0x31,0x03,"Sanitize command failed"},
+ {0x31,0x04,"Depopulation failed"}, /* spc5r15 */
{0x32,0x00,"No defect spare location available"},
{0x32,0x01,"Defect list update failure"},
{0x33,0x00,"Tape length error"},
@@ -1560,6 +1567,7 @@ struct sg_lib_simple_value_name_t sg_lib_nvme_admin_cmd_arr[] =
{0x81, "Security Send"},
{0x82, "Security Receive"},
{0x84, "Sanitize"}, /* last NVM specific in 1.3a */
+ {0x86, "Get LBA status"}, /* NVM specific, new in 1.4 */
/* Vendor specific 0xc0 to 0xff */
{0xffff, NULL}, /* Sentinel */
};
@@ -1635,7 +1643,11 @@ struct sg_lib_value_name_t sg_lib_nvme_cmd_status_arr[] =
{0x1d, 11, "Sanitize in progress"},
{0x1e, 5, "SGL data block granularity invalid"},
{0x1f, 5, "Command not supported for queue in CMB"},
+ {0x20, 18, "Namespace is write protected"}, /* NVMe 1.4 */
+ {0x21, 6, "Command interrupted"}, /* NVMe 1.4 */
+ {0x22, 5, "Transient transport error"}, /* NVMe 1.4 */
+ /* 0x80 - 0xbf: I/O command set specific */
/* Generic command status values, NVM (I/O) Command Set */
{0x80, 12, "LBA out of range"},
{0x81, 3, "Capacity exceeded"},
@@ -1680,6 +1692,9 @@ struct sg_lib_value_name_t sg_lib_nvme_cmd_status_arr[] =
{0x120, 5, "Invalid secondary controller state"},
{0x121, 5, "Invalid number of controller resources"},
{0x122, 5, "Invalid resource identifier"},
+ {0x123, 5, "Sanitize prohibited while PM enabled"}, /* NVMe 1.4 */
+ {0x124, 5, "ANA group identifier invalid"}, /* NVMe 1.4 */
+ {0x125, 5, "ANA attach failed"}, /* NVMe 1.4 */
/* Command specific status values, Status Code Type (SCT): 1h
* for NVM (I/O) Command Set */