diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:52:52 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-30 11:52:52 -0700 |
commit | 08acd4f8af42affd8cbed81cc1b69fa12ddb213f (patch) | |
tree | 988d15db6233b20db6a500cd5f590c6d2041462d /drivers/acpi/executer/exfldio.c | |
parent | ccf2779544eecfcc5447e2028d1029b6d4ff7bb6 (diff) | |
parent | 008238b54ac2350babf195084ecedbcf7851a202 (diff) | |
download | linux-08acd4f8af42affd8cbed81cc1b69fa12ddb213f.tar.gz linux-08acd4f8af42affd8cbed81cc1b69fa12ddb213f.tar.bz2 linux-08acd4f8af42affd8cbed81cc1b69fa12ddb213f.zip |
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (179 commits)
ACPI: Fix acpi_processor_idle and idle= boot parameters interaction
acpi: fix section mismatch warning in pnpacpi
intel_menlo: fix build warning
ACPI: Cleanup: Remove unneeded, multiple local dummy variables
ACPI: video - fix permissions on some proc entries
ACPI: video - properly handle errors when registering proc elements
ACPI: video - do not store invalid entries in attached_array list
ACPI: re-name acpi_pm_ops to acpi_suspend_ops
ACER_WMI/ASUS_LAPTOP: fix build bug
thinkpad_acpi: fix possible NULL pointer dereference if kstrdup failed
ACPI: check a return value correctly in acpi_power_get_context()
#if 0 acpi/bay.c:eject_removable_drive()
eeepc-laptop: add hwmon fan control
eeepc-laptop: add backlight
eeepc-laptop: add base driver
ACPI: thinkpad-acpi: bump up version to 0.20
ACPI: thinkpad-acpi: fix selects in Kconfig
ACPI: thinkpad-acpi: use a private workqueue
ACPI: thinkpad-acpi: fluff really minor fix
ACPI: thinkpad-acpi: use uppercase for "LED" on user documentation
...
Fixed conflicts in drivers/acpi/video.c and drivers/misc/intel_menlow.c
manually.
Diffstat (limited to 'drivers/acpi/executer/exfldio.c')
-rw-r--r-- | drivers/acpi/executer/exfldio.c | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/drivers/acpi/executer/exfldio.c b/drivers/acpi/executer/exfldio.c index 65a48b6170ee..e336b5dc7a50 100644 --- a/drivers/acpi/executer/exfldio.c +++ b/drivers/acpi/executer/exfldio.c @@ -5,7 +5,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 - 2007, R. Byron Moore + * Copyright (C) 2000 - 2008, Intel Corp. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -263,7 +263,8 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc, rgn_desc->region.space_id, obj_desc->common_field.access_byte_width, obj_desc->common_field.base_byte_offset, - field_datum_byte_offset, (void *)address)); + field_datum_byte_offset, ACPI_CAST_PTR(void, + address))); /* Invoke the appropriate address_space/op_region handler */ @@ -805,18 +806,39 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, u32 datum_count; u32 field_datum_count; u32 i; + u32 required_length; + void *new_buffer; ACPI_FUNCTION_TRACE(ex_insert_into_field); /* Validate input buffer */ - if (buffer_length < - ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length)) { - ACPI_ERROR((AE_INFO, - "Field size %X (bits) is too large for buffer (%X)", - obj_desc->common_field.bit_length, buffer_length)); + new_buffer = NULL; + required_length = + ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->common_field.bit_length); + /* + * We must have a buffer that is at least as long as the field + * we are writing to. This is because individual fields are + * indivisible and partial writes are not supported -- as per + * the ACPI specification. + */ + if (buffer_length < required_length) { - return_ACPI_STATUS(AE_BUFFER_OVERFLOW); + /* We need to create a new buffer */ + + new_buffer = ACPI_ALLOCATE_ZEROED(required_length); + if (!new_buffer) { + return_ACPI_STATUS(AE_NO_MEMORY); + } + + /* + * Copy the original data to the new buffer, starting + * at Byte zero. All unused (upper) bytes of the + * buffer will be 0. + */ + ACPI_MEMCPY((char *)new_buffer, (char *)buffer, buffer_length); + buffer = new_buffer; + buffer_length = required_length; } /* @@ -866,7 +888,7 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, merged_datum, field_offset); if (ACPI_FAILURE(status)) { - return_ACPI_STATUS(status); + goto exit; } field_offset += obj_desc->common_field.access_byte_width; @@ -924,5 +946,11 @@ acpi_ex_insert_into_field(union acpi_operand_object *obj_desc, mask, merged_datum, field_offset); + exit: + /* Free temporary buffer if we used one */ + + if (new_buffer) { + ACPI_FREE(new_buffer); + } return_ACPI_STATUS(status); } |