summaryrefslogtreecommitdiffstats
path: root/qemu/hw/block/nvme.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/block/nvme.c')
-rw-r--r--qemu/hw/block/nvme.c55
1 files changed, 15 insertions, 40 deletions
diff --git a/qemu/hw/block/nvme.c b/qemu/hw/block/nvme.c
index 40d488032..173988ee8 100644
--- a/qemu/hw/block/nvme.c
+++ b/qemu/hw/block/nvme.c
@@ -20,11 +20,13 @@
* -device nvme,drive=<drive_id>,serial=<serial>,id=<id[optional]>
*/
+#include "qemu/osdep.h"
#include <hw/block/block.h>
#include <hw/hw.h>
#include <hw/pci/msix.h>
#include <hw/pci/pci.h>
#include "sysemu/sysemu.h"
+#include "qapi/error.h"
#include "qapi/visitor.h"
#include "sysemu/block-backend.h"
@@ -201,10 +203,11 @@ static void nvme_rw_cb(void *opaque, int ret)
NvmeCtrl *n = sq->ctrl;
NvmeCQueue *cq = n->cq[sq->cqid];
- block_acct_done(blk_get_stats(n->conf.blk), &req->acct);
if (!ret) {
+ block_acct_done(blk_get_stats(n->conf.blk), &req->acct);
req->status = NVME_SUCCESS;
} else {
+ block_acct_failed(blk_get_stats(n->conf.blk), &req->acct);
req->status = NVME_INTERNAL_DEV_ERROR;
}
if (req->has_sg) {
@@ -238,18 +241,22 @@ static uint16_t nvme_rw(NvmeCtrl *n, NvmeNamespace *ns, NvmeCmd *cmd,
uint64_t data_size = (uint64_t)nlb << data_shift;
uint64_t aio_slba = slba << (data_shift - BDRV_SECTOR_BITS);
int is_write = rw->opcode == NVME_CMD_WRITE ? 1 : 0;
+ enum BlockAcctType acct = is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ;
if ((slba + nlb) > ns->id_ns.nsze) {
+ block_acct_invalid(blk_get_stats(n->conf.blk), acct);
return NVME_LBA_RANGE | NVME_DNR;
}
+
if (nvme_map_prp(&req->qsg, prp1, prp2, data_size, n)) {
+ block_acct_invalid(blk_get_stats(n->conf.blk), acct);
return NVME_INVALID_FIELD | NVME_DNR;
}
+
assert((nlb << data_shift) == req->qsg.size);
req->has_sg = true;
- dma_acct_start(n->conf.blk, &req->acct, &req->qsg,
- is_write ? BLOCK_ACCT_WRITE : BLOCK_ACCT_READ);
+ dma_acct_start(n->conf.blk, &req->acct, &req->qsg, acct);
req->aiocb = is_write ?
dma_blk_write(n->conf.blk, &req->qsg, aio_slba, nvme_rw_cb, req) :
dma_blk_read(n->conf.blk, &req->qsg, aio_slba, nvme_rw_cb, req);
@@ -805,7 +812,7 @@ static int nvme_init(PCIDevice *pci_dev)
n->num_namespaces = 1;
n->num_queues = 64;
- n->reg_size = 1 << qemu_fls(0x1004 + 2 * (n->num_queues + 1) * 4);
+ n->reg_size = pow2ceil(0x1004 + 2 * (n->num_queues + 1) * 4);
n->ns_size = bs_size / (uint64_t)n->num_namespaces;
n->namespaces = g_new0(NvmeNamespace, n->num_namespaces);
@@ -910,45 +917,13 @@ static void nvme_class_init(ObjectClass *oc, void *data)
dc->vmsd = &nvme_vmstate;
}
-static void nvme_get_bootindex(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
-{
- NvmeCtrl *s = NVME(obj);
-
- visit_type_int32(v, &s->conf.bootindex, name, errp);
-}
-
-static void nvme_set_bootindex(Object *obj, Visitor *v, void *opaque,
- const char *name, Error **errp)
+static void nvme_instance_init(Object *obj)
{
NvmeCtrl *s = NVME(obj);
- int32_t boot_index;
- Error *local_err = NULL;
- visit_type_int32(v, &boot_index, name, &local_err);
- if (local_err) {
- goto out;
- }
- /* check whether bootindex is present in fw_boot_order list */
- check_boot_index(boot_index, &local_err);
- if (local_err) {
- goto out;
- }
- /* change bootindex to a new one */
- s->conf.bootindex = boot_index;
-
-out:
- if (local_err) {
- error_propagate(errp, local_err);
- }
-}
-
-static void nvme_instance_init(Object *obj)
-{
- object_property_add(obj, "bootindex", "int32",
- nvme_get_bootindex,
- nvme_set_bootindex, NULL, NULL, NULL);
- object_property_set_int(obj, -1, "bootindex", NULL);
+ device_add_bootindex_property(obj, &s->conf.bootindex,
+ "bootindex", "/namespace@1,0",
+ DEVICE(obj), &error_abort);
}
static const TypeInfo nvme_info = {