Commit 2d837fe9 authored by Len Brown's avatar Len Brown Committed by Len Brown

[ACPI] ACPICA 20040527 from Bob Moore

Completed a new design and implementation for EBDA
(Extended BIOS Data Area) support in the RSDP scan code.
The original code improperly scanned for the EBDA by simply
scanning from memory location 0 to 0x400.  The correct
method is to first obtain the EBDA pointer from within
the BIOS data area, then scan 1K of memory starting at the
EBDA pointer.  There appear to be few if any machines that
place the RSDP in the EBDA, however.
http://bugme.osdl.org/show_bug.cgi?id=2415

Integrated a fix for a possible fault during evaluation
of BufferField arguments.  Obsolete code that was causing
the problem was removed. (Asus laptop boot crash)
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=121760

Found and fixed a problem in the Field Support Code
where data could be corrupted on a bit field read that
starts on an aligned boundary but does not end on an
aligned boundary.  Merged the read/write "datum length"
calculation code into a common procedure.
parent f81d800e
......@@ -79,7 +79,6 @@ acpi_ds_execute_arguments (
acpi_status status;
union acpi_parse_object *op;
struct acpi_walk_state *walk_state;
union acpi_parse_object *arg;
ACPI_FUNCTION_TRACE ("ds_execute_arguments");
......@@ -126,9 +125,7 @@ acpi_ds_execute_arguments (
/* Get and init the Op created above */
arg = op->common.value.arg;
op->common.node = node;
arg->common.node = node;
acpi_ps_delete_parse_tree (op);
/* Evaluate the deferred arguments */
......
......@@ -130,27 +130,27 @@ acpi_ev_update_gpe_enable_masks (
/* 1) Disable case. Simply clear all enable bits */
if (type == ACPI_GPE_DISABLE) {
gpe_register_info->enable_for_wake &= ~register_bit;
gpe_register_info->enable_for_run &= ~register_bit;
ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit);
ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit);
return_ACPI_STATUS (AE_OK);
}
/* 2) Enable case. Set the appropriate enable bits */
/* 2) Enable case. Set/Clear the appropriate enable bits */
switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
case ACPI_GPE_TYPE_WAKE:
gpe_register_info->enable_for_wake |= register_bit;
gpe_register_info->enable_for_run &= ~register_bit;
ACPI_SET_BIT (gpe_register_info->enable_for_wake, register_bit);
ACPI_CLEAR_BIT (gpe_register_info->enable_for_run, register_bit);
break;
case ACPI_GPE_TYPE_RUNTIME:
gpe_register_info->enable_for_wake &= ~register_bit;
gpe_register_info->enable_for_run |= register_bit;
ACPI_CLEAR_BIT (gpe_register_info->enable_for_wake, register_bit);
ACPI_SET_BIT (gpe_register_info->enable_for_run, register_bit);
break;
case ACPI_GPE_TYPE_WAKE_RUN:
gpe_register_info->enable_for_wake |= register_bit;
gpe_register_info->enable_for_run |= register_bit;
ACPI_SET_BIT (gpe_register_info->enable_for_wake, register_bit);
ACPI_SET_BIT (gpe_register_info->enable_for_run, register_bit);
break;
default:
......@@ -195,17 +195,19 @@ acpi_ev_enable_gpe (
switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
case ACPI_GPE_TYPE_WAKE:
gpe_event_info->flags |= ACPI_GPE_WAKE_ENABLED;
ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
break;
case ACPI_GPE_TYPE_WAKE_RUN:
gpe_event_info->flags |= ACPI_GPE_WAKE_ENABLED;
ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
/*lint -fallthrough */
case ACPI_GPE_TYPE_RUNTIME:
gpe_event_info->flags |= ACPI_GPE_RUN_ENABLED;
ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
if (write_to_hardware) {
/* Clear the GPE (of stale events), then enable it */
......@@ -266,11 +268,11 @@ acpi_ev_disable_gpe (
switch (gpe_event_info->flags & ACPI_GPE_TYPE_MASK) {
case ACPI_GPE_TYPE_WAKE:
gpe_event_info->flags &= ~ACPI_GPE_WAKE_ENABLED;
ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
break;
case ACPI_GPE_TYPE_WAKE_RUN:
gpe_event_info->flags &= ~ACPI_GPE_WAKE_ENABLED;
ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
/*lint -fallthrough */
......@@ -278,7 +280,7 @@ acpi_ev_disable_gpe (
/* Disable the requested runtime GPE */
gpe_event_info->flags &= ~ACPI_GPE_RUN_ENABLED;
ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
status = acpi_hw_write_gpe_enable_reg (gpe_event_info);
break;
......@@ -613,10 +615,10 @@ acpi_ev_gpe_dispatch (
/* Save current system state */
if (acpi_gbl_system_awake_and_running) {
gpe_event_info->flags |= ACPI_GPE_SYSTEM_RUNNING;
ACPI_SET_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
}
else {
gpe_event_info->flags &= ~ACPI_GPE_SYSTEM_RUNNING;
ACPI_CLEAR_BIT (gpe_event_info->flags, ACPI_GPE_SYSTEM_RUNNING);
}
/*
......@@ -629,9 +631,11 @@ acpi_ev_gpe_dispatch (
switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
case ACPI_GPE_DISPATCH_HANDLER:
/* Invoke the installed handler (at interrupt level) */
gpe_event_info->dispatch.handler->address ((void *)
/*
* Invoke the installed handler (at interrupt level)
* Ignore return status for now. TBD: leave GPE disabled on error?
*/
(void) gpe_event_info->dispatch.handler->address (
gpe_event_info->dispatch.handler->context);
/* It is now safe to clear level-triggered events. */
......
......@@ -968,8 +968,8 @@ acpi_ev_create_gpe_block (
/* Dump info about this GPE block */
ACPI_DEBUG_PRINT ((ACPI_DB_INIT,
"GPE %02d to %02d [%4.4s] %d regs at %8.8X%8.8X on int %d\n",
gpe_block->block_base_number,
"GPE %02X to %02X [%4.4s] %u regs at %8.8X%8.8X on int 0x%X\n",
(u32) gpe_block->block_base_number,
(u32) (gpe_block->block_base_number +
((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)),
gpe_device->name.ascii,
......
......@@ -321,7 +321,7 @@ acpi_ex_load_op (
table_header.length = 0;
for (i = 0; i < 8; i++) {
status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
(acpi_physical_address) i + address, 8,
(acpi_physical_address) (i + address), 8,
((u8 *) &table_header) + i);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
......@@ -345,7 +345,7 @@ acpi_ex_load_op (
for (i = 0; i < table_header.length; i++) {
status = acpi_ev_address_space_dispatch (obj_desc, ACPI_READ,
(acpi_physical_address) i + address, 8,
(acpi_physical_address) (i + address), 8,
((u8 *) table_ptr + i));
if (ACPI_FAILURE (status)) {
goto cleanup;
......
......@@ -764,16 +764,85 @@ acpi_ex_set_buffer_datum (
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_common_buffer_setup
*
* PARAMETERS: obj_desc - Field object
* buffer_length - Length of caller's buffer
* datum_count - Where the datum_count is returned
*
* RETURN: Status, datum_count
*
* DESCRIPTION: Common code to validate the incoming buffer size and compute
* the number of field "datums" that must be read or written.
* A "datum" is the smallest unit that can be read or written
* to the field, it is either 1,2,4, or 8 bytes.
*
******************************************************************************/
acpi_status
acpi_ex_common_buffer_setup (
union acpi_operand_object *obj_desc,
u32 buffer_length,
u32 *datum_count)
{
u32 byte_field_length;
u32 actual_byte_field_length;
ACPI_FUNCTION_TRACE ("ex_common_buffer_setup");
/*
* Incoming buffer must be at least as long as the field, we do not
* allow "partial" field reads/writes. We do not care if the buffer is
* larger than the field, this typically happens when an integer is
* read/written to a field that is actually smaller than an integer.
*/
byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (
obj_desc->common_field.bit_length);
if (byte_field_length > buffer_length) {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Field size %X (bytes) is too large for buffer (%X)\n",
byte_field_length, buffer_length));
return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
}
/*
* Create "actual" field byte count (minimum number of bytes that
* must be read), then convert to datum count (minimum number
* of datum-sized units that must be read)
*/
actual_byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (
obj_desc->common_field.start_field_bit_offset +
obj_desc->common_field.bit_length);
*datum_count = ACPI_ROUND_UP_TO (actual_byte_field_length,
obj_desc->common_field.access_byte_width);
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"buffer_bytes %X, actual_bytes %X, Datums %X, byte_gran %X\n",
byte_field_length, actual_byte_field_length,
*datum_count, obj_desc->common_field.access_byte_width));
return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
*
* FUNCTION: acpi_ex_extract_from_field
*
* PARAMETERS: *obj_desc - Field to be read
* *Value - Where to store value
* PARAMETERS: obj_desc - Field to be read
* Buffer - Where to store the field data
* buffer_length - Length of Buffer
*
* RETURN: Status
*
* DESCRIPTION: Retrieve the value of the given field
* DESCRIPTION: Retrieve the current value of the given field
*
******************************************************************************/
......@@ -789,7 +858,6 @@ acpi_ex_extract_from_field (
acpi_integer previous_raw_datum = 0;
acpi_integer this_raw_datum = 0;
acpi_integer merged_datum = 0;
u32 byte_field_length;
u32 datum_count;
u32 i;
......@@ -797,39 +865,13 @@ acpi_ex_extract_from_field (
ACPI_FUNCTION_TRACE ("ex_extract_from_field");
/*
* The field must fit within the caller's buffer
*/
byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (obj_desc->common_field.bit_length);
if (byte_field_length > buffer_length) {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Field size %X (bytes) too large for buffer (%X)\n",
byte_field_length, buffer_length));
return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
}
/* Convert field byte count to datum count, round up if necessary */
/* Validate buffer, compute number of datums */
datum_count = ACPI_ROUND_UP_TO (byte_field_length,
obj_desc->common_field.access_byte_width);
/*
* If the field is not aligned on a datum boundary and does not
* fit within a single datum, we must read an extra datum.
*
* We could just split the aligned and non-aligned cases since the
* aligned case is so very simple, but this would require more code.
*/
if ((obj_desc->common_field.end_field_valid_bits != 0) &&
(!(obj_desc->common_field.flags & AOPOBJ_SINGLE_DATUM))) {
datum_count++;
status = acpi_ex_common_buffer_setup (obj_desc, buffer_length, &datum_count);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"byte_len %X, datum_len %X, byte_gran %X\n",
byte_field_length, datum_count,obj_desc->common_field.access_byte_width));
/*
* Clear the caller's buffer (the whole buffer length as given)
* This is very important, especially in the cases where the buffer
......@@ -942,12 +984,13 @@ acpi_ex_extract_from_field (
*
* FUNCTION: acpi_ex_insert_into_field
*
* PARAMETERS: *obj_desc - Field to be set
* Buffer - Value to store
* PARAMETERS: obj_desc - Field to be written
* Buffer - Data to be written
* buffer_length - Length of Buffer
*
* RETURN: Status
*
* DESCRIPTION: Store the value into the given field
* DESCRIPTION: Store the Buffer contents into the given field
*
******************************************************************************/
......@@ -964,42 +1007,19 @@ acpi_ex_insert_into_field (
acpi_integer merged_datum;
acpi_integer previous_raw_datum;
acpi_integer this_raw_datum;
u32 byte_field_length;
u32 datum_count;
ACPI_FUNCTION_TRACE ("ex_insert_into_field");
/*
* Incoming buffer must be at least as long as the field, we do not
* allow "partial" field writes. We do not care if the buffer is
* larger than the field, this typically happens when an integer is
* written to a field that is actually smaller than an integer.
*/
byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (
obj_desc->common_field.bit_length);
if (buffer_length < byte_field_length) {
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Buffer length %X too small for field %X\n",
buffer_length, byte_field_length));
/* Validate buffer, compute number of datums */
return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
status = acpi_ex_common_buffer_setup (obj_desc, buffer_length, &datum_count);
if (ACPI_FAILURE (status)) {
return_ACPI_STATUS (status);
}
byte_field_length = ACPI_ROUND_BITS_UP_TO_BYTES (
obj_desc->common_field.start_field_bit_offset +
obj_desc->common_field.bit_length);
/* Convert byte count to datum count, round up if necessary */
datum_count = ACPI_ROUND_UP_TO (byte_field_length,
obj_desc->common_field.access_byte_width);
ACPI_DEBUG_PRINT ((ACPI_DB_BFIELD,
"Bytes %X, Datums %X, byte_gran %X\n",
byte_field_length, datum_count, obj_desc->common_field.access_byte_width));
/*
* Break the request into up to three parts (similar to an I/O request):
* 1) non-aligned part at start
......
......@@ -389,14 +389,17 @@ acpi_tb_scan_memory_for_rsdp (
* Flags - Current memory mode (logical vs.
* physical addressing)
*
* RETURN: Status
* RETURN: Status, RSDP physical address
*
* DESCRIPTION: search lower 1_mbyte of memory for the root system descriptor
* pointer structure. If it is found, set *RSDP to point to it.
*
* NOTE: The RSDp must be either in the first 1_k of the Extended
* BIOS Data Area or between E0000 and FFFFF (ACPI 1.0 section
* 5.2.2; assertion #421).
* NOTE1: The RSDp must be either in the first 1_k of the Extended
* BIOS Data Area or between E0000 and FFFFF (From ACPI Spec.)
* Only a 32-bit physical address is necessary.
*
* NOTE2: This function is always available, regardless of the
* initialization state of the rest of ACPI.
*
******************************************************************************/
......@@ -407,8 +410,8 @@ acpi_tb_find_rsdp (
{
u8 *table_ptr;
u8 *mem_rover;
u64 phys_addr;
acpi_status status = AE_OK;
u32 physical_address;
acpi_status status;
ACPI_FUNCTION_TRACE ("tb_find_rsdp");
......@@ -419,36 +422,57 @@ acpi_tb_find_rsdp (
*/
if ((flags & ACPI_MEMORY_MODE) == ACPI_LOGICAL_ADDRESSING) {
/*
* 1) Search EBDA (low memory) paragraphs
* 1a) Get the location of the EBDA
*/
status = acpi_os_map_memory ((u64) ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE,
status = acpi_os_map_memory ((acpi_physical_address) ACPI_EBDA_PTR_LOCATION,
ACPI_EBDA_PTR_LENGTH,
(void *) &table_ptr);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n",
ACPI_LO_RSDP_WINDOW_BASE, ACPI_LO_RSDP_WINDOW_SIZE));
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n",
ACPI_EBDA_PTR_LOCATION, ACPI_EBDA_PTR_LENGTH));
return_ACPI_STATUS (status);
}
mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE);
acpi_os_unmap_memory (table_ptr, ACPI_LO_RSDP_WINDOW_SIZE);
ACPI_MOVE_16_TO_32 (&physical_address, table_ptr);
physical_address <<= 4; /* Convert segment to physical address */
acpi_os_unmap_memory (table_ptr, ACPI_EBDA_PTR_LENGTH);
if (mem_rover) {
/* Found it, return the physical address */
/* EBDA present? */
phys_addr = ACPI_LO_RSDP_WINDOW_BASE;
phys_addr += ACPI_PTR_DIFF (mem_rover,table_ptr);
if (physical_address > 0x400) {
/*
* 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
*/
status = acpi_os_map_memory ((acpi_physical_address) physical_address,
ACPI_EBDA_WINDOW_SIZE,
(void *) &table_ptr);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n",
physical_address, ACPI_EBDA_WINDOW_SIZE));
return_ACPI_STATUS (status);
}
table_info->physical_address = phys_addr;
return_ACPI_STATUS (AE_OK);
mem_rover = acpi_tb_scan_memory_for_rsdp (table_ptr, ACPI_EBDA_WINDOW_SIZE);
acpi_os_unmap_memory (table_ptr, ACPI_EBDA_WINDOW_SIZE);
if (mem_rover) {
/* Found it, return the physical address */
physical_address += ACPI_PTR_DIFF (mem_rover, table_ptr);
table_info->physical_address = (acpi_physical_address) physical_address;
return_ACPI_STATUS (AE_OK);
}
}
/*
* 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
*/
status = acpi_os_map_memory ((u64) ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE,
status = acpi_os_map_memory ((acpi_physical_address) ACPI_HI_RSDP_WINDOW_BASE,
ACPI_HI_RSDP_WINDOW_SIZE,
(void *) &table_ptr);
if (ACPI_FAILURE (status)) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %X for length %X\n",
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not map memory at %8.8X for length %X\n",
ACPI_HI_RSDP_WINDOW_BASE, ACPI_HI_RSDP_WINDOW_SIZE));
return_ACPI_STATUS (status);
}
......@@ -459,10 +483,9 @@ acpi_tb_find_rsdp (
if (mem_rover) {
/* Found it, return the physical address */
phys_addr = ACPI_HI_RSDP_WINDOW_BASE;
phys_addr += ACPI_PTR_DIFF (mem_rover, table_ptr);
physical_address = ACPI_HI_RSDP_WINDOW_BASE + ACPI_PTR_DIFF (mem_rover, table_ptr);
table_info->physical_address = phys_addr;
table_info->physical_address = (acpi_physical_address) physical_address;
return_ACPI_STATUS (AE_OK);
}
}
......@@ -472,19 +495,29 @@ acpi_tb_find_rsdp (
*/
else {
/*
* 1) Search EBDA (low memory) paragraphs
* 1a) Get the location of the EBDA
*/
mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_LO_RSDP_WINDOW_BASE),
ACPI_LO_RSDP_WINDOW_SIZE);
if (mem_rover) {
/* Found it, return the physical address */
table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
return_ACPI_STATUS (AE_OK);
ACPI_MOVE_16_TO_32 (&physical_address, ACPI_EBDA_PTR_LOCATION);
physical_address <<= 4; /* Convert segment to physical address */
/* EBDA present? */
if (physical_address > 0x400) {
/*
* 1b) Search EBDA paragraphs (EBDa is required to be a minimum of 1_k length)
*/
mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (physical_address),
ACPI_EBDA_WINDOW_SIZE);
if (mem_rover) {
/* Found it, return the physical address */
table_info->physical_address = ACPI_TO_INTEGER (mem_rover);
return_ACPI_STATUS (AE_OK);
}
}
/*
* 2) Search upper memory: 16-byte boundaries in E0000h-F0000h
* 2) Search upper memory: 16-byte boundaries in E0000h-FFFFFh
*/
mem_rover = acpi_tb_scan_memory_for_rsdp (ACPI_PHYSADDR_TO_PTR (ACPI_HI_RSDP_WINDOW_BASE),
ACPI_HI_RSDP_WINDOW_SIZE);
......
......@@ -64,7 +64,7 @@
/* Version string */
#define ACPI_CA_VERSION 0x20040514
#define ACPI_CA_VERSION 0x20040527
/*
* OS name, used for the _OS object. The _OS object is essentially obsolete,
......@@ -78,7 +78,7 @@
/* Maximum objects in the various object caches */
#define ACPI_MAX_STATE_CACHE_DEPTH 64 /* State objects for stacks */
#define ACPI_MAX_STATE_CACHE_DEPTH 64 /* State objects */
#define ACPI_MAX_PARSE_CACHE_DEPTH 96 /* Parse tree objects */
#define ACPI_MAX_EXTPARSE_CACHE_DEPTH 64 /* Parse tree objects */
#define ACPI_MAX_OBJECT_CACHE_DEPTH 64 /* Interpreter operand objects */
......@@ -162,10 +162,11 @@
/* Constants used in searching for the RSDP in low memory */
#define ACPI_LO_RSDP_WINDOW_BASE 0 /* Physical Address */
#define ACPI_HI_RSDP_WINDOW_BASE 0xE0000 /* Physical Address */
#define ACPI_LO_RSDP_WINDOW_SIZE 0x400
#define ACPI_HI_RSDP_WINDOW_SIZE 0x20000
#define ACPI_EBDA_PTR_LOCATION 0x0000040E /* Physical Address */
#define ACPI_EBDA_PTR_LENGTH 2
#define ACPI_EBDA_WINDOW_SIZE 1024
#define ACPI_HI_RSDP_WINDOW_BASE 0x000E0000 /* Physical Address */
#define ACPI_HI_RSDP_WINDOW_SIZE 0x00020000
#define ACPI_RSDP_SCAN_STEP 16
/* Operation regions */
......
......@@ -117,6 +117,12 @@ acpi_ex_convert_to_ascii (
* exfield - ACPI AML (p-code) execution - field manipulation
*/
acpi_status
acpi_ex_common_buffer_setup (
union acpi_operand_object *obj_desc,
u32 buffer_length,
u32 *datum_count);
acpi_status
acpi_ex_extract_from_field (
union acpi_operand_object *obj_desc,
......
......@@ -53,6 +53,9 @@
#define ACPI_LOBYTE(l) ((u8)(u16)(l))
#define ACPI_HIBYTE(l) ((u8)((((u16)(l)) >> 8) & 0xFF))
#define ACPI_SET_BIT(target,bit) ((target) |= (bit))
#define ACPI_CLEAR_BIT(target,bit) ((target) &= ~(bit))
#if ACPI_MACHINE_WIDTH == 16
......
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