From: Denis Mukhin <[email protected]> 

Implement the NVM flush command (opcode 0x00) to allow callers to
synchronize any buffered data with the backing NVMe storage.

Signed-off-by: Denis Mukhin <[email protected]>
---
Changes since v2:
- gate flush by VWC check

Changes since v1:
- moved generic disk_blk_flush() to a separate patch
---
 drivers/nvme/nvme.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c
index 7bb6bb7b53f3..869e906396ae 100644
--- a/drivers/nvme/nvme.c
+++ b/drivers/nvme/nvme.c
@@ -821,9 +821,34 @@ static ulong nvme_blk_write(struct udevice *udev, lbaint_t 
blknr,
        return nvme_blk_rw(udev, blknr, blkcnt, (void *)buffer, false);
 }
 
+/*
+ * NVM Flush command (opcode 0x00).
+ *
+ * Applies to a single namespace; the controller must commit all dirty
+ * data for that namespace to storage before completing the command.
+ */
+static ulong nvme_blk_flush(struct udevice *udev)
+{
+       struct nvme_ns *ns = dev_get_priv(udev);
+       struct nvme_dev *dev = ns->dev;
+
+       if (dev->flags & NVME_VWC_ENABLED) {
+               struct nvme_command c;
+
+               memset(&c, 0, sizeof(c));
+               c.common.opcode = nvme_cmd_flush;
+               c.common.nsid = cpu_to_le32(ns->ns_id);
+
+               return nvme_submit_sync_cmd(dev->queues[NVME_IO_Q], &c, NULL, 
IO_TIMEOUT);
+       }
+
+       return 0;
+}
+
 static const struct blk_ops nvme_blk_ops = {
        .read   = nvme_blk_read,
        .write  = nvme_blk_write,
+       .flush  = nvme_blk_flush,
 };
 
 U_BOOT_DRIVER(nvme_blk) = {
-- 
2.54.0

Reply via email to