[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH 07/16] nvme: support Abort command
From: |
Klaus Birkelund Jensen |
Subject: |
[Qemu-block] [PATCH 07/16] nvme: support Abort command |
Date: |
Fri, 5 Jul 2019 09:23:24 +0200 |
Required for compliance with NVMe revision 1.2.1. See NVM Express 1.2.1,
Section 5.1 ("Abort command").
Extracted from Keith's qemu-nvme tree. Modified to only consider queued
and not executing commands.
Signed-off-by: Klaus Birkelund Jensen <address@hidden>
---
hw/block/nvme.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index b31e5ff681bd..4b9ff51868c0 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -38,6 +38,7 @@
#include "trace.h"
#include "nvme.h"
+#define NVME_OP_ABORTED 0xff
#define NVME_GUEST_ERR(trace, fmt, ...) \
do { \
(trace_##trace)(__VA_ARGS__); \
@@ -848,6 +849,54 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd
*cmd, NvmeRequest *req)
trace_nvme_err_invalid_setfeat(dw10);
return NVME_INVALID_FIELD | NVME_DNR;
}
+
+ return NVME_SUCCESS;
+}
+
+static uint16_t nvme_abort(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req)
+{
+ NvmeSQueue *sq;
+ NvmeRequest *new;
+ uint32_t index = 0;
+ uint16_t sqid = cmd->cdw10 & 0xffff;
+ uint16_t cid = (cmd->cdw10 >> 16) & 0xffff;
+
+ req->cqe.result = 1;
+ if (nvme_check_sqid(n, sqid)) {
+ return NVME_INVALID_FIELD | NVME_DNR;
+ }
+
+ sq = n->sq[sqid];
+
+ /* only consider queued (and not executing) commands for abort */
+ while ((sq->head + index) % sq->size != sq->tail) {
+ NvmeCmd abort_cmd;
+ hwaddr addr;
+
+ addr = sq->dma_addr + ((sq->head + index) % sq->size) * n->sqe_size;
+
+ nvme_addr_read(n, addr, (void *) &abort_cmd, sizeof(abort_cmd));
+ if (abort_cmd.cid == cid) {
+ req->cqe.result = 0;
+ new = QTAILQ_FIRST(&sq->req_list);
+ QTAILQ_REMOVE(&sq->req_list, new, entry);
+ QTAILQ_INSERT_TAIL(&sq->out_req_list, new, entry);
+
+ memset(&new->cqe, 0, sizeof(new->cqe));
+ new->cqe.cid = cid;
+ new->status = NVME_CMD_ABORT_REQ;
+
+ abort_cmd.opcode = NVME_OP_ABORTED;
+ nvme_addr_write(n, addr, (void *) &abort_cmd, sizeof(abort_cmd));
+
+ nvme_enqueue_req_completion(n->cq[sq->cqid], new);
+
+ return NVME_SUCCESS;
+ }
+
+ ++index;
+ }
+
return NVME_SUCCESS;
}
@@ -868,6 +917,8 @@ static uint16_t nvme_admin_cmd(NvmeCtrl *n, NvmeCmd *cmd,
NvmeRequest *req)
return nvme_set_feature(n, cmd, req);
case NVME_ADM_CMD_GET_FEATURES:
return nvme_get_feature(n, cmd, req);
+ case NVME_ADM_CMD_ABORT:
+ return nvme_abort(n, cmd, req);
default:
trace_nvme_err_invalid_admin_opc(cmd->opcode);
return NVME_INVALID_OPCODE | NVME_DNR;
@@ -890,6 +941,10 @@ static void nvme_process_sq(void *opaque)
nvme_addr_read(n, addr, (void *)&cmd, sizeof(cmd));
nvme_inc_sq_head(sq);
+ if (cmd.opcode == NVME_OP_ABORTED) {
+ continue;
+ }
+
req = QTAILQ_FIRST(&sq->req_list);
QTAILQ_REMOVE(&sq->req_list, req, entry);
QTAILQ_INSERT_TAIL(&sq->out_req_list, req, entry);
@@ -1376,6 +1431,7 @@ static void nvme_realize(PCIDevice *pci_dev, Error **errp)
id->ieee[2] = 0xb3;
id->ver = cpu_to_le32(0x00010201);
id->oacs = cpu_to_le16(0);
+ id->acl = 3;
id->frmw = 7 << 1;
id->sqes = (0x6 << 4) | 0x6;
id->cqes = (0x4 << 4) | 0x4;
--
2.20.1
- [Qemu-block] [PATCH 00/16] nvme: support NVMe v1.3d, SGLs and multiple namespaces, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 01/16] nvme: simplify namespace code, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 03/16] nvme: fix lpa field, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 06/16] nvme: support completion queue in cmb, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 02/16] nvme: move device parameters to separate struct, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 04/16] nvme: add missing fields in identify controller, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 10/16] nvme: support Get Log Page command, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 09/16] nvme: support Asynchronous Event Request command, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 07/16] nvme: support Abort command,
Klaus Birkelund Jensen <=
- [Qemu-block] [PATCH 05/16] nvme: populate the mandatory subnqn and ver fields, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 08/16] nvme: refactor device realization, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 12/16] nvme: bump supported NVMe revision to 1.3d, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 15/16] nvme: support scatter gather lists, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 11/16] nvme: add missing mandatory Features, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 13/16] nvme: simplify dma/cmb mappings, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 14/16] nvme: support multiple block requests per request, Klaus Birkelund Jensen, 2019/07/05
- [Qemu-block] [PATCH 16/16] nvme: support multiple namespaces, Klaus Birkelund Jensen, 2019/07/05