2 * Copyright (C) 2012 Intel Corporation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
30 #include <sys/param.h>
31 #include <sys/ioccom.h>
34 #include <dev/nvme/nvme.h>
47 #define DEVLIST_USAGE \
48 " nvmecontrol devlist\n"
50 #define IDENTIFY_USAGE \
51 " nvmecontrol identify <controller id|namespace id>\n"
53 #define PERFTEST_USAGE \
54 " nvmecontrol perftest <-n num_threads> <-o read|write>\n" \
55 " <-s size_in_bytes> <-t time_in_seconds>\n" \
56 " <-i intr|wait> [-f refthread] [-p]\n" \
60 " nvmecontrol reset <controller id>\n"
62 static void perftest_usage(void);
67 fprintf(stderr, "usage:\n");
68 fprintf(stderr, DEVLIST_USAGE);
69 fprintf(stderr, IDENTIFY_USAGE);
70 fprintf(stderr, RESET_USAGE);
71 fprintf(stderr, PERFTEST_USAGE);
76 print_controller_hex(struct nvme_controller_data *cdata, uint32_t length)
81 p = (uint32_t *)cdata;
82 length /= sizeof(uint32_t);
84 for (i = 0; i < length; i+=8) {
85 printf("%03x: ", i*4);
86 for (j = 0; j < 8; j++)
87 printf("%08x ", p[i+j]);
95 print_controller(struct nvme_controller_data *cdata)
97 printf("Controller Capabilities/Features\n");
98 printf("================================\n");
99 printf("Vendor ID: %04x\n", cdata->vid);
100 printf("Subsystem Vendor ID: %04x\n", cdata->ssvid);
101 printf("Serial Number: %s\n", cdata->sn);
102 printf("Model Number: %s\n", cdata->mn);
103 printf("Firmware Version: %s\n", cdata->fr);
104 printf("Recommended Arb Burst: %d\n", cdata->rab);
105 printf("IEEE OUI Identifier: %02x %02x %02x\n",
106 cdata->ieee[0], cdata->ieee[1], cdata->ieee[2]);
107 printf("Multi-Interface Cap: %02x\n", cdata->mic);
108 /* TODO: Use CAP.MPSMIN to determine true memory page size. */
109 printf("Max Data Transfer Size: ");
110 if (cdata->mdts == 0)
111 printf("Unlimited\n");
113 printf("%d\n", PAGE_SIZE * (1 << cdata->mdts));
116 printf("Admin Command Set Attributes\n");
117 printf("============================\n");
118 printf("Security Send/Receive: %s\n",
119 cdata->oacs.security ? "Supported" : "Not Supported");
120 printf("Format NVM: %s\n",
121 cdata->oacs.format ? "Supported" : "Not Supported");
122 printf("Firmware Activate/Download: %s\n",
123 cdata->oacs.firmware ? "Supported" : "Not Supported");
124 printf("Abort Command Limit: %d\n", cdata->acl+1);
125 printf("Async Event Request Limit: %d\n", cdata->aerl+1);
126 printf("Number of Firmware Slots: ");
127 if (cdata->oacs.firmware != 0)
128 printf("%d\n", cdata->frmw.num_slots);
131 printf("Firmware Slot 1 Read-Only: ");
132 if (cdata->oacs.firmware != 0)
133 printf("%s\n", cdata->frmw.slot1_ro ? "Yes" : "No");
136 printf("Per-Namespace SMART Log: %s\n",
137 cdata->lpa.ns_smart ? "Yes" : "No");
138 printf("Error Log Page Entries: %d\n", cdata->elpe+1);
139 printf("Number of Power States: %d\n", cdata->npss+1);
142 printf("NVM Command Set Attributes\n");
143 printf("==========================\n");
144 printf("Submission Queue Entry Size\n");
145 printf(" Max: %d\n", 1 << cdata->sqes.max);
146 printf(" Min: %d\n", 1 << cdata->sqes.min);
147 printf("Completion Queue Entry Size\n");
148 printf(" Max: %d\n", 1 << cdata->cqes.max);
149 printf(" Min: %d\n", 1 << cdata->cqes.min);
150 printf("Number of Namespaces: %d\n", cdata->nn);
151 printf("Compare Command: %s\n",
152 cdata->oncs.compare ? "Supported" : "Not Supported");
153 printf("Write Uncorrectable Command: %s\n",
154 cdata->oncs.write_unc ? "Supported" : "Not Supported");
155 printf("Dataset Management Command: %s\n",
156 cdata->oncs.dsm ? "Supported" : "Not Supported");
157 printf("Volatile Write Cache: %s\n",
158 cdata->vwc.present ? "Present" : "Not Present");
162 print_namespace_hex(struct nvme_namespace_data *nsdata, uint32_t length)
167 p = (uint32_t *)nsdata;
168 length /= sizeof(uint32_t);
170 for (i = 0; i < length; i+=8) {
171 printf("%03x: ", i*4);
172 for (j = 0; j < 8; j++)
173 printf("%08x ", p[i+j]);
181 print_namespace(struct nvme_namespace_data *nsdata)
185 printf("Size (in LBAs): %lld (%lldM)\n",
186 (long long)nsdata->nsze,
187 (long long)nsdata->nsze / 1024 / 1024);
188 printf("Capacity (in LBAs): %lld (%lldM)\n",
189 (long long)nsdata->ncap,
190 (long long)nsdata->ncap / 1024 / 1024);
191 printf("Utilization (in LBAs): %lld (%lldM)\n",
192 (long long)nsdata->nuse,
193 (long long)nsdata->nuse / 1024 / 1024);
194 printf("Thin Provisioning: %s\n",
195 nsdata->nsfeat.thin_prov ? "Supported" : "Not Supported");
196 printf("Number of LBA Formats: %d\n", nsdata->nlbaf+1);
197 printf("Current LBA Format: LBA Format #%d\n",
198 nsdata->flbas.format);
199 for (i = 0; i <= nsdata->nlbaf; i++) {
200 printf("LBA Format #%d:\n", i);
201 printf(" LBA Data Size: %d\n",
202 1 << nsdata->lbaf[i].lbads);
207 ns_get_sector_size(struct nvme_namespace_data *nsdata)
210 return (1 << nsdata->lbaf[0].lbads);
214 read_controller_data(int fd, struct nvme_controller_data *cdata)
216 struct nvme_pt_command pt;
218 memset(&pt, 0, sizeof(pt));
219 pt.cmd.opc = NVME_OPC_IDENTIFY;
222 pt.len = sizeof(*cdata);
225 if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
226 printf("Identify request failed. errno=%d (%s)\n",
227 errno, strerror(errno));
231 if (nvme_completion_is_error(&pt.cpl)) {
232 printf("Passthrough command returned error.\n");
238 read_namespace_data(int fd, int nsid, struct nvme_namespace_data *nsdata)
240 struct nvme_pt_command pt;
242 memset(&pt, 0, sizeof(pt));
243 pt.cmd.opc = NVME_OPC_IDENTIFY;
246 pt.len = sizeof(*nsdata);
249 if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0) {
250 printf("Identify request failed. errno=%d (%s)\n",
251 errno, strerror(errno));
255 if (nvme_completion_is_error(&pt.cpl)) {
256 printf("Passthrough command returned error.\n");
262 devlist(int argc, char *argv[])
264 struct nvme_controller_data cdata;
265 struct nvme_namespace_data nsdata;
267 char name[64], path[64];
269 int ch, ctrlr, exit_code, fd, found;
273 while ((ch = getopt(argc, argv, "")) != -1) {
285 sprintf(name, "nvme%d", ctrlr);
286 sprintf(path, "/dev/%s", name);
288 if (stat(path, &devstat) != 0)
293 fd = open(path, O_RDWR);
295 printf("Could not open %s. errno=%d (%s)\n", path,
296 errno, strerror(errno));
297 exit_code = EX_NOPERM;
301 read_controller_data(fd, &cdata);
302 printf("%6s: %s\n", name, cdata.mn);
304 for (i = 0; i < cdata.nn; i++) {
305 sprintf(name, "nvme%dns%d", ctrlr, i+1);
306 read_namespace_data(fd, i+1, &nsdata);
307 printf(" %10s (%lldGB)\n",
310 (long long)ns_get_sector_size(&nsdata) /
316 printf("No NVMe controllers found.\n");
322 identify_ctrlr(int argc, char *argv[])
324 struct nvme_controller_data cdata;
327 int ch, fd, hexflag = 0, hexlength;
330 while ((ch = getopt(argc, argv, "vx")) != -1) {
343 sprintf(path, "/dev/%s", argv[optind]);
345 if (stat(path, &devstat) < 0) {
346 printf("Invalid device node %s. errno=%d (%s)\n", path, errno,
351 fd = open(path, O_RDWR);
353 printf("Could not open %s. errno=%d (%s)\n", path, errno,
358 read_controller_data(fd, &cdata);
361 if (verboseflag == 1)
362 hexlength = sizeof(struct nvme_controller_data);
364 hexlength = offsetof(struct nvme_controller_data,
366 print_controller_hex(&cdata, hexlength);
370 if (verboseflag == 1) {
371 printf("-v not currently supported without -x.\n");
375 print_controller(&cdata);
380 identify_ns(int argc, char *argv[])
382 struct nvme_namespace_data nsdata;
386 int ch, fd, hexflag = 0, hexlength, nsid;
389 while ((ch = getopt(argc, argv, "vx")) != -1) {
403 * Check if the specified device node exists before continuing.
404 * This is a cleaner check for cases where the correct controller
405 * is specified, but an invalid namespace on that controller.
407 sprintf(path, "/dev/%s", argv[optind]);
408 if (stat(path, &devstat) < 0) {
409 printf("Invalid device node %s. errno=%d (%s)\n", path, errno,
414 nsloc = strstr(argv[optind], "ns");
416 printf("Invalid namepsace %s.\n", argv[optind]);
421 * Pull the namespace id from the string. +2 skips past the "ns" part
424 nsid = strtol(nsloc + 2, NULL, 10);
425 if (nsid == 0 && errno != 0) {
426 printf("Invalid namespace ID %s.\n", argv[optind]);
431 * We send IDENTIFY commands to the controller, not the namespace,
432 * since it is an admin cmd. So the path should only include the
433 * nvmeX part of the nvmeXnsY string.
435 sprintf(path, "/dev/");
436 strncat(path, argv[optind], nsloc - argv[optind]);
437 if (stat(path, &devstat) < 0) {
438 printf("Invalid device node %s. errno=%d (%s)\n", path, errno,
443 fd = open(path, O_RDWR);
445 printf("Could not open %s. errno=%d (%s)\n", path, errno,
450 read_namespace_data(fd, nsid, &nsdata);
453 if (verboseflag == 1)
454 hexlength = sizeof(struct nvme_namespace_data);
456 hexlength = offsetof(struct nvme_namespace_data,
458 print_namespace_hex(&nsdata, hexlength);
462 if (verboseflag == 1) {
463 printf("-v not currently supported without -x.\n");
467 print_namespace(&nsdata);
472 identify(int argc, char *argv[])
479 while (getopt(argc, argv, "vx") != -1) ;
481 target = argv[optind];
483 /* Specified device node must have "nvme" in it. */
484 if (strstr(argv[optind], "nvme") == NULL) {
485 printf("Invalid device node '%s'.\n", argv[optind]);
493 * If device node contains "ns", we consider it a namespace,
494 * otherwise, consider it a controller.
496 if (strstr(target, "ns") == NULL)
497 identify_ctrlr(argc, argv);
499 identify_ns(argc, argv);
503 print_perftest(struct nvme_io_test *io_test, bool perthread)
505 uint32_t i, io_completed = 0, iops, mbps;
507 for (i = 0; i < io_test->num_threads; i++)
508 io_completed += io_test->io_completed[i];
510 iops = io_completed/io_test->time;
511 mbps = iops * io_test->size / (1024*1024);
513 printf("Threads: %2d Size: %6d %5s Time: %3d IO/s: %7d MB/s: %4d\n",
514 io_test->num_threads, io_test->size,
515 io_test->opc == NVME_OPC_READ ? "READ" : "WRITE",
516 io_test->time, iops, mbps);
519 for (i = 0; i < io_test->num_threads; i++)
520 printf("\t%3d: %8d IO/s\n", i,
521 io_test->io_completed[i]/io_test->time);
529 fprintf(stderr, "usage:\n");
530 fprintf(stderr, PERFTEST_USAGE);
535 perftest(int argc, char *argv[])
537 struct nvme_io_test io_test;
543 u_long ioctl_cmd = NVME_IO_TEST;
544 bool nflag, oflag, sflag, tflag;
547 nflag = oflag = sflag = tflag = false;
550 memset(&io_test, 0, sizeof(io_test));
552 while ((ch = getopt(argc, argv, "f:i:n:o:ps:t:")) != -1) {
555 if (!strcmp(optarg, "refthread"))
556 io_test.flags |= NVME_TEST_FLAG_REFTHREAD;
559 if (!strcmp(optarg, "bio") ||
560 !strcmp(optarg, "wait"))
561 ioctl_cmd = NVME_BIO_TEST;
562 else if (!strcmp(optarg, "io") ||
563 !strcmp(optarg, "intr"))
564 ioctl_cmd = NVME_IO_TEST;
568 io_test.num_threads = strtoul(optarg, &p, 0);
569 if (p != NULL && *p != '\0') {
571 "\"%s\" not valid number of threads.\n",
574 } else if (io_test.num_threads == 0 ||
575 io_test.num_threads > 128) {
577 "\"%s\" not valid number of threads.\n",
584 if (!strcmp(optarg, "read") || !strcmp(optarg, "READ"))
585 io_test.opc = NVME_OPC_READ;
586 else if (!strcmp(optarg, "write") ||
587 !strcmp(optarg, "WRITE"))
588 io_test.opc = NVME_OPC_WRITE;
590 fprintf(stderr, "\"%s\" not valid opcode.\n",
600 io_test.size = strtoul(optarg, &p, 0);
601 if (p == NULL || *p == '\0' || toupper(*p) == 'B') {
603 } else if (toupper(*p) == 'K') {
604 io_test.size *= 1024;
605 } else if (toupper(*p) == 'M') {
606 io_test.size *= 1024 * 1024;
608 fprintf(stderr, "\"%s\" not valid size.\n",
615 io_test.time = strtoul(optarg, &p, 0);
616 if (p != NULL && *p != '\0') {
618 "\"%s\" not valid time duration.\n",
628 if (!nflag || !oflag || !sflag || !tflag || name == NULL)
631 sprintf(path, "/dev/%s", name);
633 fd = open(path, O_RDWR);
635 fprintf(stderr, "%s not valid device. errno=%d (%s)\n", path,
636 errno, strerror(errno));
640 if (ioctl(fd, ioctl_cmd, &io_test) < 0) {
641 fprintf(stderr, "NVME_IO_TEST failed. errno=%d (%s)\n", errno,
646 print_perftest(&io_test, perthread);
651 reset_ctrlr(int argc, char *argv[])
657 while ((ch = getopt(argc, argv, "")) != -1) {
664 sprintf(path, "/dev/%s", argv[optind]);
666 if (stat(path, &devstat) < 0) {
667 printf("Invalid device node %s. errno=%d (%s)\n", path, errno,
672 fd = open(path, O_RDWR);
674 printf("Could not open %s. errno=%d (%s)\n", path, errno,
679 if (ioctl(fd, NVME_RESET_CONTROLLER) < 0) {
680 printf("Reset request to %s failed. errno=%d (%s)\n", path,
681 errno, strerror(errno));
689 main(int argc, char *argv[])
695 if (strcmp(argv[1], "devlist") == 0)
696 devlist(argc-1, &argv[1]);
697 else if (strcmp(argv[1], "identify") == 0)
698 identify(argc-1, &argv[1]);
699 else if (strcmp(argv[1], "perftest") == 0)
700 perftest(argc-1, &argv[1]);
701 else if (strcmp(argv[1], "reset") == 0)
702 reset_ctrlr(argc-1, &argv[1]);