2 * Copyright (C) 2012-2013 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 open_dev(const char *str, int *fd, int show_error, int exit_on_error)
267 snprintf(full_path, sizeof(full_path), "/dev/%s", str);
268 if (stat(full_path, &devstat) != 0) {
270 fprintf(stderr, "error\n");
277 *fd = open(full_path, O_RDWR);
280 printf("Could not open %s. errno=%d (%s)\n", full_path,
281 errno, strerror(errno));
294 fprintf(stderr, "usage:\n");
295 fprintf(stderr, DEVLIST_USAGE);
300 devlist(int argc, char *argv[])
302 struct nvme_controller_data cdata;
303 struct nvme_namespace_data nsdata;
306 int ch, ctrlr, exit_code, fd, found;
310 while ((ch = getopt(argc, argv, "")) != -1) {
322 sprintf(name, "nvme%d", ctrlr);
324 exit_code = open_dev(name, &fd, 0, 0);
326 if (exit_code == EX_NOINPUT)
328 else if (exit_code == EX_NOPERM) {
329 printf("Could not open /dev/%s, errno = %d (%s)\n",
330 name, errno, strerror(errno));
335 read_controller_data(fd, &cdata);
336 printf("%6s: %s\n", name, cdata.mn);
338 for (i = 0; i < cdata.nn; i++) {
339 sprintf(name, "nvme%dns%d", ctrlr, i+1);
340 read_namespace_data(fd, i+1, &nsdata);
341 printf(" %10s (%lldGB)\n",
344 (long long)ns_get_sector_size(&nsdata) /
352 printf("No NVMe controllers found.\n");
360 fprintf(stderr, "usage:\n");
361 fprintf(stderr, IDENTIFY_USAGE);
366 identify_ctrlr(int argc, char *argv[])
368 struct nvme_controller_data cdata;
369 int ch, fd, hexflag = 0, hexlength;
372 while ((ch = getopt(argc, argv, "vx")) != -1) {
385 open_dev(argv[optind], &fd, 1, 1);
386 read_controller_data(fd, &cdata);
390 if (verboseflag == 1)
391 hexlength = sizeof(struct nvme_controller_data);
393 hexlength = offsetof(struct nvme_controller_data,
395 print_controller_hex(&cdata, hexlength);
399 if (verboseflag == 1) {
400 printf("-v not currently supported without -x.\n");
404 print_controller(&cdata);
409 identify_ns(int argc, char *argv[])
411 struct nvme_namespace_data nsdata;
414 int ch, fd, hexflag = 0, hexlength, nsid;
417 while ((ch = getopt(argc, argv, "vx")) != -1) {
431 * Check if the specified device node exists before continuing.
432 * This is a cleaner check for cases where the correct controller
433 * is specified, but an invalid namespace on that controller.
435 open_dev(argv[optind], &fd, 1, 1);
439 * Pull the namespace id from the string. +2 skips past the "ns" part
440 * of the string. Don't search past 10 characters into the string,
441 * otherwise we know it is malformed.
443 nsloc = strnstr(argv[optind], "ns", 10);
445 nsid = strtol(nsloc + 2, NULL, 10);
446 if (nsloc == NULL || (nsid == 0 && errno != 0)) {
447 printf("Invalid namespace ID %s.\n", argv[optind]);
452 * We send IDENTIFY commands to the controller, not the namespace,
453 * since it is an admin cmd. So the path should only include the
454 * nvmeX part of the nvmeXnsY string.
456 snprintf(path, nsloc - argv[optind] + 1, "%s", argv[optind]);
457 open_dev(path, &fd, 1, 1);
458 read_namespace_data(fd, nsid, &nsdata);
462 if (verboseflag == 1)
463 hexlength = sizeof(struct nvme_namespace_data);
465 hexlength = offsetof(struct nvme_namespace_data,
467 print_namespace_hex(&nsdata, hexlength);
471 if (verboseflag == 1) {
472 printf("-v not currently supported without -x.\n");
476 print_namespace(&nsdata);
481 identify(int argc, char *argv[])
488 while (getopt(argc, argv, "vx") != -1) ;
490 target = argv[optind];
496 * If device node contains "ns", we consider it a namespace,
497 * otherwise, consider it a controller.
499 if (strstr(target, "ns") == NULL)
500 identify_ctrlr(argc, argv);
502 identify_ns(argc, argv);
506 print_perftest(struct nvme_io_test *io_test, bool perthread)
508 uint32_t i, io_completed = 0, iops, mbps;
510 for (i = 0; i < io_test->num_threads; i++)
511 io_completed += io_test->io_completed[i];
513 iops = io_completed/io_test->time;
514 mbps = iops * io_test->size / (1024*1024);
516 printf("Threads: %2d Size: %6d %5s Time: %3d IO/s: %7d MB/s: %4d\n",
517 io_test->num_threads, io_test->size,
518 io_test->opc == NVME_OPC_READ ? "READ" : "WRITE",
519 io_test->time, iops, mbps);
522 for (i = 0; i < io_test->num_threads; i++)
523 printf("\t%3d: %8d IO/s\n", i,
524 io_test->io_completed[i]/io_test->time);
532 fprintf(stderr, "usage:\n");
533 fprintf(stderr, PERFTEST_USAGE);
538 perftest(int argc, char *argv[])
540 struct nvme_io_test io_test;
544 u_long ioctl_cmd = NVME_IO_TEST;
545 bool nflag, oflag, sflag, tflag;
548 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",
626 if (!nflag || !oflag || !sflag || !tflag || optind >= argc)
629 open_dev(argv[optind], &fd, 1, 1);
630 if (ioctl(fd, ioctl_cmd, &io_test) < 0) {
631 fprintf(stderr, "NVME_IO_TEST failed. errno=%d (%s)\n", errno,
638 print_perftest(&io_test, perthread);
645 fprintf(stderr, "usage:\n");
646 fprintf(stderr, RESET_USAGE);
651 reset_ctrlr(int argc, char *argv[])
655 while ((ch = getopt(argc, argv, "")) != -1) {
662 open_dev(argv[optind], &fd, 1, 1);
663 if (ioctl(fd, NVME_RESET_CONTROLLER) < 0) {
664 printf("Reset request to %s failed. errno=%d (%s)\n",
665 argv[optind], errno, strerror(errno));
673 main(int argc, char *argv[])
679 if (strcmp(argv[1], "devlist") == 0)
680 devlist(argc-1, &argv[1]);
681 else if (strcmp(argv[1], "identify") == 0)
682 identify(argc-1, &argv[1]);
683 else if (strcmp(argv[1], "perftest") == 0)
684 perftest(argc-1, &argv[1]);
685 else if (strcmp(argv[1], "reset") == 0)
686 reset_ctrlr(argc-1, &argv[1]);