LCOV - code coverage report
Current view: top level - spdk/app/spdk_nvme_identify - identify.c (source / functions) Hit Total Coverage
Test: Combined Lines: 1180 1849 63.8 %
Date: 2024-07-15 05:31:22 Functions: 36 52 69.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 959 2410 39.8 %

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

Generated by: LCOV version 1.14