Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147909948
D11433.1784760805.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D11433.1784760805.diff
View Options
Index: sbin/nvmecontrol/Makefile
===================================================================
--- sbin/nvmecontrol/Makefile
+++ sbin/nvmecontrol/Makefile
@@ -3,7 +3,7 @@
PACKAGE=runtime
PROG= nvmecontrol
SRCS= nvmecontrol.c devlist.c firmware.c identify.c logpage.c \
- perftest.c reset.c nvme_util.c power.c util.c wdc.c
+ perftest.c reset.c nvme_util.c power.c util.c wdc.c format.c
MAN= nvmecontrol.8
.PATH: ${SRCTOP}/sys/dev/nvme
Index: sbin/nvmecontrol/format.c
===================================================================
--- /dev/null
+++ sbin/nvmecontrol/format.c
@@ -0,0 +1,185 @@
+
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/ioccom.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "nvmecontrol.h"
+
+/* The LBAF field is 4 bits */
+#define MAX_LBAF 15
+/* The PI field is 3 bits */
+#define MAX_PI 7
+/* The SES field is 3 bits */
+#define MAX_SES 7
+
+static void
+format_usage(void)
+{
+ fprintf(stderr, "usage:\n");
+ fprintf(stderr, FORMAT_USAGE);
+ exit(1);
+}
+
+static int
+format_nvm(int fd, uint32_t nsid, uint8_t lbaf, uint8_t mset, uint8_t pi,
+ uint8_t pil, uint8_t ses)
+{
+ struct nvme_pt_command pt;
+
+ lbaf &= 0xf;
+ mset &= 0x1;
+ pi &= 0x7;
+ pil &= 0x1;
+ ses &= 0x7;
+
+ memset(&pt, 0, sizeof(pt));
+ pt.cmd.opc = NVME_OPC_FORMAT_NVM;
+ pt.cmd.nsid = nsid;
+ pt.cmd.cdw10 = lbaf | (mset << 4) | (pi << 5) | (pil << 8) | (ses << 9);
+ pt.is_read = 0;
+
+ if (ioctl(fd, NVME_PASSTHROUGH_CMD, &pt) < 0)
+ err(1, "format request failed");
+
+ if (nvme_completion_is_error(&pt.cpl))
+ errx(1, "format request returned error");
+
+ return 0;
+}
+
+void
+format(int argc, char *argv[])
+{
+ int fd = -1;
+ char ch, *p;
+ uint8_t lbaf = 0, mset = 1,
+ pi = 0, pil = 0,
+ ses = 0;
+ uint32_t nsid = 0;
+ char path[64];
+ struct nvme_controller_data cdata;
+ struct nvme_namespace_data nsdata;
+
+ while ((ch = getopt(argc, argv, "f:m:p:l:s:")) != -1) {
+ switch (ch) {
+ case 'f':
+ lbaf = strtol(optarg, &p, 0);
+ if (p != NULL && *p != '\0') {
+ fprintf(stderr,
+ "\"%s\" not valid LBAF.\n",
+ optarg);
+ format_usage();
+ } else if (lbaf > MAX_LBAF) {
+ fprintf(stderr,
+ "LBAF %u out of range (max=%u).\n",
+ lbaf, MAX_LBAF);
+ format_usage();
+ }
+ break;
+ case 'm':
+ mset = strtol(optarg, &p, 0);
+ if (p != NULL && *p != '\0') {
+ fprintf(stderr,
+ "\"%s\" not valid MSET.\n",
+ optarg);
+ format_usage();
+ } else if (mset > 1) {
+ fprintf(stderr,
+ "MSET %u out of range (max=1).\n",
+ mset);
+ format_usage();
+ }
+ break;
+ case 'p':
+ pi = strtol(optarg, &p, 0);
+ if (p != NULL && *p != '\0') {
+ fprintf(stderr,
+ "\"%s\" not valid PI.\n",
+ optarg);
+ format_usage();
+ } else if (pi > MAX_PI) {
+ fprintf(stderr,
+ "PI %u out of range (max=%u).\n",
+ pi, MAX_PI);
+ format_usage();
+ }
+ break;
+ case 'l':
+ pil = strtol(optarg, &p, 0);
+ if (p != NULL && *p != '\0') {
+ fprintf(stderr,
+ "\"%s\" not valid PIL.\n",
+ optarg);
+ format_usage();
+ } else if (pil > 1) {
+ fprintf(stderr,
+ "PIL %u out of range (max=1).\n",
+ pil);
+ format_usage();
+ }
+ break;
+ case 's':
+ ses = strtol(optarg, &p, 0);
+ if (p != NULL && *p != '\0') {
+ fprintf(stderr,
+ "\"%s\" not valid SES.\n",
+ optarg);
+ format_usage();
+ } else if (ses > MAX_SES) {
+ fprintf(stderr,
+ "SES %u out of range (max=%u).\n",
+ ses, MAX_SES);
+ }
+ break;
+ }
+ }
+
+ /* Check that a namespace (and not a controller) was specified. */
+ if (optind >= argc || strstr(argv[optind], NVME_NS_PREFIX) == NULL) {
+ printf("expecting NS optind=%d argc=%d %s\n", optind, argc, argv[optind]);
+ format_usage();
+ }
+
+ parse_ns_str(argv[optind], path, &nsid);
+ open_dev(path, &fd, 1, 1);
+ read_controller_data(fd, &cdata);
+ read_namespace_data(fd, nsid, &nsdata);
+
+ if (cdata.oacs.format == 0) {
+ errx(1, "controller does not support format");
+ }
+
+#define FNA_SUPPORTS_CRYPTO_ERASE(fna) (((fna) & 0x4) == 0x4)
+#define SES_CRYPTO_ERASE 0x2
+
+ if ((ses == SES_CRYPTO_ERASE) &&
+ !FNA_SUPPORTS_CRYPTO_ERASE(cdata.fna)) {
+ errx(1, "controller does not support cryptographic erase");
+ }
+
+ if (lbaf > nsdata.nlbaf) {
+ errx(1, "LBAF %u out of controller range (max=%u).", lbaf, nsdata.nlbaf);
+ }
+
+ format_nvm(fd, nsid, lbaf, mset, pi, pil, ses);
+
+ close(fd);
+
+ exit(0);
+}
Index: sbin/nvmecontrol/nvmecontrol.h
===================================================================
--- sbin/nvmecontrol/nvmecontrol.h
+++ sbin/nvmecontrol/nvmecontrol.h
@@ -69,6 +69,9 @@
#define WDC_USAGE \
" nvmecontrol wdc (cap-diag|drive-log|get-crash-dump|purge|purge-montior)\n"
+#define FORMAT_USAGE \
+" nvmecontrol format [-f LBAF] [-m MSET] [-p PI] [-l PIL] [-s SES] <namespace id>\n"
+
void devlist(int argc, char *argv[]);
void identify(int argc, char *argv[]);
void perftest(int argc, char *argv[]);
@@ -77,6 +80,7 @@
void firmware(int argc, char *argv[]);
void power(int argc, char *argv[]);
void wdc(int argc, char *argv[]);
+void format(int argc, char *argv[]);
int open_dev(const char *str, int *fd, int show_error, int exit_on_error);
void parse_ns_str(const char *ns_str, char *ctrlr_str, int *nsid);
Index: sbin/nvmecontrol/nvmecontrol.8
===================================================================
--- sbin/nvmecontrol/nvmecontrol.8
+++ sbin/nvmecontrol/nvmecontrol.8
@@ -95,6 +95,13 @@
.\" .Nm
.\" .Ic wdc purge-monitor
.\" .Aq device id
+.Nm
+.Ic format
+.Op Fl f Ar LBAF
+.Op Fl m Ar MSET
+.Op Fl p Ar PI
+.Op Fl s Ar SES
+.Aq namespace id
.Sh DESCRIPTION
NVM Express (NVMe) is a storage protocol standard, for SSDs and other
high-speed storage devices over PCI Express.
@@ -127,6 +134,22 @@
by .bin.
These logs must be sent to the vendor for analysis.
This tool only provides a way to extract them.
+.Ss format
+The format command allows a low level format of the NVM media. Each of the
+options mirror the field names defined in the NVM Express specification.
+.Fl f
+chooses the LBA Format. Valid values are 0-15.
+.Fl m
+chooses whether metadata is appended to the block (extended LBA) or sent
+in a separate buffer.
+.Fl p
+selects the end-to-end protection information (Type 0 - 3).
+.Fl l
+selects whether the protection information is first (1) or last (0) in the
+metadata.
+.Fl s
+selects the type of low level format (none = 0, user erase = 1, cryptographic
+erase = 2).
.Sh EXAMPLES
.Dl nvmecontrol devlist
.Pp
Index: sbin/nvmecontrol/nvmecontrol.c
===================================================================
--- sbin/nvmecontrol/nvmecontrol.c
+++ sbin/nvmecontrol/nvmecontrol.c
@@ -55,6 +55,7 @@
{"firmware", firmware, FIRMWARE_USAGE},
{"power", power, POWER_USAGE},
{"wdc", wdc, WDC_USAGE},
+ {"format", format, FORMAT_USAGE},
{NULL, NULL, NULL},
};
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jul 22, 10:53 PM (16 h, 26 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29232235
Default Alt Text
D11433.1784760805.diff (7 KB)
Attached To
Mode
D11433: Add Format NVM support to nvmecontrol
Attached
Detach File
Event Timeline
Log In to Comment