[PATCH] acpi: nfit: document sysfs interface
by Aishwarya Pant
This is an attempt to document the nfit sysfs interface. The
descriptions have been collected from git commit logs and the ACPI
specification 6.2. There are still two undocumented attributes-
range_index and ecc_unit_size, for which I couldn't collect complete
information.
Signed-off-by: Aishwarya Pant <aishpant(a)gmail.com>
---
Documentation/ABI/testing/sysfs-bus-nfit | 202 +++++++++++++++++++++++++++++++
1 file changed, 202 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-bus-nfit
diff --git a/Documentation/ABI/testing/sysfs-bus-nfit b/Documentation/ABI/testing/sysfs-bus-nfit
new file mode 100644
index 000000000000..758d8d0d4c37
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-nfit
@@ -0,0 +1,202 @@
+What: /sys/bus/nd/devices/nmemX/nfit/serial
+Date: Apr, 2015
+KernelVersion: v4.1
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) Serial number of the NVDIMM (non-volatile dual in-line
+ memory module), assigned by the module vendor.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/handle
+Date: Apr, 2015
+KernelVersion: v4.1
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) The address (given by the _ADR object) of the device on its
+ parent bus of the NVDIMM device containing the NVDIMM region.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/device
+Date: Apr, 2015
+KernelVersion: v4.1
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) Identifier for the NVDIMM, assigned by the module vendor.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/rev_id
+Date: Apr, 2015
+KernelVersion: v4.1
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) Revision of the NVDIMM, assigned by the module vendor.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/phys_id
+Date: Apr, 2015
+KernelVersion: v4.1
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) Handle (i.e., instance number) for the SMBIOS (system
+ management BIOS) Memory Device structure describing the NVDIMM
+ containing the NVDIMM region.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/flags
+Date: Jun, 2015
+KernelVersion: v4.1
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) The flags in the NFIT memory device sub-structure indicate
+ the state of the data on the nvdimm relative to its energy
+ source or last "flush to persistence".
+
+ The attribute is a translation of the 'NVDIMM State Flags' field
+ in section 5.2.25.3 'NVDIMM Region Mapping' Structure of the
+ ACPI specification 6.2.
+
+ The health states are "save_fail", "restore_fail", "flush_fail",
+ "not_armed", "smart_event", "map_fail" and "smart_notify".
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/format
+What: /sys/bus/nd/devices/nmemX/nfit/format1
+What: /sys/bus/nd/devices/nmemX/nfit/formats
+Date: Apr, 2016
+KernelVersion: v4.6
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) Identifiers for the programming interface. Starting with
+ ACPI 6.1 an NFIT table reports multiple 'NVDIMM Control Region
+ Structure' instances per-dimm, one for each supported format
+ interface. That code is represented in the sysfs as follows:
+ nmemX/nfit/formats, nmemX/nfit/format, nmemX/nfit/format1,
+ nmemX/nfit/format2 ... nmemX/nfit/formatN, where format2 -
+ formatN are theoretical as there are no known DIMMs with support
+ for more than two interface formats. The 'formats' attribute
+ displays the number of supported interfaces.
+
+ This layout is compatible with existing libndctl binaries that
+ only expect one code per-dimm as they will ignore
+ nmemX/nfit/formats and nmemX/nfit/formatN.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/vendor
+Date: Apr, 2016
+KernelVersion: v4.6
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) Identifier indicating the vendor of the NVDIMM.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/dsm_mask
+Date: Apr, 2016
+KernelVersion: v4.6
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) The bitmask indicates the supported device specific control
+ functions.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/family
+Date: Apr, 2016
+KernelVersion: v4.6
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) Displays the NVDIMM family (and the command sets). Values
+ 0, 1, 2 and 3 correspond to NVDIMM_FAMILY_INTEL,
+ NVDIMM_FAMILY_HPE1, NVDIMM_FAMILY_HPE2 and NVDIMM_FAMILY_MSFT
+ respectively.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/id
+Date: Apr, 2016
+KernelVersion: v4.6
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) ACPI specification 6.2 section 5.2.25.9, defines an
+ identifier for an NVDIMM, which refelects the id attribute.
+
+ If the manufacturing location and manufacturing date fields are
+ valid, then 'id' is composed of the vendor id (bytes 0-1),
+ manufacturing location byte, manufacturing date (bytes 0-1) and
+ the serial number(bytes 0-3), otherwise it is composed of vendor
+ id (bytes 0-1) and serial number (bytes 0-3)
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/subsystem_vendor
+Date: Apr, 2016
+KernelVersion: v4.6
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) Vendor of the NVDIMM non-volatile memory subsystem
+ controller.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/subsystem_rev_id
+Date: Apr, 2016
+KernelVersion: v4.6
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) Revision of the NVDIMM non-volatile memory subsystem
+ controller, assigned by the non-volatile memory subsystem
+ controller vendor.
+
+
+What: /sys/bus/nd/devices/nmemX/nfit/subsystem_device
+Date: Apr, 2016
+KernelVersion: v4.6
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) Identifier for the NVDIMM non-volatile memory subsystem
+ controller, assigned by the non-volatile memory subsystem
+ controller vendor.
+
+
+What: /sys/bus/nd/devices/ndbusX/nfit/revision
+Date: Apr, 2015
+KernelVersion: v4.1
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) ACPI Specification minor version number.
+
+
+What: /sys/bus/nd/devices/ndbusX/nfit/scrub
+Date: Sep, 2016
+KernelVersion: v4.8
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RW) This shows the number of full Address Range Scrubs (ARS)
+ that have been completed since driver load time. Userspace can
+ wait on this using select/poll etc. A '+' at the end indicates
+ an ARS is in progress
+
+ Writing a value of 1 triggers an ARS scan.
+
+
+What: /sys/bus/nd/devices/ndbusX/nfit/hw_error_scrub
+Date: Sep, 2016
+KernelVersion: v4.8
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RW) Provides a way to toggle the behavior between just adding
+ the address (cache line) where the MCE happened to the poison
+ list and doing a full scrub. The former (selective insertion of
+ the address) is done unconditionally.
+
+ This attribute can have the following values written to it:
+
+ '0': Switch to the default mode where an exception will only
+ insert the address of the memory error into the poison and
+ badblocks lists.
+ '1': Enable a full scrub to happen if an exception for a memory
+ error is received.
+
+
+What: /sys/bus/nd/devices/ndbusX/nfit/dsm_mask
+Date: Jun, 2017
+KernelVersion: v4.12
+Contact: linux-nvdimm(a)lists.01.org
+Description:
+ (RO) The bitmask indicates the supported bus specific control
+ functions.
--
2.16.1
2 years, 11 months
[ndctl PATCH] ndctl, test: fix dpa-alloc for kernels with 4M min size
by Dan Williams
Now that ndctl is no longer using the kernel provided ndctl.h header,
and the minimum namespace size has been reduced on recent kernels, the
dpa-alloc test can no longer assume that ND_MIN_NAMESPACE_SIZE matches
what the kernel supports. Instead use a hard coded 4MB size that works
with all kernels.
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
test/dpa-alloc.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/test/dpa-alloc.c b/test/dpa-alloc.c
index 8bb7dd7408a1..9a9c6b64c504 100644
--- a/test/dpa-alloc.c
+++ b/test/dpa-alloc.c
@@ -25,13 +25,13 @@
#include <test.h>
#include <ndctl.h>
+#include <util/size.h>
#include <linux/version.h>
#include <ndctl/libndctl.h>
#include <ccan/array_size/array_size.h>
static const char *NFIT_PROVIDER0 = "nfit_test.0";
static const char *NFIT_PROVIDER1 = "nfit_test.1";
-#define SZ_4K 0x1000UL
#define NUM_NAMESPACES 4
struct test_dpa_namespace {
@@ -40,6 +40,8 @@ struct test_dpa_namespace {
uuid_t uuid;
} namespaces[NUM_NAMESPACES];
+#define MIN_SIZE SZ_4M
+
static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test)
{
unsigned int default_available_slots, available_slots, i;
@@ -97,8 +99,7 @@ static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test)
}
region = blk_region;
- if (ndctl_region_get_available_size(region) / ND_MIN_NAMESPACE_SIZE
- < NUM_NAMESPACES) {
+ if (ndctl_region_get_available_size(region) / MIN_SIZE < NUM_NAMESPACES) {
fprintf(stderr, "%s insufficient available_size\n",
ndctl_region_get_devname(region));
return -ENXIO;
@@ -119,7 +120,7 @@ static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test)
uuid_generate_random(uuid);
ndctl_namespace_set_uuid(ndns, uuid);
ndctl_namespace_set_sector_size(ndns, 512);
- ndctl_namespace_set_size(ndns, ND_MIN_NAMESPACE_SIZE);
+ ndctl_namespace_set_size(ndns, MIN_SIZE);
rc = ndctl_namespace_enable(ndns);
if (rc) {
fprintf(stderr, "failed to enable %s: %d\n",
@@ -129,7 +130,7 @@ static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test)
ndctl_namespace_disable_invalidate(ndns);
rc = ndctl_namespace_set_size(ndns, SZ_4K);
if (rc) {
- fprintf(stderr, "failed to init %s to size: %ld\n",
+ fprintf(stderr, "failed to init %s to size: %d\n",
ndctl_namespace_get_devname(ndns),
SZ_4K);
return rc;
2 years, 11 months
[PATCH v2 1/4] ndctl: add more error outs to update firmware and enable verbose debug
by Dave Jiang
update-firmware is missing verbose option for debug outputs. Also adding
additional error outs to give better indication if something has failed
and why.
Signed-off-by: Dave Jiang <dave.jiang(a)intel.com>
Reviewed-by: Dan Williams <dan.j.williams(a)intel.com>
---
ndctl/update.c | 99 +++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 69 insertions(+), 30 deletions(-)
diff --git a/ndctl/update.c b/ndctl/update.c
index 877d37f..fc26acf 100644
--- a/ndctl/update.c
+++ b/ndctl/update.c
@@ -104,7 +104,7 @@ static int verify_fw_size(struct update_context *uctx)
struct fw_info *fw = &uctx->dimm_fw;
if (uctx->fw_size > fw->store_size) {
- error("Firmware file size greater than DIMM store\n");
+ error("Firmware file size greater than DIMM store");
return -ENOSPC;
}
@@ -119,16 +119,20 @@ static int submit_get_firmware_info(struct update_context *uctx)
struct fw_info *fw = &uctx->dimm_fw;
cmd = ndctl_dimm_cmd_new_fw_get_info(uctx->dimm);
- if (!cmd)
+ if (!cmd) {
+ error("%s: Fail to get new cmd", __func__);
return -ENXIO;
+ }
rc = ndctl_cmd_submit(cmd);
- if (rc < 0)
+ if (rc < 0) {
+ error("%s: Fail to submit cmd", __func__);
return rc;
+ }
status = ndctl_cmd_fw_xlat_firmware_status(cmd);
if (status != FW_SUCCESS) {
- error("GET FIRMWARE INFO failed: %#x\n", status);
+ error("GET FIRMWARE INFO failed: %#x", status);
return -ENXIO;
}
@@ -165,18 +169,22 @@ static int submit_start_firmware_upload(struct update_context *uctx)
struct fw_info *fw = &uctx->dimm_fw;
cmd = ndctl_dimm_cmd_new_fw_start_update(uctx->dimm);
- if (!cmd)
+ if (!cmd) {
+ error("%s: Fail to get new cmd", __func__);
return -ENXIO;
+ }
rc = ndctl_cmd_submit(cmd);
- if (rc < 0)
+ if (rc < 0) {
+ error("%s: Fail to submit cmd", __func__);
return rc;
+ }
status = ndctl_cmd_fw_xlat_firmware_status(cmd);
if (status != FW_SUCCESS) {
- error("START FIRMWARE UPDATE failed: %#x\n", status);
+ error("START FIRMWARE UPDATE failed: %#x", status);
if (status == FW_EBUSY)
- error("Another firmware upload in progress or finished.\n");
+ error("Another firmware upload in progress or finished.");
return -ENXIO;
}
@@ -196,8 +204,11 @@ static int get_fw_data_from_file(int fd, void *buf, uint32_t len,
while (len) {
rc = pread(fd, buf, len, offset);
- if (rc < 0)
- return -errno;
+ if (rc < 0) {
+ rc = -errno;
+ perror("pread");
+ return rc;
+ }
len -= rc;
}
@@ -241,7 +252,7 @@ static int send_firmware(struct update_context *uctx)
status = ndctl_cmd_fw_xlat_firmware_status(cmd);
if (status != FW_SUCCESS) {
- error("SEND FIRMWARE failed: %#x\n", status);
+ error("SEND FIRMWARE failed: %#x", status);
rc = -ENXIO;
goto cleanup;
}
@@ -267,16 +278,20 @@ static int submit_finish_firmware(struct update_context *uctx)
enum ND_FW_STATUS status;
cmd = ndctl_dimm_cmd_new_fw_finish(uctx->start);
- if (!cmd)
+ if (!cmd) {
+ error("%s: Fail to get new cmd", __func__);
return -ENXIO;
+ }
rc = ndctl_cmd_submit(cmd);
- if (rc < 0)
+ if (rc < 0) {
+ error("%s: Fail to submit cmd", __func__);
goto out;
+ }
status = ndctl_cmd_fw_xlat_firmware_status(cmd);
if (status != FW_SUCCESS) {
- error("FINISH FIRMWARE UPDATE failed: %#x\n", status);
+ error("FINISH FIRMWARE UPDATE failed: %#x", status);
rc = -ENXIO;
goto out;
}
@@ -302,7 +317,7 @@ static int submit_abort_firmware(struct update_context *uctx)
status = ndctl_cmd_fw_xlat_firmware_status(cmd);
if (!(status & ND_CMD_STATUS_FIN_ABORTED)) {
- error("FW update abort failed: %#x\n", status);
+ error("FW update abort failed: %#x", status);
rc = -ENXIO;
goto out;
}
@@ -412,36 +427,42 @@ static int update_firmware(struct update_context *uctx)
int rc;
rc = submit_get_firmware_info(uctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("Unable to get firmware info");
return rc;
+ }
rc = submit_start_firmware_upload(uctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("Unable to start firmware upload");
return rc;
+ }
printf("Uploading %s to DIMM %s\n", uctx->fw_path, uctx->dimm_id);
rc = send_firmware(uctx);
if (rc < 0) {
- error("Firmware send failed. Aborting...\n");
+ error("Firmware send failed. Aborting...");
rc = submit_abort_firmware(uctx);
if (rc < 0)
- error("Aborting update sequence failed\n");
+ error("Aborting update sequence failed");
return rc;
}
rc = submit_finish_firmware(uctx);
if (rc < 0) {
- error("Unable to end update sequence\n");
+ error("Unable to end update sequence");
rc = submit_abort_firmware(uctx);
if (rc < 0)
- error("Aborting update sequence failed\n");
+ error("Aborting update sequence failed");
return rc;
}
rc = query_fw_finish_status(uctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("Query Firmware Finish Status failed");
return rc;
+ }
return 0;
}
@@ -468,27 +489,34 @@ static int verify_fw_file(struct update_context *uctx)
int rc;
uctx->fw_fd = open(uctx->fw_path, O_RDONLY);
- if (uctx->fw_fd < 0)
- return -errno;
+ if (uctx->fw_fd < 0) {
+ rc = -errno;
+ error("Unable to open file %s: %d", uctx->fw_path, rc);
+ return rc;
+ }
rc = flock(uctx->fw_fd, LOCK_EX | LOCK_NB);
if (rc < 0) {
+ error("Unable to flock() file %s: %d", uctx->fw_path, rc);
rc = -errno;
goto cleanup;
}
if (fstat(uctx->fw_fd, &st) < 0) {
+ error("Unable to fstat() file %s: %d", uctx->fw_path, rc);
rc = -errno;
goto cleanup;
}
if (!S_ISREG(st.st_mode)) {
+ error("%s is not a regular file", uctx->fw_path);
rc = -EINVAL;
goto cleanup;
}
uctx->fw_size = st.st_size;
if (uctx->fw_size == 0) {
+ error("%s has file size of 0", uctx->fw_path);
rc = -EINVAL;
goto cleanup;
}
@@ -502,12 +530,14 @@ cleanup:
int cmd_update_firmware(int argc, const char **argv, void *ctx)
{
+ bool verbose;
struct update_context uctx = { 0 };
const struct option options[] = {
OPT_STRING('f', "firmware", &uctx.fw_path,
"file-name", "name of firmware"),
OPT_STRING('d', "dimm", &uctx.dimm_id, "dimm-id",
"dimm to be updated"),
+ OPT_BOOLEAN('v', "verbose", &verbose, "emit extra debug messages to stderr"),
OPT_END(),
};
const char * const u[] = {
@@ -518,33 +548,42 @@ int cmd_update_firmware(int argc, const char **argv, void *ctx)
argc = parse_options(argc, argv, options, u, 0);
for (i = 0; i < argc; i++)
- error("unknown parameter \"%s\"\n", argv[i]);
+ error("unknown parameter \"%s\"", argv[i]);
if (argc)
usage_with_options(u, options);
+ if (verbose)
+ ndctl_set_log_priority(ctx, LOG_DEBUG);
+
if (!uctx.fw_path) {
- error("No firmware file provided\n");
+ error("No firmware file provided");
usage_with_options(u, options);
return -EINVAL;
}
if (!uctx.dimm_id) {
- error("No DIMM ID provided\n");
+ error("No DIMM ID provided");
usage_with_options(u, options);
return -EINVAL;
}
rc = verify_fw_file(&uctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("Failed to verify firmware file %s", uctx.fw_path);
return rc;
+ }
rc = get_ndctl_dimm(&uctx, ctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("DIMM %s not found", uctx.dimm_id);
return rc;
+ }
rc = update_firmware(&uctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("Update firmware failed");
return rc;
+ }
if (uctx.start)
ndctl_cmd_unref(uctx.start);
2 years, 11 months
[PATCH] acpi: add NFIT and HMAT to the initrd override list
by Dan Williams
These tables, NFIT and HMAT, are essential for describing
next-generation platform memory topologies and performance
characteristics. Allow them to be overridden for debug and test and
purposes.
Cc: Ross Zwisler <ross.zwisler(a)linux.intel.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
drivers/acpi/tables.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 80ce2a7d224b..67a44fd79449 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -456,7 +456,8 @@ static const char * const table_sigs[] = {
ACPI_SIG_SLIC, ACPI_SIG_SPCR, ACPI_SIG_SPMI, ACPI_SIG_TCPA,
ACPI_SIG_UEFI, ACPI_SIG_WAET, ACPI_SIG_WDAT, ACPI_SIG_WDDT,
ACPI_SIG_WDRT, ACPI_SIG_DSDT, ACPI_SIG_FADT, ACPI_SIG_PSDT,
- ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, NULL };
+ ACPI_SIG_RSDT, ACPI_SIG_XSDT, ACPI_SIG_SSDT, ACPI_SIG_NFIT,
+ ACPI_SIG_HMAT, NULL };
#define ACPI_HEADER_SIZE sizeof(struct acpi_table_header)
2 years, 11 months
[PATCH 1/2] ndctl: add more error outs to update firmware and enable verbose debug
by Dave Jiang
update-firmware is missing verbose option for debug outputs. Also adding
additional error outs to give better indication if something has failed
and why.
Signed-off-by: Dave Jiang <dave.jiang(a)intel.com>
---
ndctl/update.c | 99 +++++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 69 insertions(+), 30 deletions(-)
diff --git a/ndctl/update.c b/ndctl/update.c
index 877d37f..fc26acf 100644
--- a/ndctl/update.c
+++ b/ndctl/update.c
@@ -104,7 +104,7 @@ static int verify_fw_size(struct update_context *uctx)
struct fw_info *fw = &uctx->dimm_fw;
if (uctx->fw_size > fw->store_size) {
- error("Firmware file size greater than DIMM store\n");
+ error("Firmware file size greater than DIMM store");
return -ENOSPC;
}
@@ -119,16 +119,20 @@ static int submit_get_firmware_info(struct update_context *uctx)
struct fw_info *fw = &uctx->dimm_fw;
cmd = ndctl_dimm_cmd_new_fw_get_info(uctx->dimm);
- if (!cmd)
+ if (!cmd) {
+ error("%s: Fail to get new cmd", __func__);
return -ENXIO;
+ }
rc = ndctl_cmd_submit(cmd);
- if (rc < 0)
+ if (rc < 0) {
+ error("%s: Fail to submit cmd", __func__);
return rc;
+ }
status = ndctl_cmd_fw_xlat_firmware_status(cmd);
if (status != FW_SUCCESS) {
- error("GET FIRMWARE INFO failed: %#x\n", status);
+ error("GET FIRMWARE INFO failed: %#x", status);
return -ENXIO;
}
@@ -165,18 +169,22 @@ static int submit_start_firmware_upload(struct update_context *uctx)
struct fw_info *fw = &uctx->dimm_fw;
cmd = ndctl_dimm_cmd_new_fw_start_update(uctx->dimm);
- if (!cmd)
+ if (!cmd) {
+ error("%s: Fail to get new cmd", __func__);
return -ENXIO;
+ }
rc = ndctl_cmd_submit(cmd);
- if (rc < 0)
+ if (rc < 0) {
+ error("%s: Fail to submit cmd", __func__);
return rc;
+ }
status = ndctl_cmd_fw_xlat_firmware_status(cmd);
if (status != FW_SUCCESS) {
- error("START FIRMWARE UPDATE failed: %#x\n", status);
+ error("START FIRMWARE UPDATE failed: %#x", status);
if (status == FW_EBUSY)
- error("Another firmware upload in progress or finished.\n");
+ error("Another firmware upload in progress or finished.");
return -ENXIO;
}
@@ -196,8 +204,11 @@ static int get_fw_data_from_file(int fd, void *buf, uint32_t len,
while (len) {
rc = pread(fd, buf, len, offset);
- if (rc < 0)
- return -errno;
+ if (rc < 0) {
+ rc = -errno;
+ perror("pread");
+ return rc;
+ }
len -= rc;
}
@@ -241,7 +252,7 @@ static int send_firmware(struct update_context *uctx)
status = ndctl_cmd_fw_xlat_firmware_status(cmd);
if (status != FW_SUCCESS) {
- error("SEND FIRMWARE failed: %#x\n", status);
+ error("SEND FIRMWARE failed: %#x", status);
rc = -ENXIO;
goto cleanup;
}
@@ -267,16 +278,20 @@ static int submit_finish_firmware(struct update_context *uctx)
enum ND_FW_STATUS status;
cmd = ndctl_dimm_cmd_new_fw_finish(uctx->start);
- if (!cmd)
+ if (!cmd) {
+ error("%s: Fail to get new cmd", __func__);
return -ENXIO;
+ }
rc = ndctl_cmd_submit(cmd);
- if (rc < 0)
+ if (rc < 0) {
+ error("%s: Fail to submit cmd", __func__);
goto out;
+ }
status = ndctl_cmd_fw_xlat_firmware_status(cmd);
if (status != FW_SUCCESS) {
- error("FINISH FIRMWARE UPDATE failed: %#x\n", status);
+ error("FINISH FIRMWARE UPDATE failed: %#x", status);
rc = -ENXIO;
goto out;
}
@@ -302,7 +317,7 @@ static int submit_abort_firmware(struct update_context *uctx)
status = ndctl_cmd_fw_xlat_firmware_status(cmd);
if (!(status & ND_CMD_STATUS_FIN_ABORTED)) {
- error("FW update abort failed: %#x\n", status);
+ error("FW update abort failed: %#x", status);
rc = -ENXIO;
goto out;
}
@@ -412,36 +427,42 @@ static int update_firmware(struct update_context *uctx)
int rc;
rc = submit_get_firmware_info(uctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("Unable to get firmware info");
return rc;
+ }
rc = submit_start_firmware_upload(uctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("Unable to start firmware upload");
return rc;
+ }
printf("Uploading %s to DIMM %s\n", uctx->fw_path, uctx->dimm_id);
rc = send_firmware(uctx);
if (rc < 0) {
- error("Firmware send failed. Aborting...\n");
+ error("Firmware send failed. Aborting...");
rc = submit_abort_firmware(uctx);
if (rc < 0)
- error("Aborting update sequence failed\n");
+ error("Aborting update sequence failed");
return rc;
}
rc = submit_finish_firmware(uctx);
if (rc < 0) {
- error("Unable to end update sequence\n");
+ error("Unable to end update sequence");
rc = submit_abort_firmware(uctx);
if (rc < 0)
- error("Aborting update sequence failed\n");
+ error("Aborting update sequence failed");
return rc;
}
rc = query_fw_finish_status(uctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("Query Firmware Finish Status failed");
return rc;
+ }
return 0;
}
@@ -468,27 +489,34 @@ static int verify_fw_file(struct update_context *uctx)
int rc;
uctx->fw_fd = open(uctx->fw_path, O_RDONLY);
- if (uctx->fw_fd < 0)
- return -errno;
+ if (uctx->fw_fd < 0) {
+ rc = -errno;
+ error("Unable to open file %s: %d", uctx->fw_path, rc);
+ return rc;
+ }
rc = flock(uctx->fw_fd, LOCK_EX | LOCK_NB);
if (rc < 0) {
+ error("Unable to flock() file %s: %d", uctx->fw_path, rc);
rc = -errno;
goto cleanup;
}
if (fstat(uctx->fw_fd, &st) < 0) {
+ error("Unable to fstat() file %s: %d", uctx->fw_path, rc);
rc = -errno;
goto cleanup;
}
if (!S_ISREG(st.st_mode)) {
+ error("%s is not a regular file", uctx->fw_path);
rc = -EINVAL;
goto cleanup;
}
uctx->fw_size = st.st_size;
if (uctx->fw_size == 0) {
+ error("%s has file size of 0", uctx->fw_path);
rc = -EINVAL;
goto cleanup;
}
@@ -502,12 +530,14 @@ cleanup:
int cmd_update_firmware(int argc, const char **argv, void *ctx)
{
+ bool verbose;
struct update_context uctx = { 0 };
const struct option options[] = {
OPT_STRING('f', "firmware", &uctx.fw_path,
"file-name", "name of firmware"),
OPT_STRING('d', "dimm", &uctx.dimm_id, "dimm-id",
"dimm to be updated"),
+ OPT_BOOLEAN('v', "verbose", &verbose, "emit extra debug messages to stderr"),
OPT_END(),
};
const char * const u[] = {
@@ -518,33 +548,42 @@ int cmd_update_firmware(int argc, const char **argv, void *ctx)
argc = parse_options(argc, argv, options, u, 0);
for (i = 0; i < argc; i++)
- error("unknown parameter \"%s\"\n", argv[i]);
+ error("unknown parameter \"%s\"", argv[i]);
if (argc)
usage_with_options(u, options);
+ if (verbose)
+ ndctl_set_log_priority(ctx, LOG_DEBUG);
+
if (!uctx.fw_path) {
- error("No firmware file provided\n");
+ error("No firmware file provided");
usage_with_options(u, options);
return -EINVAL;
}
if (!uctx.dimm_id) {
- error("No DIMM ID provided\n");
+ error("No DIMM ID provided");
usage_with_options(u, options);
return -EINVAL;
}
rc = verify_fw_file(&uctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("Failed to verify firmware file %s", uctx.fw_path);
return rc;
+ }
rc = get_ndctl_dimm(&uctx, ctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("DIMM %s not found", uctx.dimm_id);
return rc;
+ }
rc = update_firmware(&uctx);
- if (rc < 0)
+ if (rc < 0) {
+ error("Update firmware failed");
return rc;
+ }
if (uctx.start)
ndctl_cmd_unref(uctx.start);
2 years, 11 months
[ndctl PATCH 0/3] add -Wmaybe-uninitialized
by Vishal Verma
A few misc updates. Add the -Wmaybe-uninitialized flag to configure, and
fix the warnings it results in.
Also in update.c, remove a new unnecessary if (cmd) - unref checks as
unref already handles the NULL case.
Vishal Verma (3):
ndctl, inject-smart: cleanup uninitialized variable warnings
ndctl, update: fix uninitialized variable warnings
ndctl, update: remove the check for !cmd when dereferencing it
ndctl/inject-smart.c | 4 ++--
ndctl/update.c | 8 +++-----
2 files changed, 5 insertions(+), 7 deletions(-)
--
2.14.3
2 years, 11 months
[PATCH] ndctl, test: explicitly request namespace size
by Ross Zwisler
The btt-pad-compat.sh test was failing for me because the namespace it was
creating was 32 MiB in size, but it was trying to do 64 MiB worth of I/O
using xxd. This happened because when we created the namespace we didn't
specify a size, and in nfit_test we could have hit either a 64 MiB or a 32
MiB region. Vishal happened to be getting the 64 MiB region, and I
happened to get the 32 MiB.
Fix this by explicitly requesting a namespace size of 64 MiB.
Signed-off-by: Ross Zwisler <ross.zwisler(a)linux.intel.com>
---
test/btt-pad-compat.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/btt-pad-compat.sh b/test/btt-pad-compat.sh
index 4dfe8b0..a157c58 100755
--- a/test/btt-pad-compat.sh
+++ b/test/btt-pad-compat.sh
@@ -137,7 +137,7 @@ copy_xxd_img()
create_oldfmt_ns()
{
# create null-uuid namespace
- json=$($ndctl create-namespace -b "$bus" -t pmem -m raw -l 4096 -u 00000000-0000-0000-0000-000000000000)
+ json=$($ndctl create-namespace -b "$bus" -s 64M -t pmem -m raw -l 4096 -u 00000000-0000-0000-0000-000000000000)
eval "$(echo "$json" | sed -e "$json2var")"
[ -n "$dev" ] || err "$LINENO" 2
[ -n "$size" ] || err "$LINENO" 2
--
2.14.3
2 years, 11 months
[PATCH 1/2] ndctl: tests must use local ndctl
by Ross Zwisler
Fix a few places in our unit tests where we were using the system ndctl
instead of the locally built one. On my system this was leading to false
positive test failures because my local ndctl didn't support this new
command:
ndctl check-namespace --rewrite-log --repair --force --verbose $dev
Signed-off-by: Ross Zwisler <ross.zwisler(a)linux.intel.com>
---
test/btt-errors.sh | 4 ++--
test/btt-pad-compat.sh | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/test/btt-errors.sh b/test/btt-errors.sh
index 68e3652..383abb6 100755
--- a/test/btt-errors.sh
+++ b/test/btt-errors.sh
@@ -47,9 +47,9 @@ force_raw()
{
raw="$1"
if grep -q "$MNT" /proc/mounts; then umount $MNT; fi
- ndctl disable-namespace "$dev"
+ $NDCTL disable-namespace "$dev"
echo "$raw" > "/sys/bus/nd/devices/$dev/force_raw"
- ndctl enable-namespace "$dev"
+ $NDCTL enable-namespace "$dev"
echo "Set $dev to raw mode: $raw"
if [[ "$raw" == "1" ]]; then
raw_bdev=${blockdev%s}
diff --git a/test/btt-pad-compat.sh b/test/btt-pad-compat.sh
index faa773c..618e802 100755
--- a/test/btt-pad-compat.sh
+++ b/test/btt-pad-compat.sh
@@ -112,9 +112,9 @@ cycle_ns()
force_raw()
{
raw="$1"
- ndctl disable-namespace "$dev"
+ $ndctl disable-namespace "$dev"
echo "$raw" > "/sys/bus/nd/devices/$dev/force_raw"
- ndctl enable-namespace "$dev"
+ $ndctl enable-namespace "$dev"
echo "Set $dev to raw mode: $raw"
if [[ "$raw" == "1" ]]; then
raw_bdev=${blockdev%s}
@@ -187,13 +187,13 @@ do_tests()
verify_idx 0 2
# rewrite log using ndctl, verify conversion to new format
- ndctl check-namespace --rewrite-log --repair --force --verbose $dev
+ $ndctl check-namespace --rewrite-log --repair --force --verbose $dev
do_random_io "/dev/$blockdev"
cycle_ns "$dev"
verify_idx 0 1
# check-namespace again to make sure everything is ok
- ndctl check-namespace --force --verbose $dev
+ $ndctl check-namespace --force --verbose $dev
# the old format btt metadata was created with a null parent uuid,
# making it 'stickier' than a normally created btt. Be sure to clean
--
2.14.3
2 years, 11 months
[PATCH v7] ndctl: add option to list firmware information for a DIMM
by Dave Jiang
Adding firmware output of firmware information when ndctl list -D -F is used.
Components displayed are current firmware version, next firmware version,
and if a powercycle is required (firmware updated).
Signed-off-by: Dave Jiang <dave.jiang(a)intel.com>
Tested-by: Jeff Moyer <jmoyer(a)redhat.com>
Reviewed-by: Ross Zwisler <ross.zwisler(a)linux.intel.com>
---
v7:
- removed some unnecessary variables per Ross's comments.
v6:
- changed all instaces of API calls of updated_version to next_version for
better clarity. Data structure for Intel DSM not changed.
- changed coldboot_required to need_powercycle for better clarity.
v5:
- Changed next_version to updated version to be in sync with DSM spec.
- Changed emission of "unknown" string to -1 for error versions.
v4:
- Remove output when updated_version is 0. That indicates no updated firmware.
v3:
- Fixed issue where it skips displaying rest of the details if there's no
firmware details.
v2:
- Added copyright
- Added support for human readable option (hex) for versions
- Removed check against CMD_CALL as it's not useful
Documentation/ndctl/ndctl-list.txt | 13 ++++++
ndctl/Makefile.am | 1
ndctl/lib/firmware.c | 2 -
ndctl/lib/intel.c | 12 ++++-
ndctl/lib/libndctl.sym | 2 -
ndctl/lib/private.h | 2 -
ndctl/libndctl.h | 2 -
ndctl/list.c | 13 ++++++
ndctl/util/json-firmware.c | 81 ++++++++++++++++++++++++++++++++++++
util/json.h | 2 +
10 files changed, 124 insertions(+), 6 deletions(-)
create mode 100644 ndctl/util/json-firmware.c
diff --git a/Documentation/ndctl/ndctl-list.txt b/Documentation/ndctl/ndctl-list.txt
index fc07a71..02d4f04 100644
--- a/Documentation/ndctl/ndctl-list.txt
+++ b/Documentation/ndctl/ndctl-list.txt
@@ -110,6 +110,19 @@ include::xable-region-options.txt[]
}
}
+-F::
+--firmware::
+ Include dimm firmware info in the listing. For example:
+[verse]
+{
+ "dev":"nmem0",
+ "firmware":{
+ "current_version":0,
+ "next_version":1,
+ "need_powercycle":true
+ }
+}
+
-X::
--device-dax::
Include device-dax ("daxregion") details when a namespace is in
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index 2054c1a..e0db97b 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -13,6 +13,7 @@ ndctl_SOURCES = ndctl.c \
test.c \
../util/json.c \
util/json-smart.c \
+ util/json-firmware.c \
inject-error.c \
update.c \
inject-smart.c
diff --git a/ndctl/lib/firmware.c b/ndctl/lib/firmware.c
index 1851018..f6deec5 100644
--- a/ndctl/lib/firmware.c
+++ b/ndctl/lib/firmware.c
@@ -93,7 +93,7 @@ firmware_cmd_op(fw_info_get_max_send_len, unsigned int, 0)
firmware_cmd_op(fw_info_get_query_interval, unsigned int, 0)
firmware_cmd_op(fw_info_get_max_query_time, unsigned int, 0)
firmware_cmd_op(fw_info_get_run_version, unsigned long long, 0)
-firmware_cmd_op(fw_info_get_updated_version, unsigned long long, 0)
+firmware_cmd_op(fw_info_get_next_version, unsigned long long, 0)
firmware_cmd_op(fw_start_get_context, unsigned int, 0)
firmware_cmd_op(fw_fquery_get_fw_rev, unsigned long long, 0)
diff --git a/ndctl/lib/intel.c b/ndctl/lib/intel.c
index 8daf5d2..c5661ed 100644
--- a/ndctl/lib/intel.c
+++ b/ndctl/lib/intel.c
@@ -433,7 +433,15 @@ intel_fw_info_get_field32(cmd, max_send_len)
intel_fw_info_get_field32(cmd, query_interval)
intel_fw_info_get_field32(cmd, max_query_time);
intel_fw_info_get_field64(cmd, run_version);
-intel_fw_info_get_field64(cmd, updated_version);
+
+static unsigned long long intel_cmd_fw_info_get_next_version(
+ struct ndctl_cmd *cmd)
+{
+ if (intel_fw_get_info_valid(cmd) < 0)
+ return ULLONG_MAX;
+ return cmd->intel->info.updated_version;
+
+}
static struct ndctl_cmd *intel_dimm_cmd_new_fw_start(struct ndctl_dimm *dimm)
{
@@ -669,7 +677,7 @@ struct ndctl_dimm_ops * const intel_dimm_ops = &(struct ndctl_dimm_ops) {
.fw_info_get_query_interval = intel_cmd_fw_info_get_query_interval,
.fw_info_get_max_query_time = intel_cmd_fw_info_get_max_query_time,
.fw_info_get_run_version = intel_cmd_fw_info_get_run_version,
- .fw_info_get_updated_version = intel_cmd_fw_info_get_updated_version,
+ .fw_info_get_next_version = intel_cmd_fw_info_get_next_version,
.new_fw_start_update = intel_dimm_cmd_new_fw_start,
.fw_start_get_context = intel_cmd_fw_start_get_context,
.new_fw_send = intel_dimm_cmd_new_fw_send,
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index e7f9675..ac1e7cb 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -339,7 +339,7 @@ global:
ndctl_cmd_fw_info_get_query_interval;
ndctl_cmd_fw_info_get_max_query_time;
ndctl_cmd_fw_info_get_run_version;
- ndctl_cmd_fw_info_get_updated_version;
+ ndctl_cmd_fw_info_get_next_version;
ndctl_cmd_fw_start_get_context;
ndctl_cmd_fw_fquery_get_fw_rev;
ndctl_cmd_fw_xlat_firmware_status;
diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h
index b9e3c1d..15e983a 100644
--- a/ndctl/lib/private.h
+++ b/ndctl/lib/private.h
@@ -314,7 +314,7 @@ struct ndctl_dimm_ops {
unsigned int (*fw_info_get_query_interval)(struct ndctl_cmd *);
unsigned int (*fw_info_get_max_query_time)(struct ndctl_cmd *);
unsigned long long (*fw_info_get_run_version)(struct ndctl_cmd *);
- unsigned long long (*fw_info_get_updated_version)(struct ndctl_cmd *);
+ unsigned long long (*fw_info_get_next_version)(struct ndctl_cmd *);
struct ndctl_cmd *(*new_fw_start_update)(struct ndctl_dimm *);
unsigned int (*fw_start_get_context)(struct ndctl_cmd *);
struct ndctl_cmd *(*new_fw_send)(struct ndctl_cmd *,
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index 6091ff3..e9a8110 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -620,7 +620,7 @@ unsigned int ndctl_cmd_fw_info_get_max_send_len(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_fw_info_get_query_interval(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_fw_info_get_max_query_time(struct ndctl_cmd *cmd);
unsigned long long ndctl_cmd_fw_info_get_run_version(struct ndctl_cmd *cmd);
-unsigned long long ndctl_cmd_fw_info_get_updated_version(struct ndctl_cmd *cmd);
+unsigned long long ndctl_cmd_fw_info_get_next_version(struct ndctl_cmd *cmd);
unsigned int ndctl_cmd_fw_start_get_context(struct ndctl_cmd *cmd);
unsigned long long ndctl_cmd_fw_fquery_get_fw_rev(struct ndctl_cmd *cmd);
enum ND_FW_STATUS ndctl_cmd_fw_xlat_firmware_status(struct ndctl_cmd *cmd);
diff --git a/ndctl/list.c b/ndctl/list.c
index 37a224a..8bb9920 100644
--- a/ndctl/list.c
+++ b/ndctl/list.c
@@ -35,6 +35,7 @@ static struct {
bool dax;
bool media_errors;
bool human;
+ bool firmware;
} list;
static unsigned long listopts_to_flags(void)
@@ -277,6 +278,7 @@ int cmd_list(int argc, const char **argv, void *ctx)
"filter by region-type"),
OPT_BOOLEAN('B', "buses", &list.buses, "include bus info"),
OPT_BOOLEAN('D', "dimms", &list.dimms, "include dimm info"),
+ OPT_BOOLEAN('F', "firmware", &list.firmware, "include firmware info"),
OPT_BOOLEAN('H', "health", &list.health, "include dimm health"),
OPT_BOOLEAN('R', "regions", &list.regions,
"include region info"),
@@ -420,6 +422,17 @@ int cmd_list(int argc, const char **argv, void *ctx)
}
}
+ if (list.firmware) {
+ struct json_object *jfirmware;
+
+ jfirmware = util_dimm_firmware_to_json(dimm,
+ listopts_to_flags());
+ if (jfirmware)
+ json_object_object_add(jdimm,
+ "firmware",
+ jfirmware);
+ }
+
/*
* Without a bus we are collecting dimms anonymously
* across the platform.
diff --git a/ndctl/util/json-firmware.c b/ndctl/util/json-firmware.c
new file mode 100644
index 0000000..3c90ac6
--- /dev/null
+++ b/ndctl/util/json-firmware.c
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright(c) 2018 Intel Corporation. All rights reserved. */
+#include <limits.h>
+#include <util/json.h>
+#include <uuid/uuid.h>
+#include <json-c/json.h>
+#include <ndctl/libndctl.h>
+#include <ccan/array_size/array_size.h>
+#include <ndctl.h>
+
+struct json_object *util_dimm_firmware_to_json(struct ndctl_dimm *dimm,
+ unsigned long flags)
+{
+ struct json_object *jfirmware = json_object_new_object();
+ struct json_object *jobj;
+ struct ndctl_cmd *cmd;
+ int rc;
+ uint64_t run, next;
+
+ if (!jfirmware)
+ return NULL;
+
+ cmd = ndctl_dimm_cmd_new_fw_get_info(dimm);
+ if (!cmd)
+ goto err;
+
+ rc = ndctl_cmd_submit(cmd);
+ if (rc || ndctl_cmd_fw_xlat_firmware_status(cmd) != FW_SUCCESS) {
+ jobj = util_json_object_hex(-1, flags);
+ if (jobj)
+ json_object_object_add(jfirmware, "current_version",
+ jobj);
+ goto out;
+ }
+
+ run = ndctl_cmd_fw_info_get_run_version(cmd);
+ if (run == ULLONG_MAX) {
+ jobj = util_json_object_hex(-1, flags);
+ if (jobj)
+ json_object_object_add(jfirmware, "current_version",
+ jobj);
+ goto out;
+ }
+
+ jobj = util_json_object_hex(run, flags);
+ if (jobj)
+ json_object_object_add(jfirmware, "current_version", jobj);
+
+ next = ndctl_cmd_fw_info_get_next_version(cmd);
+ if (next == ULLONG_MAX) {
+ jobj = util_json_object_hex(-1, flags);
+ if (jobj)
+ json_object_object_add(jfirmware, "next_version",
+ jobj);
+ goto out;
+ }
+
+ if (next != 0) {
+ jobj = util_json_object_hex(next, flags);
+ if (jobj)
+ json_object_object_add(jfirmware,
+ "next_version", jobj);
+
+ jobj = json_object_new_boolean(true);
+ if (jobj)
+ json_object_object_add(jfirmware,
+ "need_powercycle", jobj);
+ }
+
+ ndctl_cmd_unref(cmd);
+ return jfirmware;
+
+err:
+ json_object_put(jfirmware);
+ jfirmware = NULL;
+out:
+ if (cmd)
+ ndctl_cmd_unref(cmd);
+ return jfirmware;
+}
+
diff --git a/util/json.h b/util/json.h
index 9663475..c5d1603 100644
--- a/util/json.h
+++ b/util/json.h
@@ -52,4 +52,6 @@ struct json_object *util_json_object_size(unsigned long long size,
struct json_object *util_json_object_hex(unsigned long long val,
unsigned long flags);
struct json_object *util_dimm_health_to_json(struct ndctl_dimm *dimm);
+struct json_object *util_dimm_firmware_to_json(struct ndctl_dimm *dimm,
+ unsigned long flags);
#endif /* __NDCTL_JSON_H__ */
2 years, 11 months