@@ -128,6 +128,9 @@ struct ndctl_dimm {
unsigned short vendor_id;
unsigned short device_id;
unsigned short revision_id;
+ unsigned short subsystem_vendor_id;
+ unsigned short subsystem_device_id;
+ unsigned short subsystem_revision_id;
unsigned long dsm_mask;
char *unique_id;
char *dimm_path;
@@ -1245,10 +1248,13 @@ static int add_dimm(void *parent, int id, const char *dimm_base)
dimm->handle = -1;
dimm->phys_id = -1;
- dimm->vendor_id = -1;
dimm->serial = -1;
+ dimm->vendor_id = -1;
dimm->device_id = -1;
dimm->revision_id = -1;
+ dimm->subsystem_vendor_id = -1;
+ dimm->subsystem_device_id = -1;
+ dimm->subsystem_revision_id = -1;
for (i = 0; i < formats; i++)
dimm->format[i] = -1;
@@ -1276,16 +1282,14 @@ static int add_dimm(void *parent, int id, const char *dimm_base)
goto err_read;
dimm->phys_id = strtoul(buf, NULL, 0);
- sprintf(path, "%s/nfit/vendor", dimm_base);
- if (sysfs_read_attr(ctx, path, buf) < 0)
- dimm->vendor_id = -1;
- else
- dimm->vendor_id = strtoul(buf, NULL, 0);
-
sprintf(path, "%s/nfit/serial", dimm_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
dimm->serial = strtoul(buf, NULL, 0);
+ sprintf(path, "%s/nfit/vendor", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) == 0)
+ dimm->vendor_id = strtoul(buf, NULL, 0);
+
sprintf(path, "%s/nfit/device", dimm_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
dimm->device_id = strtoul(buf, NULL, 0);
@@ -1294,6 +1298,18 @@ static int add_dimm(void *parent, int id, const char *dimm_base)
if (sysfs_read_attr(ctx, path, buf) == 0)
dimm->revision_id = strtoul(buf, NULL, 0);
+ sprintf(path, "%s/nfit/subsystem_vendor", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) == 0)
+ dimm->subsystem_vendor_id = strtoul(buf, NULL, 0);
+
+ sprintf(path, "%s/nfit/subsystem_device", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) == 0)
+ dimm->subsystem_device_id = strtoul(buf, NULL, 0);
+
+ sprintf(path, "%s/nfit/subsystem_rev_id", dimm_base);
+ if (sysfs_read_attr(ctx, path, buf) == 0)
+ dimm->subsystem_revision_id = strtoul(buf, NULL, 0);
+
dimm->formats = formats;
sprintf(path, "%s/nfit/format", dimm_base);
if (sysfs_read_attr(ctx, path, buf) == 0)
@@ -1368,6 +1384,24 @@ NDCTL_EXPORT unsigned short ndctl_dimm_get_revision(struct ndctl_dimm *dimm)
return dimm->revision_id;
}
+NDCTL_EXPORT unsigned short ndctl_dimm_get_subsystem_vendor(
+ struct ndctl_dimm *dimm)
+{
+ return dimm->subsystem_vendor_id;
+}
+
+NDCTL_EXPORT unsigned short ndctl_dimm_get_subsystem_device(
+ struct ndctl_dimm *dimm)
+{
+ return dimm->subsystem_device_id;
+}
+
+NDCTL_EXPORT unsigned short ndctl_dimm_get_subsystem_revision(
+ struct ndctl_dimm *dimm)
+{
+ return dimm->subsystem_revision_id;
+}
+
NDCTL_EXPORT unsigned short ndctl_dimm_get_format(struct ndctl_dimm *dimm)
{
return dimm->format[0];
@@ -40,6 +40,9 @@ global:
ndctl_dimm_get_vendor;
ndctl_dimm_get_device;
ndctl_dimm_get_revision;
+ ndctl_dimm_get_subsystem_vendor;
+ ndctl_dimm_get_subsystem_device;
+ ndctl_dimm_get_subsystem_revision;
ndctl_dimm_get_format;
ndctl_dimm_get_formats;
ndctl_dimm_get_formatN;
@@ -120,6 +120,9 @@ unsigned short ndctl_dimm_get_phys_id(struct ndctl_dimm *dimm);
unsigned short ndctl_dimm_get_vendor(struct ndctl_dimm *dimm);
unsigned short ndctl_dimm_get_device(struct ndctl_dimm *dimm);
unsigned short ndctl_dimm_get_revision(struct ndctl_dimm *dimm);
+unsigned short ndctl_dimm_get_subsystem_vendor(struct ndctl_dimm *dimm);
+unsigned short ndctl_dimm_get_subsystem_device(struct ndctl_dimm *dimm);
+unsigned short ndctl_dimm_get_subsystem_revision(struct ndctl_dimm *dimm);
unsigned short ndctl_dimm_get_format(struct ndctl_dimm *dimm);
int ndctl_dimm_get_formats(struct ndctl_dimm *dimm);
int ndctl_dimm_get_formatN(struct ndctl_dimm *dimm, int i);
@@ -116,6 +116,7 @@ static const char *NFIT_PROVIDER1 = "nfit_test.1";
struct dimm {
unsigned int handle;
unsigned int phys_id;
+ unsigned int subsystem_vendor;
union {
unsigned long flags;
struct {
@@ -134,15 +135,15 @@ struct dimm {
(((n & 0xfff) << 16) | ((s & 0xf) << 12) | ((i & 0xf) << 8) \
| ((c & 0xf) << 4) | (d & 0xf))
static struct dimm dimms0[] = {
- { DIMM_HANDLE(0, 0, 0, 0, 0), 0, { 0 }, 2, { 0x201, 0x301, }, },
- { DIMM_HANDLE(0, 0, 0, 0, 1), 1, { 0 }, 2, { 0x201, 0x301, }, },
- { DIMM_HANDLE(0, 0, 1, 0, 0), 2, { 0 }, 2, { 0x201, 0x301, }, },
- { DIMM_HANDLE(0, 0, 1, 0, 1), 3, { 0 }, 2, { 0x201, 0x301, }, },
+ { DIMM_HANDLE(0, 0, 0, 0, 0), 0, 0, { 0 }, 2, { 0x201, 0x301, }, },
+ { DIMM_HANDLE(0, 0, 0, 0, 1), 1, 0, { 0 }, 2, { 0x201, 0x301, }, },
+ { DIMM_HANDLE(0, 0, 1, 0, 0), 2, 0, { 0 }, 2, { 0x201, 0x301, }, },
+ { DIMM_HANDLE(0, 0, 1, 0, 1), 3, 0, { 0 }, 2, { 0x201, 0x301, }, },
};
static struct dimm dimms1[] = {
{
- DIMM_HANDLE(0, 0, 0, 0, 0), 0, {
+ DIMM_HANDLE(0, 0, 0, 0, 0), 0, 0, {
.f_arm = 1,
.f_save = 1,
.f_flush = 1,
@@ -2052,6 +2053,14 @@ static int check_dimms(struct ndctl_bus *bus, struct dimm *dimms, int n,
}
}
+ if (ndctl_dimm_get_subsystem_vendor(dimm)
+ != dimms[i].subsystem_vendor) {
+ fprintf(stderr, "dimm%d expected subsystem vendor: %d got: %d\n",
+ i, dimms[i].subsystem_vendor,
+ ndctl_dimm_get_subsystem_vendor(dimm));
+ return -ENXIO;
+ }
+
rc = check_commands(bus, dimm, bus_commands, dimm_commands, test);
if (rc)
return rc;
Similar to PCI device subsystem identifiers, these values are used by upper level management software. Reported-by: Ryon Jensen <ryon.jensen@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> --- lib/libndctl.c | 48 ++++++++++++++++++++++++++++++++++++++++------- lib/libndctl.sym | 3 +++ lib/ndctl/libndctl.h.in | 3 +++ test/libndctl.c | 19 ++++++++++++++----- 4 files changed, 61 insertions(+), 12 deletions(-)