[15/16] nvdimm: support NFIT_CMD_GET_CONFIG_DATA
diff mbox

Message ID 1435762232-15543-16-git-send-email-guangrong.xiao@linux.intel.com
State New
Headers show

Commit Message

Xiao Guangrong July 1, 2015, 2:50 p.m. UTC
Function 5 is used to get Namespace Label Data

Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com>
---
 hw/mem/pc-nvdimm.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

Patch
diff mbox

diff --git a/hw/mem/pc-nvdimm.c b/hw/mem/pc-nvdimm.c
index 7e5446c..0498de3 100644
--- a/hw/mem/pc-nvdimm.c
+++ b/hw/mem/pc-nvdimm.c
@@ -423,6 +423,7 @@  struct dsm_buffer {
     uint32_t arg1;
     uint32_t arg2;
     union {
+        struct cmd_in_get_config_data cmd_config_get;
         struct cmd_in_set_config_data cmd_config_set;
         char arg3[PAGE_SIZE - 3 * sizeof(uint32_t) - 16 * sizeof(uint8_t)];
     };
@@ -525,6 +526,35 @@  exit:
     return status;
 }
 
+static uint32_t dsm_cmd_config_get(struct dsm_buffer *in, struct dsm_out *out)
+{
+    GSList *list = get_nvdimm_built_list();
+    PCNVDIMMDevice *nvdimm = get_nvdimm_device_by_handle(list, in->handle);
+    struct cmd_in_get_config_data *cmd_in = &in->cmd_config_get;
+    uint32_t status = NFIT_STATUS_NON_EXISTING_MEM_DEV;
+
+    if (!nvdimm) {
+        goto exit;
+    }
+
+    nvdebug("Read Config: offset %#x length %#x.\n", cmd_in->offset,
+            cmd_in->length);
+    if (nvdimm->config_data_size < cmd_in->length + cmd_in->offset) {
+        nvdebug("position %#x is beyond config data (len = %#lx).\n",
+                cmd_in->length + cmd_in->offset, nvdimm->config_data_size);
+        status = NFIT_STATUS_INVALID_PARAS;
+        goto exit;
+    }
+
+    status = NFIT_STATUS_SUCCESS;
+    memcpy(out->cmd_config_get.out_buf, nvdimm->config_data_addr +
+           cmd_in->offset, cmd_in->length);
+
+exit:
+    g_slist_free(list);
+    return status;
+}
+
 static void dsm_write_nvdimm(struct dsm_buffer *in, struct dsm_out *out)
 {
     uint32_t function = in->arg2;
@@ -537,6 +567,9 @@  static void dsm_write_nvdimm(struct dsm_buffer *in, struct dsm_out *out)
     case NFIT_CMD_GET_CONFIG_SIZE:
         status = dsm_cmd_config_size(in, out);
         break;
+    case NFIT_CMD_GET_CONFIG_DATA:
+        status = dsm_cmd_config_get(in, out);
+        break;
     default:
         status = NFIT_STATUS_NOT_SUPPORTED;
     };