From: Keith Busch Date: Fri, 20 Mar 2015 15:13:50 +0000 (-0600) Subject: Add data input option for set features X-Git-Tag: v0.1~51 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=9ba52effcdcdb01ddeb2d9aa00a0a03143e26aac;p=users%2Fsagi%2Fnvme-cli.git Add data input option for set features Some NVMe features perform a data transfer and this provides a user option to specify where that data comes from when setting. Documentation updated as well. This also includes an unrelated fix to hush a warning for unused symbols under precompile libudev dependencies. Signed-off-by: Keith Busch --- diff --git a/Documentation/nvme-set-feature.1 b/Documentation/nvme-set-feature.1 index c3538ab4..94b5f70f 100644 --- a/Documentation/nvme-set-feature.1 +++ b/Documentation/nvme-set-feature.1 @@ -2,12 +2,12 @@ .\" Title: nvme-set-feature .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.76.1 -.\" 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 .\" ----------------------------------------------------------------- @@ -35,6 +35,7 @@ nvme-set-feature \- Sets an NVMe feature, returns applicable results \fInvme set\-feature\fR [\-\-namespace\-id= | \-n ] [\-\-feature\-id= | \-f ] [\-\-value=] [\-\-data\-len= | \-l ] + [\-\-data= | \-d ] [\-\-raw\-binary | \-b] .fi .SH "DESCRIPTION" @@ -58,7 +59,12 @@ The feature id to send with the command\&. Value provided should be in hex\&. .PP \-l , \-\-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= +.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= @@ -138,6 +144,27 @@ Retrieves the feature for the some vendor specific feature and specifically requ .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 \{\ diff --git a/Documentation/nvme-set-feature.txt b/Documentation/nvme-set-feature.txt index d0f4b2d7..7bbd66d8 100644 --- a/Documentation/nvme-set-feature.txt +++ b/Documentation/nvme-set-feature.txt @@ -11,6 +11,7 @@ SYNOPSIS 'nvme set-feature' [--namespace-id= | -n ] [--feature-id= | -f ] [--value=] [--data-len= | -l ] + [--data= | -d ] [--raw-binary | -b] DESCRIPTION @@ -43,8 +44,15 @@ OPTIONS -l :: --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=:: + 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=:: The value for command dword 11, the value you want to set the @@ -78,6 +86,13 @@ will be displayed to the user in as a hex dump: ------------ + +* 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: diff --git a/nvme.c b/nvme.c index 340746f2..7210a1a7 100644 --- a/nvme.c +++ b/nvme.c @@ -802,6 +802,7 @@ struct list_item { __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) @@ -854,8 +855,7 @@ static void print_list_items(struct list_item *list_items, unsigned len) 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"); @@ -1377,14 +1377,15 @@ static int format(int argc, char **argv) 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; @@ -1393,6 +1394,7 @@ static int set_feature(int argc, char **argv) struct config cfg; const struct config defaults = { + .file = "", .namespace_id = 0, .feature_id = 0, .value = 0, @@ -1408,6 +1410,8 @@ static int set_feature(int argc, char **argv) {"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, @@ -1426,6 +1430,19 @@ static int set_feature(int argc, char **argv) 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);