summaryrefslogtreecommitdiff
path: root/tools/testing/nvdimm/test/nfit.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/nvdimm/test/nfit.c')
-rw-r--r--tools/testing/nvdimm/test/nfit.c323
1 files changed, 226 insertions, 97 deletions
diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 620fa78b3b1b..4ea385be528f 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -104,7 +104,8 @@ enum {
NUM_HINTS = 8,
NUM_BDW = NUM_DCR,
NUM_SPA = NUM_PM + NUM_DCR + NUM_BDW,
- NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */ + 4 /* spa1 iset */,
+ NUM_MEM = NUM_DCR + NUM_BDW + 2 /* spa0 iset */
+ + 4 /* spa1 iset */ + 1 /* spa11 iset */,
DIMM_SIZE = SZ_32M,
LABEL_SIZE = SZ_128K,
SPA_VCD_SIZE = SZ_4M,
@@ -137,6 +138,7 @@ static u32 handle[] = {
};
static unsigned long dimm_fail_cmd_flags[NUM_DCR];
+static int dimm_fail_cmd_code[NUM_DCR];
struct nfit_test_fw {
enum intel_fw_update_state state;
@@ -153,6 +155,7 @@ struct nfit_test {
void *nfit_buf;
dma_addr_t nfit_dma;
size_t nfit_size;
+ size_t nfit_filled;
int dcr_idx;
int num_dcr;
int num_pm;
@@ -709,7 +712,9 @@ static void smart_notify(struct device *bus_dev,
>= thresh->media_temperature)
|| ((thresh->alarm_control & ND_INTEL_SMART_CTEMP_TRIP)
&& smart->ctrl_temperature
- >= thresh->ctrl_temperature)) {
+ >= thresh->ctrl_temperature)
+ || (smart->health != ND_INTEL_SMART_NON_CRITICAL_HEALTH)
+ || (smart->shutdown_state != 0)) {
device_lock(bus_dev);
__acpi_nvdimm_notify(dimm_dev, 0x81);
device_unlock(bus_dev);
@@ -735,6 +740,32 @@ static int nfit_test_cmd_smart_set_threshold(
return 0;
}
+static int nfit_test_cmd_smart_inject(
+ struct nd_intel_smart_inject *inj,
+ unsigned int buf_len,
+ struct nd_intel_smart_threshold *thresh,
+ struct nd_intel_smart *smart,
+ struct device *bus_dev, struct device *dimm_dev)
+{
+ if (buf_len != sizeof(*inj))
+ return -EINVAL;
+
+ if (inj->mtemp_enable)
+ smart->media_temperature = inj->media_temperature;
+ if (inj->spare_enable)
+ smart->spares = inj->spares;
+ if (inj->fatal_enable)
+ smart->health = ND_INTEL_SMART_FATAL_HEALTH;
+ if (inj->unsafe_shutdown_enable) {
+ smart->shutdown_state = 1;
+ smart->shutdown_count++;
+ }
+ inj->status = 0;
+ smart_notify(bus_dev, dimm_dev, smart, thresh);
+
+ return 0;
+}
+
static void uc_error_notify(struct work_struct *work)
{
struct nfit_test *t = container_of(work, typeof(*t), work);
@@ -862,8 +893,11 @@ static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
if (i >= ARRAY_SIZE(handle))
return -ENXIO;
- if ((1 << func) & dimm_fail_cmd_flags[i])
+ if ((1 << func) & dimm_fail_cmd_flags[i]) {
+ if (dimm_fail_cmd_code[i])
+ return dimm_fail_cmd_code[i];
return -EIO;
+ }
return i;
}
@@ -935,6 +969,13 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
t->dcr_idx],
&t->smart[i - t->dcr_idx],
&t->pdev.dev, t->dimm_dev[i]);
+ case ND_INTEL_SMART_INJECT:
+ return nfit_test_cmd_smart_inject(buf,
+ buf_len,
+ &t->smart_threshold[i -
+ t->dcr_idx],
+ &t->smart[i - t->dcr_idx],
+ &t->pdev.dev, t->dimm_dev[i]);
default:
return -ENOTTY;
}
@@ -1125,12 +1166,12 @@ static int ars_state_init(struct device *dev, struct ars_state *ars_state)
static void put_dimms(void *data)
{
- struct device **dimm_dev = data;
+ struct nfit_test *t = data;
int i;
- for (i = 0; i < NUM_DCR; i++)
- if (dimm_dev[i])
- device_unregister(dimm_dev[i]);
+ for (i = 0; i < t->num_dcr; i++)
+ if (t->dimm_dev[i])
+ device_unregister(t->dimm_dev[i]);
}
static struct class *nfit_test_dimm;
@@ -1139,13 +1180,11 @@ static int dimm_name_to_id(struct device *dev)
{
int dimm;
- if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1
- || dimm >= NUM_DCR || dimm < 0)
+ if (sscanf(dev_name(dev), "test_dimm%d", &dimm) != 1)
return -ENXIO;
return dimm;
}
-
static ssize_t handle_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -1154,7 +1193,7 @@ static ssize_t handle_show(struct device *dev, struct device_attribute *attr,
if (dimm < 0)
return dimm;
- return sprintf(buf, "%#x", handle[dimm]);
+ return sprintf(buf, "%#x\n", handle[dimm]);
}
DEVICE_ATTR_RO(handle);
@@ -1188,8 +1227,39 @@ static ssize_t fail_cmd_store(struct device *dev, struct device_attribute *attr,
}
static DEVICE_ATTR_RW(fail_cmd);
+static ssize_t fail_cmd_code_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ int dimm = dimm_name_to_id(dev);
+
+ if (dimm < 0)
+ return dimm;
+
+ return sprintf(buf, "%d\n", dimm_fail_cmd_code[dimm]);
+}
+
+static ssize_t fail_cmd_code_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ int dimm = dimm_name_to_id(dev);
+ unsigned long val;
+ ssize_t rc;
+
+ if (dimm < 0)
+ return dimm;
+
+ rc = kstrtol(buf, 0, &val);
+ if (rc)
+ return rc;
+
+ dimm_fail_cmd_code[dimm] = val;
+ return size;
+}
+static DEVICE_ATTR_RW(fail_cmd_code);
+
static struct attribute *nfit_test_dimm_attributes[] = {
&dev_attr_fail_cmd.attr,
+ &dev_attr_fail_cmd_code.attr,
&dev_attr_handle.attr,
NULL,
};
@@ -1203,6 +1273,23 @@ static const struct attribute_group *nfit_test_dimm_attribute_groups[] = {
NULL,
};
+static int nfit_test_dimm_init(struct nfit_test *t)
+{
+ int i;
+
+ if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t))
+ return -ENOMEM;
+ for (i = 0; i < t->num_dcr; i++) {
+ t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm,
+ &t->pdev.dev, 0, NULL,
+ nfit_test_dimm_attribute_groups,
+ "test_dimm%d", i + t->dcr_idx);
+ if (!t->dimm_dev[i])
+ return -ENOMEM;
+ }
+ return 0;
+}
+
static void smart_init(struct nfit_test *t)
{
int i;
@@ -1222,7 +1309,7 @@ static void smart_init(struct nfit_test *t)
| ND_INTEL_SMART_MTEMP_VALID,
.health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
.media_temperature = 23 * 16,
- .ctrl_temperature = 30 * 16,
+ .ctrl_temperature = 25 * 16,
.pmic_temperature = 40 * 16,
.spares = 75,
.alarm_flags = ND_INTEL_SMART_SPARE_TRIP
@@ -1298,17 +1385,8 @@ static int nfit_test0_alloc(struct nfit_test *t)
if (!t->_fit)
return -ENOMEM;
- if (devm_add_action_or_reset(&t->pdev.dev, put_dimms, t->dimm_dev))
+ if (nfit_test_dimm_init(t))
return -ENOMEM;
- for (i = 0; i < NUM_DCR; i++) {
- t->dimm_dev[i] = device_create_with_groups(nfit_test_dimm,
- &t->pdev.dev, 0, NULL,
- nfit_test_dimm_attribute_groups,
- "test_dimm%d", i);
- if (!t->dimm_dev[i])
- return -ENOMEM;
- }
-
smart_init(t);
return ars_state_init(&t->pdev.dev, &t->ars_state);
}
@@ -1340,6 +1418,8 @@ static int nfit_test1_alloc(struct nfit_test *t)
if (!t->spa_set[1])
return -ENOMEM;
+ if (nfit_test_dimm_init(t))
+ return -ENOMEM;
smart_init(t);
return ars_state_init(&t->pdev.dev, &t->ars_state);
}
@@ -1366,7 +1446,7 @@ static void nfit_test0_setup(struct nfit_test *t)
struct acpi_nfit_data_region *bdw;
struct acpi_nfit_flush_address *flush;
struct acpi_nfit_capabilities *pcap;
- unsigned int offset, i;
+ unsigned int offset = 0, i;
/*
* spa0 (interleave first half of dimm0 and dimm1, note storage
@@ -1380,93 +1460,102 @@ static void nfit_test0_setup(struct nfit_test *t)
spa->range_index = 0+1;
spa->address = t->spa_set_dma[0];
spa->length = SPA0_SIZE;
+ offset += spa->header.length;
/*
* spa1 (interleave last half of the 4 DIMMS, note storage
* does not actually alias the related block-data-window
* regions)
*/
- spa = nfit_buf + sizeof(*spa);
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
spa->range_index = 1+1;
spa->address = t->spa_set_dma[1];
spa->length = SPA1_SIZE;
+ offset += spa->header.length;
/* spa2 (dcr0) dimm0 */
- spa = nfit_buf + sizeof(*spa) * 2;
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
spa->range_index = 2+1;
spa->address = t->dcr_dma[0];
spa->length = DCR_SIZE;
+ offset += spa->header.length;
/* spa3 (dcr1) dimm1 */
- spa = nfit_buf + sizeof(*spa) * 3;
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
spa->range_index = 3+1;
spa->address = t->dcr_dma[1];
spa->length = DCR_SIZE;
+ offset += spa->header.length;
/* spa4 (dcr2) dimm2 */
- spa = nfit_buf + sizeof(*spa) * 4;
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
spa->range_index = 4+1;
spa->address = t->dcr_dma[2];
spa->length = DCR_SIZE;
+ offset += spa->header.length;
/* spa5 (dcr3) dimm3 */
- spa = nfit_buf + sizeof(*spa) * 5;
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_DCR), 16);
spa->range_index = 5+1;
spa->address = t->dcr_dma[3];
spa->length = DCR_SIZE;
+ offset += spa->header.length;
/* spa6 (bdw for dcr0) dimm0 */
- spa = nfit_buf + sizeof(*spa) * 6;
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
spa->range_index = 6+1;
spa->address = t->dimm_dma[0];
spa->length = DIMM_SIZE;
+ offset += spa->header.length;
/* spa7 (bdw for dcr1) dimm1 */
- spa = nfit_buf + sizeof(*spa) * 7;
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
spa->range_index = 7+1;
spa->address = t->dimm_dma[1];
spa->length = DIMM_SIZE;
+ offset += spa->header.length;
/* spa8 (bdw for dcr2) dimm2 */
- spa = nfit_buf + sizeof(*spa) * 8;
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
spa->range_index = 8+1;
spa->address = t->dimm_dma[2];
spa->length = DIMM_SIZE;
+ offset += spa->header.length;
/* spa9 (bdw for dcr3) dimm3 */
- spa = nfit_buf + sizeof(*spa) * 9;
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
spa->range_index = 9+1;
spa->address = t->dimm_dma[3];
spa->length = DIMM_SIZE;
+ offset += spa->header.length;
- offset = sizeof(*spa) * 10;
/* mem-region0 (spa0, dimm0) */
memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
@@ -1481,9 +1570,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = 0;
memdev->interleave_index = 0;
memdev->interleave_ways = 2;
+ offset += memdev->header.length;
/* mem-region1 (spa0, dimm1) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map);
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[1];
@@ -1497,9 +1587,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->interleave_index = 0;
memdev->interleave_ways = 2;
memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED;
+ offset += memdev->header.length;
/* mem-region2 (spa1, dimm0) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 2;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[0];
@@ -1513,9 +1604,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->interleave_index = 0;
memdev->interleave_ways = 4;
memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED;
+ offset += memdev->header.length;
/* mem-region3 (spa1, dimm1) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 3;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[1];
@@ -1528,9 +1620,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = SPA0_SIZE/2;
memdev->interleave_index = 0;
memdev->interleave_ways = 4;
+ offset += memdev->header.length;
/* mem-region4 (spa1, dimm2) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 4;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[2];
@@ -1544,9 +1637,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->interleave_index = 0;
memdev->interleave_ways = 4;
memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED;
+ offset += memdev->header.length;
/* mem-region5 (spa1, dimm3) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 5;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[3];
@@ -1559,9 +1653,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = SPA0_SIZE/2;
memdev->interleave_index = 0;
memdev->interleave_ways = 4;
+ offset += memdev->header.length;
/* mem-region6 (spa/dcr0, dimm0) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 6;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[0];
@@ -1574,9 +1669,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = 0;
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
+ offset += memdev->header.length;
/* mem-region7 (spa/dcr1, dimm1) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 7;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[1];
@@ -1589,9 +1685,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = 0;
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
+ offset += memdev->header.length;
/* mem-region8 (spa/dcr2, dimm2) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 8;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[2];
@@ -1604,9 +1701,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = 0;
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
+ offset += memdev->header.length;
/* mem-region9 (spa/dcr3, dimm3) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 9;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[3];
@@ -1619,9 +1717,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = 0;
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
+ offset += memdev->header.length;
/* mem-region10 (spa/bdw0, dimm0) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 10;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[0];
@@ -1634,9 +1733,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = 0;
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
+ offset += memdev->header.length;
/* mem-region11 (spa/bdw1, dimm1) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 11;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[1];
@@ -1649,9 +1749,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = 0;
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
+ offset += memdev->header.length;
/* mem-region12 (spa/bdw2, dimm2) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 12;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[2];
@@ -1664,9 +1765,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = 0;
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
+ offset += memdev->header.length;
/* mem-region13 (spa/dcr3, dimm3) */
- memdev = nfit_buf + offset + sizeof(struct acpi_nfit_memory_map) * 13;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[3];
@@ -1680,12 +1782,12 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED;
+ offset += memdev->header.length;
- offset = offset + sizeof(struct acpi_nfit_memory_map) * 14;
/* dcr-descriptor0: blk */
dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
- dcr->header.length = sizeof(struct acpi_nfit_control_region);
+ dcr->header.length = sizeof(*dcr);
dcr->region_index = 0+1;
dcr_common_init(dcr);
dcr->serial_number = ~handle[0];
@@ -1696,11 +1798,12 @@ static void nfit_test0_setup(struct nfit_test *t)
dcr->command_size = 8;
dcr->status_offset = 8;
dcr->status_size = 4;
+ offset += dcr->header.length;
/* dcr-descriptor1: blk */
- dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region);
+ dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
- dcr->header.length = sizeof(struct acpi_nfit_control_region);
+ dcr->header.length = sizeof(*dcr);
dcr->region_index = 1+1;
dcr_common_init(dcr);
dcr->serial_number = ~handle[1];
@@ -1711,11 +1814,12 @@ static void nfit_test0_setup(struct nfit_test *t)
dcr->command_size = 8;
dcr->status_offset = 8;
dcr->status_size = 4;
+ offset += dcr->header.length;
/* dcr-descriptor2: blk */
- dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region) * 2;
+ dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
- dcr->header.length = sizeof(struct acpi_nfit_control_region);
+ dcr->header.length = sizeof(*dcr);
dcr->region_index = 2+1;
dcr_common_init(dcr);
dcr->serial_number = ~handle[2];
@@ -1726,11 +1830,12 @@ static void nfit_test0_setup(struct nfit_test *t)
dcr->command_size = 8;
dcr->status_offset = 8;
dcr->status_size = 4;
+ offset += dcr->header.length;
/* dcr-descriptor3: blk */
- dcr = nfit_buf + offset + sizeof(struct acpi_nfit_control_region) * 3;
+ dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
- dcr->header.length = sizeof(struct acpi_nfit_control_region);
+ dcr->header.length = sizeof(*dcr);
dcr->region_index = 3+1;
dcr_common_init(dcr);
dcr->serial_number = ~handle[3];
@@ -1741,8 +1846,8 @@ static void nfit_test0_setup(struct nfit_test *t)
dcr->command_size = 8;
dcr->status_offset = 8;
dcr->status_size = 4;
+ offset += dcr->header.length;
- offset = offset + sizeof(struct acpi_nfit_control_region) * 4;
/* dcr-descriptor0: pmem */
dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
@@ -1753,10 +1858,10 @@ static void nfit_test0_setup(struct nfit_test *t)
dcr->serial_number = ~handle[0];
dcr->code = NFIT_FIC_BYTEN;
dcr->windows = 0;
+ offset += dcr->header.length;
/* dcr-descriptor1: pmem */
- dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region,
- window_size);
+ dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
dcr->header.length = offsetof(struct acpi_nfit_control_region,
window_size);
@@ -1765,10 +1870,10 @@ static void nfit_test0_setup(struct nfit_test *t)
dcr->serial_number = ~handle[1];
dcr->code = NFIT_FIC_BYTEN;
dcr->windows = 0;
+ offset += dcr->header.length;
/* dcr-descriptor2: pmem */
- dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region,
- window_size) * 2;
+ dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
dcr->header.length = offsetof(struct acpi_nfit_control_region,
window_size);
@@ -1777,10 +1882,10 @@ static void nfit_test0_setup(struct nfit_test *t)
dcr->serial_number = ~handle[2];
dcr->code = NFIT_FIC_BYTEN;
dcr->windows = 0;
+ offset += dcr->header.length;
/* dcr-descriptor3: pmem */
- dcr = nfit_buf + offset + offsetof(struct acpi_nfit_control_region,
- window_size) * 3;
+ dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
dcr->header.length = offsetof(struct acpi_nfit_control_region,
window_size);
@@ -1789,54 +1894,56 @@ static void nfit_test0_setup(struct nfit_test *t)
dcr->serial_number = ~handle[3];
dcr->code = NFIT_FIC_BYTEN;
dcr->windows = 0;
+ offset += dcr->header.length;
- offset = offset + offsetof(struct acpi_nfit_control_region,
- window_size) * 4;
/* bdw0 (spa/dcr0, dimm0) */
bdw = nfit_buf + offset;
bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
- bdw->header.length = sizeof(struct acpi_nfit_data_region);
+ bdw->header.length = sizeof(*bdw);
bdw->region_index = 0+1;
bdw->windows = 1;
bdw->offset = 0;
bdw->size = BDW_SIZE;
bdw->capacity = DIMM_SIZE;
bdw->start_address = 0;
+ offset += bdw->header.length;
/* bdw1 (spa/dcr1, dimm1) */
- bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region);
+ bdw = nfit_buf + offset;
bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
- bdw->header.length = sizeof(struct acpi_nfit_data_region);
+ bdw->header.length = sizeof(*bdw);
bdw->region_index = 1+1;
bdw->windows = 1;
bdw->offset = 0;
bdw->size = BDW_SIZE;
bdw->capacity = DIMM_SIZE;
bdw->start_address = 0;
+ offset += bdw->header.length;
/* bdw2 (spa/dcr2, dimm2) */
- bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region) * 2;
+ bdw = nfit_buf + offset;
bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
- bdw->header.length = sizeof(struct acpi_nfit_data_region);
+ bdw->header.length = sizeof(*bdw);
bdw->region_index = 2+1;
bdw->windows = 1;
bdw->offset = 0;
bdw->size = BDW_SIZE;
bdw->capacity = DIMM_SIZE;
bdw->start_address = 0;
+ offset += bdw->header.length;
/* bdw3 (spa/dcr3, dimm3) */
- bdw = nfit_buf + offset + sizeof(struct acpi_nfit_data_region) * 3;
+ bdw = nfit_buf + offset;
bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
- bdw->header.length = sizeof(struct acpi_nfit_data_region);
+ bdw->header.length = sizeof(*bdw);
bdw->region_index = 3+1;
bdw->windows = 1;
bdw->offset = 0;
bdw->size = BDW_SIZE;
bdw->capacity = DIMM_SIZE;
bdw->start_address = 0;
+ offset += bdw->header.length;
- offset = offset + sizeof(struct acpi_nfit_data_region) * 4;
/* flush0 (dimm0) */
flush = nfit_buf + offset;
flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
@@ -1845,48 +1952,52 @@ static void nfit_test0_setup(struct nfit_test *t)
flush->hint_count = NUM_HINTS;
for (i = 0; i < NUM_HINTS; i++)
flush->hint_address[i] = t->flush_dma[0] + i * sizeof(u64);
+ offset += flush->header.length;
/* flush1 (dimm1) */
- flush = nfit_buf + offset + flush_hint_size * 1;
+ flush = nfit_buf + offset;
flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
flush->header.length = flush_hint_size;
flush->device_handle = handle[1];
flush->hint_count = NUM_HINTS;
for (i = 0; i < NUM_HINTS; i++)
flush->hint_address[i] = t->flush_dma[1] + i * sizeof(u64);
+ offset += flush->header.length;
/* flush2 (dimm2) */
- flush = nfit_buf + offset + flush_hint_size * 2;
+ flush = nfit_buf + offset;
flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
flush->header.length = flush_hint_size;
flush->device_handle = handle[2];
flush->hint_count = NUM_HINTS;
for (i = 0; i < NUM_HINTS; i++)
flush->hint_address[i] = t->flush_dma[2] + i * sizeof(u64);
+ offset += flush->header.length;
/* flush3 (dimm3) */
- flush = nfit_buf + offset + flush_hint_size * 3;
+ flush = nfit_buf + offset;
flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
flush->header.length = flush_hint_size;
flush->device_handle = handle[3];
flush->hint_count = NUM_HINTS;
for (i = 0; i < NUM_HINTS; i++)
flush->hint_address[i] = t->flush_dma[3] + i * sizeof(u64);
+ offset += flush->header.length;
/* platform capabilities */
- pcap = nfit_buf + offset + flush_hint_size * 4;
+ pcap = nfit_buf + offset;
pcap->header.type = ACPI_NFIT_TYPE_CAPABILITIES;
pcap->header.length = sizeof(*pcap);
pcap->highest_capability = 1;
pcap->capabilities = ACPI_NFIT_CAPABILITY_CACHE_FLUSH |
ACPI_NFIT_CAPABILITY_MEM_FLUSH;
+ offset += pcap->header.length;
if (t->setup_hotplug) {
- offset = offset + flush_hint_size * 4 + sizeof(*pcap);
/* dcr-descriptor4: blk */
dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
- dcr->header.length = sizeof(struct acpi_nfit_control_region);
+ dcr->header.length = sizeof(*dcr);
dcr->region_index = 8+1;
dcr_common_init(dcr);
dcr->serial_number = ~handle[4];
@@ -1897,8 +2008,8 @@ static void nfit_test0_setup(struct nfit_test *t)
dcr->command_size = 8;
dcr->status_offset = 8;
dcr->status_size = 4;
+ offset += dcr->header.length;
- offset = offset + sizeof(struct acpi_nfit_control_region);
/* dcr-descriptor4: pmem */
dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
@@ -1909,21 +2020,20 @@ static void nfit_test0_setup(struct nfit_test *t)
dcr->serial_number = ~handle[4];
dcr->code = NFIT_FIC_BYTEN;
dcr->windows = 0;
+ offset += dcr->header.length;
- offset = offset + offsetof(struct acpi_nfit_control_region,
- window_size);
/* bdw4 (spa/dcr4, dimm4) */
bdw = nfit_buf + offset;
bdw->header.type = ACPI_NFIT_TYPE_DATA_REGION;
- bdw->header.length = sizeof(struct acpi_nfit_data_region);
+ bdw->header.length = sizeof(*bdw);
bdw->region_index = 8+1;
bdw->windows = 1;
bdw->offset = 0;
bdw->size = BDW_SIZE;
bdw->capacity = DIMM_SIZE;
bdw->start_address = 0;
+ offset += bdw->header.length;
- offset = offset + sizeof(struct acpi_nfit_data_region);
/* spa10 (dcr4) dimm4 */
spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
@@ -1932,30 +2042,32 @@ static void nfit_test0_setup(struct nfit_test *t)
spa->range_index = 10+1;
spa->address = t->dcr_dma[4];
spa->length = DCR_SIZE;
+ offset += spa->header.length;
/*
* spa11 (single-dimm interleave for hotplug, note storage
* does not actually alias the related block-data-window
* regions)
*/
- spa = nfit_buf + offset + sizeof(*spa);
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_PM), 16);
spa->range_index = 11+1;
spa->address = t->spa_set_dma[2];
spa->length = SPA0_SIZE;
+ offset += spa->header.length;
/* spa12 (bdw for dcr4) dimm4 */
- spa = nfit_buf + offset + sizeof(*spa) * 2;
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_BDW), 16);
spa->range_index = 12+1;
spa->address = t->dimm_dma[4];
spa->length = DIMM_SIZE;
+ offset += spa->header.length;
- offset = offset + sizeof(*spa) * 3;
/* mem-region14 (spa/dcr4, dimm4) */
memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
@@ -1970,10 +2082,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = 0;
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
+ offset += memdev->header.length;
- /* mem-region15 (spa0, dimm4) */
- memdev = nfit_buf + offset +
- sizeof(struct acpi_nfit_memory_map);
+ /* mem-region15 (spa11, dimm4) */
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[4];
@@ -1987,10 +2099,10 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
memdev->flags = ACPI_NFIT_MEM_HEALTH_ENABLED;
+ offset += memdev->header.length;
/* mem-region16 (spa/bdw4, dimm4) */
- memdev = nfit_buf + offset +
- sizeof(struct acpi_nfit_memory_map) * 2;
+ memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
memdev->device_handle = handle[4];
@@ -2003,8 +2115,8 @@ static void nfit_test0_setup(struct nfit_test *t)
memdev->address = 0;
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
+ offset += memdev->header.length;
- offset = offset + sizeof(struct acpi_nfit_memory_map) * 3;
/* flush3 (dimm4) */
flush = nfit_buf + offset;
flush->header.type = ACPI_NFIT_TYPE_FLUSH_ADDRESS;
@@ -2014,8 +2126,14 @@ static void nfit_test0_setup(struct nfit_test *t)
for (i = 0; i < NUM_HINTS; i++)
flush->hint_address[i] = t->flush_dma[4]
+ i * sizeof(u64);
+ offset += flush->header.length;
+
+ /* sanity check to make sure we've filled the buffer */
+ WARN_ON(offset != t->nfit_size);
}
+ t->nfit_filled = offset;
+
post_ars_status(&t->ars_state, &t->badrange, t->spa_set_dma[0],
SPA0_SIZE);
@@ -2026,6 +2144,7 @@ static void nfit_test0_setup(struct nfit_test *t)
set_bit(ND_INTEL_SMART, &acpi_desc->dimm_cmd_force_en);
set_bit(ND_INTEL_SMART_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
set_bit(ND_INTEL_SMART_SET_THRESHOLD, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_INTEL_SMART_INJECT, &acpi_desc->dimm_cmd_force_en);
set_bit(ND_CMD_ARS_CAP, &acpi_desc->bus_cmd_force_en);
set_bit(ND_CMD_ARS_START, &acpi_desc->bus_cmd_force_en);
set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
@@ -2061,17 +2180,18 @@ static void nfit_test1_setup(struct nfit_test *t)
spa->range_index = 0+1;
spa->address = t->spa_set_dma[0];
spa->length = SPA2_SIZE;
+ offset += spa->header.length;
/* virtual cd region */
- spa = nfit_buf + sizeof(*spa);
+ spa = nfit_buf + offset;
spa->header.type = ACPI_NFIT_TYPE_SYSTEM_ADDRESS;
spa->header.length = sizeof(*spa);
memcpy(spa->range_guid, to_nfit_uuid(NFIT_SPA_VCD), 16);
spa->range_index = 0;
spa->address = t->spa_set_dma[1];
spa->length = SPA_VCD_SIZE;
+ offset += spa->header.length;
- offset += sizeof(*spa) * 2;
/* mem-region0 (spa0, dimm0) */
memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
@@ -2089,8 +2209,8 @@ static void nfit_test1_setup(struct nfit_test *t)
memdev->flags = ACPI_NFIT_MEM_SAVE_FAILED | ACPI_NFIT_MEM_RESTORE_FAILED
| ACPI_NFIT_MEM_FLUSH_FAILED | ACPI_NFIT_MEM_HEALTH_OBSERVED
| ACPI_NFIT_MEM_NOT_ARMED;
+ offset += memdev->header.length;
- offset += sizeof(*memdev);
/* dcr-descriptor0 */
dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
@@ -2101,8 +2221,8 @@ static void nfit_test1_setup(struct nfit_test *t)
dcr->serial_number = ~handle[5];
dcr->code = NFIT_FIC_BYTE;
dcr->windows = 0;
-
offset += dcr->header.length;
+
memdev = nfit_buf + offset;
memdev->header.type = ACPI_NFIT_TYPE_MEMORY_MAP;
memdev->header.length = sizeof(*memdev);
@@ -2117,9 +2237,9 @@ static void nfit_test1_setup(struct nfit_test *t)
memdev->interleave_index = 0;
memdev->interleave_ways = 1;
memdev->flags = ACPI_NFIT_MEM_MAP_FAILED;
+ offset += memdev->header.length;
/* dcr-descriptor1 */
- offset += sizeof(*memdev);
dcr = nfit_buf + offset;
dcr->header.type = ACPI_NFIT_TYPE_CONTROL_REGION;
dcr->header.length = offsetof(struct acpi_nfit_control_region,
@@ -2129,6 +2249,12 @@ static void nfit_test1_setup(struct nfit_test *t)
dcr->serial_number = ~handle[6];
dcr->code = NFIT_FIC_BYTE;
dcr->windows = 0;
+ offset += dcr->header.length;
+
+ /* sanity check to make sure we've filled the buffer */
+ WARN_ON(offset != t->nfit_size);
+
+ t->nfit_filled = offset;
post_ars_status(&t->ars_state, &t->badrange, t->spa_set_dma[0],
SPA2_SIZE);
@@ -2139,6 +2265,9 @@ static void nfit_test1_setup(struct nfit_test *t)
set_bit(ND_CMD_ARS_STATUS, &acpi_desc->bus_cmd_force_en);
set_bit(ND_CMD_CLEAR_ERROR, &acpi_desc->bus_cmd_force_en);
set_bit(ND_INTEL_ENABLE_LSS_STATUS, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_CMD_GET_CONFIG_SIZE, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_CMD_GET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
+ set_bit(ND_CMD_SET_CONFIG_DATA, &acpi_desc->dimm_cmd_force_en);
}
static int nfit_test_blk_do_io(struct nd_blk_region *ndbr, resource_size_t dpa,
@@ -2487,7 +2616,7 @@ static int nfit_test_probe(struct platform_device *pdev)
nd_desc->ndctl = nfit_test_ctl;
rc = acpi_nfit_init(acpi_desc, nfit_test->nfit_buf,
- nfit_test->nfit_size);
+ nfit_test->nfit_filled);
if (rc)
return rc;