Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Toshi Kani and committed by
Dan Williams
80790039 759d6a96

+14 -5
+10 -3
drivers/acpi/nfit/core.c
··· 1044 1044 if (nd_desc) { 1045 1045 struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc); 1046 1046 1047 - rc = acpi_nfit_ars_rescan(acpi_desc); 1047 + rc = acpi_nfit_ars_rescan(acpi_desc, 0); 1048 1048 } 1049 1049 device_unlock(dev); 1050 1050 if (rc) ··· 2137 2137 memset(&ars_start, 0, sizeof(ars_start)); 2138 2138 ars_start.address = spa->address; 2139 2139 ars_start.length = spa->length; 2140 + ars_start.flags = acpi_desc->ars_start_flags; 2140 2141 if (nfit_spa_type(spa) == NFIT_SPA_PM) 2141 2142 ars_start.type = ND_ARS_PERSISTENT; 2142 2143 else if (nfit_spa_type(spa) == NFIT_SPA_VOLATILE) ··· 2164 2163 ars_start.address = ars_status->restart_address; 2165 2164 ars_start.length = ars_status->restart_length; 2166 2165 ars_start.type = ars_status->type; 2166 + ars_start.flags = acpi_desc->ars_start_flags; 2167 2167 rc = nd_desc->ndctl(nd_desc, NULL, ND_CMD_ARS_START, &ars_start, 2168 2168 sizeof(ars_start), &cmd_rc); 2169 2169 if (rc < 0) ··· 2686 2684 list_for_each_entry(nfit_spa, &acpi_desc->spas, list) 2687 2685 acpi_nfit_async_scrub(acpi_desc, nfit_spa); 2688 2686 acpi_desc->scrub_count++; 2687 + acpi_desc->ars_start_flags = 0; 2689 2688 if (acpi_desc->scrub_count_state) 2690 2689 sysfs_notify_dirent(acpi_desc->scrub_count_state); 2691 2690 mutex_unlock(&acpi_desc->init_mutex); ··· 2705 2702 return rc; 2706 2703 } 2707 2704 2705 + acpi_desc->ars_start_flags = 0; 2708 2706 if (!acpi_desc->cancel) 2709 2707 queue_work(nfit_wq, &acpi_desc->work); 2710 2708 return 0; ··· 2910 2906 return 0; 2911 2907 } 2912 2908 2913 - int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc) 2909 + int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, u8 flags) 2914 2910 { 2915 2911 struct device *dev = acpi_desc->dev; 2916 2912 struct nfit_spa *nfit_spa; ··· 2932 2928 2933 2929 nfit_spa->ars_required = 1; 2934 2930 } 2931 + acpi_desc->ars_start_flags = flags; 2935 2932 queue_work(nfit_wq, &acpi_desc->work); 2936 2933 dev_dbg(dev, "%s: ars_scan triggered\n", __func__); 2937 2934 mutex_unlock(&acpi_desc->init_mutex); ··· 3109 3104 static void acpi_nfit_uc_error_notify(struct device *dev, acpi_handle handle) 3110 3105 { 3111 3106 struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev); 3107 + u8 flags = (acpi_desc->scrub_mode == HW_ERROR_SCRUB_ON) ? 3108 + 0 : ND_ARS_RETURN_PREV_DATA; 3112 3109 3113 - acpi_nfit_ars_rescan(acpi_desc); 3110 + acpi_nfit_ars_rescan(acpi_desc, flags); 3114 3111 } 3115 3112 3116 3113 void __acpi_nfit_notify(struct device *dev, acpi_handle handle, u32 event)
+1 -1
drivers/acpi/nfit/mce.c
··· 79 79 * already in progress, just let that be the last 80 80 * authoritative one 81 81 */ 82 - acpi_nfit_ars_rescan(acpi_desc); 82 + acpi_nfit_ars_rescan(acpi_desc, 0); 83 83 } 84 84 break; 85 85 }
+2 -1
drivers/acpi/nfit/nfit.h
··· 155 155 struct list_head idts; 156 156 struct nvdimm_bus *nvdimm_bus; 157 157 struct device *dev; 158 + u8 ars_start_flags; 158 159 struct nd_cmd_ars_status *ars_status; 159 160 size_t ars_status_size; 160 161 struct work_struct work; ··· 208 207 209 208 extern struct list_head acpi_descs; 210 209 extern struct mutex acpi_desc_lock; 211 - int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc); 210 + int acpi_nfit_ars_rescan(struct acpi_nfit_desc *acpi_desc, u8 flags); 212 211 213 212 #ifdef CONFIG_X86_MCE 214 213 void nfit_mce_register(void);
+1
include/uapi/linux/ndctl.h
··· 207 207 enum { 208 208 ND_ARS_VOLATILE = 1, 209 209 ND_ARS_PERSISTENT = 2, 210 + ND_ARS_RETURN_PREV_DATA = 1 << 1, 210 211 ND_CONFIG_LOCKED = 1, 211 212 }; 212 213