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