diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c index 767051a4ca8c30987b66f4478a37e303be1f53aa..5e0276d43425a1ef2fb4278b0874b309030e669c 100644 --- a/arch/i386/kernel/mpparse.c +++ b/arch/i386/kernel/mpparse.c @@ -1086,7 +1086,7 @@ void __init mp_parse_prt (void) /* * Parsing through the PCI Interrupt Routing Table (PRT) and program - * routing for all static (IOAPIC-direct) entries. + * routing for all entries. */ list_for_each(node, &acpi_prt.entries) { entry = list_entry(node, struct acpi_prt_entry, node); @@ -1100,6 +1100,10 @@ void __init mp_parse_prt (void) else irq = entry->link.index; + /* Don't set up the ACPI SCI because it's already set up */ + if (acpi_fadt.sci_int == irq) + continue; + ioapic = mp_find_ioapic(irq); if (ioapic < 0) continue; diff --git a/drivers/acpi/dispatcher/dsinit.c b/drivers/acpi/dispatcher/dsinit.c index 4bf51506bb47249c6d82d35e6f12c9a9b23ef501..afc359ec5d2f94b1c2ee1fb07265b88e9d4e5949 100644 --- a/drivers/acpi/dispatcher/dsinit.c +++ b/drivers/acpi/dispatcher/dsinit.c @@ -222,8 +222,8 @@ acpi_ds_initialize_objects ( } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INIT, - "\nTable [%4.4s] - %hd Objects with %hd Devices %hd Methods %hd Regions\n", - table_desc->pointer->signature, info.object_count, + "\nTable [%4.4s](id %4.4X) - %hd Objects with %hd Devices %hd Methods %hd Regions\n", + table_desc->pointer->signature, table_desc->table_id, info.object_count, info.device_count, info.method_count, info.op_region_count)); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index 8ecdf4cc0a13c26c66cc3a6bcf3d448a646502ca..309e43b0346f2dcd5aac923807d34e9fa07510bc 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -290,6 +290,8 @@ acpi_ds_call_control_method ( return_ACPI_STATUS (AE_NULL_OBJECT); } + obj_desc->method.owning_id = acpi_ut_allocate_owner_id (ACPI_OWNER_TYPE_METHOD); + /* Init for new method, wait on concurrency semaphore */ status = acpi_ds_begin_method_execution (method_node, obj_desc, diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 89f3b8e52558abbc25fe11d5c3bce55d7a60879d..df5f586c73776e59674292d4fcf7eec6d9f3b76a 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -204,7 +204,8 @@ acpi_ds_build_internal_buffer_obj ( if (obj_desc->buffer.length == 0) { obj_desc->buffer.pointer = NULL; - ACPI_REPORT_WARNING (("Buffer created with zero length in AML\n")); + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, + "Buffer defined with zero length in AML, creating\n")); } else { obj_desc->buffer.pointer = ACPI_MEM_CALLOCATE ( diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index b004b33489e747d104ee44ac24e01154da1b1c72..5d8e64587f4f073de76304823d8830c89f76f477 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c @@ -82,7 +82,7 @@ acpi_ds_execute_arguments ( union acpi_parse_object *arg; - ACPI_FUNCTION_TRACE ("acpi_ds_execute_arguments"); + ACPI_FUNCTION_TRACE ("ds_execute_arguments"); /* @@ -99,7 +99,7 @@ acpi_ds_execute_arguments ( /* Create and initialize a new parser state */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL); + walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); if (!walk_state) { return_ACPI_STATUS (AE_NO_MEMORY); } @@ -139,7 +139,7 @@ acpi_ds_execute_arguments ( /* Create and initialize a new parser state */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL); + walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); if (!walk_state) { return_ACPI_STATUS (AE_NO_MEMORY); } diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 0637567b454218df8e47b235a430ce27eeee3624..0504e1ac597f22417957ada224d650c36b4f82bd 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -50,6 +50,7 @@ #include <acpi/acinterp.h> #include <acpi/acnamesp.h> #include <acpi/acdebug.h> +#include <acpi/acdisasm.h> #define _COMPONENT ACPI_DISPATCHER @@ -657,6 +658,16 @@ acpi_ds_exec_end_op ( /* Always clear the object stack */ walk_state->num_operands = 0; + +#ifdef ACPI_DISASSEMBLER + + /* On error, display method locals/args */ + + if (ACPI_FAILURE (status)) { + acpi_dm_dump_method_info (status, walk_state, op); + } +#endif + return_ACPI_STATUS (status); } diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index cd9dd6d1c89a50b1cfab2c583ed2c3a6715672b9..6281f491c6ca854d64b3bc2de4c726c760cb7c8a 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -113,7 +113,7 @@ acpi_ec_wait ( switch (event) { case ACPI_EC_EVENT_OBF: do { - acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr, 0); + acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr); if (acpi_ec_status & ACPI_EC_FLAG_OBF) return 0; udelay(ACPI_EC_UDELAY); @@ -121,7 +121,7 @@ acpi_ec_wait ( break; case ACPI_EC_EVENT_IBE: do { - acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr, 0); + acpi_hw_low_level_read(8, &acpi_ec_status, &ec->status_addr); if (!(acpi_ec_status & ACPI_EC_FLAG_IBF)) return 0; udelay(ACPI_EC_UDELAY); @@ -161,18 +161,18 @@ acpi_ec_read ( spin_lock_irqsave(&ec->lock, flags); - acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr, 0); + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_READ, &ec->command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (result) goto end; - acpi_hw_low_level_write(8, address, &ec->data_addr, 0); + acpi_hw_low_level_write(8, address, &ec->data_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (result) goto end; - acpi_hw_low_level_read(8, data, &ec->data_addr, 0); + acpi_hw_low_level_read(8, data, &ec->data_addr); ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Read [%02x] from address [%02x]\n", *data, address)); @@ -211,17 +211,17 @@ acpi_ec_write ( spin_lock_irqsave(&ec->lock, flags); - acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr, 0); + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_WRITE, &ec->command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (result) goto end; - acpi_hw_low_level_write(8, address, &ec->data_addr, 0); + acpi_hw_low_level_write(8, address, &ec->data_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (result) goto end; - acpi_hw_low_level_write(8, data, &ec->data_addr, 0); + acpi_hw_low_level_write(8, data, &ec->data_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBE); if (result) goto end; @@ -310,12 +310,12 @@ acpi_ec_query ( */ spin_lock_irqsave(&ec->lock, flags); - acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr, 0); + acpi_hw_low_level_write(8, ACPI_EC_COMMAND_QUERY, &ec->command_addr); result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF); if (result) goto end; - acpi_hw_low_level_read(8, data, &ec->data_addr, 0); + acpi_hw_low_level_read(8, data, &ec->data_addr); if (!*data) result = -ENODATA; @@ -355,7 +355,7 @@ acpi_ec_gpe_query ( goto end; spin_lock_irqsave(&ec->lock, flags); - acpi_hw_low_level_read(8, &value, &ec->command_addr, 0); + acpi_hw_low_level_read(8, &value, &ec->command_addr); spin_unlock_irqrestore(&ec->lock, flags); /* TBD: Implement asynch events! diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c index 2fc32e12c86fae24be6f84997d1ce7a73877eb75..4cb089d54c67f3b278891570425ef3010b292ea7 100644 --- a/drivers/acpi/events/evgpe.c +++ b/drivers/acpi/events/evgpe.c @@ -170,7 +170,7 @@ acpi_ev_gpe_detect ( /* Read the Status Register */ status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, - &gpe_register_info->status_address, 0); + &gpe_register_info->status_address); gpe_register_info->status = (u8) in_value; if (ACPI_FAILURE (status)) { goto unlock_and_exit; @@ -179,7 +179,7 @@ acpi_ev_gpe_detect ( /* Read the Enable Register */ status = acpi_hw_low_level_read (ACPI_GPE_REGISTER_WIDTH, &in_value, - &gpe_register_info->enable_address, 0); + &gpe_register_info->enable_address); gpe_register_info->enable = (u8) in_value; if (ACPI_FAILURE (status)) { goto unlock_and_exit; diff --git a/drivers/acpi/events/evgpeblk.c b/drivers/acpi/events/evgpeblk.c index 6592b2301caea8ba852a422e9b0bda3e6c3c69c6..c24a11d9aaec50664570e773900593f3a0de3124 100644 --- a/drivers/acpi/events/evgpeblk.c +++ b/drivers/acpi/events/evgpeblk.c @@ -634,13 +634,13 @@ acpi_ev_create_gpe_info_blocks ( * by writing a '0'. */ status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0x00, - &this_register->enable_address, 0); + &this_register->enable_address); if (ACPI_FAILURE (status)) { goto error_exit; } status = acpi_hw_low_level_write (ACPI_GPE_REGISTER_WIDTH, 0xFF, - &this_register->status_address, 0); + &this_register->status_address); if (ACPI_FAILURE (status)) { goto error_exit; } @@ -732,18 +732,16 @@ acpi_ev_create_gpe_block ( /* Dump info about this GPE block */ - ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block: [%4.4s] %X registers at %8.8X%8.8X on interrupt %d\n", + 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, + (u32) (gpe_block->block_base_number + + ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)), gpe_device->name.ascii, gpe_block->register_count, ACPI_HIDWORD (gpe_block->block_address.address), ACPI_LODWORD (gpe_block->block_address.address), interrupt_level)); - ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "GPE Block defined as GPE 0x%.2X to GPE 0x%.2X\n", - gpe_block->block_base_number, - (u32) (gpe_block->block_base_number + - ((gpe_block->register_count * ACPI_GPE_REGISTER_WIDTH) -1)))); - /* Find all GPE methods (_Lxx, _Exx) for this block */ status = acpi_ns_walk_namespace (ACPI_TYPE_METHOD, gpe_device, diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index c76f24fb372ee7b20b83271013b9ee52789d3968..8a60bab5b9ddf023bce30fcce200049101ca884f 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -156,10 +156,10 @@ acpi_ev_queue_notify_request ( case ACPI_TYPE_POWER: if (notify_value <= ACPI_MAX_SYS_NOTIFY) { - handler_obj = obj_desc->common_notify.sys_handler; + handler_obj = obj_desc->common_notify.system_notify; } else { - handler_obj = obj_desc->common_notify.drv_handler; + handler_obj = obj_desc->common_notify.device_notify; } break; @@ -171,8 +171,8 @@ acpi_ev_queue_notify_request ( /* If there is any handler to run, schedule the dispatcher */ - if ((acpi_gbl_sys_notify.handler && (notify_value <= ACPI_MAX_SYS_NOTIFY)) || - (acpi_gbl_drv_notify.handler && (notify_value > ACPI_MAX_SYS_NOTIFY)) || + if ((acpi_gbl_system_notify.handler && (notify_value <= ACPI_MAX_SYS_NOTIFY)) || + (acpi_gbl_device_notify.handler && (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) { notify_info = acpi_ut_create_generic_state (); if (!notify_info) { @@ -235,17 +235,17 @@ acpi_ev_notify_dispatch ( if (notify_info->notify.value <= ACPI_MAX_SYS_NOTIFY) { /* Global system notification handler */ - if (acpi_gbl_sys_notify.handler) { - global_handler = acpi_gbl_sys_notify.handler; - global_context = acpi_gbl_sys_notify.context; + if (acpi_gbl_system_notify.handler) { + global_handler = acpi_gbl_system_notify.handler; + global_context = acpi_gbl_system_notify.context; } } else { /* Global driver notification handler */ - if (acpi_gbl_drv_notify.handler) { - global_handler = acpi_gbl_drv_notify.handler; - global_context = acpi_gbl_drv_notify.context; + if (acpi_gbl_device_notify.handler) { + global_handler = acpi_gbl_device_notify.handler; + global_context = acpi_gbl_device_notify.context; } } @@ -259,8 +259,8 @@ acpi_ev_notify_dispatch ( handler_obj = notify_info->notify.handler_obj; if (handler_obj) { - handler_obj->notify_handler.handler (notify_info->notify.node, notify_info->notify.value, - handler_obj->notify_handler.context); + handler_obj->notify.handler (notify_info->notify.node, notify_info->notify.value, + handler_obj->notify.context); } /* All done with the info object */ diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index de32b8f856040f14fb8a9750f30d4b04f3d92ee3..6b60baf5ab41ee69a3a1a5abe19069174afba984 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c @@ -50,24 +50,32 @@ #define _COMPONENT ACPI_EVENTS ACPI_MODULE_NAME ("evregion") +#define ACPI_NUM_DEFAULT_SPACES 4 + +u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = { + ACPI_ADR_SPACE_SYSTEM_MEMORY, + ACPI_ADR_SPACE_SYSTEM_IO, + ACPI_ADR_SPACE_PCI_CONFIG, + ACPI_ADR_SPACE_DATA_TABLE}; + /******************************************************************************* * * FUNCTION: acpi_ev_init_address_spaces * - * PARAMETERS: + * PARAMETERS: None * * RETURN: Status * - * DESCRIPTION: Installs the core subsystem address space handlers. + * DESCRIPTION: Installs the core subsystem default address space handlers. * ******************************************************************************/ acpi_status acpi_ev_init_address_spaces ( - void) -{ + void) { acpi_status status; + acpi_native_uint i; ACPI_FUNCTION_TRACE ("ev_init_address_spaces"); @@ -75,9 +83,11 @@ acpi_ev_init_address_spaces ( /* * All address spaces (PCI Config, EC, SMBus) are scope dependent - * and registration must occur for a specific device. In the case - * system memory and IO address spaces there is currently no device - * associated with the address space. For these we use the root. + * and registration must occur for a specific device. + * + * In the case of the system memory and IO address spaces there is currently + * no device associated with the address space. For these we use the root. + * * We install the default PCI config space handler at the root so * that this space is immediately available even though the we have * not enumerated all the PCI Root Buses yet. This is to conform @@ -86,39 +96,27 @@ acpi_ev_init_address_spaces ( * near ready to find the PCI root buses at this point. * * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler - * has already been installed (via acpi_install_address_space_handler) + * has already been installed (via acpi_install_address_space_handler). + * Similar for AE_SAME_HANDLER. */ - status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node, - ACPI_ADR_SPACE_SYSTEM_MEMORY, - ACPI_DEFAULT_HANDLER, NULL, NULL); - if ((ACPI_FAILURE (status)) && - (status != AE_ALREADY_EXISTS)) { - return_ACPI_STATUS (status); - } + for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) { + status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node, + acpi_gbl_default_address_spaces[i], + ACPI_DEFAULT_HANDLER, NULL, NULL); + switch (status) { + case AE_OK: + case AE_SAME_HANDLER: + case AE_ALREADY_EXISTS: - status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node, - ACPI_ADR_SPACE_SYSTEM_IO, - ACPI_DEFAULT_HANDLER, NULL, NULL); - if ((ACPI_FAILURE (status)) && - (status != AE_ALREADY_EXISTS)) { - return_ACPI_STATUS (status); - } + /* These exceptions are all OK */ - status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node, - ACPI_ADR_SPACE_PCI_CONFIG, - ACPI_DEFAULT_HANDLER, NULL, NULL); - if ((ACPI_FAILURE (status)) && - (status != AE_ALREADY_EXISTS)) { - return_ACPI_STATUS (status); - } + break; + + default: - status = acpi_install_address_space_handler ((acpi_handle) acpi_gbl_root_node, - ACPI_ADR_SPACE_DATA_TABLE, - ACPI_DEFAULT_HANDLER, NULL, NULL); - if ((ACPI_FAILURE (status)) && - (status != AE_ALREADY_EXISTS)) { - return_ACPI_STATUS (status); + return_ACPI_STATUS (status); + } } return_ACPI_STATUS (AE_OK); @@ -161,10 +159,10 @@ acpi_ev_execute_reg_method ( } /* - * _REG method has two arguments - * Arg0: Integer: Operation region space ID + * _REG method has two arguments + * Arg0: Integer: Operation region space ID * Same value as region_obj->Region.space_id - * Arg1: Integer: connection status + * Arg1: Integer: connection status * 1 for connecting the handler, * 0 for disconnecting the handler * Passed as a parameter @@ -180,16 +178,14 @@ acpi_ev_execute_reg_method ( goto cleanup; } - /* - * Set up the parameter objects - */ + /* Set up the parameter objects */ + params[0]->integer.value = region_obj->region.space_id; params[1]->integer.value = function; params[2] = NULL; - /* - * Execute the method, no return value - */ + /* Execute the method, no return value */ + ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname (ACPI_TYPE_METHOD, region_obj2->extra.method_REG, NULL)); status = acpi_ns_evaluate_by_handle (region_obj2->extra.method_REG, params, NULL); @@ -245,10 +241,9 @@ acpi_ev_address_space_dispatch ( return_ACPI_STATUS (AE_NOT_EXIST); } - /* - * Ensure that there is a handler associated with this region - */ - handler_desc = region_obj->region.addr_handler; + /* Ensure that there is a handler associated with this region */ + + handler_desc = region_obj->region.address_space; if (!handler_desc) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "no handler for region(%p) [%s]\n", region_obj, acpi_ut_get_region_name (region_obj->region.space_id))); @@ -264,24 +259,23 @@ acpi_ev_address_space_dispatch ( /* * This region has not been initialized yet, do it */ - region_setup = handler_desc->addr_handler.setup; + region_setup = handler_desc->address_space.setup; if (!region_setup) { - /* - * Bad news, no init routine and not init'd - */ + /* No initialization routine, exit with error */ + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "No init routine for region(%p) [%s]\n", region_obj, acpi_ut_get_region_name (region_obj->region.space_id))); - return_ACPI_STATUS (AE_UNKNOWN_STATUS); + return_ACPI_STATUS (AE_NOT_EXIST); } /* * We must exit the interpreter because the region setup will potentially - * execute control methods + * execute control methods (e.g., _REG method for this region) */ acpi_ex_exit_interpreter (); status = region_setup (region_obj, ACPI_REGION_ACTIVATE, - handler_desc->addr_handler.context, ®ion_context); + handler_desc->address_space.context, ®ion_context); /* Re-enter the interpreter */ @@ -290,9 +284,8 @@ acpi_ev_address_space_dispatch ( return_ACPI_STATUS (status2); } - /* - * Init routine may fail - */ + /* Check for failure of the Region Setup */ + if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Region Init: %s [%s]\n", acpi_format_exception (status), @@ -300,40 +293,50 @@ acpi_ev_address_space_dispatch ( return_ACPI_STATUS (status); } - region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; - /* - * Save the returned context for use in all accesses to - * this particular region. + * Region initialization may have been completed by region_setup */ - region_obj2->extra.region_context = region_context; + if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) { + region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE; + + if (region_obj2->extra.region_context) { + /* The handler for this region was already installed */ + + ACPI_MEM_FREE (region_context); + } + else { + /* + * Save the returned context for use in all accesses to + * this particular region + */ + region_obj2->extra.region_context = region_context; + } + } } - /* - * We have everything we need, begin the process - */ - handler = handler_desc->addr_handler.handler; + /* We have everything we need, we can invoke the address space handler */ + + handler = handler_desc->address_space.handler; ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Handler %p (@%p) Address %8.8X%8.8X [%s]\n", - ®ion_obj->region.addr_handler->addr_handler, handler, + ®ion_obj->region.address_space->address_space, handler, ACPI_HIDWORD (address), ACPI_LODWORD (address), acpi_ut_get_region_name (region_obj->region.space_id))); - if (!(handler_desc->addr_handler.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { + if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* - * For handlers other than the default (supplied) handlers, we must - * exit the interpreter because the handler *might* block -- we don't - * know what it will do, so we can't hold the lock on the intepreter. + * For handlers other than the default (supplied) handlers, we must + * exit the interpreter because the handler *might* block -- we don't + * know what it will do, so we can't hold the lock on the intepreter. */ acpi_ex_exit_interpreter(); } - /* - * Invoke the handler. - */ + /* Call the handler */ + status = handler (function, address, bit_width, value, - handler_desc->addr_handler.context, + handler_desc->address_space.context, region_obj2->extra.region_context); if (ACPI_FAILURE (status)) { @@ -342,7 +345,7 @@ acpi_ev_address_space_dispatch ( acpi_format_exception (status))); } - if (!(handler_desc->addr_handler.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { + if (!(handler_desc->address_space.flags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { /* * We just returned from a non-default handler, we must re-enter the * interpreter @@ -393,35 +396,30 @@ acpi_ev_detach_region( } region_context = region_obj2->extra.region_context; - /* - * Get the address handler from the region object - */ - handler_obj = region_obj->region.addr_handler; + /* Get the address handler from the region object */ + + handler_obj = region_obj->region.address_space; if (!handler_obj) { - /* - * This region has no handler, all done - */ + /* This region has no handler, all done */ + return_VOID; } + /* Find this region in the handler's list */ - /* - * Find this region in the handler's list - */ - obj_desc = handler_obj->addr_handler.region_list; - last_obj_ptr = &handler_obj->addr_handler.region_list; + obj_desc = handler_obj->address_space.region_list; + last_obj_ptr = &handler_obj->address_space.region_list; while (obj_desc) { - /* - * See if this is the one - */ + /* Is this the correct Region? */ + if (obj_desc == region_obj) { ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Removing Region %p from address handler %p\n", region_obj, handler_obj)); - /* - * This is it, remove it from the handler's list - */ + + /* This is it, remove it from the handler's list */ + *last_obj_ptr = obj_desc->region.next; obj_desc->region.next = NULL; /* Must clear field */ @@ -432,9 +430,8 @@ acpi_ev_detach_region( } } - /* - * Now stop region accesses by executing the _REG method - */ + /* Now stop region accesses by executing the _REG method */ + status = acpi_ev_execute_reg_method (region_obj, 0); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region _REG, [%s]\n", @@ -449,16 +446,14 @@ acpi_ev_detach_region( } } - /* - * Call the setup handler with the deactivate notification - */ - region_setup = handler_obj->addr_handler.setup; + /* Call the setup handler with the deactivate notification */ + + region_setup = handler_obj->address_space.setup; status = region_setup (region_obj, ACPI_REGION_DEACTIVATE, - handler_obj->addr_handler.context, ®ion_context); + handler_obj->address_space.context, ®ion_context); + + /* Init routine may fail, Just ignore errors */ - /* - * Init routine may fail, Just ignore errors - */ if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s from region init, [%s]\n", acpi_format_exception (status), @@ -468,31 +463,29 @@ acpi_ev_detach_region( region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE); /* - * Remove handler reference in the region + * Remove handler reference in the region * - * NOTE: this doesn't mean that the region goes away - * The region is just inaccessible as indicated to - * the _REG method + * NOTE: this doesn't mean that the region goes away + * The region is just inaccessible as indicated to + * the _REG method * - * If the region is on the handler's list - * this better be the region's handler + * If the region is on the handler's list + * this better be the region's handler */ - region_obj->region.addr_handler = NULL; + region_obj->region.address_space = NULL; + acpi_ut_remove_reference (handler_obj); return_VOID; + } - } /* found the right handler */ + /* Walk the linked list of handlers */ - /* - * Move through the linked list of handlers - */ last_obj_ptr = &obj_desc->region.next; obj_desc = obj_desc->region.next; } - /* - * If we get here, the region was not in the handler's region list - */ + /* If we get here, the region was not in the handler's region list */ + ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Cannot remove region %p from address handler %p\n", region_obj, handler_obj)); @@ -534,16 +527,19 @@ acpi_ev_attach_region ( region_obj, handler_obj, acpi_ut_get_region_name (region_obj->region.space_id))); - /* - * Link this region to the front of the handler's list - */ - region_obj->region.next = handler_obj->addr_handler.region_list; - handler_obj->addr_handler.region_list = region_obj; + /* Link this region to the front of the handler's list */ - /* - * Set the region's handler - */ - region_obj->region.addr_handler = handler_obj; + region_obj->region.next = handler_obj->address_space.region_list; + handler_obj->address_space.region_list = region_obj; + + /* Install the region's handler */ + + if (region_obj->region.address_space) { + return_ACPI_STATUS (AE_ALREADY_EXISTS); + } + + region_obj->region.address_space = handler_obj; + acpi_ut_add_reference (handler_obj); /* * Tell all users that this region is usable by running the _REG @@ -571,14 +567,14 @@ acpi_ev_attach_region ( /******************************************************************************* * - * FUNCTION: acpi_ev_addr_handler_helper + * FUNCTION: acpi_ev_install_handler * * PARAMETERS: Handle - Node to be dumped * Level - Nesting level of the handle * Context - Passed into acpi_ns_walk_namespace * * DESCRIPTION: This routine installs an address handler into objects that are - * of type Region. + * of type Region or Device. * * If the Object is a Device, and the device has a handler of * the same type then the search is terminated in that branch. @@ -589,20 +585,20 @@ acpi_ev_attach_region ( ******************************************************************************/ acpi_status -acpi_ev_addr_handler_helper ( +acpi_ev_install_handler ( acpi_handle obj_handle, u32 level, void *context, void **return_value) { union acpi_operand_object *handler_obj; - union acpi_operand_object *tmp_obj; + union acpi_operand_object *next_handler_obj; union acpi_operand_object *obj_desc; struct acpi_namespace_node *node; acpi_status status; - ACPI_FUNCTION_NAME ("ev_addr_handler_helper"); + ACPI_FUNCTION_NAME ("ev_install_handler"); handler_obj = (union acpi_operand_object *) context; @@ -621,8 +617,8 @@ acpi_ev_addr_handler_helper ( } /* - * We only care about regions.and objects - * that can have address handlers + * We only care about regions.and objects + * that are allowed to have address space handlers */ if ((node->type != ACPI_TYPE_DEVICE) && (node->type != ACPI_TYPE_REGION) && @@ -634,81 +630,70 @@ acpi_ev_addr_handler_helper ( obj_desc = acpi_ns_get_attached_object (node); if (!obj_desc) { - /* - * The object DNE, we don't care about it - */ + /* No object, just exit */ + return (AE_OK); } - /* - * Devices are handled different than regions - */ + /* Devices are handled different than regions */ + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_DEVICE) { - /* - * See if this guy has any handlers - */ - tmp_obj = obj_desc->device.addr_handler; - while (tmp_obj) { - /* - * Now let's see if it's for the same address space. - */ - if (tmp_obj->addr_handler.space_id == handler_obj->addr_handler.space_id) { - /* - * It's for the same address space - */ + /* Check if this Device already has a handler for this address space */ + + next_handler_obj = obj_desc->device.address_space; + while (next_handler_obj) { + /* Found a handler, is it for the same address space? */ + + if (next_handler_obj->address_space.space_id == handler_obj->address_space.space_id) { ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "Found handler for region [%s] in device %p(%p) handler %p\n", - acpi_ut_get_region_name (handler_obj->addr_handler.space_id), - obj_desc, tmp_obj, handler_obj)); + acpi_ut_get_region_name (handler_obj->address_space.space_id), + obj_desc, next_handler_obj, handler_obj)); /* - * Since the object we found it on was a device, then it - * means that someone has already installed a handler for - * the branch of the namespace from this device on. Just - * bail out telling the walk routine to not traverse this - * branch. This preserves the scoping rule for handlers. + * Since the object we found it on was a device, then it + * means that someone has already installed a handler for + * the branch of the namespace from this device on. Just + * bail out telling the walk routine to not traverse this + * branch. This preserves the scoping rule for handlers. */ return (AE_CTRL_DEPTH); } - /* - * Move through the linked list of handlers - */ - tmp_obj = tmp_obj->addr_handler.next; + /* Walk the linked list of handlers attached to this device */ + + next_handler_obj = next_handler_obj->address_space.next; } /* - * As long as the device didn't have a handler for this - * space we don't care about it. We just ignore it and - * proceed. + * As long as the device didn't have a handler for this + * space we don't care about it. We just ignore it and + * proceed. */ return (AE_OK); } - /* - * Only here if it was a region - */ - if (obj_desc->region.space_id != handler_obj->addr_handler.space_id) { + /* Object is a Region */ + + if (obj_desc->region.space_id != handler_obj->address_space.space_id) { /* - * This region is for a different address space - * ignore it + * This region is for a different address space + * -- just ignore it */ return (AE_OK); } /* - * Now we have a region and it is for the handler's address - * space type. + * Now we have a region and it is for the handler's address + * space type. * - * First disconnect region for any previous handler (if any) + * First disconnect region for any previous handler (if any) */ acpi_ev_detach_region (obj_desc, FALSE); - /* - * Then connect the region to the new handler - */ - status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE); + /* Connect the region to the new handler */ + status = acpi_ev_attach_region (handler_obj, obj_desc, FALSE); return (status); } diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index 30391790f5390743dfd2091f3fa66608f313cfd2..dcc633fd65c98fbfe2382788b128103a2d61eb17 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c @@ -165,10 +165,11 @@ acpi_ev_pci_config_region_setup ( void **region_context) { acpi_status status = AE_OK; - acpi_integer temp; + acpi_integer pci_value; struct acpi_pci_id *pci_id = *region_context; union acpi_operand_object *handler_obj; - struct acpi_namespace_node *node; + struct acpi_namespace_node *parent_node; + struct acpi_namespace_node *pci_root_node; union acpi_operand_object *region_obj = (union acpi_operand_object *) handle; struct acpi_device_id object_hID; @@ -176,7 +177,7 @@ acpi_ev_pci_config_region_setup ( ACPI_FUNCTION_TRACE ("ev_pci_config_region_setup"); - handler_obj = region_obj->region.addr_handler; + handler_obj = region_obj->region.address_space; if (!handler_obj) { /* * No installed handler. This shouldn't happen because the dispatch @@ -187,45 +188,15 @@ acpi_ev_pci_config_region_setup ( return_ACPI_STATUS (AE_NOT_EXIST); } + *region_context = NULL; if (function == ACPI_REGION_DEACTIVATE) { if (pci_id) { ACPI_MEM_FREE (pci_id); - *region_context = NULL; } - return_ACPI_STATUS (status); } - /* Create a new context */ - - pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id)); - if (!pci_id) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - /* - * For PCI Config space access, we have to pass the segment, bus, - * device and function numbers. This routine must acquire those. - */ - - /* - * First get device and function numbers from the _ADR object - * in the parent's scope. - */ - node = acpi_ns_get_parent_node (region_obj->region.node); - - /* Evaluate the _ADR object */ - - status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node, &temp); - - /* - * The default is zero, and since the allocation above zeroed - * the data, just do nothing on failure. - */ - if (ACPI_SUCCESS (status)) { - pci_id->device = ACPI_HIWORD (ACPI_LODWORD (temp)); - pci_id->function = ACPI_LOWORD (ACPI_LODWORD (temp)); - } + parent_node = acpi_ns_get_parent_node (region_obj->region.node); /* * Get the _SEG and _BBN values from the device upon which the handler @@ -236,61 +207,106 @@ acpi_ev_pci_config_region_setup ( */ /* - * If the addr_handler.Node is still pointing to the root, we need + * If the address_space.Node is still pointing to the root, we need * to scan upward for a PCI Root bridge and re-associate the op_region * handlers with that device. */ - if (handler_obj->addr_handler.node == acpi_gbl_root_node) { - /* - * Node is currently the parent object - */ - while (node != acpi_gbl_root_node) { - status = acpi_ut_execute_HID (node, &object_hID); + if (handler_obj->address_space.node == acpi_gbl_root_node) { + /* Start search from the parent object */ + + pci_root_node = parent_node; + while (pci_root_node != acpi_gbl_root_node) { + status = acpi_ut_execute_HID (pci_root_node, &object_hID); if (ACPI_SUCCESS (status)) { /* Got a valid _HID, check if this is a PCI root */ - if (!(ACPI_STRNCMP (object_hID.buffer, PCI_ROOT_HID_STRING, + if (!(ACPI_STRNCMP (object_hID.value, PCI_ROOT_HID_STRING, sizeof (PCI_ROOT_HID_STRING)))) { /* Install a handler for this PCI root bridge */ - status = acpi_install_address_space_handler ((acpi_handle) node, + status = acpi_install_address_space_handler ((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL); if (ACPI_FAILURE (status)) { - ACPI_REPORT_ERROR (("Could not install pci_config handler for %4.4s, %s\n", - node->name.ascii, acpi_format_exception (status))); + if (status == AE_SAME_HANDLER) { + /* + * It is OK if the handler is already installed on the root + * bridge. Still need to return a context object for the + * new PCI_Config operation region, however. + */ + status = AE_OK; + } + else { + ACPI_REPORT_ERROR (( + "Could not install pci_config handler for Root Bridge %4.4s, %s\n", + pci_root_node->name.ascii, acpi_format_exception (status))); + } } break; } } - node = acpi_ns_get_parent_node (node); + pci_root_node = acpi_ns_get_parent_node (pci_root_node); } + + /* PCI root bridge not found, use namespace root node */ } else { - node = handler_obj->addr_handler.node; + pci_root_node = handler_obj->address_space.node; } /* - * The PCI segment number comes from the _SEG method + * If this region is now initialized, we are done. + * (install_address_space_handler could have initialized it) */ - status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, node, &temp); - if (ACPI_SUCCESS (status)) { - pci_id->segment = ACPI_LOWORD (temp); + if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) { + return_ACPI_STATUS (AE_OK); + } + + /* Region is still not initialized. Create a new context */ + + pci_id = ACPI_MEM_CALLOCATE (sizeof (struct acpi_pci_id)); + if (!pci_id) { + return_ACPI_STATUS (AE_NO_MEMORY); } /* - * The PCI bus number comes from the _BBN method + * For PCI_Config space access, we need the segment, bus, + * device and function numbers. Acquire them here. */ - status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, node, &temp); - if (ACPI_SUCCESS (status)) { - pci_id->bus = ACPI_LOWORD (temp); - } /* - * Complete this device's pci_id + * Get the PCI device and function numbers from the _ADR object + * contained in the parent's scope. */ - acpi_os_derive_pci_id (node, region_obj->region.node, &pci_id); + status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, parent_node, &pci_value); + + /* + * The default is zero, and since the allocation above zeroed + * the data, just do nothing on failure. + */ + if (ACPI_SUCCESS (status)) { + pci_id->device = ACPI_HIWORD (ACPI_LODWORD (pci_value)); + pci_id->function = ACPI_LOWORD (ACPI_LODWORD (pci_value)); + } + + /* The PCI segment number comes from the _SEG method */ + + status = acpi_ut_evaluate_numeric_object (METHOD_NAME__SEG, pci_root_node, &pci_value); + if (ACPI_SUCCESS (status)) { + pci_id->segment = ACPI_LOWORD (pci_value); + } + + /* The PCI bus number comes from the _BBN method */ + + status = acpi_ut_evaluate_numeric_object (METHOD_NAME__BBN, pci_root_node, &pci_value); + if (ACPI_SUCCESS (status)) { + pci_id->bus = ACPI_LOWORD (pci_value); + } + + /* Complete this device's pci_id */ + + acpi_os_derive_pci_id (pci_root_node, region_obj->region.node, &pci_id); *region_context = pci_id; return_ACPI_STATUS (AE_OK); @@ -451,14 +467,15 @@ acpi_ev_initialize_region ( node = acpi_ns_get_parent_node (region_obj->region.node); space_id = region_obj->region.space_id; - region_obj->region.addr_handler = NULL; + /* Setup defaults */ + + region_obj->region.address_space = NULL; region_obj2->extra.method_REG = NULL; region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE); region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED; - /* - * Find any "_REG" method associated with this region definition - */ + /* Find any "_REG" method associated with this region definition */ + status = acpi_ns_search_node (*reg_name_ptr, node, ACPI_TYPE_METHOD, &method_node); if (ACPI_SUCCESS (status)) { @@ -475,29 +492,27 @@ acpi_ev_initialize_region ( * ie: acpi_gbl_root_node->parent_entry being set to NULL */ while (node) { - /* - * Check to see if a handler exists - */ + /* Check to see if a handler exists */ + handler_obj = NULL; obj_desc = acpi_ns_get_attached_object (node); if (obj_desc) { - /* - * Can only be a handler if the object exists - */ + /* Can only be a handler if the object exists */ + switch (node->type) { case ACPI_TYPE_DEVICE: - handler_obj = obj_desc->device.addr_handler; + handler_obj = obj_desc->device.address_space; break; case ACPI_TYPE_PROCESSOR: - handler_obj = obj_desc->processor.addr_handler; + handler_obj = obj_desc->processor.address_space; break; case ACPI_TYPE_THERMAL: - handler_obj = obj_desc->thermal_zone.addr_handler; + handler_obj = obj_desc->thermal_zone.address_space; break; default: @@ -508,7 +523,7 @@ acpi_ev_initialize_region ( while (handler_obj) { /* Is this handler of the correct type? */ - if (handler_obj->addr_handler.space_id == space_id) { + if (handler_obj->address_space.space_id == space_id) { /* Found correct handler */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, @@ -523,7 +538,7 @@ acpi_ev_initialize_region ( /* Try next handler in the list */ - handler_obj = handler_obj->addr_handler.next; + handler_obj = handler_obj->address_space.next; } } @@ -534,9 +549,8 @@ acpi_ev_initialize_region ( node = acpi_ns_get_parent_node (node); } - /* - * If we get here, there is no handler for this region - */ + /* If we get here, there is no handler for this region */ + ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, "No handler for region_type %s(%X) (region_obj %p)\n", acpi_ut_get_region_name (space_id), space_id, region_obj)); diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c index 18b04571acf2da2aa4ccdc8ead88bce146828d88..e9a289a52d36e5309d0dffae5a30f305467411aa 100644 --- a/drivers/acpi/events/evxface.c +++ b/drivers/acpi/events/evxface.c @@ -244,22 +244,22 @@ acpi_install_notify_handler ( /* Make sure the handler is not already installed */ if (((handler_type == ACPI_SYSTEM_NOTIFY) && - acpi_gbl_sys_notify.handler) || + acpi_gbl_system_notify.handler) || ((handler_type == ACPI_DEVICE_NOTIFY) && - acpi_gbl_drv_notify.handler)) { + acpi_gbl_device_notify.handler)) { status = AE_ALREADY_EXISTS; goto unlock_and_exit; } if (handler_type == ACPI_SYSTEM_NOTIFY) { - acpi_gbl_sys_notify.node = node; - acpi_gbl_sys_notify.handler = handler; - acpi_gbl_sys_notify.context = context; + acpi_gbl_system_notify.node = node; + acpi_gbl_system_notify.handler = handler; + acpi_gbl_system_notify.context = context; } else /* ACPI_DEVICE_NOTIFY */ { - acpi_gbl_drv_notify.node = node; - acpi_gbl_drv_notify.handler = handler; - acpi_gbl_drv_notify.context = context; + acpi_gbl_device_notify.node = node; + acpi_gbl_device_notify.handler = handler; + acpi_gbl_device_notify.context = context; } /* Global notify handler installed */ @@ -282,13 +282,12 @@ acpi_install_notify_handler ( obj_desc = acpi_ns_get_attached_object (node); if (obj_desc) { - /* Object exists - make sure there's no handler */ if (((handler_type == ACPI_SYSTEM_NOTIFY) && - obj_desc->common_notify.sys_handler) || + obj_desc->common_notify.system_notify) || ((handler_type == ACPI_DEVICE_NOTIFY) && - obj_desc->common_notify.drv_handler)) { + obj_desc->common_notify.device_notify)) { status = AE_ALREADY_EXISTS; goto unlock_and_exit; } @@ -305,6 +304,11 @@ acpi_install_notify_handler ( /* Attach new object to the Node */ status = acpi_ns_attach_object (device, obj_desc, node->type); + + /* Remove local reference to the object */ + + acpi_ut_remove_reference (obj_desc); + if (ACPI_FAILURE (status)) { goto unlock_and_exit; } @@ -318,15 +322,15 @@ acpi_install_notify_handler ( goto unlock_and_exit; } - notify_obj->notify_handler.node = node; - notify_obj->notify_handler.handler = handler; - notify_obj->notify_handler.context = context; + notify_obj->notify.node = node; + notify_obj->notify.handler = handler; + notify_obj->notify.context = context; if (handler_type == ACPI_SYSTEM_NOTIFY) { - obj_desc->common_notify.sys_handler = notify_obj; + obj_desc->common_notify.system_notify = notify_obj; } else /* ACPI_DEVICE_NOTIFY */ { - obj_desc->common_notify.drv_handler = notify_obj; + obj_desc->common_notify.device_notify = notify_obj; } } @@ -395,22 +399,22 @@ acpi_remove_notify_handler ( ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n")); if (((handler_type == ACPI_SYSTEM_NOTIFY) && - !acpi_gbl_sys_notify.handler) || + !acpi_gbl_system_notify.handler) || ((handler_type == ACPI_DEVICE_NOTIFY) && - !acpi_gbl_drv_notify.handler)) { + !acpi_gbl_device_notify.handler)) { status = AE_NOT_EXIST; goto unlock_and_exit; } if (handler_type == ACPI_SYSTEM_NOTIFY) { - acpi_gbl_sys_notify.node = NULL; - acpi_gbl_sys_notify.handler = NULL; - acpi_gbl_sys_notify.context = NULL; + acpi_gbl_system_notify.node = NULL; + acpi_gbl_system_notify.handler = NULL; + acpi_gbl_system_notify.context = NULL; } else { - acpi_gbl_drv_notify.node = NULL; - acpi_gbl_drv_notify.handler = NULL; - acpi_gbl_drv_notify.context = NULL; + acpi_gbl_device_notify.node = NULL; + acpi_gbl_device_notify.handler = NULL; + acpi_gbl_device_notify.context = NULL; } } @@ -436,14 +440,14 @@ acpi_remove_notify_handler ( /* Object exists - make sure there's an existing handler */ if (handler_type == ACPI_SYSTEM_NOTIFY) { - notify_obj = obj_desc->common_notify.sys_handler; + notify_obj = obj_desc->common_notify.system_notify; } else { - notify_obj = obj_desc->common_notify.drv_handler; + notify_obj = obj_desc->common_notify.device_notify; } if ((!notify_obj) || - (notify_obj->notify_handler.handler != handler)) { + (notify_obj->notify.handler != handler)) { status = AE_BAD_PARAMETER; goto unlock_and_exit; } @@ -451,10 +455,10 @@ acpi_remove_notify_handler ( /* Remove the handler */ if (handler_type == ACPI_SYSTEM_NOTIFY) { - obj_desc->common_notify.sys_handler = NULL; + obj_desc->common_notify.system_notify = NULL; } else { - obj_desc->common_notify.drv_handler = NULL; + obj_desc->common_notify.device_notify = NULL; } acpi_ut_remove_reference (notify_obj); diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 89122dfc72a14397f5284b683c3c92cacd7f371e..6eda92f06f7b9105989656006969439c003abf7c 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c @@ -654,7 +654,11 @@ acpi_install_gpe_block ( } status = acpi_ns_attach_object (node, obj_desc, ACPI_TYPE_DEVICE); + + /* Remove local reference to the object */ + acpi_ut_remove_reference (obj_desc); + if (ACPI_FAILURE (status)) { goto unlock_and_exit; } diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c index 79d0c5a3fe334d6ca8eb77717fecf30e2b8c278a..44fa3c9ef872197ca6612ab8995bfb786fc9ba46 100644 --- a/drivers/acpi/events/evxfregn.c +++ b/drivers/acpi/events/evxfregn.c @@ -154,7 +154,7 @@ acpi_install_address_space_handler ( break; default: - status = AE_NOT_EXIST; + status = AE_BAD_PARAMETER; goto unlock_and_exit; } } @@ -170,26 +170,36 @@ acpi_install_address_space_handler ( obj_desc = acpi_ns_get_attached_object (node); if (obj_desc) { /* - * The object exists. + * The attached device object already exists. * Make sure the handler is not already installed. */ + handler_obj = obj_desc->device.address_space; - /* check the address handler the user requested */ + /* Walk the handler list for this device */ - handler_obj = obj_desc->device.addr_handler; while (handler_obj) { - /* - * Found an Address handler, see if user requested this - * address space. - */ - if(handler_obj->addr_handler.space_id == space_id) { - status = AE_ALREADY_EXISTS; + /* Same space_id indicates a handler already installed */ + + if(handler_obj->address_space.space_id == space_id) { + if (handler_obj->address_space.handler == handler) { + /* + * It is (relatively) OK to attempt to install the SAME + * handler twice. This can easily happen with PCI_Config space. + */ + status = AE_SAME_HANDLER; + goto unlock_and_exit; + } + else { + /* A handler is already installed */ + + status = AE_ALREADY_EXISTS; + } goto unlock_and_exit; } /* Walk the linked list of handlers */ - handler_obj = handler_obj->addr_handler.next; + handler_obj = handler_obj->address_space.next; } } else { @@ -218,8 +228,12 @@ acpi_install_address_space_handler ( /* Attach the new object to the Node */ status = acpi_ns_attach_object (node, obj_desc, type); + + /* Remove local reference to the object */ + + acpi_ut_remove_reference (obj_desc); + if (ACPI_FAILURE (status)) { - acpi_ut_remove_reference (obj_desc); goto unlock_and_exit; } } @@ -241,14 +255,25 @@ acpi_install_address_space_handler ( goto unlock_and_exit; } - handler_obj->addr_handler.space_id = (u8) space_id; - handler_obj->addr_handler.hflags = flags; - handler_obj->addr_handler.next = obj_desc->device.addr_handler; - handler_obj->addr_handler.region_list = NULL; - handler_obj->addr_handler.node = node; - handler_obj->addr_handler.handler = handler; - handler_obj->addr_handler.context = context; - handler_obj->addr_handler.setup = setup; + /* Init handler obj */ + + handler_obj->address_space.space_id = (u8) space_id; + handler_obj->address_space.hflags = flags; + handler_obj->address_space.region_list = NULL; + handler_obj->address_space.node = node; + handler_obj->address_space.handler = handler; + handler_obj->address_space.context = context; + handler_obj->address_space.setup = setup; + + /* Install at head of Device.address_space list */ + + handler_obj->address_space.next = obj_desc->device.address_space; + + /* + * The Device object is the first reference on the handler_obj. + * Each region that uses the handler adds a reference. + */ + obj_desc->device.address_space = handler_obj; /* * Walk the namespace finding all of the regions this @@ -262,18 +287,9 @@ acpi_install_address_space_handler ( * In either case, back up and search down the remainder * of the branch */ - status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, - ACPI_UINT32_MAX, ACPI_NS_WALK_UNLOCK, - acpi_ev_addr_handler_helper, - handler_obj, NULL); - - /* Place this handler 1st on the list */ - - handler_obj->common.reference_count = - (u16) (handler_obj->common.reference_count + - obj_desc->common.reference_count - 1); - obj_desc->device.addr_handler = handler_obj; - + status = acpi_ns_walk_namespace (ACPI_TYPE_ANY, device, ACPI_UINT32_MAX, + ACPI_NS_WALK_UNLOCK, acpi_ev_install_handler, + handler_obj, NULL); unlock_and_exit: (void) acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); @@ -341,12 +357,12 @@ acpi_remove_address_space_handler ( /* Find the address handler the user requested */ - handler_obj = obj_desc->device.addr_handler; - last_obj_ptr = &obj_desc->device.addr_handler; + handler_obj = obj_desc->device.address_space; + last_obj_ptr = &obj_desc->device.address_space; while (handler_obj) { /* We have a handler, see if user requested this one */ - if (handler_obj->addr_handler.space_id == space_id) { + if (handler_obj->address_space.space_id == space_id) { /* Matched space_id, first dereference this in the Regions */ ACPI_DEBUG_PRINT ((ACPI_DB_OPREGION, @@ -354,7 +370,7 @@ acpi_remove_address_space_handler ( handler_obj, handler, acpi_ut_get_region_name (space_id), node, obj_desc)); - region_obj = handler_obj->addr_handler.region_list; + region_obj = handler_obj->address_space.region_list; /* Walk the handler's region list */ @@ -372,13 +388,13 @@ acpi_remove_address_space_handler ( * Walk the list: Just grab the head because the * detach_region removed the previous head. */ - region_obj = handler_obj->addr_handler.region_list; + region_obj = handler_obj->address_space.region_list; } /* Remove this Handler object from the list */ - *last_obj_ptr = handler_obj->addr_handler.next; + *last_obj_ptr = handler_obj->address_space.next; /* Now we can delete the handler object */ @@ -388,8 +404,8 @@ acpi_remove_address_space_handler ( /* Walk the linked list of handlers */ - last_obj_ptr = &handler_obj->addr_handler.next; - handler_obj = handler_obj->addr_handler.next; + last_obj_ptr = &handler_obj->address_space.next; + handler_obj = handler_obj->address_space.next; } /* The handler does not exist */ diff --git a/drivers/acpi/executer/exconfig.c b/drivers/acpi/executer/exconfig.c index d7764149b8947571bf8d05062d00e2af5591c6c6..d6ae105579c8ee1fffc468d7bfb3365c4c771009 100644 --- a/drivers/acpi/executer/exconfig.c +++ b/drivers/acpi/executer/exconfig.c @@ -360,11 +360,11 @@ acpi_ex_load_op ( /* The table must be either an SSDT or a PSDT */ if ((!ACPI_STRNCMP (table_ptr->signature, - acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].signature, - acpi_gbl_acpi_table_data[ACPI_TABLE_PSDT].sig_length)) && + acpi_gbl_table_data[ACPI_TABLE_PSDT].signature, + acpi_gbl_table_data[ACPI_TABLE_PSDT].sig_length)) && (!ACPI_STRNCMP (table_ptr->signature, - acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].signature, - acpi_gbl_acpi_table_data[ACPI_TABLE_SSDT].sig_length))) { + acpi_gbl_table_data[ACPI_TABLE_SSDT].signature, + acpi_gbl_table_data[ACPI_TABLE_SSDT].sig_length))) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Table has invalid signature [%4.4s], must be SSDT or PSDT\n", table_ptr->signature)); diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c index 5d63a6383ebf81feb62c64e4f1579fc4a061c96e..6617a4374004ff17531308a21360f259c3c5fe24 100644 --- a/drivers/acpi/executer/exdump.c +++ b/drivers/acpi/executer/exdump.c @@ -635,9 +635,9 @@ acpi_ex_dump_object_descriptor ( case ACPI_TYPE_DEVICE: - acpi_ex_out_pointer ("addr_handler", obj_desc->device.addr_handler); - acpi_ex_out_pointer ("sys_handler", obj_desc->device.sys_handler); - acpi_ex_out_pointer ("drv_handler", obj_desc->device.drv_handler); + acpi_ex_out_pointer ("address_space", obj_desc->device.address_space); + acpi_ex_out_pointer ("system_notify", obj_desc->device.system_notify); + acpi_ex_out_pointer ("device_notify", obj_desc->device.device_notify); break; @@ -673,7 +673,7 @@ acpi_ex_dump_object_descriptor ( acpi_ex_out_integer ("Flags", obj_desc->region.flags); acpi_ex_out_address ("Address", obj_desc->region.address); acpi_ex_out_integer ("Length", obj_desc->region.length); - acpi_ex_out_pointer ("addr_handler", obj_desc->region.addr_handler); + acpi_ex_out_pointer ("address_space", obj_desc->region.address_space); acpi_ex_out_pointer ("Next", obj_desc->region.next); break; @@ -682,8 +682,8 @@ acpi_ex_dump_object_descriptor ( acpi_ex_out_integer ("system_level", obj_desc->power_resource.system_level); acpi_ex_out_integer ("resource_order", obj_desc->power_resource.resource_order); - acpi_ex_out_pointer ("sys_handler", obj_desc->power_resource.sys_handler); - acpi_ex_out_pointer ("drv_handler", obj_desc->power_resource.drv_handler); + acpi_ex_out_pointer ("system_notify", obj_desc->power_resource.system_notify); + acpi_ex_out_pointer ("device_notify", obj_desc->power_resource.device_notify); break; @@ -692,17 +692,17 @@ acpi_ex_dump_object_descriptor ( acpi_ex_out_integer ("Processor ID", obj_desc->processor.proc_id); acpi_ex_out_integer ("Length", obj_desc->processor.length); acpi_ex_out_address ("Address", (acpi_physical_address) obj_desc->processor.address); - acpi_ex_out_pointer ("sys_handler", obj_desc->processor.sys_handler); - acpi_ex_out_pointer ("drv_handler", obj_desc->processor.drv_handler); - acpi_ex_out_pointer ("addr_handler", obj_desc->processor.addr_handler); + acpi_ex_out_pointer ("system_notify", obj_desc->processor.system_notify); + acpi_ex_out_pointer ("device_notify", obj_desc->processor.device_notify); + acpi_ex_out_pointer ("address_space", obj_desc->processor.address_space); break; case ACPI_TYPE_THERMAL: - acpi_ex_out_pointer ("sys_handler", obj_desc->thermal_zone.sys_handler); - acpi_ex_out_pointer ("drv_handler", obj_desc->thermal_zone.drv_handler); - acpi_ex_out_pointer ("addr_handler", obj_desc->thermal_zone.addr_handler); + acpi_ex_out_pointer ("system_notify", obj_desc->thermal_zone.system_notify); + acpi_ex_out_pointer ("device_notify", obj_desc->thermal_zone.device_notify); + acpi_ex_out_pointer ("address_space", obj_desc->thermal_zone.address_space); break; @@ -762,18 +762,18 @@ acpi_ex_dump_object_descriptor ( case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: - acpi_ex_out_integer ("space_id", obj_desc->addr_handler.space_id); - acpi_ex_out_pointer ("Next", obj_desc->addr_handler.next); - acpi_ex_out_pointer ("region_list", obj_desc->addr_handler.region_list); - acpi_ex_out_pointer ("Node", obj_desc->addr_handler.node); - acpi_ex_out_pointer ("Context", obj_desc->addr_handler.context); + acpi_ex_out_integer ("space_id", obj_desc->address_space.space_id); + acpi_ex_out_pointer ("Next", obj_desc->address_space.next); + acpi_ex_out_pointer ("region_list", obj_desc->address_space.region_list); + acpi_ex_out_pointer ("Node", obj_desc->address_space.node); + acpi_ex_out_pointer ("Context", obj_desc->address_space.context); break; case ACPI_TYPE_LOCAL_NOTIFY: - acpi_ex_out_pointer ("Node", obj_desc->notify_handler.node); - acpi_ex_out_pointer ("Context", obj_desc->notify_handler.context); + acpi_ex_out_pointer ("Node", obj_desc->notify.node); + acpi_ex_out_pointer ("Context", obj_desc->notify.context); break; diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c index d7fa0b5d9881e39564fd810c697f32955323b561..1ba86f79b853e73a8abd92a003f49fb57616f753 100644 --- a/drivers/acpi/hardware/hwgpe.c +++ b/drivers/acpi/hardware/hwgpe.c @@ -77,7 +77,7 @@ acpi_hw_enable_gpe ( * to enable the GPE, and write out the new register. */ status = acpi_hw_low_level_read (8, &in_byte, - &gpe_event_info->register_info->enable_address, 0); + &gpe_event_info->register_info->enable_address); if (ACPI_FAILURE (status)) { return (status); } @@ -85,7 +85,7 @@ acpi_hw_enable_gpe ( /* Write with the new GPE bit enabled */ status = acpi_hw_low_level_write (8, (in_byte | gpe_event_info->bit_mask), - &gpe_event_info->register_info->enable_address, 0); + &gpe_event_info->register_info->enable_address); return (status); } @@ -164,7 +164,7 @@ acpi_hw_disable_gpe ( * and write out the new register value to disable the GPE. */ status = acpi_hw_low_level_read (8, &in_byte, - &gpe_register_info->enable_address, 0); + &gpe_register_info->enable_address); if (ACPI_FAILURE (status)) { return (status); } @@ -172,7 +172,7 @@ acpi_hw_disable_gpe ( /* Write the byte with this GPE bit cleared */ status = acpi_hw_low_level_write (8, (in_byte & ~(gpe_event_info->bit_mask)), - &gpe_register_info->enable_address, 0); + &gpe_register_info->enable_address); if (ACPI_FAILURE (status)) { return (status); } @@ -246,7 +246,7 @@ acpi_hw_clear_gpe ( * clear this GPE. */ status = acpi_hw_low_level_write (8, gpe_event_info->bit_mask, - &gpe_event_info->register_info->status_address, 0); + &gpe_event_info->register_info->status_address); return (status); } @@ -293,7 +293,7 @@ acpi_hw_get_gpe_status ( /* GPE Enabled? */ - status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address, 0); + status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->enable_address); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } @@ -310,7 +310,7 @@ acpi_hw_get_gpe_status ( /* GPE active (set)? */ - status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address, 0); + status = acpi_hw_low_level_read (8, &in_byte, &gpe_register_info->status_address); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } @@ -360,7 +360,7 @@ acpi_hw_disable_gpe_block ( for (i = 0; i < gpe_block->register_count; i++) { status = acpi_hw_low_level_write (8, 0x00, - &gpe_block->register_info[i].enable_address, (u32) i); + &gpe_block->register_info[i].enable_address); if (ACPI_FAILURE (status)) { return (status); } @@ -401,7 +401,7 @@ acpi_hw_clear_gpe_block ( for (i = 0; i < gpe_block->register_count; i++) { status = acpi_hw_low_level_write (8, 0xFF, - &gpe_block->register_info[i].status_address, (u32) i); + &gpe_block->register_info[i].status_address); if (ACPI_FAILURE (status)) { return (status); } @@ -447,7 +447,7 @@ acpi_hw_disable_non_wakeup_gpe_block ( * will be using it to restore all the GPEs later. */ status = acpi_hw_low_level_read (8, &in_value, - &gpe_register_info->enable_address, 0); + &gpe_register_info->enable_address); if (ACPI_FAILURE (status)) { return (status); } @@ -458,7 +458,7 @@ acpi_hw_disable_non_wakeup_gpe_block ( * Disable all GPEs except wakeup GPEs. */ status = acpi_hw_low_level_write (8, gpe_register_info->wake_enable, - &gpe_register_info->enable_address, 0); + &gpe_register_info->enable_address); if (ACPI_FAILURE (status)) { return (status); } @@ -539,7 +539,7 @@ acpi_hw_enable_non_wakeup_gpe_block ( * Blast them back in. */ status = acpi_hw_low_level_write (8, gpe_register_info->enable, - &gpe_register_info->enable_address, 0); + &gpe_register_info->enable_address); if (ACPI_FAILURE (status)) { return (status); } diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index 638c7323f1190f2c88cee061fc1da4226fd8d867..25e05b1384431a2480540707c866514cc57efb01 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c @@ -93,7 +93,7 @@ acpi_hw_clear_acpi_status (void) if (acpi_gbl_FADT->xpm1b_evt_blk.address) { status = acpi_hw_low_level_write (16, ACPI_BITMASK_ALL_FIXED_STATUS, - &acpi_gbl_FADT->xpm1b_evt_blk, 0); + &acpi_gbl_FADT->xpm1b_evt_blk); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } @@ -470,7 +470,6 @@ acpi_hw_register_read ( { u32 value1 = 0; u32 value2 = 0; - u32 bank_offset; acpi_status status; @@ -487,50 +486,53 @@ acpi_hw_register_read ( switch (register_id) { case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ - status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk, 0); + status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } - status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk, 0); + /* PM1B is optional */ + + status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk); value1 |= value2; break; - case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access*/ + case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */ - bank_offset = ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len); - status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_evt_blk, bank_offset); + status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_xpm1a_enable); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } - status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_evt_blk, bank_offset); + /* PM1B is optional */ + + status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_xpm1b_enable); value1 |= value2; break; case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ - status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_cnt_blk, 0); + status = acpi_hw_low_level_read (16, &value1, &acpi_gbl_FADT->xpm1a_cnt_blk); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } - status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_cnt_blk, 0); + status = acpi_hw_low_level_read (16, &value2, &acpi_gbl_FADT->xpm1b_cnt_blk); value1 |= value2; break; case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ - status = acpi_hw_low_level_read (8, &value1, &acpi_gbl_FADT->xpm2_cnt_blk, 0); + status = acpi_hw_low_level_read (8, &value1, &acpi_gbl_FADT->xpm2_cnt_blk); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ - status = acpi_hw_low_level_read (32, &value1, &acpi_gbl_FADT->xpm_tmr_blk, 0); + status = acpi_hw_low_level_read (32, &value1, &acpi_gbl_FADT->xpm_tmr_blk); break; case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ @@ -577,7 +579,6 @@ acpi_hw_register_write ( u32 register_id, u32 value) { - u32 bank_offset; acpi_status status; @@ -594,59 +595,62 @@ acpi_hw_register_write ( switch (register_id) { case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */ - status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk, 0); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } - status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk, 0); + /* PM1B is optional */ + + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk); break; case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access*/ - bank_offset = ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len); - status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_evt_blk, bank_offset); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1a_enable); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } - status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_evt_blk, bank_offset); + /* PM1B is optional */ + + status = acpi_hw_low_level_write (16, value, &acpi_gbl_xpm1b_enable); break; case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */ - status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk, 0); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk); if (ACPI_FAILURE (status)) { goto unlock_and_exit; } - status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk, 0); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk); break; case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */ - status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk, 0); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1a_cnt_blk); break; case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */ - status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk, 0); + status = acpi_hw_low_level_write (16, value, &acpi_gbl_FADT->xpm1b_cnt_blk); break; case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ - status = acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->xpm2_cnt_blk, 0); + status = acpi_hw_low_level_write (8, value, &acpi_gbl_FADT->xpm2_cnt_blk); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ - status = acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->xpm_tmr_blk, 0); + status = acpi_hw_low_level_write (32, value, &acpi_gbl_FADT->xpm_tmr_blk); break; @@ -676,11 +680,11 @@ acpi_hw_register_write ( * * FUNCTION: acpi_hw_low_level_read * - * PARAMETERS: Register - GAS register structure - * Offset - Offset from the base address in the GAS - * Width - 8, 16, or 32 + * PARAMETERS: Width - 8, 16, or 32 + * Value - Where the value is returned + * Register - GAS register structure * - * RETURN: Value read + * RETURN: Status * * DESCRIPTION: Read from either memory, IO, or PCI config space. * @@ -690,11 +694,8 @@ acpi_status acpi_hw_low_level_read ( u32 width, u32 *value, - struct acpi_generic_address *reg, - u32 offset) + struct acpi_generic_address *reg) { - acpi_physical_address mem_address; - acpi_io_address io_address; struct acpi_pci_id pci_id; u16 pci_register; acpi_status status; @@ -721,19 +722,16 @@ acpi_hw_low_level_read ( switch (reg->address_space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: - mem_address = (reg->address - + (acpi_physical_address) offset); - - status = acpi_os_read_memory (mem_address, value, width); + status = acpi_os_read_memory ( + (acpi_physical_address) reg->address, + value, width); break; case ACPI_ADR_SPACE_SYSTEM_IO: - io_address = (acpi_io_address) (reg->address - + (acpi_physical_address) offset); - - status = acpi_os_read_port (io_address, value, width); + status = acpi_os_read_port ((acpi_io_address) reg->address, + value, width); break; @@ -743,15 +741,16 @@ acpi_hw_low_level_read ( pci_id.bus = 0; pci_id.device = ACPI_PCI_DEVICE (reg->address); pci_id.function = ACPI_PCI_FUNCTION (reg->address); - pci_register = (u16) (ACPI_PCI_REGISTER (reg->address) - + offset); + pci_register = (u16) ACPI_PCI_REGISTER (reg->address); - status = acpi_os_read_pci_configuration (&pci_id, pci_register, value, width); + status = acpi_os_read_pci_configuration (&pci_id, pci_register, + value, width); break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", reg->address_space_id)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unsupported address space: %X\n", reg->address_space_id)); status = AE_BAD_PARAMETER; break; } @@ -767,12 +766,10 @@ acpi_hw_low_level_read ( * PARAMETERS: Width - 8, 16, or 32 * Value - To be written * Register - GAS register structure - * Offset - Offset from the base address in the GAS - * * - * RETURN: Value read + * RETURN: Status * - * DESCRIPTION: Read from either memory, IO, or PCI config space. + * DESCRIPTION: Write to either memory, IO, or PCI config space. * ******************************************************************************/ @@ -780,11 +777,8 @@ acpi_status acpi_hw_low_level_write ( u32 width, u32 value, - struct acpi_generic_address *reg, - u32 offset) + struct acpi_generic_address *reg) { - acpi_physical_address mem_address; - acpi_io_address io_address; struct acpi_pci_id pci_id; u16 pci_register; acpi_status status; @@ -809,19 +803,16 @@ acpi_hw_low_level_write ( switch (reg->address_space_id) { case ACPI_ADR_SPACE_SYSTEM_MEMORY: - mem_address = (reg->address - + (acpi_physical_address) offset); - - status = acpi_os_write_memory (mem_address, value, width); + status = acpi_os_write_memory ( + (acpi_physical_address) reg->address, + value, width); break; case ACPI_ADR_SPACE_SYSTEM_IO: - io_address = (acpi_io_address) (reg->address - + (acpi_physical_address) offset); - - status = acpi_os_write_port (io_address, value, width); + status = acpi_os_write_port ((acpi_io_address) reg->address, + value, width); break; @@ -831,15 +822,16 @@ acpi_hw_low_level_write ( pci_id.bus = 0; pci_id.device = ACPI_PCI_DEVICE (reg->address); pci_id.function = ACPI_PCI_FUNCTION (reg->address); - pci_register = (u16) (ACPI_PCI_REGISTER (reg->address) - + offset); + pci_register = (u16) ACPI_PCI_REGISTER (reg->address); - status = acpi_os_write_pci_configuration (&pci_id, pci_register, (acpi_integer) value, width); + status = acpi_os_write_pci_configuration (&pci_id, pci_register, + (acpi_integer) value, width); break; default: - ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unsupported address space: %X\n", reg->address_space_id)); + ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, + "Unsupported address space: %X\n", reg->address_space_id)); status = AE_BAD_PARAMETER; break; } diff --git a/drivers/acpi/hardware/hwtimer.c b/drivers/acpi/hardware/hwtimer.c index b8053a1d8193d112198a361d5bc6b2431e396bab..897dd6db98d9e27a30a68cb52c3e5dd81429bb5e 100644 --- a/drivers/acpi/hardware/hwtimer.c +++ b/drivers/acpi/hardware/hwtimer.c @@ -108,7 +108,7 @@ acpi_get_timer ( return_ACPI_STATUS (AE_BAD_PARAMETER); } - status = acpi_hw_low_level_read (32, ticks, &acpi_gbl_FADT->xpm_tmr_blk, 0); + status = acpi_hw_low_level_read (32, ticks, &acpi_gbl_FADT->xpm_tmr_blk); return_ACPI_STATUS (status); } diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c index c412245e848a02648c52a26dd08e8672e9fd540d..37ab3e0cbb8a3d835c3b949365065ff20fd86b2a 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/namespace/nsalloc.c @@ -116,19 +116,33 @@ acpi_ns_delete_node ( prev_node = NULL; next_node = parent_node->child; + /* Find the node that is the previous peer in the parent's child list */ + while (next_node != node) { prev_node = next_node; next_node = prev_node->peer; } if (prev_node) { + /* Node is not first child, unlink it */ + prev_node->peer = next_node->peer; if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { prev_node->flags |= ANOBJ_END_OF_PEER_LIST; } } else { - parent_node->child = next_node->peer; + /* Node is first child (has no previous peer) */ + + if (next_node->flags & ANOBJ_END_OF_PEER_LIST) { + /* No peers at all */ + + parent_node->child = NULL; + } + else { /* Link peer list to parent */ + + parent_node->child = next_node->peer; + } } @@ -222,7 +236,7 @@ acpi_ns_install_node ( struct acpi_namespace_node *node, /* New Child*/ acpi_object_type type) { - u16 owner_id = TABLE_ID_DSDT; + u16 owner_id = 0; struct acpi_namespace_node *child_node; #ifdef ACPI_ALPHABETIC_NAMESPACE @@ -355,6 +369,7 @@ acpi_ns_delete_children ( { struct acpi_namespace_node *child_node; struct acpi_namespace_node *next_node; + struct acpi_namespace_node *node; u8 flags; @@ -399,6 +414,25 @@ acpi_ns_delete_children ( * Detach an object if there is one, then free the child node */ acpi_ns_detach_object (child_node); + + /* + * Decrement the reference count(s) of all parents up to + * the root! (counts were incremented when the node was created) + */ + node = child_node; + while ((node = acpi_ns_get_parent_node (node)) != NULL) { + node->reference_count--; + } + + /* There should be only one reference remaining on this node */ + + if (child_node->reference_count != 1) { + ACPI_REPORT_WARNING (("Existing references (%d) on node being deleted (%p)\n", + child_node->reference_count, child_node)); + } + + /* Now we can delete the node */ + ACPI_MEM_FREE (child_node); /* And move on to the next child in the list */ @@ -512,7 +546,7 @@ acpi_ns_delete_namespace_subtree ( * ******************************************************************************/ -static void +void acpi_ns_remove_reference ( struct acpi_namespace_node *node) { diff --git a/drivers/acpi/namespace/nsdumpdv.c b/drivers/acpi/namespace/nsdumpdv.c index af4bdd41e5ccd5f74180e114c37319823c55fa39..6abbd09197dd3e5e25b8dc49307351e552918193 100644 --- a/drivers/acpi/namespace/nsdumpdv.c +++ b/drivers/acpi/namespace/nsdumpdv.c @@ -72,7 +72,8 @@ acpi_ns_dump_one_device ( void *context, void **return_value) { - struct acpi_device_info info; + struct acpi_buffer buffer; + struct acpi_device_info *info; acpi_status status; u32 i; @@ -82,16 +83,19 @@ acpi_ns_dump_one_device ( status = acpi_ns_dump_one_object (obj_handle, level, context, return_value); - status = acpi_get_object_info (obj_handle, &info); + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; + status = acpi_get_object_info (obj_handle, &buffer); if (ACPI_SUCCESS (status)) { + info = buffer.pointer; for (i = 0; i < level; i++) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " HID: %s, ADR: %8.8X%8.8X, Status: %X\n", - info.hardware_id, - ACPI_HIDWORD (info.address), ACPI_LODWORD (info.address), - info.current_status)); + info->hardware_id.value, + ACPI_HIDWORD (info->address), ACPI_LODWORD (info->address), + info->current_status)); + ACPI_MEM_FREE (info); } return (status); diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index 8cb42fefda19b7c8131de580e5a8151e8d8f8799..1eac324e601c70b65755e607bf9d96302a4808e5 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c @@ -79,7 +79,7 @@ acpi_ns_load_table ( /* Check if table contains valid AML (must be DSDT, PSDT, SSDT, etc.) */ - if (!(acpi_gbl_acpi_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) { + if (!(acpi_gbl_table_data[table_desc->type].flags & ACPI_TABLE_EXECUTABLE)) { /* Just ignore this table */ return_ACPI_STATUS (AE_OK); @@ -182,7 +182,7 @@ acpi_ns_load_table_by_type ( ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading DSDT\n")); - table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_DSDT]; + table_desc = acpi_gbl_table_lists[ACPI_TABLE_DSDT].next; /* If table already loaded into namespace, just return */ @@ -190,8 +190,6 @@ acpi_ns_load_table_by_type ( goto unlock_and_exit; } - table_desc->table_id = TABLE_ID_DSDT; - /* Now load the single DSDT */ status = acpi_ns_load_table (table_desc, acpi_gbl_root_node); @@ -205,13 +203,13 @@ acpi_ns_load_table_by_type ( case ACPI_TABLE_SSDT: ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d SSDTs\n", - acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count)); + acpi_gbl_table_lists[ACPI_TABLE_SSDT].count)); /* * Traverse list of SSDT tables */ - table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_SSDT]; - for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_SSDT].count; i++) { + table_desc = acpi_gbl_table_lists[ACPI_TABLE_SSDT].next; + for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_SSDT].count; i++) { /* * Only attempt to load table if it is not * already loaded! @@ -233,14 +231,14 @@ acpi_ns_load_table_by_type ( case ACPI_TABLE_PSDT: ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Loading %d PSDTs\n", - acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count)); + acpi_gbl_table_lists[ACPI_TABLE_PSDT].count)); /* * Traverse list of PSDT tables */ - table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_PSDT]; + table_desc = acpi_gbl_table_lists[ACPI_TABLE_PSDT].next; - for (i = 0; i < acpi_gbl_acpi_tables[ACPI_TABLE_PSDT].count; i++) { + for (i = 0; i < acpi_gbl_table_lists[ACPI_TABLE_PSDT].count; i++) { /* Only attempt to load table if it is not already loaded! */ if (!table_desc->loaded_into_namespace) { diff --git a/drivers/acpi/namespace/nsparse.c b/drivers/acpi/namespace/nsparse.c index 3d75e08a2d0926fb9ef414b6301aff784727b518..0ba6651976c1f9ed624abc3bed595bc6df1751a1 100644 --- a/drivers/acpi/namespace/nsparse.c +++ b/drivers/acpi/namespace/nsparse.c @@ -85,10 +85,9 @@ acpi_ns_one_complete_parse ( return_ACPI_STATUS (AE_NO_MEMORY); } - /* Create and initialize a new walk state */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, + walk_state = acpi_ds_create_walk_state (table_desc->table_id, NULL, NULL, NULL); if (!walk_state) { acpi_ps_free_op (parse_root); diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index 10fe6e8f5aedde2bcbfcc9acf38ce03df18a1fba..ba116b7900ec7aec1b9d590ee1cea8d7ad6c8e46 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c @@ -117,8 +117,9 @@ acpi_ns_search_node ( * Found matching entry. */ ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, - "Name %4.4s Type [%s] found at %p\n", - (char *) &target_name, acpi_ut_get_type_name (next_node->type), next_node)); + "Name %4.4s Type [%s] found in scope [%4.4s] %p\n", + (char *) &target_name, acpi_ut_get_type_name (next_node->type), + next_node->name.ascii, next_node)); *return_node = next_node; return_ACPI_STATUS (AE_OK); @@ -141,8 +142,10 @@ acpi_ns_search_node ( /* Searched entire namespace level, not found */ - ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Name %4.4s Type [%s] not found at %p\n", - (char *) &target_name, acpi_ut_get_type_name (type), next_node)); + ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, + "Name %4.4s Type [%s] not found in search in scope [%4.4s] %p first child %p\n", + (char *) &target_name, acpi_ut_get_type_name (type), + node->name.ascii, node, node->child)); return_ACPI_STATUS (AE_NOT_FOUND); } diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index 321dcbc0484f38ce270212da647f7a1871480024..12d6087c48cd8e614b433aba4944a3fff4c5cc99 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c @@ -181,7 +181,11 @@ acpi_ns_print_node_pathname ( status = acpi_ns_handle_to_pathname (node, &buffer); if (ACPI_SUCCESS (status)) { - acpi_os_printf ("%s [%s] (Node %p)", msg, (char *) buffer.pointer, node); + if (msg) { + acpi_os_printf ("%s ", msg); + } + + acpi_os_printf ("[%s] (Node %p)", (char *) buffer.pointer, node); ACPI_MEM_FREE (buffer.pointer); } } @@ -799,38 +803,31 @@ void acpi_ns_terminate (void) { union acpi_operand_object *obj_desc; - struct acpi_namespace_node *this_node; ACPI_FUNCTION_TRACE ("ns_terminate"); - this_node = acpi_gbl_root_node; - /* - * 1) Free the entire namespace -- all objects, tables, and stacks + * 1) Free the entire namespace -- all nodes and objects * - * Delete all objects linked to the root - * (additional table descriptors) + * Delete all object descriptors attached to namepsace nodes */ - acpi_ns_delete_namespace_subtree (this_node); + acpi_ns_delete_namespace_subtree (acpi_gbl_root_node); - /* Detach any object(s) attached to the root */ + /* Detach any objects attached to the root */ - obj_desc = acpi_ns_get_attached_object (this_node); + obj_desc = acpi_ns_get_attached_object (acpi_gbl_root_node); if (obj_desc) { - acpi_ns_detach_object (this_node); - acpi_ut_remove_reference (obj_desc); + acpi_ns_detach_object (acpi_gbl_root_node); } - acpi_ns_delete_children (this_node); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Namespace freed\n")); - /* * 2) Now we can delete the ACPI tables */ - acpi_tb_delete_acpi_tables (); + acpi_tb_delete_all_tables (); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "ACPI Tables freed\n")); return_VOID; diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index 584c76aed5239d2480ea11eb58799adde3a1826a..6706d7b42c4524c59099ebd129711c680fb8cb6a 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -437,16 +437,15 @@ acpi_ns_get_device_callback ( void *context, void **return_value) { + struct acpi_get_devices_info *info = context; acpi_status status; struct acpi_namespace_node *node; u32 flags; struct acpi_device_id hid; - struct acpi_device_id cid; - struct acpi_get_devices_info *info; + struct acpi_compatible_id_list *cid; + acpi_native_uint i; - info = context; - status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { return (status); @@ -462,9 +461,8 @@ acpi_ns_get_device_callback ( return (AE_BAD_PARAMETER); } - /* - * Run _STA to determine if device is present - */ + /* Run _STA to determine if device is present */ + status = acpi_ut_execute_STA (node, &flags); if (ACPI_FAILURE (status)) { return (AE_CTRL_DEPTH); @@ -472,12 +470,12 @@ acpi_ns_get_device_callback ( if (!(flags & 0x01)) { /* Don't return at the device or children of the device if not there */ + return (AE_CTRL_DEPTH); } - /* - * Filter based on device HID & CID - */ + /* Filter based on device HID & CID */ + if (info->hid != NULL) { status = acpi_ut_execute_HID (node, &hid); if (status == AE_NOT_FOUND) { @@ -487,7 +485,9 @@ acpi_ns_get_device_callback ( return (AE_CTRL_DEPTH); } - if (ACPI_STRNCMP (hid.buffer, info->hid, sizeof (hid.buffer)) != 0) { + if (ACPI_STRNCMP (hid.value, info->hid, sizeof (hid.value)) != 0) { + /* Get the list of Compatible IDs */ + status = acpi_ut_execute_CID (node, &cid); if (status == AE_NOT_FOUND) { return (AE_OK); @@ -496,11 +496,16 @@ acpi_ns_get_device_callback ( return (AE_CTRL_DEPTH); } - /* TBD: Handle CID packages */ + /* Walk the CID list */ - if (ACPI_STRNCMP (cid.buffer, info->hid, sizeof (cid.buffer)) != 0) { - return (AE_OK); + for (i = 0; i < cid->count; i++) { + if (ACPI_STRNCMP (cid->id[i].value, info->hid, + sizeof (struct acpi_compatible_id)) != 0) { + ACPI_MEM_FREE (cid); + return (AE_OK); + } } + ACPI_MEM_FREE (cid); } } diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index 5c146c96bb3cba142a1bc99e4a15a2bf1e0b24eb..362efe49fde816c344bc46f6d40617ca5e3ce556 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c @@ -51,7 +51,7 @@ ACPI_MODULE_NAME ("nsxfname") -/**************************************************************************** +/****************************************************************************** * * FUNCTION: acpi_get_handle * @@ -119,7 +119,8 @@ acpi_get_handle ( /* * Find the Node and convert to a handle */ - status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH, &node); + status = acpi_ns_get_node_by_path (pathname, prefix_node, ACPI_NS_NO_UPSEARCH, + &node); *ret_handle = NULL; if (ACPI_SUCCESS (status)) { @@ -130,7 +131,7 @@ acpi_get_handle ( } -/**************************************************************************** +/****************************************************************************** * * FUNCTION: acpi_get_name * @@ -211,7 +212,7 @@ acpi_get_name ( } -/**************************************************************************** +/****************************************************************************** * * FUNCTION: acpi_get_object_info * @@ -229,22 +230,27 @@ acpi_get_name ( acpi_status acpi_get_object_info ( acpi_handle handle, - struct acpi_device_info *info) + struct acpi_buffer *buffer) { - struct acpi_device_id hid; - struct acpi_device_id uid; acpi_status status; - u32 device_status = 0; - acpi_integer address = 0; struct acpi_namespace_node *node; + struct acpi_device_info info; + struct acpi_device_info *return_info; + struct acpi_compatible_id_list *cid_list = NULL; + acpi_size size; /* Parameter validation */ - if (!handle || !info) { + if (!handle || !buffer) { return (AE_BAD_PARAMETER); } + status = acpi_ut_validate_buffer (buffer); + if (ACPI_FAILURE (status)) { + return (status); + } + status = acpi_ut_acquire_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { return (status); @@ -256,69 +262,94 @@ acpi_get_object_info ( return (AE_BAD_PARAMETER); } - info->type = node->type; - info->name = node->name.integer; + /* Init return structure */ + + size = sizeof (struct acpi_device_info); + ACPI_MEMSET (&info, 0, size); + + info.type = node->type; + info.name = node->name.integer; + info.valid = 0; status = acpi_ut_release_mutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (status)) { return (status); } - /* - * If not a device, we are all done. - */ - if (info->type != ACPI_TYPE_DEVICE) { - return (AE_OK); - } + /* If not a device, we are all done */ + if (info.type == ACPI_TYPE_DEVICE) { + /* + * Get extra info for ACPI Devices objects only: + * Run the Device _HID, _UID, _CID, _STA, and _ADR methods. + * + * Note: none of these methods are required, so they may or may + * not be present for this device. The Info.Valid bitfield is used + * to indicate which methods were found and ran successfully. + */ - /* - * Get extra info for ACPI devices only. Run the - * _HID, _UID, _STA, and _ADR methods. Note: none - * of these methods are required, so they may or may - * not be present. The Info->Valid bits are used - * to indicate which methods ran successfully. - */ - info->valid = 0; + /* Execute the Device._HID method */ - /* Execute the _HID method and save the result */ + status = acpi_ut_execute_HID (node, &info.hardware_id); + if (ACPI_SUCCESS (status)) { + info.valid |= ACPI_VALID_HID; + } - status = acpi_ut_execute_HID (node, &hid); - if (ACPI_SUCCESS (status)) { - ACPI_STRNCPY (info->hardware_id, hid.buffer, sizeof(info->hardware_id)); - info->valid |= ACPI_VALID_HID; - } + /* Execute the Device._UID method */ - /* Execute the _UID method and save the result */ + status = acpi_ut_execute_UID (node, &info.unique_id); + if (ACPI_SUCCESS (status)) { + info.valid |= ACPI_VALID_UID; + } - status = acpi_ut_execute_UID (node, &uid); - if (ACPI_SUCCESS (status)) { - ACPI_STRCPY (info->unique_id, uid.buffer); - info->valid |= ACPI_VALID_UID; + /* Execute the Device._CID method */ + + status = acpi_ut_execute_CID (node, &cid_list); + if (ACPI_SUCCESS (status)) { + size += ((acpi_size) cid_list->count - 1) * + sizeof (struct acpi_compatible_id); + info.valid |= ACPI_VALID_CID; + } + + /* Execute the Device._STA method */ + + status = acpi_ut_execute_STA (node, &info.current_status); + if (ACPI_SUCCESS (status)) { + info.valid |= ACPI_VALID_STA; + } + + /* Execute the Device._ADR method */ + + status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, node, + &info.address); + if (ACPI_SUCCESS (status)) { + info.valid |= ACPI_VALID_ADR; + } + + status = AE_OK; } - /* - * Execute the _STA method and save the result - * _STA is not always present - */ - status = acpi_ut_execute_STA (node, &device_status); - if (ACPI_SUCCESS (status)) { - info->current_status = device_status; - info->valid |= ACPI_VALID_STA; + /* Validate/Allocate/Clear caller buffer */ + + status = acpi_ut_initialize_buffer (buffer, size); + if (ACPI_FAILURE (status)) { + goto cleanup; } - /* - * Execute the _ADR method and save result if successful - * _ADR is not always present - */ - status = acpi_ut_evaluate_numeric_object (METHOD_NAME__ADR, - node, &address); + /* Populate the return buffer */ - if (ACPI_SUCCESS (status)) { - info->address = address; - info->valid |= ACPI_VALID_ADR; + return_info = buffer->pointer; + ACPI_MEMCPY (return_info, &info, sizeof (struct acpi_device_info)); + + if (cid_list) { + ACPI_MEMCPY (&return_info->compatibility_id, cid_list, cid_list->size); } - return (AE_OK); + +cleanup: + if (cid_list) { + ACPI_MEM_FREE (cid_list); + } + return (status); } diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index c78ea7e34bb6f2bab70f5bd507418535ad684540..997b6cb20cf079b41f3a89332906950dd3f5f6b5 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -237,7 +237,7 @@ acpi_os_table_override (struct acpi_table_header *existing_table, static irqreturn_t acpi_irq(int irq, void *dev_id, struct pt_regs *regs) { - return (*acpi_irq_handler)(acpi_irq_context); + return (*acpi_irq_handler)(acpi_irq_context) ? IRQ_HANDLED : IRQ_NONE; } acpi_status @@ -1006,7 +1006,7 @@ acpi_os_name_setup(char *str) return 0; for (; count-- && str && *str; str++) { - if (isalnum(*str) || *str == ' ') + if (isalnum(*str) || *str == ' ' || *str == ':') *p++ = *str; else if (*str == '\'' || *str == '"') continue; diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index 2f79d963eddbf1d5a934525ad7323e10fa82ce8e..d0e8cc6acd8e8f42374aa93b050327080889da9d 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c @@ -350,6 +350,11 @@ acpi_ps_get_next_namepath ( (status != AE_NOT_FOUND)) { ACPI_REPORT_NSERROR (path, status); + + acpi_os_printf ("search_node %p start_node %p return_node %p\n", + scope_info.scope.node, parser_state->start_node, node); + + } else { /* diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c index f2a92dc2e3cf7262977aa61104a32e0fa60b9b32..43f8547a991d88d021c744f8bb1f05b60a9e7f48 100644 --- a/drivers/acpi/parser/pswalk.c +++ b/drivers/acpi/parser/pswalk.c @@ -270,7 +270,7 @@ acpi_ps_delete_parse_tree ( return_VOID; } - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, thread); + walk_state = acpi_ds_create_walk_state (0, NULL, NULL, thread); if (!walk_state) { return_VOID; } diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index bc2ce6b17c05386bf3d5886f06996a930a308fa9..1e0602883641917ea0e038daff8f3ee8ca8e7d36 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -178,7 +178,7 @@ acpi_psx_execute ( /* Create and initialize a new walk state */ - walk_state = acpi_ds_create_walk_state (TABLE_ID_DSDT, NULL, NULL, NULL); + walk_state = acpi_ds_create_walk_state (0, NULL, NULL, NULL); if (!walk_state) { return_ACPI_STATUS (AE_NO_MEMORY); } diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 63fd9ac1df7ab6c19d627117a4fe4d8c46d66120..cb2d60ea35c6336c7bbc2c356f00d8d2074343e4 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -379,25 +379,31 @@ acpi_resource_to_address64 ( { struct acpi_resource_address16 *address16; struct acpi_resource_address32 *address32; - struct acpi_resource_address64 *address64; switch (resource->id) { case ACPI_RSTYPE_ADDRESS16: + address16 = (struct acpi_resource_address16 *) &resource->data; ACPI_COPY_ADDRESS(out, address16); break; + case ACPI_RSTYPE_ADDRESS32: + address32 = (struct acpi_resource_address32 *) &resource->data; ACPI_COPY_ADDRESS(out, address32); break; + case ACPI_RSTYPE_ADDRESS64: - address64 = (struct acpi_resource_address64 *) &resource->data; - ACPI_COPY_ADDRESS(out, address64); + + /* Simple copy for 64 bit source */ + + ACPI_MEMCPY (out, &resource->data, sizeof (struct acpi_resource_address64)); break; + default: return (AE_BAD_PARAMETER); } diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index fa930325c8282e0a914828e3040379ebccf39ed0..ec8313fa549a4ac3295ca20280b3b220897161b0 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -28,6 +28,8 @@ static spinlock_t acpi_device_lock = SPIN_LOCK_UNLOCKED; static void acpi_device_release(struct kobject * kobj) { struct acpi_device * dev = container_of(kobj,struct acpi_device,kobj); + if (dev->pnp.cid_list) + kfree(dev->pnp.cid_list); kfree(dev); } @@ -69,7 +71,7 @@ static void acpi_device_register(struct acpi_device * device, struct acpi_device device->kobj.parent = &parent->kobj; device->kobj.ktype = &ktype_acpi_ns; device->kobj.kset = &acpi_namespace_kset; - kobject_register(&device->kobj); + kobject_add(&device->kobj); } static int @@ -201,32 +203,15 @@ acpi_bus_match ( goto Done; if (device->flags.compatible_ids) { - acpi_status status = AE_OK; - union acpi_object *object = NULL; - char cid[256] = {}; + struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; + int i; - status = acpi_evaluate_object(device->handle, "_CID", NULL, - &buffer); - if (ACPI_FAILURE(status) || !buffer.pointer) - return -ENOENT; - - object = (union acpi_object *) buffer.pointer; - - switch (object->type) { - case ACPI_TYPE_INTEGER: - acpi_ex_eisa_id_to_string((u32) object->integer.value, - cid); - break; - case ACPI_TYPE_STRING: - strncpy(cid, object->string.pointer, sizeof(cid) - 1); - break; - case ACPI_TYPE_PACKAGE: - /* TBD: Support CID packages */ - break; + /* compare multiple _CID entries against driver ids */ + for (i = 0; i < cid_list->count; i++) + { + if (strstr(driver->ids, cid_list->id[i].value)) + goto Done; } - - if (strlen(cid) && strstr(driver->ids,cid)) - goto Done; } error = -ENOENT; @@ -523,27 +508,30 @@ static void acpi_device_get_busid(struct acpi_device * device, acpi_handle handl static void acpi_device_set_id(struct acpi_device * device, struct acpi_device * parent, acpi_handle handle, int type) { - struct acpi_device_info info; + struct acpi_device_info *info; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; char *hid = NULL; char *uid = NULL; + struct acpi_compatible_id_list *cid_list = NULL; acpi_status status; switch (type) { case ACPI_BUS_TYPE_DEVICE: - status = acpi_get_object_info(handle, &info); + status = acpi_get_object_info(handle, &buffer); if (ACPI_FAILURE(status)) { printk("%s: Error reading device info\n",__FUNCTION__); return; } - /* Clean up info strings (not NULL terminated) */ - info.hardware_id[sizeof(info.hardware_id)-1] = '\0'; - info.unique_id[sizeof(info.unique_id)-1] = '\0'; - if (info.valid & ACPI_VALID_HID) - hid = info.hardware_id; - if (info.valid & ACPI_VALID_UID) - uid = info.unique_id; - if (info.valid & ACPI_VALID_ADR) { - device->pnp.bus_address = info.address; + + info = buffer.pointer; + if (info->valid & ACPI_VALID_HID) + hid = info->hardware_id.value; + if (info->valid & ACPI_VALID_UID) + uid = info->unique_id.value; + if (info->valid & ACPI_VALID_CID) + cid_list = &info->compatibility_id; + if (info->valid & ACPI_VALID_ADR) { + device->pnp.bus_address = info->address; device->flags.bus_address = 1; } break; @@ -586,6 +574,15 @@ static void acpi_device_set_id(struct acpi_device * device, struct acpi_device * sprintf(device->pnp.unique_id, "%s", uid); device->flags.unique_id = 1; } + if (cid_list) { + device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL); + if (device->pnp.cid_list) + memcpy(device->pnp.cid_list, cid_list, cid_list->size); + else + printk(KERN_ERR "Memory allocation error\n"); + } + + acpi_os_free(buffer.pointer); } int acpi_device_set_context(struct acpi_device * device, int type) @@ -781,8 +778,12 @@ acpi_bus_add ( end: if (!result) *child = device; - else + else { + if (device->pnp.cid_list) + kfree(device->pnp.cid_list); kfree(device); + } + return_VALUE(result); } diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c index ae9f5977f0d01cda675632cb64d3d7f66de280d3..4b412360e417a03c3f861d65c9cc4e9d59f80225 100644 --- a/drivers/acpi/tables/tbconvrt.c +++ b/drivers/acpi/tables/tbconvrt.c @@ -164,6 +164,36 @@ acpi_tb_convert_to_xsdt ( } +/****************************************************************************** + * + * FUNCTION: acpi_tb_init_generic_address + * + * PARAMETERS: new_gas_struct - GAS struct to be initialized + * register_bit_width - Width of this register + * Address - Address of the register + * + * RETURN: None + * + * DESCRIPTION: Initialize a GAS structure. + * + ******************************************************************************/ + +static void +acpi_tb_init_generic_address ( + struct acpi_generic_address *new_gas_struct, + u8 register_bit_width, + acpi_physical_address address) +{ + + ACPI_STORE_ADDRESS (new_gas_struct->address, address); + + new_gas_struct->address_space_id = ACPI_ADR_SPACE_SYSTEM_IO; + new_gas_struct->register_bit_width = register_bit_width; + new_gas_struct->register_bit_offset = 0; + new_gas_struct->reserved = 0; +} + + /******************************************************************************* * * FUNCTION: acpi_tb_convert_fadt1 @@ -233,14 +263,34 @@ acpi_tb_convert_fadt1 ( /* * Convert the V1.0 block addresses to V2.0 GAS structures */ - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len, local_fadt->V1_pm1a_evt_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len, local_fadt->V1_pm1b_evt_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len, local_fadt->V1_pm1a_cnt_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len, local_fadt->V1_pm1b_cnt_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len, local_fadt->V1_pm2_cnt_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len, local_fadt->V1_pm_tmr_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk, 0, local_fadt->V1_gpe0_blk); - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk, 0, local_fadt->V1_gpe1_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, local_fadt->pm1_evt_len, + (acpi_physical_address) local_fadt->V1_pm1a_evt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, local_fadt->pm1_evt_len, + (acpi_physical_address) local_fadt->V1_pm1b_evt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, local_fadt->pm1_cnt_len, + (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, local_fadt->pm1_cnt_len, + (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, local_fadt->pm2_cnt_len, + (acpi_physical_address) local_fadt->V1_pm2_cnt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, local_fadt->pm_tm_len, + (acpi_physical_address) local_fadt->V1_pm_tmr_blk); + acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, 0, + (acpi_physical_address) local_fadt->V1_gpe0_blk); + acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, 0, + (acpi_physical_address) local_fadt->V1_gpe1_blk); + + /* Create separate GAS structs for the PM1 Enable registers */ + + acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable, + (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), + (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address + + ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); + + acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable, + (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), + (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address + + ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); } @@ -282,44 +332,58 @@ acpi_tb_convert_fadt2 ( } if (!(local_fadt->xpm1a_evt_blk.address)) { - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_evt_blk, - local_fadt->pm1_evt_len, local_fadt->V1_pm1a_evt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1a_evt_blk, + local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1a_evt_blk); } if (!(local_fadt->xpm1b_evt_blk.address)) { - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_evt_blk, - local_fadt->pm1_evt_len, local_fadt->V1_pm1b_evt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1b_evt_blk, + local_fadt->pm1_evt_len, (acpi_physical_address) local_fadt->V1_pm1b_evt_blk); } if (!(local_fadt->xpm1a_cnt_blk.address)) { - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1a_cnt_blk, - local_fadt->pm1_cnt_len, local_fadt->V1_pm1a_cnt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1a_cnt_blk, + local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1a_cnt_blk); } if (!(local_fadt->xpm1b_cnt_blk.address)) { - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm1b_cnt_blk, - local_fadt->pm1_cnt_len, local_fadt->V1_pm1b_cnt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm1b_cnt_blk, + local_fadt->pm1_cnt_len, (acpi_physical_address) local_fadt->V1_pm1b_cnt_blk); } if (!(local_fadt->xpm2_cnt_blk.address)) { - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm2_cnt_blk, - local_fadt->pm2_cnt_len, local_fadt->V1_pm2_cnt_blk); + acpi_tb_init_generic_address (&local_fadt->xpm2_cnt_blk, + local_fadt->pm2_cnt_len, (acpi_physical_address) local_fadt->V1_pm2_cnt_blk); } if (!(local_fadt->xpm_tmr_blk.address)) { - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xpm_tmr_blk, - local_fadt->pm_tm_len, local_fadt->V1_pm_tmr_blk); + acpi_tb_init_generic_address (&local_fadt->xpm_tmr_blk, + local_fadt->pm_tm_len, (acpi_physical_address) local_fadt->V1_pm_tmr_blk); } if (!(local_fadt->xgpe0_blk.address)) { - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe0_blk, - 0, local_fadt->V1_gpe0_blk); + acpi_tb_init_generic_address (&local_fadt->xgpe0_blk, + 0, (acpi_physical_address) local_fadt->V1_gpe0_blk); } if (!(local_fadt->xgpe1_blk.address)) { - ASL_BUILD_GAS_FROM_V1_ENTRY (local_fadt->xgpe1_blk, - 0, local_fadt->V1_gpe1_blk); + acpi_tb_init_generic_address (&local_fadt->xgpe1_blk, + 0, (acpi_physical_address) local_fadt->V1_gpe1_blk); } + + /* Create separate GAS structs for the PM1 Enable registers */ + + acpi_tb_init_generic_address (&acpi_gbl_xpm1a_enable, + (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), + (acpi_physical_address) (local_fadt->xpm1a_evt_blk.address + + ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); + acpi_gbl_xpm1a_enable.address_space_id = local_fadt->xpm1a_evt_blk.address_space_id; + + acpi_tb_init_generic_address (&acpi_gbl_xpm1b_enable, + (u8) ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len), + (acpi_physical_address) (local_fadt->xpm1b_evt_blk.address + + ACPI_DIV_2 (acpi_gbl_FADT->pm1_evt_len))); + acpi_gbl_xpm1b_enable.address_space_id = local_fadt->xpm1b_evt_blk.address_space_id; } @@ -396,7 +460,7 @@ acpi_tb_convert_table_fadt (void) /* Free the original table */ - table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT]; + table_desc = acpi_gbl_table_lists[ACPI_TABLE_FADT].next; acpi_tb_delete_single_table (table_desc); /* Install the new table */ diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c index 91ed931eb2f1dae02aa341ad55229af452153184..65e696cf145eeea32fee479cf36b92aa45ce31dd 100644 --- a/drivers/acpi/tables/tbget.c +++ b/drivers/acpi/tables/tbget.c @@ -456,18 +456,18 @@ acpi_tb_get_table_ptr ( * instance is always in the list head. */ if (instance == 1) { - /* - * Just pluck the pointer out of the global table! - * Will be null if no table is present - */ - *table_ptr_loc = acpi_gbl_acpi_tables[table_type].pointer; + /* Get the first */ + + if (acpi_gbl_table_lists[table_type].next) { + *table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer; + } return_ACPI_STATUS (AE_OK); } /* * Check for instance out of range */ - if (instance > acpi_gbl_acpi_tables[table_type].count) { + if (instance > acpi_gbl_table_lists[table_type].count) { return_ACPI_STATUS (AE_NOT_EXIST); } @@ -478,7 +478,7 @@ acpi_tb_get_table_ptr ( * need to walk from the 2nd table until we reach the Instance * that the user is looking for and return its table pointer. */ - table_desc = acpi_gbl_acpi_tables[table_type].next; + table_desc = acpi_gbl_table_lists[table_type].next; for (i = 2; i < instance; i++) { table_desc = table_desc->next; } diff --git a/drivers/acpi/tables/tbgetall.c b/drivers/acpi/tables/tbgetall.c index 8c3f44ad4f6816b86beccfc2f45528eab785d1a6..48381c0dcbfec77d96f4e16070fee74cfbe5ff25 100644 --- a/drivers/acpi/tables/tbgetall.c +++ b/drivers/acpi/tables/tbgetall.c @@ -307,7 +307,7 @@ acpi_tb_get_required_tables ( /* Always delete the RSDP mapping, we are done with it */ - acpi_tb_delete_acpi_table (ACPI_TABLE_RSDP); + acpi_tb_delete_tables_by_type (ACPI_TABLE_RSDP); return_ACPI_STATUS (status); } diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index 2e5921992d9983753a35827379d37281d62ae701..a96c5de2bfeb10bd53b5403412e5bfd6cf4772aa 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c @@ -79,13 +79,13 @@ acpi_tb_match_signature ( /* * Search for a signature match among the known table types */ - for (i = 0; i < NUM_ACPI_TABLES; i++) { - if (!(acpi_gbl_acpi_table_data[i].flags & search_type)) { + for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) { + if (!(acpi_gbl_table_data[i].flags & search_type)) { continue; } - if (!ACPI_STRNCMP (signature, acpi_gbl_acpi_table_data[i].signature, - acpi_gbl_acpi_table_data[i].sig_length)) { + if (!ACPI_STRNCMP (signature, acpi_gbl_table_data[i].signature, + acpi_gbl_table_data[i].sig_length)) { /* Found a signature match, return index if requested */ if (table_info) { @@ -94,7 +94,7 @@ acpi_tb_match_signature ( ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Table [%4.4s] is an ACPI table consumed by the core subsystem\n", - (char *) acpi_gbl_acpi_table_data[i].signature)); + (char *) acpi_gbl_table_data[i].signature)); return_ACPI_STATUS (AE_OK); } @@ -149,7 +149,7 @@ acpi_tb_install_table ( } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "%s located at %p\n", - acpi_gbl_acpi_table_data[table_info->type].name, table_info->pointer)); + acpi_gbl_table_data[table_info->type].name, table_info->pointer)); (void) acpi_ut_release_mutex (ACPI_MTX_TABLES); return_ACPI_STATUS (status); @@ -239,70 +239,58 @@ acpi_tb_init_table_descriptor ( acpi_table_type table_type, struct acpi_table_desc *table_info) { - struct acpi_table_desc *list_head; + struct acpi_table_list *list_head; struct acpi_table_desc *table_desc; ACPI_FUNCTION_TRACE_U32 ("tb_init_table_descriptor", table_type); + + /* Allocate a descriptor for this table */ + + table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc)); + if (!table_desc) { + return_ACPI_STATUS (AE_NO_MEMORY); + } + /* * Install the table into the global data structure */ - list_head = &acpi_gbl_acpi_tables[table_type]; - table_desc = list_head; + list_head = &acpi_gbl_table_lists[table_type]; /* * Two major types of tables: 1) Only one instance is allowed. This * includes most ACPI tables such as the DSDT. 2) Multiple instances of * the table are allowed. This includes SSDT and PSDTs. */ - if (ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags)) { + if (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags)) { /* * Only one table allowed, and a table has alread been installed * at this location, so return an error. */ - if (list_head->pointer) { + if (list_head->next) { return_ACPI_STATUS (AE_ALREADY_EXISTS); } - - table_desc->count = 1; - table_desc->prev = NULL; - table_desc->next = NULL; } - else { - /* - * Multiple tables allowed for this table type, we must link - * the new table in to the list of tables of this type. - */ - if (list_head->pointer) { - table_desc = ACPI_MEM_CALLOCATE (sizeof (struct acpi_table_desc)); - if (!table_desc) { - return_ACPI_STATUS (AE_NO_MEMORY); - } - - list_head->count++; - - /* Update the original previous */ - - list_head->prev->next = table_desc; - - /* Update new entry */ - table_desc->prev = list_head->prev; - table_desc->next = list_head; - - /* Update list head */ + /* + * Link the new table in to the list of tables of this type. + * Just insert at the start of the list, order unimportant. + * + * table_desc->Prev is already NULL from calloc() + */ + table_desc->next = list_head->next; + list_head->next = table_desc; - list_head->prev = table_desc; - } - else { - table_desc->count = 1; - } + if (table_desc->next) { + table_desc->next->prev = table_desc; } - /* Common initialization of the table descriptor */ + list_head->count++; - table_desc->type = table_info->type; + /* Finish initialization of the table descriptor */ + + table_desc->type = (u8) table_type; table_desc->pointer = table_info->pointer; table_desc->length = table_info->length; table_desc->allocation = table_info->allocation; @@ -316,8 +304,8 @@ acpi_tb_init_table_descriptor ( * Set the appropriate global pointer (if there is one) to point to the * newly installed table */ - if (acpi_gbl_acpi_table_data[table_type].global_ptr) { - *(acpi_gbl_acpi_table_data[table_type].global_ptr) = table_info->pointer; + if (acpi_gbl_table_data[table_type].global_ptr) { + *(acpi_gbl_table_data[table_type].global_ptr) = table_info->pointer; } /* Return Data */ @@ -331,7 +319,7 @@ acpi_tb_init_table_descriptor ( /******************************************************************************* * - * FUNCTION: acpi_tb_delete_acpi_tables + * FUNCTION: acpi_tb_delete_all_tables * * PARAMETERS: None. * @@ -342,7 +330,7 @@ acpi_tb_init_table_descriptor ( ******************************************************************************/ void -acpi_tb_delete_acpi_tables (void) +acpi_tb_delete_all_tables (void) { acpi_table_type type; @@ -351,15 +339,15 @@ acpi_tb_delete_acpi_tables (void) * Free memory allocated for ACPI tables * Memory can either be mapped or allocated */ - for (type = 0; type < NUM_ACPI_TABLES; type++) { - acpi_tb_delete_acpi_table (type); + for (type = 0; type < NUM_ACPI_TABLE_TYPES; type++) { + acpi_tb_delete_tables_by_type (type); } } /******************************************************************************* * - * FUNCTION: acpi_tb_delete_acpi_table + * FUNCTION: acpi_tb_delete_tables_by_type * * PARAMETERS: Type - The table type to be deleted * @@ -371,11 +359,15 @@ acpi_tb_delete_acpi_tables (void) ******************************************************************************/ void -acpi_tb_delete_acpi_table ( +acpi_tb_delete_tables_by_type ( acpi_table_type type) { + struct acpi_table_desc *table_desc; + u32 count; + u32 i; - ACPI_FUNCTION_TRACE_U32 ("tb_delete_acpi_table", type); + + ACPI_FUNCTION_TRACE_U32 ("tb_delete_tables_by_type", type); if (type > ACPI_TABLE_MAX) { @@ -416,43 +408,10 @@ acpi_tb_delete_acpi_table ( } /* Free the table */ - - acpi_tb_free_acpi_tables_of_type (&acpi_gbl_acpi_tables[type]); - - (void) acpi_ut_release_mutex (ACPI_MTX_TABLES); - return_VOID; -} - - -/******************************************************************************* - * - * FUNCTION: acpi_tb_free_acpi_tables_of_type - * - * PARAMETERS: table_info - A table info struct - * - * RETURN: None. - * - * DESCRIPTION: Free the memory associated with an internal ACPI table - * Table mutex should be locked. - * - ******************************************************************************/ - -void -acpi_tb_free_acpi_tables_of_type ( - struct acpi_table_desc *list_head) -{ - struct acpi_table_desc *table_desc; - u32 count; - u32 i; - - - ACPI_FUNCTION_TRACE_PTR ("tb_free_acpi_tables_of_type", list_head); - - /* Get the head of the list */ - table_desc = list_head; - count = list_head->count; + table_desc = acpi_gbl_table_lists[type].next; + count = acpi_gbl_table_lists[type].count; /* * Walk the entire list, deleting both the allocated tables @@ -462,6 +421,7 @@ acpi_tb_free_acpi_tables_of_type ( table_desc = acpi_tb_uninstall_table (table_desc); } + (void) acpi_ut_release_mutex (ACPI_MTX_TABLES); return_VOID; } @@ -484,30 +444,31 @@ acpi_tb_delete_single_table ( struct acpi_table_desc *table_desc) { - if (!table_desc) { + /* Must have a valid table descriptor and pointer */ + + if ((!table_desc) || + (!table_desc->pointer)) { return; } - if (table_desc->pointer) { - /* Valid table, determine type of memory allocation */ + /* Valid table, determine type of memory allocation */ - switch (table_desc->allocation) { - case ACPI_MEM_NOT_ALLOCATED: - break; + switch (table_desc->allocation) { + case ACPI_MEM_NOT_ALLOCATED: + break; - case ACPI_MEM_ALLOCATED: + case ACPI_MEM_ALLOCATED: - ACPI_MEM_FREE (table_desc->pointer); - break; + ACPI_MEM_FREE (table_desc->pointer); + break; - case ACPI_MEM_MAPPED: + case ACPI_MEM_MAPPED: - acpi_os_unmap_memory (table_desc->pointer, table_desc->length); - break; + acpi_os_unmap_memory (table_desc->pointer, table_desc->length); + break; - default: - break; - } + default: + break; } } @@ -533,18 +494,23 @@ acpi_tb_uninstall_table ( struct acpi_table_desc *next_desc; - ACPI_FUNCTION_TRACE_PTR ("acpi_tb_uninstall_table", table_desc); + ACPI_FUNCTION_TRACE_PTR ("tb_uninstall_table", table_desc); if (!table_desc) { return_PTR (NULL); } - /* Unlink the descriptor */ + /* Unlink the descriptor from the doubly linked list */ if (table_desc->prev) { table_desc->prev->next = table_desc->next; } + else { + /* Is first on list, update list head */ + + acpi_gbl_table_lists[table_desc->type].next = table_desc->next; + } if (table_desc->next) { table_desc->next->prev = table_desc->prev; @@ -554,23 +520,12 @@ acpi_tb_uninstall_table ( acpi_tb_delete_single_table (table_desc); - /* Free the table descriptor (Don't delete the list head, tho) */ - - if ((table_desc->prev) == (table_desc->next)) { - next_desc = NULL; + /* Free the table descriptor */ - /* Clear the list head */ + next_desc = table_desc->next; + ACPI_MEM_FREE (table_desc); - table_desc->pointer = NULL; - table_desc->length = 0; - table_desc->count = 0; - } - else { - /* Free the table descriptor */ - - next_desc = table_desc->next; - ACPI_MEM_FREE (table_desc); - } + /* Return pointer to the next descriptor */ return_PTR (next_desc); } diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 94a9f001490548ecca76e4e96c18cb4e26d750f6..7e087319532a78aba032edf197157839f67f1ea5 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -66,26 +66,25 @@ acpi_status acpi_tb_handle_to_object ( u16 table_id, - struct acpi_table_desc **table_desc) + struct acpi_table_desc **return_table_desc) { u32 i; - struct acpi_table_desc *list_head; + struct acpi_table_desc *table_desc; ACPI_FUNCTION_NAME ("tb_handle_to_object"); for (i = 0; i < ACPI_TABLE_MAX; i++) { - list_head = &acpi_gbl_acpi_tables[i]; - do { - if (list_head->table_id == table_id) { - *table_desc = list_head; + table_desc = acpi_gbl_table_lists[i].next; + while (table_desc) { + if (table_desc->table_id == table_id) { + *return_table_desc = table_desc; return (AE_OK); } - list_head = list_head->next; - - } while (list_head != &acpi_gbl_acpi_tables[i]); + table_desc = table_desc->next; + } } ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "table_id=%X does not exist\n", table_id)); diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index 43597f10f2f493991327c3bcd0ac99f4015ab353..76953d7fa0b44696fe65c396e2333f8aeef63463 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -235,7 +235,7 @@ acpi_status acpi_unload_table ( acpi_table_type table_type) { - struct acpi_table_desc *list_head; + struct acpi_table_desc *table_desc; ACPI_FUNCTION_TRACE ("acpi_unload_table"); @@ -250,22 +250,22 @@ acpi_unload_table ( /* Find all tables of the requested type */ - list_head = &acpi_gbl_acpi_tables[table_type]; - do { + table_desc = acpi_gbl_table_lists[table_type].next; + while (table_desc); { /* * Delete all namespace entries owned by this table. Note that these * entries can appear anywhere in the namespace by virtue of the AML * "Scope" operator. Thus, we need to track ownership by an ID, not * simply a position within the hierarchy */ - acpi_ns_delete_namespace_by_owner (list_head->table_id); + acpi_ns_delete_namespace_by_owner (table_desc->table_id); - /* Delete (or unmap) the actual table */ - - acpi_tb_delete_acpi_table (table_type); + table_desc = table_desc->next; + } - } while (list_head != &acpi_gbl_acpi_tables[table_type]); + /* Delete (or unmap) all tables of this type */ + acpi_tb_delete_tables_by_type (table_type); return_ACPI_STATUS (AE_OK); } @@ -313,7 +313,7 @@ acpi_get_table_header ( /* Check the table type and instance */ if ((table_type > ACPI_TABLE_MAX) || - (ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) && + (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) && instance > 1)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } @@ -394,7 +394,7 @@ acpi_get_table ( /* Check the table type and instance */ if ((table_type > ACPI_TABLE_MAX) || - (ACPI_IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) && + (ACPI_IS_SINGLE_TABLE (acpi_gbl_table_data[table_type].flags) && instance > 1)) { return_ACPI_STATUS (AE_BAD_PARAMETER); } diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c index ed2d6778721451a7d2308b614396af76323c587a..0cb16126e317b74309ca85a7ac0a1cda7f2a0dc5 100644 --- a/drivers/acpi/toshiba_acpi.c +++ b/drivers/acpi/toshiba_acpi.c @@ -33,7 +33,7 @@ * */ -#define TOSHIBA_ACPI_VERSION "0.14" +#define TOSHIBA_ACPI_VERSION "0.15" #define PROC_INTERFACE_VERSION 1 #include <linux/kernel.h> @@ -172,9 +172,7 @@ hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS]) for (i = 0; i < HCI_WORDS; ++i) { in_objs[i].type = ACPI_TYPE_INTEGER; in_objs[i].integer.value = in[i]; - /*printk("%04x ", in[i]);*/ } - /*printk("\n");*/ results.length = sizeof(out_objs); results.pointer = out_objs; @@ -184,9 +182,7 @@ hci_raw(const u32 in[HCI_WORDS], u32 out[HCI_WORDS]) if ((status == AE_OK) && (out_objs->package.count <= HCI_WORDS)) { for (i = 0; i < out_objs->package.count; ++i) { out[i] = out_objs->package.elements[i].integer.value; - /*printk("%04x ", out[i]);*/ } - /*printk("\n");*/ } return status; @@ -226,7 +222,7 @@ static int key_event_valid; typedef struct _ProcItem { - char* name; + const char* name; char* (*read_func)(char*); unsigned long (*write_func)(const char*, unsigned long); } ProcItem; @@ -284,10 +280,8 @@ static unsigned long write_lcd(const char* buffer, unsigned long count) { int value; - /*int byte_count;*/ u32 hci_result; - /* ISSUE: %i doesn't work with hex values as advertised */ if (snscanf(buffer, count, " brightness : %i", &value) == 1 && value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) { value = value << HCI_LCD_BRIGHTNESS_SHIFT; @@ -414,6 +408,11 @@ read_keys(char* p) last_key_event = value; } else if (hci_result == HCI_EMPTY) { /* better luck next time */ + } else if (hci_result == HCI_NOT_SUPPORTED) { + /* This is a workaround for an unresolved issue on + * some machines where system events sporadically + * become disabled. */ + hci_write1(HCI_SYSTEM_EVENT, 1, &hci_result); } else { p += sprintf(p, "ERROR\n"); goto end; diff --git a/drivers/acpi/utilities/utcopy.c b/drivers/acpi/utilities/utcopy.c index 441920d56f6a44bacf9325a25d57cfa2472cdfb0..c21679c5aa579dbdfd7fa5be6314320845d4f7dd 100644 --- a/drivers/acpi/utilities/utcopy.c +++ b/drivers/acpi/utilities/utcopy.c @@ -651,13 +651,21 @@ acpi_ut_copy_simple_object ( */ if ((source_desc->buffer.pointer) && (!(source_desc->common.flags & AOPOBJ_STATIC_POINTER))) { - dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length); - if (!dest_desc->buffer.pointer) { - return (AE_NO_MEMORY); - } + dest_desc->buffer.pointer = NULL; + + /* Create an actual buffer only if length > 0 */ - ACPI_MEMCPY (dest_desc->buffer.pointer, source_desc->buffer.pointer, - source_desc->buffer.length); + if (source_desc->buffer.length) { + dest_desc->buffer.pointer = ACPI_MEM_ALLOCATE (source_desc->buffer.length); + if (!dest_desc->buffer.pointer) { + return (AE_NO_MEMORY); + } + + /* Copy the actual buffer data */ + + ACPI_MEMCPY (dest_desc->buffer.pointer, source_desc->buffer.pointer, + source_desc->buffer.length); + } } break; diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c index 2e2b8f44d47ee960de3c758a0fda8c636975a33b..ea0fcb867caaac6b118aee0f762a5b8f7025442f 100644 --- a/drivers/acpi/utilities/utdelete.c +++ b/drivers/acpi/utilities/utdelete.c @@ -71,6 +71,7 @@ acpi_ut_delete_internal_obj ( void *obj_pointer = NULL; union acpi_operand_object *handler_desc; union acpi_operand_object *second_desc; + union acpi_operand_object *next_desc; ACPI_FUNCTION_TRACE_PTR ("ut_delete_internal_obj", object); @@ -136,6 +137,15 @@ acpi_ut_delete_internal_obj ( if (object->device.gpe_block) { (void) acpi_ev_delete_gpe_block (object->device.gpe_block); } + + /* Walk the handler list for this device */ + + handler_desc = object->device.address_space; + while (handler_desc) { + next_desc = handler_desc->address_space.next; + acpi_ut_remove_reference (handler_desc); + handler_desc = next_desc; + } break; @@ -183,10 +193,13 @@ acpi_ut_delete_internal_obj ( * default handlers -- and therefore, we created the context object * locally, it was not created by an external caller. */ - handler_desc = object->region.addr_handler; - if ((handler_desc) && - (handler_desc->addr_handler.hflags == ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { - obj_pointer = second_desc->extra.region_context; + handler_desc = object->region.address_space; + if (handler_desc) { + if (handler_desc->address_space.hflags & ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) { + obj_pointer = second_desc->extra.region_context; + } + + acpi_ut_remove_reference (handler_desc); } /* Now we can free the Extra object */ @@ -211,7 +224,6 @@ acpi_ut_delete_internal_obj ( break; } - /* Free any allocated memory (pointer within the object) found above */ if (obj_pointer) { @@ -299,7 +311,7 @@ acpi_ut_update_ref_count ( new_count = count; /* - * Reference count action (increment, decrement, or force delete) + * Perform the reference count action (increment, decrement, or force delete) */ switch (action) { @@ -402,8 +414,6 @@ acpi_ut_update_object_reference ( { acpi_status status; u32 i; - union acpi_operand_object *next; - union acpi_operand_object *new; union acpi_generic_state *state_list = NULL; union acpi_generic_state *state; @@ -417,9 +427,8 @@ acpi_ut_update_object_reference ( return_ACPI_STATUS (AE_OK); } - /* - * Make sure that this isn't a namespace handle - */ + /* Make sure that this isn't a namespace handle */ + if (ACPI_GET_DESCRIPTOR_TYPE (object) == ACPI_DESC_TYPE_NAMED) { ACPI_DEBUG_PRINT ((ACPI_DB_ALLOCATIONS, "Object %p is NS handle\n", object)); return_ACPI_STATUS (AE_OK); @@ -439,28 +448,8 @@ acpi_ut_update_object_reference ( switch (ACPI_GET_OBJECT_TYPE (object)) { case ACPI_TYPE_DEVICE: - status = acpi_ut_create_update_state_and_push (object->device.addr_handler, - action, &state_list); - if (ACPI_FAILURE (status)) { - goto error_exit; - } - - acpi_ut_update_ref_count (object->device.sys_handler, action); - acpi_ut_update_ref_count (object->device.drv_handler, action); - break; - - - case ACPI_TYPE_LOCAL_ADDRESS_HANDLER: - - /* Must walk list of address handlers */ - - next = object->addr_handler.next; - while (next) { - new = next->addr_handler.next; - acpi_ut_update_ref_count (next, action); - - next = new; - } + acpi_ut_update_ref_count (object->device.system_notify, action); + acpi_ut_update_ref_count (object->device.device_notify, action); break; @@ -590,16 +579,14 @@ acpi_ut_add_reference ( ACPI_FUNCTION_TRACE_PTR ("ut_add_reference", object); - /* - * Ensure that we have a valid object - */ + /* Ensure that we have a valid object */ + if (!acpi_ut_valid_internal_object (object)) { return_VOID; } - /* - * We have a valid ACPI internal object, now increment the reference count - */ + /* Increment the reference count */ + (void) acpi_ut_update_object_reference (object, REF_INCREMENT); return_VOID; } @@ -624,6 +611,7 @@ acpi_ut_remove_reference ( ACPI_FUNCTION_TRACE_PTR ("ut_remove_reference", object); + /* * Allow a NULL pointer to be passed in, just ignore it. This saves * each caller from having to check. Also, ignore NS nodes. @@ -634,9 +622,8 @@ acpi_ut_remove_reference ( return_VOID; } - /* - * Ensure that we have a valid object - */ + /* Ensure that we have a valid object */ + if (!acpi_ut_valid_internal_object (object)) { return_VOID; } diff --git a/drivers/acpi/utilities/uteval.c b/drivers/acpi/utilities/uteval.c index 141f21af0cd76aa85e48f5f36b95214fc6a26bb7..4b4cd90fe5610dcaa8727b15bbcc7beb973fc767 100644 --- a/drivers/acpi/utilities/uteval.c +++ b/drivers/acpi/utilities/uteval.c @@ -208,6 +208,46 @@ acpi_ut_evaluate_numeric_object ( } +/******************************************************************************* + * + * FUNCTION: acpi_ut_copy_id_string + * + * PARAMETERS: Destination - Where to copy the string + * Source - Source string + * max_length - Length of the destination buffer + * + * RETURN: None + * + * DESCRIPTION: Copies an ID string for the _HID, _CID, and _UID methods. + * Performs removal of a leading asterisk if present -- workaround + * for a known issue on a bunch of machines. + * + ******************************************************************************/ + +static void +acpi_ut_copy_id_string ( + char *destination, + char *source, + acpi_size max_length) +{ + + + /* + * Workaround for ID strings that have a leading asterisk. This construct + * is not allowed by the ACPI specification (ID strings must be + * alphanumeric), but enough existing machines have this embedded in their + * ID strings that the following code is useful. + */ + if (*source == '*') { + source++; + } + + /* Do the actual copy */ + + ACPI_STRNCPY (destination, source, max_length); +} + + /******************************************************************************* * * FUNCTION: acpi_ut_execute_HID @@ -245,12 +285,13 @@ acpi_ut_execute_HID ( if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { /* Convert the Numeric HID to string */ - acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->buffer); + acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, hid->value); } else { /* Copy the String HID from the returned object */ - ACPI_STRNCPY (hid->buffer, obj_desc->string.pointer, sizeof(hid->buffer)); + acpi_ut_copy_id_string (hid->value, obj_desc->string.pointer, + sizeof (hid->value)); } /* On exit, we must delete the return object */ @@ -260,6 +301,57 @@ acpi_ut_execute_HID ( } +/******************************************************************************* + * + * FUNCTION: acpi_ut_translate_one_cid + * + * PARAMETERS: obj_desc - _CID object, must be integer or string + * one_cid - Where the CID string is returned + * + * RETURN: Status + * + * DESCRIPTION: Return a numeric or string _CID value as a string. + * (Compatible ID) + * + * NOTE: Assumes a maximum _CID string length of + * ACPI_MAX_CID_LENGTH. + * + ******************************************************************************/ + +static acpi_status +acpi_ut_translate_one_cid ( + union acpi_operand_object *obj_desc, + struct acpi_compatible_id *one_cid) +{ + + + switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { + case ACPI_TYPE_INTEGER: + + /* Convert the Numeric CID to string */ + + acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, one_cid->value); + return (AE_OK); + + case ACPI_TYPE_STRING: + + if (obj_desc->string.length > ACPI_MAX_CID_LENGTH) { + return (AE_AML_STRING_LIMIT); + } + + /* Copy the String CID from the returned object */ + + acpi_ut_copy_id_string (one_cid->value, obj_desc->string.pointer, + ACPI_MAX_CID_LENGTH); + return (AE_OK); + + default: + + return (AE_TYPE); + } +} + + /******************************************************************************* * * FUNCTION: acpi_ut_execute_CID @@ -279,55 +371,86 @@ acpi_ut_execute_HID ( acpi_status acpi_ut_execute_CID ( struct acpi_namespace_node *device_node, - struct acpi_device_id *cid) + struct acpi_compatible_id_list **return_cid_list) { union acpi_operand_object *obj_desc; acpi_status status; + u32 count; + u32 size; + struct acpi_compatible_id_list *cid_list; + acpi_native_uint i; ACPI_FUNCTION_TRACE ("ut_execute_CID"); + /* Evaluate the _CID method for this device */ + status = acpi_ut_evaluate_object (device_node, METHOD_NAME__CID, - ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE, &obj_desc); + ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_PACKAGE, + &obj_desc); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } - /* - * A _CID can return either a single compatible ID or a package of compatible - * IDs. Each compatible ID can be a Number (32 bit compressed EISA ID) or - * string (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss"). - */ - switch (ACPI_GET_OBJECT_TYPE (obj_desc)) { - case ACPI_TYPE_INTEGER: + /* Get the number of _CIDs returned */ - /* Convert the Numeric CID to string */ + count = 1; + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) { + count = obj_desc->package.count; + } - acpi_ex_eisa_id_to_string ((u32) obj_desc->integer.value, cid->buffer); - break; + /* Allocate a worst-case buffer for the _CIDs */ - case ACPI_TYPE_STRING: + size = (((count - 1) * sizeof (struct acpi_compatible_id)) + + sizeof (struct acpi_compatible_id_list)); - /* Copy the String CID from the returned object */ + cid_list = ACPI_MEM_CALLOCATE ((acpi_size) size); + if (!cid_list) { + return_ACPI_STATUS (AE_NO_MEMORY); + } - ACPI_STRNCPY (cid->buffer, obj_desc->string.pointer, sizeof (cid->buffer)); - break; + /* Init CID list */ - case ACPI_TYPE_PACKAGE: + cid_list->count = count; + cid_list->size = size; - /* TBD: Parse package elements; need different return struct, etc. */ + /* + * A _CID can return either a single compatible ID or a package of compatible + * IDs. Each compatible ID can be one of the following: + * -- Number (32 bit compressed EISA ID) or + * -- String (PCI ID format, e.g. "PCI\VEN_vvvv&DEV_dddd&SUBSYS_ssssssss"). + */ - status = AE_SUPPORT; - break; + /* The _CID object can be either a single CID or a package (list) of CIDs */ - default: + if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_PACKAGE) { + /* Translate each package element */ - status = AE_TYPE; - break; + for (i = 0; i < count; i++) { + status = acpi_ut_translate_one_cid (obj_desc->package.elements[i], + &cid_list->id[i]); + if (ACPI_FAILURE (status)) { + break; + } + } } + else { + /* Only one CID, translate to a string */ - /* On exit, we must delete the return object */ + status = acpi_ut_translate_one_cid (obj_desc, cid_list->id); + } + + /* Cleanup on error */ + + if (ACPI_FAILURE (status)) { + ACPI_MEM_FREE (cid_list); + } + else { + *return_cid_list = cid_list; + } + + /* On exit, we must delete the _CID return object */ acpi_ut_remove_reference (obj_desc); return_ACPI_STATUS (status); @@ -371,12 +494,13 @@ acpi_ut_execute_UID ( if (ACPI_GET_OBJECT_TYPE (obj_desc) == ACPI_TYPE_INTEGER) { /* Convert the Numeric UID to string */ - acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer); + acpi_ex_unsigned_integer_to_string (obj_desc->integer.value, uid->value); } else { /* Copy the String UID from the returned object */ - ACPI_STRNCPY (uid->buffer, obj_desc->string.pointer, sizeof (uid->buffer)); + acpi_ut_copy_id_string (uid->value, obj_desc->string.pointer, + sizeof (uid->value)); } /* On exit, we must delete the return object */ diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index b2d14d924cd94c29d3bf572be93e4700eb82a0ce..51c01acfdb0a573d2cc37e3e450265809b381b12 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -299,10 +299,10 @@ acpi_ut_hex_to_ascii_char ( ******************************************************************************/ -struct acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES]; +struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES]; -struct acpi_table_support acpi_gbl_acpi_table_data[NUM_ACPI_TABLES] = +struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES] = { /*********** Name, Signature, Global typed pointer Signature size, Type How many allowed?, Contains valid AML? */ @@ -535,12 +535,10 @@ acpi_ut_get_object_type_name ( #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) - /* * Strings and procedures used for debug only */ - /***************************************************************************** * * FUNCTION: acpi_ut_get_mutex_name @@ -558,7 +556,7 @@ acpi_ut_get_mutex_name ( u32 mutex_id) { - if (mutex_id > MAX_MTX) + if (mutex_id > MAX_MUTEX) { return ("Invalid Mutex ID"); } @@ -566,7 +564,6 @@ acpi_ut_get_mutex_name ( return (acpi_gbl_mutex_names[mutex_id]); } - #endif @@ -630,9 +627,12 @@ acpi_ut_allocate_owner_id ( owner_id = acpi_gbl_next_table_owner_id; acpi_gbl_next_table_owner_id++; + /* Check for wraparound */ + if (acpi_gbl_next_table_owner_id == ACPI_FIRST_METHOD_ID) { acpi_gbl_next_table_owner_id = ACPI_FIRST_TABLE_ID; + ACPI_REPORT_WARNING (("Table owner ID wraparound\n")); } break; @@ -644,6 +644,8 @@ acpi_ut_allocate_owner_id ( if (acpi_gbl_next_method_owner_id == ACPI_FIRST_TABLE_ID) { + /* Check for wraparound */ + acpi_gbl_next_method_owner_id = ACPI_FIRST_METHOD_ID; } break; @@ -710,23 +712,19 @@ acpi_ut_init_globals ( /* ACPI table structure */ - for (i = 0; i < NUM_ACPI_TABLES; i++) + for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) { - acpi_gbl_acpi_tables[i].prev = &acpi_gbl_acpi_tables[i]; - acpi_gbl_acpi_tables[i].next = &acpi_gbl_acpi_tables[i]; - acpi_gbl_acpi_tables[i].pointer = NULL; - acpi_gbl_acpi_tables[i].length = 0; - acpi_gbl_acpi_tables[i].allocation = ACPI_MEM_NOT_ALLOCATED; - acpi_gbl_acpi_tables[i].count = 0; + acpi_gbl_table_lists[i].next = NULL; + acpi_gbl_table_lists[i].count = 0; } /* Mutex locked flags */ - for (i = 0; i < NUM_MTX; i++) + for (i = 0; i < NUM_MUTEX; i++) { - acpi_gbl_acpi_mutex_info[i].mutex = NULL; - acpi_gbl_acpi_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED; - acpi_gbl_acpi_mutex_info[i].use_count = 0; + acpi_gbl_mutex_info[i].mutex = NULL; + acpi_gbl_mutex_info[i].owner_id = ACPI_MUTEX_NOT_ACQUIRED; + acpi_gbl_mutex_info[i].use_count = 0; } /* GPE support */ @@ -737,8 +735,8 @@ acpi_ut_init_globals ( /* Global notify handlers */ - acpi_gbl_sys_notify.handler = NULL; - acpi_gbl_drv_notify.handler = NULL; + acpi_gbl_system_notify.handler = NULL; + acpi_gbl_device_notify.handler = NULL; acpi_gbl_init_handler = NULL; /* Global "typed" ACPI table pointers */ diff --git a/drivers/acpi/utilities/utmisc.c b/drivers/acpi/utilities/utmisc.c index 6894c58aa201ce1eb7ed3206caf0cf229c2f8c0f..b16c01e8355993f815f9d07ab926989a58ba59f5 100644 --- a/drivers/acpi/utilities/utmisc.c +++ b/drivers/acpi/utilities/utmisc.c @@ -549,7 +549,7 @@ acpi_ut_mutex_initialize ( /* * Create each of the predefined mutex objects */ - for (i = 0; i < NUM_MTX; i++) { + for (i = 0; i < NUM_MUTEX; i++) { status = acpi_ut_create_mutex (i); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); @@ -588,7 +588,7 @@ acpi_ut_mutex_terminate ( /* * Delete each predefined mutex object */ - for (i = 0; i < NUM_MTX; i++) { + for (i = 0; i < NUM_MUTEX; i++) { (void) acpi_ut_delete_mutex (i); } @@ -619,15 +619,15 @@ acpi_ut_create_mutex ( ACPI_FUNCTION_TRACE_U32 ("ut_create_mutex", mutex_id); - if (mutex_id > MAX_MTX) { + if (mutex_id > MAX_MUTEX) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - if (!acpi_gbl_acpi_mutex_info[mutex_id].mutex) { + if (!acpi_gbl_mutex_info[mutex_id].mutex) { status = acpi_os_create_semaphore (1, 1, - &acpi_gbl_acpi_mutex_info[mutex_id].mutex); - acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; - acpi_gbl_acpi_mutex_info[mutex_id].use_count = 0; + &acpi_gbl_mutex_info[mutex_id].mutex); + acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; + acpi_gbl_mutex_info[mutex_id].use_count = 0; } return_ACPI_STATUS (status); @@ -656,14 +656,14 @@ acpi_ut_delete_mutex ( ACPI_FUNCTION_TRACE_U32 ("ut_delete_mutex", mutex_id); - if (mutex_id > MAX_MTX) { + if (mutex_id > MAX_MUTEX) { return_ACPI_STATUS (AE_BAD_PARAMETER); } - status = acpi_os_delete_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex); + status = acpi_os_delete_semaphore (acpi_gbl_mutex_info[mutex_id].mutex); - acpi_gbl_acpi_mutex_info[mutex_id].mutex = NULL; - acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; + acpi_gbl_mutex_info[mutex_id].mutex = NULL; + acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; return_ACPI_STATUS (status); } @@ -693,7 +693,7 @@ acpi_ut_acquire_mutex ( ACPI_FUNCTION_NAME ("ut_acquire_mutex"); - if (mutex_id > MAX_MTX) { + if (mutex_id > MAX_MUTEX) { return (AE_BAD_PARAMETER); } @@ -705,8 +705,8 @@ acpi_ut_acquire_mutex ( * the mutex ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ - for (i = mutex_id; i < MAX_MTX; i++) { - if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) { + for (i = mutex_id; i < MAX_MUTEX; i++) { + if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { if (i == mutex_id) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Mutex [%s] already acquired by this thread [%X]\n", @@ -728,14 +728,14 @@ acpi_ut_acquire_mutex ( "Thread %X attempting to acquire Mutex [%s]\n", this_thread_id, acpi_ut_get_mutex_name (mutex_id))); - status = acpi_os_wait_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, + status = acpi_os_wait_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1, ACPI_WAIT_FOREVER); if (ACPI_SUCCESS (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n", this_thread_id, acpi_ut_get_mutex_name (mutex_id))); - acpi_gbl_acpi_mutex_info[mutex_id].use_count++; - acpi_gbl_acpi_mutex_info[mutex_id].owner_id = this_thread_id; + acpi_gbl_mutex_info[mutex_id].use_count++; + acpi_gbl_mutex_info[mutex_id].owner_id = this_thread_id; } else { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n", @@ -776,14 +776,14 @@ acpi_ut_release_mutex ( "Thread %X releasing Mutex [%s]\n", this_thread_id, acpi_ut_get_mutex_name (mutex_id))); - if (mutex_id > MAX_MTX) { + if (mutex_id > MAX_MUTEX) { return (AE_BAD_PARAMETER); } /* * Mutex must be acquired in order to release it! */ - if (acpi_gbl_acpi_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) { + if (acpi_gbl_mutex_info[mutex_id].owner_id == ACPI_MUTEX_NOT_ACQUIRED) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Mutex [%s] is not acquired, cannot release\n", acpi_ut_get_mutex_name (mutex_id))); @@ -797,8 +797,8 @@ acpi_ut_release_mutex ( * ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ - for (i = mutex_id; i < MAX_MTX; i++) { - if (acpi_gbl_acpi_mutex_info[i].owner_id == this_thread_id) { + for (i = mutex_id; i < MAX_MUTEX; i++) { + if (acpi_gbl_mutex_info[i].owner_id == this_thread_id) { if (i == mutex_id) { continue; } @@ -813,9 +813,9 @@ acpi_ut_release_mutex ( /* Mark unlocked FIRST */ - acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; + acpi_gbl_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; - status = acpi_os_signal_semaphore (acpi_gbl_acpi_mutex_info[mutex_id].mutex, 1); + status = acpi_os_signal_semaphore (acpi_gbl_mutex_info[mutex_id].mutex, 1); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n", diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c index aa7dd52cf37a1dcd5d9838f84525479dbbb4ce9e..2d63be55f066f2e57b0abe5745113d97356a0537 100644 --- a/drivers/acpi/utilities/utobject.c +++ b/drivers/acpi/utilities/utobject.c @@ -149,7 +149,7 @@ acpi_ut_create_buffer_object ( acpi_size buffer_size) { union acpi_operand_object *buffer_desc; - u8 *buffer; + u8 *buffer = NULL; ACPI_FUNCTION_TRACE_U32 ("ut_create_buffer_object", buffer_size); @@ -163,14 +163,18 @@ acpi_ut_create_buffer_object ( return_PTR (NULL); } - /* Allocate the actual buffer */ + /* Create an actual buffer only if size > 0 */ - buffer = ACPI_MEM_CALLOCATE (buffer_size); - if (!buffer) { - ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n", - (u32) buffer_size)); - acpi_ut_remove_reference (buffer_desc); - return_PTR (NULL); + if (buffer_size > 0) { + /* Allocate the actual buffer */ + + buffer = ACPI_MEM_CALLOCATE (buffer_size); + if (!buffer) { + ACPI_REPORT_ERROR (("create_buffer: could not allocate size %X\n", + (u32) buffer_size)); + acpi_ut_remove_reference (buffer_desc); + return_PTR (NULL); + } } /* Complete buffer object initialization */ diff --git a/drivers/acpi/utilities/utxface.c b/drivers/acpi/utilities/utxface.c index b1eeb9e49fbc8ef380f4101611684d8b0f519011..cf03534522feea66f1e8ce3d84cdcd1be370a9bd 100644 --- a/drivers/acpi/utilities/utxface.c +++ b/drivers/acpi/utilities/utxface.c @@ -144,23 +144,9 @@ acpi_enable_subsystem ( ACPI_FUNCTION_TRACE ("acpi_enable_subsystem"); - /* - * Install the default op_region handlers. These are installed unless - * other handlers have already been installed via the - * install_address_space_handler interface - */ - if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n")); - - status = acpi_ev_init_address_spaces (); - if (ACPI_FAILURE (status)) { - return_ACPI_STATUS (status); - } - } - /* * We must initialize the hardware before we can enable ACPI. - * FADT values are validated here. + * The values from the FADT are validated here. */ if (!(flags & ACPI_NO_HARDWARE_INIT)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI hardware\n")); @@ -172,7 +158,7 @@ acpi_enable_subsystem ( } /* - * Enable ACPI on this platform + * Enable ACPI mode */ if (!(flags & ACPI_NO_ACPI_ENABLE)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Going into ACPI mode\n")); @@ -187,8 +173,9 @@ acpi_enable_subsystem ( } /* - * Note: - * We must have the hardware AND events initialized before we can execute + * Initialize ACPI Event handling + * + * NOTE: We must have the hardware AND events initialized before we can execute * ANY control methods SAFELY. Any control method can require ACPI hardware * support, so the hardware MUST be initialized before execution! */ @@ -201,7 +188,7 @@ acpi_enable_subsystem ( } } - /* Install SCI handler, Global Lock handler, GPE handlers */ + /* Install the SCI handler, Global Lock handler, and GPE handlers */ if (!(flags & ACPI_NO_HANDLER_INIT)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing SCI/GL/GPE handlers\n")); @@ -237,14 +224,20 @@ acpi_initialize_objects ( ACPI_FUNCTION_TRACE ("acpi_initialize_objects"); + /* - * Initialize all device objects in the namespace - * This runs the _STA and _INI methods. + * Install the default op_region handlers. These are installed unless + * other handlers have already been installed via the + * install_address_space_handler interface. + * + * NOTE: This will cause _REG methods to be run. Any objects accessed + * by the _REG methods will be automatically initialized, even if they + * contain executable AML (see call to acpi_ns_initialize_objects below). */ - if (!(flags & ACPI_NO_DEVICE_INIT)) { - ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n")); + if (!(flags & ACPI_NO_ADDRESS_SPACE_INIT)) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Installing default address space handlers\n")); - status = acpi_ns_initialize_devices (); + status = acpi_ev_init_address_spaces (); if (ACPI_FAILURE (status)) { return_ACPI_STATUS (status); } @@ -252,8 +245,8 @@ acpi_initialize_objects ( /* * Initialize the objects that remain uninitialized. This - * runs the executable AML that is part of the declaration of op_regions - * and Fields. + * runs the executable AML that may be part of the declaration of these + * objects: operation_regions, buffer_fields, Buffers, and Packages. */ if (!(flags & ACPI_NO_OBJECT_INIT)) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Objects\n")); @@ -264,6 +257,19 @@ acpi_initialize_objects ( } } + /* + * Initialize all device objects in the namespace + * This runs the _STA and _INI methods. + */ + if (!(flags & ACPI_NO_DEVICE_INIT)) { + ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "[Init] Initializing ACPI Devices\n")); + + status = acpi_ns_initialize_devices (); + if (ACPI_FAILURE (status)) { + return_ACPI_STATUS (status); + } + } + /* * Empty the caches (delete the cached objects) on the assumption that * the table load filled them up more than they will be at runtime -- @@ -431,9 +437,9 @@ acpi_get_system_info ( /* Current status of the ACPI tables, per table type */ - info_ptr->num_table_types = NUM_ACPI_TABLES; - for (i = 0; i < NUM_ACPI_TABLES; i++) { - info_ptr->table_info[i].count = acpi_gbl_acpi_tables[i].count; + info_ptr->num_table_types = NUM_ACPI_TABLE_TYPES; + for (i = 0; i < NUM_ACPI_TABLE_TYPES; i++) { + info_ptr->table_info[i].count = acpi_gbl_table_lists[i].count; } return_ACPI_STATUS (AE_OK); diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 8ad09844971f130314576ade92533e78b381804c..00985933a64250fd87c944b395baedb5f9dc3066 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -247,7 +247,7 @@ static ide_startstop_t write_intr (ide_drive_t *drive) * * Returns 0 on success. * - * Note that we may be called from two contexts - the do_rw_disk context + * Note that we may be called from two contexts - __ide_do_rw_disk() context * and IRQ context. The IRQ can happen any time after we've output the * full "mcount" number of sectors, so we must make sure we update the * state _before_ we output the final part of the data! @@ -351,11 +351,11 @@ static ide_startstop_t multwrite_intr (ide_drive_t *drive) } /* - * do_rw_disk() issues READ and WRITE commands to a disk, + * __ide_do_rw_disk() issues READ and WRITE commands to a disk, * using LBA if supported, or CHS otherwise, to address sectors. * It also takes care of issuing special DRIVE_CMDs. */ -static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) +ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) { ide_hwif_t *hwif = HWIF(drive); u8 lba48 = (drive->addressing == 1) ? 1 : 0; @@ -367,11 +367,6 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto if (driver_blocked) panic("Request while ide driver is blocked?"); -#if defined(CONFIG_BLK_DEV_PDC4030) || defined(CONFIG_BLK_DEV_PDC4030_MODULE) - if (IS_PDC4030_DRIVE) - return promise_rw_disk(drive, rq, block); -#endif /* CONFIG_BLK_DEV_PDC4030 */ - if (drive->using_tcq && idedisk_start_tag(drive, rq)) { if (!ata_pending_commands(drive)) BUG(); @@ -550,10 +545,11 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto } return ide_started; } - blk_dump_rq_flags(rq, "do_rw_disk - bad command"); + blk_dump_rq_flags(rq, "__ide_do_rw_disk - bad command"); ide_end_request(drive, 0, 0); return ide_stopped; } +EXPORT_SYMBOL_GPL(__ide_do_rw_disk); #else /* CONFIG_IDE_TASKFILE_IO */ @@ -562,15 +558,15 @@ static ide_startstop_t lba_28_rw_disk(ide_drive_t *, struct request *, unsigned static ide_startstop_t lba_48_rw_disk(ide_drive_t *, struct request *, unsigned long long); /* - * do_rw_disk() issues READ and WRITE commands to a disk, + * __ide_do_rw_disk() issues READ and WRITE commands to a disk, * using LBA if supported, or CHS otherwise, to address sectors. * It also takes care of issuing special DRIVE_CMDs. */ -static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) +ide_startstop_t __ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) { BUG_ON(drive->blocked); if (!blk_fs_request(rq)) { - blk_dump_rq_flags(rq, "do_rw_disk - bad command"); + blk_dump_rq_flags(rq, "__ide_do_rw_disk - bad command"); ide_end_request(drive, 0, 0); return ide_stopped; } @@ -581,11 +577,6 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto * need to add split taskfile operations based on 28bit threshold. */ -#if defined(CONFIG_BLK_DEV_PDC4030) || defined(CONFIG_BLK_DEV_PDC4030_MODULE) - if (IS_PDC4030_DRIVE) - return promise_rw_disk(drive, rq, block); -#endif /* CONFIG_BLK_DEV_PDC4030 */ - if (drive->using_tcq && idedisk_start_tag(drive, rq)) { if (!ata_pending_commands(drive)) BUG(); @@ -601,6 +592,7 @@ static ide_startstop_t do_rw_disk (ide_drive_t *drive, struct request *rq, secto /* 28-bit CHS : DIE DIE DIE piece of legacy crap!!! */ return chs_rw_disk(drive, rq, (unsigned long) block); } +EXPORT_SYMBOL_GPL(__ide_do_rw_disk); static task_ioreg_t get_command (ide_drive_t *drive, int cmd) { @@ -760,6 +752,16 @@ static ide_startstop_t lba_48_rw_disk (ide_drive_t *drive, struct request *rq, u #endif /* CONFIG_IDE_TASKFILE_IO */ +static ide_startstop_t ide_do_rw_disk (ide_drive_t *drive, struct request *rq, sector_t block) +{ + ide_hwif_t *hwif = HWIF(drive); + + if (hwif->rw_disk) + return hwif->rw_disk(drive, rq, block); + else + return __ide_do_rw_disk(drive, rq, block); +} + static int do_idedisk_flushcache(ide_drive_t *drive); static u8 idedisk_dump_status (ide_drive_t *drive, const char *msg, u8 stat) @@ -1541,11 +1543,6 @@ static void idedisk_setup (ide_drive_t *drive) struct hd_driveid *id = drive->id; unsigned long capacity; -#if 0 - if (IS_PDC4030_DRIVE) - DRIVER(drive)->do_request = promise_rw_disk; -#endif - idedisk_add_settings(drive); if (drive->id_read == 0) @@ -1674,7 +1671,7 @@ static ide_driver_t idedisk_driver = { .supports_dsc_overlap = 0, .cleanup = idedisk_cleanup, .flushcache = do_idedisk_flushcache, - .do_request = do_rw_disk, + .do_request = ide_do_rw_disk, .sense = idedisk_dump_status, .error = idedisk_error, .abort = idedisk_abort, diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 5967fe4337787d972816a6a0c97018f320c3c953..142a84ae4507da513d26ae5821739215a374a826 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -913,6 +913,8 @@ int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp) } for (index = 0; index < MAX_HWIFS; ++index) { hwif = &ide_hwifs[index]; + if (hwif->hold) + continue; if ((!hwif->present && !hwif->mate && !initializing) || (!hwif->hw.io_ports[IDE_DATA_OFFSET] && initializing)) goto found; @@ -924,6 +926,8 @@ int ide_register_hw (hw_regs_t *hw, ide_hwif_t **hwifp) found: if (hwif->present) ide_unregister(index); + else if (!hwif->hold) + init_hwif_data(index); if (hwif->present) return -1; memcpy(&hwif->hw, hw, sizeof(*hw)); diff --git a/drivers/ide/legacy/ali14xx.c b/drivers/ide/legacy/ali14xx.c index 5d3e85a59e33e863d3b2d1c8336147d6093117d6..acbe02fc156a6c7e3d6f43b07eedee633ab15c7a 100644 --- a/drivers/ide/legacy/ali14xx.c +++ b/drivers/ide/legacy/ali14xx.c @@ -54,13 +54,7 @@ #include <asm/io.h> -#ifdef CONFIG_BLK_DEV_ALI14XX_MODULE -# define _IDE_C -# include "ide_modes.h" -# undef _IDE_C -#else -# include "ide_modes.h" -#endif /* CONFIG_BLK_DEV_ALI14XX_MODULE */ +#include "ide_modes.h" /* port addresses for auto-detection */ #define ALI_NUM_PORTS 4 diff --git a/drivers/ide/legacy/dtc2278.c b/drivers/ide/legacy/dtc2278.c index fad634599dd081d006f47c68511fc72a3fdf45b3..c89e28e8894076b47fbb6845bb03825c7e000fd2 100644 --- a/drivers/ide/legacy/dtc2278.c +++ b/drivers/ide/legacy/dtc2278.c @@ -21,13 +21,7 @@ #include <asm/io.h> -#ifdef CONFIG_BLK_DEV_DTC2278_MODULE -# define _IDE_C -# include "ide_modes.h" -# undef _IDE_C -#else -# include "ide_modes.h" -#endif /* CONFIG_BLK_DEV_DTC2278_MODULE */ +#include "ide_modes.h" /* * Changing this #undef to #define may solve start up problems in some systems. diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c index 104a99d1af0f9a30ae6cd7f4fcf207c3f35d0684..dc5cfc7a8c4e347778e4f637556ff8eda81ba8bd 100644 --- a/drivers/ide/legacy/ht6560b.c +++ b/drivers/ide/legacy/ht6560b.c @@ -53,13 +53,7 @@ #include <asm/io.h> -#ifdef CONFIG_BLK_DEV_HT6560B_MODULE -# define _IDE_C -# include "ide_modes.h" -# undef _IDE_C -#else -# include "ide_modes.h" -#endif /* CONFIG_BLK_DEV_HT6560B_MODULE */ +#include "ide_modes.h" /* #define DEBUG */ /* remove comments for DEBUG messages */ diff --git a/drivers/ide/legacy/pdc4030.c b/drivers/ide/legacy/pdc4030.c index c1c407319b4d463cbf9332b9972ad1515aaf2321..8a1967a7c52550050869e801230c4e58a9173733 100644 --- a/drivers/ide/legacy/pdc4030.c +++ b/drivers/ide/legacy/pdc4030.c @@ -94,6 +94,8 @@ #include "pdc4030.h" +static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block); + /* * promise_selectproc() is invoked by ide.c * in preparation for access to the specified drive. @@ -231,6 +233,10 @@ int __init setup_pdc4030(ide_hwif_t *hwif) /* DC4030 hosted drives need their own identify... */ hwif->identify = hwif2->identify = &pdc4030_identify; + /* Override the normal ide disk read/write. */ + hwif->rw_disk = promise_rw_disk; + hwif2->rw_disk = promise_rw_disk; + /* Shift the remaining interfaces up by one */ for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) { ide_hwif_t *h = &ide_hwifs[i]; @@ -803,7 +809,7 @@ ide_startstop_t do_pdc4030_io (ide_drive_t *drive, ide_task_t *task) } } -ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) +static ide_startstop_t promise_rw_disk (ide_drive_t *drive, struct request *rq, unsigned long block) { /* The four drives on the two logical (one physical) interfaces are distinguished by writing the drive number (0-3) to the diff --git a/drivers/ide/legacy/qd65xx.c b/drivers/ide/legacy/qd65xx.c index d1c1db4cb28379af920accb9cee5a6d1fd232c67..3ff868a5896d2ee8a2e1c31527641a9f233912f2 100644 --- a/drivers/ide/legacy/qd65xx.c +++ b/drivers/ide/legacy/qd65xx.c @@ -42,14 +42,7 @@ #include <asm/system.h> #include <asm/io.h> -#ifdef CONFIG_BLK_DEV_QD65XX_MODULE -# define _IDE_C -# include "ide_modes.h" -# undef _IDE_C -#else -# include "ide_modes.h" -#endif /* CONFIG_BLK_DEV_QD65XX_MODULE */ - +#include "ide_modes.h" #include "qd65xx.h" /* diff --git a/drivers/ide/legacy/umc8672.c b/drivers/ide/legacy/umc8672.c index 8bf4dc26799cafb7d55549ca566ce0dbddb75764..1ff2a8cc844214f0bb4e47126059df1ea031512f 100644 --- a/drivers/ide/legacy/umc8672.c +++ b/drivers/ide/legacy/umc8672.c @@ -54,13 +54,7 @@ #include <asm/io.h> -#ifdef CONFIG_BLK_DEV_UMC8672_MODULE -# define _IDE_C -# include "ide_modes.h" -# undef _IDE_C -#else -# include "ide_modes.h" -#endif /* CONFIG_BLK_DEV_UMC8672_MODULE */ +#include "ide_modes.h" /* * Default speeds. These can be changed with "auto-tune" and/or hdparm. diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 96c0d428069894c9f4724c25397cd5a052aab13a..2970429d745f4a1d793efafe147d9988c13d4dbc 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -313,7 +313,8 @@ static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char case AMD_UDMA_100: pci_read_config_byte(dev, AMD_CABLE_DETECT, &t); - amd_80w = ((u & 0x3) ? 1 : 0) | ((u & 0xc) ? 2 : 0); + pci_read_config_dword(dev, AMD_UDMA_TIMING, &u); + amd_80w = ((t & 0x3) ? 1 : 0) | ((t & 0xc) ? 2 : 0); for (i = 24; i >= 0; i -= 8) if (((u >> i) & 4) && !(amd_80w & (1 << (1 - (i >> 4))))) { printk(KERN_WARNING "AMD_IDE: Bios didn't set cable bits correctly. Enabling workaround.\n"); @@ -383,11 +384,6 @@ static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char return 0; } -static unsigned int __init ata66_amd74xx(ide_hwif_t *hwif) -{ - return ((amd_enabled & amd_80w) >> hwif->channel) & 1; -} - static void __init init_hwif_amd74xx(ide_hwif_t *hwif) { int i; diff --git a/drivers/ide/pci/amd74xx.h b/drivers/ide/pci/amd74xx.h index e5984607cb56d1390c4ec12dd7449f51a07e5761..af8e0ed51330ce719a15e753d5005d3bd1d84c58 100644 --- a/drivers/ide/pci/amd74xx.h +++ b/drivers/ide/pci/amd74xx.h @@ -40,7 +40,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, + .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, .bootable = ON_BOARD, .extra = 0 },{ /* 1 */ @@ -53,7 +53,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, + .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, .bootable = ON_BOARD, .extra = 0 },{ /* 2 */ @@ -66,7 +66,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, + .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, .bootable = ON_BOARD, .extra = 0 },{ /* 3 */ @@ -79,7 +79,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, + .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, .bootable = ON_BOARD, .extra = 0 },{ /* 4 */ @@ -92,7 +92,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { .init_dma = init_dma_amd74xx, .autodma = AUTODMA, .channels = 2, - .enablebits = {{0x40,0x01,0x01}, {0x40,0x02,0x02}}, + .enablebits = {{0x40,0x02,0x02}, {0x40,0x01,0x01}}, .bootable = ON_BOARD, .extra = 0 }, @@ -106,7 +106,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x50,0x01,0x01}, {0x50,0x02,0x02}}, + .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, .bootable = ON_BOARD, .extra = 0, }, @@ -120,7 +120,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { .init_dma = init_dma_amd74xx, .channels = 2, .autodma = AUTODMA, - .enablebits = {{0x50,0x01,0x01}, {0x50,0x02,0x02}}, + .enablebits = {{0x50,0x02,0x02}, {0x50,0x01,0x01}}, .bootable = ON_BOARD, .extra = 0, }, diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c index e9952c84c23680e1755e0457b249c34b1be7edf3..e3302e156c1632fb5fd8481a827b9abe7980d509 100644 --- a/drivers/ide/pci/piix.c +++ b/drivers/ide/pci/piix.c @@ -142,6 +142,9 @@ static int piix_get_info (char *buffer, char **addr, off_t offset, int count) p += sprintf(p, "\nController: %d\n", i); p += sprintf(p, "\n Intel "); switch(dev->device) { + case PCI_DEVICE_ID_INTEL_82801EB_1: + p += sprintf(p, "PIIX4 SATA 150 "); + break; case PCI_DEVICE_ID_INTEL_82801BA_8: case PCI_DEVICE_ID_INTEL_82801BA_9: case PCI_DEVICE_ID_INTEL_82801CA_10: @@ -275,6 +278,9 @@ static u8 piix_ratemask (ide_drive_t *drive) u8 mode; switch(dev->device) { + case PCI_DEVICE_ID_INTEL_82801EB_1: + mode = 3; + break; /* UDMA 100 capable */ case PCI_DEVICE_ID_INTEL_82801BA_8: case PCI_DEVICE_ID_INTEL_82801BA_9: @@ -325,6 +331,7 @@ static u8 piix_ratemask (ide_drive_t *drive) static u8 piix_dma_2_pio (u8 xfer_rate) { switch(xfer_rate) { + case XFER_UDMA_6: case XFER_UDMA_5: case XFER_UDMA_4: case XFER_UDMA_3: @@ -603,6 +610,7 @@ static int piix_config_drive_xfer_rate (ide_drive_t *drive) static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name) { switch(dev->device) { + case PCI_DEVICE_ID_INTEL_82801EB_1: case PCI_DEVICE_ID_INTEL_82801AA_1: case PCI_DEVICE_ID_INTEL_82801AB_1: case PCI_DEVICE_ID_INTEL_82801BA_8: @@ -803,6 +811,7 @@ static struct pci_device_id piix_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_11,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801E_11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16}, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_10,PCI_ANY_ID, PCI_ANY_ID, 0, 0, 17}, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 18}, { 0, }, }; diff --git a/drivers/ide/pci/piix.h b/drivers/ide/pci/piix.h index 4502d2347112904eb2c3fe868f040b9781fe34df..87c8047da40bcdb70b8b45f096351ae17570ab11 100644 --- a/drivers/ide/pci/piix.h +++ b/drivers/ide/pci/piix.h @@ -291,10 +291,10 @@ static ide_pci_device_t piix_pci_info[] __devinitdata = { .enablebits = {{0x41,0x80,0x80}, {0x43,0x80,0x80}}, .bootable = ON_BOARD, .extra = 0, - },{ /* 17 */ + },{ /* 18 */ .vendor = PCI_VENDOR_ID_INTEL, - .device = PCI_DEVICE_ID_INTEL_82801DB_10, - .name = "ICH4", + .device = PCI_DEVICE_ID_INTEL_82801EB_1, + .name = "ICH5-SATA", .init_setup = init_setup_piix, .init_chipset = init_chipset_piix, .init_iops = NULL, diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index ae383cd05862ba2834fbd902a5ca12709299824d..6ae4c62089641c4df6054888045c320b7e2e168f 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/serverworks.c Version 0.7 10 Sept 2002 + * linux/drivers/ide/pci/serverworks.c Version 0.8 25 Ebr 2003 * * Copyright (C) 1998-2000 Michel Aubry * Copyright (C) 1998-2000 Andrzej Krzysztofowicz @@ -203,11 +203,22 @@ static int svwks_get_info (char *buffer, char **addr, off_t offset, int count) } #endif /* defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS) */ +static int check_in_drive_lists (ide_drive_t *drive, const char **list) +{ + while (*list) + if (!strcmp(*list++, drive->id->model)) + return 1; + return 0; +} + static u8 svwks_ratemask (ide_drive_t *drive) { struct pci_dev *dev = HWIF(drive)->pci_dev; u8 mode; + if (!svwks_revision) + pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision); + if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { u32 reg = 0; if (isa_dev) @@ -225,9 +236,13 @@ static u8 svwks_ratemask (ide_drive_t *drive) } else if (svwks_revision >= SVWKS_CSB5_REVISION_NEW) { u8 btr = 0; pci_read_config_byte(dev, 0x5A, &btr); - mode = btr; + mode = btr & 0x3; if (!eighty_ninty_three(drive)) mode = min(mode, (u8)1); + /* If someone decides to do UDMA133 on CSB5 the same + issue will bite so be inclusive */ + if (mode > 2 && check_in_drive_lists(drive, svwks_bad_ata100)) + mode = 2; } if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) && @@ -419,13 +434,10 @@ static void config_chipset_for_pio (ide_drive_t *drive) static void svwks_tune_drive (ide_drive_t *drive, u8 pio) { - /* Tune to desired value or to "best". We must not adjust - "best" when we adjust from pio numbers to rate values! */ - - if(pio != 255) - (void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio)); - else + if(pio == 255) (void) svwks_tune_chipset(drive, 255); + else + (void) svwks_tune_chipset(drive, (XFER_PIO_0 + pio)); } static int config_chipset_for_dma (ide_drive_t *drive) @@ -446,7 +458,7 @@ static int svwks_config_drive_xfer_rate (ide_drive_t *drive) drive->init_speed = 0; - if (id && (id->capability & 1) && drive->autodma) { + if ((id->capability & 1) && drive->autodma) { /* Consult the list of known "bad" drives */ if (hwif->ide_dma_bad_drive(drive)) goto fast_ata_pio; @@ -483,28 +495,10 @@ static int svwks_config_drive_xfer_rate (ide_drive_t *drive) return hwif->ide_dma_on(drive); } +/* This can go soon */ + static int svwks_ide_dma_end (ide_drive_t *drive) { - /* - * We never place the OSB4 into a UDMA mode with a disk - * medium, that means the UDMA "all my data is 4 byte shifted" - * problem cannot occur. - */ -#if 0 - ide_hwif_t *hwif = HWIF(drive); - u8 dma_stat = hwif->INB(hwif->dma_status); - - if ((dma_stat & 1) && drive->media == ide_disk) - { - printk(KERN_CRIT "Serverworks OSB4 in impossible state.\n"); - printk(KERN_CRIT "Disable UDMA or if you are using Seagate then try switching disk types\n"); - printk(KERN_CRIT "on this controller. Please report this event to osb4-bug@ide.cabal.tm\n"); - /* Panic might sys_sync -> death by corrupt disk */ - printk(KERN_CRIT "OSB4: continuing might cause disk corruption.\n"); - while(1) - cpu_relax(); - } -#endif return __ide_dma_end(drive); } @@ -630,8 +624,6 @@ static unsigned int __init init_chipset_svwks (struct pci_dev *dev, const char * static unsigned int __init ata66_svwks_svwks (ide_hwif_t *hwif) { -// struct pci_dev *dev = hwif->pci_dev; -// return 0; return 1; } diff --git a/drivers/ide/pci/serverworks.h b/drivers/ide/pci/serverworks.h index 73e9b6b4f0f44777438fd458b66bc3ec736bf3a0..aec835380e293d16113d88aeda1e69ccf3aadd2e 100644 --- a/drivers/ide/pci/serverworks.h +++ b/drivers/ide/pci/serverworks.h @@ -11,6 +11,16 @@ #define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */ #define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */ +/* Seagate Barracuda ATA IV Family drives in UDMA mode 5 + * can overrun their FIFOs when used with the CSB5 */ +const char *svwks_bad_ata100[] = { + "ST320011A", + "ST340016A", + "ST360021A", + "ST380021A", + NULL +}; + #define DISPLAY_SVWKS_TIMINGS 1 #if defined(DISPLAY_SVWKS_TIMINGS) && defined(CONFIG_PROC_FS) diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 6f41eade2bfb632f637b687ab530af08b210d641..5b7d079bf96ac21de63256c8d24d943bf76a321e 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c @@ -161,9 +161,10 @@ static const struct { { "SiS748", PCI_DEVICE_ID_SI_748, ATA_133, 0 }, { "SiS746", PCI_DEVICE_ID_SI_746, ATA_133, 0 }, { "SiS745", PCI_DEVICE_ID_SI_745, ATA_133, 0 }, - { "SiS740", PCI_DEVICE_ID_SI_740, ATA_100, 0 }, + { "SiS740", PCI_DEVICE_ID_SI_740, ATA_133, 0 }, { "SiS735", PCI_DEVICE_ID_SI_735, ATA_100, SIS5513_LATENCY }, { "SiS730", PCI_DEVICE_ID_SI_730, ATA_100a, SIS5513_LATENCY }, + { "SiS655", PCI_DEVICE_ID_SI_655, ATA_133, 0 }, { "SiS652", PCI_DEVICE_ID_SI_652, ATA_133, 0 }, { "SiS651", PCI_DEVICE_ID_SI_651, ATA_133, 0 }, { "SiS650", PCI_DEVICE_ID_SI_650, ATA_133, 0 }, @@ -257,8 +258,8 @@ static struct pci_dev *host_dev = NULL; static char* chipset_capability[] = { "ATA", "ATA 16", "ATA 33", "ATA 66", - "ATA 100", "ATA 100", - "ATA 133", "ATA 133" + "ATA 100 (1st gen)", "ATA 100 (2nd gen)", + "ATA 133 (1st gen)", "ATA 133 (2nd gen)" }; #if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) @@ -331,8 +332,8 @@ static char* get_drives_info (char *buffer, u8 pos) // Configuration space remapped to 0x70 drive_pci = 0x70; } - pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+8*pos, ®dw0); - pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+8*pos+4, ®dw1); + pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos, ®dw0); + pci_read_config_dword(bmide_dev, (unsigned long)drive_pci+4*pos+8, ®dw1); p += sprintf(p, "Drive %d:\n", pos); } @@ -357,8 +358,7 @@ static char* get_drives_info (char *buffer, u8 pos) case ATA_100a: p += sprintf(p, cycle_time[(reg01 & 0x70) >> 4]); break; case ATA_100: case ATA_133a: p += sprintf(p, cycle_time[reg01 & 0x0F]); break; - case ATA_133: - default: p += sprintf(p, "133+ ?"); break; + default: p += sprintf(p, "?"); break; } p += sprintf(p, " \t UDMA Cycle Time "); switch(chipset_family) { @@ -367,42 +367,39 @@ static char* get_drives_info (char *buffer, u8 pos) case ATA_100a: p += sprintf(p, cycle_time[(reg11 & 0x70) >> 4]); break; case ATA_100: case ATA_133a: p += sprintf(p, cycle_time[reg11 & 0x0F]); break; - case ATA_133: - default: p += sprintf(p, "133+ ?"); break; + default: p += sprintf(p, "?"); break; } p += sprintf(p, "\n"); } + if (chipset_family < ATA_133) { /* else case TODO */ /* Data Active */ - p += sprintf(p, " Data Active Time "); - switch(chipset_family) { - case ATA_00: - case ATA_16: /* confirmed */ - case ATA_33: - case ATA_66: - case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break; - case ATA_100: - case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break; - case ATA_133: - default: p += sprintf(p, "133+ ?"); break; - } - p += sprintf(p, " \t Data Active Time "); - switch(chipset_family) { - case ATA_00: - case ATA_16: - case ATA_33: - case ATA_66: - case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break; - case ATA_100: - case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break; - case ATA_133: - default: p += sprintf(p, "133+ ?"); break; - } - p += sprintf(p, "\n"); + p += sprintf(p, " Data Active Time "); + switch(chipset_family) { + case ATA_00: + case ATA_16: /* confirmed */ + case ATA_33: + case ATA_66: + case ATA_100a: p += sprintf(p, active_time[reg01 & 0x07]); break; + case ATA_100: + case ATA_133a: p += sprintf(p, active_time[(reg00 & 0x70) >> 4]); break; + default: p += sprintf(p, "?"); break; + } + p += sprintf(p, " \t Data Active Time "); + switch(chipset_family) { + case ATA_00: + case ATA_16: + case ATA_33: + case ATA_66: + case ATA_100a: p += sprintf(p, active_time[reg11 & 0x07]); break; + case ATA_100: + case ATA_133a: p += sprintf(p, active_time[(reg10 & 0x70) >> 4]); break; + default: p += sprintf(p, "?"); break; + } + p += sprintf(p, "\n"); /* Data Recovery */ /* warning: may need (reg&0x07) for pre ATA66 chips */ - if (chipset_family < ATA_133) { p += sprintf(p, " Data Recovery Time %s \t Data Recovery Time %s\n", recovery_time[reg00 & 0x0f], recovery_time[reg10 & 0x0f]); } @@ -430,7 +427,6 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count) p += sprintf(p, "\nSiS 5513 "); switch(chipset_family) { - case ATA_00: p += sprintf(p, "Unknown???"); break; case ATA_16: p += sprintf(p, "DMA 16"); break; case ATA_33: p += sprintf(p, "Ultra 33"); break; case ATA_66: p += sprintf(p, "Ultra 66"); break; @@ -867,6 +863,19 @@ static int sis5513_config_xfer_rate (ide_drive_t *drive) return sis5513_config_drive_xfer_rate(drive); } +/* Helper function used at init time + * returns a PCI device revision ID + * (used to detect different IDE controller versions) + */ +static u8 __init devfn_rev(int device, int function) +{ + u8 revision; + /* Find device */ + struct pci_dev* dev = pci_find_slot(0,PCI_DEVFN(device,function)); + pci_read_config_byte(dev, PCI_REVISION_ID, &revision); + return revision; +} + /* Chip detection and general config */ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name) { @@ -887,26 +896,24 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char /* check 100/133 chipset family */ if (chipset_family == ATA_133) { u32 reg54h; - u16 reg02h; + u16 devid; pci_read_config_dword(dev, 0x54, ®54h); + /* SiS962 and above report 0x5518 dev id if high bit is cleared */ pci_write_config_dword(dev, 0x54, (reg54h & 0x7fffffff)); - pci_read_config_word(dev, 0x02, ®02h); + pci_read_config_word(dev, 0x02, &devid); + /* restore register 0x54 */ pci_write_config_dword(dev, 0x54, reg54h); + /* devid 5518 here means SiS962 or later - which supports ATA133 */ - if (reg02h != 0x5518) { + which supports ATA133. + These are refered by chipset_family = ATA133 + */ + if (devid != 0x5518) { u8 reg49h; - unsigned long sbrev; /* SiS961 family */ - - /* - * FIXME !!! GAK!!!!!!!!!! PCI DIRECT POKING - */ - outl(0x80001008, 0x0cf8); - sbrev = inl(0x0cfc); - pci_read_config_byte(dev, 0x49, ®49h); - if (((sbrev & 0xff) == 0x10) && (reg49h & 0x80)) + /* check isa bridge device rev id */ + if (((devfn_rev(2,0) & 0xff) == 0x10) && (reg49h & 0x80)) chipset_family = ATA_133a; else chipset_family = ATA_100; @@ -924,6 +931,14 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char u8 latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */ pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency); } + + /* Special case for SiS630 : 630S/ET is ATA_100a */ + if (SiSHostChipInfo[i].host_id == PCI_DEVICE_ID_SI_630) { + /* check host device rev id */ + if (devfn_rev(0,0) >= 0x30) { + chipset_family = ATA_100a; + } + } } /* Make general config ops here diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 93014269ee5bf22c78a5d63725751ddc4232a2b4..7261140d50445b2ffea18d30adea25de58b562e4 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -1,12 +1,12 @@ /* * - * Version 3.36 + * Version 3.37 * * VIA IDE driver for Linux. Supported southbridges: * * vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b, * vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a, - * vt8235 + * vt8235, vt8237 * * Copyright (c) 2000-2002 Vojtech Pavlik * @@ -74,9 +74,7 @@ static struct via_isa_bridge { u8 rev_max; u16 flags; } via_isa_bridges[] = { -#ifdef FUTURE_BRIDGES - { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 }, -#endif + { "vt8237", PCI_DEVICE_ID_VIA_8237, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8235", PCI_DEVICE_ID_VIA_8235, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8233a", PCI_DEVICE_ID_VIA_8233A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, { "vt8233c", PCI_DEVICE_ID_VIA_8233C_0, 0x00, 0x2f, VIA_UDMA_100 }, @@ -148,7 +146,7 @@ static int via_get_info(char *buffer, char **addr, off_t offset, int count) via_print("----------VIA BusMastering IDE Configuration" "----------------"); - via_print("Driver Version: 3.36"); + via_print("Driver Version: 3.37"); via_print("South Bridge: VIA %s", via_config->name); diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index e25c4dbe595a29b7254bd6636040cce5daa3562e..ce1b710e0884c2cf8db5ebc272f6189ef63f320c 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -635,7 +635,22 @@ static void __init quirk_via_bridge(struct pci_dev *pdev) if(pdev->devfn == 0) interrupt_line_quirk = 1; } - + +/* + * Serverworks CSB5 IDE does not fully support native mode + */ +static void __init quirk_svwks_csb5ide(struct pci_dev *pdev) +{ + u8 prog; + pci_read_config_byte(pdev, PCI_CLASS_PROG, &prog); + if (prog & 5) { + prog &= ~5; + pdev->class &= ~5; + pci_write_config_byte(pdev, PCI_CLASS_PROG, prog); + /* need to re-assign BARs for compat mode */ + quirk_ide_bases(pdev); + } +} /* This was originally an Alpha specific thing, but it really fits here. * The i82375 PCI/EISA bridge appears as non-classified. Fix that. @@ -812,7 +827,9 @@ static struct pci_fixup pci_fixups[] __devinitdata = { { PCI_FIXUP_HEADER, PCI_VENDOR_ID_TOSHIBA, 0x605, quirk_transparent_bridge }, { PCI_FIXUP_FINAL, PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master }, - + + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, quirk_svwks_csb5ide }, + { PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge }, /* diff --git a/include/acpi/acconfig.h b/include/acpi/acconfig.h index f7532f979c7fc6e45b30a4c3c4f88b8f032bcb31..3fda218d6de3af8c731cb681e7f940e0ab7b71ef 100644 --- a/include/acpi/acconfig.h +++ b/include/acpi/acconfig.h @@ -64,7 +64,7 @@ /* Version string */ -#define ACPI_CA_VERSION 0x20030418 +#define ACPI_CA_VERSION 0x20030522 /* Maximum objects in the various object caches */ @@ -133,6 +133,11 @@ #define ACPI_MAX_STRING_CONVERSION 200 +/* Length of _HID, _UID, and _CID values */ + +#define ACPI_DEVICE_ID_LENGTH 0x09 +#define ACPI_MAX_CID_LENGTH 48 + /* * Operand Stack (in WALK_STATE), Must be large enough to contain METHOD_MAX_ARG */ diff --git a/include/acpi/acdebug.h b/include/acpi/acdebug.h index 65c18eba57a6f7d774d1b1b940cd4d242eda8e51..60cf6eac7a07db70751da169c83497f54f821a70 100644 --- a/include/acpi/acdebug.h +++ b/include/acpi/acdebug.h @@ -229,10 +229,6 @@ acpi_db_decode_and_display_object ( char *target, char *output_type); -void -acpi_db_decode_node ( - struct acpi_namespace_node *node); - void acpi_db_display_result_object ( union acpi_operand_object *obj_desc, @@ -242,11 +238,6 @@ acpi_status acpi_db_display_all_methods ( char *display_count_arg); -void -acpi_db_display_internal_object ( - union acpi_operand_object *obj_desc, - struct acpi_walk_state *walk_state); - void acpi_db_display_arguments ( void); @@ -263,6 +254,10 @@ void acpi_db_display_calling_tree ( void); +void +acpi_db_display_object_type ( + char *object_arg); + void acpi_db_display_argument_object ( union acpi_operand_object *obj_desc, @@ -276,10 +271,6 @@ void * acpi_db_get_pointer ( void *target); -void -acpi_db_decode_internal_object ( - union acpi_operand_object *obj_desc); - /* * dbexec - debugger control method execution diff --git a/include/acpi/acdisasm.h b/include/acpi/acdisasm.h new file mode 100644 index 0000000000000000000000000000000000000000..e2938c593e2c1f3d95ec570c92aac872946cb98b --- /dev/null +++ b/include/acpi/acdisasm.h @@ -0,0 +1,406 @@ +/****************************************************************************** + * + * Name: acdisasm.h - AML disassembler + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + +#ifndef __ACDISASM_H__ +#define __ACDISASM_H__ + +#include "amlresrc.h" + + +#define BLOCK_NONE 0 +#define BLOCK_PAREN 1 +#define BLOCK_BRACE 2 +#define BLOCK_COMMA_LIST 4 + +extern const char *acpi_gbl_io_decode[2]; +extern const char *acpi_gbl_word_decode[4]; +extern const char *acpi_gbl_consume_decode[2]; +extern const char *acpi_gbl_min_decode[2]; +extern const char *acpi_gbl_max_decode[2]; +extern const char *acpi_gbl_DECdecode[2]; +extern const char *acpi_gbl_RNGdecode[4]; +extern const char *acpi_gbl_MEMdecode[4]; +extern const char *acpi_gbl_RWdecode[2]; +extern const char *acpi_gbl_irq_decode[2]; +extern const char *acpi_gbl_HEdecode[2]; +extern const char *acpi_gbl_LLdecode[2]; +extern const char *acpi_gbl_SHRdecode[2]; +extern const char *acpi_gbl_TYPdecode[4]; +extern const char *acpi_gbl_BMdecode[2]; +extern const char *acpi_gbl_SIZdecode[4]; +extern const char *acpi_gbl_lock_rule[ACPI_NUM_LOCK_RULES]; +extern const char *acpi_gbl_access_types[ACPI_NUM_ACCESS_TYPES]; +extern const char *acpi_gbl_update_rules[ACPI_NUM_UPDATE_RULES]; +extern const char *acpi_gbl_match_ops[ACPI_NUM_MATCH_OPS]; + + +struct acpi_op_walk_info +{ + u32 level; + u32 bit_offset; +}; + +typedef +acpi_status (*asl_walk_callback) ( + union acpi_parse_object *op, + u32 level, + void *context); + + +/* + * dmwalk + */ + +void +acpi_dm_walk_parse_tree ( + union acpi_parse_object *op, + asl_walk_callback descending_callback, + asl_walk_callback ascending_callback, + void *context); + +acpi_status +acpi_dm_descending_op ( + union acpi_parse_object *op, + u32 level, + void *context); + +acpi_status +acpi_dm_ascending_op ( + union acpi_parse_object *op, + u32 level, + void *context); + + +/* + * dmopcode + */ + +void +acpi_dm_validate_name ( + char *name, + union acpi_parse_object *op); + +u32 +acpi_dm_dump_name ( + char *name); + +void +acpi_dm_unicode ( + union acpi_parse_object *op); + +void +acpi_dm_disassemble ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *origin, + u32 num_opcodes); + +void +acpi_dm_namestring ( + char *name); + +void +acpi_dm_display_path ( + union acpi_parse_object *op); + +void +acpi_dm_disassemble_one_op ( + struct acpi_walk_state *walk_state, + struct acpi_op_walk_info *info, + union acpi_parse_object *op); + +void +acpi_dm_decode_internal_object ( + union acpi_operand_object *obj_desc); + +void +acpi_dm_decode_node ( + struct acpi_namespace_node *node); + +u32 +acpi_dm_block_type ( + union acpi_parse_object *op); + +u32 +acpi_dm_list_type ( + union acpi_parse_object *op); + +acpi_status +acpi_ps_display_object_pathname ( + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + +void +acpi_dm_method_flags ( + union acpi_parse_object *op); + +void +acpi_dm_field_flags ( + union acpi_parse_object *op); + +void +acpi_dm_address_space ( + u8 space_id); + +void +acpi_dm_region_flags ( + union acpi_parse_object *op); + +void +acpi_dm_match_op ( + union acpi_parse_object *op); + +void +acpi_dm_match_keyword ( + union acpi_parse_object *op); + +u8 +acpi_dm_comma_if_list_member ( + union acpi_parse_object *op); + +void +acpi_dm_comma_if_field_member ( + union acpi_parse_object *op); + + +/* + * dmobject + */ + +void +acpi_dm_decode_node ( + struct acpi_namespace_node *node); + +void +acpi_dm_display_internal_object ( + union acpi_operand_object *obj_desc, + struct acpi_walk_state *walk_state); + +void +acpi_dm_display_arguments ( + struct acpi_walk_state *walk_state); + +void +acpi_dm_display_locals ( + struct acpi_walk_state *walk_state); + +void +acpi_dm_dump_method_info ( + acpi_status status, + struct acpi_walk_state *walk_state, + union acpi_parse_object *op); + + +/* + * dmbuffer + */ + +void +acpi_is_eisa_id ( + union acpi_parse_object *op); + +void +acpi_dm_eisa_id ( + u32 encoded_id); + +u8 +acpi_dm_is_unicode_buffer ( + union acpi_parse_object *op); + +u8 +acpi_dm_is_string_buffer ( + union acpi_parse_object *op); + + +/* + * dmresrc + */ + +void +acpi_dm_disasm_byte_list ( + u32 level, + u8 *byte_data, + u32 byte_count); + +void +acpi_dm_byte_list ( + struct acpi_op_walk_info *info, + union acpi_parse_object *op); + +void +acpi_dm_resource_descriptor ( + struct acpi_op_walk_info *info, + u8 *byte_data, + u32 byte_count); + +u8 +acpi_dm_is_resource_descriptor ( + union acpi_parse_object *op); + +void +acpi_dm_indent ( + u32 level); + +void +acpi_dm_bit_list ( + u16 mask); + +void +acpi_dm_decode_attribute ( + u8 attribute); + +/* + * dmresrcl + */ + +void +acpi_dm_io_flags ( + u8 flags); + +void +acpi_dm_memory_flags ( + u8 flags, + u8 specific_flags); + +void +acpi_dm_word_descriptor ( + struct asl_word_address_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_dword_descriptor ( + struct asl_dword_address_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_qword_descriptor ( + struct asl_qword_address_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_memory24_descriptor ( + struct asl_memory_24_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_memory32_descriptor ( + struct asl_memory_32_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_fixed_mem32_descriptor ( + struct asl_fixed_memory_32_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_generic_register_descriptor ( + struct asl_general_register_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_interrupt_descriptor ( + struct asl_extended_xrupt_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_vendor_large_descriptor ( + struct asl_large_vendor_desc *resource, + u32 length, + u32 level); + + +/* + * dmresrcs + */ + +void +acpi_dm_irq_descriptor ( + struct asl_irq_format_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_dma_descriptor ( + struct asl_dma_format_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_io_descriptor ( + struct asl_io_port_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_fixed_io_descriptor ( + struct asl_fixed_io_port_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_start_dependent_descriptor ( + struct asl_start_dependent_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_end_dependent_descriptor ( + struct asl_start_dependent_desc *resource, + u32 length, + u32 level); + +void +acpi_dm_vendor_small_descriptor ( + struct asl_small_vendor_desc *resource, + u32 length, + u32 level); + + +#endif /* __ACDISASM_H__ */ diff --git a/include/acpi/acevents.h b/include/acpi/acevents.h index f23360115e8385de6f796a012391684b8df983b6..38664422c5552ce42b900117eebec90710f07ded 100644 --- a/include/acpi/acevents.h +++ b/include/acpi/acevents.h @@ -165,7 +165,7 @@ acpi_ev_address_space_dispatch ( void *value); acpi_status -acpi_ev_addr_handler_helper ( +acpi_ev_install_handler ( acpi_handle obj_handle, u32 level, void *context, diff --git a/include/acpi/acexcep.h b/include/acpi/acexcep.h index cc0bb192980c63633de32742dd9c8168c90cfb88..d225bdd2b9b9136ed66b38d00825807f84438320 100644 --- a/include/acpi/acexcep.h +++ b/include/acpi/acexcep.h @@ -94,8 +94,9 @@ #define AE_NO_GLOBAL_LOCK (acpi_status) (0x001A | AE_CODE_ENVIRONMENTAL) #define AE_LOGICAL_ADDRESS (acpi_status) (0x001B | AE_CODE_ENVIRONMENTAL) #define AE_ABORT_METHOD (acpi_status) (0x001C | AE_CODE_ENVIRONMENTAL) +#define AE_SAME_HANDLER (acpi_status) (0x001D | AE_CODE_ENVIRONMENTAL) -#define AE_CODE_ENV_MAX 0x001C +#define AE_CODE_ENV_MAX 0x001D /* * Programmer exceptions @@ -219,7 +220,8 @@ char const *acpi_gbl_exception_names_env[] = "AE_NO_HARDWARE_RESPONSE", "AE_NO_GLOBAL_LOCK", "AE_LOGICAL_ADDRESS", - "AE_ABORT_METHOD" + "AE_ABORT_METHOD", + "AE_SAME_HANDLER" }; char const *acpi_gbl_exception_names_pgm[] = diff --git a/include/acpi/acglobal.h b/include/acpi/acglobal.h index 55f7eb9b71408135b25f951e4eaba64aacfc9273..254d11a7ac5e95502411e041988474136e1cd156 100644 --- a/include/acpi/acglobal.h +++ b/include/acpi/acglobal.h @@ -105,6 +105,8 @@ ACPI_EXTERN struct acpi_common_facs acpi_gbl_common_fACS; */ ACPI_EXTERN u8 acpi_gbl_integer_bit_width; ACPI_EXTERN u8 acpi_gbl_integer_byte_width; +ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable; +ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable; /* * Since there may be multiple SSDTs and PSDTS, a single pointer is not @@ -115,15 +117,15 @@ ACPI_EXTERN u8 acpi_gbl_integer_byte_width; /* * ACPI Table info arrays */ -extern struct acpi_table_desc acpi_gbl_acpi_tables[NUM_ACPI_TABLES]; -extern struct acpi_table_support acpi_gbl_acpi_table_data[NUM_ACPI_TABLES]; +extern struct acpi_table_list acpi_gbl_table_lists[NUM_ACPI_TABLE_TYPES]; +extern struct acpi_table_support acpi_gbl_table_data[NUM_ACPI_TABLE_TYPES]; /* * Predefined mutex objects. This array contains the * actual OS mutex handles, indexed by the local ACPI_MUTEX_HANDLEs. * (The table maps local handles to the real OS handles) */ -ACPI_EXTERN struct acpi_mutex_info acpi_gbl_acpi_mutex_info [NUM_MTX]; +ACPI_EXTERN struct acpi_mutex_info acpi_gbl_mutex_info[NUM_MUTEX]; /***************************************************************************** @@ -134,8 +136,8 @@ ACPI_EXTERN struct acpi_mutex_info acpi_gbl_acpi_mutex_info [NUM_MT ACPI_EXTERN struct acpi_memory_list acpi_gbl_memory_lists[ACPI_NUM_MEM_LISTS]; -ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_drv_notify; -ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_sys_notify; +ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_device_notify; +ACPI_EXTERN struct acpi_object_notify_handler acpi_gbl_system_notify; ACPI_EXTERN acpi_init_handler acpi_gbl_init_handler; ACPI_EXTERN struct acpi_walk_state *acpi_gbl_breakpoint_walk; ACPI_EXTERN acpi_handle acpi_gbl_global_lock_semaphore; @@ -200,7 +202,7 @@ ACPI_EXTERN u32 acpi_gbl_deepest_nesting; ****************************************************************************/ -ACPI_EXTERN struct acpi_thread_state *acpi_gbl_current_walk_list; +ACPI_EXTERN struct acpi_thread_state *acpi_gbl_current_walk_list; /* Control method single step flag */ @@ -213,7 +215,7 @@ ACPI_EXTERN u8 acpi_gbl_cm_single_step; * ****************************************************************************/ -ACPI_EXTERN union acpi_parse_object *acpi_gbl_parsed_namespace_root; +ACPI_EXTERN union acpi_parse_object *acpi_gbl_parsed_namespace_root; /***************************************************************************** * @@ -234,8 +236,8 @@ ACPI_EXTERN u8 acpi_gbl_sleep_type_b; extern struct acpi_fixed_event_info acpi_gbl_fixed_event_info[ACPI_NUM_FIXED_EVENTS]; ACPI_EXTERN struct acpi_fixed_event_handler acpi_gbl_fixed_event_handlers[ACPI_NUM_FIXED_EVENTS]; -ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; -ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; +ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; +ACPI_EXTERN struct acpi_gpe_block_info *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; ACPI_EXTERN acpi_handle acpi_gbl_gpe_lock; diff --git a/include/acpi/achware.h b/include/acpi/achware.h index 1d34e757d11fbd0f0189372d3fbc2b3b30698a82..4be6958950e6616cc1b2c80073c368796cf9d64f 100644 --- a/include/acpi/achware.h +++ b/include/acpi/achware.h @@ -98,15 +98,13 @@ acpi_status acpi_hw_low_level_read ( u32 width, u32 *value, - struct acpi_generic_address *reg, - u32 offset); + struct acpi_generic_address *reg); acpi_status acpi_hw_low_level_write ( u32 width, u32 value, - struct acpi_generic_address *reg, - u32 offset); + struct acpi_generic_address *reg); acpi_status acpi_hw_clear_acpi_status ( diff --git a/include/acpi/aclocal.h b/include/acpi/aclocal.h index fffbddc8f532a873f9c185491cac34acb23202a7..d0387af6169d1b96eb759a62eb18d1ece051aa45 100644 --- a/include/acpi/aclocal.h +++ b/include/acpi/aclocal.h @@ -87,8 +87,8 @@ typedef u32 acpi_mutex_handle; #define ACPI_MTX_DEBUG_CMD_COMPLETE 11 #define ACPI_MTX_DEBUG_CMD_READY 12 -#define MAX_MTX 12 -#define NUM_MTX MAX_MTX+1 +#define MAX_MUTEX 12 +#define NUM_MUTEX MAX_MUTEX+1 #if defined(ACPI_DEBUG_OUTPUT) || defined(ACPI_DEBUGGER) @@ -140,12 +140,8 @@ struct acpi_mutex_info typedef u16 acpi_owner_id; #define ACPI_OWNER_TYPE_TABLE 0x0 #define ACPI_OWNER_TYPE_METHOD 0x1 -#define ACPI_FIRST_METHOD_ID 0x0000 -#define ACPI_FIRST_TABLE_ID 0x8000 - -/* TBD: [Restructure] get rid of the need for this! */ - -#define TABLE_ID_DSDT (acpi_owner_id) 0x8000 +#define ACPI_FIRST_METHOD_ID 0x0001 +#define ACPI_FIRST_TABLE_ID 0xF000 /* Field access granularities */ @@ -232,13 +228,18 @@ struct acpi_table_desc u64 physical_address; u32 aml_length; acpi_size length; - u32 count; acpi_owner_id table_id; u8 type; u8 allocation; u8 loaded_into_namespace; }; +struct acpi_table_list +{ + struct acpi_table_desc *next; + u32 count; +}; + struct acpi_find_context { @@ -855,16 +856,6 @@ struct acpi_bit_register_info #define ACPI_RDESC_TYPE_QWORD_ADDRESS_SPACE 0x8A -/* String version of device HIDs and UIDs */ - -#define ACPI_DEVICE_ID_LENGTH 0x09 - -struct acpi_device_id -{ - char buffer[ACPI_DEVICE_ID_LENGTH]; -}; - - /***************************************************************************** * * Miscellaneous diff --git a/include/acpi/acmacros.h b/include/acpi/acmacros.h index 7b0f65b8439410a21c8a2b88abea3cc13f1c2936..7160c41972d1d6457fc632ca09d5d3a448bfc7b8 100644 --- a/include/acpi/acmacros.h +++ b/include/acpi/acmacros.h @@ -440,26 +440,6 @@ #define INCREMENT_ARG_LIST(list) (list >>= ((u32) ARG_TYPE_WIDTH)) -/* - * Build a GAS structure from earlier ACPI table entries (V1.0 and 0.71 extensions) - * - * 1) Address space - * 2) Length in bytes -- convert to length in bits - * 3) Bit offset is zero - * 4) Reserved field is zero - * 5) Expand address to 64 bits - */ -#define ASL_BUILD_GAS_FROM_ENTRY(a,b,c,d) do {a.address_space_id = (u8) d;\ - a.register_bit_width = (u8) ACPI_MUL_8 (b);\ - a.register_bit_offset = 0;\ - a.reserved = 0;\ - ACPI_STORE_ADDRESS (a.address,(acpi_physical_address) c);} while (0) - -/* ACPI V1.0 entries -- address space is always I/O */ - -#define ASL_BUILD_GAS_FROM_V1_ENTRY(a,b,c) ASL_BUILD_GAS_FROM_ENTRY(a,b,c,ACPI_ADR_SPACE_SYSTEM_IO) - - /* * Reporting macros that are never compiled out */ diff --git a/include/acpi/acnamesp.h b/include/acpi/acnamesp.h index e809068247ff8841a1c02f6861b58ad682f7e257..f6e52a7837914a050b8018a29618d0b22e8b66c4 100644 --- a/include/acpi/acnamesp.h +++ b/include/acpi/acnamesp.h @@ -201,6 +201,11 @@ acpi_ns_compare_names ( char *name1, char *name2); +void +acpi_ns_remove_reference ( + struct acpi_namespace_node *node); + + /* * Namespace modification - nsmodify */ diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h index e121f26094d3c52698f5dfe2e781dd91ff9ab8d5..be30364c52184feebf4e2d9e83f8e4abe17870af 100644 --- a/include/acpi/acobject.h +++ b/include/acpi/acobject.h @@ -112,9 +112,9 @@ * Common fields for objects that support ASL notifications */ #define ACPI_COMMON_NOTIFY_INFO \ - union acpi_operand_object *sys_handler; /* Handler for system notifies */\ - union acpi_operand_object *drv_handler; /* Handler for driver notifies */\ - union acpi_operand_object *addr_handler; /* Handler for Address space */ + union acpi_operand_object *system_notify; /* Handler for system notifies */\ + union acpi_operand_object *device_notify; /* Handler for driver notifies */\ + union acpi_operand_object *address_space; /* Handler for Address space */ /****************************************************************************** @@ -214,7 +214,7 @@ struct acpi_object_region ACPI_OBJECT_COMMON_HEADER u8 space_id; - union acpi_operand_object *addr_handler; /* Handler for system notifies */ + union acpi_operand_object *address_space; /* Handler for region access */ struct acpi_namespace_node *node; /* containing object */ union acpi_operand_object *next; u32 length; @@ -446,8 +446,8 @@ union acpi_operand_object struct acpi_object_buffer_field buffer_field; struct acpi_object_bank_field bank_field; struct acpi_object_index_field index_field; - struct acpi_object_notify_handler notify_handler; - struct acpi_object_addr_handler addr_handler; + struct acpi_object_notify_handler notify; + struct acpi_object_addr_handler address_space; struct acpi_object_reference reference; struct acpi_object_extra extra; struct acpi_object_data data; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 8acb65f9eccdc43b5949143c947a4af9ffd0e180..7e0f5941433aab4ad7a3ac4143ad26b10dab4293 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -186,6 +186,7 @@ struct acpi_device_pnp { acpi_bus_id bus_id; /* Object name */ acpi_bus_address bus_address; /* _ADR */ acpi_hardware_id hardware_id; /* _HID */ + struct acpi_compatible_id_list *cid_list; /* _CIDs */ acpi_unique_id unique_id; /* _UID */ acpi_device_name device_name; /* Driver-determined */ acpi_device_class device_class; /* " */ diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index 928b5f49030afda6f405e1a344f5492a8d220c44..bb6df66442bc15bf04e68a1fa59c912be217df34 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h @@ -290,12 +290,12 @@ acpi_os_derive_pci_id( u8 acpi_os_readable ( void *pointer, - u32 length); + acpi_size length); u8 acpi_os_writable ( void *pointer, - u32 length); + acpi_size length); u32 acpi_os_get_timer ( diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index aa97e22aeb0da9ae22febcc8236023fd1c96f8b3..cd4979869007fbfd6ed21a77119b902f95027603 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -228,8 +228,8 @@ acpi_evaluate_object_typed ( acpi_status acpi_get_object_info ( - acpi_handle device, - struct acpi_device_info *info); + acpi_handle handle, + struct acpi_buffer *return_buffer); acpi_status acpi_get_next_object ( diff --git a/include/acpi/actables.h b/include/acpi/actables.h index 32fe58c16dd7e2694557892c01f5e430306ceda8..305c2a9adf4fc90a937193501113687985f897c1 100644 --- a/include/acpi/actables.h +++ b/include/acpi/actables.h @@ -157,7 +157,7 @@ acpi_tb_match_signature ( acpi_status acpi_tb_recognize_table ( struct acpi_table_desc *table_info, - u8 search_type); + u8 search_type); acpi_status acpi_tb_init_table_descriptor ( @@ -170,11 +170,11 @@ acpi_tb_init_table_descriptor ( */ void -acpi_tb_delete_acpi_tables ( +acpi_tb_delete_all_tables ( void); void -acpi_tb_delete_acpi_table ( +acpi_tb_delete_tables_by_type ( acpi_table_type type); void @@ -185,10 +185,6 @@ struct acpi_table_desc * acpi_tb_uninstall_table ( struct acpi_table_desc *table_desc); -void -acpi_tb_free_acpi_tables_of_type ( - struct acpi_table_desc *table_info); - /* * tbrsd - RSDP, RSDT utilities diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 7ffa0b226c3187dc4e049c3e76e343e43a473ed4..875bee2947a882b88ef9735111f6f37e253d2e7c 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h @@ -407,7 +407,7 @@ typedef u32 acpi_table_type; #define ACPI_TABLE_SSDT (acpi_table_type) 5 #define ACPI_TABLE_XSDT (acpi_table_type) 6 #define ACPI_TABLE_MAX 6 -#define NUM_ACPI_TABLES (ACPI_TABLE_MAX+1) +#define NUM_ACPI_TABLE_TYPES (ACPI_TABLE_MAX+1) /* @@ -747,7 +747,7 @@ struct acpi_system_info u32 debug_level; u32 debug_layer; u32 num_table_types; - struct acpi_table_info table_info [NUM_ACPI_TABLES]; + struct acpi_table_info table_info [NUM_ACPI_TABLE_TYPES]; }; @@ -832,12 +832,35 @@ acpi_status (*acpi_walk_callback) ( #define ACPI_INTERRUPT_HANDLED 0x01 -/* Structure and flags for acpi_get_device_info */ +/* Common string version of device HIDs and UIDs */ -#define ACPI_VALID_HID 0x1 -#define ACPI_VALID_UID 0x2 -#define ACPI_VALID_ADR 0x4 -#define ACPI_VALID_STA 0x8 +struct acpi_device_id +{ + char value[ACPI_DEVICE_ID_LENGTH]; +}; + +/* Common string version of device CIDs */ + +struct acpi_compatible_id +{ + char value[ACPI_MAX_CID_LENGTH]; +}; + +struct acpi_compatible_id_list +{ + u32 count; + u32 size; + struct acpi_compatible_id id[1]; +}; + + +/* Structure and flags for acpi_get_object_info */ + +#define ACPI_VALID_STA 0x0001 +#define ACPI_VALID_ADR 0x0002 +#define ACPI_VALID_HID 0x0004 +#define ACPI_VALID_UID 0x0008 +#define ACPI_VALID_CID 0x0010 #define ACPI_COMMON_OBJ_INFO \ @@ -851,15 +874,18 @@ struct acpi_obj_info_header }; +/* Structure returned from Get Object Info */ + struct acpi_device_info { ACPI_COMMON_OBJ_INFO; - u32 valid; /* Are the next bits legit? */ - char hardware_id[9]; /* _HID value if any */ - char unique_id[9]; /* _UID value if any */ - acpi_integer address; /* _ADR value if any */ - u32 current_status; /* _STA value */ + u32 valid; /* Indicates which fields are valid */ + u32 current_status; /* _STA value */ + acpi_integer address; /* _ADR value if any */ + struct acpi_device_id hardware_id; /* _HID value if any */ + struct acpi_device_id unique_id; /* _UID value if any */ + struct acpi_compatible_id_list compatibility_id; /* List of _CIDs if any */ }; diff --git a/include/acpi/acutils.h b/include/acpi/acutils.h index 576ad04ca41f494cb1fa7c37c3b3a4f15bdb00a3..6c79df2c46ac8dc08864bcad9b8b8936da609c18 100644 --- a/include/acpi/acutils.h +++ b/include/acpi/acutils.h @@ -488,7 +488,7 @@ acpi_ut_execute_HID ( acpi_status acpi_ut_execute_CID ( struct acpi_namespace_node *device_node, - struct acpi_device_id *cid); + struct acpi_compatible_id_list **return_cid_list); acpi_status acpi_ut_execute_STA ( diff --git a/include/acpi/amlresrc.h b/include/acpi/amlresrc.h new file mode 100644 index 0000000000000000000000000000000000000000..cdaa4689f36ed2d05681d914279111d93c0f32c5 --- /dev/null +++ b/include/acpi/amlresrc.h @@ -0,0 +1,329 @@ + +/****************************************************************************** + * + * Module Name: amlresrc.h - AML resource descriptors + * + *****************************************************************************/ + +/* + * Copyright (C) 2000 - 2003, R. Byron Moore + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * substantially similar to the "NO WARRANTY" disclaimer below + * ("Disclaimer") and any redistribution must be conditioned upon + * including a substantially similar Disclaimer requirement for further + * binary redistribution. + * 3. Neither the names of the above-listed copyright holders nor the names + * of any contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + */ + + +#ifndef __AMLRESRC_H +#define __AMLRESRC_H + + +#define ASL_RESNAME_ADDRESS "_ADR" +#define ASL_RESNAME_ALIGNMENT "_ALN" +#define ASL_RESNAME_ADDRESSSPACE "_ASI" +#define ASL_RESNAME_BASEADDRESS "_BAS" +#define ASL_RESNAME_BUSMASTER "_BM_" /* Master(1), Slave(0) */ +#define ASL_RESNAME_DECODE "_DEC" +#define ASL_RESNAME_DMA "_DMA" +#define ASL_RESNAME_DMATYPE "_TYP" /* Compatible(0), A(1), B(2), F(3) */ +#define ASL_RESNAME_GRANULARITY "_GRA" +#define ASL_RESNAME_INTERRUPT "_INT" +#define ASL_RESNAME_INTERRUPTLEVEL "_LL_" /* active_lo(1), active_hi(0) */ +#define ASL_RESNAME_INTERRUPTSHARE "_SHR" /* Shareable(1), no_share(0) */ +#define ASL_RESNAME_INTERRUPTTYPE "_HE_" /* Edge(1), Level(0) */ +#define ASL_RESNAME_LENGTH "_LEN" +#define ASL_RESNAME_MEMATTRIBUTES "_MTP" /* Memory(0), Reserved(1), ACPI(2), NVS(3) */ +#define ASL_RESNAME_MEMTYPE "_MEM" /* non_cache(0), Cacheable(1) Cache+combine(2), Cache+prefetch(3) */ +#define ASL_RESNAME_MAXADDR "_MAX" +#define ASL_RESNAME_MINADDR "_MIN" +#define ASL_RESNAME_MAXTYPE "_MAF" +#define ASL_RESNAME_MINTYPE "_MIF" +#define ASL_RESNAME_REGISTERBITOFFSET "_RBO" +#define ASL_RESNAME_REGISTERBITWIDTH "_RBW" +#define ASL_RESNAME_RANGETYPE "_RNG" +#define ASL_RESNAME_READWRITETYPE "_RW_" /* read_only(0), Writeable (1) */ +#define ASL_RESNAME_TRANSLATION "_TRA" +#define ASL_RESNAME_TRANSTYPE "_TRS" /* Sparse(1), Dense(0) */ +#define ASL_RESNAME_TYPE "_TTP" /* Translation(1), Static (0) */ +#define ASL_RESNAME_XFERTYPE "_SIz" /* 8(0), 8_and16(1), 16(2) */ + + +/* Default sizes for "small" resource descriptors */ + +#define ASL_RDESC_IRQ_SIZE 0x02 +#define ASL_RDESC_DMA_SIZE 0x02 +#define ASL_RDESC_ST_DEPEND_SIZE 0x00 +#define ASL_RDESC_END_DEPEND_SIZE 0x00 +#define ASL_RDESC_IO_SIZE 0x07 +#define ASL_RDESC_FIXED_IO_SIZE 0x03 +#define ASL_RDESC_END_TAG_SIZE 0x01 + + +struct asl_resource_node +{ + u32 buffer_length; + void *buffer; + struct asl_resource_node *next; +}; + + +/* + * Resource descriptors defined in the ACPI specification. + * + * Alignment must be BYTE because these descriptors + * are used to overlay the AML byte stream. + */ +#pragma pack(1) + +struct asl_irq_format_desc +{ + u8 descriptor_type; + u16 irq_mask; + u8 flags; +}; + + +struct asl_irq_noflags_desc +{ + u8 descriptor_type; + u16 irq_mask; +}; + + +struct asl_dma_format_desc +{ + u8 descriptor_type; + u8 dma_channel_mask; + u8 flags; +}; + + +struct asl_start_dependent_desc +{ + u8 descriptor_type; + u8 flags; +}; + + +struct asl_start_dependent_noprio_desc +{ + u8 descriptor_type; +}; + + +struct asl_end_dependent_desc +{ + u8 descriptor_type; +}; + + +struct asl_io_port_desc +{ + u8 descriptor_type; + u8 information; + u16 address_min; + u16 address_max; + u8 alignment; + u8 length; +}; + + +struct asl_fixed_io_port_desc +{ + u8 descriptor_type; + u16 base_address; + u8 length; +}; + + +struct asl_small_vendor_desc +{ + u8 descriptor_type; + u8 vendor_defined[7]; +}; + + +struct asl_end_tag_desc +{ + u8 descriptor_type; + u8 checksum; +}; + + +/* LARGE descriptors */ + +struct asl_memory_24_desc +{ + u8 descriptor_type; + u16 length; + u8 information; + u16 address_min; + u16 address_max; + u16 alignment; + u16 range_length; +}; + + +struct asl_large_vendor_desc +{ + u8 descriptor_type; + u16 length; + u8 vendor_defined[1]; +}; + + +struct asl_memory_32_desc +{ + u8 descriptor_type; + u16 length; + u8 information; + u32 address_min; + u32 address_max; + u32 alignment; + u32 range_length; +}; + + +struct asl_fixed_memory_32_desc +{ + u8 descriptor_type; + u16 length; + u8 information; + u32 base_address; + u32 range_length; +}; + + +struct asl_qword_address_desc +{ + u8 descriptor_type; + u16 length; + u8 resource_type; + u8 flags; + u8 specific_flags; + u64 granularity; + u64 address_min; + u64 address_max; + u64 translation_offset; + u64 address_length; + u8 optional_fields[2]; +}; + + +struct asl_dword_address_desc +{ + u8 descriptor_type; + u16 length; + u8 resource_type; + u8 flags; + u8 specific_flags; + u32 granularity; + u32 address_min; + u32 address_max; + u32 translation_offset; + u32 address_length; + u8 optional_fields[2]; +}; + + +struct asl_word_address_desc +{ + u8 descriptor_type; + u16 length; + u8 resource_type; + u8 flags; + u8 specific_flags; + u16 granularity; + u16 address_min; + u16 address_max; + u16 translation_offset; + u16 address_length; + u8 optional_fields[2]; +}; + + +struct asl_extended_xrupt_desc +{ + u8 descriptor_type; + u16 length; + u8 flags; + u8 table_length; + u32 interrupt_number[1]; + /* res_source_index, res_source optional fields follow */ +}; + + +struct asl_general_register_desc +{ + u8 descriptor_type; + u16 length; + u8 address_space_id; + u8 bit_width; + u8 bit_offset; + u8 reserved; + u64 address; +}; + +/* restore default alignment */ + +#pragma pack() + +/* Union of all resource descriptors, sow we can allocate the worst case */ + +union asl_resource_desc +{ + struct asl_irq_format_desc irq; + struct asl_dma_format_desc dma; + struct asl_start_dependent_desc std; + struct asl_end_dependent_desc end; + struct asl_io_port_desc iop; + struct asl_fixed_io_port_desc fio; + struct asl_small_vendor_desc smv; + struct asl_end_tag_desc et; + + struct asl_memory_24_desc M24; + struct asl_large_vendor_desc lgv; + struct asl_memory_32_desc M32; + struct asl_fixed_memory_32_desc F32; + struct asl_qword_address_desc qas; + struct asl_dword_address_desc das; + struct asl_word_address_desc was; + struct asl_extended_xrupt_desc exx; + struct asl_general_register_desc grg; + u32 u32_item; + u16 u16_item; + u8 U8item; +}; + + +#endif + diff --git a/include/linux/ide.h b/include/linux/ide.h index f773ff4268a93fd7c64b0cd7f02e9f3809c18955..a6166056977c9aba7b5098de18fe31a93e3fece2 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -886,6 +886,8 @@ typedef struct hwif_s { struct pnp_dev *pnp_dev; /* for PnP devices */ + ide_startstop_t (*rw_disk)(ide_drive_t *, struct request *, sector_t); + #if 0 ide_hwif_ops_t *hwifops; #else @@ -1001,6 +1003,7 @@ typedef struct hwif_s { unsigned noprobe : 1; /* don't probe for this interface */ unsigned present : 1; /* this interface exists */ + unsigned hold : 1; /* this interface is always present */ unsigned serialized : 1; /* serialized all channel operation */ unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned reset : 1; /* reset after probe */ @@ -1534,6 +1537,8 @@ extern u8 eighty_ninty_three (ide_drive_t *); extern int set_transfer(ide_drive_t *, ide_task_t *); extern int taskfile_lib_get_identify(ide_drive_t *drive, u8 *); +ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, sector_t block); + /* * ide_system_bus_speed() returns what we think is the system VESA/PCI * bus speed (in MHz). This is used for calculating interface PIO timings. diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 4c8f4240d33d9f4e470b4c357d584847f4b6f5cb..4f5fdde6dc4b55b8af73b25567bc1c8d60632f06 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -557,6 +557,7 @@ #define PCI_DEVICE_ID_SI_650 0x0650 #define PCI_DEVICE_ID_SI_651 0x0651 #define PCI_DEVICE_ID_SI_652 0x0652 +#define PCI_DEVICE_ID_SI_655 0x0655 #define PCI_DEVICE_ID_SI_730 0x0730 #define PCI_DEVICE_ID_SI_630_VGA 0x6300 #define PCI_DEVICE_ID_SI_730_VGA 0x7300 @@ -1127,6 +1128,7 @@ #define PCI_DEVICE_ID_VIA_8753_0 0x3128 #define PCI_DEVICE_ID_VIA_8233A 0x3147 #define PCI_DEVICE_ID_VIA_8752 0x3148 +#define PCI_DEVICE_ID_VIA_8237_SATA 0x3149 #define PCI_DEVICE_ID_VIA_KN266 0x3156 #define PCI_DEVICE_ID_VIA_8754 0x3168 #define PCI_DEVICE_ID_VIA_8235 0x3177 @@ -1135,6 +1137,7 @@ #define PCI_DEVICE_ID_VIA_8377_0 0x3189 #define PCI_DEVICE_ID_VIA_KM400 0x3205 #define PCI_DEVICE_ID_VIA_P4M400 0x3209 +#define PCI_DEVICE_ID_VIA_8237 0x3227 #define PCI_DEVICE_ID_VIA_86C100A 0x6100 #define PCI_DEVICE_ID_VIA_8231 0x8231 #define PCI_DEVICE_ID_VIA_8231_4 0x8235 @@ -1893,6 +1896,7 @@ #define PCI_DEVICE_ID_INTEL_82801DB_12 0x24cc #define PCI_DEVICE_ID_INTEL_82801DB_13 0x24cd #define PCI_DEVICE_ID_INTEL_82801EB_0 0x24d0 +#define PCI_DEVICE_ID_INTEL_82801EB_1 0x24d1 #define PCI_DEVICE_ID_INTEL_82801EB_2 0x24d2 #define PCI_DEVICE_ID_INTEL_82801EB_3 0x24d3 #define PCI_DEVICE_ID_INTEL_82801EB_4 0x24d4