nvme: add support for NVMe 1.3 Timestamp Feature
authorJon Derrick <jonathan.derrick@intel.com>
Wed, 16 Aug 2017 07:51:29 +0000 (09:51 +0200)
committerChristoph Hellwig <hch@lst.de>
Mon, 28 Aug 2017 19:38:18 +0000 (21:38 +0200)
NVME's Timestamp feature allows controllers to be aware of the epoch
time in milliseconds. This patch adds the set features hook for various
transports through the identify path, so that resets and resumes can
update the controller as necessary.

Signed-off-by: Jon Derrick <jonathan.derrick@intel.com>
[hch: rebased on top of nvme-4.13 error handling changes,
      changed nvme_configure_timestamp to return the status]
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/host/core.c
include/linux/nvme.h

index a6afeedc009afe969b49082fc21de112a42dbce8..0b979e16655eecff5c3176084575fcb15386abac 100644 (file)
@@ -1507,6 +1507,23 @@ static void nvme_set_queue_limits(struct nvme_ctrl *ctrl,
        blk_queue_write_cache(q, vwc, vwc);
 }
 
+static int nvme_configure_timestamp(struct nvme_ctrl *ctrl)
+{
+       __le64 ts;
+       int ret;
+
+       if (!(ctrl->oncs & NVME_CTRL_ONCS_TIMESTAMP))
+               return 0;
+
+       ts = cpu_to_le64(ktime_to_ms(ktime_get_real()));
+       ret = nvme_set_features(ctrl, NVME_FEAT_TIMESTAMP, 0, &ts, sizeof(ts),
+                       NULL);
+       if (ret)
+               dev_warn_once(ctrl->device,
+                       "could not set timestamp (%d)\n", ret);
+       return ret;
+}
+
 static int nvme_configure_apst(struct nvme_ctrl *ctrl)
 {
        /*
@@ -1861,6 +1878,10 @@ int nvme_init_identify(struct nvme_ctrl *ctrl)
        ret = nvme_configure_apst(ctrl);
        if (ret < 0)
                return ret;
+       
+       ret = nvme_configure_timestamp(ctrl);
+       if (ret < 0)
+               return ret;
 
        ret = nvme_configure_directives(ctrl);
        if (ret < 0)
index 1d79046bf9d410ee4cfa6bf4614d7fc6e4b36505..a12b4707327323170c0caab84814136c49374e16 100644 (file)
@@ -254,6 +254,7 @@ enum {
        NVME_CTRL_ONCS_WRITE_UNCORRECTABLE      = 1 << 1,
        NVME_CTRL_ONCS_DSM                      = 1 << 2,
        NVME_CTRL_ONCS_WRITE_ZEROES             = 1 << 3,
+       NVME_CTRL_ONCS_TIMESTAMP                = 1 << 6,
        NVME_CTRL_VWC_PRESENT                   = 1 << 0,
        NVME_CTRL_OACS_SEC_SUPP                 = 1 << 0,
        NVME_CTRL_OACS_DIRECTIVES               = 1 << 5,
@@ -688,6 +689,7 @@ enum {
        NVME_FEAT_ASYNC_EVENT   = 0x0b,
        NVME_FEAT_AUTO_PST      = 0x0c,
        NVME_FEAT_HOST_MEM_BUF  = 0x0d,
+       NVME_FEAT_TIMESTAMP     = 0x0e,
        NVME_FEAT_KATO          = 0x0f,
        NVME_FEAT_SW_PROGRESS   = 0x80,
        NVME_FEAT_HOST_ID       = 0x81,