.\" Title: nvme-set-feature
.\" Author: [FIXME: author] [see http://docbook.sf.net/el/author]
.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
-.\" Date: 02/02/2015
+.\" Date: 03/20/2015
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
-.TH "NVME\-SET\-FEATURE" "1" "02/02/2015" "\ \&" "\ \&"
+.TH "NVME\-SET\-FEATURE" "1" "03/20/2015" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
\fInvme set\-feature\fR <device> [\-\-namespace\-id=<nsid> | \-n <nsid>]
[\-\-feature\-id=<fid> | \-f <fid>] [\-\-value=<value>]
[\-\-data\-len=<data\-len> | \-l <data\-len>]
+ [\-\-data=<data\-file> | \-d <data\-file>]
[\-\-raw\-binary | \-b]
.fi
.SH "DESCRIPTION"
.PP
\-l <data\-len>, \-\-data\-len=<data\-len>
.RS 4
-The data length for the buffer submitted for this feature\&. Most known features do not use this value\&. The exception is LBA Range Type
+The data length for the buffer submitted for this feature\&. Most known features do not use this value\&. The exceptions are LBA Range Type and host identifier\&.
+.RE
+.PP
+\-d <data\-file>, \-\-data=<data\-file>
+.RS 4
+The data file for the buffer submitted for this feature\&. Most known features do not use this value\&. The exceptions is LBA Range Type and host identifier\&. This defaults to STDIN so files and echos can be piped\&.
.RE
.PP
\-\-value=<value>
.sp -1
.IP \(bu 2.3
.\}
+Sets the host id to the ascii string\&.
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+# echo "abcdefgh" | nvme set\-feature /dev/nvme0 \-f 0x81 \-l 8
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
The following retrieves the feature for the LBA Range Type, which implicitly requires a buffer and will be saved to a file in its raw format:
.sp
.if n \{\
'nvme set-feature' <device> [--namespace-id=<nsid> | -n <nsid>]
[--feature-id=<fid> | -f <fid>] [--value=<value>]
[--data-len=<data-len> | -l <data-len>]
+ [--data=<data-file> | -d <data-file>]
[--raw-binary | -b]
DESCRIPTION
-l <data-len>::
--data-len=<data-len>::
The data length for the buffer submitted for this feature. Most
- known features do not use this value. The exception is LBA
- Range Type
+ known features do not use this value. The exceptions are LBA
+ Range Type and host identifier.
+
+-d <data-file>::
+--data=<data-file>::
+ The data file for the buffer submitted for this feature. Most
+ known features do not use this value. The exceptions is LBA
+ Range Type and host identifier. This defaults to STDIN so files
+ and echos can be piped.
--value=<value>::
The value for command dword 11, the value you want to set the
------------
+
+* Sets the host id to the ascii string.
++
+------------
+# echo "abcdefgh" | nvme set-feature /dev/nvme0 -f 0x81 -l 8
+------------
++
+
* The following retrieves the feature for the LBA Range Type, which
implicitly requires a buffer and will be saved to a file in its raw
format:
__le32 ver;
};
+#ifdef LIBUDEV_EXISTS
/* For pre NVMe 1.2 devices we must get the version from the BAR, not
* the ctrl_id.*/
static void get_version( struct list_item* list_item)
print_list_item(list_items[i]);
}
-
-#ifndef LIBUDEV_EXISTS
+#else
static int list(int argc, char **argv)
{
fprintf(stderr,"nvme-list: libudev not detected, install and rebuild.\n");
return err;
}
-/* FIXME: read a buffer from a file if the feature requires one */
static int set_feature(int argc, char **argv)
{
int err;
unsigned int result;
void *buf = NULL;
+ int fd = STDIN_FILENO;
struct config {
+ char *file;
__u32 namespace_id;
__u32 feature_id;
__u32 value;
struct config cfg;
const struct config defaults = {
+ .file = "",
.namespace_id = 0,
.feature_id = 0,
.value = 0,
{"v", "NUM", CFG_POSITIVE, &defaults.value, required_argument, NULL},
{"data-len", "NUM", CFG_POSITIVE, &defaults.data_len, required_argument, NULL},
{"l", "NUM", CFG_POSITIVE, &defaults.data_len, required_argument, NULL},
+ {"data", "FILE", CFG_STRING, &defaults.file, required_argument, NULL},
+ {"d", "FILE", CFG_STRING, &defaults.file, required_argument, NULL},
{0}
};
argconfig_parse(argc, argv, "set_feature", command_line_options,
cfg.data_len = 4096;
if (cfg.data_len)
buf = malloc(cfg.data_len);
+ if (buf) {
+ if (strlen(cfg.file)) {
+ fd = open(cfg.file, O_RDONLY);
+ if (fd <= 0) {
+ fprintf(stderr, "no firmware file provided\n");
+ return -EINVAL;
+ }
+ }
+ if (read(fd, (void *)buf, cfg.data_len) < 0) {
+ fprintf(stderr, "failed to read data buffer from input file\n");
+ return EINVAL;
+ }
+ }
err = nvme_feature(nvme_admin_set_features, buf, cfg.data_len, cfg.feature_id,
cfg.namespace_id, cfg.value, &result);