hw/block/nvme: add support for the abort command
Required for compliance with NVMe revision 1.3d. See NVM Express 1.3d, Section 5.1 ("Abort command"). The Abort command is a best effort command; for now, the device always fails to abort the given command. Signed-off-by: Klaus Jensen <klaus.jensen@cnexlabs.com> Signed-off-by: Klaus Jensen <k.jensen@samsung.com> Acked-by: Keith Busch <kbusch@kernel.org> Reviewed-by: Maxim Levitsky <mlevitsk@redhat.com> Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com> Message-Id: <20200706061303.246057-5-its@irrelevant.dk>
This commit is contained in:
parent
a04425fb06
commit
1504ede693
|
@ -774,6 +774,18 @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t nvme_abort(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
|
||||||
|
{
|
||||||
|
uint16_t sqid = le32_to_cpu(cmd->cdw10) & 0xffff;
|
||||||
|
|
||||||
|
req->cqe.result = 1;
|
||||||
|
if (nvme_check_sqid(n, sqid)) {
|
||||||
|
return NVME_INVALID_FIELD | NVME_DNR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NVME_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void nvme_set_timestamp(NvmeCtrl *n, uint64_t ts)
|
static inline void nvme_set_timestamp(NvmeCtrl *n, uint64_t ts)
|
||||||
{
|
{
|
||||||
trace_pci_nvme_setfeat_timestamp(ts);
|
trace_pci_nvme_setfeat_timestamp(ts);
|
||||||
|
@ -910,6 +922,8 @@ static uint16_t nvme_admin_cmd(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
|
||||||
return nvme_create_cq(n, cmd);
|
return nvme_create_cq(n, cmd);
|
||||||
case NVME_ADM_CMD_IDENTIFY:
|
case NVME_ADM_CMD_IDENTIFY:
|
||||||
return nvme_identify(n, cmd);
|
return nvme_identify(n, cmd);
|
||||||
|
case NVME_ADM_CMD_ABORT:
|
||||||
|
return nvme_abort(n, cmd, req);
|
||||||
case NVME_ADM_CMD_SET_FEATURES:
|
case NVME_ADM_CMD_SET_FEATURES:
|
||||||
return nvme_set_feature(n, cmd, req);
|
return nvme_set_feature(n, cmd, req);
|
||||||
case NVME_ADM_CMD_GET_FEATURES:
|
case NVME_ADM_CMD_GET_FEATURES:
|
||||||
|
@ -1594,6 +1608,19 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice *pci_dev)
|
||||||
id->ieee[1] = 0x02;
|
id->ieee[1] = 0x02;
|
||||||
id->ieee[2] = 0xb3;
|
id->ieee[2] = 0xb3;
|
||||||
id->oacs = cpu_to_le16(0);
|
id->oacs = cpu_to_le16(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Because the controller always completes the Abort command immediately,
|
||||||
|
* there can never be more than one concurrently executing Abort command,
|
||||||
|
* so this value is never used for anything. Note that there can easily be
|
||||||
|
* many Abort commands in the queues, but they are not considered
|
||||||
|
* "executing" until processed by nvme_abort.
|
||||||
|
*
|
||||||
|
* The specification recommends a value of 3 for Abort Command Limit (four
|
||||||
|
* concurrently outstanding Abort commands), so lets use that though it is
|
||||||
|
* inconsequential.
|
||||||
|
*/
|
||||||
|
id->acl = 3;
|
||||||
id->frmw = 7 << 1;
|
id->frmw = 7 << 1;
|
||||||
id->lpa = 1 << 0;
|
id->lpa = 1 << 0;
|
||||||
id->sqes = (0x6 << 4) | 0x6;
|
id->sqes = (0x6 << 4) | 0x6;
|
||||||
|
|
Loading…
Reference in a new issue