Skip to content

Commit 91f66d5

Browse files
authored
Merge pull request #358 from jeffreyalien/tp-4068-4084
Changes to support TP 4068 and TP 4084
2 parents 34475e2 + 9e4d83a commit 91f66d5

7 files changed

Lines changed: 299 additions & 45 deletions

File tree

doc/rst/util.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,34 @@ otherwise.
181181
Number of descriptors to construct
182182
183183
184+
.. c:function:: void nvme_init_copy_range_fl (struct nvme_copy_range_f1 *copy, __u16 *nlbs, __u64 *slbas, __u64 *eilbrts, __u32 *elbatms, __u32 *elbats, __u16 nr)
185+
186+
Constructs a copy range formate 1 structure
187+
188+
**Parameters**
189+
190+
``struct nvme_copy_range_f1 *copy``
191+
Copy range array
192+
193+
``__u16 *nlbs``
194+
Number of logical blocks
195+
196+
``__u64 *slbas``
197+
Starting LBA
198+
199+
``__u64 *eilbrts``
200+
Expected initial logical block reference tag
201+
202+
``__u32 *elbatms``
203+
Expected logical block application tag mask
204+
205+
``__u32 *elbats``
206+
Expected logical block application tag
207+
208+
``__u16 nr``
209+
Number of descriptors to construct
210+
211+
184212
.. c:function:: int nvme_get_feature_length (int fid, __u32 cdw11, __u32 *len)
185213
186214
Retreive the command payload length for a specific feature identifier

src/libnvme.map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
LIBNVME_1_1 {
44
global:
55
nvme_get_version;
6+
nvme_init_copy_range_f1;
67
};
78

89
LIBNVME_1_0 {

src/nvme/ioctl.c

Lines changed: 142 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,13 @@ enum nvme_cmd_dword_fields {
267267
NVME_FORMAT_CDW10_PI_SHIFT = 5,
268268
NVME_FORMAT_CDW10_PIL_SHIFT = 8,
269269
NVME_FORMAT_CDW10_SES_SHIFT = 9,
270+
NVME_FORMAT_CDW10_LBAFU_SHIFT = 12,
270271
NVME_FORMAT_CDW10_LBAF_MASK = 0xf,
271272
NVME_FORMAT_CDW10_MSET_MASK = 0x1,
272273
NVME_FORMAT_CDW10_PI_MASK = 0x7,
273274
NVME_FORMAT_CDW10_PIL_MASK = 0x1,
274275
NVME_FORMAT_CDW10_SES_MASK = 0x7,
276+
NVME_FORMAT_CDW10_LBAFU_MASK = 0x3,
275277
NVME_SANITIZE_CDW10_SANACT_SHIFT = 0,
276278
NVME_SANITIZE_CDW10_AUSE_SHIFT = 3,
277279
NVME_SANITIZE_CDW10_OWPASS_SHIFT = 4,
@@ -1159,11 +1161,25 @@ int nvme_get_features_iocs_profile(int fd, enum nvme_get_features_sel sel,
11591161

11601162
int nvme_format_nvm(struct nvme_format_nvm_args *args)
11611163
{
1162-
__u32 cdw10 = NVME_SET(args->lbaf, FORMAT_CDW10_LBAF) |
1163-
NVME_SET(args->mset, FORMAT_CDW10_MSET) |
1164-
NVME_SET(args->pi, FORMAT_CDW10_PI) |
1165-
NVME_SET(args->pil, FORMAT_CDW10_PIL) |
1166-
NVME_SET(args->ses, FORMAT_CDW10_SES);
1164+
const size_t size_v1 = sizeof_args(struct nvme_format_nvm_args, lbaf, __u64);
1165+
const size_t size_v2 = sizeof_args(struct nvme_format_nvm_args, lbafu, __u64);
1166+
__u32 cdw10;
1167+
1168+
if (args->args_size < size_v1 || args->args_size > size_v2) {
1169+
errno = EINVAL;
1170+
return -1;
1171+
}
1172+
1173+
cdw10 = NVME_SET(args->lbaf, FORMAT_CDW10_LBAF) |
1174+
NVME_SET(args->mset, FORMAT_CDW10_MSET) |
1175+
NVME_SET(args->pi, FORMAT_CDW10_PI) |
1176+
NVME_SET(args->pil, FORMAT_CDW10_PIL) |
1177+
NVME_SET(args->ses, FORMAT_CDW10_SES);
1178+
1179+
if (args->args_size == size_v2) {
1180+
/* set lbafu extension */
1181+
cdw10 |= NVME_SET(args->lbafu, FORMAT_CDW10_LBAFU);
1182+
}
11671183

11681184
struct nvme_passthru_cmd cmd = {
11691185
.opcode = nvme_admin_format_nvm,
@@ -1172,10 +1188,6 @@ int nvme_format_nvm(struct nvme_format_nvm_args *args)
11721188
.timeout_ms = args->timeout,
11731189
};
11741190

1175-
if (args->args_size < sizeof(*args)) {
1176-
errno = EINVAL;
1177-
return -1;
1178-
}
11791191
return nvme_submit_admin_passthru(args->fd, &cmd, args->result);
11801192
}
11811193

@@ -1588,16 +1600,81 @@ int nvme_io_passthru(int fd, __u8 opcode, __u8 flags, __u16 rsvd,
15881600
timeout_ms, result);
15891601
}
15901602

1603+
static int nvme_set_var_size_tags(__u32 *cmd_dw2, __u32 *cmd_dw3, __u32 *cmd_dw14,
1604+
__u8 pif, __u8 sts, __u64 reftag, __u64 storage_tag)
1605+
{
1606+
__u32 cdw2 = 0, cdw3 = 0, cdw14;
1607+
1608+
switch (pif) {
1609+
/* 16b Protection Information */
1610+
case 0:
1611+
cdw14 = reftag & 0xffffffff;
1612+
cdw14 |= ((storage_tag << (32 - sts)) & 0xffffffff);
1613+
break;
1614+
/* 32b Protection Information */
1615+
case 1:
1616+
cdw14 = reftag & 0xffffffff;
1617+
cdw3 = reftag >> 32;
1618+
cdw14 |= ((storage_tag << (80 - sts)) & 0xffff0000);
1619+
if (sts >= 48)
1620+
cdw3 |= ((storage_tag >> (sts - 48)) & 0xffffffff);
1621+
else
1622+
cdw3 |= ((storage_tag << (48 - sts)) & 0xffffffff);
1623+
cdw2 = (storage_tag >> (sts - 16)) & 0xffff;
1624+
break;
1625+
/* 64b Protection Information */
1626+
case 2:
1627+
cdw14 = reftag & 0xffffffff;
1628+
cdw3 = (reftag >> 32) & 0xffff;
1629+
cdw14 |= ((storage_tag << (48 - sts)) & 0xffffffff);
1630+
if (sts >= 16)
1631+
cdw3 |= ((storage_tag >> (sts - 16)) & 0xffff);
1632+
else
1633+
cdw3 |= ((storage_tag << (16 - sts)) & 0xffff);
1634+
break;
1635+
default:
1636+
perror("Unsupported Protection Information Format");
1637+
errno = EINVAL;
1638+
return -1;
1639+
}
1640+
1641+
*cmd_dw2 = cdw2;
1642+
*cmd_dw3 = cdw3;
1643+
*cmd_dw14 = cdw14;
1644+
return 0;
1645+
}
1646+
15911647
int nvme_io(struct nvme_io_args *args, __u8 opcode)
15921648
{
1593-
__u32 cdw2 = args->storage_tag & 0xffffffff;
1594-
__u32 cdw3 = (args->storage_tag >> 32) & 0xffff;
1595-
__u32 cdw10 = args->slba & 0xffffffff;
1596-
__u32 cdw11 = args->slba >> 32;
1597-
__u32 cdw12 = args->nlb | (args->control << 16);
1598-
__u32 cdw13 = args->dsm | (args->dspec << 16);
1599-
__u32 cdw14 = args->reftag;
1600-
__u32 cdw15 = args->apptag | (args->appmask << 16);
1649+
const size_t size_v1 = sizeof_args(struct nvme_io_args, dsm, __u64);
1650+
const size_t size_v2 = sizeof_args(struct nvme_io_args, pif, __u64);
1651+
__u32 cdw2, cdw3, cdw10, cdw11, cdw12, cdw13, cdw14, cdw15;
1652+
1653+
if (args->args_size < size_v1 || args->args_size > size_v2) {
1654+
errno = EINVAL;
1655+
return -1;
1656+
}
1657+
1658+
cdw10 = args->slba & 0xffffffff;
1659+
cdw11 = args->slba >> 32;
1660+
cdw12 = args->nlb | (args->control << 16);
1661+
cdw13 = args->dsm | (args->dspec << 16);
1662+
cdw15 = args->apptag | (args->appmask << 16);
1663+
1664+
if (args->args_size == size_v1) {
1665+
cdw2 = (args->storage_tag >> 32) & 0xffff;
1666+
cdw3 = args->storage_tag & 0xffffffff;
1667+
cdw14 = args->reftag;
1668+
} else {
1669+
if (nvme_set_var_size_tags(&cdw2, &cdw3, &cdw14,
1670+
args->pif,
1671+
args->sts,
1672+
args->reftag_u64,
1673+
args->storage_tag)) {
1674+
errno = EINVAL;
1675+
return -1;
1676+
}
1677+
}
16011678

16021679
struct nvme_passthru_cmd cmd = {
16031680
.opcode = opcode,
@@ -1617,10 +1694,6 @@ int nvme_io(struct nvme_io_args *args, __u8 opcode)
16171694
.timeout_ms = args->timeout,
16181695
};
16191696

1620-
if (args->args_size < sizeof(*args)) {
1621-
errno = EINVAL;
1622-
return -1;
1623-
}
16241697
return nvme_submit_io_passthru(args->fd, &cmd, args->result);
16251698
}
16261699

@@ -1645,29 +1718,48 @@ int nvme_dsm(struct nvme_dsm_args *args)
16451718

16461719
int nvme_copy(struct nvme_copy_args *args)
16471720
{
1648-
__u32 cdw12 = ((args->nr - 1) & 0xff) | ((args->format & 0xf) << 8) |
1721+
const size_t size_v1 = sizeof_args(struct nvme_copy_args, format, __u64);
1722+
const size_t size_v2 = sizeof_args(struct nvme_copy_args, ilbrt_u64, __u64);
1723+
__u32 cdw3, cdw12, cdw14, data_len;
1724+
1725+
if (args->args_size < size_v1 || args->args_size > size_v2) {
1726+
errno = EINVAL;
1727+
return -1;
1728+
}
1729+
1730+
cdw12 = ((args->nr - 1) & 0xff) | ((args->format & 0xf) << 8) |
16491731
((args->prinfor & 0xf) << 12) | ((args->dtype & 0xf) << 20) |
16501732
((args->prinfow & 0xf) << 26) | ((args->fua & 0x1) << 30) |
16511733
((args->lr & 0x1) << 31);
16521734

1735+
if (args->args_size == size_v1) {
1736+
cdw3 = 0;
1737+
cdw14 = args->ilbrt;
1738+
} else {
1739+
cdw3 = (args->ilbrt_u64 >> 32) & 0xffffffff;
1740+
cdw14 = args->ilbrt_u64 & 0xffffffff;
1741+
}
1742+
1743+
if (args->format == 1)
1744+
data_len = args->nr * sizeof(struct nvme_copy_range_f1);
1745+
else
1746+
data_len = args->nr * sizeof(struct nvme_copy_range);
1747+
16531748
struct nvme_passthru_cmd cmd = {
16541749
.opcode = nvme_cmd_copy,
16551750
.nsid = args->nsid,
16561751
.addr = (__u64)(uintptr_t)args->copy,
1657-
.data_len = args->nr * sizeof(*args->copy),
1752+
.data_len = data_len,
1753+
.cdw3 = cdw3,
16581754
.cdw10 = args->sdlba & 0xffffffff,
16591755
.cdw11 = args->sdlba >> 32,
16601756
.cdw12 = cdw12,
16611757
.cdw13 = (args->dspec & 0xffff) << 16,
1662-
.cdw14 = args->ilbrt,
1758+
.cdw14 = cdw14,
16631759
.cdw15 = (args->lbatm << 16) | args->lbat,
16641760
.timeout_ms = args->timeout,
16651761
};
16661762

1667-
if (args->args_size < sizeof(*args)) {
1668-
errno = EINVAL;
1669-
return -1;
1670-
}
16711763
return nvme_submit_io_passthru(args->fd, &cmd, args->result);
16721764
}
16731765

@@ -1821,15 +1913,32 @@ int nvme_zns_mgmt_recv(struct nvme_zns_mgmt_recv_args *args)
18211913

18221914
int nvme_zns_append(struct nvme_zns_append_args *args)
18231915
{
1824-
__u32 cdw10 = args->zslba & 0xffffffff;
1825-
__u32 cdw11 = args->zslba >> 32;
1826-
__u32 cdw12 = args->nlb | (args->control << 16);
1827-
__u32 cdw14 = args->ilbrt;
1828-
__u32 cdw15 = args->lbat | (args->lbatm << 16);
1916+
const size_t size_v1 = sizeof_args(struct nvme_zns_append_args, lbatm, __u64);
1917+
const size_t size_v2 = sizeof_args(struct nvme_zns_append_args, ilbrt_u64, __u64);
1918+
__u32 cdw3, cdw10, cdw11, cdw12, cdw14, cdw15;
1919+
1920+
if (args->args_size < size_v1 || args->args_size > size_v2) {
1921+
errno = EINVAL;
1922+
return -1;
1923+
}
1924+
1925+
cdw10 = args->zslba & 0xffffffff;
1926+
cdw11 = args->zslba >> 32;
1927+
cdw12 = args->nlb | (args->control << 16);
1928+
cdw15 = args->lbat | (args->lbatm << 16);
1929+
1930+
if (args->args_size == size_v1) {
1931+
cdw3 = 0;
1932+
cdw14 = args->ilbrt;
1933+
} else {
1934+
cdw3 = (args->ilbrt_u64 >> 32) & 0xffffffff;
1935+
cdw14 = args->ilbrt_u64 & 0xffffffff;
1936+
}
18291937

18301938
struct nvme_passthru_cmd64 cmd = {
18311939
.opcode = nvme_zns_cmd_append,
18321940
.nsid = args->nsid,
1941+
.cdw3 = cdw3,
18331942
.cdw10 = cdw10,
18341943
.cdw11 = cdw11,
18351944
.cdw12 = cdw12,
@@ -1842,10 +1951,6 @@ int nvme_zns_append(struct nvme_zns_append_args *args)
18421951
.timeout_ms = args->timeout,
18431952
};
18441953

1845-
if (args->args_size < sizeof(*args)) {
1846-
errno = EINVAL;
1847-
return -1;
1848-
}
18491954
return nvme_submit_io_passthru64(args->fd, &cmd, args->result);
18501955
}
18511956

0 commit comments

Comments
 (0)