hw/nvme patches
* namespace eui64 support (Heinrich) * aiocb refactoring (Klaus) * controller parameter for auto zone transitioning (Niklas) * misc fixes and additions (Gollu, Klaus, Keith) -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEUigzqnXi3OaiR2bATeGvMW1PDekFAmDbap8ACgkQTeGvMW1P Denz9wf9GtU4z7G0pQpFlv1smWPvQfv9qlkGiRvGcIQjEgPjcKjEsJC1CqtG6nZ5 BGYzey706iM7NAs6wPkyUyHgWXl+N/Ku5nNBvNJuzTN5J9aHgnqehe8civvS6ONU 0WtAQEEZCLu0Qbvw6KawCShXrJ6Jpmu+bYGggYEy5+baumLF0Qj50l2wRiDbImNu rE3iZuhEenwnNNSTTkyt2RT8lSzizAtth4bAqzl3Zw1Q3NO+qDCL0wPOWD7YuD8p LTZ8/ojB1+YUI3JrMM4MlzbJyGstdk2Y5zq6QpAcf86agaaFEmS0iqjOic52ImpL VzmZZZ0W7kmhJVc5H/Q5y/KAFIHnFA== =efjI -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/nvme/tags/nvme-next-pull-request' into staging hw/nvme patches * namespace eui64 support (Heinrich) * aiocb refactoring (Klaus) * controller parameter for auto zone transitioning (Niklas) * misc fixes and additions (Gollu, Klaus, Keith) # gpg: Signature made Tue 29 Jun 2021 19:46:55 BST # gpg: using RSA key 522833AA75E2DCE6A24766C04DE1AF316D4F0DE9 # gpg: Good signature from "Klaus Jensen <its@irrelevant.dk>" [unknown] # gpg: aka "Klaus Jensen <k.jensen@samsung.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: DDCA 4D9C 9EF9 31CC 3468 4272 63D5 6FC5 E55D A838 # Subkey fingerprint: 5228 33AA 75E2 DCE6 A247 66C0 4DE1 AF31 6D4F 0DE9 * remotes/nvme/tags/nvme-next-pull-request: (23 commits) hw/nvme: add 'zoned.zasl' to documentation hw/nvme: fix pin-based interrupt behavior (again) hw/nvme: fix missing check for PMR capability hw/nvme: documentation fix hw/nvme: fix endianess conversion and add controller list Partially revert "hw/block/nvme: drain namespaces on sq deletion" hw/nvme: reimplement format nvm to allow cancellation hw/nvme: reimplement zone reset to allow cancellation hw/nvme: reimplement the copy command to allow aio cancellation hw/nvme: add dw0/1 to the req completion trace event hw/nvme: use prinfo directly in nvme_check_prinfo and nvme_dif_check hw/nvme: remove assert from nvme_get_zone_by_slba hw/nvme: save reftag when generating pi hw/nvme: reimplement dsm to allow cancellation hw/nvme: add nvme_block_status_all helper hw/nvme: reimplement flush to allow cancellation hw/nvme: default for namespace EUI-64 hw/nvme: namespace parameter for EUI-64 hw/nvme: fix csi field for cns 0x00 and 0x11 hw/nvme: add param to control auto zone transitioning to zone state closed ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1ec2cd0ce2
@ -81,6 +81,12 @@ There are a number of parameters available:
|
||||
Set the UUID of the namespace. This will be reported as a "Namespace UUID"
|
||||
descriptor in the Namespace Identification Descriptor List.
|
||||
|
||||
``eui64``
|
||||
Set the EUI-64 of the namespace. This will be reported as a "IEEE Extended
|
||||
Unique Identifier" descriptor in the Namespace Identification Descriptor List.
|
||||
Since machine type 6.1 a non-zero default value is used if the parameter
|
||||
is not provided. For earlier machine types the field defaults to 0.
|
||||
|
||||
``bus``
|
||||
If there are more ``nvme`` devices defined, this parameter may be used to
|
||||
attach the namespace to a specific ``nvme`` device (identified by an ``id``
|
||||
@ -196,6 +202,12 @@ The namespace may be configured with additional parameters
|
||||
allows all zones to be open. If ``zoned.max_active`` is specified, this value
|
||||
must be less than or equal to that.
|
||||
|
||||
``zoned.zasl=UINT8`` (default: ``0``)
|
||||
Set the maximum data transfer size for the Zone Append command. Like
|
||||
``mdts``, the value is specified as a power of two (2^n) and is in units of
|
||||
the minimum memory page size (CAP.MPSMIN). The default value (``0``)
|
||||
has this property inherit the ``mdts`` value.
|
||||
|
||||
Metadata
|
||||
--------
|
||||
|
||||
|
@ -39,6 +39,7 @@
|
||||
GlobalProperty hw_compat_6_0[] = {
|
||||
{ "gpex-pcihost", "allow-unmapped-accesses", "false" },
|
||||
{ "i8042", "extended-state", "false"},
|
||||
{ "nvme-ns", "eui64-default", "off"},
|
||||
};
|
||||
const size_t hw_compat_6_0_len = G_N_ELEMENTS(hw_compat_6_0);
|
||||
|
||||
|
2039
hw/nvme/ctrl.c
2039
hw/nvme/ctrl.c
File diff suppressed because it is too large
Load Diff
@ -15,11 +15,11 @@
|
||||
#include "nvme.h"
|
||||
#include "trace.h"
|
||||
|
||||
uint16_t nvme_check_prinfo(NvmeNamespace *ns, uint16_t ctrl, uint64_t slba,
|
||||
uint16_t nvme_check_prinfo(NvmeNamespace *ns, uint8_t prinfo, uint64_t slba,
|
||||
uint32_t reftag)
|
||||
{
|
||||
if ((NVME_ID_NS_DPS_TYPE(ns->id_ns.dps) == NVME_ID_NS_DPS_TYPE_1) &&
|
||||
(ctrl & NVME_RW_PRINFO_PRCHK_REF) && (slba & 0xffffffff) != reftag) {
|
||||
(prinfo & NVME_PRINFO_PRCHK_REF) && (slba & 0xffffffff) != reftag) {
|
||||
return NVME_INVALID_PROT_INFO | NVME_DNR;
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ static uint16_t crc_t10dif(uint16_t crc, const unsigned char *buffer,
|
||||
|
||||
void nvme_dif_pract_generate_dif(NvmeNamespace *ns, uint8_t *buf, size_t len,
|
||||
uint8_t *mbuf, size_t mlen, uint16_t apptag,
|
||||
uint32_t reftag)
|
||||
uint32_t *reftag)
|
||||
{
|
||||
uint8_t *end = buf + len;
|
||||
int16_t pil = 0;
|
||||
@ -51,7 +51,7 @@ void nvme_dif_pract_generate_dif(NvmeNamespace *ns, uint8_t *buf, size_t len,
|
||||
}
|
||||
|
||||
trace_pci_nvme_dif_pract_generate_dif(len, ns->lbasz, ns->lbasz + pil,
|
||||
apptag, reftag);
|
||||
apptag, *reftag);
|
||||
|
||||
for (; buf < end; buf += ns->lbasz, mbuf += ns->lbaf.ms) {
|
||||
NvmeDifTuple *dif = (NvmeDifTuple *)(mbuf + pil);
|
||||
@ -63,17 +63,17 @@ void nvme_dif_pract_generate_dif(NvmeNamespace *ns, uint8_t *buf, size_t len,
|
||||
|
||||
dif->guard = cpu_to_be16(crc);
|
||||
dif->apptag = cpu_to_be16(apptag);
|
||||
dif->reftag = cpu_to_be32(reftag);
|
||||
dif->reftag = cpu_to_be32(*reftag);
|
||||
|
||||
if (NVME_ID_NS_DPS_TYPE(ns->id_ns.dps) != NVME_ID_NS_DPS_TYPE_3) {
|
||||
reftag++;
|
||||
(*reftag)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t nvme_dif_prchk(NvmeNamespace *ns, NvmeDifTuple *dif,
|
||||
uint8_t *buf, uint8_t *mbuf, size_t pil,
|
||||
uint16_t ctrl, uint16_t apptag,
|
||||
uint8_t prinfo, uint16_t apptag,
|
||||
uint16_t appmask, uint32_t reftag)
|
||||
{
|
||||
switch (NVME_ID_NS_DPS_TYPE(ns->id_ns.dps)) {
|
||||
@ -95,7 +95,7 @@ static uint16_t nvme_dif_prchk(NvmeNamespace *ns, NvmeDifTuple *dif,
|
||||
return NVME_SUCCESS;
|
||||
}
|
||||
|
||||
if (ctrl & NVME_RW_PRINFO_PRCHK_GUARD) {
|
||||
if (prinfo & NVME_PRINFO_PRCHK_GUARD) {
|
||||
uint16_t crc = crc_t10dif(0x0, buf, ns->lbasz);
|
||||
|
||||
if (pil) {
|
||||
@ -109,7 +109,7 @@ static uint16_t nvme_dif_prchk(NvmeNamespace *ns, NvmeDifTuple *dif,
|
||||
}
|
||||
}
|
||||
|
||||
if (ctrl & NVME_RW_PRINFO_PRCHK_APP) {
|
||||
if (prinfo & NVME_PRINFO_PRCHK_APP) {
|
||||
trace_pci_nvme_dif_prchk_apptag(be16_to_cpu(dif->apptag), apptag,
|
||||
appmask);
|
||||
|
||||
@ -118,7 +118,7 @@ static uint16_t nvme_dif_prchk(NvmeNamespace *ns, NvmeDifTuple *dif,
|
||||
}
|
||||
}
|
||||
|
||||
if (ctrl & NVME_RW_PRINFO_PRCHK_REF) {
|
||||
if (prinfo & NVME_PRINFO_PRCHK_REF) {
|
||||
trace_pci_nvme_dif_prchk_reftag(be32_to_cpu(dif->reftag), reftag);
|
||||
|
||||
if (be32_to_cpu(dif->reftag) != reftag) {
|
||||
@ -130,15 +130,15 @@ static uint16_t nvme_dif_prchk(NvmeNamespace *ns, NvmeDifTuple *dif,
|
||||
}
|
||||
|
||||
uint16_t nvme_dif_check(NvmeNamespace *ns, uint8_t *buf, size_t len,
|
||||
uint8_t *mbuf, size_t mlen, uint16_t ctrl,
|
||||
uint8_t *mbuf, size_t mlen, uint8_t prinfo,
|
||||
uint64_t slba, uint16_t apptag,
|
||||
uint16_t appmask, uint32_t reftag)
|
||||
uint16_t appmask, uint32_t *reftag)
|
||||
{
|
||||
uint8_t *end = buf + len;
|
||||
int16_t pil = 0;
|
||||
uint16_t status;
|
||||
|
||||
status = nvme_check_prinfo(ns, ctrl, slba, reftag);
|
||||
status = nvme_check_prinfo(ns, prinfo, slba, *reftag);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
@ -147,19 +147,19 @@ uint16_t nvme_dif_check(NvmeNamespace *ns, uint8_t *buf, size_t len,
|
||||
pil = ns->lbaf.ms - sizeof(NvmeDifTuple);
|
||||
}
|
||||
|
||||
trace_pci_nvme_dif_check(NVME_RW_PRINFO(ctrl), ns->lbasz + pil);
|
||||
trace_pci_nvme_dif_check(prinfo, ns->lbasz + pil);
|
||||
|
||||
for (; buf < end; buf += ns->lbasz, mbuf += ns->lbaf.ms) {
|
||||
NvmeDifTuple *dif = (NvmeDifTuple *)(mbuf + pil);
|
||||
|
||||
status = nvme_dif_prchk(ns, dif, buf, mbuf, pil, ctrl, apptag,
|
||||
appmask, reftag);
|
||||
status = nvme_dif_prchk(ns, dif, buf, mbuf, pil, prinfo, apptag,
|
||||
appmask, *reftag);
|
||||
if (status) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (NVME_ID_NS_DPS_TYPE(ns->id_ns.dps) != NVME_ID_NS_DPS_TYPE_3) {
|
||||
reftag++;
|
||||
(*reftag)++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -248,14 +248,14 @@ static void nvme_dif_rw_check_cb(void *opaque, int ret)
|
||||
NvmeCtrl *n = nvme_ctrl(req);
|
||||
NvmeRwCmd *rw = (NvmeRwCmd *)&req->cmd;
|
||||
uint64_t slba = le64_to_cpu(rw->slba);
|
||||
uint16_t ctrl = le16_to_cpu(rw->control);
|
||||
uint8_t prinfo = NVME_RW_PRINFO(le16_to_cpu(rw->control));
|
||||
uint16_t apptag = le16_to_cpu(rw->apptag);
|
||||
uint16_t appmask = le16_to_cpu(rw->appmask);
|
||||
uint32_t reftag = le32_to_cpu(rw->reftag);
|
||||
uint16_t status;
|
||||
|
||||
trace_pci_nvme_dif_rw_check_cb(nvme_cid(req), NVME_RW_PRINFO(ctrl), apptag,
|
||||
appmask, reftag);
|
||||
trace_pci_nvme_dif_rw_check_cb(nvme_cid(req), prinfo, apptag, appmask,
|
||||
reftag);
|
||||
|
||||
if (ret) {
|
||||
goto out;
|
||||
@ -269,8 +269,8 @@ static void nvme_dif_rw_check_cb(void *opaque, int ret)
|
||||
}
|
||||
|
||||
status = nvme_dif_check(ns, ctx->data.bounce, ctx->data.iov.size,
|
||||
ctx->mdata.bounce, ctx->mdata.iov.size, ctrl,
|
||||
slba, apptag, appmask, reftag);
|
||||
ctx->mdata.bounce, ctx->mdata.iov.size, prinfo,
|
||||
slba, apptag, appmask, &reftag);
|
||||
if (status) {
|
||||
req->status = status;
|
||||
goto out;
|
||||
@ -283,7 +283,7 @@ static void nvme_dif_rw_check_cb(void *opaque, int ret)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ctrl & NVME_RW_PRINFO_PRACT && ns->lbaf.ms == 8) {
|
||||
if (prinfo & NVME_PRINFO_PRACT && ns->lbaf.ms == 8) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -364,15 +364,15 @@ uint16_t nvme_dif_rw(NvmeCtrl *n, NvmeRequest *req)
|
||||
size_t mlen = nvme_m2b(ns, nlb);
|
||||
size_t mapped_len = len;
|
||||
int64_t offset = nvme_l2b(ns, slba);
|
||||
uint16_t ctrl = le16_to_cpu(rw->control);
|
||||
uint8_t prinfo = NVME_RW_PRINFO(le16_to_cpu(rw->control));
|
||||
uint16_t apptag = le16_to_cpu(rw->apptag);
|
||||
uint16_t appmask = le16_to_cpu(rw->appmask);
|
||||
uint32_t reftag = le32_to_cpu(rw->reftag);
|
||||
bool pract = !!(ctrl & NVME_RW_PRINFO_PRACT);
|
||||
bool pract = !!(prinfo & NVME_PRINFO_PRACT);
|
||||
NvmeBounceContext *ctx;
|
||||
uint16_t status;
|
||||
|
||||
trace_pci_nvme_dif_rw(pract, NVME_RW_PRINFO(ctrl));
|
||||
trace_pci_nvme_dif_rw(pract, prinfo);
|
||||
|
||||
ctx = g_new0(NvmeBounceContext, 1);
|
||||
ctx->req = req;
|
||||
@ -380,7 +380,7 @@ uint16_t nvme_dif_rw(NvmeCtrl *n, NvmeRequest *req)
|
||||
if (wrz) {
|
||||
BdrvRequestFlags flags = BDRV_REQ_MAY_UNMAP;
|
||||
|
||||
if (ctrl & NVME_RW_PRINFO_PRCHK_MASK) {
|
||||
if (prinfo & NVME_PRINFO_PRCHK_MASK) {
|
||||
status = NVME_INVALID_PROT_INFO | NVME_DNR;
|
||||
goto err;
|
||||
}
|
||||
@ -389,7 +389,7 @@ uint16_t nvme_dif_rw(NvmeCtrl *n, NvmeRequest *req)
|
||||
uint8_t *mbuf, *end;
|
||||
int16_t pil = ns->lbaf.ms - sizeof(NvmeDifTuple);
|
||||
|
||||
status = nvme_check_prinfo(ns, ctrl, slba, reftag);
|
||||
status = nvme_check_prinfo(ns, prinfo, slba, reftag);
|
||||
if (status) {
|
||||
goto err;
|
||||
}
|
||||
@ -469,7 +469,7 @@ uint16_t nvme_dif_rw(NvmeCtrl *n, NvmeRequest *req)
|
||||
}
|
||||
}
|
||||
|
||||
status = nvme_check_prinfo(ns, ctrl, slba, reftag);
|
||||
status = nvme_check_prinfo(ns, prinfo, slba, reftag);
|
||||
if (status) {
|
||||
goto err;
|
||||
}
|
||||
@ -478,11 +478,11 @@ uint16_t nvme_dif_rw(NvmeCtrl *n, NvmeRequest *req)
|
||||
/* splice generated protection information into the buffer */
|
||||
nvme_dif_pract_generate_dif(ns, ctx->data.bounce, ctx->data.iov.size,
|
||||
ctx->mdata.bounce, ctx->mdata.iov.size,
|
||||
apptag, reftag);
|
||||
apptag, &reftag);
|
||||
} else {
|
||||
status = nvme_dif_check(ns, ctx->data.bounce, ctx->data.iov.size,
|
||||
ctx->mdata.bounce, ctx->mdata.iov.size, ctrl,
|
||||
slba, apptag, appmask, reftag);
|
||||
ctx->mdata.bounce, ctx->mdata.iov.size, prinfo,
|
||||
slba, apptag, appmask, &reftag);
|
||||
if (status) {
|
||||
goto err;
|
||||
}
|
||||
|
64
hw/nvme/ns.c
64
hw/nvme/ns.c
@ -56,6 +56,7 @@ void nvme_ns_init_format(NvmeNamespace *ns)
|
||||
|
||||
static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
|
||||
{
|
||||
static uint64_t ns_count;
|
||||
NvmeIdNs *id_ns = &ns->id_ns;
|
||||
uint8_t ds;
|
||||
uint16_t ms;
|
||||
@ -73,47 +74,47 @@ static int nvme_ns_init(NvmeNamespace *ns, Error **errp)
|
||||
id_ns->nmic |= NVME_NMIC_NS_SHARED;
|
||||
}
|
||||
|
||||
/* Substitute a missing EUI-64 by an autogenerated one */
|
||||
++ns_count;
|
||||
if (!ns->params.eui64 && ns->params.eui64_default) {
|
||||
ns->params.eui64 = ns_count + NVME_EUI64_DEFAULT;
|
||||
}
|
||||
|
||||
/* simple copy */
|
||||
id_ns->mssrl = cpu_to_le16(ns->params.mssrl);
|
||||
id_ns->mcl = cpu_to_le32(ns->params.mcl);
|
||||
id_ns->msrc = ns->params.msrc;
|
||||
id_ns->eui64 = cpu_to_be64(ns->params.eui64);
|
||||
|
||||
ds = 31 - clz32(ns->blkconf.logical_block_size);
|
||||
ms = ns->params.ms;
|
||||
|
||||
if (ns->params.ms) {
|
||||
id_ns->mc = 0x3;
|
||||
id_ns->mc = NVME_ID_NS_MC_EXTENDED | NVME_ID_NS_MC_SEPARATE;
|
||||
|
||||
if (ns->params.mset) {
|
||||
id_ns->flbas |= 0x10;
|
||||
}
|
||||
|
||||
id_ns->dpc = 0x1f;
|
||||
id_ns->dps = ((ns->params.pil & 0x1) << 3) | ns->params.pi;
|
||||
|
||||
NvmeLBAF lbaf[16] = {
|
||||
[0] = { .ds = 9 },
|
||||
[1] = { .ds = 9, .ms = 8 },
|
||||
[2] = { .ds = 9, .ms = 16 },
|
||||
[3] = { .ds = 9, .ms = 64 },
|
||||
[4] = { .ds = 12 },
|
||||
[5] = { .ds = 12, .ms = 8 },
|
||||
[6] = { .ds = 12, .ms = 16 },
|
||||
[7] = { .ds = 12, .ms = 64 },
|
||||
};
|
||||
|
||||
memcpy(&id_ns->lbaf, &lbaf, sizeof(lbaf));
|
||||
id_ns->nlbaf = 7;
|
||||
} else {
|
||||
NvmeLBAF lbaf[16] = {
|
||||
[0] = { .ds = 9 },
|
||||
[1] = { .ds = 12 },
|
||||
};
|
||||
|
||||
memcpy(&id_ns->lbaf, &lbaf, sizeof(lbaf));
|
||||
id_ns->nlbaf = 1;
|
||||
if (ms && ns->params.mset) {
|
||||
id_ns->flbas |= NVME_ID_NS_FLBAS_EXTENDED;
|
||||
}
|
||||
|
||||
id_ns->dpc = 0x1f;
|
||||
id_ns->dps = ns->params.pi;
|
||||
if (ns->params.pi && ns->params.pil) {
|
||||
id_ns->dps |= NVME_ID_NS_DPS_FIRST_EIGHT;
|
||||
}
|
||||
|
||||
static const NvmeLBAF lbaf[16] = {
|
||||
[0] = { .ds = 9 },
|
||||
[1] = { .ds = 9, .ms = 8 },
|
||||
[2] = { .ds = 9, .ms = 16 },
|
||||
[3] = { .ds = 9, .ms = 64 },
|
||||
[4] = { .ds = 12 },
|
||||
[5] = { .ds = 12, .ms = 8 },
|
||||
[6] = { .ds = 12, .ms = 16 },
|
||||
[7] = { .ds = 12, .ms = 64 },
|
||||
};
|
||||
|
||||
memcpy(&id_ns->lbaf, &lbaf, sizeof(lbaf));
|
||||
id_ns->nlbaf = 7;
|
||||
|
||||
for (i = 0; i <= id_ns->nlbaf; i++) {
|
||||
NvmeLBAF *lbaf = &id_ns->lbaf[i];
|
||||
if (lbaf->ds == ds) {
|
||||
@ -518,6 +519,7 @@ static Property nvme_ns_props[] = {
|
||||
DEFINE_PROP_BOOL("shared", NvmeNamespace, params.shared, false),
|
||||
DEFINE_PROP_UINT32("nsid", NvmeNamespace, params.nsid, 0),
|
||||
DEFINE_PROP_UUID("uuid", NvmeNamespace, params.uuid),
|
||||
DEFINE_PROP_UINT64("eui64", NvmeNamespace, params.eui64, 0),
|
||||
DEFINE_PROP_UINT16("ms", NvmeNamespace, params.ms, 0),
|
||||
DEFINE_PROP_UINT8("mset", NvmeNamespace, params.mset, 0),
|
||||
DEFINE_PROP_UINT8("pi", NvmeNamespace, params.pi, 0),
|
||||
@ -538,6 +540,8 @@ static Property nvme_ns_props[] = {
|
||||
params.max_open_zones, 0),
|
||||
DEFINE_PROP_UINT32("zoned.descr_ext_size", NvmeNamespace,
|
||||
params.zd_extension_size, 0),
|
||||
DEFINE_PROP_BOOL("eui64-default", NvmeNamespace, params.eui64_default,
|
||||
true),
|
||||
DEFINE_PROP_END_OF_LIST(),
|
||||
};
|
||||
|
||||
|
@ -26,6 +26,9 @@
|
||||
|
||||
#define NVME_MAX_CONTROLLERS 32
|
||||
#define NVME_MAX_NAMESPACES 256
|
||||
#define NVME_EUI64_DEFAULT ((uint64_t)0x5254000000000000)
|
||||
|
||||
QEMU_BUILD_BUG_ON(NVME_MAX_NAMESPACES > NVME_NSID_BROADCAST - 1);
|
||||
|
||||
typedef struct NvmeCtrl NvmeCtrl;
|
||||
typedef struct NvmeNamespace NvmeNamespace;
|
||||
@ -83,6 +86,8 @@ typedef struct NvmeNamespaceParams {
|
||||
bool shared;
|
||||
uint32_t nsid;
|
||||
QemuUUID uuid;
|
||||
uint64_t eui64;
|
||||
bool eui64_default;
|
||||
|
||||
uint16_t ms;
|
||||
uint8_t mset;
|
||||
@ -382,6 +387,7 @@ typedef struct NvmeParams {
|
||||
uint8_t vsl;
|
||||
bool use_intel_id;
|
||||
uint8_t zasl;
|
||||
bool auto_transition_zones;
|
||||
bool legacy_cmb;
|
||||
} NvmeParams;
|
||||
|
||||
@ -404,6 +410,7 @@ typedef struct NvmeCtrl {
|
||||
uint32_t max_q_ents;
|
||||
uint8_t outstanding_aers;
|
||||
uint32_t irq_status;
|
||||
int cq_pending;
|
||||
uint64_t host_timestamp; /* Timestamp sent by the host */
|
||||
uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */
|
||||
uint64_t starttime_ms;
|
||||
@ -530,17 +537,17 @@ static const uint16_t t10_dif_crc_table[256] = {
|
||||
0xF0D8, 0x7B6F, 0x6C01, 0xE7B6, 0x42DD, 0xC96A, 0xDE04, 0x55B3
|
||||
};
|
||||
|
||||
uint16_t nvme_check_prinfo(NvmeNamespace *ns, uint16_t ctrl, uint64_t slba,
|
||||
uint16_t nvme_check_prinfo(NvmeNamespace *ns, uint8_t prinfo, uint64_t slba,
|
||||
uint32_t reftag);
|
||||
uint16_t nvme_dif_mangle_mdata(NvmeNamespace *ns, uint8_t *mbuf, size_t mlen,
|
||||
uint64_t slba);
|
||||
void nvme_dif_pract_generate_dif(NvmeNamespace *ns, uint8_t *buf, size_t len,
|
||||
uint8_t *mbuf, size_t mlen, uint16_t apptag,
|
||||
uint32_t reftag);
|
||||
uint32_t *reftag);
|
||||
uint16_t nvme_dif_check(NvmeNamespace *ns, uint8_t *buf, size_t len,
|
||||
uint8_t *mbuf, size_t mlen, uint16_t ctrl,
|
||||
uint8_t *mbuf, size_t mlen, uint8_t prinfo,
|
||||
uint64_t slba, uint16_t apptag,
|
||||
uint16_t appmask, uint32_t reftag);
|
||||
uint16_t appmask, uint32_t *reftag);
|
||||
uint16_t nvme_dif_rw(NvmeCtrl *n, NvmeRequest *req);
|
||||
|
||||
|
||||
|
@ -7,16 +7,14 @@ pci_nvme_map_addr(uint64_t addr, uint64_t len) "addr 0x%"PRIx64" len %"PRIu64""
|
||||
pci_nvme_map_addr_cmb(uint64_t addr, uint64_t len) "addr 0x%"PRIx64" len %"PRIu64""
|
||||
pci_nvme_map_prp(uint64_t trans_len, uint32_t len, uint64_t prp1, uint64_t prp2, int num_prps) "trans_len %"PRIu64" len %"PRIu32" prp1 0x%"PRIx64" prp2 0x%"PRIx64" num_prps %d"
|
||||
pci_nvme_map_sgl(uint8_t typ, uint64_t len) "type 0x%"PRIx8" len %"PRIu64""
|
||||
pci_nvme_io_cmd(uint16_t cid, uint32_t nsid, uint16_t sqid, uint8_t opcode, const char *opname) "cid %"PRIu16" nsid %"PRIu32" sqid %"PRIu16" opc 0x%"PRIx8" opname '%s'"
|
||||
pci_nvme_io_cmd(uint16_t cid, uint32_t nsid, uint16_t sqid, uint8_t opcode, const char *opname) "cid %"PRIu16" nsid 0x%"PRIx32" sqid %"PRIu16" opc 0x%"PRIx8" opname '%s'"
|
||||
pci_nvme_admin_cmd(uint16_t cid, uint16_t sqid, uint8_t opcode, const char *opname) "cid %"PRIu16" sqid %"PRIu16" opc 0x%"PRIx8" opname '%s'"
|
||||
pci_nvme_flush(uint16_t cid, uint32_t nsid) "cid %"PRIu16" nsid %"PRIu32""
|
||||
pci_nvme_format(uint16_t cid, uint32_t nsid, uint8_t lbaf, uint8_t mset, uint8_t pi, uint8_t pil) "cid %"PRIu16" nsid %"PRIu32" lbaf %"PRIu8" mset %"PRIu8" pi %"PRIu8" pil %"PRIu8""
|
||||
pci_nvme_format_ns(uint16_t cid, uint32_t nsid, uint8_t lbaf, uint8_t mset, uint8_t pi, uint8_t pil) "cid %"PRIu16" nsid %"PRIu32" lbaf %"PRIu8" mset %"PRIu8" pi %"PRIu8" pil %"PRIu8""
|
||||
pci_nvme_format_cb(uint16_t cid, uint32_t nsid) "cid %"PRIu16" nsid %"PRIu32""
|
||||
pci_nvme_flush_ns(uint32_t nsid) "nsid 0x%"PRIx32""
|
||||
pci_nvme_format_set(uint32_t nsid, uint8_t lbaf, uint8_t mset, uint8_t pi, uint8_t pil) "nsid %"PRIu32" lbaf %"PRIu8" mset %"PRIu8" pi %"PRIu8" pil %"PRIu8""
|
||||
pci_nvme_read(uint16_t cid, uint32_t nsid, uint32_t nlb, uint64_t count, uint64_t lba) "cid %"PRIu16" nsid %"PRIu32" nlb %"PRIu32" count %"PRIu64" lba 0x%"PRIx64""
|
||||
pci_nvme_write(uint16_t cid, const char *verb, uint32_t nsid, uint32_t nlb, uint64_t count, uint64_t lba) "cid %"PRIu16" opname '%s' nsid %"PRIu32" nlb %"PRIu32" count %"PRIu64" lba 0x%"PRIx64""
|
||||
pci_nvme_rw_cb(uint16_t cid, const char *blkname) "cid %"PRIu16" blk '%s'"
|
||||
pci_nvme_misc_cb(uint16_t cid, const char *blkname) "cid %"PRIu16" blk '%s'"
|
||||
pci_nvme_misc_cb(uint16_t cid) "cid %"PRIu16""
|
||||
pci_nvme_dif_rw(uint8_t pract, uint8_t prinfo) "pract 0x%"PRIx8" prinfo 0x%"PRIx8""
|
||||
pci_nvme_dif_rw_cb(uint16_t cid, const char *blkname) "cid %"PRIu16" blk '%s'"
|
||||
pci_nvme_dif_rw_mdata_in_cb(uint16_t cid, const char *blkname) "cid %"PRIu16" blk '%s'"
|
||||
@ -30,22 +28,20 @@ pci_nvme_dif_prchk_apptag(uint16_t apptag, uint16_t elbat, uint16_t elbatm) "app
|
||||
pci_nvme_dif_prchk_reftag(uint32_t reftag, uint32_t elbrt) "reftag 0x%"PRIx32" elbrt 0x%"PRIx32""
|
||||
pci_nvme_copy(uint16_t cid, uint32_t nsid, uint16_t nr, uint8_t format) "cid %"PRIu16" nsid %"PRIu32" nr %"PRIu16" format 0x%"PRIx8""
|
||||
pci_nvme_copy_source_range(uint64_t slba, uint32_t nlb) "slba 0x%"PRIx64" nlb %"PRIu32""
|
||||
pci_nvme_copy_in_complete(uint16_t cid) "cid %"PRIu16""
|
||||
pci_nvme_copy_cb(uint16_t cid) "cid %"PRIu16""
|
||||
pci_nvme_copy_out(uint64_t slba, uint32_t nlb) "slba 0x%"PRIx64" nlb %"PRIu32""
|
||||
pci_nvme_verify(uint16_t cid, uint32_t nsid, uint64_t slba, uint32_t nlb) "cid %"PRIu16" nsid %"PRIu32" slba 0x%"PRIx64" nlb %"PRIu32""
|
||||
pci_nvme_verify_mdata_in_cb(uint16_t cid, const char *blkname) "cid %"PRIu16" blk '%s'"
|
||||
pci_nvme_verify_cb(uint16_t cid, uint8_t prinfo, uint16_t apptag, uint16_t appmask, uint32_t reftag) "cid %"PRIu16" prinfo 0x%"PRIx8" apptag 0x%"PRIx16" appmask 0x%"PRIx16" reftag 0x%"PRIx32""
|
||||
pci_nvme_rw_complete_cb(uint16_t cid, const char *blkname) "cid %"PRIu16" blk '%s'"
|
||||
pci_nvme_block_status(int64_t offset, int64_t bytes, int64_t pnum, int ret, bool zeroed) "offset %"PRId64" bytes %"PRId64" pnum %"PRId64" ret 0x%x zeroed %d"
|
||||
pci_nvme_dsm(uint16_t cid, uint32_t nsid, uint32_t nr, uint32_t attr) "cid %"PRIu16" nsid %"PRIu32" nr %"PRIu32" attr 0x%"PRIx32""
|
||||
pci_nvme_dsm_deallocate(uint16_t cid, uint32_t nsid, uint64_t slba, uint32_t nlb) "cid %"PRIu16" nsid %"PRIu32" slba %"PRIu64" nlb %"PRIu32""
|
||||
pci_nvme_dsm(uint32_t nr, uint32_t attr) "nr %"PRIu32" attr 0x%"PRIx32""
|
||||
pci_nvme_dsm_deallocate(uint64_t slba, uint32_t nlb) "slba %"PRIu64" nlb %"PRIu32""
|
||||
pci_nvme_dsm_single_range_limit_exceeded(uint32_t nlb, uint32_t dmrsl) "nlb %"PRIu32" dmrsl %"PRIu32""
|
||||
pci_nvme_compare(uint16_t cid, uint32_t nsid, uint64_t slba, uint32_t nlb) "cid %"PRIu16" nsid %"PRIu32" slba 0x%"PRIx64" nlb %"PRIu32""
|
||||
pci_nvme_compare_data_cb(uint16_t cid) "cid %"PRIu16""
|
||||
pci_nvme_compare_mdata_cb(uint16_t cid) "cid %"PRIu16""
|
||||
pci_nvme_aio_discard_cb(uint16_t cid) "cid %"PRIu16""
|
||||
pci_nvme_aio_copy_in_cb(uint16_t cid) "cid %"PRIu16""
|
||||
pci_nvme_aio_zone_reset_cb(uint16_t cid, uint64_t zslba) "cid %"PRIu16" zslba 0x%"PRIx64""
|
||||
pci_nvme_aio_flush_cb(uint16_t cid, const char *blkname) "cid %"PRIu16" blk '%s'"
|
||||
pci_nvme_create_sq(uint64_t addr, uint16_t sqid, uint16_t cqid, uint16_t qsize, uint16_t qflags) "create submission queue, addr=0x%"PRIx64", sqid=%"PRIu16", cqid=%"PRIu16", qsize=%"PRIu16", qflags=%"PRIu16""
|
||||
pci_nvme_create_cq(uint64_t addr, uint16_t cqid, uint16_t vector, uint16_t size, uint16_t qflags, int ien) "create completion queue, addr=0x%"PRIx64", cqid=%"PRIu16", vector=%"PRIu16", qsize=%"PRIu16", qflags=%"PRIu16", ien=%d"
|
||||
@ -55,7 +51,7 @@ pci_nvme_identify(uint16_t cid, uint8_t cns, uint16_t ctrlid, uint8_t csi) "cid
|
||||
pci_nvme_identify_ctrl(void) "identify controller"
|
||||
pci_nvme_identify_ctrl_csi(uint8_t csi) "identify controller, csi=0x%"PRIx8""
|
||||
pci_nvme_identify_ns(uint32_t ns) "nsid %"PRIu32""
|
||||
pci_nvme_identify_ns_attached_list(uint16_t cntid) "cntid=%"PRIu16""
|
||||
pci_nvme_identify_ctrl_list(uint8_t cns, uint16_t cntid) "cns 0x%"PRIx8" cntid %"PRIu16""
|
||||
pci_nvme_identify_ns_csi(uint32_t ns, uint8_t csi) "nsid=%"PRIu32", csi=0x%"PRIx8""
|
||||
pci_nvme_identify_nslist(uint32_t ns) "nsid %"PRIu32""
|
||||
pci_nvme_identify_nslist_csi(uint16_t ns, uint8_t csi) "nsid=%"PRIu16", csi=0x%"PRIx8""
|
||||
@ -80,7 +76,7 @@ pci_nvme_enqueue_event(uint8_t typ, uint8_t info, uint8_t log_page) "type 0x%"PR
|
||||
pci_nvme_enqueue_event_noqueue(int queued) "queued %d"
|
||||
pci_nvme_enqueue_event_masked(uint8_t typ) "type 0x%"PRIx8""
|
||||
pci_nvme_no_outstanding_aers(void) "ignoring event; no outstanding AERs"
|
||||
pci_nvme_enqueue_req_completion(uint16_t cid, uint16_t cqid, uint16_t status) "cid %"PRIu16" cqid %"PRIu16" status 0x%"PRIx16""
|
||||
pci_nvme_enqueue_req_completion(uint16_t cid, uint16_t cqid, uint32_t dw0, uint32_t dw1, uint16_t status) "cid %"PRIu16" cqid %"PRIu16" dw0 0x%"PRIx32" dw1 0x%"PRIx32" status 0x%"PRIx16""
|
||||
pci_nvme_mmio_read(uint64_t addr, unsigned size) "addr 0x%"PRIx64" size %d"
|
||||
pci_nvme_mmio_write(uint64_t addr, uint64_t data, unsigned size) "addr 0x%"PRIx64" data 0x%"PRIx64" size %d"
|
||||
pci_nvme_mmio_doorbell_cq(uint16_t cqid, uint16_t new_head) "cqid %"PRIu16" new_head %"PRIu16""
|
||||
@ -101,6 +97,7 @@ pci_nvme_open_zone(uint64_t slba, uint32_t zone_idx, int all) "open zone, slba=%
|
||||
pci_nvme_close_zone(uint64_t slba, uint32_t zone_idx, int all) "close zone, slba=%"PRIu64", idx=%"PRIu32", all=%"PRIi32""
|
||||
pci_nvme_finish_zone(uint64_t slba, uint32_t zone_idx, int all) "finish zone, slba=%"PRIu64", idx=%"PRIu32", all=%"PRIi32""
|
||||
pci_nvme_reset_zone(uint64_t slba, uint32_t zone_idx, int all) "reset zone, slba=%"PRIu64", idx=%"PRIu32", all=%"PRIi32""
|
||||
pci_nvme_zns_zone_reset(uint64_t zslba) "zslba 0x%"PRIx64""
|
||||
pci_nvme_offline_zone(uint64_t slba, uint32_t zone_idx, int all) "offline zone, slba=%"PRIu64", idx=%"PRIu32", all=%"PRIi32""
|
||||
pci_nvme_set_descriptor_extension(uint64_t slba, uint32_t zone_idx) "set zone descriptor extension, slba=%"PRIu64", idx=%"PRIu32""
|
||||
pci_nvme_zd_extension_set(uint32_t zone_idx) "set descriptor extension for zone_idx=%"PRIu32""
|
||||
|
@ -708,6 +708,14 @@ enum {
|
||||
|
||||
#define NVME_RW_PRINFO(control) ((control >> 10) & 0xf)
|
||||
|
||||
enum {
|
||||
NVME_PRINFO_PRACT = 1 << 3,
|
||||
NVME_PRINFO_PRCHK_GUARD = 1 << 2,
|
||||
NVME_PRINFO_PRCHK_APP = 1 << 1,
|
||||
NVME_PRINFO_PRCHK_REF = 1 << 0,
|
||||
NVME_PRINFO_PRCHK_MASK = 7 << 0,
|
||||
};
|
||||
|
||||
typedef struct QEMU_PACKED NvmeDsmCmd {
|
||||
uint8_t opcode;
|
||||
uint8_t flags;
|
||||
@ -980,6 +988,7 @@ enum NvmeIdCns {
|
||||
NVME_ID_CNS_NS_PRESENT_LIST = 0x10,
|
||||
NVME_ID_CNS_NS_PRESENT = 0x11,
|
||||
NVME_ID_CNS_NS_ATTACHED_CTRL_LIST = 0x12,
|
||||
NVME_ID_CNS_CTRL_LIST = 0x13,
|
||||
NVME_ID_CNS_CS_NS_PRESENT_LIST = 0x1a,
|
||||
NVME_ID_CNS_CS_NS_PRESENT = 0x1b,
|
||||
NVME_ID_CNS_IO_COMMAND_SET = 0x1c,
|
||||
@ -1341,6 +1350,15 @@ enum NvmeIdNsDps {
|
||||
NVME_ID_NS_DPS_FIRST_EIGHT = 8,
|
||||
};
|
||||
|
||||
enum NvmeIdNsFlbas {
|
||||
NVME_ID_NS_FLBAS_EXTENDED = 1 << 4,
|
||||
};
|
||||
|
||||
enum NvmeIdNsMc {
|
||||
NVME_ID_NS_MC_EXTENDED = 1 << 0,
|
||||
NVME_ID_NS_MC_SEPARATE = 1 << 1,
|
||||
};
|
||||
|
||||
#define NVME_ID_NS_DPS_TYPE(dps) (dps & NVME_ID_NS_DPS_TYPE_MASK)
|
||||
|
||||
typedef struct NvmeDifTuple {
|
||||
|
Loading…
Reference in New Issue
Block a user