if (!test_bit(NVDIMM_INTEL_GET_SECURITY_STATE, &nfit_mem->dsm_mask)) return 0;
/* * Short circuit the state retrieval while we are doing overwrite. * The DSM spec states that the security state is indeterminate * until the overwrite DSM completes.
*/ if (nvdimm_in_overwrite(nvdimm) && ptype == NVDIMM_USER) return BIT(NVDIMM_SECURITY_OVERWRITE);
/* check and see if security is enabled and locked */ if (ptype == NVDIMM_MASTER) { if (nd_cmd.cmd.extended_state & ND_INTEL_SEC_ESTATE_ENABLED)
set_bit(NVDIMM_SECURITY_UNLOCKED, &security_flags); else
set_bit(NVDIMM_SECURITY_DISABLED, &security_flags); if (nd_cmd.cmd.extended_state & ND_INTEL_SEC_ESTATE_PLIMIT)
set_bit(NVDIMM_SECURITY_FROZEN, &security_flags); return security_flags;
}
if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_UNSUPPORTED) return 0;
if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_ENABLED) { if (nd_cmd.cmd.state & ND_INTEL_SEC_STATE_FROZEN ||
nd_cmd.cmd.state & ND_INTEL_SEC_STATE_PLIMIT)
set_bit(NVDIMM_SECURITY_FROZEN, &security_flags);
switch (nd_cmd.cmd.status) { case 0: break; case ND_INTEL_STATUS_NOT_SUPPORTED: return -EOPNOTSUPP; case ND_INTEL_STATUS_INVALID_PASS: return -EINVAL; case ND_INTEL_STATUS_INVALID_STATE: default: return -ENXIO;
}
/* The fw_ops expect to be called with the nvdimm_bus_lock() held */ staticenum nvdimm_fwa_state intel_bus_fwa_state( struct nvdimm_bus_descriptor *nd_desc)
{ struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); struct nd_intel_bus_fw_activate_businfo info; struct device *dev = acpi_desc->dev; enum nvdimm_fwa_state state; int rc;
/* * It should not be possible for platform firmware to return * busy because activate is a synchronous operation. Treat it * similar to invalid, i.e. always refresh / poll the status.
*/ switch (acpi_desc->fwa_state) { case NVDIMM_FWA_INVALID: case NVDIMM_FWA_BUSY: break; default: /* check if capability needs to be refreshed */ if (acpi_desc->fwa_cap == NVDIMM_FWA_CAP_INVALID) break; return acpi_desc->fwa_state;
}
/* Refresh with platform firmware */
rc = intel_bus_fwa_businfo(nd_desc, &info); if (rc) return NVDIMM_FWA_INVALID;
switch (info.state) { case ND_INTEL_FWA_IDLE:
state = NVDIMM_FWA_IDLE; break; case ND_INTEL_FWA_BUSY:
state = NVDIMM_FWA_BUSY; break; case ND_INTEL_FWA_ARMED: if (info.activate_tmo > info.max_quiesce_tmo)
state = NVDIMM_FWA_ARM_OVERFLOW; else
state = NVDIMM_FWA_ARMED; break; default:
dev_err_once(dev, "invalid firmware activate state %d\n",
info.state); return NVDIMM_FWA_INVALID;
}
/* * Capability data is available in the same payload as state. It * is expected to be static.
*/ if (acpi_desc->fwa_cap == NVDIMM_FWA_CAP_INVALID) { if (info.capability & ND_INTEL_BUS_FWA_CAP_FWQUIESCE)
acpi_desc->fwa_cap = NVDIMM_FWA_CAP_QUIESCE; elseif (info.capability & ND_INTEL_BUS_FWA_CAP_OSQUIESCE) { /* * Skip hibernate cycle by default if platform * indicates that it does not need devices to be * quiesced.
*/
acpi_desc->fwa_cap = NVDIMM_FWA_CAP_LIVE;
} else
acpi_desc->fwa_cap = NVDIMM_FWA_CAP_NONE;
}
/* * Whether the command succeeded, or failed, the agent checking * for the result needs to query the DIMMs individually. * Increment the activation count to invalidate all the DIMM * states at once (it's otherwise not possible to take * acpi_desc->init_mutex in this context)
*/
acpi_desc->fwa_state = NVDIMM_FWA_INVALID;
acpi_desc->fwa_count++;
/* * Similar to the bus state, since activate is synchronous the * busy state should resolve within the context of 'activate'.
*/ switch (nfit_mem->fwa_state) { case NVDIMM_FWA_INVALID: case NVDIMM_FWA_BUSY: break; default: /* If no activations occurred the old state is still valid */ if (nfit_mem->fwa_count == acpi_desc->fwa_count) return nfit_mem->fwa_state;
}
rc = intel_fwa_dimminfo(nvdimm, &info); if (rc) return NVDIMM_FWA_INVALID;
switch (info.state) { case ND_INTEL_FWA_IDLE:
nfit_mem->fwa_state = NVDIMM_FWA_IDLE; break; case ND_INTEL_FWA_BUSY:
nfit_mem->fwa_state = NVDIMM_FWA_BUSY; break; case ND_INTEL_FWA_ARMED:
nfit_mem->fwa_state = NVDIMM_FWA_ARMED; break; default:
nfit_mem->fwa_state = NVDIMM_FWA_INVALID; break;
}
switch (info.result) { case ND_INTEL_DIMM_FWA_NONE:
nfit_mem->fwa_result = NVDIMM_FWA_RESULT_NONE; break; case ND_INTEL_DIMM_FWA_SUCCESS:
nfit_mem->fwa_result = NVDIMM_FWA_RESULT_SUCCESS; break; case ND_INTEL_DIMM_FWA_NOTSTAGED:
nfit_mem->fwa_result = NVDIMM_FWA_RESULT_NOTSTAGED; break; case ND_INTEL_DIMM_FWA_NEEDRESET:
nfit_mem->fwa_result = NVDIMM_FWA_RESULT_NEEDRESET; break; case ND_INTEL_DIMM_FWA_MEDIAFAILED: case ND_INTEL_DIMM_FWA_ABORT: case ND_INTEL_DIMM_FWA_NOTSUPP: case ND_INTEL_DIMM_FWA_ERROR: default:
nfit_mem->fwa_result = NVDIMM_FWA_RESULT_FAIL; break;
}
switch (intel_fwa_state(nvdimm)) { case NVDIMM_FWA_INVALID: return -ENXIO; case NVDIMM_FWA_BUSY: return -EBUSY; case NVDIMM_FWA_IDLE: if (arm == NVDIMM_FWA_DISARM) return 0; break; case NVDIMM_FWA_ARMED: if (arm == NVDIMM_FWA_ARM) return 0; break; default: return -ENXIO;
}
/* * Invalidate the bus-level state, now that we're committed to * changing the 'arm' state.
*/
acpi_desc->fwa_state = NVDIMM_FWA_INVALID;
nfit_mem->fwa_state = NVDIMM_FWA_INVALID;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.