Commit 459413db authored by Luck, Tony's avatar Luck, Tony Committed by Len Brown

Use acpi_os_map_memory() instead of ioremap() in einj driver

ioremap() has become more picky and is now spitting out console messages like:

 ioremap error for 0xbddbd000-0xbddbe000, requested 0x10, got 0x0

when loading the einj driver.  What we are trying to so here is map
a couple of data structures that the EINJ table points to. Perhaps
acpi_os_map_memory() is a better tool for this?
Most importantly it works, but as a side benefit it maps the structures
into kernel virtual space so we can access them with normal C memory
dereferences, so instead of using:
	writel(param1, &v5param->apicid);
we can use the more natural:
	v5param->apicid = param1;
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 29924b9f
...@@ -141,21 +141,6 @@ static DEFINE_MUTEX(einj_mutex); ...@@ -141,21 +141,6 @@ static DEFINE_MUTEX(einj_mutex);
static void *einj_param; static void *einj_param;
#ifndef readq
static inline __u64 readq(volatile void __iomem *addr)
{
return ((__u64)readl(addr+4) << 32) + readl(addr);
}
#endif
#ifndef writeq
static inline void writeq(__u64 val, volatile void __iomem *addr)
{
writel(val, addr);
writel(val >> 32, addr+4);
}
#endif
static void einj_exec_ctx_init(struct apei_exec_context *ctx) static void einj_exec_ctx_init(struct apei_exec_context *ctx)
{ {
apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
...@@ -204,22 +189,21 @@ static int einj_timedout(u64 *t) ...@@ -204,22 +189,21 @@ static int einj_timedout(u64 *t)
static void check_vendor_extension(u64 paddr, static void check_vendor_extension(u64 paddr,
struct set_error_type_with_address *v5param) struct set_error_type_with_address *v5param)
{ {
int offset = readl(&v5param->vendor_extension); int offset = v5param->vendor_extension;
struct vendor_error_type_extension *v; struct vendor_error_type_extension *v;
u32 sbdf; u32 sbdf;
if (!offset) if (!offset)
return; return;
v = ioremap(paddr + offset, sizeof(*v)); v = acpi_os_map_memory(paddr + offset, sizeof(*v));
if (!v) if (!v)
return; return;
sbdf = readl(&v->pcie_sbdf); sbdf = v->pcie_sbdf;
sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n", sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n",
sbdf >> 24, (sbdf >> 16) & 0xff, sbdf >> 24, (sbdf >> 16) & 0xff,
(sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
readw(&v->vendor_id), readw(&v->device_id), v->vendor_id, v->device_id, v->rev_id);
readb(&v->rev_id)); acpi_os_unmap_memory(v, sizeof(*v));
iounmap(v);
} }
static void *einj_get_parameter_address(void) static void *einj_get_parameter_address(void)
...@@ -247,7 +231,7 @@ static void *einj_get_parameter_address(void) ...@@ -247,7 +231,7 @@ static void *einj_get_parameter_address(void)
if (paddrv5) { if (paddrv5) {
struct set_error_type_with_address *v5param; struct set_error_type_with_address *v5param;
v5param = ioremap(paddrv5, sizeof(*v5param)); v5param = acpi_os_map_memory(paddrv5, sizeof(*v5param));
if (v5param) { if (v5param) {
acpi5 = 1; acpi5 = 1;
check_vendor_extension(paddrv5, v5param); check_vendor_extension(paddrv5, v5param);
...@@ -257,11 +241,11 @@ static void *einj_get_parameter_address(void) ...@@ -257,11 +241,11 @@ static void *einj_get_parameter_address(void)
if (paddrv4) { if (paddrv4) {
struct einj_parameter *v4param; struct einj_parameter *v4param;
v4param = ioremap(paddrv4, sizeof(*v4param)); v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param));
if (!v4param) if (!v4param)
return NULL; return NULL;
if (readq(&v4param->reserved1) || readq(&v4param->reserved2)) { if (v4param->reserved1 || v4param->reserved2) {
iounmap(v4param); acpi_os_unmap_memory(v4param, sizeof(*v4param));
return NULL; return NULL;
} }
return v4param; return v4param;
...@@ -440,41 +424,41 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2) ...@@ -440,41 +424,41 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
if (acpi5) { if (acpi5) {
struct set_error_type_with_address *v5param = einj_param; struct set_error_type_with_address *v5param = einj_param;
writel(type, &v5param->type); v5param->type = type;
if (type & 0x80000000) { if (type & 0x80000000) {
switch (vendor_flags) { switch (vendor_flags) {
case SETWA_FLAGS_APICID: case SETWA_FLAGS_APICID:
writel(param1, &v5param->apicid); v5param->apicid = param1;
break; break;
case SETWA_FLAGS_MEM: case SETWA_FLAGS_MEM:
writeq(param1, &v5param->memory_address); v5param->memory_address = param1;
writeq(param2, &v5param->memory_address_range); v5param->memory_address_range = param2;
break; break;
case SETWA_FLAGS_PCIE_SBDF: case SETWA_FLAGS_PCIE_SBDF:
writel(param1, &v5param->pcie_sbdf); v5param->pcie_sbdf = param1;
break; break;
} }
writel(vendor_flags, &v5param->flags); v5param->flags = vendor_flags;
} else { } else {
switch (type) { switch (type) {
case ACPI_EINJ_PROCESSOR_CORRECTABLE: case ACPI_EINJ_PROCESSOR_CORRECTABLE:
case ACPI_EINJ_PROCESSOR_UNCORRECTABLE: case ACPI_EINJ_PROCESSOR_UNCORRECTABLE:
case ACPI_EINJ_PROCESSOR_FATAL: case ACPI_EINJ_PROCESSOR_FATAL:
writel(param1, &v5param->apicid); v5param->apicid = param1;
writel(SETWA_FLAGS_APICID, &v5param->flags); v5param->flags = SETWA_FLAGS_APICID;
break; break;
case ACPI_EINJ_MEMORY_CORRECTABLE: case ACPI_EINJ_MEMORY_CORRECTABLE:
case ACPI_EINJ_MEMORY_UNCORRECTABLE: case ACPI_EINJ_MEMORY_UNCORRECTABLE:
case ACPI_EINJ_MEMORY_FATAL: case ACPI_EINJ_MEMORY_FATAL:
writeq(param1, &v5param->memory_address); v5param->memory_address = param1;
writeq(param2, &v5param->memory_address_range); v5param->memory_address_range = param2;
writel(SETWA_FLAGS_MEM, &v5param->flags); v5param->flags = SETWA_FLAGS_MEM;
break; break;
case ACPI_EINJ_PCIX_CORRECTABLE: case ACPI_EINJ_PCIX_CORRECTABLE:
case ACPI_EINJ_PCIX_UNCORRECTABLE: case ACPI_EINJ_PCIX_UNCORRECTABLE:
case ACPI_EINJ_PCIX_FATAL: case ACPI_EINJ_PCIX_FATAL:
writel(param1, &v5param->pcie_sbdf); v5param->pcie_sbdf = param1;
writel(SETWA_FLAGS_PCIE_SBDF, &v5param->flags); v5param->flags = SETWA_FLAGS_PCIE_SBDF;
break; break;
} }
} }
...@@ -484,8 +468,8 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2) ...@@ -484,8 +468,8 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
return rc; return rc;
if (einj_param) { if (einj_param) {
struct einj_parameter *v4param = einj_param; struct einj_parameter *v4param = einj_param;
writeq(param1, &v4param->param1); v4param->param1 = param1;
writeq(param2, &v4param->param2); v4param->param2 = param2;
} }
} }
rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION); rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION);
...@@ -736,8 +720,13 @@ static int __init einj_init(void) ...@@ -736,8 +720,13 @@ static int __init einj_init(void)
return 0; return 0;
err_unmap: err_unmap:
if (einj_param) if (einj_param) {
iounmap(einj_param); acpi_size size = (acpi5) ?
sizeof(struct set_error_type_with_address) :
sizeof(struct einj_parameter);
acpi_os_unmap_memory(einj_param, size);
}
apei_exec_post_unmap_gars(&ctx); apei_exec_post_unmap_gars(&ctx);
err_release: err_release:
apei_resources_release(&einj_resources); apei_resources_release(&einj_resources);
...@@ -753,8 +742,13 @@ static void __exit einj_exit(void) ...@@ -753,8 +742,13 @@ static void __exit einj_exit(void)
{ {
struct apei_exec_context ctx; struct apei_exec_context ctx;
if (einj_param) if (einj_param) {
iounmap(einj_param); acpi_size size = (acpi5) ?
sizeof(struct set_error_type_with_address) :
sizeof(struct einj_parameter);
acpi_os_unmap_memory(einj_param, size);
}
einj_exec_ctx_init(&ctx); einj_exec_ctx_init(&ctx);
apei_exec_post_unmap_gars(&ctx); apei_exec_post_unmap_gars(&ctx);
apei_resources_release(&einj_resources); apei_resources_release(&einj_resources);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment