Commit 6ff46bbc authored by Len Brown's avatar Len Brown

Merge intel.com:/home/lenb/bk/26-latest-ref

into intel.com:/home/lenb/src/26-latest-dev
parents 43fffc41 0d67b6bc
...@@ -71,6 +71,7 @@ int acpi_ht __initdata = 1; /* enable HT */ ...@@ -71,6 +71,7 @@ int acpi_ht __initdata = 1; /* enable HT */
int acpi_lapic; int acpi_lapic;
int acpi_ioapic; int acpi_ioapic;
int acpi_strict; int acpi_strict;
EXPORT_SYMBOL(acpi_strict);
acpi_interrupt_flags acpi_sci_flags __initdata; acpi_interrupt_flags acpi_sci_flags __initdata;
int acpi_sci_override_gsi __initdata; int acpi_sci_override_gsi __initdata;
......
...@@ -598,6 +598,10 @@ acpi_early_init (void) ...@@ -598,6 +598,10 @@ acpi_early_init (void)
ACPI_FUNCTION_TRACE("acpi_bus_init"); ACPI_FUNCTION_TRACE("acpi_bus_init");
/* enable workarounds, unless strict ACPI spec. compliance */
if (!acpi_strict)
acpi_gbl_enable_interpreter_slack = TRUE;
status = acpi_initialize_subsystem(); status = acpi_initialize_subsystem();
if (ACPI_FAILURE(status)) { if (ACPI_FAILURE(status)) {
printk(KERN_ERR PREFIX "Unable to initialize the ACPI Interpreter\n"); printk(KERN_ERR PREFIX "Unable to initialize the ACPI Interpreter\n");
......
...@@ -58,15 +58,12 @@ ...@@ -58,15 +58,12 @@
* *
* FUNCTION: acpi_ds_parse_method * FUNCTION: acpi_ds_parse_method
* *
* PARAMETERS: obj_handle - Node of the method * PARAMETERS: obj_handle - Method node
* Level - Current nesting level
* Context - Points to a method counter
* return_value - Not used
* *
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Call the parser and parse the AML that is * DESCRIPTION: Call the parser and parse the AML that is associated with the
* associated with the method. * method.
* *
* MUTEX: Assumes parser is locked * MUTEX: Assumes parser is locked
* *
...@@ -191,8 +188,6 @@ acpi_ds_parse_method ( ...@@ -191,8 +188,6 @@ acpi_ds_parse_method (
* increments the thread count, and waits at the method semaphore * increments the thread count, and waits at the method semaphore
* for clearance to execute. * for clearance to execute.
* *
* MUTEX: Locks/unlocks parser.
*
******************************************************************************/ ******************************************************************************/
acpi_status acpi_status
...@@ -251,7 +246,8 @@ acpi_ds_begin_method_execution ( ...@@ -251,7 +246,8 @@ acpi_ds_begin_method_execution (
* *
* FUNCTION: acpi_ds_call_control_method * FUNCTION: acpi_ds_call_control_method
* *
* PARAMETERS: walk_state - Current state of the walk * PARAMETERS: Thread - Info for this thread
* this_walk_state - Current walk state
* Op - Current Op to be walked * Op - Current Op to be walked
* *
* RETURN: Status * RETURN: Status
...@@ -401,12 +397,13 @@ acpi_ds_call_control_method ( ...@@ -401,12 +397,13 @@ acpi_ds_call_control_method (
* *
* FUNCTION: acpi_ds_restart_control_method * FUNCTION: acpi_ds_restart_control_method
* *
* PARAMETERS: walk_state - State of the method when it was preempted * PARAMETERS: walk_state - State for preempted method (caller)
* Op - Pointer to new current op * return_desc - Return value from the called method
* *
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Restart a method that was preempted * DESCRIPTION: Restart a method that was preempted by another (nested) method
* invocation. Handle the return value (if any) from the callee.
* *
******************************************************************************/ ******************************************************************************/
...@@ -421,17 +418,35 @@ acpi_ds_restart_control_method ( ...@@ -421,17 +418,35 @@ acpi_ds_restart_control_method (
ACPI_FUNCTION_TRACE_PTR ("ds_restart_control_method", walk_state); ACPI_FUNCTION_TRACE_PTR ("ds_restart_control_method", walk_state);
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"****Restart [%4.4s] Op %p return_value_from_callee %p\n",
(char *) &walk_state->method_node->name, walk_state->method_call_op,
return_desc));
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
" return_from_this_method_used?=%X res_stack %p Walk %p\n",
walk_state->return_used,
walk_state->results, walk_state));
/* Did the called method return a value? */
if (return_desc) { if (return_desc) {
/* Are we actually going to use the return value? */
if (walk_state->return_used) { if (walk_state->return_used) {
/* /* Save the return value from the previous method */
* Get the return value (if any) from the previous method.
* NULL if no return value
*/
status = acpi_ds_result_push (return_desc, walk_state); status = acpi_ds_result_push (return_desc, walk_state);
if (ACPI_FAILURE (status)) { if (ACPI_FAILURE (status)) {
acpi_ut_remove_reference (return_desc); acpi_ut_remove_reference (return_desc);
return_ACPI_STATUS (status); return_ACPI_STATUS (status);
} }
/*
* Save as THIS method's return value in case it is returned
* immediately to yet another method
*/
walk_state->return_desc = return_desc;
} }
else { else {
/* /*
...@@ -442,11 +457,6 @@ acpi_ds_restart_control_method ( ...@@ -442,11 +457,6 @@ acpi_ds_restart_control_method (
} }
} }
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"Method=%p Return=%p return_used?=%X res_stack=%p State=%p\n",
walk_state->method_call_op, return_desc, walk_state->return_used,
walk_state->results, walk_state));
return_ACPI_STATUS (AE_OK); return_ACPI_STATUS (AE_OK);
} }
......
...@@ -60,11 +60,10 @@ ...@@ -60,11 +60,10 @@
* *
* FUNCTION: acpi_ds_is_result_used * FUNCTION: acpi_ds_is_result_used
* *
* PARAMETERS: Op * PARAMETERS: Op - Current Op
* result_obj * walk_state - Current State
* walk_state
* *
* RETURN: Status * RETURN: TRUE if result is used, FALSE otherwise
* *
* DESCRIPTION: Check if a result object will be used by the parent * DESCRIPTION: Check if a result object will be used by the parent
* *
...@@ -89,18 +88,39 @@ acpi_ds_is_result_used ( ...@@ -89,18 +88,39 @@ acpi_ds_is_result_used (
} }
/* /*
* If there is no parent, the result can't possibly be used! * If there is no parent, we are executing at the method level.
* (An executing method typically has no parent, since each * An executing method typically has no parent, since each method
* method is parsed separately) However, a method that is * is parsed separately.
* invoked from another method has a parent.
*/ */
if (!op->common.parent) { if (!op->common.parent) {
/*
* If this is the last statement in the method, we know it is not a
* Return() operator (would not come here.) The following code is the
* optional support for a so-called "implicit return". Some AML code
* assumes that the last value of the method is "implicitly" returned
* to the caller. Just save the last result as the return value.
* NOTE: this is optional because the ASL language does not actually
* support this behavior.
*/
if ((acpi_gbl_enable_interpreter_slack) &&
(walk_state->parser_state.aml >= walk_state->parser_state.aml_end)) {
ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH,
"Result of [%s] will be implicitly returned\n",
acpi_ps_get_opcode_name (op->common.aml_opcode)));
/* Use the top of the result stack as the implicit return value */
walk_state->return_desc = walk_state->results->results.obj_desc[0];
return_VALUE (TRUE);
}
/* No parent, the return value cannot possibly be used */
return_VALUE (FALSE); return_VALUE (FALSE);
} }
/* /* Get info on the parent. The root_op is AML_SCOPE */
* Get info on the parent. The root Op is AML_SCOPE
*/
parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode); parent_info = acpi_ps_get_opcode_info (op->common.parent->common.aml_opcode);
if (parent_info->class == AML_CLASS_UNKNOWN) { if (parent_info->class == AML_CLASS_UNKNOWN) {
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown parent opcode. Op=%p\n", op)); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown parent opcode. Op=%p\n", op));
...@@ -204,9 +224,9 @@ acpi_ds_is_result_used ( ...@@ -204,9 +224,9 @@ acpi_ds_is_result_used (
* *
* FUNCTION: acpi_ds_delete_result_if_not_used * FUNCTION: acpi_ds_delete_result_if_not_used
* *
* PARAMETERS: Op * PARAMETERS: Op - Current parse Op
* result_obj * result_obj - Result of the operation
* walk_state * walk_state - Current state
* *
* RETURN: Status * RETURN: Status
* *
...@@ -338,8 +358,9 @@ acpi_ds_clear_operands ( ...@@ -338,8 +358,9 @@ acpi_ds_clear_operands (
* *
* FUNCTION: acpi_ds_create_operand * FUNCTION: acpi_ds_create_operand
* *
* PARAMETERS: walk_state * PARAMETERS: walk_state - Current walk state
* Arg * Arg - Parse object for the argument
* arg_index - Which argument (zero based)
* *
* RETURN: Status * RETURN: Status
* *
......
...@@ -102,6 +102,8 @@ acpi_ev_set_gpe_type ( ...@@ -102,6 +102,8 @@ acpi_ev_set_gpe_type (
* FUNCTION: acpi_ev_update_gpe_enable_masks * FUNCTION: acpi_ev_update_gpe_enable_masks
* *
* PARAMETERS: gpe_event_info - GPE to update * PARAMETERS: gpe_event_info - GPE to update
* Type - What to do: ACPI_GPE_DISABLE or
* ACPI_GPE_ENABLE
* *
* RETURN: Status * RETURN: Status
* *
...@@ -166,6 +168,8 @@ acpi_ev_update_gpe_enable_masks ( ...@@ -166,6 +168,8 @@ acpi_ev_update_gpe_enable_masks (
* FUNCTION: acpi_ev_enable_gpe * FUNCTION: acpi_ev_enable_gpe
* *
* PARAMETERS: gpe_event_info - GPE to enable * PARAMETERS: gpe_event_info - GPE to enable
* write_to_hardware - Enable now, or just mark data structs
* (WAKE GPEs should be deferred)
* *
* RETURN: Status * RETURN: Status
* *
...@@ -707,7 +711,7 @@ acpi_ev_gpe_dispatch ( ...@@ -707,7 +711,7 @@ acpi_ev_gpe_dispatch (
#ifdef ACPI_GPE_NOTIFY_CHECK #ifdef ACPI_GPE_NOTIFY_CHECK
/******************************************************************************* /*******************************************************************************
* NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED * TBD: NOT USED, PROTOTYPE ONLY AND WILL PROBABLY BE REMOVED
* *
* FUNCTION: acpi_ev_check_for_wake_only_gpe * FUNCTION: acpi_ev_check_for_wake_only_gpe
* *
......
...@@ -88,9 +88,10 @@ acpi_ev_is_notify_object ( ...@@ -88,9 +88,10 @@ acpi_ev_is_notify_object (
* *
* FUNCTION: acpi_ev_queue_notify_request * FUNCTION: acpi_ev_queue_notify_request
* *
* PARAMETERS: * PARAMETERS: Node - NS node for the notified object
* notify_value - Value from the Notify() request
* *
* RETURN: None. * RETURN: Status
* *
* DESCRIPTION: Dispatch a device notification event to a previously * DESCRIPTION: Dispatch a device notification event to a previously
* installed handler. * installed handler.
...@@ -143,9 +144,8 @@ acpi_ev_queue_notify_request ( ...@@ -143,9 +144,8 @@ acpi_ev_queue_notify_request (
notify_value)); notify_value));
} }
/* /* Get the notify object attached to the NS Node */
* Get the notify object attached to the NS Node
*/
obj_desc = acpi_ns_get_attached_object (node); obj_desc = acpi_ns_get_attached_object (node);
if (obj_desc) { if (obj_desc) {
/* We have the notify object, Get the right handler */ /* We have the notify object, Get the right handler */
...@@ -193,8 +193,10 @@ acpi_ev_queue_notify_request ( ...@@ -193,8 +193,10 @@ acpi_ev_queue_notify_request (
} }
if (!handler_obj) { if (!handler_obj) {
/* There is no per-device notify handler for this device */ /*
* There is no per-device notify handler for this device.
* This may or may not be a problem.
*/
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
"No notify handler for Notify(%4.4s, %X) node %p\n", "No notify handler for Notify(%4.4s, %X) node %p\n",
acpi_ut_get_node_name (node), notify_value, node)); acpi_ut_get_node_name (node), notify_value, node));
...@@ -208,7 +210,7 @@ acpi_ev_queue_notify_request ( ...@@ -208,7 +210,7 @@ acpi_ev_queue_notify_request (
* *
* FUNCTION: acpi_ev_notify_dispatch * FUNCTION: acpi_ev_notify_dispatch
* *
* PARAMETERS: * PARAMETERS: Context - To be passsed to the notify handler
* *
* RETURN: None. * RETURN: None.
* *
...@@ -275,6 +277,8 @@ acpi_ev_notify_dispatch ( ...@@ -275,6 +277,8 @@ acpi_ev_notify_dispatch (
* *
* FUNCTION: acpi_ev_global_lock_thread * FUNCTION: acpi_ev_global_lock_thread
* *
* PARAMETERS: Context - From thread interface, not used
*
* RETURN: None * RETURN: None
* *
* DESCRIPTION: Invoked by SCI interrupt handler upon acquisition of the * DESCRIPTION: Invoked by SCI interrupt handler upon acquisition of the
...@@ -308,7 +312,9 @@ acpi_ev_global_lock_thread ( ...@@ -308,7 +312,9 @@ acpi_ev_global_lock_thread (
* *
* FUNCTION: acpi_ev_global_lock_handler * FUNCTION: acpi_ev_global_lock_handler
* *
* RETURN: Status * PARAMETERS: Context - From thread interface, not used
*
* RETURN: ACPI_INTERRUPT_HANDLED or ACPI_INTERRUPT_NOT_HANDLED
* *
* DESCRIPTION: Invoked directly from the SCI handler when a global lock * DESCRIPTION: Invoked directly from the SCI handler when a global lock
* release interrupt occurs. Grab the global lock and queue * release interrupt occurs. Grab the global lock and queue
...@@ -355,6 +361,8 @@ acpi_ev_global_lock_handler ( ...@@ -355,6 +361,8 @@ acpi_ev_global_lock_handler (
* *
* FUNCTION: acpi_ev_init_global_lock_handler * FUNCTION: acpi_ev_init_global_lock_handler
* *
* PARAMETERS: None
*
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Install a handler for the global lock release event * DESCRIPTION: Install a handler for the global lock release event
...@@ -394,6 +402,8 @@ acpi_ev_init_global_lock_handler (void) ...@@ -394,6 +402,8 @@ acpi_ev_init_global_lock_handler (void)
* *
* FUNCTION: acpi_ev_acquire_global_lock * FUNCTION: acpi_ev_acquire_global_lock
* *
* PARAMETERS: Timeout - Max time to wait for the lock, in millisec.
*
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Attempt to gain ownership of the Global Lock. * DESCRIPTION: Attempt to gain ownership of the Global Lock.
...@@ -461,6 +471,10 @@ acpi_ev_acquire_global_lock ( ...@@ -461,6 +471,10 @@ acpi_ev_acquire_global_lock (
* *
* FUNCTION: acpi_ev_release_global_lock * FUNCTION: acpi_ev_release_global_lock
* *
* PARAMETERS: None
*
* RETURN: Status
*
* DESCRIPTION: Releases ownership of the Global Lock. * DESCRIPTION: Releases ownership of the Global Lock.
* *
******************************************************************************/ ******************************************************************************/
......
...@@ -180,7 +180,7 @@ acpi_ev_initialize_op_regions ( ...@@ -180,7 +180,7 @@ acpi_ev_initialize_op_regions (
* FUNCTION: acpi_ev_execute_reg_method * FUNCTION: acpi_ev_execute_reg_method
* *
* PARAMETERS: region_obj - Object structure * PARAMETERS: region_obj - Object structure
* Function - On (1) or Off (0) * Function - Passed to _REG: On (1) or Off (0)
* *
* RETURN: Status * RETURN: Status
* *
...@@ -232,7 +232,7 @@ acpi_ev_execute_reg_method ( ...@@ -232,7 +232,7 @@ acpi_ev_execute_reg_method (
goto cleanup; goto cleanup;
} }
/* Set up the parameter objects */ /* Setup the parameter objects */
params[0]->integer.value = region_obj->region.space_id; params[0]->integer.value = region_obj->region.space_id;
params[1]->integer.value = function; params[1]->integer.value = function;
...@@ -262,7 +262,6 @@ acpi_ev_execute_reg_method ( ...@@ -262,7 +262,6 @@ acpi_ev_execute_reg_method (
* FUNCTION: acpi_ev_address_space_dispatch * FUNCTION: acpi_ev_address_space_dispatch
* *
* PARAMETERS: region_obj - Internal region object * PARAMETERS: region_obj - Internal region object
* space_id - ID of the address space (0-255)
* Function - Read or Write operation * Function - Read or Write operation
* Address - Where in the space to read or write * Address - Where in the space to read or write
* bit_width - Field width in bits (8, 16, 32, or 64) * bit_width - Field width in bits (8, 16, 32, or 64)
...@@ -425,8 +424,8 @@ acpi_ev_address_space_dispatch ( ...@@ -425,8 +424,8 @@ acpi_ev_address_space_dispatch (
* *
* FUNCTION: acpi_ev_detach_region * FUNCTION: acpi_ev_detach_region
* *
* PARAMETERS: region_obj - Region Object * PARAMETERS: region_obj - Region Object
* acpi_ns_is_locked - Namespace Region Already Locked? * acpi_ns_is_locked - Namespace Region Already Locked?
* *
* RETURN: None * RETURN: None
* *
...@@ -560,9 +559,9 @@ acpi_ev_detach_region( ...@@ -560,9 +559,9 @@ acpi_ev_detach_region(
* *
* FUNCTION: acpi_ev_attach_region * FUNCTION: acpi_ev_attach_region
* *
* PARAMETERS: handler_obj - Handler Object * PARAMETERS: handler_obj - Handler Object
* region_obj - Region Object * region_obj - Region Object
* acpi_ns_is_locked - Namespace Region Already Locked? * acpi_ns_is_locked - Namespace Region Already Locked?
* *
* RETURN: None * RETURN: None
* *
...@@ -971,7 +970,7 @@ acpi_ev_install_space_handler ( ...@@ -971,7 +970,7 @@ acpi_ev_install_space_handler (
* *
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Run _REG methods for the Space ID; * DESCRIPTION: Run all _REG methods for the input Space ID;
* Note: assumes namespace is locked, or system init time. * Note: assumes namespace is locked, or system init time.
* *
******************************************************************************/ ******************************************************************************/
......
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
* *
* FUNCTION: acpi_ev_system_memory_region_setup * FUNCTION: acpi_ev_system_memory_region_setup
* *
* PARAMETERS: region_obj - Region we are interested in * PARAMETERS: Handle - Region we are interested in
* Function - Start or stop * Function - Start or stop
* handler_context - Address space handler context * handler_context - Address space handler context
* region_context - Region specific context * region_context - Region specific context
...@@ -108,7 +108,7 @@ acpi_ev_system_memory_region_setup ( ...@@ -108,7 +108,7 @@ acpi_ev_system_memory_region_setup (
* *
* FUNCTION: acpi_ev_io_space_region_setup * FUNCTION: acpi_ev_io_space_region_setup
* *
* PARAMETERS: region_obj - Region we are interested in * PARAMETERS: Handle - Region we are interested in
* Function - Start or stop * Function - Start or stop
* handler_context - Address space handler context * handler_context - Address space handler context
* region_context - Region specific context * region_context - Region specific context
...@@ -144,7 +144,7 @@ acpi_ev_io_space_region_setup ( ...@@ -144,7 +144,7 @@ acpi_ev_io_space_region_setup (
* *
* FUNCTION: acpi_ev_pci_config_region_setup * FUNCTION: acpi_ev_pci_config_region_setup
* *
* PARAMETERS: region_obj - Region we are interested in * PARAMETERS: Handle - Region we are interested in
* Function - Start or stop * Function - Start or stop
* handler_context - Address space handler context * handler_context - Address space handler context
* region_context - Region specific context * region_context - Region specific context
...@@ -317,7 +317,7 @@ acpi_ev_pci_config_region_setup ( ...@@ -317,7 +317,7 @@ acpi_ev_pci_config_region_setup (
* *
* FUNCTION: acpi_ev_pci_bar_region_setup * FUNCTION: acpi_ev_pci_bar_region_setup
* *
* PARAMETERS: region_obj - Region we are interested in * PARAMETERS: Handle - Region we are interested in
* Function - Start or stop * Function - Start or stop
* handler_context - Address space handler context * handler_context - Address space handler context
* region_context - Region specific context * region_context - Region specific context
...@@ -348,7 +348,7 @@ acpi_ev_pci_bar_region_setup ( ...@@ -348,7 +348,7 @@ acpi_ev_pci_bar_region_setup (
* *
* FUNCTION: acpi_ev_cmos_region_setup * FUNCTION: acpi_ev_cmos_region_setup
* *
* PARAMETERS: region_obj - Region we are interested in * PARAMETERS: Handle - Region we are interested in
* Function - Start or stop * Function - Start or stop
* handler_context - Address space handler context * handler_context - Address space handler context
* region_context - Region specific context * region_context - Region specific context
...@@ -379,7 +379,7 @@ acpi_ev_cmos_region_setup ( ...@@ -379,7 +379,7 @@ acpi_ev_cmos_region_setup (
* *
* FUNCTION: acpi_ev_default_region_setup * FUNCTION: acpi_ev_default_region_setup
* *
* PARAMETERS: region_obj - Region we are interested in * PARAMETERS: Handle - Region we are interested in
* Function - Start or stop * Function - Start or stop
* handler_context - Address space handler context * handler_context - Address space handler context
* region_context - Region specific context * region_context - Region specific context
......
...@@ -359,6 +359,7 @@ acpi_install_notify_handler ( ...@@ -359,6 +359,7 @@ acpi_install_notify_handler (
* ACPI_DEVICE_NOTIFY: driver_handler (80-ff) * ACPI_DEVICE_NOTIFY: driver_handler (80-ff)
* ACPI_ALL_NOTIFY: both system and device * ACPI_ALL_NOTIFY: both system and device
* Handler - Address of the handler * Handler - Address of the handler
*
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Remove a handler for notifies on an ACPI device * DESCRIPTION: Remove a handler for notifies on an ACPI device
...@@ -401,9 +402,8 @@ acpi_remove_notify_handler ( ...@@ -401,9 +402,8 @@ acpi_remove_notify_handler (
goto unlock_and_exit; goto unlock_and_exit;
} }
/* /* Root Object */
* Root Object
*/
if (device == ACPI_ROOT_OBJECT) { if (device == ACPI_ROOT_OBJECT) {
ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n")); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing notify handler for ROOT object.\n"));
...@@ -437,9 +437,8 @@ acpi_remove_notify_handler ( ...@@ -437,9 +437,8 @@ acpi_remove_notify_handler (
} }
} }
/* /* All Other Objects */
* All Other Objects
*/
else { else {
/* Notifies allowed on this object? */ /* Notifies allowed on this object? */
......
...@@ -130,7 +130,7 @@ acpi_ex_setup_region ( ...@@ -130,7 +130,7 @@ acpi_ex_setup_region (
if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset if (rgn_desc->region.length < (obj_desc->common_field.base_byte_offset
+ field_datum_byte_offset + field_datum_byte_offset
+ obj_desc->common_field.access_byte_width)) { + obj_desc->common_field.access_byte_width)) {
if (acpi_gbl_enable_interpeter_slack) { if (acpi_gbl_enable_interpreter_slack) {
/* /*
* Slack mode only: We will go ahead and allow access to this * Slack mode only: We will go ahead and allow access to this
* field if it is within the region length rounded up to the next * field if it is within the region length rounded up to the next
...@@ -169,40 +169,7 @@ acpi_ex_setup_region ( ...@@ -169,40 +169,7 @@ acpi_ex_setup_region (
field_datum_byte_offset, obj_desc->common_field.access_byte_width, field_datum_byte_offset, obj_desc->common_field.access_byte_width,
acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length)); acpi_ut_get_node_name (rgn_desc->region.node), rgn_desc->region.length));
if (!acpi_strict) { return_ACPI_STATUS (AE_AML_REGION_LIMIT);
/*
* Allow access to the field if it is within the region size
* rounded up to a multiple of the access byte width. This
* overcomes "off-by-one" programming errors in the AML often
* found in Toshiba laptops. These errors were allowed by
* the Microsoft ASL compiler.
*/
u32 rounded_length = ACPI_ROUND_UP(rgn_desc->region.length,
obj_desc->common_field.access_byte_width);
if (rounded_length < (obj_desc->common_field.base_byte_offset
+ field_datum_byte_offset
+ obj_desc->common_field.access_byte_width)) {
return_ACPI_STATUS (AE_AML_REGION_LIMIT);
} else {
static int warn_once = 1;
if (warn_once) {
// Could also associate a flag with each field, and
// warn once for each field.
ACPI_REPORT_WARNING((
"The ACPI AML in your computer contains errors, "
"please nag the manufacturer to correct it.\n"));
ACPI_REPORT_WARNING((
"Allowing relaxed access to fields; "
"turn on CONFIG_ACPI_DEBUG for details.\n"));
warn_once = 0;
}
return_ACPI_STATUS (AE_OK);
}
}
else {
return_ACPI_STATUS (AE_AML_REGION_LIMIT);
}
} }
return_ACPI_STATUS (AE_OK); return_ACPI_STATUS (AE_OK);
......
...@@ -96,7 +96,7 @@ acpi_hw_write_gpe_enable_reg ( ...@@ -96,7 +96,7 @@ acpi_hw_write_gpe_enable_reg (
* *
* PARAMETERS: gpe_event_info - Info block for the GPE to be cleared * PARAMETERS: gpe_event_info - Info block for the GPE to be cleared
* *
* RETURN: status_status * RETURN: Status
* *
* DESCRIPTION: Clear the status bit for a single GPE. * DESCRIPTION: Clear the status bit for a single GPE.
* *
......
...@@ -249,8 +249,8 @@ acpi_hw_get_bit_register_info ( ...@@ -249,8 +249,8 @@ acpi_hw_get_bit_register_info (
* return_value - Value that was read from the register * return_value - Value that was read from the register
* Flags - Lock the hardware or not * Flags - Lock the hardware or not
* *
* RETURN: Value is read from specified Register. Value returned is * RETURN: Status and the value read from specified Register. Value
* normalized to bit0 (is shifted all the way right) * returned is normalized to bit0 (is shifted all the way right)
* *
* DESCRIPTION: ACPI bit_register read function. * DESCRIPTION: ACPI bit_register read function.
* *
...@@ -284,6 +284,8 @@ acpi_get_register ( ...@@ -284,6 +284,8 @@ acpi_get_register (
} }
} }
/* Read from the register */
status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK, status = acpi_hw_register_read (ACPI_MTX_DO_NOT_LOCK,
bit_reg_info->parent_register, &register_value); bit_reg_info->parent_register, &register_value);
...@@ -313,10 +315,10 @@ acpi_get_register ( ...@@ -313,10 +315,10 @@ acpi_get_register (
* *
* PARAMETERS: register_id - ID of ACPI bit_register to access * PARAMETERS: register_id - ID of ACPI bit_register to access
* Value - (only used on write) value to write to the * Value - (only used on write) value to write to the
* Register, NOT pre-normalized to the bit pos. * Register, NOT pre-normalized to the bit pos
* Flags - Lock the hardware or not * Flags - Lock the hardware or not
* *
* RETURN: None * RETURN: Status
* *
* DESCRIPTION: ACPI Bit Register write function. * DESCRIPTION: ACPI Bit Register write function.
* *
...@@ -461,10 +463,11 @@ acpi_set_register ( ...@@ -461,10 +463,11 @@ acpi_set_register (
* *
* FUNCTION: acpi_hw_register_read * FUNCTION: acpi_hw_register_read
* *
* PARAMETERS: use_lock - Mutex hw access. * PARAMETERS: use_lock - Mutex hw access
* register_id - register_iD + Offset. * register_id - register_iD + Offset
* return_value - Value that was read from the register
* *
* RETURN: Value read or written. * RETURN: Status and the value read.
* *
* DESCRIPTION: Acpi register read function. Registers are read at the * DESCRIPTION: Acpi register read function. Registers are read at the
* given offset. * given offset.
...@@ -572,10 +575,11 @@ acpi_hw_register_read ( ...@@ -572,10 +575,11 @@ acpi_hw_register_read (
* *
* FUNCTION: acpi_hw_register_write * FUNCTION: acpi_hw_register_write
* *
* PARAMETERS: use_lock - Mutex hw access. * PARAMETERS: use_lock - Mutex hw access
* register_id - register_iD + Offset. * register_id - register_iD + Offset
* Value - The value to write
* *
* RETURN: Value read or written. * RETURN: Status
* *
* DESCRIPTION: Acpi register Write function. Registers are written at the * DESCRIPTION: Acpi register Write function. Registers are written at the
* given offset. * given offset.
...@@ -691,11 +695,11 @@ acpi_hw_register_write ( ...@@ -691,11 +695,11 @@ acpi_hw_register_write (
* *
* PARAMETERS: Width - 8, 16, or 32 * PARAMETERS: Width - 8, 16, or 32
* Value - Where the value is returned * Value - Where the value is returned
* Register - GAS register structure * Reg - GAS register structure
* *
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Read from either memory, IO, or PCI config space. * DESCRIPTION: Read from either memory or IO space.
* *
******************************************************************************/ ******************************************************************************/
...@@ -705,8 +709,6 @@ acpi_hw_low_level_read ( ...@@ -705,8 +709,6 @@ acpi_hw_low_level_read (
u32 *value, u32 *value,
struct acpi_generic_address *reg) struct acpi_generic_address *reg)
{ {
struct acpi_pci_id pci_id;
u16 pci_register;
acpi_status status; acpi_status status;
...@@ -725,8 +727,8 @@ acpi_hw_low_level_read ( ...@@ -725,8 +727,8 @@ acpi_hw_low_level_read (
*value = 0; *value = 0;
/* /*
* Three address spaces supported: * Two address spaces supported: Memory or IO.
* Memory, IO, or PCI_Config. * PCI_Config is not supported here because the GAS struct is insufficient
*/ */
switch (reg->address_space_id) { switch (reg->address_space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_MEMORY:
...@@ -744,19 +746,6 @@ acpi_hw_low_level_read ( ...@@ -744,19 +746,6 @@ acpi_hw_low_level_read (
break; break;
case ACPI_ADR_SPACE_PCI_CONFIG:
pci_id.segment = 0;
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);
status = acpi_os_read_pci_configuration (&pci_id, pci_register,
value, width);
break;
default: default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Unsupported address space: %X\n", reg->address_space_id)); "Unsupported address space: %X\n", reg->address_space_id));
...@@ -778,11 +767,11 @@ acpi_hw_low_level_read ( ...@@ -778,11 +767,11 @@ acpi_hw_low_level_read (
* *
* PARAMETERS: Width - 8, 16, or 32 * PARAMETERS: Width - 8, 16, or 32
* Value - To be written * Value - To be written
* Register - GAS register structure * Reg - GAS register structure
* *
* RETURN: Status * RETURN: Status
* *
* DESCRIPTION: Write to either memory, IO, or PCI config space. * DESCRIPTION: Write to either memory or IO space.
* *
******************************************************************************/ ******************************************************************************/
...@@ -792,8 +781,6 @@ acpi_hw_low_level_write ( ...@@ -792,8 +781,6 @@ acpi_hw_low_level_write (
u32 value, u32 value,
struct acpi_generic_address *reg) struct acpi_generic_address *reg)
{ {
struct acpi_pci_id pci_id;
u16 pci_register;
acpi_status status; acpi_status status;
...@@ -811,8 +798,8 @@ acpi_hw_low_level_write ( ...@@ -811,8 +798,8 @@ acpi_hw_low_level_write (
} }
/* /*
* Three address spaces supported: * Two address spaces supported: Memory or IO.
* Memory, IO, or PCI_Config. * PCI_Config is not supported here because the GAS struct is insufficient
*/ */
switch (reg->address_space_id) { switch (reg->address_space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY: case ACPI_ADR_SPACE_SYSTEM_MEMORY:
...@@ -830,19 +817,6 @@ acpi_hw_low_level_write ( ...@@ -830,19 +817,6 @@ acpi_hw_low_level_write (
break; break;
case ACPI_ADR_SPACE_PCI_CONFIG:
pci_id.segment = 0;
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);
status = acpi_os_write_pci_configuration (&pci_id, pci_register,
(acpi_integer) value, width);
break;
default: default:
ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
"Unsupported address space: %X\n", reg->address_space_id)); "Unsupported address space: %X\n", reg->address_space_id));
......
...@@ -52,11 +52,11 @@ ...@@ -52,11 +52,11 @@
* *
* FUNCTION: acpi_get_timer_resolution * FUNCTION: acpi_get_timer_resolution
* *
* PARAMETERS: none * PARAMETERS: Resolution - Where the resolution is returned
* *
* RETURN: Number of bits of resolution in the PM Timer (24 or 32). * RETURN: Status and timer resolution
* *
* DESCRIPTION: Obtains resolution of the ACPI PM Timer. * DESCRIPTION: Obtains resolution of the ACPI PM Timer (24 or 32 bits).
* *
******************************************************************************/ ******************************************************************************/
...@@ -86,11 +86,11 @@ acpi_get_timer_resolution ( ...@@ -86,11 +86,11 @@ acpi_get_timer_resolution (
* *
* FUNCTION: acpi_get_timer * FUNCTION: acpi_get_timer
* *
* PARAMETERS: none * PARAMETERS: Ticks - Where the timer value is returned
* *
* RETURN: Current value of the ACPI PM Timer (in ticks). * RETURN: Status and current ticks
* *
* DESCRIPTION: Obtains current value of ACPI PM Timer. * DESCRIPTION: Obtains current value of ACPI PM Timer (in ticks).
* *
******************************************************************************/ ******************************************************************************/
...@@ -118,11 +118,11 @@ acpi_get_timer ( ...@@ -118,11 +118,11 @@ acpi_get_timer (
* *
* FUNCTION: acpi_get_timer_duration * FUNCTION: acpi_get_timer_duration
* *
* PARAMETERS: start_ticks * PARAMETERS: start_ticks - Starting timestamp
* end_ticks * end_ticks - End timestamp
* time_elapsed * time_elapsed - Where the elapsed time is returned
* *
* RETURN: time_elapsed * RETURN: Status and time_elapsed
* *
* DESCRIPTION: Computes the time elapsed (in microseconds) between two * DESCRIPTION: Computes the time elapsed (in microseconds) between two
* PM Timer time stamps, taking into account the possibility of * PM Timer time stamps, taking into account the possibility of
...@@ -136,7 +136,7 @@ acpi_get_timer ( ...@@ -136,7 +136,7 @@ acpi_get_timer (
* Note that this function accommodates only a single timer * Note that this function accommodates only a single timer
* rollover. Thus for 24-bit timers, this function should only * rollover. Thus for 24-bit timers, this function should only
* be used for calculating durations less than ~4.6 seconds * be used for calculating durations less than ~4.6 seconds
* (~20 minutes for 32-bit timers) -- calculations below * (~20 minutes for 32-bit timers) -- calculations below:
* *
* 2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec * 2**24 Ticks / 3,600,000 Ticks/Sec = 4.66 sec
* 2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes * 2**32 Ticks / 3,600,000 Ticks/Sec = 1193 sec or 19.88 minutes
...@@ -164,7 +164,6 @@ acpi_get_timer_duration ( ...@@ -164,7 +164,6 @@ acpi_get_timer_duration (
/* /*
* Compute Tick Delta: * Compute Tick Delta:
* -------------------
* Handle (max one) timer rollovers on 24- versus 32-bit timers. * Handle (max one) timer rollovers on 24- versus 32-bit timers.
*/ */
if (start_ticks < end_ticks) { if (start_ticks < end_ticks) {
...@@ -188,10 +187,7 @@ acpi_get_timer_duration ( ...@@ -188,10 +187,7 @@ acpi_get_timer_duration (
} }
/* /*
* Compute Duration: * Compute Duration (Requires a 64-bit divide):
* -----------------
*
* Requires a 64-bit divide:
* *
* time_elapsed = (delta_ticks * 1000000) / PM_TIMER_FREQUENCY; * time_elapsed = (delta_ticks * 1000000) / PM_TIMER_FREQUENCY;
*/ */
......
...@@ -51,6 +51,7 @@ acpi_table_print_srat_entry ( ...@@ -51,6 +51,7 @@ acpi_table_print_srat_entry (
switch (header->type) { switch (header->type) {
case ACPI_SRAT_PROCESSOR_AFFINITY: case ACPI_SRAT_PROCESSOR_AFFINITY:
#ifdef ACPI_DEBUG_OUTPUT
{ {
struct acpi_table_processor_affinity *p = struct acpi_table_processor_affinity *p =
(struct acpi_table_processor_affinity*) header; (struct acpi_table_processor_affinity*) header;
...@@ -58,9 +59,11 @@ acpi_table_print_srat_entry ( ...@@ -58,9 +59,11 @@ acpi_table_print_srat_entry (
p->apic_id, p->lsapic_eid, p->proximity_domain, p->apic_id, p->lsapic_eid, p->proximity_domain,
p->flags.enabled?"enabled":"disabled")); p->flags.enabled?"enabled":"disabled"));
} }
#endif /* ACPI_DEBUG_OUTPUT */
break; break;
case ACPI_SRAT_MEMORY_AFFINITY: case ACPI_SRAT_MEMORY_AFFINITY:
#ifdef ACPI_DEBUG_OUTPUT
{ {
struct acpi_table_memory_affinity *p = struct acpi_table_memory_affinity *p =
(struct acpi_table_memory_affinity*) header; (struct acpi_table_memory_affinity*) header;
...@@ -70,6 +73,7 @@ acpi_table_print_srat_entry ( ...@@ -70,6 +73,7 @@ acpi_table_print_srat_entry (
p->flags.enabled ? "enabled" : "disabled", p->flags.enabled ? "enabled" : "disabled",
p->flags.hot_pluggable ? " hot-pluggable" : "")); p->flags.hot_pluggable ? " hot-pluggable" : ""));
} }
#endif /* ACPI_DEBUG_OUTPUT */
break; break;
default: default:
...@@ -94,8 +98,6 @@ acpi_parse_slit (unsigned long phys_addr, unsigned long size) ...@@ -94,8 +98,6 @@ acpi_parse_slit (unsigned long phys_addr, unsigned long size)
/* downcast just for %llu vs %lu for i386/ia64 */ /* downcast just for %llu vs %lu for i386/ia64 */
localities = (u32) slit->localities; localities = (u32) slit->localities;
printk(KERN_INFO PREFIX "SLIT localities %ux%u\n", localities, localities);
acpi_numa_slit_init(slit); acpi_numa_slit_init(slit);
return 0; return 0;
...@@ -103,7 +105,9 @@ acpi_parse_slit (unsigned long phys_addr, unsigned long size) ...@@ -103,7 +105,9 @@ acpi_parse_slit (unsigned long phys_addr, unsigned long size)
static int __init static int __init
acpi_parse_processor_affinity (acpi_table_entry_header *header) acpi_parse_processor_affinity (
acpi_table_entry_header *header,
const unsigned long end)
{ {
struct acpi_table_processor_affinity *processor_affinity; struct acpi_table_processor_affinity *processor_affinity;
...@@ -121,7 +125,9 @@ acpi_parse_processor_affinity (acpi_table_entry_header *header) ...@@ -121,7 +125,9 @@ acpi_parse_processor_affinity (acpi_table_entry_header *header)
static int __init static int __init
acpi_parse_memory_affinity (acpi_table_entry_header *header) acpi_parse_memory_affinity (
acpi_table_entry_header *header,
const unsigned long end)
{ {
struct acpi_table_memory_affinity *memory_affinity; struct acpi_table_memory_affinity *memory_affinity;
...@@ -148,8 +154,6 @@ acpi_parse_srat (unsigned long phys_addr, unsigned long size) ...@@ -148,8 +154,6 @@ acpi_parse_srat (unsigned long phys_addr, unsigned long size)
srat = (struct acpi_table_srat *) __va(phys_addr); srat = (struct acpi_table_srat *) __va(phys_addr);
printk(KERN_INFO PREFIX "SRAT revision %d\n", srat->table_revision);
return 0; return 0;
} }
......
...@@ -448,7 +448,7 @@ acpi_pci_link_set ( ...@@ -448,7 +448,7 @@ acpi_pci_link_set (
#define PIRQ_PENALTY_ISA_USED (16*16*16*16*16) #define PIRQ_PENALTY_ISA_USED (16*16*16*16*16)
#define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16) #define PIRQ_PENALTY_ISA_ALWAYS (16*16*16*16*16*16)
static int __initdata acpi_irq_penalty[ACPI_MAX_IRQS] = { static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */ PIRQ_PENALTY_ISA_ALWAYS, /* IRQ0 timer */
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */ PIRQ_PENALTY_ISA_ALWAYS, /* IRQ1 keyboard */
PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */ PIRQ_PENALTY_ISA_ALWAYS, /* IRQ2 cascade */
...@@ -468,7 +468,7 @@ static int __initdata acpi_irq_penalty[ACPI_MAX_IRQS] = { ...@@ -468,7 +468,7 @@ static int __initdata acpi_irq_penalty[ACPI_MAX_IRQS] = {
/* >IRQ15 */ /* >IRQ15 */
}; };
int int __init
acpi_irq_penalty_init(void) acpi_irq_penalty_init(void)
{ {
struct list_head *node = NULL; struct list_head *node = NULL;
......
...@@ -101,7 +101,7 @@ acpi_table_print ( ...@@ -101,7 +101,7 @@ acpi_table_print (
else else
name = header->signature; name = header->signature;
printk(KERN_INFO PREFIX "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n", printk(KERN_DEBUG PREFIX "%.4s (v%3.3d %6.6s %8.8s 0x%08x %.4s 0x%08x) @ 0x%p\n",
name, header->revision, header->oem_id, name, header->revision, header->oem_id,
header->oem_table_id, header->oem_revision, header->oem_table_id, header->oem_revision,
header->asl_compiler_id, header->asl_compiler_revision, header->asl_compiler_id, header->asl_compiler_revision,
...@@ -587,7 +587,7 @@ acpi_table_init (void) ...@@ -587,7 +587,7 @@ acpi_table_init (void)
return -ENODEV; return -ENODEV;
} }
printk(KERN_INFO PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n", printk(KERN_DEBUG PREFIX "RSDP (v%3.3d %6.6s ) @ 0x%p\n",
rsdp->revision, rsdp->oem_id, (void *) rsdp_phys); rsdp->revision, rsdp->oem_id, (void *) rsdp_phys);
if (rsdp->revision < 2) if (rsdp->revision < 2)
......
...@@ -64,7 +64,7 @@ ...@@ -64,7 +64,7 @@
/* Version string */ /* Version string */
#define ACPI_CA_VERSION 0x20040715 #define ACPI_CA_VERSION 0x20040816
/* /*
* OS name, used for the _OS object. The _OS object is essentially obsolete, * OS name, used for the _OS object. The _OS object is essentially obsolete,
......
...@@ -166,7 +166,7 @@ ...@@ -166,7 +166,7 @@
#define AE_AML_CIRCULAR_REFERENCE (acpi_status) (0x0020 | AE_CODE_AML) #define AE_AML_CIRCULAR_REFERENCE (acpi_status) (0x0020 | AE_CODE_AML)
#define AE_AML_BAD_RESOURCE_LENGTH (acpi_status) (0x0021 | AE_CODE_AML) #define AE_AML_BAD_RESOURCE_LENGTH (acpi_status) (0x0021 | AE_CODE_AML)
#define AE_CODE_AML_MAX 0x0020 #define AE_CODE_AML_MAX 0x0021
/* /*
* Internal exceptions used for control * Internal exceptions used for control
......
...@@ -94,7 +94,7 @@ extern u32 acpi_gbl_nesting_level; ...@@ -94,7 +94,7 @@ extern u32 acpi_gbl_nesting_level;
* interpreter strictly follows the ACPI specification. Setting to TRUE * interpreter strictly follows the ACPI specification. Setting to TRUE
* allows the interpreter to forgive certain bad AML constructs. * allows the interpreter to forgive certain bad AML constructs.
*/ */
ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_enable_interpeter_slack, FALSE); ACPI_EXTERN u8 ACPI_INIT_GLOBAL (acpi_gbl_enable_interpreter_slack, FALSE);
/* /*
* Automatically serialize ALL control methods? Default is FALSE, meaning * Automatically serialize ALL control methods? Default is FALSE, meaning
......
...@@ -364,24 +364,6 @@ ...@@ -364,24 +364,6 @@
#define ACPI_IS_OCTAL_DIGIT(d) (((char)(d) >= '0') && ((char)(d) <= '7')) #define ACPI_IS_OCTAL_DIGIT(d) (((char)(d) >= '0') && ((char)(d) <= '7'))
/* Macros for GAS addressing */
#if ACPI_MACHINE_WIDTH != 16
#define ACPI_PCI_DEVICE(a) (u16) ((ACPI_HIDWORD ((a))) & 0x0000FFFF)
#define ACPI_PCI_FUNCTION(a) (u16) ((ACPI_LODWORD ((a))) >> 16)
#define ACPI_PCI_REGISTER(a) (u16) ((ACPI_LODWORD ((a))) & 0x0000FFFF)
#else
/* No support for GAS and PCI IDs in 16-bit mode */
#define ACPI_PCI_FUNCTION(a) (u16) ((a) & 0xFFFF0000)
#define ACPI_PCI_DEVICE(a) (u16) ((a) & 0x0000FFFF)
#define ACPI_PCI_REGISTER(a) (u16) ((a) & 0x0000FFFF)
#endif
/* Bitfields within ACPI registers */ /* Bitfields within ACPI registers */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment