diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2016-08-05 13:05:29 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2016-08-05 13:05:29 +0100 |
commit | bd8eda537fbe6f28a94db30e8facab2bf528b204 (patch) | |
tree | ffbddd89dfed1d48db6aa51aa093470d084919de /hw/block | |
parent | 8bfa87a231a846343a33bd817ea002740d84ae51 (diff) | |
parent | 47989f14472262a289894058f7babf1db37edda5 (diff) | |
download | qemu-bd8eda537fbe6f28a94db30e8facab2bf528b204.tar.gz qemu-bd8eda537fbe6f28a94db30e8facab2bf528b204.tar.bz2 qemu-bd8eda537fbe6f28a94db30e8facab2bf528b204.zip |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches for 2.7.0-rc2
# gpg: Signature made Fri 05 Aug 2016 10:30:12 BST
# gpg: using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6
* remotes/kevin/tags/for-upstream:
nvme: bump PCI revision
nvme: fix identify to be NVMe 1.1 compliant
block: Accept any target node for transactional blockdev-backup
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/block')
-rw-r--r-- | hw/block/nvme.c | 61 |
1 files changed, 53 insertions, 8 deletions
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); |