diff --git a/hw/block/nvme.c b/hw/block/nvme.c index dc9caf07fe..40d4880326 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -487,26 +487,32 @@ static uint16_t nvme_identify(NvmeCtrl *n, NvmeCmd *cmd) static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req) { uint32_t dw10 = le32_to_cpu(cmd->cdw10); + uint32_t result; switch (dw10) { - case NVME_NUMBER_OF_QUEUES: - req->cqe.result = - cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16)); - break; case NVME_VOLATILE_WRITE_CACHE: - req->cqe.result = cpu_to_le32(1); + result = blk_enable_write_cache(n->conf.blk); + break; + case NVME_NUMBER_OF_QUEUES: + result = cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16)); break; default: return NVME_INVALID_FIELD | NVME_DNR; } + + req->cqe.result = result; return NVME_SUCCESS; } static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req) { uint32_t dw10 = le32_to_cpu(cmd->cdw10); + uint32_t dw11 = le32_to_cpu(cmd->cdw11); switch (dw10) { + case NVME_VOLATILE_WRITE_CACHE: + blk_set_enable_write_cache(n->conf.blk, dw11 & 1); + break; case NVME_NUMBER_OF_QUEUES: req->cqe.result = cpu_to_le32((n->num_queues - 1) | ((n->num_queues - 1) << 16)); @@ -831,6 +837,9 @@ static int nvme_init(PCIDevice *pci_dev) id->psd[0].mp = cpu_to_le16(0x9c4); id->psd[0].enlat = cpu_to_le32(0x10); id->psd[0].exlat = cpu_to_le32(0x4); + if (blk_enable_write_cache(n->conf.blk)) { + id->vwc = 1; + } n->bar.cap = 0; NVME_CAP_SET_MQES(n->bar.cap, 0x7ff);