mirror of https://gitee.com/openkylin/linux.git
acpi/nfit: Issue Start ARS to retrieve existing records
ACPI 6.2 defines in section 9.20.7.2 that the OSPM may call a Start ARS with Flags Bit [1] set upon receiving the 0x81 notification. Upon receiving the notification, the OSPM may decide to issue a Start ARS with Flags Bit [1] set to prepare for the retrieval of existing records and issue the Query ARS Status function to retrieve the records. Add support to call a Start ARS from acpi_nfit_uc_error_notify() with ND_ARS_RETURN_PREV_DATA set when HW_ERROR_SCRUB_ON is not set. Link: http://www.uefi.org/sites/default/files/resources/ACPI_6_2.pdf Signed-off-by: Toshi Kani <toshi.kani@hpe.com> Cc: Dan Williams <dan.j.williams@intel.com> Cc: Rafael J. Wysocki <rjw@rjwysocki.net> Cc: Vishal Verma <vishal.l.verma@intel.com> Cc: Linda Knippers <linda.knippers@hpe.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
759d6a9641
commit
807900395e
|
@ -1044,7 +1044,7 @@ static ssize_t scrub_store(struct device *dev,
|
|||
if (nd_desc) {
|
||||
struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
|
||||
|
||||
rc = acpi_nfit_ars_rescan(acpi_desc);
|
||||
rc = acpi_nfit_ars_rescan(acpi_desc, 0);
|
||||
}
|
||||
device_unlock(dev);
|
||||
if (rc)
|
||||
|
@ -2137,6 +2137,7 @@ static int ars_start(struct acpi_nfit_desc *acpi_desc, struct nfit_spa *nfit_spa
|
|||
memset(&ars_start, 0, sizeof(ars_start));
|
||||
ars_start.address = spa->address;
|
||||
ars_start.length = spa->length;
|
||||
ars_start.flags = acpi_desc->ars_start_flags;
|
||||
if (nfit_spa_type(spa) == NFIT_SPA_PM)
|
||||
ars_start.type = ND_ARS_PERSISTENT;
|
||||
else if (nfit_spa_type(spa) == NFIT_SPA_VOLATILE)
|
||||
|
@ -2163,6 +2164,7 @@ static int ars_continue(struct acpi_nfit_desc *acpi_desc)
|
|||
ars_start.address = ars_status->restart_address;
|
||||
ars_start.length = ars_status->restart_length;
|
||||
ars_start.type = ars_status->type;
|
||||
ars_start.flags = acpi_desc->ars_start_flags;
|
||||
rc = nd_desc->ndctl(nd_desc, NULL, ND_CMD_ARS_START, &ars_start,
|
||||
sizeof(ars_start), &cmd_rc);
|
||||
if (rc < 0)
|
||||
|
@ -2684,6 +2686,7 @@ static void acpi_nfit_scrub(struct work_struct *work)
|
|||
list_for_each_entry(nfit_spa, &acpi_desc->spas, list)
|
||||
acpi_nfit_async_scrub(acpi_desc, nfit_spa);
|
||||
acpi_desc->scrub_count++;
|
||||
acpi_desc->ars_start_flags = 0;
|
||||
if (acpi_desc->scrub_count_state)
|
||||
sysfs_notify_dirent(acpi_desc->scrub_count_state);
|
||||
mutex_unlock(&acpi_desc->init_mutex);
|
||||
|
@ -2702,6 +2705,7 @@ static int acpi_nfit_register_regions(struct acpi_nfit_desc *acpi_desc)
|
|||
return rc;
|
||||
}
|
||||
|
||||
acpi_desc->ars_start_flags = 0;
|
||||
if (!acpi_desc->cancel)
|
||||
queue_work(nfit_wq, &acpi_desc->work);
|
||||
return 0;
|
||||
|
@ -2906,7 +2910,7 @@ static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc)
|
||||
int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, u8 flags)
|
||||
{
|
||||
struct device *dev = acpi_desc->dev;
|
||||
struct nfit_spa *nfit_spa;
|
||||
|
@ -2928,6 +2932,7 @@ int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc)
|
|||
|
||||
nfit_spa->ars_required = 1;
|
||||
}
|
||||
acpi_desc->ars_start_flags = flags;
|
||||
queue_work(nfit_wq, &acpi_desc->work);
|
||||
dev_dbg(dev, "%s: ars_scan triggered\n", __func__);
|
||||
mutex_unlock(&acpi_desc->init_mutex);
|
||||
|
@ -3104,8 +3109,10 @@ static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
|
|||
static void acpi_nfit_uc_error_notify(struct device *dev, acpi_handle handle)
|
||||
{
|
||||
struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev);
|
||||
u8 flags = (acpi_desc->scrub_mode == HW_ERROR_SCRUB_ON) ?
|
||||
0 : ND_ARS_RETURN_PREV_DATA;
|
||||
|
||||
acpi_nfit_ars_rescan(acpi_desc);
|
||||
acpi_nfit_ars_rescan(acpi_desc, flags);
|
||||
}
|
||||
|
||||
void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event)
|
||||
|
|
|
@ -79,7 +79,7 @@ static int nfit_handle_mce(struct notifier_block *nb, unsigned long val,
|
|||
* already in progress, just let that be the last
|
||||
* authoritative one
|
||||
*/
|
||||
acpi_nfit_ars_rescan(acpi_desc);
|
||||
acpi_nfit_ars_rescan(acpi_desc, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -155,6 +155,7 @@ struct acpi_nfit_desc {
|
|||
struct list_head idts;
|
||||
struct nvdimm_bus *nvdimm_bus;
|
||||
struct device *dev;
|
||||
u8 ars_start_flags;
|
||||
struct nd_cmd_ars_status *ars_status;
|
||||
size_t ars_status_size;
|
||||
struct work_struct work;
|
||||
|
@ -207,7 +208,7 @@ struct nfit_blk {
|
|||
|
||||
extern struct list_head acpi_descs;
|
||||
extern struct mutex acpi_desc_lock;
|
||||
int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc);
|
||||
int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, u8 flags);
|
||||
|
||||
#ifdef CONFIG_X86_MCE
|
||||
void nfit_mce_register(void);
|
||||
|
|
|
@ -207,6 +207,7 @@ enum {
|
|||
enum {
|
||||
ND_ARS_VOLATILE = 1,
|
||||
ND_ARS_PERSISTENT = 2,
|
||||
ND_ARS_RETURN_PREV_DATA = 1 << 1,
|
||||
ND_CONFIG_LOCKED = 1,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue