|
@@ -142,6 +142,28 @@ static u32 handle[] = {
|
|
|
static unsigned long dimm_fail_cmd_flags[NUM_DCR];
|
|
|
static int dimm_fail_cmd_code[NUM_DCR];
|
|
|
|
|
|
+static const struct nd_intel_smart smart_def = {
|
|
|
+ .flags = ND_INTEL_SMART_HEALTH_VALID
|
|
|
+ | ND_INTEL_SMART_SPARES_VALID
|
|
|
+ | ND_INTEL_SMART_ALARM_VALID
|
|
|
+ | ND_INTEL_SMART_USED_VALID
|
|
|
+ | ND_INTEL_SMART_SHUTDOWN_VALID
|
|
|
+ | ND_INTEL_SMART_MTEMP_VALID
|
|
|
+ | ND_INTEL_SMART_CTEMP_VALID,
|
|
|
+ .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
|
|
|
+ .media_temperature = 23 * 16,
|
|
|
+ .ctrl_temperature = 25 * 16,
|
|
|
+ .pmic_temperature = 40 * 16,
|
|
|
+ .spares = 75,
|
|
|
+ .alarm_flags = ND_INTEL_SMART_SPARE_TRIP
|
|
|
+ | ND_INTEL_SMART_TEMP_TRIP,
|
|
|
+ .ait_status = 1,
|
|
|
+ .life_used = 5,
|
|
|
+ .shutdown_state = 0,
|
|
|
+ .vendor_size = 0,
|
|
|
+ .shutdown_count = 100,
|
|
|
+};
|
|
|
+
|
|
|
struct nfit_test_fw {
|
|
|
enum intel_fw_update_state state;
|
|
|
u32 context;
|
|
@@ -752,15 +774,30 @@ static int nfit_test_cmd_smart_inject(
|
|
|
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++;
|
|
|
+ if (inj->flags & ND_INTEL_SMART_INJECT_MTEMP) {
|
|
|
+ if (inj->mtemp_enable)
|
|
|
+ smart->media_temperature = inj->media_temperature;
|
|
|
+ else
|
|
|
+ smart->media_temperature = smart_def.media_temperature;
|
|
|
+ }
|
|
|
+ if (inj->flags & ND_INTEL_SMART_INJECT_SPARE) {
|
|
|
+ if (inj->spare_enable)
|
|
|
+ smart->spares = inj->spares;
|
|
|
+ else
|
|
|
+ smart->spares = smart_def.spares;
|
|
|
+ }
|
|
|
+ if (inj->flags & ND_INTEL_SMART_INJECT_FATAL) {
|
|
|
+ if (inj->fatal_enable)
|
|
|
+ smart->health = ND_INTEL_SMART_FATAL_HEALTH;
|
|
|
+ else
|
|
|
+ smart->health = ND_INTEL_SMART_NON_CRITICAL_HEALTH;
|
|
|
+ }
|
|
|
+ if (inj->flags & ND_INTEL_SMART_INJECT_SHUTDOWN) {
|
|
|
+ if (inj->unsafe_shutdown_enable) {
|
|
|
+ smart->shutdown_state = 1;
|
|
|
+ smart->shutdown_count++;
|
|
|
+ } else
|
|
|
+ smart->shutdown_state = 0;
|
|
|
}
|
|
|
inj->status = 0;
|
|
|
smart_notify(bus_dev, dimm_dev, smart, thresh);
|
|
@@ -884,6 +921,16 @@ static int nd_intel_test_cmd_set_lss_status(struct nfit_test *t,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int override_return_code(int dimm, unsigned int func, int rc)
|
|
|
+{
|
|
|
+ if ((1 << func) & dimm_fail_cmd_flags[dimm]) {
|
|
|
+ if (dimm_fail_cmd_code[dimm])
|
|
|
+ return dimm_fail_cmd_code[dimm];
|
|
|
+ return -EIO;
|
|
|
+ }
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
|
|
|
{
|
|
|
int i;
|
|
@@ -894,13 +941,6 @@ static int get_dimm(struct nfit_mem *nfit_mem, unsigned int func)
|
|
|
break;
|
|
|
if (i >= ARRAY_SIZE(handle))
|
|
|
return -ENXIO;
|
|
|
-
|
|
|
- if ((1 << func) & dimm_fail_cmd_flags[i]) {
|
|
|
- if (dimm_fail_cmd_code[i])
|
|
|
- return dimm_fail_cmd_code[i];
|
|
|
- return -EIO;
|
|
|
- }
|
|
|
-
|
|
|
return i;
|
|
|
}
|
|
|
|
|
@@ -939,48 +979,59 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
|
|
|
|
|
|
switch (func) {
|
|
|
case ND_INTEL_ENABLE_LSS_STATUS:
|
|
|
- return nd_intel_test_cmd_set_lss_status(t,
|
|
|
+ rc = nd_intel_test_cmd_set_lss_status(t,
|
|
|
buf, buf_len);
|
|
|
+ break;
|
|
|
case ND_INTEL_FW_GET_INFO:
|
|
|
- return nd_intel_test_get_fw_info(t, buf,
|
|
|
+ rc = nd_intel_test_get_fw_info(t, buf,
|
|
|
buf_len, i - t->dcr_idx);
|
|
|
+ break;
|
|
|
case ND_INTEL_FW_START_UPDATE:
|
|
|
- return nd_intel_test_start_update(t, buf,
|
|
|
+ rc = nd_intel_test_start_update(t, buf,
|
|
|
buf_len, i - t->dcr_idx);
|
|
|
+ break;
|
|
|
case ND_INTEL_FW_SEND_DATA:
|
|
|
- return nd_intel_test_send_data(t, buf,
|
|
|
+ rc = nd_intel_test_send_data(t, buf,
|
|
|
buf_len, i - t->dcr_idx);
|
|
|
+ break;
|
|
|
case ND_INTEL_FW_FINISH_UPDATE:
|
|
|
- return nd_intel_test_finish_fw(t, buf,
|
|
|
+ rc = nd_intel_test_finish_fw(t, buf,
|
|
|
buf_len, i - t->dcr_idx);
|
|
|
+ break;
|
|
|
case ND_INTEL_FW_FINISH_QUERY:
|
|
|
- return nd_intel_test_finish_query(t, buf,
|
|
|
+ rc = nd_intel_test_finish_query(t, buf,
|
|
|
buf_len, i - t->dcr_idx);
|
|
|
+ break;
|
|
|
case ND_INTEL_SMART:
|
|
|
- return nfit_test_cmd_smart(buf, buf_len,
|
|
|
+ rc = nfit_test_cmd_smart(buf, buf_len,
|
|
|
&t->smart[i - t->dcr_idx]);
|
|
|
+ break;
|
|
|
case ND_INTEL_SMART_THRESHOLD:
|
|
|
- return nfit_test_cmd_smart_threshold(buf,
|
|
|
+ rc = nfit_test_cmd_smart_threshold(buf,
|
|
|
buf_len,
|
|
|
&t->smart_threshold[i -
|
|
|
t->dcr_idx]);
|
|
|
+ break;
|
|
|
case ND_INTEL_SMART_SET_THRESHOLD:
|
|
|
- return nfit_test_cmd_smart_set_threshold(buf,
|
|
|
+ rc = nfit_test_cmd_smart_set_threshold(buf,
|
|
|
buf_len,
|
|
|
&t->smart_threshold[i -
|
|
|
t->dcr_idx],
|
|
|
&t->smart[i - t->dcr_idx],
|
|
|
&t->pdev.dev, t->dimm_dev[i]);
|
|
|
+ break;
|
|
|
case ND_INTEL_SMART_INJECT:
|
|
|
- return nfit_test_cmd_smart_inject(buf,
|
|
|
+ rc = 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]);
|
|
|
+ break;
|
|
|
default:
|
|
|
return -ENOTTY;
|
|
|
}
|
|
|
+ return override_return_code(i, func, rc);
|
|
|
}
|
|
|
|
|
|
if (!test_bit(cmd, &cmd_mask)
|
|
@@ -1006,6 +1057,7 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
|
|
|
default:
|
|
|
return -ENOTTY;
|
|
|
}
|
|
|
+ return override_return_code(i, func, rc);
|
|
|
} else {
|
|
|
struct ars_state *ars_state = &t->ars_state;
|
|
|
struct nd_cmd_pkg *call_pkg = buf;
|
|
@@ -1302,29 +1354,9 @@ static void smart_init(struct nfit_test *t)
|
|
|
.ctrl_temperature = 30 * 16,
|
|
|
.spares = 5,
|
|
|
};
|
|
|
- const struct nd_intel_smart smart_data = {
|
|
|
- .flags = ND_INTEL_SMART_HEALTH_VALID
|
|
|
- | ND_INTEL_SMART_SPARES_VALID
|
|
|
- | ND_INTEL_SMART_ALARM_VALID
|
|
|
- | ND_INTEL_SMART_USED_VALID
|
|
|
- | ND_INTEL_SMART_SHUTDOWN_VALID
|
|
|
- | ND_INTEL_SMART_MTEMP_VALID,
|
|
|
- .health = ND_INTEL_SMART_NON_CRITICAL_HEALTH,
|
|
|
- .media_temperature = 23 * 16,
|
|
|
- .ctrl_temperature = 25 * 16,
|
|
|
- .pmic_temperature = 40 * 16,
|
|
|
- .spares = 75,
|
|
|
- .alarm_flags = ND_INTEL_SMART_SPARE_TRIP
|
|
|
- | ND_INTEL_SMART_TEMP_TRIP,
|
|
|
- .ait_status = 1,
|
|
|
- .life_used = 5,
|
|
|
- .shutdown_state = 0,
|
|
|
- .vendor_size = 0,
|
|
|
- .shutdown_count = 100,
|
|
|
- };
|
|
|
|
|
|
for (i = 0; i < t->num_dcr; i++) {
|
|
|
- memcpy(&t->smart[i], &smart_data, sizeof(smart_data));
|
|
|
+ memcpy(&t->smart[i], &smart_def, sizeof(smart_def));
|
|
|
memcpy(&t->smart_threshold[i], &smart_t_data,
|
|
|
sizeof(smart_t_data));
|
|
|
}
|