diff options
author | Douglas Gilbert <dgilbert@interlog.com> | 2020-04-04 02:45:35 +0000 |
---|---|---|
committer | Douglas Gilbert <dgilbert@interlog.com> | 2020-04-04 02:45:35 +0000 |
commit | 7f78fcb9b12c87fdc6eca644bc1582d8e5e1242c (patch) | |
tree | 85f77e9b0489f0e984e917b2e0312d0ddcd7ef88 /lib | |
parent | 6d0bc453c737596c5b563dd27d69c2301e9fe280 (diff) | |
download | sg3_utils-7f78fcb9b12c87fdc6eca644bc1582d8e5e1242c.tar.gz |
sync with sbc4r19a; start req/write SNTL work; testing fixes
git-svn-id: https://svn.bingwo.ca/repos/sg3_utils/trunk@846 6180dd3e-e324-4e3e-922d-17de1ae2f315
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sg_io_linux.c | 8 | ||||
-rw-r--r-- | lib/sg_lib_data.c | 5 | ||||
-rw-r--r-- | lib/sg_pt_common.c | 21 | ||||
-rw-r--r-- | lib/sg_pt_linux_nvme.c | 70 |
4 files changed, 89 insertions, 15 deletions
diff --git a/lib/sg_io_linux.c b/lib/sg_io_linux.c index 15e684e2..25ccb47d 100644 --- a/lib/sg_io_linux.c +++ b/lib/sg_io_linux.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2018 Douglas Gilbert. + * Copyright (c) 1999-2020 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. @@ -24,7 +24,7 @@ #include "sg_pr2serr.h" -/* Version 1.10 20180613 */ +/* Version 1.11 20200401 */ void @@ -62,7 +62,7 @@ sg_print_host_status(int host_status) static const char * linux_driver_bytes[] = { "DRIVER_OK", "DRIVER_BUSY", "DRIVER_SOFT", "DRIVER_MEDIA", "DRIVER_ERROR", "DRIVER_INVALID", "DRIVER_TIMEOUT", "DRIVER_HARD", - "DRIVER_SENSE" + "DRIVER_SENSE", }; #if 0 @@ -72,7 +72,7 @@ static const char * linux_driver_bytes[] = { static const char * linux_driver_suggests[] = { "SUGGEST_OK", "SUGGEST_RETRY", "SUGGEST_ABORT", "SUGGEST_REMAP", "SUGGEST_DIE", "UNKNOWN","UNKNOWN","UNKNOWN", - "SUGGEST_SENSE" + "SUGGEST_SENSE", }; #endif diff --git a/lib/sg_lib_data.c b/lib/sg_lib_data.c index 6c0326c3..725596f5 100644 --- a/lib/sg_lib_data.c +++ b/lib/sg_lib_data.c @@ -19,8 +19,8 @@ #include "sg_lib_data.h" -const char * sg_lib_version_str = "2.72 20200125"; -/* spc5r22, sbc4r17, zbc2r04 */ +const char * sg_lib_version_str = "2.73 20200331"; +/* spc6r01, sbc4r19, zbc2r04 */ /* indexed by pdt; those that map to own index do not decay */ @@ -363,6 +363,7 @@ struct sg_lib_value_name_t sg_lib_serv_in16_arr[] = { {0x16, 0, "Get stream status"}, {0x17, 0, "Get physical element status"}, /* added sbc4r13 */ {0x18, 0, "Remove element and truncate"}, /* added sbc4r13 */ + {0x19, 0, "Restore elements and rebuild"}, /* added sbc4r19 */ {0xffff, 0, NULL}, }; diff --git a/lib/sg_pt_common.c b/lib/sg_pt_common.c index 47e01e1b..5d087171 100644 --- a/lib/sg_pt_common.c +++ b/lib/sg_pt_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009-2019 Douglas Gilbert. + * Copyright (c) 2009-2020 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. @@ -31,7 +31,7 @@ #include "sg_pt_nvme.h" #endif -static const char * scsi_pt_version_str = "3.12 20190612"; +static const char * scsi_pt_version_str = "3.13 20200313"; const char * @@ -76,10 +76,27 @@ static struct sg_opcode_info_t sg_opcode_info_arr[] = 0x1, 0xff, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, {0x1d, 0, 0, {6, /* SEND DIAGNOSTIC */ 0xf7, 0x0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }, + {0x25, 0, 0, {10, /* READ CAPACITY(10) */ + 0x1, 0xff, 0xff, 0xff, 0xff, 0, 0, 0x1, 0xc7, 0, 0, 0, 0, 0, 0} }, + {0x28, 0, 0, {10, /* READ(10) */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, 0, 0, 0, + 0, 0} }, + {0x2a, 0, 0, {10, /* WRITE(10) */ + 0xfb, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7, 0, 0, 0, 0, + 0, 0} }, {0x55, 0, 0, {10, /* MODE SELECT(10) */ 0x13, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} }, {0x5a, 0, 0, {10, /* MODE SENSE(10) */ 0x18, 0xff, 0xff, 0x0, 0x0, 0x0, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} }, + {0x88, 0, 0, {16, /* READ(16) */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc7} }, + {0x8a, 0, 0, {16, /* WRITE(16) */ + 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc7} }, + {0x9e, 0x10, F_SA_LOW, {16, /* READ CAPACITY(16) [service action in] */ + 0x10, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x1, 0xc7} }, {0xa0, 0, 0, {12, /* REPORT LUNS */ 0xe3, 0xff, 0, 0, 0, 0xff, 0xff, 0xff, 0xff, 0, 0xc7, 0, 0, 0, 0} }, {0xa3, 0xc, F_SA_LOW, {12, /* REPORT SUPPORTED OPERATION CODES */ diff --git a/lib/sg_pt_linux_nvme.c b/lib/sg_pt_linux_nvme.c index 10e176b1..7b633feb 100644 --- a/lib/sg_pt_linux_nvme.c +++ b/lib/sg_pt_linux_nvme.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Douglas Gilbert. + * Copyright (c) 2017-2020 Douglas Gilbert. * All rights reserved. * Use of this source code is governed by a BSD-style * license that can be found in the BSD_LICENSE file. @@ -41,7 +41,7 @@ * MA 02110-1301, USA. */ -/* sg_pt_linux_nvme version 1.09 20190303 */ +/* sg_pt_linux_nvme version 1.10 20200313 */ /* This file contains a small "SPC-only" SNTL to support the SES pass-through * of SEND DIAGNOSTIC and RECEIVE DIAGNOSTIC RESULTS through NVME-MI @@ -87,11 +87,15 @@ #define SCSI_SEND_DIAGNOSTIC_OPC 0x1d #define SCSI_RECEIVE_DIAGNOSTIC_OPC 0x1c #define SCSI_MAINT_IN_OPC 0xa3 +#define SCSI_READ10_OPC 0x28 +#define SCSI_READ16_OPC 0x88 #define SCSI_REP_SUP_OPCS_OPC 0xc #define SCSI_REP_SUP_TMFS_OPC 0xd #define SCSI_MODE_SENSE10_OPC 0x5a #define SCSI_MODE_SELECT10_OPC 0x55 #define SCSI_READ_CAPACITY10_OPC 0x25 +#define SCSI_WRITE10_OPC 0x2a +#define SCSI_WRITE16_OPC 0x8a #define SCSI_SERVICE_ACT_IN_OPC 0x9e #define SCSI_READ_CAPACITY16_SA 0x10 #define SCSI_SA_MSK 0x1f @@ -423,7 +427,7 @@ sntl_do_identify(struct sg_pt_linux_scsi * ptp, int cns, int nsid, struct sg_nvme_passthru_cmd cmd; memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = 0x6; /* Identify */ + cmd.opcode = 0x6; /* NVME Identify command opcode */ cmd.nsid = nsid; cmd.cdw10 = cns; cmd.addr = (uint64_t)(sg_uintptr_t)up; @@ -693,7 +697,7 @@ sntl_tur(struct sg_pt_linux_scsi * ptp, int time_secs, int vb) return res; } memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = 0xa; /* Get feature */ + cmd.opcode = 0xa; /* NVMe Get feature command */ cmd.nsid = SG_NVME_BROADCAST_NSID; cmd.cdw10 = 0x2; /* SEL=0 (current), Feature=2 Power Management */ cmd.timeout_ms = (time_secs < 0) ? 0 : (1000 * time_secs); @@ -742,7 +746,7 @@ sntl_req_sense(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, desc = !!(0x1 & cdbp[1]); alloc_len = cdbp[4]; memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = 0xa; /* Get feature */ + cmd.opcode = 0xa; /* NVMe Get feature command */ cmd.nsid = SG_NVME_BROADCAST_NSID; cmd.cdw10 = 0x2; /* SEL=0 (current), Feature=2 Power Management */ cmd.timeout_ms = (time_secs < 0) ? 0 : (1000 * time_secs); @@ -932,7 +936,7 @@ sntl_senddiag(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, pr2ws("%s: passing through d_pg=0x%x, len=%u to NVME_MI SES send\n", __func__, dpg_cd, dpg_len); memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = 0x1d; /* MI send; hmmm same opcode as SEND DIAG */ + cmd.opcode = 0x1d; /* NVMe MI Send; hmmm same opcode as SEND DIAG */ cmd.addr = (uint64_t)(sg_uintptr_t)dop; cmd.data_len = 0x1000; /* NVMe 4k page size. Maybe determine this? */ /* dout_len > 0x1000, is this a problem?? */ @@ -987,7 +991,7 @@ sntl_recvdiag(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, pr2ws("%s: expecting d_pg=0x%x from NVME_MI SES receive\n", __func__, dpg_cd); memset(&cmd, 0, sizeof(cmd)); - cmd.opcode = 0x1e; /* MI receive */ + cmd.opcode = 0x1e; /* NVMe MI Receive command */ cmd.addr = (uint64_t)(sg_uintptr_t)dip; cmd.data_len = 0x1000; /* NVMe 4k page size. Maybe determine this? */ /* din_len > 0x1000, is this a problem?? */ @@ -1238,6 +1242,52 @@ fini: return res; } +static int +sntl_read(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, + int time_secs, int vb) +{ + bool is_read10 = (SCSI_READ10_OPC == cdbp[0]); + uint64_t lba; + uint32_t num; + struct sg_nvme_user_io io; + struct sg_nvme_user_io * iop = &io; + + memset(iop, 0, sizeof(*iop)); + iop->opcode = 0x2; /* NVMe Read command */ + if (is_read10) { + lba = sg_get_unaligned_be32(cdbp + 2); + num = sg_get_unaligned_be16(cdbp + 7); + } else { + lba = sg_get_unaligned_be64(cdbp + 2); + num = sg_get_unaligned_be32(cdbp + 10); + } + iop->slba = lba; + iop->nblocks = num; + return 0; +} + +static int +sntl_write(struct sg_pt_linux_scsi * ptp, const uint8_t * cdbp, + int time_secs, int vb) +{ + bool is_write10 = (SCSI_WRITE10_OPC == cdbp[0]); + uint64_t lba; + uint32_t num; + struct sg_nvme_user_io io; + struct sg_nvme_user_io * iop = &io; + + memset(iop, 0, sizeof(*iop)); + iop->opcode = 0x3; /* NVMe Write command */ + if (is_write10) { + lba = sg_get_unaligned_be32(cdbp + 2); + num = sg_get_unaligned_be16(cdbp + 7); + } else { + lba = sg_get_unaligned_be64(cdbp + 2); + num = sg_get_unaligned_be32(cdbp + 10); + } + return 0; +} + /* Executes NVMe Admin command (or at least forwards it to lower layers). * Returns 0 for success, negative numbers are negated 'errno' values from * OS system calls. Positive return values are errors from this package. @@ -1292,6 +1342,12 @@ sg_do_nvme_pt(struct sg_pt_base * vp, int fd, int time_secs, int vb) return sntl_tur(ptp, time_secs, vb); case SCSI_REQUEST_SENSE_OPC: return sntl_req_sense(ptp, cdbp, time_secs, vb); + case SCSI_READ10_OPC: + case SCSI_READ16_OPC: + return sntl_read(ptp, cdbp, time_secs, vb); + case SCSI_WRITE10_OPC: + case SCSI_WRITE16_OPC: + return sntl_write(ptp, cdbp, time_secs, vb); case SCSI_SEND_DIAGNOSTIC_OPC: return sntl_senddiag(ptp, cdbp, time_secs, vb); case SCSI_RECEIVE_DIAGNOSTIC_OPC: |