diff options
-rw-r--r-- | blockdev.c | 8 | ||||
-rw-r--r-- | hw/block/nvme.c | 61 | ||||
-rw-r--r-- | qapi/block-core.json | 2 |
3 files changed, 58 insertions, 13 deletions
diff --git a/blockdev.c b/blockdev.c index eafeba96d0..21614004d1 100644 --- a/blockdev.c +++ b/blockdev.c @@ -1937,7 +1937,8 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp) { BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common); BlockdevBackup *backup; - BlockBackend *blk, *target; + BlockBackend *blk; + BlockDriverState *target; Error *local_err = NULL; assert(common->action->type == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP); @@ -1954,15 +1955,14 @@ static void blockdev_backup_prepare(BlkActionState *common, Error **errp) return; } - target = blk_by_name(backup->target); + target = bdrv_lookup_bs(backup->target, backup->target, errp); if (!target) { - error_setg(errp, "Device '%s' not found", backup->target); return; } /* AioContext is released in .clean() */ state->aio_context = blk_get_aio_context(blk); - if (state->aio_context != blk_get_aio_context(target)) { + if (state->aio_context != bdrv_get_aio_context(target)) { state->aio_context = NULL; error_setg(errp, "Backup between two IO threads is not implemented"); return; diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 2ded2475ee..cef3bb42f1 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -469,19 +469,22 @@ static uint16_t nvme_create_cq(NvmeCtrl *n, NvmeCmd *cmd) return NVME_SUCCESS; } -static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd) +static uint16_t nvme_identify_ctrl(NvmeCtrl *n, NvmeIdentify *c) +{ + uint64_t prp1 = le64_to_cpu(c->prp1); + uint64_t prp2 = le64_to_cpu(c->prp2); + + return nvme_dma_read_prp(n, (uint8_t *)&n->id_ctrl, sizeof(n->id_ctrl), + prp1, prp2); +} + +static uint16_t nvme_identify_ns(NvmeCtrl *n, NvmeIdentify *c) { NvmeNamespace *ns; - NvmeIdentify *c = (NvmeIdentify *)cmd; - uint32_t cns = le32_to_cpu(c->cns); uint32_t nsid = le32_to_cpu(c->nsid); uint64_t prp1 = le64_to_cpu(c->prp1); uint64_t prp2 = le64_to_cpu(c->prp2); - if (cns) { - return nvme_dma_read_prp(n, (uint8_t *)&n->id_ctrl, sizeof(n->id_ctrl), - prp1, prp2); - } if (nsid == 0 || nsid > n->num_namespaces) { return NVME_INVALID_NSID | NVME_DNR; } @@ -491,6 +494,48 @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd) prp1, prp2); } +static uint16_t nvme_identify_nslist(NvmeCtrl *n, NvmeIdentify *c) +{ + static const int data_len = 4096; + uint32_t min_nsid = le32_to_cpu(c->nsid); + uint64_t prp1 = le64_to_cpu(c->prp1); + uint64_t prp2 = le64_to_cpu(c->prp2); + uint32_t *list; + uint16_t ret; + int i, j = 0; + + list = g_malloc0(data_len); + for (i = 0; i < n->num_namespaces; i++) { + if (i < min_nsid) { + continue; + } + list[j++] = cpu_to_le32(i + 1); + if (j == data_len / sizeof(uint32_t)) { + break; + } + } + ret = nvme_dma_read_prp(n, (uint8_t *)list, data_len, prp1, prp2); + g_free(list); + return ret; +} + + +static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd) +{ + NvmeIdentify *c = (NvmeIdentify *)cmd; + + switch (le32_to_cpu(c->cns)) { + case 0x00: + return nvme_identify_ns(n, c); + case 0x01: + return nvme_identify_ctrl(n, c); + case 0x02: + return nvme_identify_nslist(n, c); + default: + return NVME_INVALID_FIELD | NVME_DNR; + } +} + static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req) { uint32_t dw10 = le32_to_cpu(cmd->cdw10); @@ -909,7 +954,7 @@ static void nvme_class_init(ObjectClass *oc, void *data) pc->class_id = PCI_CLASS_STORAGE_EXPRESS; pc->vendor_id = PCI_VENDOR_ID_INTEL; pc->device_id = 0x5845; - pc->revision = 1; + pc->revision = 2; pc->is_express = 1; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); diff --git a/qapi/block-core.json b/qapi/block-core.json index 2bbc027311..5e2d7d78d2 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -927,7 +927,7 @@ # # @device: the name of the device which should be copied. # -# @target: the name of the backup target device. +# @target: the device name or node-name of the backup target node. # # @sync: what parts of the disk image should be copied to the destination # (all the disk, only the sectors allocated in the topmost image, or |