LCOV - code coverage report
Current view: top level - spdk/app/spdk_nvme_identify - identify.c (source / functions) Hit Total Coverage
Test: Combined Lines: 1292 1936 66.7 %
Date: 2024-07-12 19:53:08 Functions: 39 54 72.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 1041 2485 41.9 %

           Branch data     Line data    Source code
       1                 :            : /*   SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  *   Copyright (C) 2015 Intel Corporation. All rights reserved.
       3                 :            :  *   Copyright (c) 2020 Mellanox Technologies LTD. All rights reserved.
       4                 :            :  */
       5                 :            : 
       6                 :            : #include "spdk/stdinc.h"
       7                 :            : 
       8                 :            : #include "spdk/endian.h"
       9                 :            : #include "spdk/log.h"
      10                 :            : #include "spdk/nvme.h"
      11                 :            : #include "spdk/vmd.h"
      12                 :            : #include "spdk/nvme_ocssd.h"
      13                 :            : #include "spdk/nvme_zns.h"
      14                 :            : #include "spdk/env.h"
      15                 :            : #include "spdk/nvme_intel.h"
      16                 :            : #include "spdk/nvmf_spec.h"
      17                 :            : #include "spdk/pci_ids.h"
      18                 :            : #include "spdk/string.h"
      19                 :            : #include "spdk/util.h"
      20                 :            : #include "spdk/uuid.h"
      21                 :            : #include "spdk/sock.h"
      22                 :            : 
      23                 :            : #define MAX_DISCOVERY_LOG_ENTRIES       ((uint64_t)1000)
      24                 :            : 
      25                 :            : #define NUM_CHUNK_INFO_ENTRIES          8
      26                 :            : #define MAX_OCSSD_PU                    128
      27                 :            : #define MAX_ZONE_DESC_ENTRIES           8
      28                 :            : 
      29                 :            : #define FDP_LOG_PAGE_SIZE               4096
      30                 :            : 
      31                 :            : static int outstanding_commands;
      32                 :            : 
      33                 :            : struct feature {
      34                 :            :         uint32_t result;
      35                 :            :         bool valid;
      36                 :            : };
      37                 :            : 
      38                 :            : static struct feature features[256] = {};
      39                 :            : 
      40                 :            : static struct spdk_nvme_error_information_entry error_page[256];
      41                 :            : 
      42                 :            : static struct spdk_nvme_health_information_page health_page;
      43                 :            : 
      44                 :            : static struct spdk_nvme_firmware_page firmware_page;
      45                 :            : 
      46                 :            : static struct spdk_nvme_ana_page *g_ana_log_page;
      47                 :            : 
      48                 :            : static struct spdk_nvme_ana_group_descriptor *g_copied_ana_desc;
      49                 :            : 
      50                 :            : static size_t g_ana_log_page_size;
      51                 :            : 
      52                 :            : static size_t g_fdp_cfg_log_page_size;
      53                 :            : 
      54                 :            : static size_t g_fdp_ruhu_log_page_size;
      55                 :            : 
      56                 :            : static size_t g_fdp_events_log_page_size;
      57                 :            : 
      58                 :            : static struct spdk_nvme_fdp_stats_log_page g_fdp_stats_log_page;
      59                 :            : 
      60                 :            : static struct spdk_nvme_fdp_cfg_log_page *g_fdp_cfg_log_page;
      61                 :            : 
      62                 :            : static struct spdk_nvme_fdp_ruhu_log_page *g_fdp_ruhu_log_page;
      63                 :            : 
      64                 :            : static struct spdk_nvme_fdp_events_log_page *g_fdp_events_log_page;
      65                 :            : 
      66                 :            : static struct spdk_nvme_cmds_and_effect_log_page cmd_effects_log_page;
      67                 :            : 
      68                 :            : static struct spdk_nvme_intel_smart_information_page intel_smart_page;
      69                 :            : 
      70                 :            : static struct spdk_nvme_intel_temperature_page intel_temperature_page;
      71                 :            : 
      72                 :            : static struct spdk_nvme_intel_marketing_description_page intel_md_page;
      73                 :            : 
      74                 :            : static struct spdk_nvmf_discovery_log_page *g_discovery_page;
      75                 :            : static size_t g_discovery_page_size;
      76                 :            : static uint64_t g_discovery_page_numrec;
      77                 :            : 
      78                 :            : static struct spdk_ocssd_geometry_data geometry_data;
      79                 :            : 
      80                 :            : static struct spdk_ocssd_chunk_information_entry *g_ocssd_chunk_info_page;
      81                 :            : 
      82                 :            : static int64_t g_zone_report_limit = 8;
      83                 :            : 
      84                 :            : static bool g_hex_dump = false;
      85                 :            : 
      86                 :            : static int g_shm_id = -1;
      87                 :            : 
      88                 :            : static int g_dpdk_mem = 0;
      89                 :            : 
      90                 :            : static bool g_dpdk_mem_single_seg = false;
      91                 :            : 
      92                 :            : static int g_main_core = 0;
      93                 :            : 
      94                 :            : static char g_core_mask[20] = "0x1";
      95                 :            : 
      96                 :            : static struct spdk_nvme_transport_id g_trid;
      97                 :            : static char g_hostnqn[SPDK_NVMF_NQN_MAX_LEN + 1];
      98                 :            : 
      99                 :            : static int g_controllers_found = 0;
     100                 :            : 
     101                 :            : static bool g_vmd = false;
     102                 :            : 
     103                 :            : static bool g_ocssd_verbose = false;
     104                 :            : 
     105                 :            : static struct spdk_nvme_detach_ctx *g_detach_ctx = NULL;
     106                 :            : 
     107                 :            : static const char *g_iova_mode;
     108                 :            : 
     109                 :            : static void
     110                 :          0 : hex_dump(const void *data, size_t size)
     111                 :            : {
     112                 :          0 :         size_t offset = 0, i;
     113                 :          0 :         const uint8_t *bytes = data;
     114                 :            : 
     115         [ #  # ]:          0 :         while (size) {
     116         [ #  # ]:          0 :                 printf("%08zX:", offset);
     117                 :            : 
     118         [ #  # ]:          0 :                 for (i = 0; i < 16; i++) {
     119         [ #  # ]:          0 :                         if (i == 8) {
     120                 :          0 :                                 printf("-");
     121                 :            :                         } else {
     122                 :          0 :                                 printf(" ");
     123                 :            :                         }
     124                 :            : 
     125         [ #  # ]:          0 :                         if (i < size) {
     126         [ #  # ]:          0 :                                 printf("%02X", bytes[offset + i]);
     127                 :            :                         } else {
     128         [ #  # ]:          0 :                                 printf("  ");
     129                 :            :                         }
     130                 :            :                 }
     131                 :            : 
     132         [ #  # ]:          0 :                 printf("  ");
     133                 :            : 
     134         [ #  # ]:          0 :                 for (i = 0; i < 16; i++) {
     135         [ #  # ]:          0 :                         if (i < size) {
     136   [ #  #  #  # ]:          0 :                                 if (bytes[offset + i] > 0x20 && bytes[offset + i] < 0x7F) {
     137                 :          0 :                                         printf("%c", bytes[offset + i]);
     138                 :            :                                 } else {
     139                 :          0 :                                         printf(".");
     140                 :            :                                 }
     141                 :            :                         }
     142                 :            :                 }
     143                 :            : 
     144                 :          0 :                 printf("\n");
     145                 :            : 
     146                 :          0 :                 offset += 16;
     147         [ #  # ]:          0 :                 if (size > 16) {
     148                 :          0 :                         size -= 16;
     149                 :            :                 } else {
     150                 :          0 :                         break;
     151                 :            :                 }
     152                 :            :         }
     153                 :          0 : }
     154                 :            : 
     155                 :            : static void
     156                 :        332 : get_feature_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl)
     157                 :            : {
     158                 :        332 :         struct feature *feature = cb_arg;
     159                 :        332 :         int fid = feature - features;
     160                 :            : 
     161   [ +  +  -  + ]:        332 :         if (spdk_nvme_cpl_is_error(cpl)) {
     162         [ -  + ]:         16 :                 printf("get_feature(0x%02X) failed\n", fid);
     163                 :            :         } else {
     164                 :        316 :                 feature->result = cpl->cdw0;
     165                 :        316 :                 feature->valid = true;
     166                 :            :         }
     167                 :        332 :         outstanding_commands--;
     168                 :        332 : }
     169                 :            : 
     170                 :            : static void
     171                 :        306 : get_log_page_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl)
     172                 :            : {
     173   [ +  -  -  + ]:        306 :         if (spdk_nvme_cpl_is_error(cpl)) {
     174         [ #  # ]:          0 :                 printf("get log page failed\n");
     175                 :            :         }
     176                 :        306 :         outstanding_commands--;
     177                 :        306 : }
     178                 :            : 
     179                 :            : static void
     180                 :          0 : get_ocssd_geometry_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl)
     181                 :            : {
     182   [ #  #  #  # ]:          0 :         if (spdk_nvme_cpl_is_error(cpl)) {
     183         [ #  # ]:          0 :                 printf("get ocssd geometry failed\n");
     184                 :            :         }
     185                 :          0 :         outstanding_commands--;
     186                 :          0 : }
     187                 :            : 
     188                 :            : static void
     189                 :          0 : get_zns_zone_report_completion(void *cb_arg, const struct spdk_nvme_cpl *cpl)
     190                 :            : {
     191   [ #  #  #  # ]:          0 :         if (spdk_nvme_cpl_is_error(cpl)) {
     192         [ #  # ]:          0 :                 printf("get zns zone report failed\n");
     193                 :            :         }
     194                 :            : 
     195                 :          0 :         outstanding_commands--;
     196                 :          0 : }
     197                 :            : 
     198                 :            : static int
     199                 :        332 : get_feature(struct spdk_nvme_ctrlr *ctrlr, uint8_t fid, uint32_t cdw11, uint32_t nsid)
     200                 :            : {
     201                 :        332 :         struct spdk_nvme_cmd cmd = {};
     202                 :        332 :         struct feature *feature = &features[fid];
     203                 :            : 
     204                 :        332 :         feature->valid = false;
     205                 :            : 
     206                 :        332 :         cmd.opc = SPDK_NVME_OPC_GET_FEATURES;
     207                 :        332 :         cmd.cdw10_bits.get_features.fid = fid;
     208                 :        332 :         cmd.cdw11 = cdw11;
     209                 :        332 :         cmd.nsid = nsid;
     210                 :            : 
     211                 :        332 :         return spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, NULL, 0, get_feature_completion, feature);
     212                 :            : }
     213                 :            : 
     214                 :            : static void
     215                 :        136 : get_features(struct spdk_nvme_ctrlr *ctrlr, uint8_t *features_to_get, size_t num_features,
     216                 :            :              uint32_t nsid)
     217                 :            : {
     218                 :            :         size_t i;
     219                 :            :         uint32_t cdw11;
     220                 :            : 
     221                 :            :         /* Submit only one GET FEATURES at a time. There is a known issue #1799
     222                 :            :          * with Google Cloud Platform NVMe SSDs that do not handle overlapped
     223                 :            :          * GET FEATURES commands correctly.
     224                 :            :          */
     225                 :        136 :         outstanding_commands = 0;
     226         [ +  + ]:        600 :         for (i = 0; i < num_features; i++) {
     227                 :        464 :                 cdw11 = 0;
     228         [ +  - ]:        464 :                 if (!spdk_nvme_ctrlr_is_ocssd_supported(ctrlr) &&
     229         [ +  + ]:        464 :                     features_to_get[i] == SPDK_OCSSD_FEAT_MEDIA_FEEDBACK) {
     230                 :         64 :                         continue;
     231                 :            :                 }
     232         [ +  + ]:        400 :                 if (features_to_get[i] == SPDK_NVME_FEAT_FDP) {
     233                 :         72 :                         const struct spdk_nvme_ctrlr_data *cdata = spdk_nvme_ctrlr_get_data(ctrlr);
     234                 :         72 :                         struct spdk_nvme_ns *ns = spdk_nvme_ctrlr_get_ns(ctrlr, nsid);
     235                 :         72 :                         const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns);
     236                 :            : 
     237         [ +  + ]:         72 :                         if (!cdata->ctratt.bits.fdps) {
     238                 :         68 :                                 continue;
     239                 :            :                         } else {
     240                 :          4 :                                 cdw11 = nsdata->endgid;
     241                 :            :                                 /* Endurance group scope */
     242                 :          4 :                                 nsid = 0;
     243                 :            :                         }
     244                 :            :                 }
     245         [ +  - ]:        332 :                 if (get_feature(ctrlr, features_to_get[i], cdw11, nsid) == 0) {
     246                 :        332 :                         outstanding_commands++;
     247                 :            :                 } else {
     248         [ #  # ]:          0 :                         printf("get_feature(0x%02X) failed to submit command\n", features_to_get[i]);
     249                 :            :                 }
     250                 :            : 
     251         [ +  + ]:       9347 :                 while (outstanding_commands) {
     252                 :       9015 :                         spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     253                 :            :                 }
     254                 :            :         }
     255                 :            : 
     256                 :        136 : }
     257                 :            : 
     258                 :            : static void
     259                 :         64 : get_ctrlr_features(struct spdk_nvme_ctrlr *ctrlr)
     260                 :            : {
     261                 :         64 :         uint8_t features_to_get[] = {
     262                 :            :                 SPDK_NVME_FEAT_ARBITRATION,
     263                 :            :                 SPDK_NVME_FEAT_POWER_MANAGEMENT,
     264                 :            :                 SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD,
     265                 :            :                 SPDK_NVME_FEAT_NUMBER_OF_QUEUES,
     266                 :            :                 SPDK_OCSSD_FEAT_MEDIA_FEEDBACK,
     267                 :            :         };
     268                 :            : 
     269                 :         64 :         get_features(ctrlr, features_to_get, SPDK_COUNTOF(features_to_get), 0);
     270                 :         64 : }
     271                 :            : 
     272                 :            : static void
     273                 :         72 : get_ns_features(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid)
     274                 :            : {
     275                 :         72 :         uint8_t features_to_get[] = {
     276                 :            :                 SPDK_NVME_FEAT_ERROR_RECOVERY,
     277                 :            :                 SPDK_NVME_FEAT_FDP,
     278                 :            :         };
     279                 :            : 
     280                 :         72 :         get_features(ctrlr, features_to_get, SPDK_COUNTOF(features_to_get), nsid);
     281                 :         72 : }
     282                 :            : 
     283                 :            : static int
     284                 :         64 : get_error_log_page(struct spdk_nvme_ctrlr *ctrlr)
     285                 :            : {
     286                 :            :         const struct spdk_nvme_ctrlr_data *cdata;
     287                 :            : 
     288                 :         64 :         cdata = spdk_nvme_ctrlr_get_data(ctrlr);
     289                 :            : 
     290         [ -  + ]:         64 :         if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_ERROR,
     291                 :            :                                              SPDK_NVME_GLOBAL_NS_TAG, error_page,
     292                 :         64 :                                              sizeof(*error_page) * (cdata->elpe + 1),
     293                 :            :                                              0,
     294                 :            :                                              get_log_page_completion, NULL)) {
     295         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
     296                 :          0 :                 exit(1);
     297                 :            :         }
     298                 :            : 
     299                 :         64 :         return 0;
     300                 :            : }
     301                 :            : 
     302                 :            : static int
     303                 :         64 : get_health_log_page(struct spdk_nvme_ctrlr *ctrlr)
     304                 :            : {
     305         [ -  + ]:         64 :         if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_HEALTH_INFORMATION,
     306                 :            :                                              SPDK_NVME_GLOBAL_NS_TAG, &health_page, sizeof(health_page), 0, get_log_page_completion, NULL)) {
     307         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
     308                 :          0 :                 exit(1);
     309                 :            :         }
     310                 :            : 
     311                 :         64 :         return 0;
     312                 :            : }
     313                 :            : 
     314                 :            : static int
     315                 :         64 : get_firmware_log_page(struct spdk_nvme_ctrlr *ctrlr)
     316                 :            : {
     317         [ -  + ]:         64 :         if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_FIRMWARE_SLOT,
     318                 :            :                                              SPDK_NVME_GLOBAL_NS_TAG, &firmware_page, sizeof(firmware_page), 0, get_log_page_completion, NULL)) {
     319         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
     320                 :          0 :                 exit(1);
     321                 :            :         }
     322                 :            : 
     323                 :         64 :         return 0;
     324                 :            : }
     325                 :            : 
     326                 :            : static int
     327                 :          4 : get_ana_log_page(struct spdk_nvme_ctrlr *ctrlr)
     328                 :            : {
     329         [ -  + ]:          4 :         if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS,
     330                 :            :                                              SPDK_NVME_GLOBAL_NS_TAG, g_ana_log_page, g_ana_log_page_size, 0,
     331                 :            :                                              get_log_page_completion, NULL)) {
     332         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
     333                 :          0 :                 exit(1);
     334                 :            :         }
     335                 :            : 
     336                 :          4 :         return 0;
     337                 :            : }
     338                 :            : 
     339                 :            : static int
     340                 :         64 : get_cmd_effects_log_page(struct spdk_nvme_ctrlr *ctrlr)
     341                 :            : {
     342         [ -  + ]:         64 :         if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_LOG_COMMAND_EFFECTS_LOG,
     343                 :            :                                              SPDK_NVME_GLOBAL_NS_TAG, &cmd_effects_log_page, sizeof(cmd_effects_log_page), 0,
     344                 :            :                                              get_log_page_completion, NULL)) {
     345         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
     346                 :          0 :                 exit(1);
     347                 :            :         }
     348                 :            : 
     349                 :         64 :         return 0;
     350                 :            : }
     351                 :            : 
     352                 :            : static int
     353                 :          6 : get_intel_smart_log_page(struct spdk_nvme_ctrlr *ctrlr)
     354                 :            : {
     355         [ -  + ]:          6 :         if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_INTEL_LOG_SMART, SPDK_NVME_GLOBAL_NS_TAG,
     356                 :            :                                              &intel_smart_page, sizeof(intel_smart_page), 0, get_log_page_completion, NULL)) {
     357         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
     358                 :          0 :                 exit(1);
     359                 :            :         }
     360                 :            : 
     361                 :          6 :         return 0;
     362                 :            : }
     363                 :            : 
     364                 :            : static int
     365                 :          6 : get_intel_temperature_log_page(struct spdk_nvme_ctrlr *ctrlr)
     366                 :            : {
     367         [ -  + ]:          6 :         if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_INTEL_LOG_TEMPERATURE,
     368                 :            :                                              SPDK_NVME_GLOBAL_NS_TAG, &intel_temperature_page, sizeof(intel_temperature_page), 0,
     369                 :            :                                              get_log_page_completion, NULL)) {
     370         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
     371                 :          0 :                 exit(1);
     372                 :            :         }
     373                 :          6 :         return 0;
     374                 :            : }
     375                 :            : 
     376                 :            : static int
     377                 :          6 : get_intel_md_log_page(struct spdk_nvme_ctrlr *ctrlr)
     378                 :            : {
     379         [ -  + ]:          6 :         if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_NVME_INTEL_MARKETING_DESCRIPTION,
     380                 :            :                                              SPDK_NVME_GLOBAL_NS_TAG, &intel_md_page, sizeof(intel_md_page), 0,
     381                 :            :                                              get_log_page_completion, NULL)) {
     382         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page() failed\n");
     383                 :          0 :                 exit(1);
     384                 :            :         }
     385                 :          6 :         return 0;
     386                 :            : }
     387                 :            : 
     388                 :            : static void
     389                 :          8 : get_discovery_log_page_cb(void *ctx, int rc, const struct spdk_nvme_cpl *cpl,
     390                 :            :                           struct spdk_nvmf_discovery_log_page *log_page)
     391                 :            : {
     392   [ +  -  +  -  :          8 :         if (rc || spdk_nvme_cpl_is_error(cpl)) {
                   -  + ]
     393         [ #  # ]:          0 :                 printf("get discovery log page failed\n");
     394                 :          0 :                 exit(1);
     395                 :            :         }
     396                 :            : 
     397                 :          8 :         g_discovery_page = log_page;
     398                 :          8 :         g_discovery_page_numrec = from_le64(&log_page->numrec);
     399                 :          8 :         g_discovery_page_size = sizeof(struct spdk_nvmf_discovery_log_page);
     400                 :          8 :         g_discovery_page_size += g_discovery_page_numrec *
     401                 :            :                                  sizeof(struct spdk_nvmf_discovery_log_page_entry);
     402                 :          8 :         outstanding_commands--;
     403                 :          8 : }
     404                 :            : 
     405                 :            : static int
     406                 :          8 : get_discovery_log_page(struct spdk_nvme_ctrlr *ctrlr)
     407                 :            : {
     408                 :          8 :         return spdk_nvme_ctrlr_get_discovery_log_page(ctrlr, get_discovery_log_page_cb, NULL);
     409                 :            : }
     410                 :            : 
     411                 :            : static void
     412                 :         72 : get_log_pages(struct spdk_nvme_ctrlr *ctrlr)
     413                 :            : {
     414                 :            :         const struct spdk_nvme_ctrlr_data *cdata;
     415                 :         72 :         outstanding_commands = 0;
     416                 :         72 :         bool is_discovery = spdk_nvme_ctrlr_is_discovery(ctrlr);
     417                 :         72 :         uint32_t nsid, active_ns_count = 0;
     418                 :            : 
     419                 :         72 :         cdata = spdk_nvme_ctrlr_get_data(ctrlr);
     420                 :            : 
     421         [ +  + ]:         72 :         if (!is_discovery) {
     422                 :            :                 /*
     423                 :            :                  * Only attempt to retrieve the following log pages
     424                 :            :                  * when the NVM subsystem that's being targeted is
     425                 :            :                  * NOT the Discovery Controller which only fields
     426                 :            :                  * a Discovery Log Page.
     427                 :            :                  */
     428         [ +  - ]:         64 :                 if (get_error_log_page(ctrlr) == 0) {
     429                 :         64 :                         outstanding_commands++;
     430                 :            :                 } else {
     431         [ #  # ]:          0 :                         printf("Get Error Log Page failed\n");
     432                 :            :                 }
     433                 :            : 
     434         [ +  - ]:         64 :                 if (get_health_log_page(ctrlr) == 0) {
     435                 :         64 :                         outstanding_commands++;
     436                 :            :                 } else {
     437         [ #  # ]:          0 :                         printf("Get Log Page (SMART/health) failed\n");
     438                 :            :                 }
     439                 :            : 
     440         [ +  - ]:         64 :                 if (get_firmware_log_page(ctrlr) == 0) {
     441                 :         64 :                         outstanding_commands++;
     442                 :            :                 } else {
     443         [ #  # ]:          0 :                         printf("Get Log Page (Firmware Slot Information) failed\n");
     444                 :            :                 }
     445                 :            :         }
     446                 :            : 
     447         [ +  + ]:         72 :         if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_LOG_ASYMMETRIC_NAMESPACE_ACCESS)) {
     448         [ #  # ]:          4 :                 for (nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr);
     449         [ +  + ]:          8 :                      nsid != 0; nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr, nsid)) {
     450                 :          4 :                         active_ns_count++;
     451                 :            :                 }
     452                 :            : 
     453                 :            :                 /* We always set RGO (Return Groups Only) to 0 in this tool, an ANA group
     454                 :            :                  * descriptor is returned only if that ANA group contains namespaces
     455                 :            :                  * that are attached to the controller processing the command, and
     456                 :            :                  * namespaces attached to the controller shall be members of an ANA group.
     457                 :            :                  * Hence the following size should be enough.
     458                 :            :                  */
     459                 :          4 :                 g_ana_log_page_size = sizeof(struct spdk_nvme_ana_page) + cdata->nanagrpid *
     460                 :          4 :                                       sizeof(struct spdk_nvme_ana_group_descriptor) + active_ns_count *
     461                 :            :                                       sizeof(uint32_t);
     462                 :          4 :                 g_ana_log_page = calloc(1, g_ana_log_page_size);
     463         [ -  + ]:          4 :                 if (g_ana_log_page == NULL) {
     464                 :          0 :                         exit(1);
     465                 :            :                 }
     466                 :          4 :                 g_copied_ana_desc = calloc(1, g_ana_log_page_size);
     467         [ -  + ]:          4 :                 if (g_copied_ana_desc == NULL) {
     468                 :          0 :                         exit(1);
     469                 :            :                 }
     470         [ +  - ]:          4 :                 if (get_ana_log_page(ctrlr) == 0) {
     471                 :          4 :                         outstanding_commands++;
     472                 :            :                 } else {
     473         [ #  # ]:          0 :                         printf("Get Log Page (Asymmetric Namespace Access) failed\n");
     474                 :            :                 }
     475                 :            :         }
     476         [ +  + ]:         72 :         if (cdata->lpa.celp) {
     477         [ +  - ]:         64 :                 if (get_cmd_effects_log_page(ctrlr) == 0) {
     478                 :         64 :                         outstanding_commands++;
     479                 :            :                 } else {
     480         [ #  # ]:          0 :                         printf("Get Log Page (Commands Supported and Effects) failed\n");
     481                 :            :                 }
     482                 :            :         }
     483                 :            : 
     484         [ +  + ]:         72 :         if (cdata->vid == SPDK_PCI_VID_INTEL) {
     485         [ +  + ]:         14 :                 if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_INTEL_LOG_SMART)) {
     486         [ +  - ]:          6 :                         if (get_intel_smart_log_page(ctrlr) == 0) {
     487                 :          6 :                                 outstanding_commands++;
     488                 :            :                         } else {
     489         [ #  # ]:          0 :                                 printf("Get Log Page (Intel SMART/health) failed\n");
     490                 :            :                         }
     491                 :            :                 }
     492         [ +  + ]:         14 :                 if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_INTEL_LOG_TEMPERATURE)) {
     493         [ +  - ]:          6 :                         if (get_intel_temperature_log_page(ctrlr) == 0) {
     494                 :          6 :                                 outstanding_commands++;
     495                 :            :                         } else {
     496         [ #  # ]:          0 :                                 printf("Get Log Page (Intel temperature) failed\n");
     497                 :            :                         }
     498                 :            :                 }
     499         [ +  + ]:         14 :                 if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_INTEL_MARKETING_DESCRIPTION)) {
     500         [ +  - ]:          6 :                         if (get_intel_md_log_page(ctrlr) == 0) {
     501                 :          6 :                                 outstanding_commands++;
     502                 :            :                         } else {
     503         [ #  # ]:          0 :                                 printf("Get Log Page (Intel Marketing Description) failed\n");
     504                 :            :                         }
     505                 :            :                 }
     506                 :            : 
     507                 :            :         }
     508                 :            : 
     509   [ +  +  +  - ]:         72 :         if (is_discovery && (get_discovery_log_page(ctrlr) == 0)) {
     510                 :          8 :                 outstanding_commands++;
     511                 :            :         }
     512                 :            : 
     513         [ +  + ]:      23136 :         while (outstanding_commands) {
     514                 :      23064 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     515                 :            :         }
     516                 :         72 : }
     517                 :            : 
     518                 :            : static int
     519                 :          4 : get_fdp_cfg_log_page(struct spdk_nvme_ns *ns)
     520                 :            : {
     521                 :          4 :         struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns);
     522                 :          4 :         const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns);
     523                 :            : 
     524                 :          4 :         outstanding_commands = 0;
     525                 :            : 
     526                 :          4 :         g_fdp_cfg_log_page_size = sizeof(struct spdk_nvme_fdp_cfg_log_page);
     527                 :          4 :         g_fdp_cfg_log_page = calloc(1, g_fdp_cfg_log_page_size);
     528         [ -  + ]:          4 :         if (!g_fdp_cfg_log_page) {
     529         [ #  # ]:          0 :                 printf("FDP config log page allocation failed!\n");
     530                 :          0 :                 return -1;
     531                 :            :         }
     532                 :            : 
     533                 :            :         /* Fetch the FDP configurations log page header */
     534         [ +  - ]:          4 :         if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_CONFIGURATIONS, 0,
     535         [ -  + ]:          4 :                         g_fdp_cfg_log_page, g_fdp_cfg_log_page_size, 0, 0, (nsdata->endgid << 16),
     536                 :            :                         0, get_log_page_completion, NULL) == 0) {
     537                 :          4 :                 outstanding_commands++;
     538                 :            :         } else {
     539         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP config) failed\n");
     540                 :          0 :                 free(g_fdp_cfg_log_page);
     541                 :          0 :                 return -1;
     542                 :            :         }
     543                 :            : 
     544         [ +  + ]:         21 :         while (outstanding_commands) {
     545                 :         17 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     546                 :            :         }
     547                 :            : 
     548                 :          4 :         g_fdp_cfg_log_page_size = g_fdp_cfg_log_page->size;
     549                 :          4 :         g_fdp_cfg_log_page = realloc(g_fdp_cfg_log_page, g_fdp_cfg_log_page_size);
     550         [ -  + ]:          4 :         if (!g_fdp_cfg_log_page) {
     551         [ #  # ]:          0 :                 printf("FDP config log page reallocation failed!\n");
     552                 :          0 :                 return -1;
     553                 :            :         }
     554                 :            : 
     555                 :            :         /* Fetch the FDP configurations log page */
     556         [ +  - ]:          4 :         if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_CONFIGURATIONS, 0,
     557         [ -  + ]:          4 :                         g_fdp_cfg_log_page, g_fdp_cfg_log_page_size, 0, 0, (nsdata->endgid << 16),
     558                 :            :                         0, get_log_page_completion, NULL) == 0) {
     559                 :          4 :                 outstanding_commands++;
     560                 :            :         } else {
     561         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP config) failed\n");
     562                 :          0 :                 free(g_fdp_cfg_log_page);
     563                 :          0 :                 return -1;
     564                 :            :         }
     565                 :            : 
     566         [ +  + ]:         17 :         while (outstanding_commands) {
     567                 :         13 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     568                 :            :         }
     569                 :            : 
     570                 :          4 :         return 0;
     571                 :            : }
     572                 :            : 
     573                 :            : static int
     574                 :          4 : get_fdp_ruhu_log_page(struct spdk_nvme_ns *ns)
     575                 :            : {
     576                 :          4 :         struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns);
     577                 :          4 :         const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns);
     578                 :            : 
     579                 :          4 :         outstanding_commands = 0;
     580                 :            : 
     581                 :          4 :         g_fdp_ruhu_log_page_size = sizeof(struct spdk_nvme_fdp_ruhu_log_page);
     582                 :          4 :         g_fdp_ruhu_log_page = calloc(1, g_fdp_ruhu_log_page_size);
     583         [ -  + ]:          4 :         if (!g_fdp_ruhu_log_page) {
     584         [ #  # ]:          0 :                 printf("FDP RUH usage log page allocation failed!\n");
     585                 :          0 :                 return -1;
     586                 :            :         }
     587                 :            : 
     588                 :            :         /* Fetch the reclaim unit handle usage log page header */
     589         [ +  - ]:          4 :         if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE, 0,
     590         [ -  + ]:          4 :                         g_fdp_ruhu_log_page, g_fdp_ruhu_log_page_size, 0, 0, (nsdata->endgid << 16),
     591                 :            :                         0, get_log_page_completion, NULL) == 0) {
     592                 :          4 :                 outstanding_commands++;
     593                 :            :         } else {
     594         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(RUH usage) failed\n");
     595                 :          0 :                 free(g_fdp_ruhu_log_page);
     596                 :          0 :                 return -1;
     597                 :            :         }
     598                 :            : 
     599         [ +  + ]:         17 :         while (outstanding_commands) {
     600                 :         13 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     601                 :            :         }
     602                 :            : 
     603                 :          4 :         g_fdp_ruhu_log_page_size += g_fdp_ruhu_log_page->nruh *
     604                 :            :                                     sizeof(struct spdk_nvme_fdp_ruhu_descriptor);
     605                 :          4 :         g_fdp_ruhu_log_page = realloc(g_fdp_ruhu_log_page, g_fdp_ruhu_log_page_size);
     606         [ -  + ]:          4 :         if (!g_fdp_ruhu_log_page) {
     607         [ #  # ]:          0 :                 printf("FDP RUH usage log page reallocation failed!\n");
     608                 :          0 :                 return -1;
     609                 :            :         }
     610                 :            : 
     611                 :            :         /* Fetch the reclaim unit handle usage log page */
     612         [ +  - ]:          4 :         if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_RECLAIM_UNIT_HANDLE_USAGE, 0,
     613         [ -  + ]:          4 :                         g_fdp_ruhu_log_page, g_fdp_ruhu_log_page_size, 0, 0, (nsdata->endgid << 16),
     614                 :            :                         0, get_log_page_completion, NULL) == 0) {
     615                 :          4 :                 outstanding_commands++;
     616                 :            :         } else {
     617         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(RUH usage) failed\n");
     618                 :          0 :                 free(g_fdp_ruhu_log_page);
     619                 :          0 :                 return -1;
     620                 :            :         }
     621                 :            : 
     622         [ +  + ]:         17 :         while (outstanding_commands) {
     623                 :         13 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     624                 :            :         }
     625                 :            : 
     626                 :          4 :         return 0;
     627                 :            : }
     628                 :            : 
     629                 :            : static int
     630                 :          4 : get_fdp_stats_log_page(struct spdk_nvme_ns *ns)
     631                 :            : {
     632                 :          4 :         struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns);
     633                 :          4 :         const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns);
     634                 :            : 
     635                 :          4 :         outstanding_commands = 0;
     636                 :            : 
     637         [ +  - ]:          4 :         if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_STATISTICS, 0,
     638         [ -  + ]:          4 :                         &g_fdp_stats_log_page, 64, 0, 0, (nsdata->endgid << 16), 0,
     639                 :            :                         get_log_page_completion, NULL) == 0) {
     640                 :          4 :                 outstanding_commands++;
     641                 :            :         } else {
     642         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP stats) failed\n");
     643                 :          0 :                 return -1;
     644                 :            :         }
     645                 :            : 
     646         [ +  + ]:         22 :         while (outstanding_commands) {
     647                 :         18 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     648                 :            :         }
     649                 :            : 
     650                 :          4 :         return 0;
     651                 :            : }
     652                 :            : 
     653                 :            : static int
     654                 :          4 : get_fdp_events_log_page(struct spdk_nvme_ns *ns)
     655                 :            : {
     656                 :          4 :         struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns);
     657                 :          4 :         const struct spdk_nvme_ns_data *nsdata = spdk_nvme_ns_get_data(ns);
     658                 :            : 
     659                 :          4 :         outstanding_commands = 0;
     660                 :            : 
     661                 :          4 :         g_fdp_events_log_page_size = sizeof(struct spdk_nvme_fdp_events_log_page);
     662                 :          4 :         g_fdp_events_log_page = calloc(1, g_fdp_events_log_page_size);
     663         [ -  + ]:          4 :         if (!g_fdp_events_log_page) {
     664         [ #  # ]:          0 :                 printf("FDP events log page allocation failed!\n");
     665                 :          0 :                 return -1;
     666                 :            :         }
     667                 :            : 
     668                 :            :         /* Fetch the FDP events log page header */
     669         [ +  - ]:          4 :         if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_EVENTS, 0,
     670                 :            :                         g_fdp_events_log_page, g_fdp_events_log_page_size, 0,
     671         [ -  + ]:          4 :                         (SPDK_NVME_FDP_REPORT_HOST_EVENTS << 8), (nsdata->endgid << 16),
     672                 :            :                         0, get_log_page_completion, NULL) == 0) {
     673                 :          4 :                 outstanding_commands++;
     674                 :            :         } else {
     675         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP events) failed\n");
     676                 :          0 :                 free(g_fdp_events_log_page);
     677                 :          0 :                 return -1;
     678                 :            :         }
     679                 :            : 
     680         [ +  + ]:         30 :         while (outstanding_commands) {
     681                 :         26 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     682                 :            :         }
     683                 :            : 
     684                 :          4 :         g_fdp_events_log_page_size += g_fdp_events_log_page->nevents *
     685                 :            :                                       sizeof(struct spdk_nvme_fdp_event);
     686                 :          4 :         g_fdp_events_log_page = realloc(g_fdp_events_log_page, g_fdp_events_log_page_size);
     687         [ -  + ]:          4 :         if (!g_fdp_events_log_page) {
     688         [ #  # ]:          0 :                 printf("FDP events log page reallocation failed!\n");
     689                 :          0 :                 return -1;
     690                 :            :         }
     691                 :            : 
     692                 :            :         /* Only fetch FDP events log page for host events */
     693         [ +  - ]:          4 :         if (spdk_nvme_ctrlr_cmd_get_log_page_ext(ctrlr, SPDK_NVME_LOG_FDP_EVENTS, 0,
     694                 :            :                         g_fdp_events_log_page, g_fdp_events_log_page_size, 0,
     695         [ -  + ]:          4 :                         (SPDK_NVME_FDP_REPORT_HOST_EVENTS << 8), (nsdata->endgid << 16),
     696                 :            :                         0, get_log_page_completion, NULL) == 0) {
     697                 :          4 :                 outstanding_commands++;
     698                 :            :         } else {
     699         [ #  # ]:          0 :                 printf("spdk_nvme_ctrlr_cmd_get_log_page_ext(FDP events) failed\n");
     700                 :          0 :                 free(g_fdp_events_log_page);
     701                 :          0 :                 return -1;
     702                 :            :         }
     703                 :            : 
     704         [ +  + ]:         18 :         while (outstanding_commands) {
     705                 :         14 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     706                 :            :         }
     707                 :            : 
     708                 :          4 :         return 0;
     709                 :            : }
     710                 :            : 
     711                 :            : static int
     712                 :          0 : get_ocssd_chunk_info_log_page(struct spdk_nvme_ns *ns)
     713                 :            : {
     714                 :          0 :         struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns);
     715                 :          0 :         int nsid = spdk_nvme_ns_get_id(ns);
     716                 :          0 :         uint32_t num_entry = geometry_data.num_grp * geometry_data.num_pu * geometry_data.num_chk;
     717                 :          0 :         uint32_t xfer_size = spdk_nvme_ns_get_max_io_xfer_size(ns);
     718                 :          0 :         uint32_t buf_size = 0;
     719                 :          0 :         uint64_t buf_offset = 0;
     720                 :          0 :         outstanding_commands = 0;
     721                 :            : 
     722         [ #  # ]:          0 :         assert(num_entry != 0);
     723   [ #  #  #  # ]:          0 :         if (!g_ocssd_verbose) {
     724                 :          0 :                 num_entry = spdk_min(num_entry, NUM_CHUNK_INFO_ENTRIES);
     725                 :            :         }
     726                 :            : 
     727                 :          0 :         g_ocssd_chunk_info_page = calloc(num_entry, sizeof(struct spdk_ocssd_chunk_information_entry));
     728         [ #  # ]:          0 :         assert(g_ocssd_chunk_info_page != NULL);
     729                 :            : 
     730                 :          0 :         buf_size = num_entry * sizeof(struct spdk_ocssd_chunk_information_entry);
     731         [ #  # ]:          0 :         while (buf_size > 0) {
     732                 :          0 :                 xfer_size = spdk_min(buf_size, xfer_size);
     733         [ #  # ]:          0 :                 if (spdk_nvme_ctrlr_cmd_get_log_page(ctrlr, SPDK_OCSSD_LOG_CHUNK_INFO,
     734                 :          0 :                                                      nsid, (void *) g_ocssd_chunk_info_page + buf_offset,
     735                 :            :                                                      xfer_size, buf_offset, get_log_page_completion, NULL) == 0) {
     736                 :          0 :                         outstanding_commands++;
     737                 :            :                 } else {
     738         [ #  # ]:          0 :                         printf("get_ocssd_chunk_info_log_page() failed\n");
     739                 :          0 :                         return -1;
     740                 :            :                 }
     741                 :            : 
     742                 :          0 :                 buf_size -= xfer_size;
     743                 :          0 :                 buf_offset += xfer_size;
     744                 :            :         }
     745                 :            : 
     746         [ #  # ]:          0 :         while (outstanding_commands) {
     747                 :          0 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     748                 :            :         }
     749                 :            : 
     750                 :          0 :         return 0;
     751                 :            : }
     752                 :            : 
     753                 :            : static void
     754                 :          0 : get_ocssd_geometry(struct spdk_nvme_ns *ns, struct spdk_ocssd_geometry_data *geometry_data)
     755                 :            : {
     756                 :          0 :         struct spdk_nvme_ctrlr *ctrlr = spdk_nvme_ns_get_ctrlr(ns);
     757                 :          0 :         int nsid = spdk_nvme_ns_get_id(ns);
     758                 :          0 :         outstanding_commands = 0;
     759                 :            : 
     760         [ #  # ]:          0 :         if (spdk_nvme_ocssd_ctrlr_cmd_geometry(ctrlr, nsid, geometry_data,
     761                 :            :                                                sizeof(*geometry_data), get_ocssd_geometry_completion, NULL)) {
     762         [ #  # ]:          0 :                 printf("Get OpenChannel SSD geometry failed\n");
     763                 :          0 :                 exit(1);
     764                 :            :         } else {
     765                 :          0 :                 outstanding_commands++;
     766                 :            :         }
     767                 :            : 
     768         [ #  # ]:          0 :         while (outstanding_commands) {
     769                 :          0 :                 spdk_nvme_ctrlr_process_admin_completions(ctrlr);
     770                 :            :         }
     771                 :          0 : }
     772                 :            : 
     773                 :            : static void
     774                 :         26 : print_hex_be(const void *v, size_t size)
     775                 :            : {
     776                 :         26 :         const uint8_t *buf = v;
     777                 :            : 
     778         [ +  + ]:        362 :         while (size--) {
     779         [ -  + ]:        336 :                 printf("%02X", *buf++);
     780                 :            :         }
     781                 :         26 : }
     782                 :            : 
     783                 :            : static void
     784                 :          0 : print_uint128_hex(uint64_t *v)
     785                 :            : {
     786                 :          0 :         unsigned long long lo = v[0], hi = v[1];
     787         [ #  # ]:          0 :         if (hi) {
     788         [ #  # ]:          0 :                 printf("0x%llX%016llX", hi, lo);
     789                 :            :         } else {
     790         [ #  # ]:          0 :                 printf("0x%llX", lo);
     791                 :            :         }
     792                 :          0 : }
     793                 :            : 
     794                 :            : static void
     795                 :        612 : print_uint128_dec(uint64_t *v)
     796                 :            : {
     797                 :        612 :         unsigned long long lo = v[0], hi = v[1];
     798         [ -  + ]:        612 :         if (hi) {
     799                 :            :                 /* can't handle large (>64-bit) decimal values for now, so fall back to hex */
     800                 :          0 :                 print_uint128_hex(v);
     801                 :            :         } else {
     802         [ -  + ]:        612 :                 printf("%llu", (unsigned long long)lo);
     803                 :            :         }
     804                 :        612 : }
     805                 :            : 
     806                 :            : /* The len should be <= 8. */
     807                 :            : static void
     808                 :         90 : print_uint_var_dec(uint8_t *array, unsigned int len)
     809                 :            : {
     810                 :         90 :         uint64_t result = 0;
     811                 :         90 :         int i = len;
     812                 :            : 
     813         [ +  + ]:        546 :         while (i > 0) {
     814         [ -  + ]:        456 :                 result += (uint64_t)array[i - 1] << (8 * (i - 1));
     815                 :        456 :                 i--;
     816                 :            :         }
     817         [ -  + ]:         90 :         printf("%" PRIu64, result);
     818                 :         90 : }
     819                 :            : 
     820                 :            : /* Print ASCII string as defined by the NVMe spec */
     821                 :            : static void
     822                 :        276 : print_ascii_string(const void *buf, size_t size)
     823                 :            : {
     824                 :        276 :         const uint8_t *str = buf;
     825                 :            : 
     826                 :            :         /* Trim trailing spaces */
     827   [ +  -  +  + ]:       3094 :         while (size > 0 && str[size - 1] == ' ') {
     828                 :       2818 :                 size--;
     829                 :            :         }
     830                 :            : 
     831         [ +  + ]:       2834 :         while (size--) {
     832   [ +  +  +  - ]:       2558 :                 if (*str >= 0x20 && *str <= 0x7E) {
     833                 :       2318 :                         printf("%c", *str);
     834                 :            :                 } else {
     835                 :        240 :                         printf(".");
     836                 :            :                 }
     837                 :       2558 :                 str++;
     838                 :            :         }
     839                 :        276 : }
     840                 :            : 
     841                 :            : /* Underline a "line" with the given marker, e.g. print_uline("=", printf(...)); */
     842                 :            : static void
     843                 :          0 : print_uline(char marker, int line_len)
     844                 :            : {
     845         [ #  # ]:          0 :         for (int i = 1; i < line_len; ++i) {
     846                 :          0 :                 putchar(marker);
     847                 :            :         }
     848                 :          0 :         putchar('\n');
     849                 :          0 : }
     850                 :            : 
     851                 :            : static void
     852                 :          4 : print_fdp_cfg_log_page(void)
     853                 :            : {
     854                 :            :         uint32_t i, j;
     855                 :            :         struct spdk_nvme_fdp_cfg_descriptor *cfg_desc;
     856                 :          4 :         void *log = g_fdp_cfg_log_page->cfg_desc;
     857                 :            : 
     858         [ -  + ]:          4 :         printf("FDP configurations log page\n");
     859         [ -  + ]:          4 :         printf("===========================\n");
     860   [ -  +  -  + ]:          4 :         if (g_hex_dump) {
     861                 :          0 :                 hex_dump(g_fdp_cfg_log_page, FDP_LOG_PAGE_SIZE);
     862                 :          0 :                 printf("\n");
     863                 :            :         }
     864                 :            : 
     865         [ -  + ]:          4 :         printf("Number of FDP configurations:         %u\n", g_fdp_cfg_log_page->ncfg + 1);
     866         [ -  + ]:          4 :         printf("Version:                              %u\n", g_fdp_cfg_log_page->version);
     867         [ -  + ]:          4 :         printf("Size:                                 %u\n", g_fdp_cfg_log_page->size);
     868                 :            : 
     869         [ +  + ]:          8 :         for (i = 0; i <= g_fdp_cfg_log_page->ncfg; i++) {
     870                 :          4 :                 cfg_desc = log;
     871         [ -  + ]:          4 :                 printf("FDP Configuration Descriptor:         %u\n", i);
     872         [ -  + ]:          4 :                 printf("  Descriptor Size:                    %u\n", cfg_desc->ds);
     873         [ -  + ]:          4 :                 printf("  Reclaim Group Identifier format:    %u\n", cfg_desc->fdpa.bits.rgif);
     874         [ -  + ]:          4 :                 printf("  FDP Volatile Write Cache:           %s\n",
     875         [ -  + ]:          4 :                        cfg_desc->fdpa.bits.fdpvwc ? "Present" : "Not Present");
     876         [ -  + ]:          4 :                 printf("  FDP Configuration:                  %s\n",
     877         [ +  - ]:          4 :                        cfg_desc->fdpa.bits.fdpcv ? "Valid" : "Invalid");
     878         [ -  + ]:          4 :                 printf("  Vendor Specific Size:               %u\n", cfg_desc->vss);
     879         [ -  + ]:          4 :                 printf("  Number of Reclaim Groups:           %u\n", cfg_desc->nrg);
     880         [ -  + ]:          4 :                 printf("  Number of Recalim Unit Handles:     %u\n", cfg_desc->nruh);
     881         [ -  + ]:          4 :                 printf("  Max Placement Identifiers:          %u\n", cfg_desc->maxpids + 1);
     882         [ -  + ]:          4 :                 printf("  Number of Namespaces Suppprted:     %u\n", cfg_desc->nns);
     883         [ -  + ]:          4 :                 printf("  Reclaim unit Nominal Size:          %" PRIx64 " bytes\n", cfg_desc->runs);
     884         [ -  + ]:          4 :                 printf("  Estimated Reclaim Unit Time Limit:  ");
     885         [ -  + ]:          4 :                 if (cfg_desc->erutl) {
     886         [ #  # ]:          0 :                         printf("%u seconds\n", cfg_desc->erutl);
     887                 :            :                 } else {
     888         [ -  + ]:          4 :                         printf("Not Reported\n");
     889                 :            :                 }
     890         [ +  + ]:         36 :                 for (j = 0; j < cfg_desc->nruh; j++) {
     891         [ -  + ]:         32 :                         printf("    RUH Desc #%03d:          RUH Type: %s\n", j,
     892         [ -  + ]:         32 :                                cfg_desc->ruh_desc[j].ruht == SPDK_NVME_FDP_RUHT_INITIALLY_ISOLATED ? "Initially Isolated" :
     893         [ #  # ]:          0 :                                cfg_desc->ruh_desc[j].ruht == SPDK_NVME_FDP_RUHT_PERSISTENTLY_ISOLATED ? "Persistently Isolated" :
     894                 :            :                                "Reserved");
     895                 :            :                 }
     896                 :          4 :                 log += cfg_desc->ds;
     897                 :            :         }
     898                 :            : 
     899                 :          4 :         free(g_fdp_cfg_log_page);
     900                 :          4 :         printf("\n");
     901                 :          4 : }
     902                 :            : 
     903                 :            : static void
     904                 :          4 : print_fdp_ruhu_log_page(void)
     905                 :            : {
     906                 :            :         uint32_t i;
     907                 :            :         struct spdk_nvme_fdp_ruhu_descriptor *ruhu_desc;
     908                 :            : 
     909         [ -  + ]:          4 :         printf("FDP reclaim unit handle usage log page\n");
     910         [ -  + ]:          4 :         printf("======================================\n");
     911   [ -  +  -  + ]:          4 :         if (g_hex_dump) {
     912                 :          0 :                 hex_dump(g_fdp_ruhu_log_page, FDP_LOG_PAGE_SIZE);
     913                 :          0 :                 printf("\n");
     914                 :            :         }
     915                 :            : 
     916         [ -  + ]:          4 :         printf("Number of Reclaim Unit Handles:       %u\n", g_fdp_ruhu_log_page->nruh);
     917                 :            : 
     918         [ +  + ]:         36 :         for (i = 0; i < g_fdp_ruhu_log_page->nruh; i++) {
     919                 :         32 :                 ruhu_desc = &g_fdp_ruhu_log_page->ruhu_desc[i];
     920                 :            : 
     921         [ -  + ]:         32 :                 printf("  RUH Usage Desc #%03d:   RUH Attributes: %s\n", i,
     922         [ +  + ]:         32 :                        ruhu_desc->ruha == SPDK_NVME_FDP_RUHA_UNUSED ? "Unused" :
     923         [ +  - ]:          8 :                        ruhu_desc->ruha == SPDK_NVME_FDP_RUHA_HOST_SPECIFIED ? "Host Specified" :
     924         [ +  - ]:          4 :                        ruhu_desc->ruha == SPDK_NVME_FDP_RUHA_CTRLR_SPECIFIED ? "Controller Specified" :
     925                 :            :                        "Reserved");
     926                 :            :         }
     927                 :            : 
     928                 :          4 :         free(g_fdp_ruhu_log_page);
     929                 :          4 :         printf("\n");
     930                 :          4 : }
     931                 :            : 
     932                 :            : static void
     933                 :          4 : print_fdp_stats_log_page(void)
     934                 :            : {
     935         [ -  + ]:          4 :         printf("FDP statistics log page\n");
     936         [ -  + ]:          4 :         printf("=======================\n");
     937   [ -  +  -  + ]:          4 :         if (g_hex_dump) {
     938                 :          0 :                 hex_dump(&g_fdp_stats_log_page, 64);
     939                 :          0 :                 printf("\n");
     940                 :            :         }
     941                 :            : 
     942         [ -  + ]:          4 :         printf("Host bytes with metadata written:  ");
     943                 :          4 :         print_uint128_dec(g_fdp_stats_log_page.hbmw);
     944                 :          4 :         printf("\n");
     945         [ -  + ]:          4 :         printf("Media bytes with metadata written: ");
     946                 :          4 :         print_uint128_dec(g_fdp_stats_log_page.mbmw);
     947                 :          4 :         printf("\n");
     948         [ -  + ]:          4 :         printf("Media bytes erased:                ");
     949                 :          4 :         print_uint128_dec(g_fdp_stats_log_page.mbe);
     950         [ -  + ]:          4 :         printf("\n\n");
     951                 :          4 : }
     952                 :            : 
     953                 :            : static void
     954                 :          4 : print_fdp_events_log_page(void)
     955                 :            : {
     956                 :            :         uint32_t i;
     957                 :            :         struct spdk_nvme_fdp_event *event;
     958                 :            :         struct spdk_nvme_fdp_event_media_reallocated *media_reallocated;
     959                 :            : 
     960         [ -  + ]:          4 :         printf("FDP events log page\n");
     961         [ -  + ]:          4 :         printf("===================\n");
     962   [ -  +  -  + ]:          4 :         if (g_hex_dump) {
     963                 :          0 :                 hex_dump(g_fdp_events_log_page, FDP_LOG_PAGE_SIZE);
     964                 :          0 :                 printf("\n");
     965                 :            :         }
     966                 :            : 
     967         [ -  + ]:          4 :         printf("Number of FDP events:              %u\n", g_fdp_events_log_page->nevents);
     968                 :            : 
     969         [ -  + ]:          4 :         for (i = 0; i < g_fdp_events_log_page->nevents; i++) {
     970                 :          0 :                 event = &g_fdp_events_log_page->event[i];
     971                 :            : 
     972         [ #  # ]:          0 :                 printf("FDP Event #%u:\n", i);
     973         [ #  # ]:          0 :                 printf("  Event Type:                      %s\n",
     974         [ #  # ]:          0 :                        event->etype == SPDK_NVME_FDP_EVENT_RU_NOT_WRITTEN_CAPACITY ? "RU Not Written to Capacity" :
     975         [ #  # ]:          0 :                        event->etype == SPDK_NVME_FDP_EVENT_RU_TIME_LIMIT_EXCEEDED ? "RU Time Limit Exceeded" :
     976         [ #  # ]:          0 :                        event->etype == SPDK_NVME_FDP_EVENT_CTRLR_RESET_MODIFY_RUH ? "Ctrlr Reset Modified RUH's" :
     977         [ #  # ]:          0 :                        event->etype == SPDK_NVME_FDP_EVENT_INVALID_PLACEMENT_ID ? "Invalid Placement Identifier" :
     978         [ #  # ]:          0 :                        event->etype == SPDK_NVME_FDP_EVENT_MEDIA_REALLOCATED ? "Media Reallocated" :
     979         [ #  # ]:          0 :                        event->etype == SPDK_NVME_FDP_EVENT_IMPLICIT_MODIFIED_RUH ? "Implicitly modified RUH" :
     980                 :            :                        "Reserved");
     981         [ #  # ]:          0 :                 printf("  Placement Identifier:            %s\n",
     982         [ #  # ]:          0 :                        event->fdpef.bits.piv ? "Valid" : "Invalid");
     983         [ #  # ]:          0 :                 printf("  NSID:                            %s\n",
     984         [ #  # ]:          0 :                        event->fdpef.bits.nsidv ? "Valid" : "Invalid");
     985         [ #  # ]:          0 :                 printf("  Location:                        %s\n",
     986         [ #  # ]:          0 :                        event->fdpef.bits.lv ? "Valid" : "Invalid");
     987         [ #  # ]:          0 :                 if (event->fdpef.bits.piv) {
     988         [ #  # ]:          0 :                         printf("  Placement Identifier:            %u\n", event->pid);
     989                 :            :                 } else {
     990         [ #  # ]:          0 :                         printf("  Placement Identifier:            Reserved\n");
     991                 :            :                 }
     992         [ #  # ]:          0 :                 printf("  Event Timestamp:                 %" PRIx64 "\n", event->timestamp);
     993         [ #  # ]:          0 :                 if (event->fdpef.bits.nsidv) {
     994         [ #  # ]:          0 :                         printf("  Namespace Identifier:            %u\n", event->nsid);
     995                 :            :                 } else {
     996         [ #  # ]:          0 :                         printf("  Namespace Identifier:            Ignore\n");
     997                 :            :                 }
     998                 :            : 
     999         [ #  # ]:          0 :                 if (event->etype == SPDK_NVME_FDP_EVENT_MEDIA_REALLOCATED) {
    1000                 :          0 :                         media_reallocated = (struct spdk_nvme_fdp_event_media_reallocated *)&event->event_type_specific;
    1001                 :            : 
    1002         [ #  # ]:          0 :                         printf("  LBA:                             %s\n",
    1003         [ #  # ]:          0 :                                media_reallocated->sef.bits.lbav ? "Valid" : "Invalid");
    1004         [ #  # ]:          0 :                         printf("  Number of LBA's Moved:           %u\n", media_reallocated->nlbam);
    1005         [ #  # ]:          0 :                         if (media_reallocated->sef.bits.lbav) {
    1006         [ #  # ]:          0 :                                 printf("  Logical Block Address:           %u\n", event->nsid);
    1007                 :            :                         } else {
    1008         [ #  # ]:          0 :                                 printf("  Logical Block Address:           Ignore\n");
    1009                 :            :                         }
    1010                 :            :                 }
    1011                 :            : 
    1012         [ #  # ]:          0 :                 if (event->fdpef.bits.lv) {
    1013         [ #  # ]:          0 :                         printf("  Reclaim Group Identifier:        %u\n", event->rgid);
    1014                 :            :                 } else {
    1015         [ #  # ]:          0 :                         printf("  Reclaim Group Identifier:        Ignore\n");
    1016                 :            :                 }
    1017         [ #  # ]:          0 :                 if (event->fdpef.bits.lv) {
    1018         [ #  # ]:          0 :                         printf("  Reclaim Unit Handle Identifier:  %u\n", event->ruhid);
    1019                 :            :                 } else {
    1020         [ #  # ]:          0 :                         printf("  Reclaim Unit Handle Identifier:  Ignore\n");
    1021                 :            :                 }
    1022                 :            :         }
    1023                 :            : 
    1024                 :          4 :         free(g_fdp_events_log_page);
    1025                 :          4 :         printf("\n");
    1026                 :          4 : }
    1027                 :            : 
    1028                 :            : static void
    1029                 :          0 : print_ocssd_chunk_info(struct spdk_ocssd_chunk_information_entry *chk_info, int chk_num)
    1030                 :            : {
    1031                 :            :         int i;
    1032                 :            :         char *cs_str, *ct_str;
    1033                 :            : 
    1034         [ #  # ]:          0 :         printf("OCSSD Chunk Info Glance\n");
    1035         [ #  # ]:          0 :         printf("======================\n");
    1036                 :            : 
    1037         [ #  # ]:          0 :         for (i = 0; i < chk_num; i++) {
    1038         [ #  # ]:          0 :                 cs_str = chk_info[i].cs.free ? "Free" :
    1039         [ #  # ]:          0 :                          chk_info[i].cs.closed ? "Closed" :
    1040         [ #  # ]:          0 :                          chk_info[i].cs.open ? "Open" :
    1041         [ #  # ]:          0 :                          chk_info[i].cs.offline ? "Offline" : "Unknown";
    1042         [ #  # ]:          0 :                 ct_str = chk_info[i].ct.seq_write ? "Sequential Write" :
    1043         [ #  # ]:          0 :                          chk_info[i].ct.rnd_write ? "Random Write" : "Unknown";
    1044                 :            : 
    1045         [ #  # ]:          0 :                 printf("------------\n");
    1046         [ #  # ]:          0 :                 printf("Chunk index:                    %d\n", i);
    1047         [ #  # ]:          0 :                 printf("Chunk state:                    %s(0x%x)\n", cs_str, *(uint8_t *) & (chk_info[i].cs));
    1048         [ #  # ]:          0 :                 printf("Chunk type (write mode):        %s\n", ct_str);
    1049   [ #  #  #  # ]:          0 :                 printf("Chunk type (size_deviate):      %s\n", chk_info[i].ct.size_deviate ? "Yes" : "No");
    1050         [ #  # ]:          0 :                 printf("Wear-level Index:               %d\n", chk_info[i].wli);
    1051         [ #  # ]:          0 :                 printf("Starting LBA:                   %" PRIu64 "\n", chk_info[i].slba);
    1052         [ #  # ]:          0 :                 printf("Number of blocks in chunk:      %" PRIu64 "\n", chk_info[i].cnlb);
    1053         [ #  # ]:          0 :                 printf("Write Pointer:                  %" PRIu64 "\n", chk_info[i].wp);
    1054                 :            :         }
    1055                 :          0 : }
    1056                 :            : 
    1057                 :            : static void
    1058                 :          0 : print_ocssd_chunk_info_verbose(struct spdk_ocssd_chunk_information_entry *chk_info)
    1059                 :            : {
    1060                 :            :         uint32_t pu, chk, i;
    1061                 :            :         uint32_t cnt_free, cnt_closed, cnt_open, cnt_offline;
    1062                 :          0 :         uint32_t max_pu = spdk_min(MAX_OCSSD_PU, (geometry_data.num_grp * geometry_data.num_pu));
    1063                 :          0 :         char cs_str[MAX_OCSSD_PU + 1], cs;
    1064                 :            : 
    1065         [ #  # ]:          0 :         assert(chk_info != NULL);
    1066         [ #  # ]:          0 :         printf("OCSSD Chunk Info Verbose\n");
    1067         [ #  # ]:          0 :         printf("======================\n");
    1068                 :            : 
    1069         [ #  # ]:          0 :         printf("%4s %-*s %3s %3s %3s %3s\n", "band", max_pu, "chunk state", "fr", "cl", "op", "of");
    1070         [ #  # ]:          0 :         for (chk = 0; chk < geometry_data.num_chk; chk++) {
    1071                 :          0 :                 cnt_free = cnt_closed = cnt_open = cnt_offline = 0;
    1072         [ #  # ]:          0 :                 for (pu = 0; pu < max_pu; pu++) {
    1073                 :          0 :                         i = (pu * geometry_data.num_chk) + chk;
    1074         [ #  # ]:          0 :                         if (chk_info[i].cs.free) {
    1075                 :          0 :                                 cnt_free++;
    1076                 :          0 :                                 cs = 'f';
    1077         [ #  # ]:          0 :                         } else if (chk_info[i].cs.closed) {
    1078                 :          0 :                                 cnt_closed++;
    1079                 :          0 :                                 cs = 'c';
    1080         [ #  # ]:          0 :                         } else if (chk_info[i].cs.open) {
    1081                 :          0 :                                 cnt_open++;
    1082                 :          0 :                                 cs = 'o';
    1083         [ #  # ]:          0 :                         } else if (chk_info[i].cs.offline) {
    1084                 :          0 :                                 cnt_offline++;
    1085                 :          0 :                                 cs = 'l';
    1086                 :            :                         } else {
    1087                 :          0 :                                 cs = '.';
    1088                 :            :                         }
    1089                 :          0 :                         cs_str[pu] = cs;
    1090                 :            :                 }
    1091                 :          0 :                 cs_str[pu] = 0;
    1092         [ #  # ]:          0 :                 printf("%4d %s %3d %3d %3d %3d\n", chk, cs_str, cnt_free, cnt_closed, cnt_open, cnt_offline);
    1093                 :            :         }
    1094                 :          0 : }
    1095                 :            : 
    1096                 :            : static void
    1097                 :          0 : print_ocssd_geometry(struct spdk_ocssd_geometry_data *geometry_data)
    1098                 :            : {
    1099         [ #  # ]:          0 :         printf("Namespace OCSSD Geometry\n");
    1100         [ #  # ]:          0 :         printf("=======================\n");
    1101                 :            : 
    1102         [ #  # ]:          0 :         if (geometry_data->mjr < 2) {
    1103         [ #  # ]:          0 :                 printf("Open-Channel Spec version is less than 2.0\n");
    1104         [ #  # ]:          0 :                 printf("OC version:             maj:%d\n", geometry_data->mjr);
    1105                 :          0 :                 return;
    1106                 :            :         }
    1107                 :            : 
    1108         [ #  # ]:          0 :         printf("OC version:                     maj:%d min:%d\n", geometry_data->mjr, geometry_data->mnr);
    1109         [ #  # ]:          0 :         printf("LBA format:\n");
    1110         [ #  # ]:          0 :         printf("  Group bits:                   %d\n", geometry_data->lbaf.grp_len);
    1111         [ #  # ]:          0 :         printf("  PU bits:                      %d\n", geometry_data->lbaf.pu_len);
    1112         [ #  # ]:          0 :         printf("  Chunk bits:                   %d\n", geometry_data->lbaf.chk_len);
    1113         [ #  # ]:          0 :         printf("  Logical block bits:           %d\n", geometry_data->lbaf.lbk_len);
    1114                 :            : 
    1115         [ #  # ]:          0 :         printf("Media and Controller Capabilities:\n");
    1116         [ #  # ]:          0 :         printf("  Namespace supports Vector Chunk Copy:                 %s\n",
    1117         [ #  # ]:          0 :                geometry_data->mccap.vec_chk_cpy ? "Supported" : "Not Supported");
    1118         [ #  # ]:          0 :         printf("  Namespace supports multiple resets a free chunk:      %s\n",
    1119         [ #  # ]:          0 :                geometry_data->mccap.multi_reset ? "Supported" : "Not Supported");
    1120                 :            : 
    1121         [ #  # ]:          0 :         printf("Wear-level Index Delta Threshold:                       %d\n", geometry_data->wit);
    1122         [ #  # ]:          0 :         printf("Groups (channels):              %d\n", geometry_data->num_grp);
    1123         [ #  # ]:          0 :         printf("PUs (LUNs) per group:           %d\n", geometry_data->num_pu);
    1124         [ #  # ]:          0 :         printf("Chunks per LUN:                 %d\n", geometry_data->num_chk);
    1125         [ #  # ]:          0 :         printf("Logical blks per chunk:         %d\n", geometry_data->clba);
    1126         [ #  # ]:          0 :         printf("MIN write size:                 %d\n", geometry_data->ws_min);
    1127         [ #  # ]:          0 :         printf("OPT write size:                 %d\n", geometry_data->ws_opt);
    1128         [ #  # ]:          0 :         printf("Cache min write size:           %d\n", geometry_data->mw_cunits);
    1129         [ #  # ]:          0 :         printf("Max open chunks:                %d\n", geometry_data->maxoc);
    1130         [ #  # ]:          0 :         printf("Max open chunks per PU:         %d\n", geometry_data->maxocpu);
    1131                 :          0 :         printf("\n");
    1132                 :            : }
    1133                 :            : 
    1134                 :            : static void
    1135                 :          0 : print_zns_zone(uint8_t *report, uint32_t index, uint32_t zdes)
    1136                 :            : {
    1137                 :            :         struct spdk_nvme_zns_zone_desc *desc;
    1138                 :            :         uint32_t i, zds, zrs, zd_index;
    1139                 :            : 
    1140                 :          0 :         zrs = sizeof(struct spdk_nvme_zns_zone_report);
    1141                 :          0 :         zds = sizeof(struct spdk_nvme_zns_zone_desc);
    1142                 :          0 :         zd_index = zrs + index * (zds + zdes);
    1143                 :            : 
    1144                 :          0 :         desc = (struct spdk_nvme_zns_zone_desc *)(report + zd_index);
    1145                 :            : 
    1146         [ #  # ]:          0 :         printf("ZSLBA: 0x%016"PRIx64" ZCAP: 0x%016"PRIx64" WP: 0x%016"PRIx64" ZS: ", desc->zslba,
    1147                 :            :                desc->zcap, desc->wp);
    1148   [ #  #  #  #  :          0 :         switch (desc->zs) {
             #  #  #  # ]
    1149                 :          0 :         case SPDK_NVME_ZONE_STATE_EMPTY:
    1150         [ #  # ]:          0 :                 printf("Empty");
    1151                 :          0 :                 break;
    1152                 :          0 :         case SPDK_NVME_ZONE_STATE_IOPEN:
    1153         [ #  # ]:          0 :                 printf("Implicit open");
    1154                 :          0 :                 break;
    1155                 :          0 :         case SPDK_NVME_ZONE_STATE_EOPEN:
    1156         [ #  # ]:          0 :                 printf("Explicit open");
    1157                 :          0 :                 break;
    1158                 :          0 :         case SPDK_NVME_ZONE_STATE_CLOSED:
    1159         [ #  # ]:          0 :                 printf("Closed");
    1160                 :          0 :                 break;
    1161                 :          0 :         case SPDK_NVME_ZONE_STATE_RONLY:
    1162         [ #  # ]:          0 :                 printf("Read only");
    1163                 :          0 :                 break;
    1164                 :          0 :         case SPDK_NVME_ZONE_STATE_FULL:
    1165         [ #  # ]:          0 :                 printf("Full");
    1166                 :          0 :                 break;
    1167                 :          0 :         case SPDK_NVME_ZONE_STATE_OFFLINE:
    1168         [ #  # ]:          0 :                 printf("Offline");
    1169                 :          0 :                 break;
    1170                 :          0 :         default:
    1171         [ #  # ]:          0 :                 printf("Reserved");
    1172                 :            :         }
    1173   [ #  #  #  # ]:          0 :         printf(" ZT: %s ZA: %x\n", (desc->zt == SPDK_NVME_ZONE_TYPE_SEQWR) ? "SWR" : "Reserved",
    1174         [ #  # ]:          0 :                desc->za.raw);
    1175                 :            : 
    1176         [ #  # ]:          0 :         if (!desc->za.bits.zdev) {
    1177                 :          0 :                 return;
    1178                 :            :         }
    1179                 :            : 
    1180         [ #  # ]:          0 :         for (i = 0; i < zdes; i += 8) {
    1181         [ #  # ]:          0 :                 printf("zone_desc_ext[%d] : 0x%"PRIx64"\n", i,
    1182                 :          0 :                        *(uint64_t *)(report + zd_index + zds + i));
    1183                 :            :         }
    1184                 :            : }
    1185                 :            : 
    1186                 :            : static void
    1187                 :          0 : get_and_print_zns_zone_report(struct spdk_nvme_ns *ns, struct spdk_nvme_qpair *qpair)
    1188                 :            : {
    1189                 :            :         const struct spdk_nvme_ns_data *nsdata;
    1190                 :            :         const struct spdk_nvme_zns_ns_data *nsdata_zns;
    1191                 :            :         uint8_t *report_buf;
    1192                 :            :         size_t report_bufsize;
    1193                 :          0 :         uint64_t zone_size_lba = spdk_nvme_zns_ns_get_zone_size_sectors(ns);
    1194                 :          0 :         uint64_t total_zones = spdk_nvme_zns_ns_get_num_zones(ns);
    1195                 :            :         uint64_t max_zones_per_buf, zones_to_print, i;
    1196                 :          0 :         uint64_t nr_zones = 0;
    1197                 :          0 :         uint64_t handled_zones = 0;
    1198                 :          0 :         uint64_t slba = 0;
    1199                 :          0 :         size_t zdes = 0;
    1200                 :            :         uint32_t zds, zrs, format_index;
    1201                 :          0 :         int rc = 0;
    1202                 :            : 
    1203                 :          0 :         outstanding_commands = 0;
    1204                 :            : 
    1205                 :          0 :         nsdata = spdk_nvme_ns_get_data(ns);
    1206                 :          0 :         nsdata_zns = spdk_nvme_zns_ns_get_data(ns);
    1207                 :            : 
    1208                 :          0 :         zrs = sizeof(struct spdk_nvme_zns_zone_report);
    1209                 :          0 :         zds = sizeof(struct spdk_nvme_zns_zone_desc);
    1210                 :            : 
    1211                 :          0 :         format_index = spdk_nvme_ns_get_format_index(nsdata);
    1212                 :          0 :         zdes = nsdata_zns->lbafe[format_index].zdes * 64;
    1213         [ #  # ]:          0 :         zones_to_print = g_zone_report_limit ? spdk_min(total_zones, (uint64_t)g_zone_report_limit) : \
    1214                 :            :                          total_zones;
    1215                 :            : 
    1216         [ #  # ]:          0 :         report_bufsize = spdk_min(zrs + zones_to_print * (zds + zdes),
    1217                 :            :                                   spdk_nvme_ns_get_max_io_xfer_size(ns));
    1218                 :          0 :         report_buf = calloc(1, report_bufsize);
    1219         [ #  # ]:          0 :         if (!report_buf) {
    1220         [ #  # ]:          0 :                 printf("Zone report allocation failed!\n");
    1221                 :          0 :                 exit(1);
    1222                 :            :         }
    1223                 :            : 
    1224         [ #  # ]:          0 :         print_uline('=', printf("NVMe ZNS Zone Report (first %zu of %zu)\n", zones_to_print, total_zones));
    1225                 :            : 
    1226         [ #  # ]:          0 :         while (handled_zones < zones_to_print) {
    1227         [ #  # ]:          0 :                 memset(report_buf, 0, report_bufsize);
    1228                 :            : 
    1229         [ #  # ]:          0 :                 if (zdes) {
    1230         [ #  # ]:          0 :                         max_zones_per_buf = (report_bufsize - zrs) / (zds + zdes);
    1231                 :          0 :                         rc = spdk_nvme_zns_ext_report_zones(ns, qpair, report_buf, report_bufsize,
    1232                 :            :                                                             slba, SPDK_NVME_ZRA_LIST_ALL, true,
    1233                 :            :                                                             get_zns_zone_report_completion, NULL);
    1234                 :            :                 } else {
    1235         [ #  # ]:          0 :                         max_zones_per_buf = (report_bufsize - zrs) / zds;
    1236                 :          0 :                         rc = spdk_nvme_zns_report_zones(ns, qpair, report_buf, report_bufsize,
    1237                 :            :                                                         slba, SPDK_NVME_ZRA_LIST_ALL, true,
    1238                 :            :                                                         get_zns_zone_report_completion, NULL);
    1239                 :            :                 }
    1240                 :            : 
    1241         [ #  # ]:          0 :                 if (rc) {
    1242   [ #  #  #  # ]:          0 :                         fprintf(stderr, "Report zones failed\n");
    1243                 :          0 :                         exit(1);
    1244                 :            :                 } else {
    1245                 :          0 :                         outstanding_commands++;
    1246                 :            :                 }
    1247                 :            : 
    1248         [ #  # ]:          0 :                 while (outstanding_commands) {
    1249                 :          0 :                         spdk_nvme_qpair_process_completions(qpair, 0);
    1250                 :            :                 }
    1251                 :            : 
    1252                 :          0 :                 nr_zones = report_buf[0];
    1253         [ #  # ]:          0 :                 if (nr_zones > max_zones_per_buf) {
    1254   [ #  #  #  # ]:          0 :                         fprintf(stderr, "nr_zones too big\n");
    1255                 :          0 :                         exit(1);
    1256                 :            :                 }
    1257                 :            : 
    1258         [ #  # ]:          0 :                 if (!nr_zones) {
    1259                 :          0 :                         break;
    1260                 :            :                 }
    1261                 :            : 
    1262   [ #  #  #  # ]:          0 :                 for (i = 0; i < nr_zones && handled_zones < zones_to_print; i++) {
    1263                 :          0 :                         print_zns_zone(report_buf, i, zdes);
    1264                 :          0 :                         slba += zone_size_lba;
    1265                 :          0 :                         handled_zones++;
    1266                 :            :                 }
    1267                 :          0 :                 printf("\n");
    1268                 :            :         }
    1269                 :            : 
    1270                 :          0 :         free(report_buf);
    1271                 :          0 : }
    1272                 :            : 
    1273                 :            : static void
    1274                 :          0 : print_zns_ns_data(const struct spdk_nvme_zns_ns_data *nsdata_zns)
    1275                 :            : {
    1276         [ #  # ]:          0 :         printf("ZNS Specific Namespace Data\n");
    1277         [ #  # ]:          0 :         printf("===========================\n");
    1278         [ #  # ]:          0 :         printf("Variable Zone Capacity:                %s\n",
    1279         [ #  # ]:          0 :                nsdata_zns->zoc.variable_zone_capacity ? "Yes" : "No");
    1280         [ #  # ]:          0 :         printf("Zone Active Excursions:                %s\n",
    1281         [ #  # ]:          0 :                nsdata_zns->zoc.zone_active_excursions ? "Yes" : "No");
    1282         [ #  # ]:          0 :         printf("Read Across Zone Boundaries:           %s\n",
    1283         [ #  # ]:          0 :                nsdata_zns->ozcs.read_across_zone_boundaries ? "Yes" : "No");
    1284         [ #  # ]:          0 :         if (nsdata_zns->mar == 0xffffffff) {
    1285         [ #  # ]:          0 :                 printf("Max Active Resources:                  No Limit\n");
    1286                 :            :         } else {
    1287                 :          0 :                 printf("Max Active Resources:                  %"PRIu32"\n",
    1288         [ #  # ]:          0 :                        nsdata_zns->mar + 1);
    1289                 :            :         }
    1290         [ #  # ]:          0 :         if (nsdata_zns->mor == 0xffffffff) {
    1291         [ #  # ]:          0 :                 printf("Max Open Resources:                    No Limit\n");
    1292                 :            :         } else {
    1293                 :          0 :                 printf("Max Open Resources:                    %"PRIu32"\n",
    1294         [ #  # ]:          0 :                        nsdata_zns->mor + 1);
    1295                 :            :         }
    1296         [ #  # ]:          0 :         if (nsdata_zns->rrl == 0) {
    1297         [ #  # ]:          0 :                 printf("Reset Recommended Limit:               Not Reported\n");
    1298                 :            :         } else {
    1299         [ #  # ]:          0 :                 printf("Reset Recommended Limit:               %"PRIu32" seconds\n",
    1300         [ #  # ]:          0 :                        nsdata_zns->rrl);
    1301                 :            :         }
    1302         [ #  # ]:          0 :         if (nsdata_zns->rrl1 == 0) {
    1303         [ #  # ]:          0 :                 printf("Reset Recommended Limit 1:             Not Reported\n");
    1304                 :            :         } else {
    1305         [ #  # ]:          0 :                 printf("Reset Recommended Limit 1:             %"PRIu32" seconds\n",
    1306         [ #  # ]:          0 :                        nsdata_zns->rrl1);
    1307                 :            :         }
    1308         [ #  # ]:          0 :         if (nsdata_zns->rrl2 == 0) {
    1309         [ #  # ]:          0 :                 printf("Reset Recommended Limit 2:             Not Reported\n");
    1310                 :            :         } else {
    1311         [ #  # ]:          0 :                 printf("Reset Recommended Limit 2:             %"PRIu32" seconds\n",
    1312         [ #  # ]:          0 :                        nsdata_zns->rrl2);
    1313                 :            :         }
    1314         [ #  # ]:          0 :         if (nsdata_zns->rrl3 == 0) {
    1315         [ #  # ]:          0 :                 printf("Reset Recommended Limit 3:             Not Reported\n");
    1316                 :            :         } else {
    1317         [ #  # ]:          0 :                 printf("Reset Recommended Limit 3:             %"PRIu32" seconds\n",
    1318         [ #  # ]:          0 :                        nsdata_zns->rrl3);
    1319                 :            :         }
    1320         [ #  # ]:          0 :         if (nsdata_zns->frl == 0) {
    1321         [ #  # ]:          0 :                 printf("Finish Recommended Limit:              Not Reported\n");
    1322                 :            :         } else {
    1323         [ #  # ]:          0 :                 printf("Finish Recommended Limit:              %"PRIu32" seconds\n",
    1324         [ #  # ]:          0 :                        nsdata_zns->frl);
    1325                 :            :         }
    1326         [ #  # ]:          0 :         if (nsdata_zns->frl1 == 0) {
    1327         [ #  # ]:          0 :                 printf("Finish Recommended Limit 1:            Not Reported\n");
    1328                 :            :         } else {
    1329         [ #  # ]:          0 :                 printf("Finish Recommended Limit 1:            %"PRIu32" seconds\n",
    1330         [ #  # ]:          0 :                        nsdata_zns->frl1);
    1331                 :            :         }
    1332         [ #  # ]:          0 :         if (nsdata_zns->frl2 == 0) {
    1333         [ #  # ]:          0 :                 printf("Finish Recommended Limit 2:            Not Reported\n");
    1334                 :            :         } else {
    1335         [ #  # ]:          0 :                 printf("Finish Recommended Limit 2:            %"PRIu32" seconds\n",
    1336         [ #  # ]:          0 :                        nsdata_zns->frl2);
    1337                 :            :         }
    1338         [ #  # ]:          0 :         if (nsdata_zns->frl3 == 0) {
    1339         [ #  # ]:          0 :                 printf("Finish Recommended Limit 3:            Not Reported\n");
    1340                 :            :         } else {
    1341         [ #  # ]:          0 :                 printf("Finish Recommended Limit 3:            %"PRIu32" seconds\n",
    1342         [ #  # ]:          0 :                        nsdata_zns->frl3);
    1343                 :            :         }
    1344                 :          0 :         printf("\n");
    1345                 :          0 : }
    1346                 :            : 
    1347                 :            : static const char *
    1348                 :        416 : pi_format_string(uint32_t pif)
    1349                 :            : {
    1350   [ +  -  -  -  :        416 :         switch (pif) {
                      - ]
    1351                 :        416 :         case 0:
    1352                 :        416 :                 return "16b Guard PI";
    1353                 :          0 :         case 1:
    1354                 :          0 :                 return "32b Guard PI";
    1355                 :          0 :         case 2:
    1356                 :          0 :                 return "64b Guard PI";
    1357                 :          0 :         case 3:
    1358                 :          0 :                 return "Reserved";
    1359                 :          0 :         default:
    1360                 :          0 :                 return "Unknown";
    1361                 :            :         }
    1362                 :            : }
    1363                 :            : 
    1364                 :            : static void
    1365                 :         52 : print_nvm_ns_data(const struct spdk_nvme_nvm_ns_data *nsdata_nvm,
    1366                 :            :                   const struct spdk_nvme_ns_data *nsdata)
    1367                 :            : {
    1368                 :            :         uint32_t i;
    1369                 :            : 
    1370         [ -  + ]:         52 :         printf("NVM Specific Namespace Data\n");
    1371         [ -  + ]:         52 :         printf("===========================\n");
    1372         [ -  + ]:         52 :         printf("Logical Block Storage Tag Mask:               %"PRIx64"\n", nsdata_nvm->lbstm);
    1373         [ -  + ]:         52 :         printf("Protection Information Capabilities:\n");
    1374         [ -  + ]:         52 :         printf("  16b Guard Protection Information Storage Tag Support:  %s\n",
    1375         [ -  + ]:         52 :                nsdata_nvm->pic._16bpists != 0 ? "Yes" : "No");
    1376         [ -  + ]:         52 :         printf("  16b Guard Protection Information Storage Tag Mask:     %s\n",
    1377         [ -  + ]:         52 :                nsdata_nvm->pic._16bpistm != 0 ? "LBSTM must be all 1s" : "Any bit in LBSTM can be 0");
    1378         [ -  + ]:         52 :         printf("  Storage Tag Check Read Support:                        %s\n",
    1379         [ -  + ]:         52 :                nsdata_nvm->pic.stcrs != 0 ? "Yes" : "No");
    1380                 :            : 
    1381         [ +  + ]:        468 :         for (i = 0; i <= nsdata->nlbaf; i++) {
    1382                 :        528 :                 printf("Extended LBA Format #%02d: Storage Tag Size: %-2d, Protection Information Format: %s\n",
    1383         [ -  + ]:        416 :                        i, nsdata_nvm->elbaf[i].sts, pi_format_string(nsdata_nvm->elbaf[i].pif));
    1384                 :            :         }
    1385                 :         52 : }
    1386                 :            : 
    1387                 :            : static const char *
    1388                 :         72 : csi_name(enum spdk_nvme_csi csi)
    1389                 :            : {
    1390   [ +  -  -  - ]:         72 :         switch (csi) {
    1391                 :         72 :         case SPDK_NVME_CSI_NVM:
    1392                 :         72 :                 return "NVM";
    1393                 :          0 :         case SPDK_NVME_CSI_KV:
    1394                 :          0 :                 return "KV";
    1395                 :          0 :         case SPDK_NVME_CSI_ZNS:
    1396                 :          0 :                 return "ZNS";
    1397                 :          0 :         default:
    1398   [ #  #  #  # ]:          0 :                 if (csi >= 0x30 && csi <= 0x3f) {
    1399                 :          0 :                         return "Vendor specific";
    1400                 :            :                 }
    1401                 :          0 :                 return "Unknown";
    1402                 :            :         }
    1403                 :            : }
    1404                 :            : 
    1405                 :            : static void
    1406                 :         72 : print_namespace(struct spdk_nvme_ctrlr *ctrlr, struct spdk_nvme_ns *ns)
    1407                 :            : {
    1408                 :            :         const struct spdk_nvme_ctrlr_data       *cdata;
    1409                 :            :         const struct spdk_nvme_ns_data          *nsdata;
    1410                 :            :         const struct spdk_nvme_zns_ns_data      *nsdata_zns;
    1411                 :            :         const struct spdk_nvme_nvm_ns_data      *nsdata_nvm;
    1412                 :            :         const struct spdk_uuid                  *uuid;
    1413                 :            :         uint32_t                                i;
    1414                 :            :         uint32_t                                flags;
    1415                 :         36 :         char                                    uuid_str[SPDK_UUID_STRING_LEN];
    1416                 :            :         uint32_t                                blocksize, format_index;
    1417                 :            :         enum spdk_nvme_dealloc_logical_block_read_value dlfeat_read_value;
    1418                 :            : 
    1419                 :         72 :         cdata = spdk_nvme_ctrlr_get_data(ctrlr);
    1420                 :         72 :         nsdata = spdk_nvme_ns_get_data(ns);
    1421                 :         72 :         nsdata_zns = spdk_nvme_zns_ns_get_data(ns);
    1422                 :         72 :         nsdata_nvm = spdk_nvme_nvm_ns_get_data(ns);
    1423                 :         72 :         flags  = spdk_nvme_ns_get_flags(ns);
    1424                 :            : 
    1425         [ -  + ]:         72 :         printf("Namespace ID:%d\n", spdk_nvme_ns_get_id(ns));
    1426                 :            : 
    1427   [ -  +  -  + ]:         72 :         if (g_hex_dump) {
    1428                 :          0 :                 hex_dump(nsdata, sizeof(*nsdata));
    1429                 :          0 :                 printf("\n");
    1430                 :            :         }
    1431                 :            : 
    1432                 :            :         /* This function is only called for active namespaces. */
    1433         [ -  + ]:         72 :         assert(spdk_nvme_ns_is_active(ns));
    1434                 :            : 
    1435   [ +  +  +  + ]:         72 :         if (features[SPDK_NVME_FEAT_ERROR_RECOVERY].valid) {
    1436                 :         68 :                 unsigned tler = features[SPDK_NVME_FEAT_ERROR_RECOVERY].result & 0xFFFF;
    1437         [ -  + ]:         68 :                 printf("Error Recovery Timeout:                ");
    1438         [ +  - ]:         68 :                 if (tler == 0) {
    1439         [ -  + ]:         68 :                         printf("Unlimited\n");
    1440                 :            :                 } else {
    1441         [ #  # ]:          0 :                         printf("%u milliseconds\n", tler * 100);
    1442                 :            :                 }
    1443                 :            :         }
    1444                 :            : 
    1445         [ -  + ]:         72 :         printf("Command Set Identifier:                %s (%02Xh)\n",
    1446                 :         72 :                csi_name(spdk_nvme_ns_get_csi(ns)), spdk_nvme_ns_get_csi(ns));
    1447         [ -  + ]:         72 :         printf("Deallocate:                            %s\n",
    1448         [ +  - ]:         72 :                (flags & SPDK_NVME_NS_DEALLOCATE_SUPPORTED) ? "Supported" : "Not Supported");
    1449         [ -  + ]:         72 :         printf("Deallocated/Unwritten Error:           %s\n",
    1450         [ +  + ]:         72 :                nsdata->nsfeat.dealloc_or_unwritten_error ? "Supported" : "Not Supported");
    1451                 :         72 :         dlfeat_read_value = spdk_nvme_ns_get_dealloc_logical_block_read_value(ns);
    1452   [ +  +  -  + ]:         86 :         printf("Deallocated Read Value:                %s\n",
    1453                 :            :                dlfeat_read_value == SPDK_NVME_DEALLOC_READ_00 ? "All 0x00" :
    1454         [ -  + ]:         14 :                dlfeat_read_value == SPDK_NVME_DEALLOC_READ_FF ? "All 0xFF" :
    1455                 :            :                "Unknown");
    1456         [ -  + ]:         72 :         printf("Deallocate in Write Zeroes:            %s\n",
    1457         [ -  + ]:         72 :                nsdata->dlfeat.bits.write_zero_deallocate ? "Supported" : "Not Supported");
    1458         [ -  + ]:         72 :         printf("Deallocated Guard Field:               %s\n",
    1459         [ -  + ]:         72 :                nsdata->dlfeat.bits.guard_value ? "CRC for Read Value" : "0xFFFF");
    1460         [ -  + ]:         72 :         printf("Flush:                                 %s\n",
    1461         [ +  + ]:         72 :                (flags & SPDK_NVME_NS_FLUSH_SUPPORTED) ? "Supported" : "Not Supported");
    1462         [ -  + ]:         72 :         printf("Reservation:                           %s\n",
    1463         [ +  + ]:         72 :                (flags & SPDK_NVME_NS_RESERVATION_SUPPORTED) ? "Supported" : "Not Supported");
    1464         [ -  + ]:         72 :         if (flags & SPDK_NVME_NS_DPS_PI_SUPPORTED) {
    1465         [ #  # ]:          0 :                 printf("End-to-End Data Protection:            Supported\n");
    1466         [ #  # ]:          0 :                 printf("Protection Type:                       Type%d\n", nsdata->dps.pit);
    1467         [ #  # ]:          0 :                 printf("Protection Information Transferred as: %s\n",
    1468         [ #  # ]:          0 :                        nsdata->dps.md_start ? "First 8/16 Bytes" : "Last 8/16 Bytes");
    1469                 :            :         }
    1470                 :         72 :         format_index = spdk_nvme_ns_get_format_index(nsdata);
    1471         [ +  + ]:         72 :         if (nsdata->lbaf[format_index].ms > 0) {
    1472         [ -  + ]:          4 :                 printf("Metadata Transferred as:               %s\n",
    1473         [ -  + ]:          4 :                        nsdata->flbas.extended ? "Extended Data LBA" : "Separate Metadata Buffer");
    1474                 :            :         }
    1475         [ -  + ]:         72 :         printf("Namespace Sharing Capabilities:        %s\n",
    1476         [ +  + ]:         72 :                nsdata->nmic.can_share ? "Multiple Controllers" : "Private");
    1477         [ -  + ]:         72 :         blocksize = 1 << nsdata->lbaf[format_index].lbads;
    1478                 :         72 :         printf("Size (in LBAs):                        %lld (%lldGiB)\n",
    1479         [ -  + ]:         72 :                (long long)nsdata->nsze,
    1480                 :         72 :                (long long)nsdata->nsze * blocksize / 1024 / 1024 / 1024);
    1481                 :         72 :         printf("Capacity (in LBAs):                    %lld (%lldGiB)\n",
    1482         [ -  + ]:         72 :                (long long)nsdata->ncap,
    1483                 :         72 :                (long long)nsdata->ncap * blocksize / 1024 / 1024 / 1024);
    1484                 :         72 :         printf("Utilization (in LBAs):                 %lld (%lldGiB)\n",
    1485         [ -  + ]:         72 :                (long long)nsdata->nuse,
    1486                 :         72 :                (long long)nsdata->nuse * blocksize / 1024 / 1024 / 1024);
    1487         [ +  + ]:         72 :         if (nsdata->noiob) {
    1488         [ -  + ]:          2 :                 printf("Optimal I/O Boundary:                  %u blocks\n", nsdata->noiob);
    1489                 :            :         }
    1490         [ +  + ]:         72 :         if (!spdk_mem_all_zero(nsdata->nguid, sizeof(nsdata->nguid))) {
    1491         [ -  + ]:         16 :                 printf("NGUID:                                 ");
    1492                 :         16 :                 print_hex_be(nsdata->nguid, sizeof(nsdata->nguid));
    1493                 :         16 :                 printf("\n");
    1494                 :            :         }
    1495         [ +  + ]:         72 :         if (!spdk_mem_all_zero(&nsdata->eui64, sizeof(nsdata->eui64))) {
    1496         [ -  + ]:         10 :                 printf("EUI64:                                 ");
    1497                 :         10 :                 print_hex_be(&nsdata->eui64, sizeof(nsdata->eui64));
    1498                 :         10 :                 printf("\n");
    1499                 :            :         }
    1500                 :         72 :         uuid = spdk_nvme_ns_get_uuid(ns);
    1501         [ +  + ]:         72 :         if (uuid) {
    1502                 :         14 :                 spdk_uuid_fmt_lower(uuid_str, sizeof(uuid_str), uuid);
    1503         [ -  + ]:         14 :                 printf("UUID:                                  %s\n", uuid_str);
    1504                 :            :         }
    1505         [ -  + ]:         72 :         printf("Thin Provisioning:                     %s\n",
    1506         [ -  + ]:         72 :                nsdata->nsfeat.thin_prov ? "Supported" : "Not Supported");
    1507         [ -  + ]:         72 :         printf("Per-NS Atomic Units:                   %s\n",
    1508         [ +  + ]:         72 :                nsdata->nsfeat.ns_atomic_write_unit ? "Yes" : "No");
    1509         [ +  + ]:         72 :         if (nsdata->nsfeat.ns_atomic_write_unit) {
    1510         [ -  + ]:         14 :                 if (nsdata->nawun) {
    1511         [ #  # ]:          0 :                         printf("  Atomic Write Unit (Normal):          %d\n", nsdata->nawun + 1);
    1512                 :            :                 }
    1513                 :            : 
    1514         [ -  + ]:         14 :                 if (nsdata->nawupf) {
    1515         [ #  # ]:          0 :                         printf("  Atomic Write Unit (PFail):           %d\n", nsdata->nawupf + 1);
    1516                 :            :                 }
    1517                 :            : 
    1518         [ -  + ]:         14 :                 if (nsdata->npwg) {
    1519         [ #  # ]:          0 :                         printf("  Preferred Write Granularity:         %d\n", nsdata->npwg + 1);
    1520                 :            :                 }
    1521                 :            : 
    1522         [ -  + ]:         14 :                 if (nsdata->nacwu) {
    1523         [ #  # ]:          0 :                         printf("  Atomic Compare & Write Unit:         %d\n", nsdata->nacwu + 1);
    1524                 :            :                 }
    1525                 :            : 
    1526         [ -  + ]:         14 :                 printf("  Atomic Boundary Size (Normal):       %d\n", nsdata->nabsn);
    1527         [ -  + ]:         14 :                 printf("  Atomic Boundary Size (PFail):        %d\n", nsdata->nabspf);
    1528         [ -  + ]:         14 :                 printf("  Atomic Boundary Offset:              %d\n", nsdata->nabo);
    1529                 :            :         }
    1530                 :            : 
    1531         [ +  + ]:         72 :         if (cdata->oncs.copy) {
    1532         [ -  + ]:         62 :                 printf("Maximum Single Source Range Length:    %d\n", nsdata->mssrl);
    1533         [ -  + ]:         62 :                 printf("Maximum Copy Length:                   %d\n", nsdata->mcl);
    1534         [ -  + ]:         62 :                 printf("Maximum Source Range Count:            %d\n", nsdata->msrc + 1);
    1535                 :            :         }
    1536                 :            : 
    1537         [ -  + ]:         72 :         printf("NGUID/EUI64 Never Reused:              %s\n",
    1538         [ -  + ]:         72 :                nsdata->nsfeat.guid_never_reused ? "Yes" : "No");
    1539                 :            : 
    1540         [ +  + ]:         72 :         if (cdata->cmic.ana_reporting) {
    1541         [ -  + ]:          4 :                 printf("ANA group ID:                          %u\n", nsdata->anagrpid);
    1542                 :            :         }
    1543                 :            : 
    1544         [ -  + ]:         72 :         printf("Namespace Write Protected:             %s\n",
    1545         [ -  + ]:         72 :                nsdata->nsattr.write_protected ? "Yes" : "No");
    1546                 :            : 
    1547         [ -  + ]:         72 :         if (cdata->ctratt.bits.nvm_sets) {
    1548         [ #  # ]:          0 :                 printf("NVM set ID:                            %u\n", nsdata->nvmsetid);
    1549                 :            :         }
    1550                 :            : 
    1551         [ +  + ]:         72 :         if (cdata->ctratt.bits.endurance_groups) {
    1552         [ -  + ]:          4 :                 printf("Endurance group ID:                    %u\n", nsdata->endgid);
    1553                 :            :         }
    1554                 :            : 
    1555         [ -  + ]:         72 :         printf("Number of LBA Formats:                 %d\n", nsdata->nlbaf + 1);
    1556         [ -  + ]:         72 :         printf("Current LBA Format:                    LBA Format #%02d\n",
    1557                 :            :                format_index);
    1558         [ +  + ]:        514 :         for (i = 0; i <= nsdata->nlbaf; i++) {
    1559                 :        682 :                 printf("LBA Format #%02d: Data Size: %5d  Metadata Size: %5d\n",
    1560   [ -  +  -  + ]:        442 :                        i, 1 << nsdata->lbaf[i].lbads, nsdata->lbaf[i].ms);
    1561         [ -  + ]:        442 :                 if (spdk_nvme_ns_get_csi(ns) == SPDK_NVME_CSI_ZNS) {
    1562                 :          0 :                         printf("LBA Format Extension #%02d: Zone Size (in LBAs): 0x%"PRIx64" Zone Descriptor Extension Size: %d bytes\n",
    1563   [ #  #  #  # ]:          0 :                                i, nsdata_zns->lbafe[i].zsze, nsdata_zns->lbafe[i].zdes << 6);
    1564                 :            :                 }
    1565                 :            : 
    1566                 :            :         }
    1567                 :         72 :         printf("\n");
    1568                 :            : 
    1569         [ +  + ]:         72 :         if (cdata->ctratt.bits.fdps) {
    1570                 :            :                 union spdk_nvme_feat_fdp_cdw12 fdp_res;
    1571                 :            : 
    1572   [ -  +  +  - ]:          4 :                 if (features[SPDK_NVME_FEAT_FDP].valid) {
    1573                 :          4 :                         fdp_res.raw = features[SPDK_NVME_FEAT_FDP].result;
    1574                 :            : 
    1575         [ -  + ]:          4 :                         printf("Get Feature FDP:\n");
    1576         [ -  + ]:          4 :                         printf("================\n");
    1577         [ -  + ]:          4 :                         printf("  Enabled:                 %s\n",
    1578         [ +  - ]:          4 :                                fdp_res.bits.fdpe ? "Yes" : "No");
    1579         [ -  + ]:          4 :                         printf("  FDP configuration index: %u\n\n", fdp_res.bits.fdpci);
    1580                 :            : 
    1581   [ +  -  +  - ]:          4 :                         if (fdp_res.bits.fdpe && !get_fdp_cfg_log_page(ns)) {
    1582                 :          4 :                                 print_fdp_cfg_log_page();
    1583                 :            :                         }
    1584   [ +  -  +  - ]:          4 :                         if (fdp_res.bits.fdpe && !get_fdp_ruhu_log_page(ns)) {
    1585                 :          4 :                                 print_fdp_ruhu_log_page();
    1586                 :            :                         }
    1587   [ +  -  +  - ]:          4 :                         if (fdp_res.bits.fdpe && !get_fdp_stats_log_page(ns)) {
    1588                 :          4 :                                 print_fdp_stats_log_page();
    1589                 :            :                         }
    1590   [ +  -  +  - ]:          4 :                         if (fdp_res.bits.fdpe && !get_fdp_events_log_page(ns)) {
    1591                 :          4 :                                 print_fdp_events_log_page();
    1592                 :            :                         }
    1593                 :            :                 }
    1594                 :            :         }
    1595                 :            : 
    1596         [ -  + ]:         72 :         if (spdk_nvme_ctrlr_is_ocssd_supported(ctrlr)) {
    1597                 :          0 :                 get_ocssd_geometry(ns, &geometry_data);
    1598                 :          0 :                 print_ocssd_geometry(&geometry_data);
    1599                 :          0 :                 get_ocssd_chunk_info_log_page(ns);
    1600   [ #  #  #  # ]:          0 :                 if (g_ocssd_verbose) {
    1601                 :          0 :                         print_ocssd_chunk_info_verbose(g_ocssd_chunk_info_page);
    1602                 :            :                 } else {
    1603                 :          0 :                         print_ocssd_chunk_info(g_ocssd_chunk_info_page, NUM_CHUNK_INFO_ENTRIES);
    1604                 :            :                 }
    1605         [ -  + ]:         72 :         } else if (spdk_nvme_ns_get_csi(ns) == SPDK_NVME_CSI_ZNS) {
    1606                 :          0 :                 struct spdk_nvme_qpair *qpair = spdk_nvme_ctrlr_alloc_io_qpair(ctrlr, NULL, 0);
    1607         [ #  # ]:          0 :                 if (qpair == NULL) {
    1608         [ #  # ]:          0 :                         printf("ERROR: spdk_nvme_ctrlr_alloc_io_qpair() failed\n");
    1609                 :          0 :                         exit(1);
    1610                 :            :                 }
    1611                 :          0 :                 print_zns_ns_data(nsdata_zns);
    1612                 :          0 :                 get_and_print_zns_zone_report(ns, qpair);
    1613                 :          0 :                 spdk_nvme_ctrlr_free_io_qpair(qpair);
    1614         [ +  + ]:         72 :         } else if (nsdata_nvm != NULL) {
    1615                 :         52 :                 print_nvm_ns_data(nsdata_nvm, nsdata);
    1616                 :            :         }
    1617                 :         72 : }
    1618                 :            : 
    1619                 :            : static const char *
    1620                 :        916 : admin_opc_name(uint8_t opc)
    1621                 :            : {
    1622   [ +  +  +  +  :        916 :         switch (opc) {
          +  +  +  +  +  
          +  +  +  +  -  
          +  +  +  +  +  
          -  -  +  +  -  
                -  -  + ]
    1623                 :         50 :         case SPDK_NVME_OPC_DELETE_IO_SQ:
    1624                 :         50 :                 return "Delete I/O Submission Queue";
    1625                 :         50 :         case SPDK_NVME_OPC_CREATE_IO_SQ:
    1626                 :         50 :                 return "Create I/O Submission Queue";
    1627                 :         64 :         case SPDK_NVME_OPC_GET_LOG_PAGE:
    1628                 :         64 :                 return "Get Log Page";
    1629                 :         50 :         case SPDK_NVME_OPC_DELETE_IO_CQ:
    1630                 :         50 :                 return "Delete I/O Completion Queue";
    1631                 :         50 :         case SPDK_NVME_OPC_CREATE_IO_CQ:
    1632                 :         50 :                 return "Create I/O Completion Queue";
    1633                 :         64 :         case SPDK_NVME_OPC_IDENTIFY:
    1634                 :         64 :                 return "Identify";
    1635                 :         64 :         case SPDK_NVME_OPC_ABORT:
    1636                 :         64 :                 return "Abort";
    1637                 :         64 :         case SPDK_NVME_OPC_SET_FEATURES:
    1638                 :         64 :                 return "Set Features";
    1639                 :         64 :         case SPDK_NVME_OPC_GET_FEATURES:
    1640                 :         64 :                 return "Get Features";
    1641                 :         64 :         case SPDK_NVME_OPC_ASYNC_EVENT_REQUEST:
    1642                 :         64 :                 return "Asynchronous Event Request";
    1643                 :          6 :         case SPDK_NVME_OPC_NS_MANAGEMENT:
    1644                 :          6 :                 return "Namespace Management";
    1645                 :          6 :         case SPDK_NVME_OPC_FIRMWARE_COMMIT:
    1646                 :          6 :                 return "Firmware Commit";
    1647                 :          6 :         case SPDK_NVME_OPC_FIRMWARE_IMAGE_DOWNLOAD:
    1648                 :          6 :                 return "Firmware Image Download";
    1649                 :          0 :         case SPDK_NVME_OPC_DEVICE_SELF_TEST:
    1650                 :          0 :                 return "Device Self-test";
    1651                 :         50 :         case SPDK_NVME_OPC_NS_ATTACHMENT:
    1652                 :         50 :                 return "Namespace Attachment";
    1653                 :         14 :         case SPDK_NVME_OPC_KEEP_ALIVE:
    1654                 :         14 :                 return "Keep Alive";
    1655                 :         44 :         case SPDK_NVME_OPC_DIRECTIVE_SEND:
    1656                 :         44 :                 return "Directive Send";
    1657                 :         44 :         case SPDK_NVME_OPC_DIRECTIVE_RECEIVE:
    1658                 :         44 :                 return "Directive Receive";
    1659                 :         44 :         case SPDK_NVME_OPC_VIRTUALIZATION_MANAGEMENT:
    1660                 :         44 :                 return "Virtualization Management";
    1661                 :          0 :         case SPDK_NVME_OPC_NVME_MI_SEND:
    1662                 :          0 :                 return "NVMe-MI Send";
    1663                 :          0 :         case SPDK_NVME_OPC_NVME_MI_RECEIVE:
    1664                 :          0 :                 return "NVMe-MI Receive";
    1665                 :         44 :         case SPDK_NVME_OPC_DOORBELL_BUFFER_CONFIG:
    1666                 :         44 :                 return "Doorbell Buffer Config";
    1667                 :         50 :         case SPDK_NVME_OPC_FORMAT_NVM:
    1668                 :         50 :                 return "Format NVM";
    1669                 :          0 :         case SPDK_NVME_OPC_SECURITY_SEND:
    1670                 :          0 :                 return "Security Send";
    1671                 :          0 :         case SPDK_NVME_OPC_SECURITY_RECEIVE:
    1672                 :          0 :                 return "Security Receive";
    1673                 :          0 :         case SPDK_NVME_OPC_SANITIZE:
    1674                 :          0 :                 return "Sanitize";
    1675                 :         24 :         default:
    1676         [ +  - ]:         24 :                 if (opc >= 0xC0) {
    1677                 :         24 :                         return "Vendor specific";
    1678                 :            :                 }
    1679                 :          0 :                 return "Unknown";
    1680                 :            :         }
    1681                 :            : }
    1682                 :            : 
    1683                 :            : static const char *
    1684                 :        560 : io_opc_name(uint8_t opc)
    1685                 :            : {
    1686   [ +  +  +  +  :        560 :         switch (opc) {
          +  +  +  -  -  
             -  -  +  + ]
    1687                 :         64 :         case SPDK_NVME_OPC_FLUSH:
    1688                 :         64 :                 return "Flush";
    1689                 :         64 :         case SPDK_NVME_OPC_WRITE:
    1690                 :         64 :                 return "Write";
    1691                 :         64 :         case SPDK_NVME_OPC_READ:
    1692                 :         64 :                 return "Read";
    1693                 :          6 :         case SPDK_NVME_OPC_WRITE_UNCORRECTABLE:
    1694                 :          6 :                 return "Write Uncorrectable";
    1695                 :         54 :         case SPDK_NVME_OPC_COMPARE:
    1696                 :         54 :                 return "Compare";
    1697                 :         58 :         case SPDK_NVME_OPC_WRITE_ZEROES:
    1698                 :         58 :                 return "Write Zeroes";
    1699                 :         64 :         case SPDK_NVME_OPC_DATASET_MANAGEMENT:
    1700                 :         64 :                 return "Dataset Management";
    1701                 :          0 :         case SPDK_NVME_OPC_RESERVATION_REGISTER:
    1702                 :          0 :                 return "Reservation Register";
    1703                 :          0 :         case SPDK_NVME_OPC_RESERVATION_REPORT:
    1704                 :          0 :                 return "Reservation Report";
    1705                 :          0 :         case SPDK_NVME_OPC_RESERVATION_ACQUIRE:
    1706                 :          0 :                 return "Reservation Acquire";
    1707                 :          0 :         case SPDK_NVME_OPC_RESERVATION_RELEASE:
    1708                 :          0 :                 return "Reservation Release";
    1709                 :         54 :         case SPDK_NVME_OPC_COPY:
    1710                 :         54 :                 return "Copy";
    1711                 :        132 :         default:
    1712         [ -  + ]:        132 :                 if (opc >= 0x80) {
    1713                 :          0 :                         return "Vendor specific";
    1714                 :            :                 }
    1715                 :        132 :                 return "Unknown";
    1716                 :            :         }
    1717                 :            : }
    1718                 :            : 
    1719                 :            : static void
    1720                 :         72 : print_controller(struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_transport_id *trid,
    1721                 :            :                  const struct spdk_nvme_ctrlr_opts *opts)
    1722                 :            : {
    1723                 :            :         const struct spdk_nvme_ctrlr_data       *cdata;
    1724                 :            :         union spdk_nvme_cap_register            cap;
    1725                 :            :         union spdk_nvme_vs_register             vs;
    1726                 :         28 :         uint8_t                                 str[512];
    1727                 :            :         uint32_t                                i, j;
    1728                 :            :         struct spdk_nvme_error_information_entry *error_entry;
    1729                 :         28 :         struct spdk_pci_addr                    pci_addr;
    1730                 :            :         struct spdk_pci_device                  *pci_dev;
    1731                 :            :         struct spdk_pci_id                      pci_id;
    1732                 :            :         uint32_t                                nsid;
    1733                 :            :         uint8_t                                 *orig_desc;
    1734                 :            :         struct spdk_nvme_ana_group_descriptor   *copied_desc;
    1735                 :            :         uint32_t                                desc_size, copy_len;
    1736                 :            : 
    1737                 :            : 
    1738                 :         72 :         cap = spdk_nvme_ctrlr_get_regs_cap(ctrlr);
    1739                 :         72 :         vs = spdk_nvme_ctrlr_get_regs_vs(ctrlr);
    1740                 :            : 
    1741         [ +  + ]:         72 :         if (!spdk_nvme_ctrlr_is_discovery(ctrlr)) {
    1742                 :            :                 /*
    1743                 :            :                  * Discovery Controller only supports the
    1744                 :            :                  * IDENTIFY and GET_LOG_PAGE cmd set, so only
    1745                 :            :                  * attempt GET_FEATURES when NOT targeting a
    1746                 :            :                  * Discovery Controller.
    1747                 :            :                  */
    1748                 :         64 :                 get_ctrlr_features(ctrlr);
    1749                 :            :         }
    1750                 :         72 :         get_log_pages(ctrlr);
    1751                 :            : 
    1752                 :         72 :         cdata = spdk_nvme_ctrlr_get_data(ctrlr);
    1753                 :            : 
    1754         [ -  + ]:         72 :         printf("=====================================================\n");
    1755         [ +  + ]:         72 :         if (trid->trtype != SPDK_NVME_TRANSPORT_PCIE) {
    1756                 :         22 :                 printf("NVMe over Fabrics controller at %s:%s: %s\n",
    1757         [ -  + ]:         22 :                        trid->traddr, trid->trsvcid, trid->subnqn);
    1758                 :            :         } else {
    1759         [ -  + ]:         50 :                 if (spdk_pci_addr_parse(&pci_addr, trid->traddr) != 0) {
    1760                 :          0 :                         return;
    1761                 :            :                 }
    1762                 :            : 
    1763                 :         50 :                 pci_dev = spdk_nvme_ctrlr_get_pci_device(ctrlr);
    1764         [ -  + ]:         50 :                 if (!pci_dev) {
    1765                 :          0 :                         return;
    1766                 :            :                 }
    1767                 :            : 
    1768                 :         50 :                 pci_id = spdk_pci_device_get_id(pci_dev);
    1769                 :            : 
    1770                 :         50 :                 printf("NVMe Controller at %04x:%02x:%02x.%x [%04x:%04x]\n",
    1771                 :         50 :                        pci_addr.domain, pci_addr.bus,
    1772                 :         50 :                        pci_addr.dev, pci_addr.func,
    1773         [ -  + ]:         50 :                        pci_id.vendor_id, pci_id.device_id);
    1774                 :            :         }
    1775         [ -  + ]:         72 :         printf("=====================================================\n");
    1776                 :            : 
    1777   [ -  +  -  + ]:         72 :         if (g_hex_dump) {
    1778                 :          0 :                 hex_dump(cdata, sizeof(*cdata));
    1779                 :          0 :                 printf("\n");
    1780                 :            :         }
    1781                 :            : 
    1782         [ -  + ]:         72 :         printf("Controller Capabilities/Features\n");
    1783         [ -  + ]:         72 :         printf("================================\n");
    1784         [ -  + ]:         72 :         printf("Vendor ID:                             %04x\n", cdata->vid);
    1785         [ -  + ]:         72 :         printf("Subsystem Vendor ID:                   %04x\n", cdata->ssvid);
    1786         [ -  + ]:         72 :         printf("Serial Number:                         ");
    1787                 :         72 :         print_ascii_string(cdata->sn, sizeof(cdata->sn));
    1788                 :         72 :         printf("\n");
    1789         [ -  + ]:         72 :         printf("Model Number:                          ");
    1790                 :         72 :         print_ascii_string(cdata->mn, sizeof(cdata->mn));
    1791                 :         72 :         printf("\n");
    1792         [ -  + ]:         72 :         printf("Firmware Version:                      ");
    1793                 :         72 :         print_ascii_string(cdata->fr, sizeof(cdata->fr));
    1794                 :         72 :         printf("\n");
    1795         [ -  + ]:         72 :         printf("Recommended Arb Burst:                 %d\n", cdata->rab);
    1796                 :         72 :         printf("IEEE OUI Identifier:                   %02x %02x %02x\n",
    1797         [ -  + ]:         72 :                cdata->ieee[0], cdata->ieee[1], cdata->ieee[2]);
    1798         [ -  + ]:         72 :         printf("Multi-path I/O\n");
    1799   [ +  +  -  + ]:         72 :         printf("  May have multiple subsystem ports:   %s\n", cdata->cmic.multi_port ? "Yes" : "No");
    1800   [ +  +  -  + ]:         72 :         printf("  May have multiple controllers:       %s\n", cdata->cmic.multi_ctrlr ? "Yes" : "No");
    1801   [ -  +  -  + ]:         72 :         printf("  Associated with SR-IOV VF:           %s\n", cdata->cmic.sr_iov ? "Yes" : "No");
    1802         [ -  + ]:         72 :         printf("Max Data Transfer Size:                ");
    1803         [ +  + ]:         72 :         if (cdata->mdts == 0) {
    1804         [ -  + ]:          7 :                 printf("Unlimited\n");
    1805                 :            :         } else {
    1806   [ -  +  -  + ]:         65 :                 printf("%" PRIu64 "\n", (uint64_t)1 << (12 + cap.bits.mpsmin + cdata->mdts));
    1807                 :            :         }
    1808         [ -  + ]:         72 :         printf("Max Number of Namespaces:              %d\n", cdata->nn);
    1809         [ -  + ]:         72 :         printf("Max Number of I/O Queues:              %d\n", opts->num_io_queues);
    1810         [ -  + ]:         72 :         printf("NVMe Specification Version (VS):       %u.%u", vs.bits.mjr, vs.bits.mnr);
    1811         [ -  + ]:         72 :         if (vs.bits.ter) {
    1812         [ #  # ]:          0 :                 printf(".%u", vs.bits.ter);
    1813                 :            :         }
    1814                 :         72 :         printf("\n");
    1815         [ +  - ]:         72 :         if (cdata->ver.raw != 0) {
    1816         [ -  + ]:         72 :                 printf("NVMe Specification Version (Identify): %u.%u", cdata->ver.bits.mjr, cdata->ver.bits.mnr);
    1817         [ -  + ]:         72 :                 if (cdata->ver.bits.ter) {
    1818         [ #  # ]:          0 :                         printf(".%u", cdata->ver.bits.ter);
    1819                 :            :                 }
    1820                 :         72 :                 printf("\n");
    1821                 :            :         }
    1822                 :            : 
    1823         [ -  + ]:         72 :         printf("Maximum Queue Entries:                 %u\n", cap.bits.mqes + 1);
    1824   [ +  +  -  + ]:         72 :         printf("Contiguous Queues Required:            %s\n", cap.bits.cqr ? "Yes" : "No");
    1825         [ -  + ]:         72 :         printf("Arbitration Mechanisms Supported\n");
    1826         [ -  + ]:         72 :         printf("  Weighted Round Robin:                %s\n",
    1827         [ +  + ]:         72 :                cap.bits.ams & SPDK_NVME_CAP_AMS_WRR ? "Supported" : "Not Supported");
    1828         [ -  + ]:         72 :         printf("  Vendor Specific:                     %s\n",
    1829         [ -  + ]:         72 :                cap.bits.ams & SPDK_NVME_CAP_AMS_VS ? "Supported" : "Not Supported");
    1830         [ -  + ]:         72 :         printf("Reset Timeout:                         %" PRIu64 " ms\n", (uint64_t)500 * cap.bits.to);
    1831                 :         72 :         printf("Doorbell Stride:                       %" PRIu64 " bytes\n",
    1832   [ -  +  -  + ]:         72 :                (uint64_t)1 << (2 + cap.bits.dstrd));
    1833         [ -  + ]:         72 :         printf("NVM Subsystem Reset:                   %s\n",
    1834         [ -  + ]:         72 :                cap.bits.nssrs ? "Supported" : "Not Supported");
    1835         [ -  + ]:         72 :         printf("Command Sets Supported\n");
    1836         [ -  + ]:         72 :         printf("  NVM Command Set:                     %s\n",
    1837         [ +  - ]:         72 :                cap.bits.css & SPDK_NVME_CAP_CSS_NVM ? "Supported" : "Not Supported");
    1838         [ -  + ]:         72 :         printf("Boot Partition:                        %s\n",
    1839         [ -  + ]:         72 :                cap.bits.bps ? "Supported" : "Not Supported");
    1840                 :         72 :         printf("Memory Page Size Minimum:              %" PRIu64 " bytes\n",
    1841   [ -  +  -  + ]:         72 :                (uint64_t)1 << (12 + cap.bits.mpsmin));
    1842                 :         72 :         printf("Memory Page Size Maximum:              %" PRIu64 " bytes\n",
    1843   [ -  +  -  + ]:         72 :                (uint64_t)1 << (12 + cap.bits.mpsmax));
    1844         [ -  + ]:         72 :         printf("Persistent Memory Region:              %s\n",
    1845         [ +  + ]:         72 :                cap.bits.pmrs ? "Supported" : "Not Supported");
    1846                 :            : 
    1847         [ -  + ]:         72 :         printf("Optional Asynchronous Events Supported\n");
    1848         [ -  + ]:         72 :         printf("  Namespace Attribute Notices:         %s\n",
    1849         [ +  + ]:         72 :                cdata->oaes.ns_attribute_notices ? "Supported" : "Not Supported");
    1850         [ -  + ]:         72 :         printf("  Firmware Activation Notices:         %s\n",
    1851         [ +  + ]:         72 :                cdata->oaes.fw_activation_notices ? "Supported" : "Not Supported");
    1852         [ -  + ]:         72 :         printf("  ANA Change Notices:                  %s\n",
    1853         [ +  + ]:         72 :                cdata->oaes.ana_change_notices ? "Supported" : "Not Supported");
    1854         [ -  + ]:         72 :         printf("  PLE Aggregate Log Change Notices:    %s\n",
    1855         [ -  + ]:         72 :                cdata->oaes.pleal_change_notices ? "Supported" : "Not Supported");
    1856         [ -  + ]:         72 :         printf("  LBA Status Info Alert Notices:       %s\n",
    1857         [ -  + ]:         72 :                cdata->oaes.lba_sia_notices ? "Supported" : "Not Supported");
    1858         [ -  + ]:         72 :         printf("  EGE Aggregate Log Change Notices:    %s\n",
    1859         [ -  + ]:         72 :                cdata->oaes.egealp_change_notices ? "Supported" : "Not Supported");
    1860         [ -  + ]:         72 :         printf("  Normal NVM Subsystem Shutdown event: %s\n",
    1861         [ -  + ]:         72 :                cdata->oaes.nnvm_sse ? "Supported" : "Not Supported");
    1862         [ -  + ]:         72 :         printf("  Zone Descriptor Change Notices:      %s\n",
    1863         [ -  + ]:         72 :                cdata->oaes.zdes_change_notices ? "Supported" : "Not Supported");
    1864         [ -  + ]:         72 :         printf("  Discovery Log Change Notices:        %s\n",
    1865         [ +  + ]:         72 :                cdata->oaes.discovery_log_change_notices ? "Supported" : "Not Supported");
    1866                 :            : 
    1867         [ -  + ]:         72 :         printf("Controller Attributes\n");
    1868         [ -  + ]:         72 :         printf("  128-bit Host Identifier:             %s\n",
    1869         [ +  + ]:         72 :                cdata->ctratt.bits.host_id_exhid_supported ? "Supported" : "Not Supported");
    1870         [ -  + ]:         72 :         printf("  Non-Operational Permissive Mode:     %s\n",
    1871         [ -  + ]:         72 :                cdata->ctratt.bits.non_operational_power_state_permissive_mode ? "Supported" : "Not Supported");
    1872         [ -  + ]:         72 :         printf("  NVM Sets:                            %s\n",
    1873         [ -  + ]:         72 :                cdata->ctratt.bits.nvm_sets ? "Supported" : "Not Supported");
    1874         [ -  + ]:         72 :         printf("  Read Recovery Levels:                %s\n",
    1875         [ -  + ]:         72 :                cdata->ctratt.bits.read_recovery_levels ? "Supported" : "Not Supported");
    1876         [ -  + ]:         72 :         printf("  Endurance Groups:                    %s\n",
    1877         [ +  + ]:         72 :                cdata->ctratt.bits.endurance_groups ? "Supported" : "Not Supported");
    1878         [ -  + ]:         72 :         printf("  Predictable Latency Mode:            %s\n",
    1879         [ -  + ]:         72 :                cdata->ctratt.bits.predictable_latency_mode ? "Supported" : "Not Supported");
    1880         [ -  + ]:         72 :         printf("  Traffic Based Keep ALive:            %s\n",
    1881         [ +  + ]:         72 :                cdata->ctratt.bits.tbkas ? "Supported" : "Not Supported");
    1882         [ -  + ]:         72 :         printf("  Namespace Granularity:               %s\n",
    1883         [ -  + ]:         72 :                cdata->ctratt.bits.namespace_granularity ? "Supported" : "Not Supported");
    1884         [ -  + ]:         72 :         printf("  SQ Associations:                     %s\n",
    1885         [ -  + ]:         72 :                cdata->ctratt.bits.sq_associations ? "Supported" : "Not Supported");
    1886         [ -  + ]:         72 :         printf("  UUID List:                           %s\n",
    1887         [ -  + ]:         72 :                cdata->ctratt.bits.uuid_list ? "Supported" : "Not Supported");
    1888         [ -  + ]:         72 :         printf("  Multi-Domain Subsystem:              %s\n",
    1889         [ -  + ]:         72 :                cdata->ctratt.bits.mds ? "Supported" : "Not Supported");
    1890         [ -  + ]:         72 :         printf("  Fixed Capacity Management:           %s\n",
    1891         [ -  + ]:         72 :                cdata->ctratt.bits.fixed_capacity_management ? "Supported" : "Not Supported");
    1892         [ -  + ]:         72 :         printf("  Variable Capacity Management:        %s\n",
    1893         [ -  + ]:         72 :                cdata->ctratt.bits.variable_capacity_management ? "Supported" : "Not Supported");
    1894         [ -  + ]:         72 :         printf("  Delete Endurance Group:              %s\n",
    1895         [ -  + ]:         72 :                cdata->ctratt.bits.delete_endurance_group ? "Supported" : "Not Supported");
    1896         [ -  + ]:         72 :         printf("  Delete NVM Set:                      %s\n",
    1897         [ -  + ]:         72 :                cdata->ctratt.bits.delete_nvm_set ? "Supported" : "Not Supported");
    1898         [ -  + ]:         72 :         printf("  Extended LBA Formats Supported:      %s\n",
    1899         [ +  + ]:         72 :                cdata->ctratt.bits.elbas ? "Supported" : "Not Supported");
    1900         [ -  + ]:         72 :         printf("  Flexible Data Placement Supported:   %s\n",
    1901         [ +  + ]:         72 :                cdata->ctratt.bits.fdps ? "Supported" : "Not Supported");
    1902                 :         72 :         printf("\n");
    1903                 :            : 
    1904         [ -  + ]:         72 :         printf("Controller Memory Buffer Support\n");
    1905         [ -  + ]:         72 :         printf("================================\n");
    1906         [ +  + ]:         72 :         if (cap.bits.cmbs != 0) {
    1907                 :            :                 union spdk_nvme_cmbsz_register          cmbsz;
    1908                 :            :                 uint64_t size;
    1909                 :            : 
    1910                 :          8 :                 cmbsz = spdk_nvme_ctrlr_get_regs_cmbsz(ctrlr);
    1911                 :          8 :                 size = cmbsz.bits.sz;
    1912                 :            : 
    1913                 :            :                 /* Convert the size to bytes by multiplying by the granularity.
    1914                 :            :                    By spec, szu is at most 6 and sz is 20 bits, so size requires
    1915                 :            :                    at most 56 bits. */
    1916         [ #  # ]:          8 :                 size *= (0x1000 << (cmbsz.bits.szu * 4));
    1917                 :            : 
    1918         [ #  # ]:          8 :                 printf("Supported:                             Yes\n");
    1919         [ #  # ]:          8 :                 printf("Total Size:                            %" PRIu64 " bytes\n", size);
    1920         [ #  # ]:          8 :                 printf("Submission Queues in CMB:              %s\n",
    1921         [ +  - ]:          8 :                        cmbsz.bits.sqs ? "Supported" : "Not Supported");
    1922         [ #  # ]:          8 :                 printf("Completion Queues in CMB:              %s\n",
    1923         [ -  + ]:          8 :                        cmbsz.bits.cqs ? "Supported" : "Not Supported");
    1924         [ #  # ]:          8 :                 printf("Read data and metadata in CMB          %s\n",
    1925         [ +  - ]:          8 :                        cmbsz.bits.rds ? "Supported" : "Not Supported");
    1926         [ #  # ]:          8 :                 printf("Write data and metadata in CMB:        %s\n",
    1927         [ +  - ]:          8 :                        cmbsz.bits.wds ? "Supported" : "Not Supported");
    1928                 :            :         } else {
    1929         [ -  + ]:         64 :                 printf("Supported:                             No\n");
    1930                 :            :         }
    1931                 :         72 :         printf("\n");
    1932                 :            : 
    1933         [ -  + ]:         72 :         printf("Persistent Memory Region Support\n");
    1934         [ -  + ]:         72 :         printf("================================\n");
    1935         [ +  + ]:         72 :         if (cap.bits.pmrs != 0) {
    1936                 :            :                 union spdk_nvme_pmrcap_register         pmrcap;
    1937                 :            :                 uint64_t                                pmrsz;
    1938                 :            : 
    1939                 :          8 :                 pmrcap = spdk_nvme_ctrlr_get_regs_pmrcap(ctrlr);
    1940                 :          8 :                 pmrsz = spdk_nvme_ctrlr_get_pmrsz(ctrlr);
    1941                 :            : 
    1942         [ #  # ]:          8 :                 printf("Supported:                             Yes\n");
    1943         [ #  # ]:          8 :                 printf("Total Size:                            %" PRIu64 " bytes\n", pmrsz);
    1944         [ #  # ]:          8 :                 printf("Read data and metadata in PMR          %s\n",
    1945         [ +  - ]:          8 :                        pmrcap.bits.rds ? "Supported" : "Not Supported");
    1946         [ #  # ]:          8 :                 printf("Write data and metadata in PMR:        %s\n",
    1947         [ +  - ]:          8 :                        pmrcap.bits.wds ? "Supported" : "Not Supported");
    1948                 :            :         } else {
    1949         [ -  + ]:         64 :                 printf("Supported:                             No\n");
    1950                 :            :         }
    1951                 :         72 :         printf("\n");
    1952                 :            : 
    1953         [ -  + ]:         72 :         printf("Admin Command Set Attributes\n");
    1954         [ -  + ]:         72 :         printf("============================\n");
    1955         [ -  + ]:         72 :         printf("Security Send/Receive:                 %s\n",
    1956         [ +  + ]:         72 :                cdata->oacs.security ? "Supported" : "Not Supported");
    1957         [ -  + ]:         72 :         printf("Format NVM:                            %s\n",
    1958         [ +  + ]:         72 :                cdata->oacs.format ? "Supported" : "Not Supported");
    1959         [ -  + ]:         72 :         printf("Firmware Activate/Download:            %s\n",
    1960         [ +  + ]:         72 :                cdata->oacs.firmware ? "Supported" : "Not Supported");
    1961         [ -  + ]:         72 :         printf("Namespace Management:                  %s\n",
    1962         [ +  + ]:         72 :                cdata->oacs.ns_manage ? "Supported" : "Not Supported");
    1963         [ -  + ]:         72 :         printf("Device Self-Test:                      %s\n",
    1964         [ -  + ]:         72 :                cdata->oacs.device_self_test ? "Supported" : "Not Supported");
    1965         [ -  + ]:         72 :         printf("Directives:                            %s\n",
    1966         [ +  + ]:         72 :                cdata->oacs.directives ? "Supported" : "Not Supported");
    1967         [ -  + ]:         72 :         printf("NVMe-MI:                               %s\n",
    1968         [ -  + ]:         72 :                cdata->oacs.nvme_mi ? "Supported" : "Not Supported");
    1969         [ -  + ]:         72 :         printf("Virtualization Management:             %s\n",
    1970         [ -  + ]:         72 :                cdata->oacs.virtualization_management ? "Supported" : "Not Supported");
    1971         [ -  + ]:         72 :         printf("Doorbell Buffer Config:                %s\n",
    1972         [ +  + ]:         72 :                cdata->oacs.doorbell_buffer_config ? "Supported" : "Not Supported");
    1973         [ -  + ]:         72 :         printf("Get LBA Status Capability:             %s\n",
    1974         [ -  + ]:         72 :                cdata->oacs.get_lba_status ? "Supported" : "Not Supported");
    1975         [ -  + ]:         72 :         printf("Command & Feature Lockdown Capability: %s\n",
    1976         [ -  + ]:         72 :                cdata->oacs.command_feature_lockdown ? "Supported" : "Not Supported");
    1977         [ -  + ]:         72 :         printf("Abort Command Limit:                   %d\n", cdata->acl + 1);
    1978         [ -  + ]:         72 :         printf("Async Event Request Limit:             %d\n", cdata->aerl + 1);
    1979         [ -  + ]:         72 :         printf("Number of Firmware Slots:              ");
    1980         [ +  + ]:         72 :         if (cdata->oacs.firmware != 0) {
    1981         [ -  + ]:          6 :                 printf("%d\n", cdata->frmw.num_slots);
    1982                 :            :         } else {
    1983         [ -  + ]:         66 :                 printf("N/A\n");
    1984                 :            :         }
    1985         [ -  + ]:         72 :         printf("Firmware Slot 1 Read-Only:             ");
    1986         [ +  + ]:         72 :         if (cdata->oacs.firmware != 0) {
    1987   [ -  +  -  + ]:          6 :                 printf("%s\n", cdata->frmw.slot1_ro ? "Yes" : "No");
    1988                 :            :         } else {
    1989         [ -  + ]:         66 :                 printf("N/A\n");
    1990                 :            :         }
    1991         [ -  + ]:         72 :         printf("Firmware Activation Without Reset:     ");
    1992         [ +  + ]:         72 :         if (cdata->oacs.firmware != 0) {
    1993   [ +  -  -  + ]:          6 :                 printf("%s\n", cdata->frmw.activation_without_reset ? "Yes" : "No");
    1994                 :            :         } else {
    1995         [ -  + ]:         66 :                 printf("N/A\n");
    1996                 :            :         }
    1997         [ -  + ]:         72 :         printf("Multiple Update Detection Support:     ");
    1998         [ +  + ]:         72 :         if (cdata->oacs.firmware != 0) {
    1999   [ -  +  -  + ]:          6 :                 printf("%s\n", cdata->frmw.multiple_update_detection ? "Yes" : "No");
    2000                 :            :         } else {
    2001         [ -  + ]:         66 :                 printf("N/A\n");
    2002                 :            :         }
    2003         [ +  - ]:         72 :         if (cdata->fwug == 0x00) {
    2004         [ -  + ]:         72 :                 printf("Firmware Update Granularity:           No Information Provided\n");
    2005         [ #  # ]:          0 :         } else if (cdata->fwug == 0xFF) {
    2006         [ #  # ]:          0 :                 printf("Firmware Update Granularity:           No Restriction\n");
    2007                 :            :         } else {
    2008                 :          0 :                 printf("Firmware Update Granularity:           %u KiB\n",
    2009         [ #  # ]:          0 :                        cdata->fwug * 4);
    2010                 :            :         }
    2011         [ -  + ]:         72 :         printf("Per-Namespace SMART Log:               %s\n",
    2012         [ +  + ]:         72 :                cdata->lpa.ns_smart ? "Yes" : "No");
    2013         [ +  + ]:         72 :         if (cdata->cmic.ana_reporting == 0) {
    2014         [ -  + ]:         68 :                 printf("Asymmetric Namespace Access Log Page:  Not Supported\n");
    2015                 :            :         } else {
    2016         [ -  + ]:          4 :                 printf("Asymmetric Namespace Access Log Page:  Supported\n");
    2017         [ -  + ]:          4 :                 printf("ANA Transition Time                 :  %u sec\n", cdata->anatt);
    2018                 :          4 :                 printf("\n");
    2019         [ -  + ]:          4 :                 printf("Asymmetric Namespace Access Capabilities\n");
    2020         [ -  + ]:          4 :                 printf("  ANA Optimized State               : %s\n",
    2021         [ +  - ]:          4 :                        cdata->anacap.ana_optimized_state ? "Supported" : "Not Supported");
    2022         [ -  + ]:          4 :                 printf("  ANA Non-Optimized State           : %s\n",
    2023         [ +  - ]:          4 :                        cdata->anacap.ana_non_optimized_state ? "Supported" : "Not Supported");
    2024         [ -  + ]:          4 :                 printf("  ANA Inaccessible State            : %s\n",
    2025         [ +  - ]:          4 :                        cdata->anacap.ana_inaccessible_state ? "Supported" : "Not Supported");
    2026         [ -  + ]:          4 :                 printf("  ANA Persistent Loss State         : %s\n",
    2027         [ +  - ]:          4 :                        cdata->anacap.ana_persistent_loss_state ? "Supported" : "Not Supported");
    2028         [ -  + ]:          4 :                 printf("  ANA Change State                  : %s\n",
    2029         [ +  - ]:          4 :                        cdata->anacap.ana_change_state ? "Supported" : "Not Supported");
    2030         [ -  + ]:          4 :                 printf("  ANAGRPID is not changed           : %s\n",
    2031         [ -  + ]:          4 :                        cdata->anacap.no_change_anagrpid ? "Yes" : "No");
    2032         [ -  + ]:          4 :                 printf("  Non-Zero ANAGRPID for NS Mgmt Cmd : %s\n",
    2033         [ -  + ]:          4 :                        cdata->anacap.non_zero_anagrpid ? "Supported" : "Not Supported");
    2034                 :          4 :                 printf("\n");
    2035         [ -  + ]:          4 :                 printf("ANA Group Identifier Maximum        : %u\n", cdata->anagrpmax);
    2036         [ -  + ]:          4 :                 printf("Number of ANA Group Identifiers     : %u\n", cdata->nanagrpid);
    2037         [ -  + ]:          4 :                 printf("Max Number of Allowed Namespaces    : %u\n", cdata->mnan);
    2038                 :            :         }
    2039         [ -  + ]:         72 :         printf("Subsystem NQN:                         %s\n", cdata->subnqn);
    2040         [ -  + ]:         72 :         printf("Command Effects Log Page:              %s\n",
    2041         [ +  + ]:         72 :                cdata->lpa.celp ? "Supported" : "Not Supported");
    2042         [ -  + ]:         72 :         printf("Get Log Page Extended Data:            %s\n",
    2043         [ +  - ]:         72 :                cdata->lpa.edlp ? "Supported" : "Not Supported");
    2044         [ -  + ]:         72 :         printf("Telemetry Log Pages:                   %s\n",
    2045         [ +  + ]:         72 :                cdata->lpa.telemetry ? "Supported" : "Not Supported");
    2046         [ -  + ]:         72 :         printf("Persistent Event Log Pages:            %s\n",
    2047         [ -  + ]:         72 :                cdata->lpa.pelp ? "Supported" : "Not Supported");
    2048         [ -  + ]:         72 :         printf("Supported Log Pages Log Page:          %s\n",
    2049         [ -  + ]:         72 :                cdata->lpa.lplp ? "Supported" : "May Support");
    2050         [ -  + ]:         72 :         printf("Commands Supported & Effects Log Page: %s\n",
    2051         [ -  + ]:         72 :                cdata->lpa.lplp ? "Supported" : "Not Supported");
    2052         [ -  + ]:         72 :         printf("Feature Identifiers & Effects Log Page:%s\n",
    2053         [ -  + ]:         72 :                cdata->lpa.lplp ? "Supported" : "May Support");
    2054         [ -  + ]:         72 :         printf("NVMe-MI Commands & Effects Log Page:   %s\n",
    2055         [ -  + ]:         72 :                cdata->lpa.lplp ? "Supported" : "May Support");
    2056         [ -  + ]:         72 :         printf("Data Area 4 for Telemetry Log:         %s\n",
    2057         [ -  + ]:         72 :                cdata->lpa.da4_telemetry ? "Supported" : "Not Supported");
    2058         [ -  + ]:         72 :         printf("Error Log Page Entries Supported:      %d\n", cdata->elpe + 1);
    2059         [ +  + ]:         72 :         if (cdata->kas == 0) {
    2060         [ -  + ]:         58 :                 printf("Keep Alive:                            Not Supported\n");
    2061                 :            :         } else {
    2062         [ -  + ]:         14 :                 printf("Keep Alive:                            Supported\n");
    2063                 :         14 :                 printf("Keep Alive Granularity:                %u ms\n",
    2064         [ -  + ]:         14 :                        cdata->kas * 100);
    2065                 :            :         }
    2066                 :         72 :         printf("\n");
    2067                 :            : 
    2068         [ -  + ]:         72 :         printf("NVM Command Set Attributes\n");
    2069         [ -  + ]:         72 :         printf("==========================\n");
    2070         [ -  + ]:         72 :         printf("Submission Queue Entry Size\n");
    2071   [ -  +  -  + ]:         72 :         printf("  Max:                       %d\n", 1 << cdata->sqes.max);
    2072   [ -  +  -  + ]:         72 :         printf("  Min:                       %d\n", 1 << cdata->sqes.min);
    2073         [ -  + ]:         72 :         printf("Completion Queue Entry Size\n");
    2074   [ -  +  -  + ]:         72 :         printf("  Max:                       %d\n", 1 << cdata->cqes.max);
    2075   [ -  +  -  + ]:         72 :         printf("  Min:                       %d\n", 1 << cdata->cqes.min);
    2076         [ -  + ]:         72 :         printf("Number of Namespaces:        %d\n", cdata->nn);
    2077         [ -  + ]:         72 :         printf("Compare Command:             %s\n",
    2078         [ +  + ]:         72 :                cdata->oncs.compare ? "Supported" : "Not Supported");
    2079         [ -  + ]:         72 :         printf("Write Uncorrectable Command: %s\n",
    2080         [ +  + ]:         72 :                cdata->oncs.write_unc ? "Supported" : "Not Supported");
    2081         [ -  + ]:         72 :         printf("Dataset Management Command:  %s\n",
    2082         [ +  + ]:         72 :                cdata->oncs.dsm ? "Supported" : "Not Supported");
    2083         [ -  + ]:         72 :         printf("Write Zeroes Command:        %s\n",
    2084         [ +  + ]:         72 :                cdata->oncs.write_zeroes ? "Supported" : "Not Supported");
    2085         [ -  + ]:         72 :         printf("Set Features Save Field:     %s\n",
    2086         [ +  + ]:         72 :                cdata->oncs.set_features_save ? "Supported" : "Not Supported");
    2087         [ -  + ]:         72 :         printf("Reservations:                %s\n",
    2088         [ +  + ]:         72 :                cdata->oncs.reservations ? "Supported" : "Not Supported");
    2089         [ -  + ]:         72 :         printf("Timestamp:                   %s\n",
    2090         [ +  + ]:         72 :                cdata->oncs.timestamp ? "Supported" : "Not Supported");
    2091         [ -  + ]:         72 :         printf("Copy:                        %s\n",
    2092         [ +  + ]:         72 :                cdata->oncs.copy ? "Supported" : "Not Supported");
    2093         [ -  + ]:         72 :         printf("Volatile Write Cache:        %s\n",
    2094         [ +  + ]:         72 :                cdata->vwc.present ? "Present" : "Not Present");
    2095         [ -  + ]:         72 :         printf("Atomic Write Unit (Normal):  %d\n", cdata->awun + 1);
    2096         [ -  + ]:         72 :         printf("Atomic Write Unit (PFail):   %d\n", cdata->awupf + 1);
    2097         [ -  + ]:         72 :         printf("Atomic Compare & Write Unit: %d\n", cdata->acwu + 1);
    2098         [ -  + ]:         72 :         printf("Fused Compare & Write:       %s\n",
    2099         [ +  + ]:         72 :                cdata->fuses.compare_and_write ? "Supported" : "Not Supported");
    2100         [ -  + ]:         72 :         printf("Scatter-Gather List\n");
    2101         [ -  + ]:         72 :         printf("  SGL Command Set:           %s\n",
    2102         [ +  + ]:         72 :                cdata->sgls.supported == SPDK_NVME_SGLS_SUPPORTED ? "Supported" :
    2103         [ +  + ]:          8 :                cdata->sgls.supported == SPDK_NVME_SGLS_SUPPORTED_DWORD_ALIGNED ? "Supported (Dword aligned)" :
    2104                 :            :                "Not Supported");
    2105         [ -  + ]:         72 :         printf("  SGL Keyed:                 %s\n",
    2106         [ +  + ]:         72 :                cdata->sgls.keyed_sgl ? "Supported" : "Not Supported");
    2107         [ -  + ]:         72 :         printf("  SGL Bit Bucket Descriptor: %s\n",
    2108         [ -  + ]:         72 :                cdata->sgls.bit_bucket_descriptor ? "Supported" : "Not Supported");
    2109         [ -  + ]:         72 :         printf("  SGL Metadata Pointer:      %s\n",
    2110         [ -  + ]:         72 :                cdata->sgls.metadata_pointer ? "Supported" : "Not Supported");
    2111         [ -  + ]:         72 :         printf("  Oversized SGL:             %s\n",
    2112         [ -  + ]:         72 :                cdata->sgls.oversized_sgl ? "Supported" : "Not Supported");
    2113         [ -  + ]:         72 :         printf("  SGL Metadata Address:      %s\n",
    2114         [ -  + ]:         72 :                cdata->sgls.metadata_address ? "Supported" : "Not Supported");
    2115         [ -  + ]:         72 :         printf("  SGL Offset:                %s\n",
    2116         [ +  + ]:         72 :                cdata->sgls.sgl_offset ? "Supported" : "Not Supported");
    2117         [ -  + ]:         72 :         printf("  Transport SGL Data Block:  %s\n",
    2118         [ -  + ]:         72 :                cdata->sgls.transport_sgl ? "Supported" : "Not Supported");
    2119         [ -  + ]:         72 :         printf("Replay Protected Memory Block:");
    2120         [ -  + ]:         72 :         if (cdata->rpmbs.num_rpmb_units > 0) {
    2121         [ #  # ]:          0 :                 printf("  Supported\n");
    2122         [ #  # ]:          0 :                 printf("  Number of RPMB Units:  %d\n", cdata->rpmbs.num_rpmb_units);
    2123   [ #  #  #  # ]:          0 :                 printf("  Authentication Method: %s\n", cdata->rpmbs.auth_method == 0 ? "HMAC SHA-256" : "Unknown");
    2124         [ #  # ]:          0 :                 printf("  Total Size (in 128KB units) = %d\n", cdata->rpmbs.total_size + 1);
    2125         [ #  # ]:          0 :                 printf("  Access Size (in 512B units) = %d\n", cdata->rpmbs.access_size + 1);
    2126                 :            :         } else {
    2127         [ -  + ]:         72 :                 printf("  Not Supported\n");
    2128                 :            :         }
    2129         [ -  + ]:         72 :         if (cdata->crdt[0]) {
    2130         [ #  # ]:          0 :                 printf("Command Retry Delay Time 1:  %u milliseconds\n", cdata->crdt[0] * 100);
    2131                 :            :         }
    2132         [ -  + ]:         72 :         if (cdata->crdt[1]) {
    2133         [ #  # ]:          0 :                 printf("Command Retry Delay Time 2:  %u milliseconds\n", cdata->crdt[1] * 100);
    2134                 :            :         }
    2135         [ -  + ]:         72 :         if (cdata->crdt[2]) {
    2136         [ #  # ]:          0 :                 printf("Command Retry Delay Time 3:  %u milliseconds\n", cdata->crdt[2] * 100);
    2137                 :            :         }
    2138                 :         72 :         printf("\n");
    2139                 :            : 
    2140         [ -  + ]:         72 :         printf("Firmware Slot Information\n");
    2141         [ -  + ]:         72 :         printf("=========================\n");
    2142   [ -  +  -  + ]:         72 :         if (g_hex_dump) {
    2143                 :          0 :                 hex_dump(&firmware_page, sizeof(firmware_page));
    2144                 :          0 :                 printf("\n");
    2145                 :            :         }
    2146         [ -  + ]:         72 :         printf("Active slot:                 %u\n", firmware_page.afi.active_slot);
    2147         [ -  + ]:         72 :         if (firmware_page.afi.next_reset_slot) {
    2148         [ #  # ]:          0 :                 printf("Next controller reset slot:  %u\n", firmware_page.afi.next_reset_slot);
    2149                 :            :         }
    2150         [ +  + ]:        576 :         for (i = 0; i < 7; i++) {
    2151         [ +  + ]:        504 :                 if (!spdk_mem_all_zero(firmware_page.revision[i], sizeof(firmware_page.revision[i]))) {
    2152         [ -  + ]:         60 :                         printf("Slot %u Firmware Revision:    ", i + 1);
    2153                 :         60 :                         print_ascii_string(firmware_page.revision[i], sizeof(firmware_page.revision[i]));
    2154                 :         60 :                         printf("\n");
    2155                 :            :                 }
    2156                 :            :         }
    2157                 :         72 :         printf("\n");
    2158                 :            : 
    2159         [ +  + ]:         72 :         if (g_ana_log_page) {
    2160         [ -  + ]:          4 :                 printf("Asymmetric Namespace Access\n");
    2161         [ -  + ]:          4 :                 printf("===========================\n");
    2162   [ -  +  -  + ]:          4 :                 if (g_hex_dump) {
    2163                 :          0 :                         hex_dump(g_ana_log_page, g_ana_log_page_size);
    2164                 :          0 :                         printf("\n");
    2165                 :            :                 }
    2166                 :            : 
    2167         [ -  + ]:          4 :                 printf("Change Count                    : %" PRIx64 "\n", g_ana_log_page->change_count);
    2168         [ -  + ]:          4 :                 printf("Number of ANA Group Descriptors : %u\n", g_ana_log_page->num_ana_group_desc);
    2169                 :            : 
    2170                 :          4 :                 copied_desc = g_copied_ana_desc;
    2171                 :          4 :                 orig_desc = (uint8_t *)g_ana_log_page + sizeof(struct spdk_nvme_ana_page);
    2172                 :          4 :                 copy_len = g_ana_log_page_size - sizeof(struct spdk_nvme_ana_page);
    2173                 :            : 
    2174         [ +  + ]:          8 :                 for (i = 0; i < g_ana_log_page->num_ana_group_desc; i++) {
    2175   [ -  +  -  + ]:          4 :                         memcpy(copied_desc, orig_desc, copy_len);
    2176                 :            : 
    2177         [ -  + ]:          4 :                         printf("ANA Group Descriptor            : %u\n", i);
    2178         [ -  + ]:          4 :                         printf("  ANA Group ID                  : %u\n", copied_desc->ana_group_id);
    2179         [ -  + ]:          4 :                         printf("  Number of NSID Values         : %u\n", copied_desc->num_of_nsid);
    2180         [ -  + ]:          4 :                         printf("  Change Count                  : %" PRIx64 "\n", copied_desc->change_count);
    2181         [ -  + ]:          4 :                         printf("  ANA State                     : %u\n", copied_desc->ana_state);
    2182         [ +  + ]:          8 :                         for (j = 0; j < copied_desc->num_of_nsid; j++) {
    2183         [ -  + ]:          4 :                                 printf("  Namespace Identifier          : %u\n", copied_desc->nsid[j]);
    2184                 :            :                         }
    2185                 :            : 
    2186                 :          4 :                         desc_size = sizeof(struct spdk_nvme_ana_group_descriptor) +
    2187                 :          4 :                                     copied_desc->num_of_nsid * sizeof(uint32_t);
    2188                 :          4 :                         orig_desc += desc_size;
    2189                 :          4 :                         copy_len -= desc_size;
    2190                 :            :                 }
    2191                 :          4 :                 free(g_ana_log_page);
    2192                 :          4 :                 free(g_copied_ana_desc);
    2193                 :            :         }
    2194                 :            : 
    2195                 :         72 :         printf("\n");
    2196                 :            : 
    2197         [ +  + ]:         72 :         if (cdata->lpa.celp) {
    2198         [ -  + ]:         64 :                 printf("Commands Supported and Effects\n");
    2199         [ -  + ]:         64 :                 printf("==============================\n");
    2200                 :            : 
    2201   [ -  +  -  + ]:         64 :                 if (g_hex_dump) {
    2202                 :          0 :                         hex_dump(&cmd_effects_log_page, sizeof(cmd_effects_log_page));
    2203                 :          0 :                         printf("\n");
    2204                 :            :                 }
    2205                 :            : 
    2206         [ -  + ]:         64 :                 printf("Admin Commands\n");
    2207         [ -  + ]:         64 :                 printf("--------------\n");
    2208         [ +  + ]:      16448 :                 for (i = 0; i < SPDK_COUNTOF(cmd_effects_log_page.admin_cmds_supported); i++) {
    2209                 :      16384 :                         struct spdk_nvme_cmds_and_effect_entry *cmd = &cmd_effects_log_page.admin_cmds_supported[i];
    2210         [ +  + ]:      16384 :                         if (cmd->csupp) {
    2211         [ -  + ]:       4580 :                                 printf("%30s (%02Xh): Supported %s%s%s%s%s\n",
    2212                 :            :                                        admin_opc_name(i), i,
    2213         [ +  + ]:        916 :                                        cmd->lbcc ? "LBA-Change " : "",
    2214         [ +  + ]:        916 :                                        cmd->ncc ? "NS-Cap-Change " : "",
    2215         [ +  + ]:        916 :                                        cmd->nic ? "NS-Inventory-Change " : "",
    2216         [ +  + ]:        916 :                                        cmd->ccc ? "Ctrlr-Cap-Change " : "",
    2217   [ +  +  +  +  :        916 :                                        cmd->cse == 0 ? "" : cmd->cse == 1 ? "Per-NS-Exclusive" : cmd->cse == 2 ? "All-NS-Exclusive" : "");
                   +  - ]
    2218                 :            :                         }
    2219                 :            :                 }
    2220                 :            : 
    2221         [ -  + ]:         64 :                 printf("I/O Commands\n");
    2222         [ -  + ]:         64 :                 printf("------------\n");
    2223         [ +  + ]:      16448 :                 for (i = 0; i < SPDK_COUNTOF(cmd_effects_log_page.io_cmds_supported); i++) {
    2224                 :      16384 :                         struct spdk_nvme_cmds_and_effect_entry *cmd = &cmd_effects_log_page.io_cmds_supported[i];
    2225         [ +  + ]:      16384 :                         if (cmd->csupp) {
    2226         [ -  + ]:       2800 :                                 printf("%30s (%02Xh): Supported %s%s%s%s%s\n",
    2227                 :            :                                        io_opc_name(i), i,
    2228         [ +  + ]:        560 :                                        cmd->lbcc ? "LBA-Change " : "",
    2229         [ -  + ]:        560 :                                        cmd->ncc ? "NS-Cap-Change " : "",
    2230         [ -  + ]:        560 :                                        cmd->nic ? "NS-Inventory-Change " : "",
    2231         [ -  + ]:        560 :                                        cmd->ccc ? "Ctrlr-Cap-Change " : "",
    2232   [ -  +  -  -  :        560 :                                        cmd->cse == 0 ? "" : cmd->cse == 1 ? "Per-NS-Exclusive" : cmd->cse == 2 ? "All-NS-Exclusive" : "");
                   -  - ]
    2233                 :            :                         }
    2234                 :            :                 }
    2235                 :         64 :                 printf("\n");
    2236                 :            :         }
    2237                 :            : 
    2238         [ -  + ]:         72 :         printf("Error Log\n");
    2239         [ -  + ]:         72 :         printf("=========\n");
    2240         [ +  + ]:       2808 :         for (i = 0; i <= cdata->elpe; i++) {
    2241                 :       2736 :                 error_entry = &error_page[i];
    2242         [ +  + ]:       2736 :                 if (error_entry->error_count == 0) {
    2243                 :       2404 :                         continue;
    2244                 :            :                 }
    2245         [ +  + ]:        332 :                 if (i != 0) {
    2246         [ -  + ]:        322 :                         printf("-----------\n");
    2247                 :            :                 }
    2248                 :            : 
    2249         [ -  + ]:        332 :                 printf("Entry: %u\n", i);
    2250         [ -  + ]:        332 :                 printf("Error Count:            0x%"PRIx64"\n", error_entry->error_count);
    2251         [ -  + ]:        332 :                 printf("Submission Queue Id:    0x%x\n", error_entry->sqid);
    2252         [ -  + ]:        332 :                 printf("Command Id:             0x%x\n", error_entry->cid);
    2253         [ -  + ]:        332 :                 printf("Phase Bit:              %x\n", error_entry->status.p);
    2254         [ -  + ]:        332 :                 printf("Status Code:            0x%x\n", error_entry->status.sc);
    2255         [ -  + ]:        332 :                 printf("Status Code Type:       0x%x\n", error_entry->status.sct);
    2256         [ -  + ]:        332 :                 printf("Do Not Retry:           %x\n", error_entry->status.dnr);
    2257         [ -  + ]:        332 :                 printf("Error Location:         0x%x\n", error_entry->error_location);
    2258         [ -  + ]:        332 :                 printf("LBA:                    0x%"PRIx64"\n", error_entry->lba);
    2259         [ -  + ]:        332 :                 printf("Namespace:              0x%x\n", error_entry->nsid);
    2260         [ -  + ]:        332 :                 printf("Vendor Log Page:        0x%x\n", error_entry->vendor_specific);
    2261                 :            : 
    2262                 :            :         }
    2263                 :         72 :         printf("\n");
    2264                 :            : 
    2265   [ +  +  +  + ]:         72 :         if (features[SPDK_NVME_FEAT_ARBITRATION].valid) {
    2266                 :         60 :                 uint32_t arb = features[SPDK_NVME_FEAT_ARBITRATION].result;
    2267                 :            :                 unsigned ab, lpw, mpw, hpw;
    2268                 :            : 
    2269                 :         60 :                 ab = arb & 0x7;
    2270                 :         60 :                 lpw = ((arb >> 8) & 0xFF) + 1;
    2271                 :         60 :                 mpw = ((arb >> 16) & 0xFF) + 1;
    2272                 :         60 :                 hpw = ((arb >> 24) & 0xFF) + 1;
    2273                 :            : 
    2274         [ -  + ]:         60 :                 printf("Arbitration\n");
    2275         [ -  + ]:         60 :                 printf("===========\n");
    2276         [ -  + ]:         60 :                 printf("Arbitration Burst:           ");
    2277         [ +  + ]:         60 :                 if (ab == 0x7) {
    2278         [ -  + ]:         44 :                         printf("no limit\n");
    2279                 :            :                 } else {
    2280   [ -  +  -  + ]:         16 :                         printf("%u\n", 1u << ab);
    2281                 :            :                 }
    2282                 :            : 
    2283         [ +  + ]:         60 :                 if (cap.bits.ams & SPDK_NVME_CAP_AMS_WRR) {
    2284         [ -  + ]:          6 :                         printf("Low Priority Weight:         %u\n", lpw);
    2285         [ -  + ]:          6 :                         printf("Medium Priority Weight:      %u\n", mpw);
    2286         [ -  + ]:          6 :                         printf("High Priority Weight:        %u\n", hpw);
    2287                 :            :                 }
    2288                 :         60 :                 printf("\n");
    2289                 :            :         }
    2290                 :            : 
    2291   [ +  +  +  + ]:         72 :         if (features[SPDK_NVME_FEAT_POWER_MANAGEMENT].valid) {
    2292                 :         60 :                 unsigned ps = features[SPDK_NVME_FEAT_POWER_MANAGEMENT].result & 0x1F;
    2293         [ -  + ]:         60 :                 printf("Power Management\n");
    2294         [ -  + ]:         60 :                 printf("================\n");
    2295         [ -  + ]:         60 :                 printf("Number of Power States:          %u\n", cdata->npss + 1);
    2296         [ -  + ]:         60 :                 printf("Current Power State:             Power State #%u\n", ps);
    2297         [ +  + ]:        120 :                 for (i = 0; i <= cdata->npss; i++) {
    2298                 :         60 :                         const struct spdk_nvme_power_state psd = cdata->psd[i];
    2299         [ -  + ]:         60 :                         printf("Power State #%u:\n", i);
    2300         [ -  + ]:         60 :                         if (psd.mps) {
    2301                 :            :                                 /* MP scale is 0.0001 W */
    2302                 :          0 :                                 printf("  Max Power:                    %u.%04u W\n",
    2303                 :          0 :                                        psd.mp / 10000,
    2304         [ #  # ]:          0 :                                        psd.mp % 10000);
    2305                 :            :                         } else {
    2306                 :            :                                 /* MP scale is 0.01 W */
    2307                 :         60 :                                 printf("  Max Power:                    %3u.%02u W\n",
    2308                 :         60 :                                        psd.mp / 100,
    2309         [ -  + ]:         60 :                                        psd.mp % 100);
    2310                 :            :                         }
    2311         [ -  + ]:         60 :                         printf("  Non-Operational State:         %s\n",
    2312         [ -  + ]:         60 :                                psd.nops ? "Non-Operation" : "Operational");
    2313         [ -  + ]:         60 :                         printf("  Entry Latency:                 ");
    2314         [ +  + ]:         60 :                         if (psd.enlat) {
    2315         [ -  + ]:         44 :                                 printf("%u microseconds\n", psd.enlat);
    2316                 :            :                         } else {
    2317         [ -  + ]:         16 :                                 printf("Not Reported\n");
    2318                 :            :                         }
    2319         [ -  + ]:         60 :                         printf("  Exit Latency:                  ");
    2320         [ +  + ]:         60 :                         if (psd.exlat) {
    2321         [ -  + ]:         44 :                                 printf("%u microseconds\n", psd.exlat);
    2322                 :            :                         } else {
    2323         [ -  + ]:         16 :                                 printf("Not Reported\n");
    2324                 :            :                         }
    2325         [ -  + ]:         60 :                         printf("  Relative Read Throughput:      %u\n", psd.rrt);
    2326         [ -  + ]:         60 :                         printf("  Relative Read Latency:         %u\n", psd.rrl);
    2327         [ -  + ]:         60 :                         printf("  Relative Write Throughput:     %u\n", psd.rwt);
    2328         [ -  + ]:         60 :                         printf("  Relative Write Latency:        %u\n", psd.rwl);
    2329         [ -  + ]:         60 :                         printf("  Idle Power:                    ");
    2330      [ -  -  + ]:         60 :                         switch (psd.ips) {
    2331                 :          0 :                         case 1:
    2332                 :            :                                 /* Idle Power scale is 0.0001 W */
    2333         [ #  # ]:          0 :                                 printf("%u.%04u W\n", psd.idlp / 10000, psd.idlp % 10000);
    2334                 :          0 :                                 break;
    2335                 :          0 :                         case 2:
    2336                 :            :                                 /* Idle Power scale is 0.01 W */
    2337         [ #  # ]:          0 :                                 printf("%u.%02u W\n", psd.idlp / 100, psd.idlp % 100);
    2338                 :          0 :                                 break;
    2339                 :         60 :                         default:
    2340         [ -  + ]:         60 :                                 printf(" Not Reported\n");
    2341                 :            :                         }
    2342         [ -  + ]:         60 :                         printf("  Active Power:                  ");
    2343      [ -  -  + ]:         60 :                         switch (psd.aps) {
    2344                 :          0 :                         case 1:
    2345                 :            :                                 /* Active Power scale is 0.0001 W */
    2346         [ #  # ]:          0 :                                 printf("%u.%04u W\n", psd.actp / 10000, psd.actp % 10000);
    2347                 :          0 :                                 break;
    2348                 :          0 :                         case 2:
    2349                 :            :                                 /* Active Power scale is 0.01 W */
    2350         [ #  # ]:          0 :                                 printf("%u.%02u W\n", psd.actp / 100, psd.actp % 100);
    2351                 :          0 :                                 break;
    2352                 :         60 :                         default:
    2353         [ -  + ]:         60 :                                 printf(" Not Reported\n");
    2354                 :            :                         }
    2355                 :            :                 }
    2356         [ -  + ]:         60 :                 printf("Non-Operational Permissive Mode: %s\n",
    2357         [ -  + ]:         60 :                        cdata->ctratt.bits.non_operational_power_state_permissive_mode ? "Supported" : "Not Supported");
    2358                 :         60 :                 printf("\n");
    2359                 :            :         }
    2360                 :            : 
    2361   [ +  +  +  + ]:         72 :         if (features[SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD].valid) {
    2362         [ -  + ]:         60 :                 printf("Health Information\n");
    2363         [ -  + ]:         60 :                 printf("==================\n");
    2364                 :            : 
    2365   [ -  +  -  + ]:         60 :                 if (g_hex_dump) {
    2366                 :          0 :                         hex_dump(&health_page, sizeof(health_page));
    2367                 :          0 :                         printf("\n");
    2368                 :            :                 }
    2369                 :            : 
    2370         [ -  + ]:         60 :                 printf("Critical Warnings:\n");
    2371         [ -  + ]:         60 :                 printf("  Available Spare Space:     %s\n",
    2372         [ -  + ]:         60 :                        health_page.critical_warning.bits.available_spare ? "WARNING" : "OK");
    2373         [ -  + ]:         60 :                 printf("  Temperature:               %s\n",
    2374         [ -  + ]:         60 :                        health_page.critical_warning.bits.temperature ? "WARNING" : "OK");
    2375         [ -  + ]:         60 :                 printf("  Device Reliability:        %s\n",
    2376         [ -  + ]:         60 :                        health_page.critical_warning.bits.device_reliability ? "WARNING" : "OK");
    2377         [ -  + ]:         60 :                 printf("  Read Only:                 %s\n",
    2378         [ -  + ]:         60 :                        health_page.critical_warning.bits.read_only ? "Yes" : "No");
    2379         [ -  + ]:         60 :                 printf("  Volatile Memory Backup:    %s\n",
    2380         [ -  + ]:         60 :                        health_page.critical_warning.bits.volatile_memory_backup ? "WARNING" : "OK");
    2381                 :         60 :                 printf("Current Temperature:         %u Kelvin (%d Celsius)\n",
    2382                 :         60 :                        health_page.temperature,
    2383         [ -  + ]:         60 :                        (int)health_page.temperature - 273);
    2384                 :         60 :                 printf("Temperature Threshold:       %u Kelvin (%d Celsius)\n",
    2385                 :            :                        features[SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD].result,
    2386         [ -  + ]:         60 :                        (int)features[SPDK_NVME_FEAT_TEMPERATURE_THRESHOLD].result - 273);
    2387         [ -  + ]:         60 :                 printf("Available Spare:             %u%%\n", health_page.available_spare);
    2388         [ -  + ]:         60 :                 printf("Available Spare Threshold:   %u%%\n", health_page.available_spare_threshold);
    2389         [ -  + ]:         60 :                 printf("Life Percentage Used:        %u%%\n", health_page.percentage_used);
    2390         [ -  + ]:         60 :                 printf("Data Units Read:             ");
    2391                 :         60 :                 print_uint128_dec(health_page.data_units_read);
    2392                 :         60 :                 printf("\n");
    2393         [ -  + ]:         60 :                 printf("Data Units Written:          ");
    2394                 :         60 :                 print_uint128_dec(health_page.data_units_written);
    2395                 :         60 :                 printf("\n");
    2396         [ -  + ]:         60 :                 printf("Host Read Commands:          ");
    2397                 :         60 :                 print_uint128_dec(health_page.host_read_commands);
    2398                 :         60 :                 printf("\n");
    2399         [ -  + ]:         60 :                 printf("Host Write Commands:         ");
    2400                 :         60 :                 print_uint128_dec(health_page.host_write_commands);
    2401                 :         60 :                 printf("\n");
    2402         [ -  + ]:         60 :                 printf("Controller Busy Time:        ");
    2403                 :         60 :                 print_uint128_dec(health_page.controller_busy_time);
    2404         [ -  + ]:         60 :                 printf(" minutes\n");
    2405         [ -  + ]:         60 :                 printf("Power Cycles:                ");
    2406                 :         60 :                 print_uint128_dec(health_page.power_cycles);
    2407                 :         60 :                 printf("\n");
    2408         [ -  + ]:         60 :                 printf("Power On Hours:              ");
    2409                 :         60 :                 print_uint128_dec(health_page.power_on_hours);
    2410         [ -  + ]:         60 :                 printf(" hours\n");
    2411         [ -  + ]:         60 :                 printf("Unsafe Shutdowns:            ");
    2412                 :         60 :                 print_uint128_dec(health_page.unsafe_shutdowns);
    2413                 :         60 :                 printf("\n");
    2414         [ -  + ]:         60 :                 printf("Unrecoverable Media Errors:  ");
    2415                 :         60 :                 print_uint128_dec(health_page.media_errors);
    2416                 :         60 :                 printf("\n");
    2417         [ -  + ]:         60 :                 printf("Lifetime Error Log Entries:  ");
    2418                 :         60 :                 print_uint128_dec(health_page.num_error_info_log_entries);
    2419                 :         60 :                 printf("\n");
    2420         [ -  + ]:         60 :                 printf("Warning Temperature Time:    %u minutes\n", health_page.warning_temp_time);
    2421         [ -  + ]:         60 :                 printf("Critical Temperature Time:   %u minutes\n", health_page.critical_temp_time);
    2422         [ +  + ]:        540 :                 for (i = 0; i < 8; i++) {
    2423         [ -  + ]:        480 :                         if (health_page.temp_sensor[i] != 0) {
    2424                 :          0 :                                 printf("Temperature Sensor %d:        %u Kelvin (%d Celsius)\n",
    2425         [ #  # ]:          0 :                                        i + 1, health_page.temp_sensor[i],
    2426                 :          0 :                                        (int)health_page.temp_sensor[i] - 273);
    2427                 :            :                         }
    2428                 :            :                 }
    2429                 :         60 :                 printf("\n");
    2430                 :            :         }
    2431                 :            : 
    2432   [ +  +  +  + ]:         72 :         if (features[SPDK_NVME_FEAT_NUMBER_OF_QUEUES].valid) {
    2433                 :         64 :                 uint32_t result = features[SPDK_NVME_FEAT_NUMBER_OF_QUEUES].result;
    2434                 :            : 
    2435         [ -  + ]:         64 :                 printf("Number of Queues\n");
    2436         [ -  + ]:         64 :                 printf("================\n");
    2437         [ -  + ]:         64 :                 printf("Number of I/O Submission Queues:      %u\n", (result & 0xFFFF) + 1);
    2438         [ -  + ]:         64 :                 printf("Number of I/O Completion Queues:      %u\n", (result & 0xFFFF0000 >> 16) + 1);
    2439                 :         64 :                 printf("\n");
    2440                 :            :         }
    2441                 :            : 
    2442   [ -  +  -  + ]:         72 :         if (features[SPDK_OCSSD_FEAT_MEDIA_FEEDBACK].valid) {
    2443                 :          0 :                 uint32_t result = features[SPDK_OCSSD_FEAT_MEDIA_FEEDBACK].result;
    2444                 :            : 
    2445         [ #  # ]:          0 :                 printf("OCSSD Media Feedback\n");
    2446         [ #  # ]:          0 :                 printf("=======================\n");
    2447         [ #  # ]:          0 :                 printf("High ECC status:                %u\n", (result & 0x1));
    2448         [ #  # ]:          0 :                 printf("Vector High ECC status:         %u\n", (result & 0x2 >> 1));
    2449                 :          0 :                 printf("\n");
    2450                 :            :         }
    2451                 :            : 
    2452         [ -  + ]:         72 :         if (cdata->hctma.bits.supported) {
    2453         [ #  # ]:          0 :                 printf("Host Controlled Thermal Management\n");
    2454         [ #  # ]:          0 :                 printf("==================================\n");
    2455         [ #  # ]:          0 :                 printf("Minimum Thermal Management Temperature:  ");
    2456         [ #  # ]:          0 :                 if (cdata->mntmt) {
    2457         [ #  # ]:          0 :                         printf("%u Kelvin (%d Celsius)\n", cdata->mntmt, (int)cdata->mntmt - 273);
    2458                 :            :                 } else {
    2459         [ #  # ]:          0 :                         printf("Not Reported\n");
    2460                 :            :                 }
    2461         [ #  # ]:          0 :                 printf("Maximum Thermal Management Temperature:   ");
    2462         [ #  # ]:          0 :                 if (cdata->mxtmt) {
    2463         [ #  # ]:          0 :                         printf("%u Kelvin (%d Celsius)\n", cdata->mxtmt, (int)cdata->mxtmt - 273);
    2464                 :            :                 } else {
    2465         [ #  # ]:          0 :                         printf("Not Reported\n");
    2466                 :            :                 }
    2467                 :          0 :                 printf("\n");
    2468                 :            :         }
    2469                 :            : 
    2470         [ +  + ]:         72 :         if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_INTEL_LOG_SMART)) {
    2471                 :          6 :                 size_t i = 0;
    2472                 :            : 
    2473         [ -  + ]:          6 :                 printf("Intel Health Information\n");
    2474         [ -  + ]:          6 :                 printf("==================\n");
    2475         [ #  # ]:          6 :                 for (i = 0;
    2476         [ +  + ]:         84 :                      i < SPDK_COUNTOF(intel_smart_page.attributes); i++) {
    2477         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_PROGRAM_FAIL_COUNT) {
    2478         [ -  + ]:          6 :                                 printf("Program Fail Count:\n");
    2479                 :          6 :                                 printf("  Normalized Value : %d\n",
    2480         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2481         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2482                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2483                 :          6 :                                 printf("\n");
    2484                 :            :                         }
    2485         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_ERASE_FAIL_COUNT) {
    2486         [ -  + ]:          6 :                                 printf("Erase Fail Count:\n");
    2487                 :          6 :                                 printf("  Normalized Value : %d\n",
    2488         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2489         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2490                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2491                 :          6 :                                 printf("\n");
    2492                 :            :                         }
    2493         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_WEAR_LEVELING_COUNT) {
    2494         [ -  + ]:          6 :                                 printf("Wear Leveling Count:\n");
    2495                 :          6 :                                 printf("  Normalized Value : %d\n",
    2496         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2497         [ -  + ]:          6 :                                 printf("  Current Raw Value:\n");
    2498         [ -  + ]:          6 :                                 printf("  Min: ");
    2499                 :          6 :                                 print_uint_var_dec(&intel_smart_page.attributes[i].raw_value[0], 2);
    2500                 :          6 :                                 printf("\n");
    2501         [ -  + ]:          6 :                                 printf("  Max: ");
    2502                 :          6 :                                 print_uint_var_dec(&intel_smart_page.attributes[i].raw_value[2], 2);
    2503                 :          6 :                                 printf("\n");
    2504         [ -  + ]:          6 :                                 printf("  Avg: ");
    2505                 :          6 :                                 print_uint_var_dec(&intel_smart_page.attributes[i].raw_value[4], 2);
    2506                 :          6 :                                 printf("\n");
    2507                 :            :                         }
    2508         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_E2E_ERROR_COUNT) {
    2509         [ -  + ]:          6 :                                 printf("End to End Error Detection Count:\n");
    2510                 :          6 :                                 printf("  Normalized Value : %d\n",
    2511         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2512         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2513                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2514                 :          6 :                                 printf("\n");
    2515                 :            :                         }
    2516         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_CRC_ERROR_COUNT) {
    2517         [ -  + ]:          6 :                                 printf("CRC Error Count:\n");
    2518                 :          6 :                                 printf("  Normalized Value : %d\n",
    2519         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2520         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2521                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2522                 :          6 :                                 printf("\n");
    2523                 :            :                         }
    2524         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_MEDIA_WEAR) {
    2525         [ -  + ]:          6 :                                 printf("Timed Workload, Media Wear:\n");
    2526                 :          6 :                                 printf("  Normalized Value : %d\n",
    2527         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2528         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2529                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2530                 :          6 :                                 printf("\n");
    2531                 :            :                         }
    2532         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_HOST_READ_PERCENTAGE) {
    2533         [ -  + ]:          6 :                                 printf("Timed Workload, Host Read/Write Ratio:\n");
    2534                 :          6 :                                 printf("  Normalized Value : %d\n",
    2535         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2536         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2537                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2538         [ -  + ]:          6 :                                 printf("%%");
    2539                 :          6 :                                 printf("\n");
    2540                 :            :                         }
    2541         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_TIMER) {
    2542         [ -  + ]:          6 :                                 printf("Timed Workload, Timer:\n");
    2543                 :          6 :                                 printf("  Normalized Value : %d\n",
    2544         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2545         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2546                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2547                 :          6 :                                 printf("\n");
    2548                 :            :                         }
    2549         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_THERMAL_THROTTLE_STATUS) {
    2550         [ -  + ]:          6 :                                 printf("Thermal Throttle Status:\n");
    2551                 :          6 :                                 printf("  Normalized Value : %d\n",
    2552         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2553         [ -  + ]:          6 :                                 printf("  Current Raw Value:\n");
    2554         [ -  + ]:          6 :                                 printf("  Percentage: %d%%\n", intel_smart_page.attributes[i].raw_value[0]);
    2555         [ -  + ]:          6 :                                 printf("  Throttling Event Count: ");
    2556                 :          6 :                                 print_uint_var_dec(&intel_smart_page.attributes[i].raw_value[1], 4);
    2557                 :          6 :                                 printf("\n");
    2558                 :            :                         }
    2559         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_RETRY_BUFFER_OVERFLOW_COUNTER) {
    2560         [ -  + ]:          6 :                                 printf("Retry Buffer Overflow Counter:\n");
    2561                 :          6 :                                 printf("  Normalized Value : %d\n",
    2562         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2563         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2564                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2565                 :          6 :                                 printf("\n");
    2566                 :            :                         }
    2567         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_PLL_LOCK_LOSS_COUNT) {
    2568         [ -  + ]:          6 :                                 printf("PLL Lock Loss Count:\n");
    2569                 :          6 :                                 printf("  Normalized Value : %d\n",
    2570         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2571         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2572                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2573                 :          6 :                                 printf("\n");
    2574                 :            :                         }
    2575         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_NAND_BYTES_WRITTEN) {
    2576         [ -  + ]:          6 :                                 printf("NAND Bytes Written:\n");
    2577                 :          6 :                                 printf("  Normalized Value : %d\n",
    2578         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2579         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2580                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2581                 :          6 :                                 printf("\n");
    2582                 :            :                         }
    2583         [ +  + ]:         78 :                         if (intel_smart_page.attributes[i].code == SPDK_NVME_INTEL_SMART_HOST_BYTES_WRITTEN) {
    2584         [ -  + ]:          6 :                                 printf("Host Bytes Written:\n");
    2585                 :          6 :                                 printf("  Normalized Value : %d\n",
    2586         [ -  + ]:          6 :                                        intel_smart_page.attributes[i].normalized_value);
    2587         [ -  + ]:          6 :                                 printf("  Current Raw Value: ");
    2588                 :          6 :                                 print_uint_var_dec(intel_smart_page.attributes[i].raw_value, 6);
    2589                 :          6 :                                 printf("\n");
    2590                 :            :                         }
    2591                 :            :                 }
    2592                 :          6 :                 printf("\n");
    2593                 :            :         }
    2594                 :            : 
    2595         [ +  + ]:         72 :         if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_INTEL_LOG_TEMPERATURE)) {
    2596         [ -  + ]:          6 :                 printf("Intel Temperature Information\n");
    2597         [ -  + ]:          6 :                 printf("==================\n");
    2598         [ -  + ]:          6 :                 printf("Current Temperature: %" PRIu64 "\n", intel_temperature_page.current_temperature);
    2599         [ -  + ]:          6 :                 printf("Overtemp shutdown Flag for last critical component temperature: %" PRIu64 "\n",
    2600                 :            :                        intel_temperature_page.shutdown_flag_last);
    2601         [ -  + ]:          6 :                 printf("Overtemp shutdown Flag for life critical component temperature: %" PRIu64 "\n",
    2602                 :            :                        intel_temperature_page.shutdown_flag_life);
    2603         [ -  + ]:          6 :                 printf("Highest temperature: %" PRIu64 "\n", intel_temperature_page.highest_temperature);
    2604         [ -  + ]:          6 :                 printf("Lowest temperature: %" PRIu64 "\n", intel_temperature_page.lowest_temperature);
    2605         [ -  + ]:          6 :                 printf("Specified Maximum Operating Temperature: %" PRIu64 "\n",
    2606                 :            :                        intel_temperature_page.specified_max_op_temperature);
    2607         [ -  + ]:          6 :                 printf("Specified Minimum Operating Temperature: %" PRIu64 "\n",
    2608                 :            :                        intel_temperature_page.specified_min_op_temperature);
    2609         [ -  + ]:          6 :                 printf("Estimated offset: %" PRId64 "\n", (int64_t)intel_temperature_page.estimated_offset);
    2610                 :          6 :                 printf("\n");
    2611                 :          6 :                 printf("\n");
    2612                 :            : 
    2613                 :            :         }
    2614                 :            : 
    2615         [ +  + ]:         72 :         if (spdk_nvme_ctrlr_is_log_page_supported(ctrlr, SPDK_NVME_INTEL_MARKETING_DESCRIPTION)) {
    2616         [ -  + ]:          6 :                 printf("Intel Marketing Information\n");
    2617         [ -  + ]:          6 :                 printf("==================\n");
    2618         [ -  + ]:          6 :                 snprintf(str, sizeof(intel_md_page.marketing_product), "%s", intel_md_page.marketing_product);
    2619         [ -  + ]:          6 :                 printf("Marketing Product Information:             %s\n", str);
    2620                 :          6 :                 printf("\n");
    2621                 :          6 :                 printf("\n");
    2622                 :            :         }
    2623                 :            : 
    2624         [ +  + ]:         72 :         if (spdk_nvme_zns_ctrlr_get_data(ctrlr)) {
    2625         [ -  + ]:         48 :                 printf("ZNS Specific Controller Data\n");
    2626         [ -  + ]:         48 :                 printf("============================\n");
    2627                 :         48 :                 printf("Zone Append Size Limit:      %u\n",
    2628         [ -  + ]:         48 :                        spdk_nvme_zns_ctrlr_get_data(ctrlr)->zasl);
    2629                 :         48 :                 printf("\n");
    2630                 :         48 :                 printf("\n");
    2631                 :            :         }
    2632                 :            : 
    2633         [ -  + ]:         72 :         printf("Active Namespaces\n");
    2634         [ -  + ]:         72 :         printf("=================\n");
    2635         [ +  + ]:         78 :         for (nsid = spdk_nvme_ctrlr_get_first_active_ns(ctrlr);
    2636         [ +  + ]:        138 :              nsid != 0; nsid = spdk_nvme_ctrlr_get_next_active_ns(ctrlr, nsid)) {
    2637                 :         72 :                 get_ns_features(ctrlr, nsid);
    2638                 :         72 :                 print_namespace(ctrlr, spdk_nvme_ctrlr_get_ns(ctrlr, nsid));
    2639                 :            :         }
    2640                 :            : 
    2641         [ +  + ]:         72 :         if (g_discovery_page) {
    2642         [ -  + ]:          8 :                 printf("Discovery Log Page\n");
    2643         [ -  + ]:          8 :                 printf("==================\n");
    2644                 :            : 
    2645   [ -  +  -  + ]:          8 :                 if (g_hex_dump) {
    2646                 :          0 :                         hex_dump(g_discovery_page, g_discovery_page_size);
    2647                 :          0 :                         printf("\n");
    2648                 :            :                 }
    2649                 :            : 
    2650         [ -  + ]:          8 :                 printf("Generation Counter:                    %" PRIu64 "\n",
    2651                 :          8 :                        from_le64(&g_discovery_page->genctr));
    2652         [ -  + ]:          8 :                 printf("Number of Records:                     %" PRIu64 "\n",
    2653                 :          8 :                        from_le64(&g_discovery_page->numrec));
    2654         [ -  + ]:          8 :                 printf("Record Format:                         %" PRIu16 "\n",
    2655                 :          8 :                        from_le16(&g_discovery_page->recfmt));
    2656                 :          8 :                 printf("\n");
    2657                 :            : 
    2658         [ +  + ]:         24 :                 for (i = 0; i < g_discovery_page_numrec; i++) {
    2659                 :         16 :                         struct spdk_nvmf_discovery_log_page_entry *entry = &g_discovery_page->entries[i];
    2660                 :            : 
    2661         [ -  + ]:         16 :                         printf("Discovery Log Entry %u\n", i);
    2662         [ -  + ]:         16 :                         printf("----------------------\n");
    2663                 :         16 :                         printf("Transport Type:                        %u (%s)\n",
    2664         [ -  + ]:         16 :                                entry->trtype, spdk_nvme_transport_id_trtype_str(entry->trtype));
    2665                 :         16 :                         printf("Address Family:                        %u (%s)\n",
    2666         [ -  + ]:         16 :                                entry->adrfam, spdk_nvme_transport_id_adrfam_str(entry->adrfam));
    2667                 :         32 :                         printf("Subsystem Type:                        %u (%s)\n",
    2668         [ -  + ]:         16 :                                entry->subtype,
    2669         [ +  - ]:         16 :                                entry->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY ? "Referral to a discovery service" :
    2670         [ +  + ]:         24 :                                entry->subtype == SPDK_NVMF_SUBTYPE_NVME ? "NVM Subsystem" :
    2671         [ +  - ]:          8 :                                entry->subtype == SPDK_NVMF_SUBTYPE_DISCOVERY_CURRENT ? "Current Discovery Subsystem" :
    2672                 :            :                                "Unknown");
    2673         [ -  + ]:         16 :                         printf("Entry Flags:\n");
    2674                 :         16 :                         printf("  Duplicate Returned Information:                  %u\n",
    2675         [ -  + ]:         16 :                                !!(entry->eflags & SPDK_NVMF_DISCOVERY_LOG_EFLAGS_DUPRETINFO));
    2676                 :         16 :                         printf("  Explicit Persistent Connection Support for Discovery: %u\n",
    2677         [ -  + ]:         16 :                                !!(entry->eflags & SPDK_NVMF_DISCOVERY_LOG_EFLAGS_EPCSD));
    2678         [ -  + ]:         16 :                         printf("Transport Requirements:\n");
    2679         [ -  + ]:         16 :                         printf("  Secure Channel:                      %s\n",
    2680         [ +  + ]:         16 :                                entry->treq.secure_channel == SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_SPECIFIED ? "Not Specified" :
    2681         [ +  - ]:         16 :                                entry->treq.secure_channel == SPDK_NVMF_TREQ_SECURE_CHANNEL_REQUIRED ? "Required" :
    2682         [ +  - ]:          8 :                                entry->treq.secure_channel == SPDK_NVMF_TREQ_SECURE_CHANNEL_NOT_REQUIRED ? "Not Required" :
    2683                 :            :                                "Reserved");
    2684         [ -  + ]:         16 :                         printf("Port ID:                               %" PRIu16 " (0x%04" PRIx16 ")\n",
    2685                 :         16 :                                from_le16(&entry->portid), from_le16(&entry->portid));
    2686         [ -  + ]:         16 :                         printf("Controller ID:                         %" PRIu16 " (0x%04" PRIx16 ")\n",
    2687                 :         16 :                                from_le16(&entry->cntlid), from_le16(&entry->cntlid));
    2688         [ -  + ]:         16 :                         printf("Admin Max SQ Size:                     %" PRIu16 "\n",
    2689                 :         16 :                                from_le16(&entry->asqsz));
    2690         [ -  + ]:         16 :                         snprintf(str, sizeof(entry->trsvcid) + 1, "%s", entry->trsvcid);
    2691         [ -  + ]:         16 :                         printf("Transport Service Identifier:          %s\n", str);
    2692         [ -  + ]:         16 :                         snprintf(str, sizeof(entry->subnqn) + 1, "%s", entry->subnqn);
    2693         [ -  + ]:         16 :                         printf("NVM Subsystem Qualified Name:          %s\n", str);
    2694         [ -  + ]:         16 :                         snprintf(str, sizeof(entry->traddr) + 1, "%s", entry->traddr);
    2695         [ -  + ]:         16 :                         printf("Transport Address:                     %s\n", str);
    2696                 :            : 
    2697         [ +  + ]:         16 :                         if (entry->trtype == SPDK_NVMF_TRTYPE_RDMA) {
    2698         [ -  + ]:          4 :                                 printf("Transport Specific Address Subtype - RDMA\n");
    2699                 :          8 :                                 printf("  RDMA QP Service Type:                %u (%s)\n",
    2700         [ -  + ]:          4 :                                        entry->tsas.rdma.rdma_qptype,
    2701         [ -  + ]:          4 :                                        entry->tsas.rdma.rdma_qptype == SPDK_NVMF_RDMA_QPTYPE_RELIABLE_CONNECTED ? "Reliable Connected" :
    2702         [ #  # ]:          0 :                                        entry->tsas.rdma.rdma_qptype == SPDK_NVMF_RDMA_QPTYPE_RELIABLE_DATAGRAM ? "Reliable Datagram" :
    2703                 :            :                                        "Unknown");
    2704                 :          8 :                                 printf("  RDMA Provider Type:                  %u (%s)\n",
    2705         [ -  + ]:          4 :                                        entry->tsas.rdma.rdma_prtype,
    2706         [ -  + ]:          4 :                                        entry->tsas.rdma.rdma_prtype == SPDK_NVMF_RDMA_PRTYPE_NONE ? "No provider specified" :
    2707         [ #  # ]:          0 :                                        entry->tsas.rdma.rdma_prtype == SPDK_NVMF_RDMA_PRTYPE_IB ? "InfiniBand" :
    2708         [ #  # ]:          0 :                                        entry->tsas.rdma.rdma_prtype == SPDK_NVMF_RDMA_PRTYPE_ROCE ? "InfiniBand RoCE" :
    2709         [ #  # ]:          0 :                                        entry->tsas.rdma.rdma_prtype == SPDK_NVMF_RDMA_PRTYPE_ROCE2 ? "InfiniBand RoCE v2" :
    2710         [ #  # ]:          0 :                                        entry->tsas.rdma.rdma_prtype == SPDK_NVMF_RDMA_PRTYPE_IWARP ? "iWARP" :
    2711                 :            :                                        "Unknown");
    2712                 :          8 :                                 printf("  RDMA CM Service:                     %u (%s)\n",
    2713         [ -  + ]:          4 :                                        entry->tsas.rdma.rdma_cms,
    2714         [ +  - ]:          4 :                                        entry->tsas.rdma.rdma_cms == SPDK_NVMF_RDMA_CMS_RDMA_CM ? "RDMA_CM" :
    2715                 :            :                                        "Unknown");
    2716         [ -  + ]:          4 :                                 if (entry->adrfam == SPDK_NVMF_ADRFAM_IB) {
    2717         [ #  # ]:          0 :                                         printf("  RDMA Partition Key:                  %" PRIu32 "\n",
    2718                 :          0 :                                                from_le32(&entry->tsas.rdma.rdma_pkey));
    2719                 :            :                                 }
    2720                 :            :                         }
    2721                 :            :                 }
    2722                 :          8 :                 free(g_discovery_page);
    2723                 :          8 :                 g_discovery_page = NULL;
    2724                 :            :         }
    2725                 :            : }
    2726                 :            : 
    2727                 :            : static void
    2728                 :          0 : usage(const char *program_name)
    2729                 :            : {
    2730         [ #  # ]:          0 :         printf("%s [options]", program_name);
    2731                 :          0 :         printf("\n");
    2732         [ #  # ]:          0 :         printf("options:\n");
    2733         [ #  # ]:          0 :         printf(" -r trid    remote NVMe over Fabrics target address\n");
    2734         [ #  # ]:          0 :         printf("    Format: 'key:value [key:value] ...'\n");
    2735         [ #  # ]:          0 :         printf("    Keys:\n");
    2736         [ #  # ]:          0 :         printf("     trtype      Transport type (e.g. RDMA)\n");
    2737         [ #  # ]:          0 :         printf("     adrfam      Address family (e.g. IPv4, IPv6)\n");
    2738         [ #  # ]:          0 :         printf("     traddr      Transport address (e.g. 192.168.100.8)\n");
    2739         [ #  # ]:          0 :         printf("     trsvcid     Transport service identifier (e.g. 4420)\n");
    2740         [ #  # ]:          0 :         printf("     subnqn      Subsystem NQN (default: %s)\n", SPDK_NVMF_DISCOVERY_NQN);
    2741         [ #  # ]:          0 :         printf("     hostnqn     Host NQN\n");
    2742         [ #  # ]:          0 :         printf("    Example: -r 'trtype:RDMA adrfam:IPv4 traddr:192.168.100.8 trsvcid:4420'\n");
    2743                 :            : 
    2744                 :          0 :         spdk_log_usage(stdout, "-L");
    2745                 :            : 
    2746         [ #  # ]:          0 :         printf(" -i         shared memory group ID\n");
    2747         [ #  # ]:          0 :         printf(" -p         core number in decimal to run this application which started from 0\n");
    2748         [ #  # ]:          0 :         printf(" -d         DPDK huge memory size in MB\n");
    2749         [ #  # ]:          0 :         printf(" -g         use single file descriptor for DPDK memory segments\n");
    2750         [ #  # ]:          0 :         printf(" -v         IOVA mode ('pa' or 'va')\n");
    2751         [ #  # ]:          0 :         printf(" -x         print hex dump of raw data\n");
    2752         [ #  # ]:          0 :         printf(" -z         For NVMe Zoned Namespaces, dump the full zone report (-z) or the first N entries (-z N)\n");
    2753         [ #  # ]:          0 :         printf(" -V         enumerate VMD\n");
    2754         [ #  # ]:          0 :         printf(" -S         socket implementation, e.g. -S uring (default is posix)\n");
    2755         [ #  # ]:          0 :         printf(" -H         show this usage\n");
    2756                 :          0 : }
    2757                 :            : 
    2758                 :            : static int
    2759                 :         68 : parse_args(int argc, char **argv)
    2760                 :            : {
    2761                 :            :         int op, rc;
    2762                 :            :         char *hostnqn;
    2763                 :            : 
    2764                 :         68 :         spdk_nvme_trid_populate_transport(&g_trid, SPDK_NVME_TRANSPORT_PCIE);
    2765                 :         68 :         snprintf(g_trid.subnqn, sizeof(g_trid.subnqn), "%s", SPDK_NVMF_DISCOVERY_NQN);
    2766                 :            : 
    2767   [ +  +  +  + ]:        166 :         while ((op = getopt(argc, argv, "d:gi:op:r:v:xz::HL:S:V")) != -1) {
    2768   [ -  +  +  -  :         98 :                 switch (op) {
          -  +  -  -  -  
             +  -  -  -  
                      - ]
    2769                 :          0 :                 case 'd':
    2770                 :          0 :                         g_dpdk_mem = spdk_strtol(optarg, 10);
    2771         [ #  # ]:          0 :                         if (g_dpdk_mem < 0) {
    2772         [ #  # ]:          0 :                                 fprintf(stderr, "Invalid DPDK memory size\n");
    2773                 :          0 :                                 return g_dpdk_mem;
    2774                 :            :                         }
    2775                 :          0 :                         break;
    2776                 :          2 :                 case 'g':
    2777                 :          2 :                         g_dpdk_mem_single_seg = true;
    2778                 :          2 :                         break;
    2779                 :         20 :                 case 'i':
    2780                 :         20 :                         g_shm_id = spdk_strtol(optarg, 10);
    2781         [ -  + ]:         20 :                         if (g_shm_id < 0) {
    2782         [ #  # ]:          0 :                                 fprintf(stderr, "Invalid shared memory ID\n");
    2783                 :          0 :                                 return g_shm_id;
    2784                 :            :                         }
    2785                 :         20 :                         break;
    2786                 :          0 :                 case 'o':
    2787                 :          0 :                         g_ocssd_verbose = true;
    2788                 :          0 :                         break;
    2789                 :          0 :                 case 'p':
    2790                 :          0 :                         g_main_core = spdk_strtol(optarg, 10);
    2791         [ #  # ]:          0 :                         if (g_main_core < 0) {
    2792         [ #  # ]:          0 :                                 fprintf(stderr, "Invalid core number\n");
    2793                 :          0 :                                 return g_main_core;
    2794                 :            :                         }
    2795         [ #  # ]:          0 :                         snprintf(g_core_mask, sizeof(g_core_mask), "0x%llx", 1ULL << g_main_core);
    2796                 :          0 :                         break;
    2797                 :         62 :                 case 'r':
    2798         [ -  + ]:         62 :                         if (spdk_nvme_transport_id_parse(&g_trid, optarg) != 0) {
    2799         [ #  # ]:          0 :                                 fprintf(stderr, "Error parsing transport address\n");
    2800                 :          0 :                                 return 1;
    2801                 :            :                         }
    2802                 :            : 
    2803         [ -  + ]:         62 :                         assert(optarg != NULL);
    2804         [ -  + ]:         62 :                         hostnqn = strcasestr(optarg, "hostnqn:");
    2805         [ -  + ]:         62 :                         if (hostnqn) {
    2806                 :            :                                 size_t len;
    2807                 :            : 
    2808                 :          0 :                                 hostnqn += strlen("hostnqn:");
    2809                 :            : 
    2810         [ #  # ]:          0 :                                 len = strcspn(hostnqn, " \t\n");
    2811         [ #  # ]:          0 :                                 if (len > (sizeof(g_hostnqn) - 1)) {
    2812         [ #  # ]:          0 :                                         fprintf(stderr, "Host NQN is too long\n");
    2813                 :          0 :                                         return 1;
    2814                 :            :                                 }
    2815                 :            : 
    2816         [ #  # ]:          0 :                                 memcpy(g_hostnqn, hostnqn, len);
    2817                 :          0 :                                 g_hostnqn[len] = '\0';
    2818                 :            :                         }
    2819                 :         62 :                         break;
    2820                 :          0 :                 case 'v':
    2821                 :          0 :                         g_iova_mode = optarg;
    2822                 :          0 :                         break;
    2823                 :          0 :                 case 'x':
    2824                 :          0 :                         g_hex_dump = true;
    2825                 :          0 :                         break;
    2826                 :          0 :                 case 'z':
    2827   [ #  #  #  #  :          0 :                         if (optarg == NULL && argv[optind] != NULL && argv[optind][0] != '-') {
                   #  # ]
    2828                 :          0 :                                 g_zone_report_limit = spdk_strtol(argv[optind], 10);
    2829                 :          0 :                                 ++optind;
    2830         [ #  # ]:          0 :                         } else if (optarg) {
    2831                 :          0 :                                 g_zone_report_limit = spdk_strtol(optarg, 10);
    2832                 :            :                         } else {
    2833                 :          0 :                                 g_zone_report_limit = 0;
    2834                 :            :                         }
    2835         [ #  # ]:          0 :                         if (g_zone_report_limit < 0) {
    2836         [ #  # ]:          0 :                                 fprintf(stderr, "Invalid Zone Report limit\n");
    2837                 :          0 :                                 return g_zone_report_limit;
    2838                 :            :                         }
    2839                 :          0 :                         break;
    2840                 :         14 :                 case 'L':
    2841                 :         14 :                         rc = spdk_log_set_flag(optarg);
    2842         [ -  + ]:         14 :                         if (rc < 0) {
    2843         [ #  # ]:          0 :                                 fprintf(stderr, "unknown flag\n");
    2844                 :          0 :                                 usage(argv[0]);
    2845                 :          0 :                                 exit(EXIT_FAILURE);
    2846                 :            :                         }
    2847                 :            : #ifdef DEBUG
    2848                 :         14 :                         spdk_log_set_print_level(SPDK_LOG_DEBUG);
    2849                 :            : #endif
    2850                 :         14 :                         break;
    2851                 :          0 :                 case 'H':
    2852                 :          0 :                         usage(argv[0]);
    2853                 :          0 :                         exit(EXIT_SUCCESS);
    2854                 :          0 :                 case 'V':
    2855                 :          0 :                         g_vmd = true;
    2856                 :          0 :                         break;
    2857                 :          0 :                 case 'S':
    2858                 :          0 :                         rc = spdk_sock_set_default_impl(optarg);
    2859         [ #  # ]:          0 :                         if (rc < 0) {
    2860         [ #  # ]:          0 :                                 fprintf(stderr, "Invalid socket implementation\n");
    2861                 :          0 :                                 exit(EXIT_FAILURE);
    2862                 :            :                         }
    2863                 :          0 :                         break;
    2864                 :          0 :                 default:
    2865                 :          0 :                         usage(argv[0]);
    2866                 :          0 :                         return 1;
    2867                 :            :                 }
    2868                 :            :         }
    2869                 :            : 
    2870                 :         68 :         return 0;
    2871                 :            : }
    2872                 :            : 
    2873                 :            : static bool
    2874                 :          0 : probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
    2875                 :            :          struct spdk_nvme_ctrlr_opts *opts)
    2876                 :            : {
    2877                 :          0 :         memcpy(opts->hostnqn, g_hostnqn, sizeof(opts->hostnqn));
    2878                 :          0 :         return true;
    2879                 :            : }
    2880                 :            : 
    2881                 :            : static void
    2882                 :         10 : attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid,
    2883                 :            :           struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts)
    2884                 :            : {
    2885                 :         10 :         g_controllers_found++;
    2886                 :         10 :         print_controller(ctrlr, trid, opts);
    2887                 :         10 :         spdk_nvme_detach_async(ctrlr, &g_detach_ctx);
    2888                 :         10 : }
    2889                 :            : 
    2890                 :            : int
    2891                 :         68 : main(int argc, char **argv)
    2892                 :            : {
    2893                 :            :         int                             rc;
    2894                 :         25 :         struct spdk_env_opts            opts;
    2895                 :            :         struct spdk_nvme_ctrlr          *ctrlr;
    2896                 :            : 
    2897                 :         68 :         rc = parse_args(argc, argv);
    2898         [ -  + ]:         68 :         if (rc != 0) {
    2899                 :          0 :                 return rc;
    2900                 :            :         }
    2901                 :            : 
    2902                 :         68 :         spdk_env_opts_init_ext(&opts, sizeof(opts));
    2903                 :         68 :         opts.name = "identify";
    2904                 :         68 :         opts.shm_id = g_shm_id;
    2905                 :         68 :         opts.mem_size = g_dpdk_mem;
    2906                 :         68 :         opts.mem_channel = 1;
    2907                 :         68 :         opts.main_core = g_main_core;
    2908                 :         68 :         opts.core_mask = g_core_mask;
    2909         [ -  + ]:         68 :         opts.hugepage_single_segments = g_dpdk_mem_single_seg;
    2910                 :         68 :         opts.iova_mode = g_iova_mode;
    2911         [ +  + ]:         68 :         if (g_trid.trtype != SPDK_NVME_TRANSPORT_PCIE) {
    2912                 :         22 :                 opts.no_pci = true;
    2913                 :            :         }
    2914         [ -  + ]:         68 :         if (spdk_env_init_ext(&opts) < 0) {
    2915   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Unable to initialize SPDK env\n");
    2916                 :          0 :                 return 1;
    2917                 :            :         }
    2918                 :            : 
    2919   [ -  +  -  +  :         68 :         if (g_vmd && spdk_vmd_init()) {
                   -  - ]
    2920   [ #  #  #  # ]:          0 :                 fprintf(stderr, "Failed to initialize VMD."
    2921                 :            :                         " Some NVMe devices can be unavailable.\n");
    2922                 :            :         }
    2923                 :            : 
    2924                 :            :         /* A specific trid is required. */
    2925         [ +  + ]:         68 :         if (strlen(g_trid.traddr) != 0) {
    2926                 :         22 :                 struct spdk_nvme_ctrlr_opts opts;
    2927                 :            : 
    2928                 :         62 :                 spdk_nvme_ctrlr_get_default_ctrlr_opts(&opts, sizeof(opts));
    2929         [ -  + ]:         62 :                 if (g_hostnqn[0] != '\0') {
    2930                 :          0 :                         memcpy(opts.hostnqn, g_hostnqn, sizeof(opts.hostnqn));
    2931                 :            :                 }
    2932                 :         62 :                 ctrlr = spdk_nvme_connect(&g_trid, &opts, sizeof(opts));
    2933         [ -  + ]:         62 :                 if (!ctrlr) {
    2934   [ #  #  #  # ]:          0 :                         fprintf(stderr, "spdk_nvme_connect() failed\n");
    2935                 :          0 :                         rc = 1;
    2936                 :          0 :                         goto exit;
    2937                 :            :                 }
    2938                 :            : 
    2939                 :         62 :                 g_controllers_found++;
    2940                 :         62 :                 print_controller(ctrlr, &g_trid, spdk_nvme_ctrlr_get_opts(ctrlr));
    2941                 :         62 :                 spdk_nvme_detach_async(ctrlr, &g_detach_ctx);
    2942         [ -  + ]:          6 :         } else if (spdk_nvme_probe(&g_trid, NULL, probe_cb, attach_cb, NULL) != 0) {
    2943   [ #  #  #  # ]:          0 :                 fprintf(stderr, "spdk_nvme_probe() failed\n");
    2944                 :          0 :                 rc = 1;
    2945                 :          0 :                 goto exit;
    2946                 :            :         }
    2947                 :            : 
    2948         [ +  + ]:         68 :         if (g_detach_ctx) {
    2949                 :         52 :                 spdk_nvme_detach_poll(g_detach_ctx);
    2950                 :            :         }
    2951                 :            : 
    2952         [ +  - ]:         68 :         if (g_controllers_found == 0) {
    2953   [ #  #  #  # ]:          0 :                 fprintf(stderr, "No NVMe controllers found.\n");
    2954                 :            :         }
    2955                 :            : 
    2956                 :         68 : exit:
    2957   [ -  +  -  + ]:         68 :         if (g_vmd) {
    2958                 :          0 :                 spdk_vmd_fini();
    2959                 :            :         }
    2960                 :            : 
    2961                 :         68 :         spdk_env_fini();
    2962                 :            : 
    2963                 :         68 :         return rc;
    2964                 :            : }

Generated by: LCOV version 1.14