# SPDX-License-Identifier: LGPL-2.1-or-later
+LIBNVME_1_7 {
+ global:
+ nvme_init_copy_range_f2;
+ nvme_init_copy_range_f3;
+};
+
LIBNVME_1_6 {
global:
nvme_ctrl_config_match;
if (args->format == 1)
data_len = args->nr * sizeof(struct nvme_copy_range_f1);
+ else if (args->format == 2)
+ data_len = args->nr * sizeof(struct nvme_copy_range_f2);
+ else if (args->format == 3)
+ data_len = args->nr * sizeof(struct nvme_copy_range_f3);
else
data_len = args->nr * sizeof(struct nvme_copy_range);
* the Verify command.
* @NVME_CTRL_ONCS_COPY: If set, then the controller supports
* the copy command.
+ * @NVME_CTRL_ONCS_COPY_SINGLE_ATOMICITY: If set, then the write portion of a
+ * Copy command is performed as a single
+ * write command to which the same
+ * atomicity requirements that apply to
+ * a write command apply.
+ * @NVME_CTRL_ONCS_ALL_FAST_COPY: If set, then all copy operations for
+ * the Copy command are fast copy
+ * operations.
*/
enum nvme_id_ctrl_oncs {
NVME_CTRL_ONCS_COMPARE = 1 << 0,
NVME_CTRL_ONCS_TIMESTAMP = 1 << 6,
NVME_CTRL_ONCS_VERIFY = 1 << 7,
NVME_CTRL_ONCS_COPY = 1 << 8,
+ NVME_CTRL_ONCS_COPY_SINGLE_ATOMICITY = 1 << 9,
+ NVME_CTRL_ONCS_ALL_FAST_COPY = 1 << 10,
};
/**
* struct nvme_feat_host_behavior - Host Behavior Support - Data Structure
* @acre: Advanced Command Retry Enable
* @rsvd1: Reserved
+ * @cdfe: Copy Descriptor Formats Enable
+ * @rsvd6: Reserved
*/
struct nvme_feat_host_behavior {
__u8 acre;
- __u8 rsvd1[511];
+ __u8 rsvd1[3];
+ __u16 cdfe;
+ __u8 rsvd6[506];
};
/**
__le16 elbatm;
};
+/**
+ * enum nvme_copy_range_sopt - NVMe Copy Range Source Options
+ * @NVME_COPY_SOPT_FCO: NVMe Copy Source Option Fast Copy Only
+ */
+enum nvme_copy_range_sopt {
+ NVME_COPY_SOPT_FCO = 1 << 15,
+};
+
+/**
+ * struct nvme_copy_range_f2 - Copy - Source Range Entries Descriptor Format 2h
+ * @snsid: Source Namespace Identifier
+ * @rsvd4: Reserved
+ * @slba: Starting LBA
+ * @nlb: Number of Logical Blocks
+ * @rsvd18: Reserved
+ * @sopt: Source Options
+ * @eilbrt: Expected Initial Logical Block Reference Tag /
+ * Expected Logical Block Storage Tag
+ * @elbatm: Expected Logical Block Application Tag Mask
+ * @elbat: Expected Logical Block Application Tag
+ */
+struct nvme_copy_range_f2 {
+ __le32 snsid;
+ __u8 rsvd4[4];
+ __le64 slba;
+ __le16 nlb;
+ __u8 rsvd18[4];
+ __le16 sopt;
+ __le32 eilbrt;
+ __le16 elbat;
+ __le16 elbatm;
+};
+
+/**
+ * struct nvme_copy_range_f3 - Copy - Source Range Entries Descriptor Format 3h
+ * @snsid: Source Namespace Identifier
+ * @rsvd4: Reserved
+ * @slba: Starting LBA
+ * @nlb: Number of Logical Blocks
+ * @rsvd18: Reserved
+ * @sopt: Source Options
+ * @rsvd24: Reserved
+ * @elbt: Expected Initial Logical Block Reference Tag /
+ * Expected Logical Block Storage Tag
+ * @elbatm: Expected Logical Block Application Tag Mask
+ * @elbat: Expected Logical Block Application Tag
+ */
+struct nvme_copy_range_f3 {
+ __le32 snsid;
+ __u8 rsvd4[4];
+ __le64 slba;
+ __le16 nlb;
+ __u8 rsvd18[4];
+ __le16 sopt;
+ __u8 rsvd24[2];
+ __u8 elbt[10];
+ __le16 elbat;
+ __le16 elbatm;
+};
+
/**
* struct nvme_registered_ctrl - Registered Controller Data Structure
* @cntlid: Controller ID
* @NVME_SC_INVALID_PI: Invalid Protection Information
* @NVME_SC_READ_ONLY: Attempted Write to Read Only Range
* @NVME_SC_CMD_SIZE_LIMIT_EXCEEDED: Command Size Limit Exceeded
+ * @NVME_SC_INCOMPATIBLE_NS: Incompatible Namespace or Format: At
+ * least one source namespace and the
+ * destination namespace have incompatible
+ * formats.
+ * @NVME_SC_FAST_COPY_NOT_POSSIBLE: Fast Copy Not Possible: The Fast Copy
+ * Only (FCO) bit was set to ‘1’ in a Source
+ * Range entry and the controller was not
+ * able to use fast copy operations to copy
+ * the specified data.
+ * @NVME_SC_OVERLAPPING_IO_RANGE: Overlapping I/O Range: A source logical
+ * block range overlaps the destination
+ * logical block range.
+ * @NVME_SC_INSUFFICIENT_RESOURCES: Insufficient Resources: A resource
+ * shortage prevented the controller from
+ * performing the requested copy.
* @NVME_SC_CONNECT_FORMAT: Incompatible Format: The NVM subsystem
* does not support the record format
* specified by the host.
NVME_SC_INVALID_PI = 0x81,
NVME_SC_READ_ONLY = 0x82,
NVME_SC_CMD_SIZE_LIMIT_EXCEEDED = 0x83,
+ NVME_SC_INCOMPATIBLE_NS = 0x85,
+ NVME_SC_FAST_COPY_NOT_POSSIBLE = 0x86,
+ NVME_SC_OVERLAPPING_IO_RANGE = 0x87,
+ NVME_SC_INSUFFICIENT_RESOURCES = 0x89,
/*
* I/O Command Set Specific - Fabrics commands:
[NVME_SC_INVALID_PI] = "Invalid Protection Information: The command's Protection Information Field settings are invalid for the namespace's Protection Information format",
[NVME_SC_READ_ONLY] = "Attempted Write to Read Only Range: The LBA range specified contains read-only blocks",
[NVME_SC_CMD_SIZE_LIMIT_EXCEEDED] = "Command Size Limit Exceeded",
+ [NVME_SC_INCOMPATIBLE_NS] = "Incompatible Namespace or Format",
+ [NVME_SC_FAST_COPY_NOT_POSSIBLE] = "Fast Copy Not Possible",
+ [NVME_SC_OVERLAPPING_IO_RANGE] = "Overlapping I/O Range",
+ [NVME_SC_INSUFFICIENT_RESOURCES] = "Insufficient Resources",
[NVME_SC_ZNS_INVALID_OP_REQUEST] = "Invalid Zone Operation Request: The operation requested is invalid",
[NVME_SC_ZNS_ZRWA_RESOURCES_UNAVAILABLE] = "ZRWA Resources Unavailable: No ZRWAs are available",
[NVME_SC_ZNS_BOUNDARY_ERROR] = "Zoned Boundary Error: Invalid Zone Boundary crossing",
return s;
}
+static inline void nvme_init_copy_range_elbt(__u8 *elbt, __u64 eilbrt)
+{
+ int i;
+
+ for (i = 0; i < 8; i++)
+ elbt[9 - i] = (eilbrt >> (8 * i)) & 0xff;
+ elbt[1] = 0;
+ elbt[0] = 0;
+}
+
void nvme_init_copy_range(struct nvme_copy_range *copy, __u16 *nlbs,
__u64 *slbas, __u32 *eilbrts, __u32 *elbatms,
__u32 *elbats, __u16 nr)
__u64 *slbas, __u64 *eilbrts, __u32 *elbatms,
__u32 *elbats, __u16 nr)
{
- int i, j;
+ int i;
for (i = 0; i < nr; i++) {
copy[i].nlb = cpu_to_le16(nlbs[i]);
copy[i].slba = cpu_to_le64(slbas[i]);
copy[i].elbatm = cpu_to_le16(elbatms[i]);
copy[i].elbat = cpu_to_le16(elbats[i]);
- for (j = 0; j < 8; j++)
- copy[i].elbt[9 - j] = (eilbrts[i] >> (8 * j)) & 0xff;
- copy[i].elbt[1] = 0;
- copy[i].elbt[0] = 0;
+ nvme_init_copy_range_elbt(copy[i].elbt, eilbrts[i]);
}
}
+void nvme_init_copy_range_f2(struct nvme_copy_range_f2 *copy, __u32 *snsids,
+ __u16 *nlbs, __u64 *slbas, __u16 *sopts,
+ __u32 *eilbrts, __u32 *elbatms, __u32 *elbats,
+ __u16 nr)
+{
+ int i;
+
+ for (i = 0; i < nr; i++) {
+ copy[i].snsid = cpu_to_le32(snsids[i]);
+ copy[i].nlb = cpu_to_le16(nlbs[i]);
+ copy[i].slba = cpu_to_le64(slbas[i]);
+ copy[i].sopt = cpu_to_le16(sopts[i]);
+ copy[i].eilbrt = cpu_to_le32(eilbrts[i]);
+ copy[i].elbatm = cpu_to_le16(elbatms[i]);
+ copy[i].elbat = cpu_to_le16(elbats[i]);
+ }
+}
+
+void nvme_init_copy_range_f3(struct nvme_copy_range_f3 *copy, __u32 *snsids,
+ __u16 *nlbs, __u64 *slbas, __u16 *sopts,
+ __u64 *eilbrts, __u32 *elbatms, __u32 *elbats,
+ __u16 nr)
+{
+ int i;
+
+ for (i = 0; i < nr; i++) {
+ copy[i].snsid = cpu_to_le32(snsids[i]);
+ copy[i].nlb = cpu_to_le16(nlbs[i]);
+ copy[i].slba = cpu_to_le64(slbas[i]);
+ copy[i].sopt = cpu_to_le16(sopts[i]);
+ copy[i].elbatm = cpu_to_le16(elbatms[i]);
+ copy[i].elbat = cpu_to_le16(elbats[i]);
+ nvme_init_copy_range_elbt(copy[i].elbt, eilbrts[i]);
+ }
+}
+
void nvme_init_dsm_range(struct nvme_dsm_range *dsm, __u32 *ctx_attrs,
__u32 *llbas, __u64 *slbas, __u16 nr_ranges)
{
__u64 *slbas, __u64 *eilbrts, __u32 *elbatms,
__u32 *elbats, __u16 nr);
+/**
+ * nvme_init_copy_range_f2() - Constructs a copy range f2 structure
+ * @copy: Copy range array
+ * @snsids: Source namespace identifier
+ * @nlbs: Number of logical blocks
+ * @slbas: Starting LBA
+ * @sopts: Source options
+ * @eilbrts: Expected initial logical block reference tag
+ * @elbatms: Expected logical block application tag mask
+ * @elbats: Expected logical block application tag
+ * @nr: Number of descriptors to construct
+ */
+void nvme_init_copy_range_f2(struct nvme_copy_range_f2 *copy, __u32 *snsids,
+ __u16 *nlbs, __u64 *slbas, __u16 *sopts,
+ __u32 *eilbrts, __u32 *elbatms, __u32 *elbats,
+ __u16 nr);
+
+/**
+ * nvme_init_copy_range_f3() - Constructs a copy range f3 structure
+ * @copy: Copy range array
+ * @snsids: Source namespace identifier
+ * @nlbs: Number of logical blocks
+ * @slbas: Starting LBA
+ * @sopts: Source options
+ * @eilbrts: Expected initial logical block reference tag
+ * @elbatms: Expected logical block application tag mask
+ * @elbats: Expected logical block application tag
+ * @nr: Number of descriptors to construct
+ */
+void nvme_init_copy_range_f3(struct nvme_copy_range_f3 *copy, __u32 *snsids,
+ __u16 *nlbs, __u64 *slbas, __u16 *sopts,
+ __u64 *eilbrts, __u32 *elbatms, __u32 *elbats,
+ __u16 nr);
+
/**
* nvme_get_feature_length() - Retreive the command payload length for a
* specific feature identifier