aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2016-02-23 00:50:31 -0500
committerDan Williams <dan.j.williams@intel.com>2016-03-05 15:24:06 -0500
commit87bf572e19a092cc9cc77d5a00d543a2b628c142 (patch)
treeae275e80641400bccfbf39c168dbfc5178b44159 /drivers/acpi
parent1cf03c00e7c17d3cf13a267dac83b3162a16ba8c (diff)
nfit: disable userspace initiated ars during scrub
While the nfit driver is issuing address range scrub commands and reaping the results do not permit an ars_start command issued from userspace. The scrub thread assumes that all ars completions are for scrubs initiated by platform firmware at boot, or by the nfit driver. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/nfit.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
index 3646501b01d7..0def4ebf5d43 100644
--- a/drivers/acpi/nfit.c
+++ b/drivers/acpi/nfit.c
@@ -2186,6 +2186,28 @@ static int acpi_nfit_flush_probe(struct nvdimm_bus_descriptor *nd_desc)
2186 return wait_for_completion_interruptible(&flush.cmp); 2186 return wait_for_completion_interruptible(&flush.cmp);
2187} 2187}
2188 2188
2189static int acpi_nfit_clear_to_send(struct nvdimm_bus_descriptor *nd_desc,
2190 struct nvdimm *nvdimm, unsigned int cmd)
2191{
2192 struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc);
2193
2194 if (nvdimm)
2195 return 0;
2196 if (cmd != ND_CMD_ARS_START)
2197 return 0;
2198
2199 /*
2200 * The kernel and userspace may race to initiate a scrub, but
2201 * the scrub thread is prepared to lose that initial race. It
2202 * just needs guarantees that any ars it initiates are not
2203 * interrupted by any intervening start reqeusts from userspace.
2204 */
2205 if (work_busy(&acpi_desc->work))
2206 return -EBUSY;
2207
2208 return 0;
2209}
2210
2189void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev) 2211void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev)
2190{ 2212{
2191 struct nvdimm_bus_descriptor *nd_desc; 2213 struct nvdimm_bus_descriptor *nd_desc;
@@ -2197,6 +2219,7 @@ void acpi_nfit_desc_init(struct acpi_nfit_desc *acpi_desc, struct device *dev)
2197 nd_desc->provider_name = "ACPI.NFIT"; 2219 nd_desc->provider_name = "ACPI.NFIT";
2198 nd_desc->ndctl = acpi_nfit_ctl; 2220 nd_desc->ndctl = acpi_nfit_ctl;
2199 nd_desc->flush_probe = acpi_nfit_flush_probe; 2221 nd_desc->flush_probe = acpi_nfit_flush_probe;
2222 nd_desc->clear_to_send = acpi_nfit_clear_to_send;
2200 nd_desc->attr_groups = acpi_nfit_attribute_groups; 2223 nd_desc->attr_groups = acpi_nfit_attribute_groups;
2201 2224
2202 INIT_LIST_HEAD(&acpi_desc->spa_maps); 2225 INIT_LIST_HEAD(&acpi_desc->spa_maps);