Index: usr.sbin/bhyve/pci_nvme.c =================================================================== --- usr.sbin/bhyve/pci_nvme.c +++ usr.sbin/bhyve/pci_nvme.c @@ -365,6 +365,8 @@ cd->oncs = (NVME_CTRLR_DATA_ONCS_DSM_MASK << NVME_CTRLR_DATA_ONCS_DSM_SHIFT); cd->fna = 0x03; + cd->vwc = 1 << NVME_CTRLR_DATA_VWC_PRESENT_SHIFT; + cd->power_state[0].mp = 10; } @@ -979,6 +981,7 @@ break; case NVME_FEAT_VOLATILE_WRITE_CACHE: DPRINTF((" volatile write cache\r\n")); + compl->cdw0 = 1; break; case NVME_FEAT_NUMBER_OF_QUEUES: compl->cdw0 = NVME_FEATURE_NUM_QUEUES(sc); @@ -1472,6 +1475,50 @@ return (err); } +static int +nvme_opc_flush(struct pci_nvme_softc *sc, + struct nvme_command *cmd, + struct pci_nvme_blockstore *nvstore, + struct pci_nvme_ioreq *req, + uint16_t *status) +{ + int err; + + /* Check if the given nsid in command is out-of-range */ + if ((!cmd->nsid || cmd->nsid > sc->ctrldata.nn) && + cmd->nsid != NVME_GLOBAL_NAMESPACE_TAG) { + pci_nvme_status_genc(status, + NVME_SC_INVALID_NAMESPACE_OR_FORMAT); + + return (1); + } + + if (nvstore->type == NVME_STOR_RAM) { + uint16_t status; + + pci_nvme_status_genc(&status, NVME_SC_SUCCESS); + pci_nvme_set_completion(sc, req->nvme_sq, req->sqid, cmd->cid, 0, + status, 1); + + return (0); + } + + req->opc = cmd->opc; + req->cid = cmd->cid; + req->nsid = cmd->nsid; + req->io_req.br_iovcnt = 0; + req->io_req.br_offset = 0; + req->io_req.br_resid = 0; + + req->io_req.br_callback = pci_nvme_io_done; + + err = blockif_flush(sc->nvstore.ctx, &req->io_req); + if (err) + pci_nvme_status_genc(status, NVME_SC_INTERNAL_DEVICE_ERROR); + + return (err); +} + static void pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint16_t idx) { @@ -1506,13 +1553,7 @@ lba = ((uint64_t)cmd->cdw11 << 32) | cmd->cdw10; - if (cmd->opc == NVME_OPC_FLUSH) { - pci_nvme_status_genc(&status, NVME_SC_SUCCESS); - pci_nvme_set_completion(sc, sq, idx, cmd->cid, 0, - status, 1); - - continue; - } else if (cmd->opc == 0x08) { + if (cmd->opc == 0x08) { /* TODO: write zeroes */ WPRINTF(("%s write zeroes lba 0x%lx blocks %u\r\n", __func__, lba, cmd->cdw12 & 0xFFFF)); @@ -1529,7 +1570,15 @@ req->sqid = idx; } - if (cmd->opc == NVME_OPC_DATASET_MANAGEMENT) { + if (cmd->opc == NVME_OPC_FLUSH) { + if (nvme_opc_flush(sc, cmd, &sc->nvstore, req, + &status)) { + pci_nvme_set_completion(sc, sq, idx, cmd->cid, + 0, status, 1); + pci_nvme_release_ioreq(sc, req); + } + continue; + } else if (cmd->opc == NVME_OPC_DATASET_MANAGEMENT) { if (nvme_opc_dataset_mgmt(sc, cmd, &sc->nvstore, req, &status)) { pci_nvme_set_completion(sc, sq, idx, cmd->cid,