record_header = (void *)subtable_header + offset;
offset += record_header->length;
+ if (!record_header->length) {
+ pr_err(FW_BUG "Zero-length record found in FPTD.\n");
+ result = -EINVAL;
+ goto err;
+ }
+
switch (record_header->type) {
case RECORD_S3_RESUME:
if (subtable_type != SUBTABLE_S3PT) {
pr_err(FW_BUG "Invalid record %d for subtable %s\n",
record_header->type, signature);
- return -EINVAL;
+ result = -EINVAL;
+ goto err;
}
if (record_resume) {
pr_err("Duplicate resume performance record found.\n");
record_resume = (struct resume_performance_record *)record_header;
result = sysfs_create_group(fpdt_kobj, &resume_attr_group);
if (result)
- return result;
+ goto err;
break;
case RECORD_S3_SUSPEND:
if (subtable_type != SUBTABLE_S3PT) {
record_suspend = (struct suspend_performance_record *)record_header;
result = sysfs_create_group(fpdt_kobj, &suspend_attr_group);
if (result)
- return result;
+ goto err;
break;
case RECORD_BOOT:
if (subtable_type != SUBTABLE_FBPT) {
pr_err(FW_BUG "Invalid %d for subtable %s\n",
record_header->type, signature);
- return -EINVAL;
+ result = -EINVAL;
+ goto err;
}
if (record_boot) {
pr_err("Duplicate boot performance record found.\n");
record_boot = (struct boot_performance_record *)record_header;
result = sysfs_create_group(fpdt_kobj, &boot_attr_group);
if (result)
- return result;
+ goto err;
break;
default:
}
}
return 0;
+
+err:
+ if (record_boot)
+ sysfs_remove_group(fpdt_kobj, &boot_attr_group);
+
+ if (record_suspend)
+ sysfs_remove_group(fpdt_kobj, &suspend_attr_group);
+
+ if (record_resume)
+ sysfs_remove_group(fpdt_kobj, &resume_attr_group);
+
+ return result;
}
static int __init acpi_init_fpdt(void)
struct acpi_table_header *header;
struct fpdt_subtable_entry *subtable;
u32 offset = sizeof(*header);
+ int result;
status = acpi_get_table(ACPI_SIG_FPDT, 0, &header);
fpdt_kobj = kobject_create_and_add("fpdt", acpi_kobj);
if (!fpdt_kobj) {
- acpi_put_table(header);
- return -ENOMEM;
+ result = -ENOMEM;
+ goto err_nomem;
}
while (offset < header->length) {
switch (subtable->type) {
case SUBTABLE_FBPT:
case SUBTABLE_S3PT:
- fpdt_process_subtable(subtable->address,
+ result = fpdt_process_subtable(subtable->address,
subtable->type);
+ if (result)
+ goto err_subtable;
break;
default:
/* Other types are reserved in ACPI 6.4 spec. */
offset += sizeof(*subtable);
}
return 0;
+err_subtable:
+ kobject_put(fpdt_kobj);
+
+err_nomem:
+ acpi_put_table(header);
+ return result;
}
fs_initcall(acpi_init_fpdt);
break;
} else if (osi->string[0] == '\0') {
osi->enable = enable;
- strncpy(osi->string, str, OSI_STRING_LENGTH_MAX);
+ strscpy(osi->string, str, OSI_STRING_LENGTH_MAX);
break;
}
}
}
EXPORT_SYMBOL(acpi_os_printf);
-void acpi_os_vprintf(const char *fmt, va_list args)
+void __printf(1, 0) acpi_os_vprintf(const char *fmt, va_list args)
{
static char buffer[512];
#ifdef ACPI_FUTURE_USAGE
acpi_status
-acpi_os_get_physical_address(void *virt, acpi_physical_address * phys)
+acpi_os_get_physical_address(void *virt, acpi_physical_address *phys)
{
if (!phys || !virt)
return AE_BAD_PARAMETER;
#ifdef CONFIG_PCI
acpi_status
-acpi_os_read_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
+acpi_os_read_pci_configuration(struct acpi_pci_id *pci_id, u32 reg,
u64 *value, u32 width)
{
int result, size;
}
acpi_status
-acpi_os_write_pci_configuration(struct acpi_pci_id * pci_id, u32 reg,
+acpi_os_write_pci_configuration(struct acpi_pci_id *pci_id, u32 reg,
u64 value, u32 width)
{
int result, size;
struct acpi_os_dpc *dpc;
struct workqueue_struct *queue;
int ret;
+
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"Scheduling function [%p(%p)] for deferred execution.\n",
function, context));
}
acpi_status
-acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle * handle)
+acpi_os_create_semaphore(u32 max_units, u32 initial_units, acpi_handle *handle)
{
struct semaphore *sem = NULL;
__acquires(lockp)
{
acpi_cpu_flags flags;
+
spin_lock_irqsave(lockp, flags);
return flags;
}
******************************************************************************/
acpi_status
-acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t ** cache)
+acpi_os_create_cache(char *name, u16 size, u16 depth, acpi_cache_t **cache)
{
*cache = kmem_cache_create(name, size, 0, 0, NULL);
if (*cache == NULL)
*
******************************************************************************/
-acpi_status acpi_os_purge_cache(acpi_cache_t * cache)
+acpi_status acpi_os_purge_cache(acpi_cache_t *cache)
{
kmem_cache_shrink(cache);
- return (AE_OK);
+ return AE_OK;
}
/*******************************************************************************
*
******************************************************************************/
-acpi_status acpi_os_delete_cache(acpi_cache_t * cache)
+acpi_status acpi_os_delete_cache(acpi_cache_t *cache)
{
kmem_cache_destroy(cache);
- return (AE_OK);
+ return AE_OK;
}
/*******************************************************************************
*
******************************************************************************/
-acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
+acpi_status acpi_os_release_object(acpi_cache_t *cache, void *object)
{
kmem_cache_free(cache, object);
- return (AE_OK);
+ return AE_OK;
}
#endif
u32 pm1b_control)
{
int rc = 0;
+
if (__acpi_os_prepare_sleep)
rc = __acpi_os_prepare_sleep(sleep_state,
pm1a_control, pm1b_control);
u32 val_b)
{
int rc = 0;
+
if (__acpi_os_prepare_extended_sleep)
rc = __acpi_os_prepare_extended_sleep(sleep_state,
val_a, val_b);
return 0;
}
-static int acpi_scan_device_not_present(struct acpi_device *adev)
+static int acpi_scan_device_not_enumerated(struct acpi_device *adev)
{
if (!acpi_device_enumerated(adev)) {
- dev_warn(&adev->dev, "Still not present\n");
+ dev_warn(&adev->dev, "Still not enumerated\n");
return -EALREADY;
}
acpi_bus_trim(adev);
int error;
acpi_bus_get_status(adev);
- if (adev->status.present || adev->status.functional) {
+ if (acpi_device_is_present(adev)) {
/*
* This function is only called for device objects for which
* matching scan handlers exist. The only situation in which
error = -ENODEV;
}
} else {
- error = acpi_scan_device_not_present(adev);
+ error = acpi_scan_device_not_enumerated(adev);
}
return error;
}
int error;
acpi_bus_get_status(adev);
- if (!(adev->status.present || adev->status.functional)) {
- acpi_scan_device_not_present(adev);
+ if (!acpi_device_is_present(adev)) {
+ acpi_scan_device_not_enumerated(adev);
return 0;
}
if (handler && handler->hotplug.scan_dependent)