cm适配NoF+接口

This commit is contained in:
hemny 2023-07-06 12:25:28 +08:00
parent ad700ac4f2
commit fd0bf15a55
4 changed files with 518 additions and 9 deletions

283
src/cm_persist/cm_nvme.cpp Normal file
View File

@ -0,0 +1,283 @@
/*
* Copyright (c) 2022 Huawei Technologies Co.,Ltd.
*
* CM is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* cm_nvme.cpp
*
* IDENTIFICATION
* src/cm_persist/cm_nvme.cpp
*
* -------------------------------------------------------------------------
*/
#include "cm_nvme.h"
#include <sys/ioctl.h>
#include <stdio.h>
#define CM_DEF_BLOCK_SIZE (512)
#define CM_NVME_SC_SUCCESS 0x0
#define CM_NVME_ERR_MISCOMPARE (-2)
typedef enum en_status {
CM_ERROR = -1,
CM_SUCCESS = 0
} status_t;
// NVMe vaai compare and write, just support 1 block now
int32 CmNVMeCaw(int32 fd, uint64 blockAddr, char *buff, uint32 buffLen)
{
int32 status;
struct nvme_user_io io = {0};
io.opcode = nvme_cmd_compare;
io.slba = blockAddr;
io.addr = (uint64) buff;
status = ioctl(fd, NVME_IOCTL_SUBMIT_IO, &io);
if (status == CM_NVME_SC_COMPARE_FAILED) {
(void)printf(_("Sending NVMe compare command in caw failed, %s(%#x)."), CmNVMeStatusMessage(status), status);
return CM_NVME_ERR_MISCOMPARE;
} else if (status != CM_NVME_SC_SUCCESS) {
(void)printf(_("Sending NVMe compare command in caw failed, %s(%#x)."), CmNVMeStatusMessage(status), status);
return CM_ERROR;
}
io.opcode = nvme_cmd_write;
io.addr = (uint64)(buff + CM_DEF_BLOCK_SIZE);
status = ioctl(fd, NVME_IOCTL_SUBMIT_IO, &io);
if (status != CM_NVME_SC_SUCCESS) {
(void)printf(_("Sending NVMe write command in caw failed, %s(%#x)."), CmNVMeStatusMessage(status), status);
return CM_ERROR;
}
return CM_SUCCESS;
}
const char* CmNVMeStatusMessage(uint32 status)
{
switch (status & 0x3ff) {
case CM_NVME_SC_SUCCESS:
return "SUCCESS: The command completed successfully";
case CM_NVME_SC_INVALID_OPCODE:
return "INVALID_OPCODE: The associated command opcode field is not valid";
case CM_NVME_SC_INVALID_FIELD:
return "INVALID_FIELD: A reserved coded value or an unsupported value in a defined field";
case CM_NVME_SC_CMDID_CONFLICT:
return "CMDID_CONFLICT: The command identifier is already in use";
case CM_NVME_SC_DATA_XFER_ERROR:
return "DATA_XFER_ERROR: Error while trying to transfer the data or metadata";
case CM_NVME_SC_POWER_LOSS:
return "POWER_LOSS: Command aborted due to power loss notification";
case CM_NVME_SC_INTERNAL:
return "INTERNAL: The command was not completed successfully due to an internal error";
case CM_NVME_SC_ABORT_REQ:
return "ABORT_REQ: The command was aborted due to a Command Abort request";
case CM_NVME_SC_ABORT_QUEUE:
return "ABORT_QUEUE: The command was aborted due to a Delete I/O Submission Queue request";
case CM_NVME_SC_FUSED_FAIL:
return "FUSED_FAIL: The command was aborted due to the other command in a fused operation failing";
case CM_NVME_SC_FUSED_MISSING:
return "FUSED_MISSING: The command was aborted due to a Missing Fused Command";
case CM_NVME_SC_INVALID_NS:
return "INVALID_NS: The namespace or the format of that namespace is invalid";
case CM_NVME_SC_CMD_SEQ_ERROR:
return "CMD_SEQ_ERROR: The command was aborted due to a protocol violation in a multicommand sequence";
case CM_NVME_SC_SGL_INVALID_LAST:
return "SGL_INVALID_LAST: The command includes an invalid SGL Last Segment or SGL Segment descriptor.";
case CM_NVME_SC_SGL_INVALID_COUNT:
return "SGL_INVALID_COUNT: There is an SGL Last Segment descriptor or an SGL Segment descriptor in a"
" location other than the last descriptor of a segment based on the length indicated.";
case CM_NVME_SC_SGL_INVALID_DATA:
return "SGL_INVALID_DATA: This may occur if the length of a Data SGL is too short.";
case CM_NVME_SC_SGL_INVALID_METADATA:
return "SGL_INVALID_METADATA: This may occur if the length of a Metadata SGL is too short";
case CM_NVME_SC_SGL_INVALID_TYPE:
return "SGL_INVALID_TYPE: The type of an SGL Descriptor is a type that is not supported by the controller.";
case CM_NVME_SC_CMB_INVALID_USE:
return "CMB_INVALID_USE: The attempted use of the Controller Memory Buffer is not supported by the controller.";
case CM_NVME_SC_PRP_INVALID_OFFSET:
return "PRP_INVALID_OFFSET: The Offset field for a PRP entry is invalid.";
case CM_NVME_SC_ATOMIC_WRITE_UNIT_EXCEEDED:
return "ATOMIC_WRITE_UNIT_EXCEEDED: The length specified exceeds the atomic write unit size.";
case CM_NVME_SC_OPERATION_DENIED:
return "OPERATION_DENIED: The command was denied due to lack of access rights.";
case CM_NVME_SC_SGL_INVALID_OFFSET:
return "SGL_INVALID_OFFSET: The offset specified in a descriptor is invalid.";
case CM_NVME_SC_INCONSISTENT_HOST_ID:
return "INCONSISTENT_HOST_ID: The NVM subsystem detected the simultaneous use of 64-bit and 128-bit Host"
" Identifier values on different controllers.";
case CM_NVME_SC_KEEP_ALIVE_EXPIRED:
return "KEEP_ALIVE_EXPIRED: The Keep Alive Timer expired.";
case CM_NVME_SC_KEEP_ALIVE_INVALID:
return "KEEP_ALIVE_INVALID: The Keep Alive Timeout value specified is invalid.";
case CM_NVME_SC_PREEMPT_ABORT:
return "PREEMPT_ABORT: The command was aborted due to a Reservation Acquire command with the Reservation"
" Acquire Action (RACQA) set to 010b (Preempt and Abort).";
case CM_NVME_SC_SANITIZE_FAILED:
return "SANITIZE_FAILED: The most recent sanitize operation failed and no recovery actions has been"
" successfully completed";
case CM_NVME_SC_SANITIZE_IN_PROGRESS:
return "SANITIZE_IN_PROGRESS: The requested function is prohibited while a sanitize operation is in progress";
case CM_NVME_SC_LBA_RANGE:
return "LBA_RANGE: The command references a LBA that exceeds the size of the namespace";
case CM_NVME_SC_NS_WRITE_PROTECTED:
return "NS_WRITE_PROTECTED: The command is prohibited while the namespace is write protected by the host.";
case CM_NVME_SC_TRANSIENT_TRANSPORT:
return "TRANSIENT_TRANSPORT: A transient transport error was detected.";
case CM_NVME_SC_CAP_EXCEEDED:
return "CAP_EXCEEDED: The execution of the command has caused the capacity of the namespace to be exceeded";
case CM_NVME_SC_NS_NOT_READY:
return "NS_NOT_READY: The namespace is not ready to be accessed as a result of a condition other than a"
" condition that is reported as an Asymmetric Namespace Access condition";
case CM_NVME_SC_RESERVATION_CONFLICT:
return "RESERVATION_CONFLICT: The command was aborted due to a conflict with a reservation held on"
" the accessed namespace";
case CM_NVME_SC_FORMAT_IN_PROGRESS:
return "FORMAT_IN_PROGRESS: A Format NVM command is in progress on the namespace.";
case CM_NVME_SC_CQ_INVALID:
return "CQ_INVALID: The Completion Queue identifier specified in the command does not exist";
case CM_NVME_SC_QID_INVALID:
return "QID_INVALID: The creation of the I/O Completion Queue failed due to an invalid queue identifier"
" specified as part of the command. An invalid queue identifier is one that is currently in use"
" or one that is outside the range supported by the controller";
case CM_NVME_SC_QUEUE_SIZE:
return "QUEUE_SIZE: The host attempted to create an I/O Completion Queue with an invalid number of entries";
case CM_NVME_SC_ABORT_LIMIT:
return "ABORT_LIMIT: The number of concurrently outstanding Abort commands has exceeded the limit indicated"
" in the Identify Controller data structure";
case CM_NVME_SC_ABORT_MISSING:
return "ABORT_MISSING: The abort command is missing";
case CM_NVME_SC_ASYNC_LIMIT:
return "ASYNC_LIMIT: The number of concurrently outstanding Asynchronous Event Request commands"
" has been exceeded";
case CM_NVME_SC_FIRMWARE_SLOT:
return "FIRMWARE_SLOT: The firmware slot indicated is invalid or read only. This error is indicated if the"
" firmware slot exceeds the number supported";
case CM_NVME_SC_FIRMWARE_IMAGE:
return "FIRMWARE_IMAGE: The firmware image specified for activation is invalid and not loaded"
" by the controller";
case CM_NVME_SC_INVALID_VECTOR:
return "INVALID_VECTOR: The creation of the I/O Completion Queue failed due to an invalid interrupt vector"
" specified as part of the command";
case CM_NVME_SC_INVALID_LOG_PAGE:
return "INVALID_LOG_PAGE: The log page indicated is invalid. This error condition is also returned if a"
" reserved log page is requested";
case CM_NVME_SC_INVALID_FORMAT:
return "INVALID_FORMAT: The LBA Format specified is not supported. This may be due to various conditions";
case CM_NVME_SC_FW_NEEDS_CONV_RESET:
return "FW_NEEDS_CONVENTIONAL_RESET: The firmware commit was successful, however, activation of the firmware"
" image requires a conventional reset";
case CM_NVME_SC_INVALID_QUEUE:
return "INVALID_QUEUE: This error indicates that it is invalid to delete the I/O Completion Queue specified."
" The typical reason for this error condition is that there is an associated I/O Submission Queue"
" that has not been deleted.";
case CM_NVME_SC_FEATURE_NOT_SAVEABLE:
return "FEATURE_NOT_SAVEABLE: The Feature Identifier specified does not support a saveable value";
case CM_NVME_SC_FEATURE_NOT_CHANGEABLE:
return "FEATURE_NOT_CHANGEABLE: The Feature Identifier is not able to be changed";
case CM_NVME_SC_FEATURE_NOT_PER_NS:
return "FEATURE_NOT_PER_NS: The Feature Identifier specified is not namespace specific. The Feature Identifier"
" settings apply across all namespaces";
case CM_NVME_SC_FW_NEEDS_SUBSYS_RESET:
return "FW_NEEDS_SUBSYSTEM_RESET: The firmware commit was successful, however, activation of the firmware image"
" requires an NVM Subsystem";
case CM_NVME_SC_FW_NEEDS_RESET:
return "FW_NEEDS_RESET: The firmware commit was successful; however, the image specified does not support being"
" activated without a reset";
case CM_NVME_SC_FW_NEEDS_MAX_TIME:
return "FW_NEEDS_MAX_TIME_VIOLATION: The image specified if activated immediately would exceed"
" the Maximum Time for Firmware Activation (MTFA) value reported in Identify Controller."
" To activate the firmware, the Firmware Commit command needs to be re-issued"
" and the image activated using a reset";
case CM_NVME_SC_FW_ACTIVATE_PROHIBITED:
return "FW_ACTIVATION_PROHIBITED: The image specified is being prohibited from activation by the controller"
" for vendor specific reasons";
case CM_NVME_SC_OVERLAPPING_RANGE:
return "OVERLAPPING_RANGE: This error is indicated if the firmware image has overlapping ranges";
case CM_NVME_SC_NS_INSUFFICIENT_CAP:
return "NS_INSUFFICIENT_CAPACITY: Creating the namespace requires more free space than is currently available."
" The Command Specific Information field of the Error Information Log specifies"
" the total amount of NVM capacity required to create the namespace in bytes";
case CM_NVME_SC_NS_ID_UNAVAILABLE:
return "NS_ID_UNAVAILABLE: The number of namespaces supported has been exceeded";
case CM_NVME_SC_NS_ALREADY_ATTACHED:
return "NS_ALREADY_ATTACHED: The controller is already attached to the namespace specified";
case CM_NVME_SC_NS_IS_PRIVATE:
return "NS_IS_PRIVATE: The namespace is private and is already attached to one controller";
case CM_NVME_SC_NS_NOT_ATTACHED:
return "NS_NOT_ATTACHED: The request to detach the controller could not be completed because"
" the controller is not attached to the namespace";
case CM_NVME_SC_THIN_PROV_NOT_SUPP:
return "THIN_PROVISIONING_NOT_SUPPORTED: Thin provisioning is not supported by the controller";
case CM_NVME_SC_CTRL_LIST_INVALID:
return "CONTROLLER_LIST_INVALID: The controller list provided is invalid";
case CM_NVME_SC_DEVICE_SELF_TEST_IN_PROGRESS:
return "DEVICE_SELF_TEST_IN_PROGRESS: The controller or NVM subsystem already has"
" a device self-test operation in process.";
case CM_NVME_SC_BP_WRITE_PROHIBITED:
return "BOOT PARTITION WRITE PROHIBITED: The command is trying to modify a Boot Partition while it is locked";
case CM_NVME_SC_INVALID_CTRL_ID:
return "INVALID_CTRL_ID: An invalid Controller Identifier was specified.";
case CM_NVME_SC_INVALID_SECONDARY_CTRL_STATE:
return "INVALID_SECONDARY_CTRL_STATE: The action requested for the secondary controller is invalid based"
" on the current state of the secondary controller and its primary controller.";
case CM_NVME_SC_INVALID_NUM_CTRL_RESOURCE:
return "INVALID_NUM_CTRL_RESOURCE: The specified number of Flexible Resources is invalid";
case CM_NVME_SC_INVALID_RESOURCE_ID:
return "INVALID_RESOURCE_ID: At least one of the specified resource identifiers was invalid";
case CM_NVME_SC_ANA_INVALID_GROUP_ID:
return "ANA_INVALID_GROUP_ID: The specified ANA Group Identifier (ANAGRPID) is not supported"
" in the submitted command.";
case CM_NVME_SC_ANA_ATTACH_FAIL:
return "ANA_ATTACH_FAIL: The controller is not attached to the namespace as a result of an ANA condition";
case CM_NVME_SC_BAD_ATTRIBUTES:
return "BAD_ATTRIBUTES: Bad attributes were given";
case CM_NVME_SC_WRITE_FAULT:
return "WRITE_FAULT: The write data could not be committed to the media";
case CM_NVME_SC_READ_ERROR:
return "READ_ERROR: The read data could not be recovered from the media";
case CM_NVME_SC_GUARD_CHECK:
return "GUARD_CHECK: The command was aborted due to an end-to-end guard check failure";
case CM_NVME_SC_APPTAG_CHECK:
return "APPTAG_CHECK: The command was aborted due to an end-to-end application tag check failure";
case CM_NVME_SC_REFTAG_CHECK:
return "REFTAG_CHECK: The command was aborted due to an end-to-end reference tag check failure";
case CM_NVME_SC_COMPARE_FAILED:
return "COMPARE_FAILED: The command failed due to a miscompare during a Compare command";
case CM_NVME_SC_ACCESS_DENIED:
return "ACCESS_DENIED: Access to the namespace and/or LBA range is denied due to lack of access rights";
case CM_NVME_SC_UNWRITTEN_BLOCK:
return "UNWRITTEN_BLOCK: The command failed due to an attempt to read from an LBA range containing"
" a deallocated or unwritten logical block";
case CM_NVME_SC_ANA_PERSISTENT_LOSS:
return "ASYMMETRIC_NAMESPACE_ACCESS_PERSISTENT_LOSS: The requested function (e.g., command)"
" is not able to be performed as a result of the relationship between the controller"
" and the namespace being in the ANA Persistent Loss state";
case CM_NVME_SC_ANA_INACCESSIBLE:
return "ASYMMETRIC_NAMESPACE_ACCESS_INACCESSIBLE: The requested function (e.g., command)"
" is not able to be performed as a result of the relationship between the controller"
" and the namespace being in the ANA Inaccessible state";
case CM_NVME_SC_ANA_TRANSITION:
return "ASYMMETRIC_NAMESPACE_ACCESS_TRANSITION: The requested function (e.g., command)"
" is not able to be performed as a result of the relationship between the controller"
" and the namespace transitioning between Asymmetric Namespace Access states";
case CM_NVME_SC_CMD_INTERRUPTED:
return "CMD_INTERRUPTED: Command processing was interrupted and the controller is unable"
" to successfully complete the command. The host should retry the command.";
case CM_NVME_SC_PMR_SAN_PROHIBITED:
return "Sanitize Prohibited While Persistent Memory Region is Enabled: A sanitize operation"
" is prohibited while the Persistent Memory Region is enabled.";
default:
return "Unknown";
}
}

View File

@ -20,6 +20,7 @@
*
* -------------------------------------------------------------------------
*/
#include <sys/ioctl.h>
#include <sys/types.h>
#include <fcntl.h>
#include <stdio.h>
@ -27,6 +28,9 @@
#include "securec.h"
#include "share_disk_lock.h"
#define CM_DISK_PROTOCOL_SCSI3 0
#define CM_DISK_PROTOCOL_NVME 1
const int BLOCK_NUMS = 3;
const uint32 LOCK_BLOCK_NUMS = 2;
const time_t MAX_VALID_LOCK_TIME = 125;
@ -151,10 +155,31 @@ status_t CmDiskLockS(dlock_t *lock, const char *scsiDev, int32 fd)
return CM_SUCCESS;
}
static cm_disk_caw_hdl_t gCmDiskCawHandle[] = {
{ CmScsi3Caw, "Scsi3 caw" },
{ CmNVMeCaw, "NVMe caw" }
};
static int32 CmDiskProtocol(int32 fd)
{
int32 nsid;
int cmDiskProtocol = CM_DISK_PROTOCOL_SCSI3;
nsid = ioctl(fd, NVME_IOCTL_ID);
if (nsid == -1) {
(void)printf(_("Ioctl get nsid error, errno %d.\n"), errno);
cmDiskProtocol = CM_DISK_PROTOCOL_SCSI3;
} else {
cmDiskProtocol = CM_DISK_PROTOCOL_NVME;
}
return cmDiskProtocol;
}
int32 CmDiskLock(dlock_t *lock, int32 fd)
{
uint32 buffLen = LOCK_BLOCK_NUMS * CM_DEF_BLOCK_SIZE;
int32 cmDiskProtocol = CM_DISK_PROTOCOL_SCSI3;
if (lock == NULL || fd < 0) {
return -1;
}
@ -162,14 +187,15 @@ int32 CmDiskLock(dlock_t *lock, int32 fd)
time_t t = time(NULL);
LOCKW_LOCK_TIME(*lock) = CalcLockTime(t);
LOCKW_LOCK_CREATE_TIME(*lock) = t;
int32 ret = CmScsi3Caw(fd, lock->lockAddr / CM_DEF_BLOCK_SIZE, lock->lockr, buffLen);
cmDiskProtocol = CmDiskProtocol(fd);
int32 ret = gCmDiskCawHandle[cmDiskProtocol].exec(fd, lock->lockAddr / CM_DEF_BLOCK_SIZE, lock->lockr, buffLen);
if (ret != (int)CM_SUCCESS) {
if (ret != CM_SCSI_ERR_MISCOMPARE) {
(void)printf(_("Scsi3 caw failed, addr %lu.\n"), lock->lockAddr);
(void)printf(_("%s failed, addr %lu.\n"), gCmDiskCawHandle[cmDiskProtocol].desc, lock->lockAddr);
return -1;
}
} else {
(void)printf(_("Scsi3 caw succ.\n"));
(void)printf(_("%s succ.\n"), gCmDiskCawHandle[cmDiskProtocol].desc);
return 0;
}
@ -182,28 +208,30 @@ int32 CmDiskLock(dlock_t *lock, int32 fd)
// if the owner of the lock is zero, we can lock succ
LOCKR_INST_ID(*lock) = 0;
LOCKW_LOCK_CREATE_TIME(*lock) = LOCKR_LOCK_CREATE_TIME(*lock);
ret = CmScsi3Caw(fd, lock->lockAddr / CM_DEF_BLOCK_SIZE, lock->lockr, buffLen);
ret = gCmDiskCawHandle[cmDiskProtocol].exec(fd, lock->lockAddr / CM_DEF_BLOCK_SIZE, lock->lockr, buffLen);
if (ret != (int)CM_SUCCESS) {
if (ret != CM_SCSI_ERR_MISCOMPARE) {
(void)printf(_("Scsi3 caw failed after reset, addr %lu.\n"), lock->lockAddr);
(void)printf(_("%s failed after reset, addr %lu.\n"), gCmDiskCawHandle[cmDiskProtocol].desc,
lock->lockAddr);
return -1;
}
} else {
(void)printf(_("Scsi3 caw succ after reset.\n"));
(void)printf(_("%s succ after reset.\n"), gCmDiskCawHandle[cmDiskProtocol].desc);
return 0;
}
// if the owner of the lock on the disk is the current instance, we can lock succ
LOCKR_INST_ID(*lock) = LOCKW_INST_ID(*lock);
LOCKW_LOCK_CREATE_TIME(*lock) = LOCKR_LOCK_CREATE_TIME(*lock);
ret = CmScsi3Caw(fd, lock->lockAddr / CM_DEF_BLOCK_SIZE, lock->lockr, buffLen);
ret = gCmDiskCawHandle[cmDiskProtocol].exec(fd, lock->lockAddr / CM_DEF_BLOCK_SIZE, lock->lockr, buffLen);
if (ret != (int)CM_SUCCESS) {
if (ret == CM_SCSI_ERR_MISCOMPARE) {
// the lock is hold by another instance
LOCKW_LOCK_TIME(*lock) = LOCKR_LOCK_TIME(*lock);
return CM_DLOCK_ERR_LOCK_OCCUPIED;
} else {
(void)printf(_("Scsi3 caw failed when reset instanceId, addr %lu.\n"), lock->lockAddr);
(void)printf(_("%s failed when reset instanceId, addr %lu.\n"), gCmDiskCawHandle[cmDiskProtocol].desc,
lock->lockAddr);
LOCKW_LOCK_TIME(*lock) = LOCKR_LOCK_TIME(*lock);
return -1;
}

View File

@ -0,0 +1,189 @@
/*
* Copyright (c) 2021 Huawei Technologies Co.,Ltd.
*
* CM is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*
* cm_nvme.h
*
*
* IDENTIFICATION
* include/cm/cm_persist/cm_nvme.h
*
* -------------------------------------------------------------------------
*/
#ifndef CM_NVME_H
#define CM_NVME_H
#define _(x) x
typedef unsigned char uchar;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef signed int int32;
typedef unsigned long int uint64;
typedef long int int64;
typedef unsigned int uint32;
struct nvme_user_io {
uint8 opcode;
uint8 flags;
uint16 control;
uint16 nblocks;
uint16 rsvd;
uint64 metadata;
uint64 addr;
uint64 slba;
uint32 dsmgmt;
uint32 reftag;
uint16 apptag;
uint16 appmask;
};
enum {
/*
* Generic Command Status:
*/
CM_NVME_SC_SUCCESS = 0x0,
CM_NVME_SC_INVALID_OPCODE = 0x1,
CM_NVME_SC_INVALID_FIELD = 0x2,
CM_NVME_SC_CMDID_CONFLICT = 0x3,
CM_NVME_SC_DATA_XFER_ERROR = 0x4,
CM_NVME_SC_POWER_LOSS = 0x5,
CM_NVME_SC_INTERNAL = 0x6,
CM_NVME_SC_ABORT_REQ = 0x7,
CM_NVME_SC_ABORT_QUEUE = 0x8,
CM_NVME_SC_FUSED_FAIL = 0x9,
CM_NVME_SC_FUSED_MISSING = 0xa,
CM_NVME_SC_INVALID_NS = 0xb,
CM_NVME_SC_CMD_SEQ_ERROR = 0xc,
CM_NVME_SC_SGL_INVALID_LAST = 0xd,
CM_NVME_SC_SGL_INVALID_COUNT = 0xe,
CM_NVME_SC_SGL_INVALID_DATA = 0xf,
CM_NVME_SC_SGL_INVALID_METADATA = 0x10,
CM_NVME_SC_SGL_INVALID_TYPE = 0x11,
CM_NVME_SC_CMB_INVALID_USE = 0x12,
CM_NVME_SC_PRP_INVALID_OFFSET = 0x13,
CM_NVME_SC_ATOMIC_WRITE_UNIT_EXCEEDED = 0x14,
CM_NVME_SC_OPERATION_DENIED = 0x15,
CM_NVME_SC_SGL_INVALID_OFFSET = 0x16,
CM_NVME_SC_INCONSISTENT_HOST_ID = 0x18,
CM_NVME_SC_KEEP_ALIVE_EXPIRED = 0x19,
CM_NVME_SC_KEEP_ALIVE_INVALID = 0x1A,
CM_NVME_SC_PREEMPT_ABORT = 0x1B,
CM_NVME_SC_SANITIZE_FAILED = 0x1C,
CM_NVME_SC_SANITIZE_IN_PROGRESS = 0x1D,
CM_NVME_SC_NS_WRITE_PROTECTED = 0x20,
CM_NVME_SC_CMD_INTERRUPTED = 0x21,
CM_NVME_SC_TRANSIENT_TRANSPORT = 0x22,
CM_NVME_SC_LBA_RANGE = 0x80,
CM_NVME_SC_CAP_EXCEEDED = 0x81,
CM_NVME_SC_NS_NOT_READY = 0x82,
CM_NVME_SC_RESERVATION_CONFLICT = 0x83,
CM_NVME_SC_FORMAT_IN_PROGRESS = 0x84,
/*
* Command Specific Status:
*/
CM_NVME_SC_CQ_INVALID = 0x100,
CM_NVME_SC_QID_INVALID = 0x101,
CM_NVME_SC_QUEUE_SIZE = 0x102,
CM_NVME_SC_ABORT_LIMIT = 0x103,
CM_NVME_SC_ABORT_MISSING = 0x104,
CM_NVME_SC_ASYNC_LIMIT = 0x105,
CM_NVME_SC_FIRMWARE_SLOT = 0x106,
CM_NVME_SC_FIRMWARE_IMAGE = 0x107,
CM_NVME_SC_INVALID_VECTOR = 0x108,
CM_NVME_SC_INVALID_LOG_PAGE = 0x109,
CM_NVME_SC_INVALID_FORMAT = 0x10a,
CM_NVME_SC_FW_NEEDS_CONV_RESET = 0x10b,
CM_NVME_SC_INVALID_QUEUE = 0x10c,
CM_NVME_SC_FEATURE_NOT_SAVEABLE = 0x10d,
CM_NVME_SC_FEATURE_NOT_CHANGEABLE = 0x10e,
CM_NVME_SC_FEATURE_NOT_PER_NS = 0x10f,
CM_NVME_SC_FW_NEEDS_SUBSYS_RESET = 0x110,
CM_NVME_SC_FW_NEEDS_RESET = 0x111,
CM_NVME_SC_FW_NEEDS_MAX_TIME = 0x112,
CM_NVME_SC_FW_ACTIVATE_PROHIBITED = 0x113,
CM_NVME_SC_OVERLAPPING_RANGE = 0x114,
CM_NVME_SC_NS_INSUFFICIENT_CAP = 0x115,
CM_NVME_SC_NS_ID_UNAVAILABLE = 0x116,
CM_NVME_SC_NS_ALREADY_ATTACHED = 0x118,
CM_NVME_SC_NS_IS_PRIVATE = 0x119,
CM_NVME_SC_NS_NOT_ATTACHED = 0x11a,
CM_NVME_SC_THIN_PROV_NOT_SUPP = 0x11b,
CM_NVME_SC_CTRL_LIST_INVALID = 0x11c,
CM_NVME_SC_DEVICE_SELF_TEST_IN_PROGRESS = 0x11d,
CM_NVME_SC_BP_WRITE_PROHIBITED = 0x11e,
CM_NVME_SC_INVALID_CTRL_ID = 0x11f,
CM_NVME_SC_INVALID_SECONDARY_CTRL_STATE = 0x120,
CM_NVME_SC_INVALID_NUM_CTRL_RESOURCE = 0x121,
CM_NVME_SC_INVALID_RESOURCE_ID = 0x122,
CM_NVME_SC_PMR_SAN_PROHIBITED = 0x123,
CM_NVME_SC_ANA_INVALID_GROUP_ID = 0x124,
CM_NVME_SC_ANA_ATTACH_FAIL = 0x125,
/*
* I/O Command Set Specific - NVM commands:
*/
CM_NVME_SC_BAD_ATTRIBUTES = 0x180,
CM_NVME_SC_INVALID_PI = 0x181,
CM_NVME_SC_READ_ONLY = 0x182,
CM_NVME_SC_ONCS_NOT_SUPPORTED = 0x183,
/*
* I/O Command Set Specific - Fabrics commands:
*/
CM_NVME_SC_CONNECT_FORMAT = 0x180,
CM_NVME_SC_CONNECT_CTRL_BUSY = 0x181,
CM_NVME_SC_CONNECT_INVALID_PARAM = 0x182,
CM_NVME_SC_CONNECT_RESTART_DISC = 0x183,
CM_NVME_SC_CONNECT_INVALID_HOST = 0x184,
CM_NVME_SC_DISCOVERY_RESTART = 0x190,
CM_NVME_SC_AUTH_REQUIRED = 0x191,
/*
* Media and Data Integrity Errors:
*/
CM_NVME_SC_WRITE_FAULT = 0x280,
CM_NVME_SC_READ_ERROR = 0x281,
CM_NVME_SC_GUARD_CHECK = 0x282,
CM_NVME_SC_APPTAG_CHECK = 0x283,
CM_NVME_SC_REFTAG_CHECK = 0x284,
CM_NVME_SC_COMPARE_FAILED = 0x285,
CM_NVME_SC_ACCESS_DENIED = 0x286,
CM_NVME_SC_UNWRITTEN_BLOCK = 0x287,
/*
* Path-related Errors:
*/
CM_NVME_SC_ANA_PERSISTENT_LOSS = 0x301,
CM_NVME_SC_ANA_INACCESSIBLE = 0x302,
CM_NVME_SC_ANA_TRANSITION = 0x303,
CM_NVME_SC_CRD = 0x1800,
CM_NVME_SC_DNR = 0x4000,
};
#define nvme_cmd_write 0x01
#define nvme_cmd_compare 0x05
#define NVME_IOCTL_ID _IO('N', 0x40)
#define NVME_IOCTL_SUBMIT_IO _IOW('N', 0x42, struct nvme_user_io)
int32 CmNVMeCaw(int32 fd, uint64 blockAddr, char *buff, uint32 buffLen);
const char* CmNVMeStatusMessage(uint32 status);
#endif

View File

@ -24,8 +24,10 @@
#ifndef CM_DISK_LOCK_H
#define CM_DISK_LOCK_H
#include <time.h>
#include "cm_nvme.h"
#include "cm_scsi.h"
#define DISK_LOCK_HEADER_MAGIC (0x3847EEFFFFEE3847)
#define DISK_DEFAULT_LOCK_INTERVAL (100)
#define DISK_LOCK_ALIGN_SIZE_512 (512)
@ -106,4 +108,11 @@ status_t CmDiskLockS(dlock_t *lock, const char *scsiDev, int32 fd);
int32 CmDiskLock(dlock_t *lock, int32 fd);
status_t CmDiskLockf(dlock_t *lock, int32 fd, int64 lockTime);
status_t CmGetDlockInfo(dlock_t *lock, int32 fd);
typedef int32 (*CmDiskCaw)(int32 fd, uint64 blockAddr, char *buff, uint32 buffLen);
typedef struct st_cm_disk_caw_hdl {
CmDiskCaw exec;
char * desc;
} cm_disk_caw_hdl_t;
#endif