Author: chuck
Date: Sun Jul 19 22:40:02 2020
New Revision: 363334
URL: https://svnweb.freebsd.org/changeset/base/363334

Log:
  MFC r362746 bhyve: implement NVMe Flush command

Modified:
  stable/12/usr.sbin/bhyve/pci_nvme.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/usr.sbin/bhyve/pci_nvme.c
==============================================================================
--- stable/12/usr.sbin/bhyve/pci_nvme.c Sun Jul 19 22:37:47 2020        
(r363333)
+++ stable/12/usr.sbin/bhyve/pci_nvme.c Sun Jul 19 22:40:02 2020        
(r363334)
@@ -58,6 +58,7 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/errno.h>
 #include <sys/types.h>
 #include <net/ieee_oui.h>
 
@@ -1386,7 +1387,47 @@ pci_nvme_io_partial(struct blockif_req *br, int err)
        pthread_cond_signal(&req->cv);
 }
 
+/*
+ * Implements the Flush command. The specification states:
+ *    If a volatile write cache is not present, Flush commands complete
+ *    successfully and have no effect
+ * in the description of the Volatile Write Cache (VWC) field of the Identify
+ * Controller data. Therefore, set status to Success if the command is
+ * not supported (i.e. RAM or as indicated by the blockif).
+ */
 static bool
+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)
+{
+       bool pending = false;
+
+       if (nvstore->type == NVME_STOR_RAM) {
+               pci_nvme_status_genc(status, NVME_SC_SUCCESS);
+       } else {
+               int err;
+
+               req->io_req.br_callback = pci_nvme_io_done;
+
+               err = blockif_flush(nvstore->ctx, &req->io_req);
+               switch (err) {
+               case 0:
+                       pending = true;
+                       break;
+               case EOPNOTSUPP:
+                       pci_nvme_status_genc(status, NVME_SC_SUCCESS);
+                       break;
+               default:
+                       pci_nvme_status_genc(status, 
NVME_SC_INTERNAL_DEVICE_ERROR);
+               }
+       }
+
+       return (pending);
+}
+
+static bool
 nvme_opc_write_read(struct pci_nvme_softc *sc,
     struct nvme_command *cmd,
     struct pci_nvme_blockstore *nvstore,
@@ -1681,7 +1722,8 @@ pci_nvme_handle_io_cmd(struct pci_nvme_softc* sc, uint
 
                switch (cmd->opc) {
                case NVME_OPC_FLUSH:
-                       pci_nvme_status_genc(&status, NVME_SC_SUCCESS);
+                       pending = nvme_opc_flush(sc, cmd, &sc->nvstore,
+                           req, &status);
                        break;
                case NVME_OPC_WRITE:
                case NVME_OPC_READ:
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to