1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright (C) 2016 Intel Corporation. 3 * All rights reserved. 4 */ 5 6 #include "spdk/stdinc.h" 7 8 #include "spdk/nvme.h" 9 #include "spdk/env.h" 10 #include "spdk/string.h" 11 #include "spdk/util.h" 12 #include "spdk/opal.h" 13 14 #define MAX_DEVS 64 15 16 struct dev { 17 struct spdk_pci_addr pci_addr; 18 struct spdk_nvme_ctrlr *ctrlr; 19 const struct spdk_nvme_ctrlr_data *cdata; 20 struct spdk_nvme_ns_data *common_ns_data; 21 int outstanding_admin_cmds; 22 struct spdk_opal_dev *opal_dev; 23 }; 24 25 static struct dev devs[MAX_DEVS]; 26 static int num_devs = 0; 27 static int g_shm_id = -1; 28 29 #define foreach_dev(iter) \ 30 for (iter = devs; iter - devs < num_devs; iter++) 31 32 enum controller_display_model { 33 CONTROLLER_DISPLAY_ALL = 0x0, 34 CONTROLLER_DISPLAY_SIMPLISTIC = 0x1, 35 }; 36 37 static int 38 cmp_devs(const void *ap, const void *bp) 39 { 40 const struct dev *a = ap, *b = bp; 41 42 return spdk_pci_addr_compare(&a->pci_addr, &b->pci_addr); 43 } 44 45 static bool 46 probe_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 47 struct spdk_nvme_ctrlr_opts *opts) 48 { 49 return true; 50 } 51 52 static void 53 identify_common_ns_cb(void *cb_arg, const struct spdk_nvme_cpl *cpl) 54 { 55 struct dev *dev = cb_arg; 56 57 if (cpl->status.sc != SPDK_NVME_SC_SUCCESS) { 58 /* Identify Namespace for NSID = FFFFFFFFh is optional, so failure is not fatal. */ 59 spdk_dma_free(dev->common_ns_data); 60 dev->common_ns_data = NULL; 61 } 62 63 dev->outstanding_admin_cmds--; 64 } 65 66 static void 67 attach_cb(void *cb_ctx, const struct spdk_nvme_transport_id *trid, 68 struct spdk_nvme_ctrlr *ctrlr, const struct spdk_nvme_ctrlr_opts *opts) 69 { 70 struct dev *dev; 71 struct spdk_nvme_cmd cmd; 72 73 /* add to dev list */ 74 dev = &devs[num_devs]; 75 if (spdk_pci_addr_parse(&dev->pci_addr, trid->traddr) != 0) { 76 fprintf(stderr, "spdk_pci_addr_parse failure\n"); 77 assert(false); 78 return; 79 } 80 num_devs++; 81 82 dev->ctrlr = ctrlr; 83 84 /* Retrieve controller data */ 85 dev->cdata = spdk_nvme_ctrlr_get_data(dev->ctrlr); 86 87 dev->common_ns_data = spdk_dma_zmalloc(sizeof(struct spdk_nvme_ns_data), 4096, NULL); 88 if (dev->common_ns_data == NULL) { 89 fprintf(stderr, "common_ns_data allocation failure\n"); 90 return; 91 } 92 93 /* Identify Namespace with NSID set to FFFFFFFFh to get common namespace capabilities. */ 94 memset(&cmd, 0, sizeof(cmd)); 95 cmd.opc = SPDK_NVME_OPC_IDENTIFY; 96 cmd.cdw10_bits.identify.cns = 0; /* CNS = 0 (Identify Namespace) */ 97 cmd.nsid = SPDK_NVME_GLOBAL_NS_TAG; 98 99 dev->outstanding_admin_cmds++; 100 if (spdk_nvme_ctrlr_cmd_admin_raw(ctrlr, &cmd, dev->common_ns_data, 101 sizeof(struct spdk_nvme_ns_data), identify_common_ns_cb, dev) != 0) { 102 dev->outstanding_admin_cmds--; 103 spdk_dma_free(dev->common_ns_data); 104 dev->common_ns_data = NULL; 105 } 106 107 while (dev->outstanding_admin_cmds) { 108 spdk_nvme_ctrlr_process_admin_completions(ctrlr); 109 } 110 } 111 112 static void 113 usage(void) 114 { 115 printf("NVMe Management Options"); 116 printf("\n"); 117 printf("\t[1: list controllers]\n"); 118 printf("\t[2: create namespace]\n"); 119 printf("\t[3: delete namespace]\n"); 120 printf("\t[4: attach namespace to controller]\n"); 121 printf("\t[5: detach namespace from controller]\n"); 122 printf("\t[6: format namespace or controller]\n"); 123 printf("\t[7: firmware update]\n"); 124 printf("\t[8: opal]\n"); 125 printf("\t[9: quit]\n"); 126 } 127 128 static void 129 display_namespace_dpc(const struct spdk_nvme_ns_data *nsdata) 130 { 131 if (nsdata->dpc.pit1 || nsdata->dpc.pit2 || nsdata->dpc.pit3) { 132 if (nsdata->dpc.pit1) { 133 printf("PIT1 "); 134 } 135 136 if (nsdata->dpc.pit2) { 137 printf("PIT2 "); 138 } 139 140 if (nsdata->dpc.pit3) { 141 printf("PIT3 "); 142 } 143 } else { 144 printf("Not Supported\n"); 145 return; 146 } 147 148 if (nsdata->dpc.md_start && nsdata->dpc.md_end) { 149 printf("Location: Head or Tail\n"); 150 } else if (nsdata->dpc.md_start) { 151 printf("Location: Head\n"); 152 } else if (nsdata->dpc.md_end) { 153 printf("Location: Tail\n"); 154 } else { 155 printf("Not Supported\n"); 156 } 157 } 158 159 static void 160 display_namespace(struct spdk_nvme_ns *ns) 161 { 162 const struct spdk_nvme_ns_data *nsdata; 163 uint32_t i; 164 uint32_t format_index; 165 166 nsdata = spdk_nvme_ns_get_data(ns); 167 format_index = spdk_nvme_ns_get_format_index(nsdata); 168 169 printf("Namespace ID:%d\n", spdk_nvme_ns_get_id(ns)); 170 171 printf("Size (in LBAs): %lld (%lldM)\n", 172 (long long)nsdata->nsze, 173 (long long)nsdata->nsze / 1024 / 1024); 174 printf("Capacity (in LBAs): %lld (%lldM)\n", 175 (long long)nsdata->ncap, 176 (long long)nsdata->ncap / 1024 / 1024); 177 printf("Utilization (in LBAs): %lld (%lldM)\n", 178 (long long)nsdata->nuse, 179 (long long)nsdata->nuse / 1024 / 1024); 180 printf("Format Progress Indicator: %s\n", 181 nsdata->fpi.fpi_supported ? "Supported" : "Not Supported"); 182 if (nsdata->fpi.fpi_supported && nsdata->fpi.percentage_remaining) { 183 printf("Formatted Percentage: %d%%\n", 100 - nsdata->fpi.percentage_remaining); 184 } 185 printf("Number of LBA Formats: %d\n", nsdata->nlbaf + 1); 186 printf("Current LBA Format: LBA Format #%02d\n", 187 format_index); 188 for (i = 0; i <= nsdata->nlbaf; i++) 189 printf("LBA Format #%02d: Data Size: %5d Metadata Size: %5d\n", 190 i, 1 << nsdata->lbaf[i].lbads, nsdata->lbaf[i].ms); 191 printf("Data Protection Capabilities:"); 192 display_namespace_dpc(nsdata); 193 if (SPDK_NVME_FMT_NVM_PROTECTION_DISABLE == nsdata->dps.pit) { 194 printf("Data Protection Setting: N/A\n"); 195 } else { 196 printf("Data Protection Setting: PIT%d Location: %s\n", 197 nsdata->dps.pit, nsdata->dps.md_start ? "Head" : "Tail"); 198 } 199 printf("Multipath IO and Sharing: %s\n", 200 nsdata->nmic.can_share ? "Supported" : "Not Supported"); 201 printf("\n"); 202 } 203 204 static void 205 display_controller(struct dev *dev, int model) 206 { 207 struct spdk_nvme_ns *ns; 208 const struct spdk_nvme_ctrlr_data *cdata; 209 uint8_t str[128]; 210 uint32_t nsid; 211 212 cdata = spdk_nvme_ctrlr_get_data(dev->ctrlr); 213 214 if (model == CONTROLLER_DISPLAY_SIMPLISTIC) { 215 printf("%04x:%02x:%02x.%02x ", 216 dev->pci_addr.domain, dev->pci_addr.bus, dev->pci_addr.dev, dev->pci_addr.func); 217 printf("%-40.40s %-20.20s ", 218 cdata->mn, cdata->sn); 219 printf("%5d ", cdata->cntlid); 220 printf("\n"); 221 return; 222 } 223 224 printf("=====================================================\n"); 225 printf("NVMe Controller: %04x:%02x:%02x.%02x\n", 226 dev->pci_addr.domain, dev->pci_addr.bus, dev->pci_addr.dev, dev->pci_addr.func); 227 printf("============================\n"); 228 printf("Controller Capabilities/Features\n"); 229 printf("Controller ID: %d\n", cdata->cntlid); 230 snprintf(str, sizeof(cdata->sn) + 1, "%s", cdata->sn); 231 printf("Serial Number: %s\n", str); 232 printf("\n"); 233 234 printf("Admin Command Set Attributes\n"); 235 printf("============================\n"); 236 printf("Namespace Manage And Attach: %s\n", 237 cdata->oacs.ns_manage ? "Supported" : "Not Supported"); 238 printf("Namespace Format: %s\n", 239 cdata->oacs.format ? "Supported" : "Not Supported"); 240 printf("\n"); 241 printf("NVM Command Set Attributes\n"); 242 printf("============================\n"); 243 if (cdata->fna.format_all_ns) { 244 printf("Namespace format operation applies to all namespaces\n"); 245 } else { 246 printf("Namespace format operation applies to per namespace\n"); 247 } 248 printf("\n"); 249 printf("Namespace Attributes\n"); 250 printf("============================\n"); 251 for (nsid = spdk_nvme_ctrlr_get_first_active_ns(dev->ctrlr); 252 nsid != 0; nsid = spdk_nvme_ctrlr_get_next_active_ns(dev->ctrlr, nsid)) { 253 ns = spdk_nvme_ctrlr_get_ns(dev->ctrlr, nsid); 254 assert(ns != NULL); 255 display_namespace(ns); 256 } 257 } 258 259 static void 260 display_controller_list(void) 261 { 262 struct dev *iter; 263 264 foreach_dev(iter) { 265 display_controller(iter, CONTROLLER_DISPLAY_ALL); 266 } 267 } 268 269 static char * 270 get_line(char *buf, int buf_size, FILE *f, bool secret) 271 { 272 char *ch; 273 size_t len; 274 struct termios default_attr = {}, new_attr = {}; 275 int ret; 276 277 if (secret) { 278 ret = tcgetattr(STDIN_FILENO, &default_attr); 279 if (ret) { 280 return NULL; 281 } 282 283 new_attr = default_attr; 284 new_attr.c_lflag &= ~ECHO; /* disable echo */ 285 ret = tcsetattr(STDIN_FILENO, TCSAFLUSH, &new_attr); 286 if (ret) { 287 return NULL; 288 } 289 } 290 291 ch = fgets(buf, buf_size, f); 292 if (ch == NULL) { 293 return NULL; 294 } 295 296 if (secret) { 297 ret = tcsetattr(STDIN_FILENO, TCSAFLUSH, &default_attr); /* restore default config */ 298 if (ret) { 299 return NULL; 300 } 301 } 302 303 len = strlen(buf); 304 if (len > 0 && buf[len - 1] == '\n') { 305 buf[len - 1] = '\0'; 306 } 307 return buf; 308 } 309 310 static struct dev * 311 get_controller(void) 312 { 313 struct spdk_pci_addr pci_addr; 314 char address[64]; 315 char *p; 316 int ch; 317 struct dev *iter; 318 319 memset(address, 0, sizeof(address)); 320 321 foreach_dev(iter) { 322 display_controller(iter, CONTROLLER_DISPLAY_SIMPLISTIC); 323 } 324 325 printf("Please Input PCI Address(domain:bus:dev.func):\n"); 326 327 while ((ch = getchar()) != '\n' && ch != EOF); 328 p = get_line(address, 64, stdin, false); 329 if (p == NULL) { 330 return NULL; 331 } 332 333 while (isspace(*p)) { 334 p++; 335 } 336 337 if (spdk_pci_addr_parse(&pci_addr, p) < 0) { 338 return NULL; 339 } 340 341 foreach_dev(iter) { 342 if (spdk_pci_addr_compare(&pci_addr, &iter->pci_addr) == 0) { 343 return iter; 344 } 345 } 346 return NULL; 347 } 348 349 static int 350 get_lba_format(const struct spdk_nvme_ns_data *ns_data) 351 { 352 int lbaf, i; 353 354 printf("\nSupported LBA formats:\n"); 355 for (i = 0; i <= ns_data->nlbaf; i++) { 356 printf("%2d: %d data bytes", i, 1 << ns_data->lbaf[i].lbads); 357 if (ns_data->lbaf[i].ms) { 358 printf(" + %d metadata bytes", ns_data->lbaf[i].ms); 359 } 360 printf("\n"); 361 } 362 363 printf("Please input LBA format index (0 - %d):\n", ns_data->nlbaf); 364 if (scanf("%d", &lbaf) != 1 || lbaf > ns_data->nlbaf) { 365 return -1; 366 } 367 368 return lbaf; 369 } 370 371 static void 372 identify_allocated_ns_cb(void *cb_arg, const struct spdk_nvme_cpl *cpl) 373 { 374 struct dev *dev = cb_arg; 375 376 dev->outstanding_admin_cmds--; 377 } 378 379 static uint32_t 380 get_allocated_nsid(struct dev *dev) 381 { 382 uint32_t nsid; 383 size_t i; 384 struct spdk_nvme_ns_list *ns_list; 385 struct spdk_nvme_cmd cmd = {0}; 386 387 ns_list = spdk_dma_zmalloc(sizeof(*ns_list), 4096, NULL); 388 if (ns_list == NULL) { 389 printf("Allocation error\n"); 390 return 0; 391 } 392 393 cmd.opc = SPDK_NVME_OPC_IDENTIFY; 394 cmd.cdw10_bits.identify.cns = SPDK_NVME_IDENTIFY_ALLOCATED_NS_LIST; 395 cmd.nsid = 0; 396 397 dev->outstanding_admin_cmds++; 398 if (spdk_nvme_ctrlr_cmd_admin_raw(dev->ctrlr, &cmd, ns_list, sizeof(*ns_list), 399 identify_allocated_ns_cb, dev)) { 400 printf("Identify command failed\n"); 401 spdk_dma_free(ns_list); 402 return 0; 403 } 404 405 while (dev->outstanding_admin_cmds) { 406 spdk_nvme_ctrlr_process_admin_completions(dev->ctrlr); 407 } 408 409 printf("Allocated Namespace IDs:\n"); 410 for (i = 0; i < SPDK_COUNTOF(ns_list->ns_list); i++) { 411 if (ns_list->ns_list[i] == 0) { 412 break; 413 } 414 printf("%u\n", ns_list->ns_list[i]); 415 } 416 417 spdk_dma_free(ns_list); 418 419 printf("Please Input Namespace ID:\n"); 420 if (!scanf("%u", &nsid)) { 421 printf("Invalid Namespace ID\n"); 422 nsid = 0; 423 } 424 425 return nsid; 426 } 427 428 static void 429 ns_attach(struct dev *device, int attachment_op, int ctrlr_id, int ns_id) 430 { 431 int ret = 0; 432 struct spdk_nvme_ctrlr_list *ctrlr_list; 433 434 ctrlr_list = spdk_dma_zmalloc(sizeof(struct spdk_nvme_ctrlr_list), 435 4096, NULL); 436 if (ctrlr_list == NULL) { 437 printf("Allocation error (controller list)\n"); 438 exit(1); 439 } 440 441 ctrlr_list->ctrlr_count = 1; 442 ctrlr_list->ctrlr_list[0] = ctrlr_id; 443 444 if (attachment_op == SPDK_NVME_NS_CTRLR_ATTACH) { 445 ret = spdk_nvme_ctrlr_attach_ns(device->ctrlr, ns_id, ctrlr_list); 446 } else if (attachment_op == SPDK_NVME_NS_CTRLR_DETACH) { 447 ret = spdk_nvme_ctrlr_detach_ns(device->ctrlr, ns_id, ctrlr_list); 448 } 449 450 if (ret) { 451 fprintf(stdout, "ns attach: Failed\n"); 452 } 453 454 spdk_dma_free(ctrlr_list); 455 } 456 457 static void 458 ns_manage_add(struct dev *device, uint64_t ns_size, uint64_t ns_capacity, int ns_lbasize, 459 uint8_t ns_dps_type, uint8_t ns_dps_location, uint8_t ns_nmic) 460 { 461 uint32_t nsid; 462 struct spdk_nvme_ns_data *ndata; 463 464 ndata = spdk_dma_zmalloc(sizeof(struct spdk_nvme_ns_data), 4096, NULL); 465 if (ndata == NULL) { 466 printf("Allocation error (namespace data)\n"); 467 exit(1); 468 } 469 470 ndata->nsze = ns_size; 471 ndata->ncap = ns_capacity; 472 ndata->flbas.format = ns_lbasize & 0xF; 473 ndata->flbas.msb_format = (ns_lbasize >> 4) & 0x3; 474 if (SPDK_NVME_FMT_NVM_PROTECTION_DISABLE != ns_dps_type) { 475 ndata->dps.pit = ns_dps_type; 476 ndata->dps.md_start = ns_dps_location; 477 } 478 ndata->nmic.can_share = ns_nmic; 479 nsid = spdk_nvme_ctrlr_create_ns(device->ctrlr, ndata); 480 if (nsid == 0) { 481 fprintf(stdout, "ns manage: Failed\n"); 482 } else { 483 printf("Created namespace ID %u\n", nsid); 484 } 485 486 spdk_dma_free(ndata); 487 } 488 489 static void 490 ns_manage_delete(struct dev *device, int ns_id) 491 { 492 int ret = 0; 493 494 ret = spdk_nvme_ctrlr_delete_ns(device->ctrlr, ns_id); 495 if (ret) { 496 fprintf(stdout, "ns manage: Failed\n"); 497 return; 498 } 499 } 500 501 static void 502 nvme_manage_format(struct dev *device, int ns_id, int ses, int pi, int pil, int ms, int lbaf) 503 { 504 int ret = 0; 505 struct spdk_nvme_format format = {}; 506 507 format.lbaf = lbaf & 0xF; 508 format.ms = ms; 509 format.pi = pi; 510 format.pil = pil; 511 format.ses = ses; 512 format.lbafu = (lbaf >> 4) & 0x3; 513 ret = spdk_nvme_ctrlr_format(device->ctrlr, ns_id, &format); 514 if (ret) { 515 fprintf(stdout, "nvme format: Failed\n"); 516 return; 517 } 518 } 519 520 static void 521 attach_and_detach_ns(int attachment_op) 522 { 523 uint32_t nsid; 524 struct dev *ctrlr; 525 526 ctrlr = get_controller(); 527 if (ctrlr == NULL) { 528 printf("Invalid controller PCI Address.\n"); 529 return; 530 } 531 532 if (!ctrlr->cdata->oacs.ns_manage) { 533 printf("Controller does not support ns management\n"); 534 return; 535 } 536 537 nsid = get_allocated_nsid(ctrlr); 538 if (nsid == 0) { 539 printf("Invalid Namespace ID\n"); 540 return; 541 } 542 543 ns_attach(ctrlr, attachment_op, ctrlr->cdata->cntlid, nsid); 544 } 545 546 static void 547 add_ns(void) 548 { 549 uint64_t ns_size = 0; 550 uint64_t ns_capacity = 0; 551 int ns_lbasize; 552 int ns_dps_type = 0; 553 int ns_dps_location = 0; 554 int ns_nmic = 0; 555 struct dev *ctrlr = NULL; 556 557 ctrlr = get_controller(); 558 if (ctrlr == NULL) { 559 printf("Invalid controller PCI Address.\n"); 560 return; 561 } 562 563 if (!ctrlr->cdata->oacs.ns_manage) { 564 printf("Controller does not support ns management\n"); 565 return; 566 } 567 568 if (!ctrlr->common_ns_data) { 569 printf("Controller did not return common namespace capabilities\n"); 570 return; 571 } 572 573 ns_lbasize = get_lba_format(ctrlr->common_ns_data); 574 if (ns_lbasize < 0) { 575 printf("Invalid LBA format number\n"); 576 return; 577 } 578 579 printf("Please Input Namespace Size (in LBAs):\n"); 580 if (!scanf("%" SCNu64, &ns_size)) { 581 printf("Invalid Namespace Size\n"); 582 while (getchar() != '\n'); 583 return; 584 } 585 586 printf("Please Input Namespace Capacity (in LBAs):\n"); 587 if (!scanf("%" SCNu64, &ns_capacity)) { 588 printf("Invalid Namespace Capacity\n"); 589 while (getchar() != '\n'); 590 return; 591 } 592 593 printf("Please Input Data Protection Type (0 - 3):\n"); 594 if (!scanf("%d", &ns_dps_type)) { 595 printf("Invalid Data Protection Type\n"); 596 while (getchar() != '\n'); 597 return; 598 } 599 600 if (SPDK_NVME_FMT_NVM_PROTECTION_DISABLE != ns_dps_type) { 601 printf("Please Input Data Protection Location (1: Head; 0: Tail):\n"); 602 if (!scanf("%d", &ns_dps_location)) { 603 printf("Invalid Data Protection Location\n"); 604 while (getchar() != '\n'); 605 return; 606 } 607 } 608 609 printf("Please Input Multi-path IO and Sharing Capabilities (1: Share; 0: Private):\n"); 610 if (!scanf("%d", &ns_nmic)) { 611 printf("Invalid Multi-path IO and Sharing Capabilities\n"); 612 while (getchar() != '\n'); 613 return; 614 } 615 616 ns_manage_add(ctrlr, ns_size, ns_capacity, ns_lbasize, 617 ns_dps_type, ns_dps_location, ns_nmic); 618 } 619 620 static void 621 delete_ns(void) 622 { 623 int ns_id; 624 struct dev *ctrlr; 625 626 ctrlr = get_controller(); 627 if (ctrlr == NULL) { 628 printf("Invalid controller PCI Address.\n"); 629 return; 630 } 631 632 if (!ctrlr->cdata->oacs.ns_manage) { 633 printf("Controller does not support ns management\n"); 634 return; 635 } 636 637 printf("Please Input Namespace ID:\n"); 638 if (!scanf("%d", &ns_id)) { 639 printf("Invalid Namespace ID\n"); 640 while (getchar() != '\n'); 641 return; 642 } 643 644 ns_manage_delete(ctrlr, ns_id); 645 } 646 647 static void 648 format_nvm(void) 649 { 650 int ns_id; 651 int ses; 652 int pil; 653 int pi; 654 int ms; 655 int lbaf; 656 char option; 657 struct dev *ctrlr; 658 const struct spdk_nvme_ctrlr_data *cdata; 659 struct spdk_nvme_ns *ns; 660 const struct spdk_nvme_ns_data *nsdata; 661 662 ctrlr = get_controller(); 663 if (ctrlr == NULL) { 664 printf("Invalid controller PCI BDF.\n"); 665 return; 666 } 667 668 cdata = ctrlr->cdata; 669 670 if (!cdata->oacs.format) { 671 printf("Controller does not support Format NVM command\n"); 672 return; 673 } 674 675 if (cdata->fna.format_all_ns) { 676 ns_id = SPDK_NVME_GLOBAL_NS_TAG; 677 ns = spdk_nvme_ctrlr_get_ns(ctrlr->ctrlr, 1); 678 } else { 679 printf("Please Input Namespace ID (1 - %d):\n", cdata->nn); 680 if (!scanf("%d", &ns_id)) { 681 printf("Invalid Namespace ID\n"); 682 while (getchar() != '\n'); 683 return; 684 } 685 ns = spdk_nvme_ctrlr_get_ns(ctrlr->ctrlr, ns_id); 686 } 687 688 if (ns == NULL) { 689 printf("Namespace ID %d not found\n", ns_id); 690 while (getchar() != '\n'); 691 return; 692 } 693 694 nsdata = spdk_nvme_ns_get_data(ns); 695 696 printf("Please Input Secure Erase Setting:\n"); 697 printf(" 0: No secure erase operation requested\n"); 698 printf(" 1: User data erase\n"); 699 if (cdata->fna.crypto_erase_supported) { 700 printf(" 2: Cryptographic erase\n"); 701 } 702 if (!scanf("%d", &ses)) { 703 printf("Invalid Secure Erase Setting\n"); 704 while (getchar() != '\n'); 705 return; 706 } 707 708 lbaf = get_lba_format(nsdata); 709 if (lbaf < 0) { 710 printf("Invalid LBA format number\n"); 711 return; 712 } 713 714 if (nsdata->lbaf[lbaf].ms) { 715 printf("Please Input Protection Information:\n"); 716 printf(" 0: Protection information is not enabled\n"); 717 printf(" 1: Protection information is enabled, Type 1\n"); 718 printf(" 2: Protection information is enabled, Type 2\n"); 719 printf(" 3: Protection information is enabled, Type 3\n"); 720 if (!scanf("%d", &pi)) { 721 printf("Invalid protection information\n"); 722 while (getchar() != '\n'); 723 return; 724 } 725 726 if (pi) { 727 printf("Please Input Protection Information Location:\n"); 728 printf(" 0: Protection information transferred as the last eight bytes of metadata\n"); 729 printf(" 1: Protection information transferred as the first eight bytes of metadata\n"); 730 if (!scanf("%d", &pil)) { 731 printf("Invalid protection information location\n"); 732 while (getchar() != '\n'); 733 return; 734 } 735 } else { 736 pil = 0; 737 } 738 739 printf("Please Input Metadata Setting:\n"); 740 printf(" 0: Metadata is transferred as part of a separate buffer\n"); 741 printf(" 1: Metadata is transferred as part of an extended data LBA\n"); 742 if (!scanf("%d", &ms)) { 743 printf("Invalid metadata setting\n"); 744 while (getchar() != '\n'); 745 return; 746 } 747 } else { 748 ms = 0; 749 pi = 0; 750 pil = 0; 751 } 752 753 printf("Warning: use this utility at your own risk.\n" 754 "This command will format your namespace and all data will be lost.\n" 755 "This command may take several minutes to complete,\n" 756 "so do not interrupt the utility until it completes.\n" 757 "Press 'Y' to continue with the format operation.\n"); 758 759 while (getchar() != '\n'); 760 if (!scanf("%c", &option)) { 761 printf("Invalid option\n"); 762 while (getchar() != '\n'); 763 return; 764 } 765 766 if (option == 'y' || option == 'Y') { 767 nvme_manage_format(ctrlr, ns_id, ses, pi, pil, ms, lbaf); 768 } else { 769 printf("NVMe format abort\n"); 770 } 771 } 772 773 static void 774 update_firmware_image(void) 775 { 776 int rc; 777 int fd = -1; 778 int slot; 779 unsigned int size; 780 struct stat fw_stat; 781 char path[256]; 782 void *fw_image; 783 struct dev *ctrlr; 784 const struct spdk_nvme_ctrlr_data *cdata; 785 enum spdk_nvme_fw_commit_action commit_action; 786 struct spdk_nvme_status status; 787 788 ctrlr = get_controller(); 789 if (ctrlr == NULL) { 790 printf("Invalid controller PCI BDF.\n"); 791 return; 792 } 793 794 cdata = ctrlr->cdata; 795 796 if (!cdata->oacs.firmware) { 797 printf("Controller does not support firmware download and commit command\n"); 798 return; 799 } 800 801 printf("Please Input The Path Of Firmware Image\n"); 802 803 if (get_line(path, sizeof(path), stdin, false) == NULL) { 804 printf("Invalid path setting\n"); 805 while (getchar() != '\n'); 806 return; 807 } 808 809 fd = open(path, O_RDONLY); 810 if (fd < 0) { 811 perror("Open file failed"); 812 return; 813 } 814 rc = fstat(fd, &fw_stat); 815 if (rc < 0) { 816 printf("Fstat failed\n"); 817 close(fd); 818 return; 819 } 820 821 if (fw_stat.st_size % 4) { 822 printf("Firmware image size is not multiple of 4\n"); 823 close(fd); 824 return; 825 } 826 827 size = fw_stat.st_size; 828 829 fw_image = spdk_dma_zmalloc(size, 4096, NULL); 830 if (fw_image == NULL) { 831 printf("Allocation error\n"); 832 close(fd); 833 return; 834 } 835 836 if (read(fd, fw_image, size) != ((ssize_t)(size))) { 837 printf("Read firmware image failed\n"); 838 close(fd); 839 spdk_dma_free(fw_image); 840 return; 841 } 842 close(fd); 843 844 printf("Please Input Slot(0 - 7):\n"); 845 if (!scanf("%d", &slot)) { 846 printf("Invalid Slot\n"); 847 spdk_dma_free(fw_image); 848 while (getchar() != '\n'); 849 return; 850 } 851 852 commit_action = SPDK_NVME_FW_COMMIT_REPLACE_AND_ENABLE_IMG; 853 rc = spdk_nvme_ctrlr_update_firmware(ctrlr->ctrlr, fw_image, size, slot, commit_action, &status); 854 if (rc == -ENXIO && status.sct == SPDK_NVME_SCT_COMMAND_SPECIFIC && 855 status.sc == SPDK_NVME_SC_FIRMWARE_REQ_CONVENTIONAL_RESET) { 856 printf("conventional reset is needed to enable firmware !\n"); 857 } else if (rc) { 858 printf("spdk_nvme_ctrlr_update_firmware failed\n"); 859 } else { 860 printf("spdk_nvme_ctrlr_update_firmware success\n"); 861 } 862 spdk_dma_free(fw_image); 863 } 864 865 static void 866 opal_dump_info(struct spdk_opal_d0_features_info *feat) 867 { 868 if (feat->tper.hdr.code) { 869 printf("\nOpal TPer feature:\n"); 870 printf("ACKNACK = %s", (feat->tper.acknack ? "Y, " : "N, ")); 871 printf("ASYNC = %s", (feat->tper.async ? "Y, " : "N, ")); 872 printf("BufferManagement = %s\n", (feat->tper.buffer_management ? "Y, " : "N, ")); 873 printf("ComIDManagement = %s", (feat->tper.comid_management ? "Y, " : "N, ")); 874 printf("Streaming = %s", (feat->tper.streaming ? "Y, " : "N, ")); 875 printf("Sync = %s\n", (feat->tper.sync ? "Y" : "N")); 876 printf("\n"); 877 } 878 879 if (feat->locking.hdr.code) { 880 printf("Opal Locking feature:\n"); 881 printf("Locked = %s", (feat->locking.locked ? "Y, " : "N, ")); 882 printf("Locking Enabled = %s", (feat->locking.locking_enabled ? "Y, " : "N, ")); 883 printf("Locking supported = %s\n", (feat->locking.locking_supported ? "Y" : "N")); 884 885 printf("MBR done = %s", (feat->locking.mbr_done ? "Y, " : "N, ")); 886 printf("MBR enabled = %s", (feat->locking.mbr_enabled ? "Y, " : "N, ")); 887 printf("Media encrypt = %s\n", (feat->locking.media_encryption ? "Y" : "N")); 888 printf("\n"); 889 } 890 891 if (feat->geo.hdr.code) { 892 printf("Opal Geometry feature:\n"); 893 printf("Align = %s", (feat->geo.alignment_granularity ? "Y, " : "N, ")); 894 printf("Logical block size = %d, ", from_be32(&feat->geo.logical_block_size)); 895 printf("Lowest aligned LBA = %" PRIu64 "\n", from_be64(&feat->geo.lowest_aligned_lba)); 896 printf("\n"); 897 } 898 899 if (feat->single_user.hdr.code) { 900 printf("Opal Single User Mode feature:\n"); 901 printf("Any in SUM = %s", (feat->single_user.any ? "Y, " : "N, ")); 902 printf("All in SUM = %s", (feat->single_user.all ? "Y, " : "N, ")); 903 printf("Policy: %s Authority,\n", (feat->single_user.policy ? "Admin" : "Users")); 904 printf("Number of locking objects = %d\n ", from_be32(&feat->single_user.num_locking_objects)); 905 printf("\n"); 906 } 907 908 if (feat->datastore.hdr.code) { 909 printf("Opal DataStore feature:\n"); 910 printf("Table alignment = %d, ", from_be32(&feat->datastore.alignment)); 911 printf("Max number of tables = %d, ", from_be16(&feat->datastore.max_tables)); 912 printf("Max size of tables = %d\n", from_be32(&feat->datastore.max_table_size)); 913 printf("\n"); 914 } 915 916 if (feat->v100.hdr.code) { 917 printf("Opal V100 feature:\n"); 918 printf("Base comID = %d, ", from_be16(&feat->v100.base_comid)); 919 printf("Number of comIDs = %d, ", from_be16(&feat->v100.number_comids)); 920 printf("Range crossing = %s\n", (feat->v100.range_crossing ? "N" : "Y")); 921 printf("\n"); 922 } 923 924 if (feat->v200.hdr.code) { 925 printf("Opal V200 feature:\n"); 926 printf("Base comID = %d, ", from_be16(&feat->v200.base_comid)); 927 printf("Number of comIDs = %d, ", from_be16(&feat->v200.num_comids)); 928 printf("Initial PIN = %d,\n", feat->v200.initial_pin); 929 printf("Reverted PIN = %d, ", feat->v200.reverted_pin); 930 printf("Number of admins = %d, ", from_be16(&feat->v200.num_locking_admin_auth)); 931 printf("Number of users = %d\n", from_be16(&feat->v200.num_locking_user_auth)); 932 printf("\n"); 933 } 934 } 935 936 static void 937 opal_usage(void) 938 { 939 printf("Opal General Usage:\n"); 940 printf("\n"); 941 printf("\t[1: scan device]\n"); 942 printf("\t[2: init - take ownership and activate locking]\n"); 943 printf("\t[3: revert tper]\n"); 944 printf("\t[4: setup locking range]\n"); 945 printf("\t[5: list locking ranges]\n"); 946 printf("\t[6: enable user]\n"); 947 printf("\t[7: set new password]\n"); 948 printf("\t[8: add user to locking range]\n"); 949 printf("\t[9: lock/unlock range]\n"); 950 printf("\t[10: erase locking range]\n"); 951 printf("\t[0: quit]\n"); 952 } 953 954 static void 955 opal_scan(struct dev *iter) 956 { 957 while (getchar() != '\n'); 958 if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { 959 iter->opal_dev = spdk_opal_dev_construct(iter->ctrlr); 960 if (iter->opal_dev == NULL) { 961 return; 962 } 963 964 printf("\n\nOpal Supported:\n"); 965 display_controller(iter, CONTROLLER_DISPLAY_SIMPLISTIC); 966 opal_dump_info(spdk_opal_get_d0_features_info(iter->opal_dev)); 967 spdk_opal_dev_destruct(iter->opal_dev); 968 } else { 969 printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\n", 970 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 971 printf("%04x:%02x:%02x.%02x: Opal Not Supported\n\n\n", 972 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 973 } 974 } 975 976 static void 977 opal_init(struct dev *iter) 978 { 979 char new_passwd[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 980 char *passwd_p; 981 int ret; 982 int ch; 983 984 if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { 985 iter->opal_dev = spdk_opal_dev_construct(iter->ctrlr); 986 if (iter->opal_dev == NULL) { 987 return; 988 } 989 printf("Please input the new password for ownership:"); 990 while ((ch = getchar()) != '\n' && ch != EOF); 991 passwd_p = get_line(new_passwd, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 992 printf("\n...\n"); 993 if (passwd_p) { 994 ret = spdk_opal_cmd_take_ownership(iter->opal_dev, passwd_p); 995 if (ret) { 996 printf("Take ownership failure: %d\n", ret); 997 spdk_opal_dev_destruct(iter->opal_dev); 998 return; 999 } 1000 1001 ret = spdk_opal_cmd_activate_locking_sp(iter->opal_dev, passwd_p); 1002 if (ret) { 1003 printf("Locking SP activate failure: %d\n", ret); 1004 spdk_opal_dev_destruct(iter->opal_dev); 1005 return; 1006 } 1007 printf("...\nOpal Init Success\n"); 1008 } else { 1009 printf("Input password invalid. Opal Init failure\n"); 1010 } 1011 spdk_opal_dev_destruct(iter->opal_dev); 1012 } else { 1013 printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n", 1014 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 1015 } 1016 } 1017 1018 static void 1019 opal_locking_usage(void) 1020 { 1021 printf("Choose Opal locking state:\n"); 1022 printf("\n"); 1023 printf("\t[1: read write lock]\n"); 1024 printf("\t[2: read only]\n"); 1025 printf("\t[3: read write unlock]\n"); 1026 } 1027 1028 static void 1029 opal_setup_lockingrange(struct dev *iter) 1030 { 1031 char passwd[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 1032 char *passwd_p; 1033 int ret; 1034 int ch; 1035 uint64_t range_start; 1036 uint64_t range_length; 1037 int locking_range_id; 1038 struct spdk_opal_locking_range_info *info; 1039 1040 if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { 1041 iter->opal_dev = spdk_opal_dev_construct(iter->ctrlr); 1042 if (iter->opal_dev == NULL) { 1043 return; 1044 } 1045 printf("Please input the password for setting up locking range:"); 1046 while ((ch = getchar()) != '\n' && ch != EOF); 1047 passwd_p = get_line(passwd, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 1048 printf("\n"); 1049 if (passwd_p) { 1050 printf("Specify locking range id:\n"); 1051 if (!scanf("%d", &locking_range_id)) { 1052 printf("Invalid locking range id\n"); 1053 spdk_opal_dev_destruct(iter->opal_dev); 1054 return; 1055 } 1056 1057 printf("range length:\n"); 1058 if (!scanf("%" SCNu64, &range_length)) { 1059 printf("Invalid range length\n"); 1060 spdk_opal_dev_destruct(iter->opal_dev); 1061 return; 1062 } 1063 1064 printf("range start:\n"); 1065 if (!scanf("%" SCNu64, &range_start)) { 1066 printf("Invalid range start address\n"); 1067 spdk_opal_dev_destruct(iter->opal_dev); 1068 return; 1069 } 1070 while (getchar() != '\n'); 1071 1072 ret = spdk_opal_cmd_setup_locking_range(iter->opal_dev, 1073 OPAL_ADMIN1, locking_range_id, range_start, range_length, passwd_p); 1074 if (ret) { 1075 printf("Setup locking range failure: %d\n", ret); 1076 spdk_opal_dev_destruct(iter->opal_dev); 1077 return; 1078 } 1079 1080 ret = spdk_opal_cmd_get_locking_range_info(iter->opal_dev, 1081 passwd_p, OPAL_ADMIN1, locking_range_id); 1082 if (ret) { 1083 printf("Get locking range info failure: %d\n", ret); 1084 spdk_opal_dev_destruct(iter->opal_dev); 1085 return; 1086 } 1087 info = spdk_opal_get_locking_range_info(iter->opal_dev, locking_range_id); 1088 1089 printf("\nlocking range ID: %d\n", info->locking_range_id); 1090 printf("range start: %" PRIu64 "\n", info->range_start); 1091 printf("range length: %" PRIu64 "\n", info->range_length); 1092 printf("read lock enabled: %d\n", info->read_lock_enabled); 1093 printf("write lock enabled: %d\n", info->write_lock_enabled); 1094 printf("read locked: %d\n", info->read_locked); 1095 printf("write locked: %d\n", info->write_locked); 1096 1097 printf("...\n...\nOpal setup locking range success\n"); 1098 } else { 1099 printf("Input password invalid. Opal setup locking range failure\n"); 1100 } 1101 spdk_opal_dev_destruct(iter->opal_dev); 1102 } else { 1103 printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n", 1104 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 1105 } 1106 } 1107 1108 static void 1109 opal_list_locking_ranges(struct dev *iter) 1110 { 1111 char passwd[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 1112 char *passwd_p; 1113 int ret; 1114 int ch; 1115 int max_ranges; 1116 int i; 1117 struct spdk_opal_locking_range_info *info; 1118 1119 if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { 1120 iter->opal_dev = spdk_opal_dev_construct(iter->ctrlr); 1121 if (iter->opal_dev == NULL) { 1122 return; 1123 } 1124 printf("Please input password:"); 1125 while ((ch = getchar()) != '\n' && ch != EOF); 1126 passwd_p = get_line(passwd, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 1127 printf("\n"); 1128 if (passwd_p) { 1129 ret = spdk_opal_cmd_get_max_ranges(iter->opal_dev, passwd_p); 1130 if (ret <= 0) { 1131 printf("get max ranges failure: %d\n", ret); 1132 spdk_opal_dev_destruct(iter->opal_dev); 1133 return; 1134 } 1135 1136 max_ranges = ret; 1137 for (i = 0; i < max_ranges; i++) { 1138 ret = spdk_opal_cmd_get_locking_range_info(iter->opal_dev, 1139 passwd_p, OPAL_ADMIN1, i); 1140 if (ret) { 1141 printf("Get locking range info failure: %d\n", ret); 1142 spdk_opal_dev_destruct(iter->opal_dev); 1143 return; 1144 } 1145 info = spdk_opal_get_locking_range_info(iter->opal_dev, i); 1146 if (info == NULL) { 1147 continue; 1148 } 1149 1150 printf("===============================================\n"); 1151 printf("locking range ID: %d\t", info->locking_range_id); 1152 if (i == 0) { printf("(Global Range)"); } 1153 printf("\n===============================================\n"); 1154 printf("range start: %" PRIu64 "\t", info->range_start); 1155 printf("range length: %" PRIu64 "\n", info->range_length); 1156 printf("read lock enabled: %d\t", info->read_lock_enabled); 1157 printf("write lock enabled: %d\t", info->write_lock_enabled); 1158 printf("read locked: %d\t", info->read_locked); 1159 printf("write locked: %d\n", info->write_locked); 1160 printf("\n"); 1161 } 1162 } else { 1163 printf("Input password invalid. List locking ranges failure\n"); 1164 } 1165 spdk_opal_dev_destruct(iter->opal_dev); 1166 } else { 1167 printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n", 1168 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 1169 } 1170 } 1171 1172 static void 1173 opal_new_user_enable(struct dev *iter) 1174 { 1175 int user_id; 1176 char passwd[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 1177 char *passwd_p; 1178 char user_pw[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 1179 char *user_pw_p; 1180 int ret; 1181 int ch; 1182 1183 if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { 1184 iter->opal_dev = spdk_opal_dev_construct(iter->ctrlr); 1185 if (iter->opal_dev == NULL) { 1186 return; 1187 } 1188 printf("Please input admin password:"); 1189 while ((ch = getchar()) != '\n' && ch != EOF); 1190 passwd_p = get_line(passwd, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 1191 printf("\n"); 1192 if (passwd_p) { 1193 printf("which user to enable: "); 1194 if (!scanf("%d", &user_id)) { 1195 printf("Invalid user id\n"); 1196 spdk_opal_dev_destruct(iter->opal_dev); 1197 return; 1198 } 1199 1200 ret = spdk_opal_cmd_enable_user(iter->opal_dev, user_id, passwd_p); 1201 if (ret) { 1202 printf("Enable user failure error code: %d\n", ret); 1203 spdk_opal_dev_destruct(iter->opal_dev); 1204 return; 1205 } 1206 printf("Please set a new password for this user:"); 1207 while ((ch = getchar()) != '\n' && ch != EOF); 1208 user_pw_p = get_line(user_pw, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 1209 if (user_pw_p == NULL) { 1210 printf("Input password invalid. Enable user failure\n"); 1211 spdk_opal_dev_destruct(iter->opal_dev); 1212 return; 1213 } 1214 1215 ret = spdk_opal_cmd_set_new_passwd(iter->opal_dev, user_id, user_pw_p, passwd_p, true); 1216 if (ret) { 1217 printf("Set new password failure error code: %d\n", ret); 1218 spdk_opal_dev_destruct(iter->opal_dev); 1219 return; 1220 } 1221 1222 printf("\n...\n...\nEnable User Success\n"); 1223 } else { 1224 printf("Input password invalid. Enable user failure\n"); 1225 } 1226 spdk_opal_dev_destruct(iter->opal_dev); 1227 } else { 1228 printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n", 1229 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 1230 } 1231 } 1232 1233 static void 1234 opal_change_password(struct dev *iter) 1235 { 1236 int user_id; 1237 char old_passwd[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 1238 char *old_passwd_p; 1239 char new_passwd[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 1240 char *new_passwd_p; 1241 int ret; 1242 int ch; 1243 1244 if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { 1245 iter->opal_dev = spdk_opal_dev_construct(iter->ctrlr); 1246 if (iter->opal_dev == NULL) { 1247 return; 1248 } 1249 printf("user id: "); 1250 if (!scanf("%d", &user_id)) { 1251 printf("Invalid user id\n"); 1252 spdk_opal_dev_destruct(iter->opal_dev); 1253 return; 1254 } 1255 printf("Password:"); 1256 while ((ch = getchar()) != '\n' && ch != EOF); 1257 old_passwd_p = get_line(old_passwd, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 1258 printf("\n"); 1259 if (old_passwd_p) { 1260 printf("Please input new password:\n"); 1261 new_passwd_p = get_line(new_passwd, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 1262 printf("\n"); 1263 if (new_passwd_p == NULL) { 1264 printf("Input password invalid. Change password failure\n"); 1265 spdk_opal_dev_destruct(iter->opal_dev); 1266 return; 1267 } 1268 1269 ret = spdk_opal_cmd_set_new_passwd(iter->opal_dev, user_id, new_passwd_p, old_passwd_p, false); 1270 if (ret) { 1271 printf("Set new password failure error code: %d\n", ret); 1272 spdk_opal_dev_destruct(iter->opal_dev); 1273 return; 1274 } 1275 1276 printf("...\n...\nChange password Success\n"); 1277 } else { 1278 printf("Input password invalid. Change password failure\n"); 1279 } 1280 spdk_opal_dev_destruct(iter->opal_dev); 1281 } else { 1282 printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n", 1283 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 1284 } 1285 } 1286 1287 static void 1288 opal_add_user_to_locking_range(struct dev *iter) 1289 { 1290 int locking_range_id, user_id; 1291 char passwd[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 1292 char *passwd_p; 1293 int ret; 1294 int ch; 1295 1296 if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { 1297 iter->opal_dev = spdk_opal_dev_construct(iter->ctrlr); 1298 if (iter->opal_dev == NULL) { 1299 return; 1300 } 1301 printf("Please input admin password:"); 1302 while ((ch = getchar()) != '\n' && ch != EOF); 1303 passwd_p = get_line(passwd, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 1304 printf("\n"); 1305 if (passwd_p) { 1306 printf("Specify locking range id:\n"); 1307 if (!scanf("%d", &locking_range_id)) { 1308 printf("Invalid locking range id\n"); 1309 spdk_opal_dev_destruct(iter->opal_dev); 1310 return; 1311 } 1312 1313 printf("which user to enable:\n"); 1314 if (!scanf("%d", &user_id)) { 1315 printf("Invalid user id\n"); 1316 spdk_opal_dev_destruct(iter->opal_dev); 1317 return; 1318 } 1319 while (getchar() != '\n'); 1320 1321 ret = spdk_opal_cmd_add_user_to_locking_range(iter->opal_dev, user_id, locking_range_id, 1322 OPAL_READONLY, passwd_p); 1323 ret += spdk_opal_cmd_add_user_to_locking_range(iter->opal_dev, user_id, locking_range_id, 1324 OPAL_READWRITE, passwd_p); 1325 if (ret) { 1326 printf("Add user to locking range error: %d\n", ret); 1327 spdk_opal_dev_destruct(iter->opal_dev); 1328 return; 1329 } 1330 1331 printf("...\n...\nAdd user to locking range Success\n"); 1332 } else { 1333 printf("Input password invalid. Add user to locking range failure\n"); 1334 } 1335 spdk_opal_dev_destruct(iter->opal_dev); 1336 } else { 1337 printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n", 1338 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 1339 } 1340 } 1341 1342 static void 1343 opal_user_lock_unlock_range(struct dev *iter) 1344 { 1345 char passwd[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 1346 char *passwd_p; 1347 int ch; 1348 int ret; 1349 int user_id; 1350 int locking_range_id; 1351 int state; 1352 enum spdk_opal_lock_state state_flag; 1353 1354 if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { 1355 iter->opal_dev = spdk_opal_dev_construct(iter->ctrlr); 1356 if (iter->opal_dev == NULL) { 1357 return; 1358 } 1359 printf("User id: "); 1360 if (!scanf("%d", &user_id)) { 1361 printf("Invalid user id\n"); 1362 spdk_opal_dev_destruct(iter->opal_dev); 1363 return; 1364 } 1365 1366 printf("Please input password:"); 1367 while ((ch = getchar()) != '\n' && ch != EOF); 1368 passwd_p = get_line(passwd, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 1369 printf("\n"); 1370 if (passwd_p) { 1371 printf("Specify locking range id:\n"); 1372 if (!scanf("%d", &locking_range_id)) { 1373 printf("Invalid locking range id\n"); 1374 spdk_opal_dev_destruct(iter->opal_dev); 1375 return; 1376 } 1377 1378 opal_locking_usage(); 1379 if (!scanf("%d", &state)) { 1380 printf("Invalid option\n"); 1381 } 1382 switch (state) { 1383 case 1: 1384 state_flag = OPAL_RWLOCK; 1385 break; 1386 case 2: 1387 state_flag = OPAL_READONLY; 1388 break; 1389 case 3: 1390 state_flag = OPAL_READWRITE; 1391 break; 1392 default: 1393 printf("Invalid options\n"); 1394 spdk_opal_dev_destruct(iter->opal_dev); 1395 return; 1396 } 1397 while (getchar() != '\n'); 1398 1399 ret = spdk_opal_cmd_lock_unlock(iter->opal_dev, user_id, state_flag, 1400 locking_range_id, passwd_p); 1401 if (ret) { 1402 printf("lock/unlock range failure: %d\n", ret); 1403 spdk_opal_dev_destruct(iter->opal_dev); 1404 return; 1405 } 1406 printf("...\n...\nLock/unlock range Success\n"); 1407 } else { 1408 printf("Input password invalid. lock/unlock range failure\n"); 1409 } 1410 spdk_opal_dev_destruct(iter->opal_dev); 1411 } else { 1412 printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n", 1413 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 1414 } 1415 } 1416 1417 static void 1418 opal_revert_tper(struct dev *iter) 1419 { 1420 char passwd[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 1421 char *passwd_p; 1422 int ret; 1423 int ch; 1424 1425 if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { 1426 iter->opal_dev = spdk_opal_dev_construct(iter->ctrlr); 1427 if (iter->opal_dev == NULL) { 1428 return; 1429 } 1430 printf("Please be noted this operation will erase ALL DATA on this drive\n"); 1431 printf("Please don't terminate this execution. Otherwise undefined error may occur\n"); 1432 printf("Please input password for revert TPer:"); 1433 while ((ch = getchar()) != '\n' && ch != EOF); 1434 passwd_p = get_line(passwd, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 1435 printf("\n...\n"); 1436 if (passwd_p) { 1437 ret = spdk_opal_cmd_revert_tper(iter->opal_dev, passwd_p); 1438 if (ret) { 1439 printf("Revert TPer failure: %d\n", ret); 1440 spdk_opal_dev_destruct(iter->opal_dev); 1441 return; 1442 } 1443 printf("...\nRevert TPer Success\n"); 1444 } else { 1445 printf("Input password invalid. Revert TPer failure\n"); 1446 } 1447 spdk_opal_dev_destruct(iter->opal_dev); 1448 } else { 1449 printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n", 1450 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 1451 } 1452 } 1453 1454 static void 1455 opal_erase_locking_range(struct dev *iter) 1456 { 1457 char passwd[SPDK_OPAL_MAX_PASSWORD_SIZE] = {0}; 1458 char *passwd_p; 1459 int ret; 1460 int ch; 1461 int locking_range_id; 1462 1463 if (spdk_nvme_ctrlr_get_flags(iter->ctrlr) & SPDK_NVME_CTRLR_SECURITY_SEND_RECV_SUPPORTED) { 1464 iter->opal_dev = spdk_opal_dev_construct(iter->ctrlr); 1465 if (iter->opal_dev == NULL) { 1466 return; 1467 } 1468 printf("Please be noted this operation will erase ALL DATA on this range\n"); 1469 printf("Please input password for erase locking range:"); 1470 while ((ch = getchar()) != '\n' && ch != EOF); 1471 passwd_p = get_line(passwd, SPDK_OPAL_MAX_PASSWORD_SIZE, stdin, true); 1472 if (passwd_p) { 1473 printf("\nSpecify locking range id:\n"); 1474 if (!scanf("%d", &locking_range_id)) { 1475 printf("Invalid locking range id\n"); 1476 spdk_opal_dev_destruct(iter->opal_dev); 1477 return; 1478 } 1479 printf("\n...\n"); 1480 ret = spdk_opal_cmd_secure_erase_locking_range(iter->opal_dev, OPAL_ADMIN1, locking_range_id, 1481 passwd_p); 1482 if (ret) { 1483 printf("Erase locking range failure: %d\n", ret); 1484 spdk_opal_dev_destruct(iter->opal_dev); 1485 return; 1486 } 1487 printf("...\nErase locking range Success\n"); 1488 } else { 1489 printf("Input password invalid. Erase locking range failure\n"); 1490 } 1491 spdk_opal_dev_destruct(iter->opal_dev); 1492 } else { 1493 printf("%04x:%02x:%02x.%02x: NVMe Security Support/Receive Not supported.\nOpal Not Supported\n\n\n", 1494 iter->pci_addr.domain, iter->pci_addr.bus, iter->pci_addr.dev, iter->pci_addr.func); 1495 } 1496 } 1497 1498 static void 1499 test_opal(void) 1500 { 1501 int exit_flag = false; 1502 struct dev *ctrlr; 1503 1504 ctrlr = get_controller(); 1505 if (ctrlr == NULL) { 1506 printf("Invalid controller PCI Address.\n"); 1507 return; 1508 } 1509 1510 opal_usage(); 1511 while (!exit_flag) { 1512 int cmd; 1513 if (!scanf("%d", &cmd)) { 1514 printf("Invalid Command: command must be number 0-9\n"); 1515 while (getchar() != '\n'); 1516 opal_usage(); 1517 continue; 1518 } 1519 1520 switch (cmd) { 1521 case 0: 1522 exit_flag = true; 1523 continue; 1524 case 1: 1525 opal_scan(ctrlr); 1526 break; 1527 case 2: 1528 opal_init(ctrlr); /* Take ownership, Activate Locking SP */ 1529 break; 1530 case 3: 1531 opal_revert_tper(ctrlr); 1532 break; 1533 case 4: 1534 opal_setup_lockingrange(ctrlr); 1535 break; 1536 case 5: 1537 opal_list_locking_ranges(ctrlr); 1538 break; 1539 case 6: 1540 opal_new_user_enable(ctrlr); 1541 break; 1542 case 7: 1543 opal_change_password(ctrlr); 1544 break; 1545 case 8: 1546 opal_add_user_to_locking_range(ctrlr); 1547 break; 1548 case 9: 1549 opal_user_lock_unlock_range(ctrlr); 1550 break; 1551 case 10: 1552 opal_erase_locking_range(ctrlr); 1553 break; 1554 1555 default: 1556 printf("Invalid option\n"); 1557 } 1558 1559 printf("\npress Enter to display Opal cmd menu ...\n"); 1560 while (getchar() != '\n'); 1561 opal_usage(); 1562 } 1563 } 1564 1565 static void 1566 args_usage(const char *program_name) 1567 { 1568 printf("%s [options]", program_name); 1569 printf("\n"); 1570 printf("options:\n"); 1571 printf(" -i shared memory group ID\n"); 1572 } 1573 1574 static int 1575 parse_args(int argc, char **argv) 1576 { 1577 int op; 1578 1579 while ((op = getopt(argc, argv, "i:")) != -1) { 1580 switch (op) { 1581 case 'i': 1582 g_shm_id = spdk_strtol(optarg, 10); 1583 if (g_shm_id < 0) { 1584 fprintf(stderr, "Invalid shared memory ID\n"); 1585 return g_shm_id; 1586 } 1587 break; 1588 default: 1589 args_usage(argv[0]); 1590 return 1; 1591 } 1592 } 1593 1594 return 0; 1595 } 1596 1597 int 1598 main(int argc, char **argv) 1599 { 1600 int rc; 1601 struct spdk_env_opts opts; 1602 struct dev *dev; 1603 struct spdk_nvme_detach_ctx *detach_ctx = NULL; 1604 1605 rc = parse_args(argc, argv); 1606 if (rc != 0) { 1607 return rc; 1608 } 1609 1610 opts.opts_size = sizeof(opts); 1611 spdk_env_opts_init(&opts); 1612 opts.name = "nvme_manage"; 1613 opts.core_mask = "0x1"; 1614 opts.shm_id = g_shm_id; 1615 if (spdk_env_init(&opts) < 0) { 1616 fprintf(stderr, "Unable to initialize SPDK env\n"); 1617 return 1; 1618 } 1619 1620 if (spdk_nvme_probe(NULL, NULL, probe_cb, attach_cb, NULL) != 0) { 1621 fprintf(stderr, "spdk_nvme_probe() failed\n"); 1622 spdk_env_fini(); 1623 return 1; 1624 } 1625 1626 qsort(devs, num_devs, sizeof(devs[0]), cmp_devs); 1627 1628 usage(); 1629 1630 while (1) { 1631 int cmd; 1632 bool exit_flag = false; 1633 1634 if (!scanf("%d", &cmd)) { 1635 printf("Invalid Command: command must be number 1-8\n"); 1636 while (getchar() != '\n'); 1637 usage(); 1638 continue; 1639 } 1640 switch (cmd) { 1641 case 1: 1642 display_controller_list(); 1643 break; 1644 case 2: 1645 add_ns(); 1646 break; 1647 case 3: 1648 delete_ns(); 1649 break; 1650 case 4: 1651 attach_and_detach_ns(SPDK_NVME_NS_CTRLR_ATTACH); 1652 break; 1653 case 5: 1654 attach_and_detach_ns(SPDK_NVME_NS_CTRLR_DETACH); 1655 break; 1656 case 6: 1657 format_nvm(); 1658 break; 1659 case 7: 1660 update_firmware_image(); 1661 break; 1662 case 8: 1663 test_opal(); 1664 break; 1665 case 9: 1666 exit_flag = true; 1667 break; 1668 default: 1669 printf("Invalid Command\n"); 1670 break; 1671 } 1672 1673 if (exit_flag) { 1674 break; 1675 } 1676 1677 while (getchar() != '\n'); 1678 printf("press Enter to display cmd menu ...\n"); 1679 while (getchar() != '\n'); 1680 usage(); 1681 } 1682 1683 printf("Cleaning up...\n"); 1684 1685 foreach_dev(dev) { 1686 spdk_nvme_detach_async(dev->ctrlr, &detach_ctx); 1687 } 1688 1689 if (detach_ctx) { 1690 spdk_nvme_detach_poll(detach_ctx); 1691 } 1692 1693 spdk_env_fini(); 1694 1695 return 0; 1696 } 1697