summaryrefslogtreecommitdiff
path: root/drivers/firmware
diff options
context:
space:
mode:
authorScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
committerScott Wood <scottwood@freescale.com>2014-04-07 23:49:35 (GMT)
commit62b8c978ee6b8d135d9e7953221de58000dba986 (patch)
tree683b04b2e627f6710c22c151b23c8cc9a165315e /drivers/firmware
parent78fd82238d0e5716578c326404184a27ba67fd6e (diff)
downloadlinux-fsl-qoriq-62b8c978ee6b8d135d9e7953221de58000dba986.tar.xz
Rewind v3.13-rc3+ (78fd82238d0e5716) to v3.12
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/dcdbas.c32
-rw-r--r--drivers/firmware/dmi_scan.c61
-rw-r--r--drivers/firmware/efi/Kconfig3
-rw-r--r--drivers/firmware/efi/Makefile1
-rw-r--r--drivers/firmware/efi/cper.c410
-rw-r--r--drivers/firmware/efi/efi-pstore.c163
-rw-r--r--drivers/firmware/efi/efi-stub-helper.c636
-rw-r--r--drivers/firmware/efi/efi.c140
-rw-r--r--drivers/firmware/efi/efivars.c14
-rw-r--r--drivers/firmware/efi/vars.c12
-rw-r--r--drivers/firmware/google/gsmi.c13
11 files changed, 41 insertions, 1444 deletions
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 1b5e8e4..ff080ee 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -545,15 +545,12 @@ static int dcdbas_probe(struct platform_device *dev)
host_control_action = HC_ACTION_NONE;
host_control_smi_type = HC_SMITYPE_NONE;
- dcdbas_pdev = dev;
-
/*
* BIOS SMI calls require buffer addresses be in 32-bit address space.
* This is done by setting the DMA mask below.
*/
- error = dma_set_coherent_mask(&dcdbas_pdev->dev, DMA_BIT_MASK(32));
- if (error)
- return error;
+ dcdbas_pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ dcdbas_pdev->dev.dma_mask = &dcdbas_pdev->dev.coherent_dma_mask;
error = sysfs_create_group(&dev->dev.kobj, &dcdbas_attr_group);
if (error)
@@ -584,14 +581,6 @@ static struct platform_driver dcdbas_driver = {
.remove = dcdbas_remove,
};
-static const struct platform_device_info dcdbas_dev_info __initdata = {
- .name = DRIVER_NAME,
- .id = -1,
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-static struct platform_device *dcdbas_pdev_reg;
-
/**
* dcdbas_init: initialize driver
*/
@@ -603,14 +592,20 @@ static int __init dcdbas_init(void)
if (error)
return error;
- dcdbas_pdev_reg = platform_device_register_full(&dcdbas_dev_info);
- if (IS_ERR(dcdbas_pdev_reg)) {
- error = PTR_ERR(dcdbas_pdev_reg);
+ dcdbas_pdev = platform_device_alloc(DRIVER_NAME, -1);
+ if (!dcdbas_pdev) {
+ error = -ENOMEM;
goto err_unregister_driver;
}
+ error = platform_device_add(dcdbas_pdev);
+ if (error)
+ goto err_free_device;
+
return 0;
+ err_free_device:
+ platform_device_put(dcdbas_pdev);
err_unregister_driver:
platform_driver_unregister(&dcdbas_driver);
return error;
@@ -633,9 +628,8 @@ static void __exit dcdbas_exit(void)
* all sysfs attributes belonging to this module have been
* released.
*/
- if (dcdbas_pdev)
- smi_data_buf_free();
- platform_device_unregister(dcdbas_pdev_reg);
+ smi_data_buf_free();
+ platform_device_unregister(dcdbas_pdev);
platform_driver_unregister(&dcdbas_driver);
}
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index c7e81ff..fa0affb 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -8,7 +8,6 @@
#include <linux/bootmem.h>
#include <linux/random.h>
#include <asm/dmi.h>
-#include <asm/unaligned.h>
/*
* DMI stands for "Desktop Management Interface". It is part
@@ -26,13 +25,6 @@ static int dmi_initialized;
/* DMI system identification string used during boot */
static char dmi_ids_string[128] __initdata;
-static struct dmi_memdev_info {
- const char *device;
- const char *bank;
- u16 handle;
-} *dmi_memdev;
-static int dmi_memdev_nr;
-
static const char * __init dmi_string_nosave(const struct dmi_header *dm, u8 s)
{
const u8 *bp = ((u8 *) dm) + dm->length;
@@ -330,42 +322,6 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
dmi_save_one_device(*d & 0x7f, dmi_string_nosave(dm, *(d - 1)));
}
-static void __init count_mem_devices(const struct dmi_header *dm, void *v)
-{
- if (dm->type != DMI_ENTRY_MEM_DEVICE)
- return;
- dmi_memdev_nr++;
-}
-
-static void __init save_mem_devices(const struct dmi_header *dm, void *v)
-{
- const char *d = (const char *)dm;
- static int nr;
-
- if (dm->type != DMI_ENTRY_MEM_DEVICE)
- return;
- if (nr >= dmi_memdev_nr) {
- pr_warn(FW_BUG "Too many DIMM entries in SMBIOS table\n");
- return;
- }
- dmi_memdev[nr].handle = get_unaligned(&dm->handle);
- dmi_memdev[nr].device = dmi_string(dm, d[0x10]);
- dmi_memdev[nr].bank = dmi_string(dm, d[0x11]);
- nr++;
-}
-
-void __init dmi_memdev_walk(void)
-{
- if (!dmi_available)
- return;
-
- if (dmi_walk_early(count_mem_devices) == 0 && dmi_memdev_nr) {
- dmi_memdev = dmi_alloc(sizeof(*dmi_memdev) * dmi_memdev_nr);
- if (dmi_memdev)
- dmi_walk_early(save_mem_devices);
- }
-}
-
/*
* Process a DMI table entry. Right now all we care about are the BIOS
* and machine entries. For 2.5 we should pull the smbus controller info
@@ -859,20 +815,3 @@ bool dmi_match(enum dmi_field f, const char *str)
return !strcmp(info, str);
}
EXPORT_SYMBOL_GPL(dmi_match);
-
-void dmi_memdev_name(u16 handle, const char **bank, const char **device)
-{
- int n;
-
- if (dmi_memdev == NULL)
- return;
-
- for (n = 0; n < dmi_memdev_nr; n++) {
- if (handle == dmi_memdev[n].handle) {
- *bank = dmi_memdev[n].bank;
- *device = dmi_memdev[n].device;
- break;
- }
- }
-}
-EXPORT_SYMBOL_GPL(dmi_memdev_name);
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 3150aa4..b0fc7c7 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -36,7 +36,4 @@ config EFI_VARS_PSTORE_DEFAULT_DISABLE
backend for pstore by default. This setting can be overridden
using the efivars module's pstore_disable parameter.
-config UEFI_CPER
- def_bool n
-
endmenu
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
index 9ba156d..99245ab 100644
--- a/drivers/firmware/efi/Makefile
+++ b/drivers/firmware/efi/Makefile
@@ -4,4 +4,3 @@
obj-y += efi.o vars.o
obj-$(CONFIG_EFI_VARS) += efivars.o
obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o
-obj-$(CONFIG_UEFI_CPER) += cper.o
diff --git a/drivers/firmware/efi/cper.c b/drivers/firmware/efi/cper.c
deleted file mode 100644
index 1491dd4..0000000
--- a/drivers/firmware/efi/cper.c
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * UEFI Common Platform Error Record (CPER) support
- *
- * Copyright (C) 2010, Intel Corp.
- * Author: Huang Ying <ying.huang@intel.com>
- *
- * CPER is the format used to describe platform hardware error by
- * various tables, such as ERST, BERT and HEST etc.
- *
- * For more information about CPER, please refer to Appendix N of UEFI
- * Specification version 2.4.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License version
- * 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/time.h>
-#include <linux/cper.h>
-#include <linux/dmi.h>
-#include <linux/acpi.h>
-#include <linux/pci.h>
-#include <linux/aer.h>
-
-#define INDENT_SP " "
-/*
- * CPER record ID need to be unique even after reboot, because record
- * ID is used as index for ERST storage, while CPER records from
- * multiple boot may co-exist in ERST.
- */
-u64 cper_next_record_id(void)
-{
- static atomic64_t seq;
-
- if (!atomic64_read(&seq))
- atomic64_set(&seq, ((u64)get_seconds()) << 32);
-
- return atomic64_inc_return(&seq);
-}
-EXPORT_SYMBOL_GPL(cper_next_record_id);
-
-static const char *cper_severity_strs[] = {
- "recoverable",
- "fatal",
- "corrected",
- "info",
-};
-
-static const char *cper_severity_str(unsigned int severity)
-{
- return severity < ARRAY_SIZE(cper_severity_strs) ?
- cper_severity_strs[severity] : "unknown";
-}
-
-/*
- * cper_print_bits - print strings for set bits
- * @pfx: prefix for each line, including log level and prefix string
- * @bits: bit mask
- * @strs: string array, indexed by bit position
- * @strs_size: size of the string array: @strs
- *
- * For each set bit in @bits, print the corresponding string in @strs.
- * If the output length is longer than 80, multiple line will be
- * printed, with @pfx is printed at the beginning of each line.
- */
-void cper_print_bits(const char *pfx, unsigned int bits,
- const char * const strs[], unsigned int strs_size)
-{
- int i, len = 0;
- const char *str;
- char buf[84];
-
- for (i = 0; i < strs_size; i++) {
- if (!(bits & (1U << i)))
- continue;
- str = strs[i];
- if (!str)
- continue;
- if (len && len + strlen(str) + 2 > 80) {
- printk("%s\n", buf);
- len = 0;
- }
- if (!len)
- len = snprintf(buf, sizeof(buf), "%s%s", pfx, str);
- else
- len += snprintf(buf+len, sizeof(buf)-len, ", %s", str);
- }
- if (len)
- printk("%s\n", buf);
-}
-
-static const char * const cper_proc_type_strs[] = {
- "IA32/X64",
- "IA64",
-};
-
-static const char * const cper_proc_isa_strs[] = {
- "IA32",
- "IA64",
- "X64",
-};
-
-static const char * const cper_proc_error_type_strs[] = {
- "cache error",
- "TLB error",
- "bus error",
- "micro-architectural error",
-};
-
-static const char * const cper_proc_op_strs[] = {
- "unknown or generic",
- "data read",
- "data write",
- "instruction execution",
-};
-
-static const char * const cper_proc_flag_strs[] = {
- "restartable",
- "precise IP",
- "overflow",
- "corrected",
-};
-
-static void cper_print_proc_generic(const char *pfx,
- const struct cper_sec_proc_generic *proc)
-{
- if (proc->validation_bits & CPER_PROC_VALID_TYPE)
- printk("%s""processor_type: %d, %s\n", pfx, proc->proc_type,
- proc->proc_type < ARRAY_SIZE(cper_proc_type_strs) ?
- cper_proc_type_strs[proc->proc_type] : "unknown");
- if (proc->validation_bits & CPER_PROC_VALID_ISA)
- printk("%s""processor_isa: %d, %s\n", pfx, proc->proc_isa,
- proc->proc_isa < ARRAY_SIZE(cper_proc_isa_strs) ?
- cper_proc_isa_strs[proc->proc_isa] : "unknown");
- if (proc->validation_bits & CPER_PROC_VALID_ERROR_TYPE) {
- printk("%s""error_type: 0x%02x\n", pfx, proc->proc_error_type);
- cper_print_bits(pfx, proc->proc_error_type,
- cper_proc_error_type_strs,
- ARRAY_SIZE(cper_proc_error_type_strs));
- }
- if (proc->validation_bits & CPER_PROC_VALID_OPERATION)
- printk("%s""operation: %d, %s\n", pfx, proc->operation,
- proc->operation < ARRAY_SIZE(cper_proc_op_strs) ?
- cper_proc_op_strs[proc->operation] : "unknown");
- if (proc->validation_bits & CPER_PROC_VALID_FLAGS) {
- printk("%s""flags: 0x%02x\n", pfx, proc->flags);
- cper_print_bits(pfx, proc->flags, cper_proc_flag_strs,
- ARRAY_SIZE(cper_proc_flag_strs));
- }
- if (proc->validation_bits & CPER_PROC_VALID_LEVEL)
- printk("%s""level: %d\n", pfx, proc->level);
- if (proc->validation_bits & CPER_PROC_VALID_VERSION)
- printk("%s""version_info: 0x%016llx\n", pfx, proc->cpu_version);
- if (proc->validation_bits & CPER_PROC_VALID_ID)
- printk("%s""processor_id: 0x%016llx\n", pfx, proc->proc_id);
- if (proc->validation_bits & CPER_PROC_VALID_TARGET_ADDRESS)
- printk("%s""target_address: 0x%016llx\n",
- pfx, proc->target_addr);
- if (proc->validation_bits & CPER_PROC_VALID_REQUESTOR_ID)
- printk("%s""requestor_id: 0x%016llx\n",
- pfx, proc->requestor_id);
- if (proc->validation_bits & CPER_PROC_VALID_RESPONDER_ID)
- printk("%s""responder_id: 0x%016llx\n",
- pfx, proc->responder_id);
- if (proc->validation_bits & CPER_PROC_VALID_IP)
- printk("%s""IP: 0x%016llx\n", pfx, proc->ip);
-}
-
-static const char *cper_mem_err_type_strs[] = {
- "unknown",
- "no error",
- "single-bit ECC",
- "multi-bit ECC",
- "single-symbol chipkill ECC",
- "multi-symbol chipkill ECC",
- "master abort",
- "target abort",
- "parity error",
- "watchdog timeout",
- "invalid address",
- "mirror Broken",
- "memory sparing",
- "scrub corrected error",
- "scrub uncorrected error",
- "physical memory map-out event",
-};
-
-static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem)
-{
- if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS)
- printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status);
- if (mem->validation_bits & CPER_MEM_VALID_PA)
- printk("%s""physical_address: 0x%016llx\n",
- pfx, mem->physical_addr);
- if (mem->validation_bits & CPER_MEM_VALID_PA_MASK)
- printk("%s""physical_address_mask: 0x%016llx\n",
- pfx, mem->physical_addr_mask);
- if (mem->validation_bits & CPER_MEM_VALID_NODE)
- pr_debug("node: %d\n", mem->node);
- if (mem->validation_bits & CPER_MEM_VALID_CARD)
- pr_debug("card: %d\n", mem->card);
- if (mem->validation_bits & CPER_MEM_VALID_MODULE)
- pr_debug("module: %d\n", mem->module);
- if (mem->validation_bits & CPER_MEM_VALID_RANK_NUMBER)
- pr_debug("rank: %d\n", mem->rank);
- if (mem->validation_bits & CPER_MEM_VALID_BANK)
- pr_debug("bank: %d\n", mem->bank);
- if (mem->validation_bits & CPER_MEM_VALID_DEVICE)
- pr_debug("device: %d\n", mem->device);
- if (mem->validation_bits & CPER_MEM_VALID_ROW)
- pr_debug("row: %d\n", mem->row);
- if (mem->validation_bits & CPER_MEM_VALID_COLUMN)
- pr_debug("column: %d\n", mem->column);
- if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION)
- pr_debug("bit_position: %d\n", mem->bit_pos);
- if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID)
- pr_debug("requestor_id: 0x%016llx\n", mem->requestor_id);
- if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID)
- pr_debug("responder_id: 0x%016llx\n", mem->responder_id);
- if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID)
- pr_debug("target_id: 0x%016llx\n", mem->target_id);
- if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) {
- u8 etype = mem->error_type;
- printk("%s""error_type: %d, %s\n", pfx, etype,
- etype < ARRAY_SIZE(cper_mem_err_type_strs) ?
- cper_mem_err_type_strs[etype] : "unknown");
- }
- if (mem->validation_bits & CPER_MEM_VALID_MODULE_HANDLE) {
- const char *bank = NULL, *device = NULL;
- dmi_memdev_name(mem->mem_dev_handle, &bank, &device);
- if (bank != NULL && device != NULL)
- printk("%s""DIMM location: %s %s", pfx, bank, device);
- else
- printk("%s""DIMM DMI handle: 0x%.4x",
- pfx, mem->mem_dev_handle);
- }
-}
-
-static const char *cper_pcie_port_type_strs[] = {
- "PCIe end point",
- "legacy PCI end point",
- "unknown",
- "unknown",
- "root port",
- "upstream switch port",
- "downstream switch port",
- "PCIe to PCI/PCI-X bridge",
- "PCI/PCI-X to PCIe bridge",
- "root complex integrated endpoint device",
- "root complex event collector",
-};
-
-static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie,
- const struct acpi_generic_data *gdata)
-{
- if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE)
- printk("%s""port_type: %d, %s\n", pfx, pcie->port_type,
- pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ?
- cper_pcie_port_type_strs[pcie->port_type] : "unknown");
- if (pcie->validation_bits & CPER_PCIE_VALID_VERSION)
- printk("%s""version: %d.%d\n", pfx,
- pcie->version.major, pcie->version.minor);
- if (pcie->validation_bits & CPER_PCIE_VALID_COMMAND_STATUS)
- printk("%s""command: 0x%04x, status: 0x%04x\n", pfx,
- pcie->command, pcie->status);
- if (pcie->validation_bits & CPER_PCIE_VALID_DEVICE_ID) {
- const __u8 *p;
- printk("%s""device_id: %04x:%02x:%02x.%x\n", pfx,
- pcie->device_id.segment, pcie->device_id.bus,
- pcie->device_id.device, pcie->device_id.function);
- printk("%s""slot: %d\n", pfx,
- pcie->device_id.slot >> CPER_PCIE_SLOT_SHIFT);
- printk("%s""secondary_bus: 0x%02x\n", pfx,
- pcie->device_id.secondary_bus);
- printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx,
- pcie->device_id.vendor_id, pcie->device_id.device_id);
- p = pcie->device_id.class_code;
- printk("%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]);
- }
- if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER)
- printk("%s""serial number: 0x%04x, 0x%04x\n", pfx,
- pcie->serial_number.lower, pcie->serial_number.upper);
- if (pcie->validation_bits & CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS)
- printk(
- "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n",
- pfx, pcie->bridge.secondary_status, pcie->bridge.control);
-}
-
-static void cper_estatus_print_section(
- const char *pfx, const struct acpi_generic_data *gdata, int sec_no)
-{
- uuid_le *sec_type = (uuid_le *)gdata->section_type;
- __u16 severity;
- char newpfx[64];
-
- severity = gdata->error_severity;
- printk("%s""Error %d, type: %s\n", pfx, sec_no,
- cper_severity_str(severity));
- if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID)
- printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id);
- if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT)
- printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text);
-
- snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
- if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) {
- struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1);
- printk("%s""section_type: general processor error\n", newpfx);
- if (gdata->error_data_length >= sizeof(*proc_err))
- cper_print_proc_generic(newpfx, proc_err);
- else
- goto err_section_too_small;
- } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) {
- struct cper_sec_mem_err *mem_err = (void *)(gdata + 1);
- printk("%s""section_type: memory error\n", newpfx);
- if (gdata->error_data_length >= sizeof(*mem_err))
- cper_print_mem(newpfx, mem_err);
- else
- goto err_section_too_small;
- } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) {
- struct cper_sec_pcie *pcie = (void *)(gdata + 1);
- printk("%s""section_type: PCIe error\n", newpfx);
- if (gdata->error_data_length >= sizeof(*pcie))
- cper_print_pcie(newpfx, pcie, gdata);
- else
- goto err_section_too_small;
- } else
- printk("%s""section type: unknown, %pUl\n", newpfx, sec_type);
-
- return;
-
-err_section_too_small:
- pr_err(FW_WARN "error section length is too small\n");
-}
-
-void cper_estatus_print(const char *pfx,
- const struct acpi_generic_status *estatus)
-{
- struct acpi_generic_data *gdata;
- unsigned int data_len, gedata_len;
- int sec_no = 0;
- char newpfx[64];
- __u16 severity;
-
- severity = estatus->error_severity;
- if (severity == CPER_SEV_CORRECTED)
- printk("%s%s\n", pfx,
- "It has been corrected by h/w "
- "and requires no further action");
- printk("%s""event severity: %s\n", pfx, cper_severity_str(severity));
- data_len = estatus->data_length;
- gdata = (struct acpi_generic_data *)(estatus + 1);
- snprintf(newpfx, sizeof(newpfx), "%s%s", pfx, INDENT_SP);
- while (data_len >= sizeof(*gdata)) {
- gedata_len = gdata->error_data_length;
- cper_estatus_print_section(newpfx, gdata, sec_no);
- data_len -= gedata_len + sizeof(*gdata);
- gdata = (void *)(gdata + 1) + gedata_len;
- sec_no++;
- }
-}
-EXPORT_SYMBOL_GPL(cper_estatus_print);
-
-int cper_estatus_check_header(const struct acpi_generic_status *estatus)
-{
- if (estatus->data_length &&
- estatus->data_length < sizeof(struct acpi_generic_data))
- return -EINVAL;
- if (estatus->raw_data_length &&
- estatus->raw_data_offset < sizeof(*estatus) + estatus->data_length)
- return -EINVAL;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cper_estatus_check_header);
-
-int cper_estatus_check(const struct acpi_generic_status *estatus)
-{
- struct acpi_generic_data *gdata;
- unsigned int data_len, gedata_len;
- int rc;
-
- rc = cper_estatus_check_header(estatus);
- if (rc)
- return rc;
- data_len = estatus->data_length;
- gdata = (struct acpi_generic_data *)(estatus + 1);
- while (data_len >= sizeof(*gdata)) {
- gedata_len = gdata->error_data_length;
- if (gedata_len > data_len - sizeof(*gdata))
- return -EINVAL;
- data_len -= gedata_len + sizeof(*gdata);
- gdata = (void *)(gdata + 1) + gedata_len;
- }
- if (data_len)
- return -EINVAL;
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(cper_estatus_check);
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 743fd42..5002d50 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -18,12 +18,14 @@ module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
static int efi_pstore_open(struct pstore_info *psi)
{
+ efivar_entry_iter_begin();
psi->data = NULL;
return 0;
}
static int efi_pstore_close(struct pstore_info *psi)
{
+ efivar_entry_iter_end();
psi->data = NULL;
return 0;
}
@@ -37,12 +39,6 @@ struct pstore_read_data {
char **buf;
};
-static inline u64 generic_id(unsigned long timestamp,
- unsigned int part, int count)
-{
- return (timestamp * 100 + part) * 1000 + count;
-}
-
static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
{
efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
@@ -61,7 +57,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
if (sscanf(name, "dump-type%u-%u-%d-%lu-%c",
cb_data->type, &part, &cnt, &time, &data_type) == 5) {
- *cb_data->id = generic_id(time, part, cnt);
+ *cb_data->id = part;
*cb_data->count = cnt;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
@@ -71,7 +67,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
*cb_data->compressed = false;
} else if (sscanf(name, "dump-type%u-%u-%d-%lu",
cb_data->type, &part, &cnt, &time) == 4) {
- *cb_data->id = generic_id(time, part, cnt);
+ *cb_data->id = part;
*cb_data->count = cnt;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
@@ -83,7 +79,7 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
* which doesn't support holding
* multiple logs, remains.
*/
- *cb_data->id = generic_id(time, part, 0);
+ *cb_data->id = part;
*cb_data->count = 0;
cb_data->timespec->tv_sec = time;
cb_data->timespec->tv_nsec = 0;
@@ -95,125 +91,19 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
__efivar_entry_get(entry, &entry->var.Attributes,
&entry->var.DataSize, entry->var.Data);
size = entry->var.DataSize;
- memcpy(*cb_data->buf, entry->var.Data,
- (size_t)min_t(unsigned long, EFIVARS_DATA_SIZE_MAX, size));
-
- return size;
-}
-
-/**
- * efi_pstore_scan_sysfs_enter
- * @entry: scanning entry
- * @next: next entry
- * @head: list head
- */
-static void efi_pstore_scan_sysfs_enter(struct efivar_entry *pos,
- struct efivar_entry *next,
- struct list_head *head)
-{
- pos->scanning = true;
- if (&next->list != head)
- next->scanning = true;
-}
-
-/**
- * __efi_pstore_scan_sysfs_exit
- * @entry: deleting entry
- * @turn_off_scanning: Check if a scanning flag should be turned off
- */
-static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,
- bool turn_off_scanning)
-{
- if (entry->deleting) {
- list_del(&entry->list);
- efivar_entry_iter_end();
- efivar_unregister(entry);
- efivar_entry_iter_begin();
- } else if (turn_off_scanning)
- entry->scanning = false;
-}
-
-/**
- * efi_pstore_scan_sysfs_exit
- * @pos: scanning entry
- * @next: next entry
- * @head: list head
- * @stop: a flag checking if scanning will stop
- */
-static void efi_pstore_scan_sysfs_exit(struct efivar_entry *pos,
- struct efivar_entry *next,
- struct list_head *head, bool stop)
-{
- __efi_pstore_scan_sysfs_exit(pos, true);
- if (stop)
- __efi_pstore_scan_sysfs_exit(next, &next->list != head);
-}
-/**
- * efi_pstore_sysfs_entry_iter
- *
- * @data: function-specific data to pass to callback
- * @pos: entry to begin iterating from
- *
- * You MUST call efivar_enter_iter_begin() before this function, and
- * efivar_entry_iter_end() afterwards.
- *
- * It is possible to begin iteration from an arbitrary entry within
- * the list by passing @pos. @pos is updated on return to point to
- * the next entry of the last one passed to efi_pstore_read_func().
- * To begin iterating from the beginning of the list @pos must be %NULL.
- */
-static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos)
-{
- struct efivar_entry *entry, *n;
- struct list_head *head = &efivar_sysfs_list;
- int size = 0;
-
- if (!*pos) {
- list_for_each_entry_safe(entry, n, head, list) {
- efi_pstore_scan_sysfs_enter(entry, n, head);
-
- size = efi_pstore_read_func(entry, data);
- efi_pstore_scan_sysfs_exit(entry, n, head, size < 0);
- if (size)
- break;
- }
- *pos = n;
- return size;
- }
-
- list_for_each_entry_safe_from((*pos), n, head, list) {
- efi_pstore_scan_sysfs_enter((*pos), n, head);
-
- size = efi_pstore_read_func((*pos), data);
- efi_pstore_scan_sysfs_exit((*pos), n, head, size < 0);
- if (size)
- break;
- }
- *pos = n;
+ *cb_data->buf = kmemdup(entry->var.Data, size, GFP_KERNEL);
+ if (*cb_data->buf == NULL)
+ return -ENOMEM;
return size;
}
-/**
- * efi_pstore_read
- *
- * This function returns a size of NVRAM entry logged via efi_pstore_write().
- * The meaning and behavior of efi_pstore/pstore are as below.
- *
- * size > 0: Got data of an entry logged via efi_pstore_write() successfully,
- * and pstore filesystem will continue reading subsequent entries.
- * size == 0: Entry was not logged via efi_pstore_write(),
- * and efi_pstore driver will continue reading subsequent entries.
- * size < 0: Failed to get data of entry logging via efi_pstore_write(),
- * and pstore will stop reading entry.
- */
static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
int *count, struct timespec *timespec,
char **buf, bool *compressed,
struct pstore_info *psi)
{
struct pstore_read_data data;
- ssize_t size;
data.id = id;
data.type = type;
@@ -222,17 +112,8 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
data.compressed = compressed;
data.buf = buf;
- *data.buf = kzalloc(EFIVARS_DATA_SIZE_MAX, GFP_KERNEL);
- if (!*data.buf)
- return -ENOMEM;
-
- efivar_entry_iter_begin();
- size = efi_pstore_sysfs_entry_iter(&data,
- (struct efivar_entry **)&psi->data);
- efivar_entry_iter_end();
- if (size <= 0)
- kfree(*data.buf);
- return size;
+ return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data,
+ (struct efivar_entry **)&psi->data);
}
static int efi_pstore_write(enum pstore_type_id type,
@@ -303,17 +184,9 @@ static int efi_pstore_erase_func(struct efivar_entry *entry, void *data)
return 0;
}
- if (entry->scanning) {
- /*
- * Skip deletion because this entry will be deleted
- * after scanning is completed.
- */
- entry->deleting = true;
- } else
- list_del(&entry->list);
-
/* found */
__efivar_entry_delete(entry);
+ list_del(&entry->list);
return 1;
}
@@ -326,16 +199,14 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
char name[DUMP_NAME_LEN];
efi_char16_t efi_name[DUMP_NAME_LEN];
int found, i;
- unsigned int part;
- do_div(id, 1000);
- part = do_div(id, 100);
- sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count, time.tv_sec);
+ sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count,
+ time.tv_sec);
for (i = 0; i < DUMP_NAME_LEN; i++)
efi_name[i] = name[i];
- edata.id = part;
+ edata.id = id;
edata.type = type;
edata.count = count;
edata.time = time;
@@ -343,12 +214,10 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
efivar_entry_iter_begin();
found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
+ efivar_entry_iter_end();
- if (found && !entry->scanning) {
- efivar_entry_iter_end();
+ if (found)
efivar_unregister(entry);
- } else
- efivar_entry_iter_end();
return 0;
}
diff --git a/drivers/firmware/efi/efi-stub-helper.c b/drivers/firmware/efi/efi-stub-helper.c
deleted file mode 100644
index b6bffbf..0000000
--- a/drivers/firmware/efi/efi-stub-helper.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Helper functions used by the EFI stub on multiple
- * architectures. This should be #included by the EFI stub
- * implementation files.
- *
- * Copyright 2011 Intel Corporation; author Matt Fleming
- *
- * This file is part of the Linux kernel, and is made available
- * under the terms of the GNU General Public License version 2.
- *
- */
-#define EFI_READ_CHUNK_SIZE (1024 * 1024)
-
-struct file_info {
- efi_file_handle_t *handle;
- u64 size;
-};
-
-
-
-
-static void efi_char16_printk(efi_system_table_t *sys_table_arg,
- efi_char16_t *str)
-{
- struct efi_simple_text_output_protocol *out;
-
- out = (struct efi_simple_text_output_protocol *)sys_table_arg->con_out;
- efi_call_phys2(out->output_string, out, str);
-}
-
-static void efi_printk(efi_system_table_t *sys_table_arg, char *str)
-{
- char *s8;
-
- for (s8 = str; *s8; s8++) {
- efi_char16_t ch[2] = { 0 };
-
- ch[0] = *s8;
- if (*s8 == '\n') {
- efi_char16_t nl[2] = { '\r', 0 };
- efi_char16_printk(sys_table_arg, nl);
- }
-
- efi_char16_printk(sys_table_arg, ch);
- }
-}
-
-
-static efi_status_t efi_get_memory_map(efi_system_table_t *sys_table_arg,
- efi_memory_desc_t **map,
- unsigned long *map_size,
- unsigned long *desc_size,
- u32 *desc_ver,
- unsigned long *key_ptr)
-{
- efi_memory_desc_t *m = NULL;
- efi_status_t status;
- unsigned long key;
- u32 desc_version;
-
- *map_size = sizeof(*m) * 32;
-again:
- /*
- * Add an additional efi_memory_desc_t because we're doing an
- * allocation which may be in a new descriptor region.
- */
- *map_size += sizeof(*m);
- status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
- EFI_LOADER_DATA, *map_size, (void **)&m);
- if (status != EFI_SUCCESS)
- goto fail;
-
- status = efi_call_phys5(sys_table_arg->boottime->get_memory_map,
- map_size, m, &key, desc_size, &desc_version);
- if (status == EFI_BUFFER_TOO_SMALL) {
- efi_call_phys1(sys_table_arg->boottime->free_pool, m);
- goto again;
- }
-
- if (status != EFI_SUCCESS)
- efi_call_phys1(sys_table_arg->boottime->free_pool, m);
- if (key_ptr && status == EFI_SUCCESS)
- *key_ptr = key;
- if (desc_ver && status == EFI_SUCCESS)
- *desc_ver = desc_version;
-
-fail:
- *map = m;
- return status;
-}
-
-/*
- * Allocate at the highest possible address that is not above 'max'.
- */
-static efi_status_t efi_high_alloc(efi_system_table_t *sys_table_arg,
- unsigned long size, unsigned long align,
- unsigned long *addr, unsigned long max)
-{
- unsigned long map_size, desc_size;
- efi_memory_desc_t *map;
- efi_status_t status;
- unsigned long nr_pages;
- u64 max_addr = 0;
- int i;
-
- status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size,
- NULL, NULL);
- if (status != EFI_SUCCESS)
- goto fail;
-
- /*
- * Enforce minimum alignment that EFI requires when requesting
- * a specific address. We are doing page-based allocations,
- * so we must be aligned to a page.
- */
- if (align < EFI_PAGE_SIZE)
- align = EFI_PAGE_SIZE;
-
- nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
-again:
- for (i = 0; i < map_size / desc_size; i++) {
- efi_memory_desc_t *desc;
- unsigned long m = (unsigned long)map;
- u64 start, end;
-
- desc = (efi_memory_desc_t *)(m + (i * desc_size));
- if (desc->type != EFI_CONVENTIONAL_MEMORY)
- continue;
-
- if (desc->num_pages < nr_pages)
- continue;
-
- start = desc->phys_addr;
- end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
-
- if ((start + size) > end || (start + size) > max)
- continue;
-
- if (end - size > max)
- end = max;
-
- if (round_down(end - size, align) < start)
- continue;
-
- start = round_down(end - size, align);
-
- /*
- * Don't allocate at 0x0. It will confuse code that
- * checks pointers against NULL.
- */
- if (start == 0x0)
- continue;
-
- if (start > max_addr)
- max_addr = start;
- }
-
- if (!max_addr)
- status = EFI_NOT_FOUND;
- else {
- status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &max_addr);
- if (status != EFI_SUCCESS) {
- max = max_addr;
- max_addr = 0;
- goto again;
- }
-
- *addr = max_addr;
- }
-
- efi_call_phys1(sys_table_arg->boottime->free_pool, map);
-
-fail:
- return status;
-}
-
-/*
- * Allocate at the lowest possible address.
- */
-static efi_status_t efi_low_alloc(efi_system_table_t *sys_table_arg,
- unsigned long size, unsigned long align,
- unsigned long *addr)
-{
- unsigned long map_size, desc_size;
- efi_memory_desc_t *map;
- efi_status_t status;
- unsigned long nr_pages;
- int i;
-
- status = efi_get_memory_map(sys_table_arg, &map, &map_size, &desc_size,
- NULL, NULL);
- if (status != EFI_SUCCESS)
- goto fail;
-
- /*
- * Enforce minimum alignment that EFI requires when requesting
- * a specific address. We are doing page-based allocations,
- * so we must be aligned to a page.
- */
- if (align < EFI_PAGE_SIZE)
- align = EFI_PAGE_SIZE;
-
- nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- for (i = 0; i < map_size / desc_size; i++) {
- efi_memory_desc_t *desc;
- unsigned long m = (unsigned long)map;
- u64 start, end;
-
- desc = (efi_memory_desc_t *)(m + (i * desc_size));
-
- if (desc->type != EFI_CONVENTIONAL_MEMORY)
- continue;
-
- if (desc->num_pages < nr_pages)
- continue;
-
- start = desc->phys_addr;
- end = start + desc->num_pages * (1UL << EFI_PAGE_SHIFT);
-
- /*
- * Don't allocate at 0x0. It will confuse code that
- * checks pointers against NULL. Skip the first 8
- * bytes so we start at a nice even number.
- */
- if (start == 0x0)
- start += 8;
-
- start = round_up(start, align);
- if ((start + size) > end)
- continue;
-
- status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &start);
- if (status == EFI_SUCCESS) {
- *addr = start;
- break;
- }
- }
-
- if (i == map_size / desc_size)
- status = EFI_NOT_FOUND;
-
- efi_call_phys1(sys_table_arg->boottime->free_pool, map);
-fail:
- return status;
-}
-
-static void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
- unsigned long addr)
-{
- unsigned long nr_pages;
-
- if (!size)
- return;
-
- nr_pages = round_up(size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- efi_call_phys2(sys_table_arg->boottime->free_pages, addr, nr_pages);
-}
-
-
-/*
- * Check the cmdline for a LILO-style file= arguments.
- *
- * We only support loading a file from the same filesystem as
- * the kernel image.
- */
-static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
- efi_loaded_image_t *image,
- char *cmd_line, char *option_string,
- unsigned long max_addr,
- unsigned long *load_addr,
- unsigned long *load_size)
-{
- struct file_info *files;
- unsigned long file_addr;
- efi_guid_t fs_proto = EFI_FILE_SYSTEM_GUID;
- u64 file_size_total;
- efi_file_io_interface_t *io;
- efi_file_handle_t *fh;
- efi_status_t status;
- int nr_files;
- char *str;
- int i, j, k;
-
- file_addr = 0;
- file_size_total = 0;
-
- str = cmd_line;
-
- j = 0; /* See close_handles */
-
- if (!load_addr || !load_size)
- return EFI_INVALID_PARAMETER;
-
- *load_addr = 0;
- *load_size = 0;
-
- if (!str || !*str)
- return EFI_SUCCESS;
-
- for (nr_files = 0; *str; nr_files++) {
- str = strstr(str, option_string);
- if (!str)
- break;
-
- str += strlen(option_string);
-
- /* Skip any leading slashes */
- while (*str == '/' || *str == '\\')
- str++;
-
- while (*str && *str != ' ' && *str != '\n')
- str++;
- }
-
- if (!nr_files)
- return EFI_SUCCESS;
-
- status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
- EFI_LOADER_DATA,
- nr_files * sizeof(*files),
- (void **)&files);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to alloc mem for file handle list\n");
- goto fail;
- }
-
- str = cmd_line;
- for (i = 0; i < nr_files; i++) {
- struct file_info *file;
- efi_file_handle_t *h;
- efi_file_info_t *info;
- efi_char16_t filename_16[256];
- unsigned long info_sz;
- efi_guid_t info_guid = EFI_FILE_INFO_ID;
- efi_char16_t *p;
- u64 file_sz;
-
- str = strstr(str, option_string);
- if (!str)
- break;
-
- str += strlen(option_string);
-
- file = &files[i];
- p = filename_16;
-
- /* Skip any leading slashes */
- while (*str == '/' || *str == '\\')
- str++;
-
- while (*str && *str != ' ' && *str != '\n') {
- if ((u8 *)p >= (u8 *)filename_16 + sizeof(filename_16))
- break;
-
- if (*str == '/') {
- *p++ = '\\';
- str++;
- } else {
- *p++ = *str++;
- }
- }
-
- *p = '\0';
-
- /* Only open the volume once. */
- if (!i) {
- efi_boot_services_t *boottime;
-
- boottime = sys_table_arg->boottime;
-
- status = efi_call_phys3(boottime->handle_protocol,
- image->device_handle, &fs_proto,
- (void **)&io);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to handle fs_proto\n");
- goto free_files;
- }
-
- status = efi_call_phys2(io->open_volume, io, &fh);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to open volume\n");
- goto free_files;
- }
- }
-
- status = efi_call_phys5(fh->open, fh, &h, filename_16,
- EFI_FILE_MODE_READ, (u64)0);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to open file: ");
- efi_char16_printk(sys_table_arg, filename_16);
- efi_printk(sys_table_arg, "\n");
- goto close_handles;
- }
-
- file->handle = h;
-
- info_sz = 0;
- status = efi_call_phys4(h->get_info, h, &info_guid,
- &info_sz, NULL);
- if (status != EFI_BUFFER_TOO_SMALL) {
- efi_printk(sys_table_arg, "Failed to get file info size\n");
- goto close_handles;
- }
-
-grow:
- status = efi_call_phys3(sys_table_arg->boottime->allocate_pool,
- EFI_LOADER_DATA, info_sz,
- (void **)&info);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to alloc mem for file info\n");
- goto close_handles;
- }
-
- status = efi_call_phys4(h->get_info, h, &info_guid,
- &info_sz, info);
- if (status == EFI_BUFFER_TOO_SMALL) {
- efi_call_phys1(sys_table_arg->boottime->free_pool,
- info);
- goto grow;
- }
-
- file_sz = info->file_size;
- efi_call_phys1(sys_table_arg->boottime->free_pool, info);
-
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to get file info\n");
- goto close_handles;
- }
-
- file->size = file_sz;
- file_size_total += file_sz;
- }
-
- if (file_size_total) {
- unsigned long addr;
-
- /*
- * Multiple files need to be at consecutive addresses in memory,
- * so allocate enough memory for all the files. This is used
- * for loading multiple files.
- */
- status = efi_high_alloc(sys_table_arg, file_size_total, 0x1000,
- &file_addr, max_addr);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to alloc highmem for files\n");
- goto close_handles;
- }
-
- /* We've run out of free low memory. */
- if (file_addr > max_addr) {
- efi_printk(sys_table_arg, "We've run out of free low memory\n");
- status = EFI_INVALID_PARAMETER;
- goto free_file_total;
- }
-
- addr = file_addr;
- for (j = 0; j < nr_files; j++) {
- unsigned long size;
-
- size = files[j].size;
- while (size) {
- unsigned long chunksize;
- if (size > EFI_READ_CHUNK_SIZE)
- chunksize = EFI_READ_CHUNK_SIZE;
- else
- chunksize = size;
- status = efi_call_phys3(fh->read,
- files[j].handle,
- &chunksize,
- (void *)addr);
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "Failed to read file\n");
- goto free_file_total;
- }
- addr += chunksize;
- size -= chunksize;
- }
-
- efi_call_phys1(fh->close, files[j].handle);
- }
-
- }
-
- efi_call_phys1(sys_table_arg->boottime->free_pool, files);
-
- *load_addr = file_addr;
- *load_size = file_size_total;
-
- return status;
-
-free_file_total:
- efi_free(sys_table_arg, file_size_total, file_addr);
-
-close_handles:
- for (k = j; k < i; k++)
- efi_call_phys1(fh->close, files[k].handle);
-free_files:
- efi_call_phys1(sys_table_arg->boottime->free_pool, files);
-fail:
- *load_addr = 0;
- *load_size = 0;
-
- return status;
-}
-/*
- * Relocate a kernel image, either compressed or uncompressed.
- * In the ARM64 case, all kernel images are currently
- * uncompressed, and as such when we relocate it we need to
- * allocate additional space for the BSS segment. Any low
- * memory that this function should avoid needs to be
- * unavailable in the EFI memory map, as if the preferred
- * address is not available the lowest available address will
- * be used.
- */
-static efi_status_t efi_relocate_kernel(efi_system_table_t *sys_table_arg,
- unsigned long *image_addr,
- unsigned long image_size,
- unsigned long alloc_size,
- unsigned long preferred_addr,
- unsigned long alignment)
-{
- unsigned long cur_image_addr;
- unsigned long new_addr = 0;
- efi_status_t status;
- unsigned long nr_pages;
- efi_physical_addr_t efi_addr = preferred_addr;
-
- if (!image_addr || !image_size || !alloc_size)
- return EFI_INVALID_PARAMETER;
- if (alloc_size < image_size)
- return EFI_INVALID_PARAMETER;
-
- cur_image_addr = *image_addr;
-
- /*
- * The EFI firmware loader could have placed the kernel image
- * anywhere in memory, but the kernel has restrictions on the
- * max physical address it can run at. Some architectures
- * also have a prefered address, so first try to relocate
- * to the preferred address. If that fails, allocate as low
- * as possible while respecting the required alignment.
- */
- nr_pages = round_up(alloc_size, EFI_PAGE_SIZE) / EFI_PAGE_SIZE;
- status = efi_call_phys4(sys_table_arg->boottime->allocate_pages,
- EFI_ALLOCATE_ADDRESS, EFI_LOADER_DATA,
- nr_pages, &efi_addr);
- new_addr = efi_addr;
- /*
- * If preferred address allocation failed allocate as low as
- * possible.
- */
- if (status != EFI_SUCCESS) {
- status = efi_low_alloc(sys_table_arg, alloc_size, alignment,
- &new_addr);
- }
- if (status != EFI_SUCCESS) {
- efi_printk(sys_table_arg, "ERROR: Failed to allocate usable memory for kernel.\n");
- return status;
- }
-
- /*
- * We know source/dest won't overlap since both memory ranges
- * have been allocated by UEFI, so we can safely use memcpy.
- */
- memcpy((void *)new_addr, (void *)cur_image_addr, image_size);
-
- /* Return the new address of the relocated image. */
- *image_addr = new_addr;
-
- return status;
-}
-
-/*
- * Convert the unicode UEFI command line to ASCII to pass to kernel.
- * Size of memory allocated return in *cmd_line_len.
- * Returns NULL on error.
- */
-static char *efi_convert_cmdline_to_ascii(efi_system_table_t *sys_table_arg,
- efi_loaded_image_t *image,
- int *cmd_line_len)
-{
- u16 *s2;
- u8 *s1 = NULL;
- unsigned long cmdline_addr = 0;
- int load_options_size = image->load_options_size / 2; /* ASCII */
- void *options = image->load_options;
- int options_size = 0;
- efi_status_t status;
- int i;
- u16 zero = 0;
-
- if (options) {
- s2 = options;
- while (*s2 && *s2 != '\n' && options_size < load_options_size) {
- s2++;
- options_size++;
- }
- }
-
- if (options_size == 0) {
- /* No command line options, so return empty string*/
- options_size = 1;
- options = &zero;
- }
-
- options_size++; /* NUL termination */
-#ifdef CONFIG_ARM
- /*
- * For ARM, allocate at a high address to avoid reserved
- * regions at low addresses that we don't know the specfics of
- * at the time we are processing the command line.
- */
- status = efi_high_alloc(sys_table_arg, options_size, 0,
- &cmdline_addr, 0xfffff000);
-#else
- status = efi_low_alloc(sys_table_arg, options_size, 0,
- &cmdline_addr);
-#endif
- if (status != EFI_SUCCESS)
- return NULL;
-
- s1 = (u8 *)cmdline_addr;
- s2 = (u16 *)options;
-
- for (i = 0; i < options_size - 1; i++)
- *s1++ = *s2++;
-
- *s1 = '\0';
-
- *cmd_line_len = options_size;
- return (char *)cmdline_addr;
-}
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 2e2fbde..5145fa3 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -13,27 +13,11 @@
* This file is released under the GPLv2.
*/
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
#include <linux/kobject.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/efi.h>
-#include <linux/io.h>
-
-struct efi __read_mostly efi = {
- .mps = EFI_INVALID_TABLE_ADDR,
- .acpi = EFI_INVALID_TABLE_ADDR,
- .acpi20 = EFI_INVALID_TABLE_ADDR,
- .smbios = EFI_INVALID_TABLE_ADDR,
- .sal_systab = EFI_INVALID_TABLE_ADDR,
- .boot_info = EFI_INVALID_TABLE_ADDR,
- .hcdp = EFI_INVALID_TABLE_ADDR,
- .uga = EFI_INVALID_TABLE_ADDR,
- .uv_systab = EFI_INVALID_TABLE_ADDR,
-};
-EXPORT_SYMBOL(efi);
static struct kobject *efi_kobj;
static struct kobject *efivars_kobj;
@@ -148,127 +132,3 @@ err_put:
}
subsys_initcall(efisubsys_init);
-
-
-/*
- * We can't ioremap data in EFI boot services RAM, because we've already mapped
- * it as RAM. So, look it up in the existing EFI memory map instead. Only
- * callable after efi_enter_virtual_mode and before efi_free_boot_services.
- */
-void __iomem *efi_lookup_mapped_addr(u64 phys_addr)
-{
- struct efi_memory_map *map;
- void *p;
- map = efi.memmap;
- if (!map)
- return NULL;
- if (WARN_ON(!map->map))
- return NULL;
- for (p = map->map; p < map->map_end; p += map->desc_size) {
- efi_memory_desc_t *md = p;
- u64 size = md->num_pages << EFI_PAGE_SHIFT;
- u64 end = md->phys_addr + size;
- if (!(md->attribute & EFI_MEMORY_RUNTIME) &&
- md->type != EFI_BOOT_SERVICES_CODE &&
- md->type != EFI_BOOT_SERVICES_DATA)
- continue;
- if (!md->virt_addr)
- continue;
- if (phys_addr >= md->phys_addr && phys_addr < end) {
- phys_addr += md->virt_addr - md->phys_addr;
- return (__force void __iomem *)(unsigned long)phys_addr;
- }
- }
- return NULL;
-}
-
-static __initdata efi_config_table_type_t common_tables[] = {
- {ACPI_20_TABLE_GUID, "ACPI 2.0", &efi.acpi20},
- {ACPI_TABLE_GUID, "ACPI", &efi.acpi},
- {HCDP_TABLE_GUID, "HCDP", &efi.hcdp},
- {MPS_TABLE_GUID, "MPS", &efi.mps},
- {SAL_SYSTEM_TABLE_GUID, "SALsystab", &efi.sal_systab},
- {SMBIOS_TABLE_GUID, "SMBIOS", &efi.smbios},
- {UGA_IO_PROTOCOL_GUID, "UGA", &efi.uga},
- {NULL_GUID, NULL, 0},
-};
-
-static __init int match_config_table(efi_guid_t *guid,
- unsigned long table,
- efi_config_table_type_t *table_types)
-{
- u8 str[EFI_VARIABLE_GUID_LEN + 1];
- int i;
-
- if (table_types) {
- efi_guid_unparse(guid, str);
-
- for (i = 0; efi_guidcmp(table_types[i].guid, NULL_GUID); i++) {
- efi_guid_unparse(&table_types[i].guid, str);
-
- if (!efi_guidcmp(*guid, table_types[i].guid)) {
- *(table_types[i].ptr) = table;
- pr_cont(" %s=0x%lx ",
- table_types[i].name, table);
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-int __init efi_config_init(efi_config_table_type_t *arch_tables)
-{
- void *config_tables, *tablep;
- int i, sz;
-
- if (efi_enabled(EFI_64BIT))
- sz = sizeof(efi_config_table_64_t);
- else
- sz = sizeof(efi_config_table_32_t);
-
- /*
- * Let's see what config tables the firmware passed to us.
- */
- config_tables = early_memremap(efi.systab->tables,
- efi.systab->nr_tables * sz);
- if (config_tables == NULL) {
- pr_err("Could not map Configuration table!\n");
- return -ENOMEM;
- }
-
- tablep = config_tables;
- pr_info("");
- for (i = 0; i < efi.systab->nr_tables; i++) {
- efi_guid_t guid;
- unsigned long table;
-
- if (efi_enabled(EFI_64BIT)) {
- u64 table64;
- guid = ((efi_config_table_64_t *)tablep)->guid;
- table64 = ((efi_config_table_64_t *)tablep)->table;
- table = table64;
-#ifndef CONFIG_64BIT
- if (table64 >> 32) {
- pr_cont("\n");
- pr_err("Table located above 4GB, disabling EFI.\n");
- early_iounmap(config_tables,
- efi.systab->nr_tables * sz);
- return -EINVAL;
- }
-#endif
- } else {
- guid = ((efi_config_table_32_t *)tablep)->guid;
- table = ((efi_config_table_32_t *)tablep)->table;
- }
-
- if (!match_config_table(&guid, table, common_tables))
- match_config_table(&guid, table, arch_tables);
-
- tablep += sz;
- }
- pr_cont("\n");
- early_iounmap(config_tables, efi.systab->nr_tables * sz);
- return 0;
-}
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index 3dc2482..8a7432a 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -383,16 +383,12 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj,
else if (__efivar_entry_delete(entry))
err = -EIO;
- if (err) {
- efivar_entry_iter_end();
+ efivar_entry_iter_end();
+
+ if (err)
return err;
- }
- if (!entry->scanning) {
- efivar_entry_iter_end();
- efivar_unregister(entry);
- } else
- efivar_entry_iter_end();
+ efivar_unregister(entry);
/* It's dead Jim.... */
return count;
@@ -568,7 +564,7 @@ static int efivar_sysfs_destroy(struct efivar_entry *entry, void *data)
return 0;
}
-static void efivars_sysfs_exit(void)
+void efivars_sysfs_exit(void)
{
/* Remove all entries and destroy */
__efivar_entry_iter(efivar_sysfs_destroy, &efivar_sysfs_list, NULL, NULL);
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index b22659c..391c67b 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -683,16 +683,8 @@ struct efivar_entry *efivar_entry_find(efi_char16_t *name, efi_guid_t guid,
if (!found)
return NULL;
- if (remove) {
- if (entry->scanning) {
- /*
- * The entry will be deleted
- * after scanning is completed.
- */
- entry->deleting = true;
- } else
- list_del(&entry->list);
- }
+ if (remove)
+ list_del(&entry->list);
return entry;
}
diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
index e5a67b2..6eb535f 100644
--- a/drivers/firmware/google/gsmi.c
+++ b/drivers/firmware/google/gsmi.c
@@ -764,13 +764,6 @@ static __init int gsmi_system_valid(void)
static struct kobject *gsmi_kobj;
static struct efivars efivars;
-static const struct platform_device_info gsmi_dev_info = {
- .name = "gsmi",
- .id = -1,
- /* SMI callbacks require 32bit addresses */
- .dma_mask = DMA_BIT_MASK(32),
-};
-
static __init int gsmi_init(void)
{
unsigned long flags;
@@ -783,7 +776,7 @@ static __init int gsmi_init(void)
gsmi_dev.smi_cmd = acpi_gbl_FADT.smi_command;
/* register device */
- gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info);
+ gsmi_dev.pdev = platform_device_register_simple("gsmi", -1, NULL, 0);
if (IS_ERR(gsmi_dev.pdev)) {
printk(KERN_ERR "gsmi: unable to register platform device\n");
return PTR_ERR(gsmi_dev.pdev);
@@ -792,6 +785,10 @@ static __init int gsmi_init(void)
/* SMI access needs to be serialized */
spin_lock_init(&gsmi_dev.lock);
+ /* SMI callbacks require 32bit addresses */
+ gsmi_dev.pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+ gsmi_dev.pdev->dev.dma_mask =
+ &gsmi_dev.pdev->dev.coherent_dma_mask;
ret = -ENOMEM;
gsmi_dev.dma_pool = dma_pool_create("gsmi", &gsmi_dev.pdev->dev,
GSMI_BUF_SIZE, GSMI_BUF_ALIGN, 0);