diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2018-01-13 06:38:53 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2018-01-13 06:38:53 +0000 |
commit | 239d147229acac3d3504360a38cd5ec8505d0d5e (patch) | |
tree | 308272c943a93228ac732eff81e7f94840d6e76e /lib | |
parent | 605b21190ce9af77ee3533e12b2e59a7f883ffee (diff) | |
download | sg3_utils-239d147229acac3d3504360a38cd5ec8505d0d5e.tar.gz |
sg_ses_microcode: add --dry-run and --ealsd; sg_write_buffer: add --dry-run
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@744 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sg_cmds_basic.c | 2 | ||||
-rw-r--r-- | lib/sg_cmds_extra.c | 31 | ||||
-rw-r--r-- | lib/sg_lib.c | 5 | ||||
-rw-r--r-- | lib/sg_lib_data.c | 9 | ||||
-rw-r--r-- | lib/sg_pt_freebsd.c | 139 | ||||
-rw-r--r-- | lib/sg_pt_linux_nvme.c | 51 |
6 files changed, 147 insertions, 90 deletions
diff --git a/lib/sg_cmds_basic.c b/lib/sg_cmds_basic.c index 479d45b3..2f0cbac0 100644 --- a/lib/sg_cmds_basic.c +++ b/lib/sg_cmds_basic.c @@ -36,7 +36,7 @@ #endif -static const char * const version_str = "1.78 20180104"; +static const char * const version_str = "1.79 20180112"; #define SENSE_BUFF_LEN 64 /* Arbitrary, could be larger */ diff --git a/lib/sg_cmds_extra.c b/lib/sg_cmds_extra.c index cbd8e626..a6072c95 100644 --- a/lib/sg_cmds_extra.c +++ b/lib/sg_cmds_extra.c @@ -452,7 +452,7 @@ sg_ll_report_referrals(int sg_fd, uint64_t start_llba, bool one_seg, * value is taken as the timeout value in seconds. Return of 0 -> success, * various SG_LIB_CAT_* positive values or -1 -> other errors */ int -sg_ll_send_diag(int sg_fd, int sf_code, bool pf_bit, bool sf_bit, +sg_ll_send_diag(int sg_fd, int st_code, bool pf_bit, bool st_bit, bool devofl_bit, bool unitofl_bit, int long_duration, void * paramp, int param_len, bool noisy, int verbose) { @@ -463,10 +463,10 @@ sg_ll_send_diag(int sg_fd, int sf_code, bool pf_bit, bool sf_bit, unsigned char sense_b[SENSE_BUFF_LEN]; struct sg_pt_base * ptvp; - senddiag_cdb[1] = (unsigned char)(sf_code << 5); + senddiag_cdb[1] = (unsigned char)(st_code << 5); if (pf_bit) senddiag_cdb[1] |= 0x10; - if (sf_bit) + if (st_bit) senddiag_cdb[1] |= 0x4; if (devofl_bit) senddiag_cdb[1] |= 0x2; @@ -851,19 +851,32 @@ sg_ll_format_unit(int sg_fd, int fmtpinfo, bool longlist, bool fmtdata, bool cmplst, int dlist_format, int timeout_secs, void * paramp, int param_len, bool noisy, int verbose) { - return sg_ll_format_unit2(sg_fd, fmtpinfo, longlist, fmtdata, cmplst, - dlist_format, 0, timeout_secs, paramp, - param_len, noisy, verbose); + return sg_ll_format_unit_v2(sg_fd, fmtpinfo, longlist, fmtdata, cmplst, + dlist_format, 0, timeout_secs, paramp, + param_len, noisy, verbose); } -/* Invokes a FORMAT UNIT (SBC-4) command. Return of 0 -> success, - * various SG_LIB_CAT_* positive values or -1 -> other errors. - * FFMT field added in sbc4r10 [20160121] */ +/* Invokes a FORMAT UNIT (SBC-3) command. Return of 0 -> success, + * various SG_LIB_CAT_* positive values or -1 -> other errors */ int sg_ll_format_unit2(int sg_fd, int fmtpinfo, bool longlist, bool fmtdata, bool cmplst, int dlist_format, int ffmt, int timeout_secs, void * paramp, int param_len, bool noisy, int verbose) { + return sg_ll_format_unit_v2(sg_fd, fmtpinfo, longlist, fmtdata, cmplst, + dlist_format, ffmt, timeout_secs, paramp, + param_len, noisy, verbose); +} + +/* Invokes a FORMAT UNIT (SBC-4) command. Return of 0 -> success, + * various SG_LIB_CAT_* positive values or -1 -> other errors. + * FFMT field added in sbc4r10 [20160121] */ +int +sg_ll_format_unit_v2(int sg_fd, int fmtpinfo, bool longlist, bool fmtdata, + bool cmplst, int dlist_format, int ffmt, + int timeout_secs, void * paramp, int param_len, + bool noisy, int verbose) +{ static const char * const cdb_name_s = "format unit"; int k, res, ret, sense_cat, tmout; unsigned char fu_cdb[FORMAT_UNIT_CMDLEN] = diff --git a/lib/sg_lib.c b/lib/sg_lib.c index f6bafb52..314a5508 100644 --- a/lib/sg_lib.c +++ b/lib/sg_lib.c @@ -27,13 +27,14 @@ * */ +#define _POSIX_C_SOURCE 200809L /* for posix_memalign() */ +#define __STDC_FORMAT_MACROS 1 #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <stdbool.h> #include <string.h> #include <ctype.h> -#define __STDC_FORMAT_MACROS 1 #include <inttypes.h> #ifdef HAVE_CONFIG_H @@ -3265,6 +3266,8 @@ sg_memalign(uint32_t num_bytes, uint32_t align_to, uint8_t ** buff_to_free, size_t psz; uint8_t * res; + if (buff_to_free) /* make sure buff_to_free is NULL if alloc fails */ + *buff_to_free = NULL; psz = (align_to > 0) ? align_to : sg_get_page_size(); if (0 == num_bytes) num_bytes = psz; /* ugly to handle otherwise */ diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c index b3842632..5ac4a9bb 100644 --- a/lib/sg_lib_data.c +++ b/lib/sg_lib_data.c @@ -17,7 +17,7 @@ #include "sg_lib_data.h" -const char * sg_lib_version_str = "2.36 20180104";/* spc5r17, sbc4r15 */ +const char * sg_lib_version_str = "2.37 20180109";/* spc5r17, sbc4r15 */ /* indexed by pdt; those that map to own index do not decay */ @@ -1507,6 +1507,8 @@ struct sg_lib_value_name_t sg_lib_scsi_feature_sets[] = {0x0, 0, NULL}, /* 0x0 is reserved sfs; trailing sentinel */ }; +#if (SG_SCSI_STRINGS && HAVE_NVME && (! IGNORE_NVME)) + /* .value is completion queue's DW3 as follows: ((DW3 >> 17) & 0x3ff) * .peri_dev_type is an index for the sg_lib_scsi_status_sense_arr[] * .name is taken from NVMe 1.3a document, section 4.6.1.2.1 with less @@ -1516,7 +1518,6 @@ struct sg_lib_value_name_t sg_lib_scsi_feature_sets[] = * Bits 29:28 are reserved, bit 27:25 are the "Status Code Type" (SCT) * and bits 24:17 are the Status Code (SC). This table is in ascending * order of its .value field so a binary search could be done on it. */ -#ifdef SG_SCSI_STRINGS struct sg_lib_value_name_t sg_lib_nvme_cmd_status_arr[] = { /* Generic command status values, Status Code Type (SCT): 0h @@ -1665,7 +1666,7 @@ struct sg_lib_4tuple_u8 sg_lib_scsi_status_sense_arr[] = }; -#else /* no SG_SCSI_STRINGS define in config.sys */ +#else /* (SG_SCSI_STRINGS && HAVE_NVME && (! IGNORE_NVME)) */ struct sg_lib_value_name_t sg_lib_nvme_cmd_status_arr[] = { @@ -1680,4 +1681,4 @@ struct sg_lib_4tuple_u8 sg_lib_scsi_status_sense_arr[] = {0xff, 0xff, 0xff, 0xff}, }; -#endif /* SG_SCSI_STRINGS */ +#endif /* (SG_SCSI_STRINGS && HAVE_NVME && (! IGNORE_NVME)) */ diff --git a/lib/sg_pt_freebsd.c b/lib/sg_pt_freebsd.c index 9ded65ca..efad6d12 100644 --- a/lib/sg_pt_freebsd.c +++ b/lib/sg_pt_freebsd.c @@ -5,7 +5,7 @@ * license that can be found in the BSD_LICENSE file. */ -/* sg_pt_freebsd version 1.21 20180104 */ +/* sg_pt_freebsd version 1.22 20180112 */ #include <stdio.h> #include <stdlib.h> @@ -39,7 +39,13 @@ #include "sg_lib.h" #include "sg_unaligned.h" #include "sg_pt_nvme.h" + +#if (HAVE_NVME && (! IGNORE_NVME)) #include "freebsd_nvme_ioctl.h" +#else +#define NVME_CTRLR_PREFIX "/dev/nvme" +#define NVME_NS_PREFIX "ns" +#endif #define FREEBSD_MAXDEV 64 @@ -128,10 +134,12 @@ pr2ws(const char * fmt, ...) return n; } +#if (HAVE_NVME && (! IGNORE_NVME)) static inline bool is_aligned(const void * pointer, size_t byte_count) { - return (sg_uintptr_t)pointer % byte_count == 0; + return ((sg_uintptr_t)pointer % byte_count) == 0; } +#endif /* Returns >= 0 if successful. If error in Unix returns negated errno. */ int @@ -577,34 +585,6 @@ set_scsi_pt_flags(struct sg_pt_base * objp, int flags) if (flags) { ; } /* unused, suppress warning */ } -static int -nvme_pt_low(struct freebsd_dev_channel *fdc_p, void * dxferp, uint32_t len, - bool is_read, struct nvme_pt_command * npcp, int vb) -{ - int err, status; - uint8_t opcode; - char b[80]; - - if (fdc_p->dev_fd < 0) { - if (vb) - pr2ws("%s: is_nvme is true but dev_fd<0, inconsistent\n", - __func__); - return -EINVAL; - } - npcp->buf = dxferp; - npcp->len = len; - npcp->is_read = (uint32_t)is_read; - opcode = npcp->cmd.opc; - err = ioctl(fdc_p->dev_fd, NVME_PASSTHROUGH_CMD, npcp); - if (err < 0) - return -errno; - status = ((npcp->cpl.status.sct << 8) | npcp->cpl.status.sc); - if (status && vb) - pr2ws("%s: opcode=0x%x, status: %s\n", __func__, opcode, - sg_get_nvme_cmd_status_str(status, sizeof(b), b)); - return status; -} - /* Executes SCSI command (or at least forwards it to lower layers). * Clears os_err field prior to active call (whose result may set it * again). */ @@ -950,6 +930,8 @@ get_scsi_pt_os_err_str(const struct sg_pt_base * vp, int max_b_len, char * b) #define MICROCODE_CHANGED_ASCQ 0x1 /* with TARGET_CHANGED_ASC */ #define MICROCODE_CHANGED_WO_RESET_ASCQ 0x16 +#if (HAVE_NVME && (! IGNORE_NVME)) + static void build_sense_buffer(bool desc, uint8_t *buf, uint8_t skey, uint8_t asc, uint8_t ascq) @@ -1069,6 +1051,36 @@ mk_sense_invalid_fld(struct sg_pt_freebsd_scsi * ptp, bool in_cdb, __func__, asc, in_cdb ? 'C' : 'D', in_byte, in_bit); } +/* Does actual ioctl(NVME_PASSTHROUGH_CMD). Returns 0 on success; negative + * values are Unix negated errno values; positive values are NVMe status. */ +static int +nvme_pt_low(struct freebsd_dev_channel *fdc_p, void * dxferp, uint32_t len, + bool is_read, struct nvme_pt_command * npcp, int vb) +{ + int err, status; + uint8_t opcode; + char b[80]; + + if (fdc_p->dev_fd < 0) { + if (vb) + pr2ws("%s: is_nvme is true but dev_fd<0, inconsistent\n", + __func__); + return -EINVAL; + } + npcp->buf = dxferp; + npcp->len = len; + npcp->is_read = (uint32_t)is_read; + opcode = npcp->cmd.opc; + err = ioctl(fdc_p->dev_fd, NVME_PASSTHROUGH_CMD, npcp); + if (err < 0) + return -errno; /* Assume Unix error in normal place */ + status = ((npcp->cpl.status.sct << 8) | npcp->cpl.status.sc); + if (status && vb) + pr2ws("%s: opcode=0x%x, status: %s\n", __func__, opcode, + sg_get_nvme_cmd_status_str(status, sizeof(b), b)); + return status; +} + static int sntl_cache_identity(struct freebsd_dev_channel * fdc_p, int vb) { @@ -1081,7 +1093,7 @@ sntl_cache_identity(struct freebsd_dev_channel * fdc_p, int vb) &fdc_p->free_nvme_id_ctlp, vb > 3); if (NULL == fdc_p->nvme_id_ctlp) { pr2ws("%s: sg_memalign() failed to get memory\n", __func__); - return SG_LIB_OS_BASE_ERR + ENOMEM; + return -ENOMEM; } memset(npc_up, 0, sizeof(npc)); npc_up[SG_NVME_PT_OPCODE] = 0x6; /* Identify */ @@ -1094,12 +1106,11 @@ sntl_cache_identity(struct freebsd_dev_channel * fdc_p, int vb) err = nvme_pt_low(fdc_p, fdc_p->nvme_id_ctlp, pg_sz, true, &npc, vb); if (err) { if (err < 0) { - err = -err; if (vb > 1) pr2ws("%s: do_nvme_pt() failed: %s (errno=%d)\n", __func__, - strerror(err), err); - return SG_LIB_OS_BASE_ERR + err; - } else { + strerror(-err), -err); + return err; + } else { /* non-zero NVMe command status */ fdc_p->nvme_status = err; return SG_LIB_NVME_STATUS; } @@ -1132,7 +1143,7 @@ sntl_inq(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb) fdc_p = get_fdc_p(ptp); if (NULL == fdc_p) { pr2ws("%s: get_fdc_p() failed, no file descriptor ?\n", __func__); - return SG_LIB_OS_BASE_ERR + EINVAL; + return -EINVAL; } if (NULL == fdc_p->nvme_id_ctlp) { res = sntl_cache_identity(fdc_p, vb); @@ -1246,7 +1257,7 @@ sntl_rluns(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb) fdc_p = get_fdc_p(ptp); if (NULL == fdc_p) { pr2ws("%s: get_fdc_p() failed, no file descriptor ?\n", __func__); - return SG_LIB_OS_BASE_ERR + EINVAL; + return -EINVAL; } sel_report = cdbp[2]; alloc_len = sg_get_unaligned_be32(cdbp + 6); @@ -1282,7 +1293,7 @@ sntl_rluns(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb) rl_doutp = (uint8_t *)calloc(num + 1, 8); if (NULL == rl_doutp) { pr2ws("%s: calloc() failed to get memory\n", __func__); - return SG_LIB_OS_BASE_ERR + ENOMEM; + return -ENOMEM; } for (k = 0, up = rl_doutp + 8; k < num; ++k, up += 8) sg_put_unaligned_be16(k, up); @@ -1316,7 +1327,7 @@ sntl_tur(struct sg_pt_freebsd_scsi * ptp, int vb) fdc_p = get_fdc_p(ptp); if (NULL == fdc_p) { pr2ws("%s: get_fdc_p() failed, no file descriptor ?\n", __func__); - return SG_LIB_OS_BASE_ERR + EINVAL; + return -EINVAL; } if (NULL == fdc_p->nvme_id_ctlp) { res = sntl_cache_identity(fdc_p, vb); @@ -1334,11 +1345,10 @@ sntl_tur(struct sg_pt_freebsd_scsi * ptp, int vb) err = nvme_pt_low(fdc_p, NULL, 0, false, &npc, vb); if (err) { if (err < 0) { - err = -err; if (vb > 1) pr2ws("%s: do_nvme_pt() failed: %s (errno=%d)\n", __func__, - strerror(err), err); - return SG_LIB_OS_BASE_ERR + err; + strerror(-err), -err); + return err; } else { fdc_p->nvme_status = err; mk_sense_from_nvme_status(ptp, err, vb); @@ -1372,7 +1382,7 @@ sntl_req_sense(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb) fdc_p = get_fdc_p(ptp); if (NULL == fdc_p) { pr2ws("%s: get_fdc_p() failed, no file descriptor ?\n", __func__); - return SG_LIB_OS_BASE_ERR + EINVAL; + return -EINVAL; } if (NULL == fdc_p->nvme_id_ctlp) { res = sntl_cache_identity(fdc_p, vb); @@ -1392,11 +1402,10 @@ sntl_req_sense(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb) err = nvme_pt_low(fdc_p, NULL, 0, false, &npc, vb); if (err) { if (err < 0) { - err = -err; if (vb > 1) pr2ws("%s: do_nvme_pt() failed: %s (errno=%d)\n", __func__, - strerror(err), err); - return SG_LIB_OS_BASE_ERR + err; + strerror(-err), -err); + return err; } else { fdc_p->nvme_status = err; mk_sense_from_nvme_status(ptp, err, vb); @@ -1450,7 +1459,7 @@ sntl_senddiag(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb) fdc_p = get_fdc_p(ptp); if (NULL == fdc_p) { pr2ws("%s: get_fdc_p() failed, no file descriptor ?\n", __func__); - return SG_LIB_OS_BASE_ERR + EINVAL; + return -EINVAL; } if (self_test || st_cd) { memset(npc_up, 0, sizeof(npc)); @@ -1472,7 +1481,8 @@ sntl_senddiag(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb) break; default: pr2ws("%s: bad self-test code [0x%x]\n", __func__, st_cd); - return SG_LIB_SYNTAX_ERROR; + mk_sense_invalid_fld(ptp, true, 1, 7, vb); + return 0; } sg_put_unaligned_le32(nvme_dst, npc_up + SG_NVME_PT_CDW10); err = nvme_pt_low(fdc_p, NULL, 0x0, false, &npc, vb); @@ -1541,11 +1551,10 @@ sntl_senddiag(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb) do_low: if (err) { if (err < 0) { - err = -err; if (vb > 1) pr2ws("%s: do_nvme_pt() failed: %s (errno=%d)\n", - __func__, strerror(err), err); - return SG_LIB_OS_BASE_ERR + err; + __func__, strerror(-err), -err); + return err; } else { fdc_p->nvme_status = err; mk_sense_from_nvme_status(ptp, err, vb); @@ -1582,7 +1591,7 @@ sntl_recvdiag(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb) fdc_p = get_fdc_p(ptp); if (NULL == fdc_p) { pr2ws("%s: get_fdc_p() failed, no file descriptor ?\n", __func__); - return SG_LIB_OS_BASE_ERR + EINVAL; + return -EINVAL; } din_len = ptp->dxfer_len; if (pcv) { @@ -1637,11 +1646,10 @@ sntl_recvdiag(struct sg_pt_freebsd_scsi * ptp, const uint8_t * cdbp, int vb) err = nvme_pt_low(fdc_p, ptp->dxferp, 0x1000, true, &npc, vb); if (err) { if (err < 0) { - err = -err; if (vb > 1) pr2ws("%s: do_nvme_pt() failed: %s (errno=%d)\n", - __func__, strerror(err), err); - return SG_LIB_OS_BASE_ERR + err; + __func__, strerror(-err), -err); + return err; } else { fdc_p->nvme_status = err; mk_sense_from_nvme_status(ptp, err, vb); @@ -1680,7 +1688,7 @@ sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int vb) if (fd < 0) { if (NULL == fdc_p) { pr2ws("%s: no device handle in object or fd ?\n", __func__); - return SG_LIB_FILE_ERROR; + return -EINVAL; } } else { int han = fd - FREEBSD_FDOFFSET; @@ -1761,11 +1769,10 @@ sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int vb) err = nvme_pt_low(fdc_p, dxferp, io_len, in_xfer, &npc, vb); if (err) { if (err < 0) { - err = -err; if (vb > 1) pr2ws("%s: do_nvme_pt() failed: %s (errno=%d)\n", - __func__, strerror(err), err); - return SG_LIB_OS_BASE_ERR + err; + __func__, strerror(-err), -err); + return err; } else { fdc_p->nvme_status = err; mk_sense_from_nvme_status(ptp, err, vb); @@ -1776,3 +1783,17 @@ sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int vb) ptp->resid = 0; /* Just hoping ... */ return 0; } + +#else /* if not(HAVE_NVME && (! IGNORE_NVME)) */ + +static int +sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int vb) +{ + if (vb) + pr2ws("%s: not supported\n", __func__); + if (vp) { ; } /* suppress warning */ + if (fd) { ; } /* suppress warning */ + return -ENOTTY; /* inappropriate ioctl error */ +} + +#endif /* (HAVE_NVME && (! IGNORE_NVME)) */ diff --git a/lib/sg_pt_linux_nvme.c b/lib/sg_pt_linux_nvme.c index 9c2d8124..f62366f7 100644 --- a/lib/sg_pt_linux_nvme.c +++ b/lib/sg_pt_linux_nvme.c @@ -112,7 +112,7 @@ static inline bool is_aligned(const void * pointer, size_t byte_count) { - return (sg_uintptr_t)pointer % byte_count == 0; + return ((sg_uintptr_t)pointer % byte_count) == 0; } @@ -136,6 +136,8 @@ pr2ws(const char * fmt, ...) return n; } +#if (HAVE_NVME && (! IGNORE_NVME)) + /* This trims given NVMe block device name in Linux (e.g. /dev/nvme0n1p5) * to the name of its associated char device (e.g. /dev/nvme0). If this * occurs true is returned and the char device name is placed in 'b' (as @@ -283,9 +285,10 @@ mk_sense_invalid_fld(struct sg_pt_linux_scsi * ptp, bool in_cdb, int in_byte, /* Returns 0 for success. Returns SG_LIB_NVME_STATUS if there is non-zero * NVMe status (from the completion queue) with the value placed in - * ptp->nvme_status. If Unix error from ioctl add equivalent errno value to - * SG_LIB_OS_BASE_ERR. Should not return negative values. CDW0 from - * the completion queue is placed in ptp->nvme_result on success. */ + * ptp->nvme_status. If Unix error from ioctl then return negated value + * (equivalent -errno from basic Unix system functions like open()). + * CDW0 from the completion queue is placed in ptp->nvme_result in the + * absence of a Unix error. */ static int do_nvme_admin_cmd(struct sg_pt_linux_scsi * ptp, struct sg_nvme_passthru_cmd *cmdp, const void * dp, @@ -318,14 +321,14 @@ do_nvme_admin_cmd(struct sg_pt_linux_scsi * ptp, res = ioctl(ptp->dev_fd, NVME_IOCTL_ADMIN_CMD, cmdp); if (0 != res) { if (res < 0) { /* OS error (errno negated) */ - res = (-res & 0x3ff); /* clear DNR and More, if present */ - ptp->os_err = res; + ptp->os_err = -res; if (vb > 3) { pr2ws("%s: ioctl opcode=0x%x failed: %s " - "(errno=%d)\n", __func__, *up, strerror(res), res); + "(errno=%d)\n", __func__, *up, strerror(-res), -res); } - return SG_LIB_OS_BASE_ERR + res; + return res; } else { /* NVMe errors are positive return values */ + res &= 0x3ff; /* clear DNR and More bits */ ptp->nvme_status = res; if (vb > 2) { char b[80]; @@ -364,20 +367,20 @@ sntl_cache_identity(struct sg_pt_linux_scsi * ptp, int time_secs, int vb) { struct sg_nvme_passthru_cmd cmd; uint32_t pg_sz = sg_get_page_size(); - void * vp; + uint8_t * up; - vp = sg_memalign(pg_sz, pg_sz, &ptp->free_nvme_id_ctlp, vb > 3); - ptp->nvme_id_ctlp = vp; - if (NULL == vp) { + up = sg_memalign(pg_sz, pg_sz, &ptp->free_nvme_id_ctlp, vb > 3); + ptp->nvme_id_ctlp = up; + if (NULL == up) { pr2ws("%s: sg_memalign() failed to get memory\n", __func__); - return SG_LIB_OS_BASE_ERR + ENOMEM; + return -ENOMEM; } memset(&cmd, 0, sizeof(cmd)); cmd.opcode = 0x6; /* Identify */ cmd.cdw10 = 0x1; /* CNS=0x1 Identify controller */ cmd.addr = (uint64_t)(sg_uintptr_t)ptp->nvme_id_ctlp; cmd.data_len = pg_sz; - return do_nvme_admin_cmd(ptp, &cmd, vp, true, time_secs, vb); + return do_nvme_admin_cmd(ptp, &cmd, up, true, time_secs, vb); } static const char * nvme_scsi_vendor_str = "NVMe "; @@ -543,7 +546,7 @@ sntl_rluns(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, int time_secs, rl_doutp = (uint8_t *)calloc(num + 1, 8); if (NULL == rl_doutp) { pr2ws("%s: calloc() failed to get memory\n", __func__); - return SG_LIB_OS_BASE_ERR + ENOMEM; + return -ENOMEM; } for (k = 0, up = rl_doutp + 8; k < num; ++k, up += 8) sg_put_unaligned_be16(k, up); @@ -710,7 +713,8 @@ sntl_senddiag(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, break; default: pr2ws("%s: bad self-test code [0x%x]\n", __func__, st_cd); - return SG_LIB_SYNTAX_ERROR; + mk_sense_invalid_fld(ptp, true, 1, 7, vb); + return 0; } sg_put_unaligned_le32(nvme_dst, cmd_up + SG_NVME_PT_CDW10); res = do_nvme_admin_cmd(ptp, &cmd, NULL, false, time_secs, vb); @@ -928,3 +932,18 @@ sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int time_secs, int vb) } return do_nvme_admin_cmd(ptp, &cmd, dp, is_read, time_secs, vb); } + +#else /* (HAVE_NVME && (! IGNORE_NVME)) */ + +int +sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int time_secs, int vb) +{ + if (vb) + pr2ws("%s: not supported\n", __func__); + if (vp) { ; } /* suppress warning */ + if (fd) { ; } /* suppress warning */ + if (time_secs) { ; } /* suppress warning */ + return -ENOTTY; /* inappropriate ioctl error */ +} + +#endif /* (HAVE_NVME && (! IGNORE_NVME)) */ |