Signed-off-by: Ayush Mishra <ayush....@samsung.com>
---
 hw/nvme/ctrl.c       | 63 ++++++++++++++++++++++++++++++++++++++++++++
 include/block/nvme.h | 21 +++++++++++++++
 2 files changed, 84 insertions(+)

diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c
index 93c950b5b2..5ef2282fd2 100644
--- a/hw/nvme/ctrl.c
+++ b/hw/nvme/ctrl.c
@@ -252,6 +252,24 @@ static const bool nvme_feature_support[NVME_FID_MAX] = {
     [NVME_FDP_EVENTS]               = true,
 };
 
+static const uint32_t nvme_fid_supp_effects[NVME_FID_MAX] = {
+    [NVME_ARBITRATION]             = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_POWER_MANAGEMENT]        = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_TEMPERATURE_THRESHOLD]   = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_ERROR_RECOVERY]          = NVME_EFFECTS_CSUPP | NVME_NMSP_SCOPE,
+    [NVME_VOLATILE_WRITE_CACHE]    = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_NUMBER_OF_QUEUES]        = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_INTERRUPT_COALESCING]    = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_INTERRUPT_VECTOR_CONF]   = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_WRITE_ATOMICITY]         = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_ASYNCHRONOUS_EVENT_CONF] = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_TIMESTAMP]               = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_HOST_BEHAVIOR_SUPPORT]   = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_COMMAND_SET_PROFILE]     = NVME_EFFECTS_CSUPP | NVME_CTRL_SCOPE,
+    [NVME_FDP_MODE]                = NVME_EFFECTS_CSUPP | NVME_ENDURANCE_SCOPE,
+    [NVME_FDP_EVENTS]              = NVME_EFFECTS_CSUPP,
+};
+
 static const uint32_t nvme_feature_cap[NVME_FID_MAX] = {
     [NVME_TEMPERATURE_THRESHOLD]    = NVME_FEAT_CAP_CHANGE,
     [NVME_ERROR_RECOVERY]           = NVME_FEAT_CAP_CHANGE | NVME_FEAT_CAP_NS,
@@ -5086,6 +5104,47 @@ static uint16_t nvme_endgrp_info(NvmeCtrl *n,  uint8_t 
rae, uint32_t buf_len,
     return nvme_c2h(n, (uint8_t *)&info + off, buf_len, req);
 }
 
+static uint16_t nvme_log_fid_supp_effects_log(NvmeCtrl *n, uint8_t csi,
+                uint32_t buf_len, uint64_t off, NvmeRequest *req)
+{
+    NvmeFidSuppLog log = {};
+    const uint32_t *supp_fid = NULL;
+    uint32_t trans_len;
+    bool ot = le32_to_cpu(req->cmd.cdw14) >> 23;
+
+    if (off >= sizeof(log) || (ot == 1 && (off * 4 >= sizeof(log)))) {
+        trace_pci_nvme_err_invalid_log_page_offset(off, sizeof(log));
+        return NVME_INVALID_FIELD | NVME_DNR;
+    }
+
+    switch (NVME_CC_CSS(ldl_le_p(&n->bar.cc))) {
+    case NVME_CC_CSS_NVM:
+        supp_fid = nvme_fid_supp_effects;
+        /* fall through */
+    case NVME_CC_CSS_ADMIN_ONLY:
+        break;
+    case NVME_CC_CSS_ALL:
+        switch (csi) {
+        case NVME_CSI_NVM:
+            supp_fid = nvme_fid_supp_effects;
+            break;
+        case NVME_CSI_ZONED:
+            break;
+        }
+    }
+
+    if (ot == 1) {
+        off *= 4;
+    }
+
+    if (supp_fid) {
+        memcpy(log.fis, supp_fid, sizeof(log.fis));
+    }
+
+    trans_len = MIN(sizeof(log) - off, buf_len);
+
+    return nvme_c2h(n, ((uint8_t *)&log) + off, trans_len, req);
+}
 
 static uint16_t nvme_fw_log_info(NvmeCtrl *n, uint32_t buf_len, uint64_t off,
                                  NvmeRequest *req)
@@ -5506,6 +5565,8 @@ static uint16_t nvme_get_log(NvmeCtrl *n, NvmeRequest 
*req)
         return nvme_cmd_effects(n, csi, len, off, req);
     case NVME_LOG_ENDGRP:
         return nvme_endgrp_info(n, rae, len, off, req);
+    case NVME_LOG_FID_SUPP_EFFECTS:
+        return nvme_log_fid_supp_effects_log(n, csi, len, off, req);
     case NVME_LOG_FDP_CONFS:
         return nvme_fdp_confs(n, lspi, len, off, req);
     case NVME_LOG_FDP_RUH_USAGE:
@@ -8930,6 +8991,8 @@ static void nvme_init_ctrl(NvmeCtrl *n, PCIDevice 
*pci_dev)
     n->supplogpage[NVME_LOG_CHANGED_NSLIST].lsupp_ios = NVME_LID_SUPP;
     n->supplogpage[NVME_LOG_CMD_EFFECTS].lsupp_ios = NVME_LID_SUPP;
     n->supplogpage[NVME_LOG_ENDGRP].lsupp_ios = NVME_LID_SUPP;
+    n->supplogpage[NVME_LOG_FID_SUPP_EFFECTS].lsupp_ios = NVME_LID_SUPP
+                                                        | NVME_INDEX_OFF_SUPP;
     n->supplogpage[NVME_LOG_FDP_CONFS].lsupp_ios = NVME_LID_SUPP;
     n->supplogpage[NVME_LOG_FDP_RUH_USAGE].lsupp_ios = NVME_LID_SUPP;
     n->supplogpage[NVME_LOG_FDP_STATS].lsupp_ios = NVME_LID_SUPP;
diff --git a/include/block/nvme.h b/include/block/nvme.h
index c38422b38d..0ba69477a0 100644
--- a/include/block/nvme.h
+++ b/include/block/nvme.h
@@ -1068,6 +1068,10 @@ typedef struct NvmeEffectsLog {
     uint8_t     resv[2048];
 } NvmeEffectsLog;
 
+typedef struct NvmeFidSuppLog {
+    uint32_t    fis[256];
+} NvmeFidSuppLog;
+
 enum {
     NVME_CMD_EFF_CSUPP      = 1 << 0,
     NVME_CMD_EFF_LBCC       = 1 << 1,
@@ -1086,6 +1090,7 @@ enum NvmeLogIdentifier {
     NVME_LOG_CHANGED_NSLIST             = 0x04,
     NVME_LOG_CMD_EFFECTS                = 0x05,
     NVME_LOG_ENDGRP                     = 0x09,
+    NVME_LOG_FID_SUPP_EFFECTS           = 0x12,
     NVME_LOG_FDP_CONFS                  = 0x20,
     NVME_LOG_FDP_RUH_USAGE              = 0x21,
     NVME_LOG_FDP_STATS                  = 0x22,
@@ -1364,6 +1369,22 @@ typedef enum NvmeFeatureCap {
     NVME_FEAT_CAP_CHANGE    = 1 << 2,
 } NvmeFeatureCap;
 
+typedef enum NvmeFidSuppEffects {
+    NVME_EFFECTS_CSUPP      = 1 <<  0,
+    NVME_EFFECTS_UDCC       = 1 <<  1,
+    NVME_EFFECTS_NCC        = 1 <<  2,
+    NVME_EFFECTS_NIC        = 1 <<  3,
+    NVME_EFFECTS_CCC        = 1 <<  4,
+    NVME_EFFECTS_UUID_SEL   = 1 << 19,
+    NVME_NMSP_SCOPE         = 1 << 20,
+    NVME_CTRL_SCOPE         = 1 << 21,
+    NVME_NVM_SET_SCOPE      = 1 << 22,
+    NVME_ENDURANCE_SCOPE    = 1 << 23,
+    NVME_DOMAIN_SCOPE       = 1 << 24,
+    NVME_SUBSYSTEM_SCOPE    = 1 << 25,
+    NVME_CTRL_DATA_QUEUE    = 1 << 26,
+} NvmeFidSuppEffects;
+
 typedef enum NvmeGetFeatureSelect {
     NVME_GETFEAT_SELECT_CURRENT = 0x0,
     NVME_GETFEAT_SELECT_DEFAULT = 0x1,
-- 
2.43.0


Reply via email to