]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
plugins/ocp: Added ocp unsupported requirements log page
authorVigneshwaran Saravanan <s.vignesh@samsung.com>
Fri, 28 Apr 2023 07:12:39 +0000 (12:42 +0530)
committerDaniel Wagner <wagi@monom.org>
Mon, 15 May 2023 14:30:55 +0000 (16:30 +0200)
Reviewed-by: Karthik Balan <karthik.b82@samsung.com>
Reviewed-by: Arunpandian J <arun.j@samsung.com>
Signed-off-by: Vigneshwaran Saravanan <s.vignesh@samsung.com>
Documentation/nvme-ocp-unsupported-reqs-log-pages.txt [new file with mode: 0644]
plugins/ocp/ocp-nvme.c
plugins/ocp/ocp-nvme.h

diff --git a/Documentation/nvme-ocp-unsupported-reqs-log-pages.txt b/Documentation/nvme-ocp-unsupported-reqs-log-pages.txt
new file mode 100644 (file)
index 0000000..65818d3
--- /dev/null
@@ -0,0 +1,45 @@
+unsupported-reqs-log
+====================
+
+NAME
+----
+unsupported-reqs-log - Retrieves unsupported requirements log page of given OCP
+compliant device
+
+SYNOPSIS
+--------
+[verse]
+'nvme ocp unsupported-reqs-log' <device> [--output-format=<fmt> | -o <fmt>]
+
+DESCRIPTION
+-----------
+For the NVMe device given, send a unsupported-reqs-log command and
+provide the unsupported requirements log page.
+
+The <device> parameter is mandatory and may be either the NVMe character
+device (ex: /dev/nvme0) or block device (ex: /dev/nvme0n1).
+
+This will only work on OCP compliant devices supporting this feature.
+Results for any other device are undefined.
+
+On success it returns 0, error code otherwise.
+
+OPTIONS
+-------
+
+-o <format>::
+--output-format=<format>::
+       This option will set the reporting format to normal, json, or binary.
+       Only one output format can be used at a time.
+
+EXAMPLES
+--------
+* Has the program issue a unsupported-reqs-log command to retrieve the 0xC5 log page.
++
+------------
+# nvme ocp unsupported-reqs-log /dev/nvme0
+------------
+
+NVME
+----
+Part of the nvme-user suite
\ No newline at end of file
index 607355253572f4cf2d1d873000864b93f927b533..7778d9ba6bc18e36ece81f760b649481c4d0e551 100644 (file)
@@ -1245,6 +1245,213 @@ static int ocp_telemetry_log(int argc, char **argv, struct command *cmd,
 return err;
 }
 
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+/// Unsupported Requirement Log Page (LID : C5h)
+
+/* C5 Unsupported Requirement Log Page */
+#define C5_GUID_LENGTH                     16
+#define C5_UNSUPPORTED_REQS_LEN            4096
+#define C5_UNSUPPORTED_REQS_OPCODE         0xC5
+#define C5_UNSUPPORTED_REQS_LOG_VERSION    0x1
+#define C5_NUM_UNSUPPORTED_REQ_ENTRIES     253
+
+static __u8 unsupported_req_guid[C5_GUID_LENGTH] = {
+       0x2F, 0x72, 0x9C, 0x0E,
+       0x99, 0x23, 0x2C, 0xBB,
+       0x63, 0x48, 0x32, 0xD0,
+       0xB7, 0x98, 0xBB, 0xC7
+};
+
+/*
+ * struct unsupported_requirement_log - unsupported requirement list
+ * @unsupported_count:        Number of Unsupported Requirement IDs
+ * @rsvd1:                    Reserved
+ * @unsupported_req_list:     Unsupported Requirements lists upto 253.
+ * @rsvd2:                    Reserved
+ * @log_page_version:         indicates the version of the mapping this log page uses.
+                              Shall be set to 0001h
+ * @log_page_guid:            Shall be set to C7BB98B7D0324863BB2C23990E9C722Fh.
+*/
+struct __attribute__((__packed__)) unsupported_requirement_log {
+       __le16  unsupported_count;
+       __u8    rsvd1[14];
+       __u8    unsupported_req_list[C5_NUM_UNSUPPORTED_REQ_ENTRIES][16];
+       __u8    rsvd2[14];
+       __le16  log_page_version;
+       __u8    log_page_guid[C5_GUID_LENGTH];
+};
+
+/*Function declaration for unsupported requirement log page(LID:C5h)*/
+static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *cmd,
+                                            struct plugin *plugin);
+
+static int ocp_print_C5_log_normal(struct nvme_dev *dev,
+                                                  struct unsupported_requirement_log *log_data)
+{
+       int j;
+       printf("Unsupported Requirement-C5 Log Page Data- \n");
+
+       printf("  Number Unsupported Req IDs            : 0x%x \n", le16_to_cpu(log_data->unsupported_count));
+
+       for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++) {
+               printf("  Unsupported Requirement List %d       : %s \n", j, log_data->unsupported_req_list[j]);
+       }
+
+       printf("  Log Page Version                      : 0x%x \n", le16_to_cpu(log_data->log_page_version));
+       printf("  Log page GUID                         : 0x");
+       for (j = C5_GUID_LENGTH - 1; j >= 0; j--) {
+               printf("%x", log_data->log_page_guid[j]);
+       }
+       printf("\n");
+
+       return 0;
+}
+
+static void ocp_print_C5_log_json(struct unsupported_requirement_log *log_data)
+{
+       int j;
+       struct json_object *root;
+       root = json_create_object();
+
+       json_object_add_value_int(root, "Number Unsupported Req IDs", le16_to_cpu(log_data->unsupported_count));
+
+       char unsup_req_list_str[40];
+       memset((void *)unsup_req_list_str, 0, 40);
+       for (j = 0; j < le16_to_cpu(log_data->unsupported_count); j++) {
+               sprintf((char *)unsup_req_list_str, "Unsupported Requirement List %d", j);
+               json_object_add_value_string(root, unsup_req_list_str, (char *)log_data->unsupported_req_list[j]);
+       }
+
+       json_object_add_value_int(root, "Log Page Version", le16_to_cpu(log_data->log_page_version));
+       char guid_buf[C5_GUID_LENGTH];
+       char *guid = guid_buf;
+       memset((void*)guid, 0, C5_GUID_LENGTH);
+       for (j = C5_GUID_LENGTH - 1; j >= 0; j--){
+               guid += sprintf(guid, "%02x", log_data->log_page_guid[j]);
+       }
+       json_object_add_value_string(root, "Log page GUID", guid_buf);
+
+       json_print_object(root, NULL);
+       printf("\n");
+
+       json_free_object(root);
+}
+
+static void ocp_print_c5_log_binary(struct unsupported_requirement_log *log_data)
+{
+       return d_raw((unsigned char *)log_data, sizeof(*log_data));
+}
+
+static int get_c5_log_page(struct nvme_dev *dev, char *format)
+{
+       int ret = 0;
+       int fmt = -1;
+       __u8 *data;
+       int i;
+       struct unsupported_requirement_log *log_data;
+
+       fmt = validate_output_format(format);
+       if (fmt < 0) {
+               fprintf(stderr, "ERROR : OCP : invalid output format\n");
+               return fmt;
+       }
+
+       if ((data = (__u8 *) malloc(sizeof(__u8) * C5_UNSUPPORTED_REQS_LEN)) == NULL) {
+               fprintf(stderr, "ERROR : OCP : malloc : %s\n", strerror(errno));
+               return -1;
+       }
+       memset(data, 0, sizeof (__u8) * C5_UNSUPPORTED_REQS_LEN);
+
+       ret = nvme_get_log_simple(dev_fd(dev), C5_UNSUPPORTED_REQS_OPCODE,
+                                                         C5_UNSUPPORTED_REQS_LEN, data);
+
+       if (ret == 0) {
+               log_data = (struct unsupported_requirement_log*)data;
+
+               /* check log page version */
+               if (log_data->log_page_version != C5_UNSUPPORTED_REQS_LOG_VERSION) {
+                       fprintf(stderr, "ERROR : OCP : invalid unsupported requirement version\n");
+                       ret = -1;
+                       goto out;
+               }
+
+               /* check log page guid */
+               /* Verify GUID matches */
+               for (i=0; i<16; i++) {
+                       if (unsupported_req_guid[i] != log_data->log_page_guid[i]) {
+                               fprintf(stderr, "ERROR : OCP : Unknown GUID in C5 Log Page data\n");
+                               int j;
+                               fprintf(stderr, "ERROR : OCP : Expected GUID: 0x");
+                               for (j = 0; j<16; j++) {
+                                       fprintf(stderr, "%x", unsupported_req_guid[j]);
+                               }
+                               fprintf(stderr, "\nERROR : OCP : Actual GUID: 0x");
+                               for (j = 0; j<16; j++) {
+                                       fprintf(stderr, "%x", log_data->log_page_guid[j]);
+                               }
+                               fprintf(stderr, "\n");
+
+                               ret = -1;
+                               goto out;
+                       }
+               }
+
+               switch (fmt) {
+               case NORMAL:
+                       ocp_print_C5_log_normal(dev, log_data);
+                       break;
+               case JSON:
+                       ocp_print_C5_log_json(log_data);
+                       break;
+               case BINARY:
+                       ocp_print_c5_log_binary(log_data);
+                       break;
+               }
+       } else {
+               fprintf(stderr, "ERROR : OCP : Unable to read C3 data from buffer\n");
+       }
+
+out:
+       free(data);
+       return ret;
+}
+
+
+static int ocp_unsupported_requirements_log(int argc, char **argv, struct command *cmd,
+                                            struct plugin *plugin)
+{
+       const char *desc = "Retrieve unsupported requirements log data.";
+       struct nvme_dev *dev;
+       int ret = 0;
+
+       struct config {
+               char *output_format;
+       };
+
+       struct config cfg = {
+               .output_format = "normal",
+       };
+
+       OPT_ARGS(opts) = {
+               OPT_FMT("output-format", 'o', &cfg.output_format, "output Format: normal|json"),
+               OPT_END()
+       };
+
+       ret = parse_and_open(&dev, argc, argv, desc, opts);
+       if (ret)
+               return ret;
+
+       ret = get_c5_log_page(dev, cfg.output_format);
+       if (ret)
+               fprintf(stderr, "ERROR : OCP : Failure reading the C5 Log Page, ret = %d\n", ret);
+
+       dev_close(dev);
+       return ret;
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
index a4390db8a229cfb39296b377e022b7d2fb6588ad..24f91af8a13e558f33c8e9807546e898fdd5b83f 100644 (file)
@@ -23,6 +23,7 @@ PLUGIN(NAME("ocp", "OCP cloud SSD extensions", NVME_VERSION),
                ENTRY("eol-plp-failure-mode", "Define EOL or PLP circuitry failure mode.", eol_plp_failure_mode)
                ENTRY("clear-pcie-correctable-error-counters", "Clear PCIe correctable error counters", clear_pcie_corectable_error_counters)
                ENTRY("vs-fw-activate-history", "Get firmware activation history log", fw_activation_history_log)
+               ENTRY("unsupported-reqs-log", "Get Unsupported Requirements Log Page", ocp_unsupported_requirements_log)
        )
 );