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