acpi_status acpi_os_delete_semaphore( acpi_handle handle) { struct semaphore *sem = (struct semaphore*) handle; PROC_NAME("acpi_os_delete_semaphore"); if (!sem) return AE_BAD_PARAMETER; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Deleting semaphore[%p].\n", handle)); acpi_os_free(sem); sem = NULL; return AE_OK; }
u8 acpi_ut_valid_internal_object ( void *object) { PROC_NAME ("Ut_valid_internal_object"); /* Check for a null pointer */ if (!object) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Null Object Ptr\n")); return (FALSE); } /* Check the descriptor type field */ if (!VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_INTERNAL)) { /* Not an ACPI internal object, do some further checking */ if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_NAMED)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Obj %p is a named obj, not ACPI obj\n", object)); } else if (VALID_DESCRIPTOR_TYPE (object, ACPI_DESC_TYPE_PARSER)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Obj %p is a parser obj, not ACPI obj\n", object)); } else { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "**** Obj %p is of unknown type\n", object)); } return (FALSE); } /* The object appears to be a valid acpi_operand_object */ return (TRUE); }
void acpi_ps_free_op ( acpi_parse_object *op) { PROC_NAME ("Ps_free_op"); if (op->opcode == AML_INT_RETURN_VALUE_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Free retval op: %p\n", op)); } if (op->flags == PARSEOP_GENERIC) { acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE, op); } else { acpi_ut_release_to_cache (ACPI_MEM_LIST_PSNODE_EXT, op); } }
void acpi_ds_scope_stack_clear ( acpi_walk_state *walk_state) { acpi_generic_state *scope_info; PROC_NAME ("Ds_scope_stack_clear"); while (walk_state->scope_info) { /* Pop a scope off the stack */ scope_info = walk_state->scope_info; walk_state->scope_info = scope_info->scope.next; ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "Popped object type %X\n", scope_info->common.value)); acpi_ut_delete_generic_state (scope_info); } }
void ec_print ( EC_CONTEXT *ec) { #ifdef ACPI_DEBUG acpi_buffer buffer; #endif /*ACPI_DEBUG*/ PROC_NAME("ec_print"); if (!ec) { return; } acpi_os_printf("EC: found, GPE %d\n", ec->gpe_bit); #ifdef ACPI_DEBUG buffer.length = 256; buffer.pointer = acpi_os_callocate(buffer.length); if (!buffer.pointer) { return; } /* * Get the full pathname for this ACPI object. */ acpi_get_name(ec->acpi_handle, ACPI_FULL_PATHNAME, &buffer); /* * Print out basic thermal zone information. */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Embedded_controller[%02x]:[%p] %s\n", ec->device_handle, ec->acpi_handle, (char*)buffer.pointer)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| gpe_bit[%02x] status/command_port[%02x] data_port[%02x]\n", ec->gpe_bit, ec->status_port, ec->data_port)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); acpi_os_free(buffer.pointer); #endif /*ACPI_DEBUG*/ return; }
/* * TODO: Support for units > 1? */ acpi_status acpi_os_signal_semaphore( acpi_handle handle, u32 units) { struct semaphore *sem = (struct semaphore *) handle; PROC_NAME("acpi_os_signal_semaphore"); if (!sem || (units < 1)) return AE_BAD_PARAMETER; if (units > 1) return AE_SUPPORT; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Signaling semaphore[%p|%d]\n", handle, units)); up(sem); return AE_OK; }
void AcpiNsDumpRootDevices (void) { ACPI_HANDLE SysBusHandle; PROC_NAME ("NsDumpRootDevices"); /* Only dump the table if tracing is enabled */ if (!(ACPI_LV_TABLES & AcpiDbgLevel)) { return; } AcpiGetHandle (0, NS_SYSTEM_BUS, &SysBusHandle); ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Display of all devices in the namespace:\n")); AcpiNsWalkNamespace (ACPI_TYPE_DEVICE, SysBusHandle, ACPI_UINT32_MAX, NS_WALK_NO_UNLOCK, AcpiNsDumpOneDevice, NULL, NULL); }
acpi_status acpi_os_create_semaphore( u32 max_units, u32 initial_units, acpi_handle *handle) { struct semaphore *sem = NULL; PROC_NAME("acpi_os_create_semaphore"); sem = acpi_os_callocate(sizeof(struct semaphore)); if (!sem) return AE_NO_MEMORY; sema_init(sem, initial_units); *handle = (acpi_handle*)sem; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Creating semaphore[%p|%d].\n", *handle, initial_units)); return AE_OK; }
/* * See acpi_os_queue_for_execution() */ static int acpi_os_queue_exec ( void *context) { ACPI_OS_DPC *dpc = (ACPI_OS_DPC*)context; PROC_NAME("acpi_os_queue_exec"); daemonize(); strcpy(current->comm, "kacpidpc"); if (!dpc || !dpc->function) return AE_BAD_PARAMETER; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Executing function [%p(%p)].\n", dpc->function, dpc->context)); dpc->function(dpc->context); kfree(dpc); return 1; }
void acpi_ut_display_init_pathname ( acpi_handle obj_handle, char *path) { acpi_status status; u32 length = 128; char buffer[128]; PROC_NAME ("Ut_display_init_pathname"); status = acpi_ns_handle_to_pathname (obj_handle, &length, buffer); if (ACPI_SUCCESS (status)) { if (path) { ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s.%s\n", buffer, path)); } else { ACPI_DEBUG_PRINT ((ACPI_DB_INIT, "%s\n", buffer)); } } }
void ac_print ( AC_CONTEXT *ac_adapter) { #ifdef ACPI_DEBUG acpi_buffer buffer; PROC_NAME("ac_print"); if (!ac_adapter) { return; } buffer.length = 256; buffer.pointer = acpi_os_callocate(buffer.length); if (!buffer.pointer) { return; } /* * Get the full pathname for this ACPI object. */ acpi_get_name(ac_adapter->acpi_handle, ACPI_FULL_PATHNAME, &buffer); /* * Print out basic adapter information. */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| AC Adapter[%02x]:[%p] %s\n", ac_adapter->device_handle, ac_adapter->acpi_handle, (char*)buffer.pointer)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------\n")); acpi_os_free(buffer.pointer); #endif /*ACPI_DEBUG*/ return; }
static void acpi_os_schedule_exec ( void *context) { ACPI_OS_DPC *dpc = NULL; int thread_pid = -1; PROC_NAME("acpi_os_schedule_exec"); dpc = (ACPI_OS_DPC*)context; if (!dpc) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid (NULL) context.\n")); return; } ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Creating new thread to run function [%p(%p)].\n", dpc->function, dpc->context)); thread_pid = kernel_thread(acpi_os_queue_exec, dpc, (CLONE_FS | CLONE_FILES | SIGCHLD)); if (thread_pid < 0) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to kernel_thread() failed.\n")); acpi_os_free(dpc); } }
void bm_print_eval_error ( u32 debug_level, acpi_handle handle, acpi_string pathname, acpi_status status) { acpi_buffer buffer; acpi_status local_status; PROC_NAME("bm_print_eval_error"); buffer.length = 256; buffer.pointer = acpi_os_callocate(buffer.length); if (!buffer.pointer) { return; } local_status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); if (ACPI_FAILURE(local_status)) { ACPI_DEBUG_PRINT((ACPI_DEBUG_LEVEL(debug_level), "Evaluate object [%p], %s\n", handle, acpi_format_exception(status))); return; } if (pathname) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate object [%s.%s], %s\n", (char*)buffer.pointer, pathname, acpi_format_exception(status))); } else { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate object [%s], %s\n", (char*)buffer.pointer, acpi_format_exception(status))); } acpi_os_free(buffer.pointer); }
acpi_status acpi_os_queue_for_execution( u32 priority, OSD_EXECUTION_CALLBACK function, void *context) { acpi_status status = AE_OK; ACPI_OS_DPC *dpc = NULL; PROC_NAME("acpi_os_queue_for_execution"); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Scheduling function [%p(%p)] for deferred execution.\n", function, context)); if (!function) return AE_BAD_PARAMETER; /* * Queue via DPC: * -------------- * Note that we have to use two different processes for queuing DPCs: * Interrupt-Level: Use schedule_task; can't spawn a new thread. * Kernel-Level: Spawn a new kernel thread, as schedule_task has * its limitations (e.g. single-threaded model), and * all other task queues run at interrupt-level. */ switch (priority) { case OSD_PRIORITY_GPE: { static struct tq_struct task; /* * Allocate/initialize DPC structure. Note that this memory will be * freed by the callee. */ dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_ATOMIC); if (!dpc) return AE_NO_MEMORY; dpc->function = function; dpc->context = context; memset(&task, 0, sizeof(struct tq_struct)); task.routine = acpi_os_schedule_exec; task.data = (void*)dpc; if (schedule_task(&task) < 0) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Call to schedule_task() failed.\n")); status = AE_ERROR; } } break; default: /* * Allocate/initialize DPC structure. Note that this memory will be * freed by the callee. */ dpc = kmalloc(sizeof(ACPI_OS_DPC), GFP_KERNEL); if (!dpc) return AE_NO_MEMORY; dpc->function = function; dpc->context = context; acpi_os_schedule_exec(dpc); break; } return status; }
acpi_status acpi_ut_release_mutex ( ACPI_MUTEX_HANDLE mutex_id) { acpi_status status; u32 i; u32 this_thread_id; PROC_NAME ("Ut_release_mutex"); this_thread_id = acpi_os_get_thread_id (); ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X releasing Mutex [%s]\n", this_thread_id, acpi_ut_get_mutex_name (mutex_id))); if (mutex_id > MAX_MTX) { 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) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Mutex [%s] is not acquired, cannot release\n", acpi_ut_get_mutex_name (mutex_id))); return (AE_NOT_ACQUIRED); } /* * Deadlock prevention. Check if this thread owns any mutexes of value * greater than this one. If so, the thread has violated 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) { if (i == mutex_id) { continue; } ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid release order: owns [%s], releasing [%s]\n", acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id))); return (AE_RELEASE_DEADLOCK); } } /* Mark unlocked FIRST */ acpi_gbl_acpi_mutex_info[mutex_id].owner_id = ACPI_MUTEX_NOT_ACQUIRED; status = acpi_os_signal_semaphore (acpi_gbl_acpi_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", this_thread_id, acpi_ut_get_mutex_name (mutex_id), acpi_format_exception (status))); } else { ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n", this_thread_id, acpi_ut_get_mutex_name (mutex_id))); } return (status); }
static acpi_status acpi_ev_save_method_info ( acpi_handle obj_handle, u32 level, void *obj_desc, void **return_value) { u32 gpe_number; NATIVE_CHAR name[ACPI_NAME_SIZE + 1]; u8 type; PROC_NAME ("Ev_save_method_info"); /* Extract the name from the object and convert to a string */ MOVE_UNALIGNED32_TO_32 (name, &((acpi_namespace_node *) obj_handle)->name); name[ACPI_NAME_SIZE] = 0; /* * Edge/Level determination is based on the 2nd s8 of the method name */ if (name[1] == 'L') { type = ACPI_EVENT_LEVEL_TRIGGERED; } else if (name[1] == 'E') { type = ACPI_EVENT_EDGE_TRIGGERED; } else { /* Unknown method type, just ignore it! */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unknown GPE method type: %s (name not of form _Lnn or _Enn)\n", name)); return (AE_OK); } /* Convert the last two characters of the name to the Gpe Number */ gpe_number = STRTOUL (&name[2], NULL, 16); if (gpe_number == ACPI_UINT32_MAX) { /* Conversion failed; invalid method, just ignore it */ ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Could not extract GPE number from name: %s (name not of form _Lnn or _Enn)\n", name)); return (AE_OK); } /* Ensure that we have a valid GPE number */ if (acpi_gbl_gpe_valid[gpe_number] == ACPI_GPE_INVALID) { /* Not valid, all we can do here is ignore it */ return (AE_OK); } /* * Now we can add this information to the Gpe_info block * for use during dispatch of this GPE. */ acpi_gbl_gpe_info [gpe_number].type = type; acpi_gbl_gpe_info [gpe_number].method_handle = obj_handle; /* * Enable the GPE (SCIs should be disabled at this point) */ acpi_hw_enable_gpe (gpe_number); ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Registered GPE method %s as GPE number %X\n", name, gpe_number)); return (AE_OK); }
NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ NULL, /* truncate */ NULL, /* permission */ NULL, /* smap */ NULL, /* updatepage */ NULL, /* revalidate */ }; static struct proc_dir_entry proc_ftp = { 0, PROC_NAME("ftp_proxy"), /* inode, name */ S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0, /* mode, nlink, uid, gid */ 0, &proc_ftp_inode_operations, /* size, ops */ NULL, NULL, /* get_info, fill_inode */ NULL, /* next */ NULL, NULL, /* parent, subdir */ NULL, /* data */ NULL, NULL, /* read_proc, write_proc */ NULL, /* readlink_proc */ 0, 0, /* count, deleted */ }; /* ------------------------------------------------------------ ** ** ** Function......: proc_ftp_read
acpi_status acpi_ut_acquire_mutex ( ACPI_MUTEX_HANDLE mutex_id) { acpi_status status; u32 i; u32 this_thread_id; PROC_NAME ("Ut_acquire_mutex"); if (mutex_id > MAX_MTX) { return (AE_BAD_PARAMETER); } this_thread_id = acpi_os_get_thread_id (); /* * Deadlock prevention. Check if this thread owns any mutexes of value * greater than or equal to this one. If so, the thread has violated * 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) { if (i == mutex_id) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Mutex [%s] already acquired by this thread [%X]\n", acpi_ut_get_mutex_name (mutex_id), this_thread_id)); return (AE_ALREADY_ACQUIRED); } ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid acquire order: Thread %X owns [%s], wants [%s]\n", this_thread_id, acpi_ut_get_mutex_name (i), acpi_ut_get_mutex_name (mutex_id))); return (AE_ACQUIRE_DEADLOCK); } } ACPI_DEBUG_PRINT ((ACPI_DB_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, 1, 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; } else { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n", this_thread_id, acpi_ut_get_mutex_name (mutex_id), acpi_format_exception (status))); } return (status); }
acpi_status acpi_ds_load2_end_op ( acpi_walk_state *walk_state) { acpi_parse_object *op; acpi_status status = AE_OK; acpi_object_type8 data_type; acpi_namespace_node *node; acpi_parse_object *arg; acpi_namespace_node *new_node; u32 i; PROC_NAME ("Ds_load2_end_op"); op = walk_state->op; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); /* Only interested in opcodes that have namespace objects */ if (!(walk_state->op_info->flags & AML_NSOBJECT)) { return (AE_OK); } if (op->opcode == AML_SCOPE_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Ending scope Op=%p State=%p\n", op, walk_state)); if (((acpi_parse2_object *)op)->name == -1) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Unnamed scope! Op=%p State=%p\n", op, walk_state)); return (AE_OK); } } data_type = acpi_ds_map_named_opcode_to_data_type (op->opcode); /* * Get the Node/name from the earlier lookup * (It was saved in the *op structure) */ node = op->node; /* * Put the Node on the object stack (Contains the ACPI Name of * this object) */ walk_state->operands[0] = (void *) node; walk_state->num_operands = 1; /* Pop the scope stack */ if (acpi_ns_opens_scope (data_type)) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "(%s) Popping scope for Op %p\n", acpi_ut_get_type_name (data_type), op)); acpi_ds_scope_stack_pop (walk_state); } /* * Named operations are as follows: * * AML_ALIAS * AML_BANKFIELD * AML_CREATEBITFIELD * AML_CREATEBYTEFIELD * AML_CREATEDWORDFIELD * AML_CREATEFIELD * AML_CREATEQWORDFIELD * AML_CREATEWORDFIELD * AML_DATA_REGION * AML_DEVICE * AML_EVENT * AML_FIELD * AML_INDEXFIELD * AML_METHOD * AML_METHODCALL * AML_MUTEX * AML_NAME * AML_NAMEDFIELD * AML_OPREGION * AML_POWERRES * AML_PROCESSOR * AML_SCOPE * AML_THERMALZONE */ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Create-Load [%s] State=%p Op=%p Named_obj=%p\n", acpi_ps_get_opcode_name (op->opcode), walk_state, op, node)); /* Decode the opcode */ arg = op->value.arg; switch (walk_state->op_info->type) { case AML_TYPE_CREATE_FIELD: /* * Create the field object, but the field buffer and index must * be evaluated later during the execution phase */ status = acpi_ds_create_buffer_field (op, walk_state); break; case AML_TYPE_NAMED_FIELD: arg = op->value.arg; switch (op->opcode) { case AML_INDEX_FIELD_OP: status = acpi_ds_create_index_field (op, (acpi_handle) arg->node, walk_state); break; case AML_BANK_FIELD_OP: status = acpi_ds_create_bank_field (op, arg->node, walk_state); break; case AML_FIELD_OP: status = acpi_ds_create_field (op, arg->node, walk_state); break; } break; case AML_TYPE_NAMED_SIMPLE: status = acpi_ds_create_operands (walk_state, arg); if (ACPI_FAILURE (status)) { goto cleanup; } switch (op->opcode) { case AML_PROCESSOR_OP: status = acpi_ex_create_processor (walk_state); break; case AML_POWER_RES_OP: status = acpi_ex_create_power_resource (walk_state); break; case AML_MUTEX_OP: status = acpi_ex_create_mutex (walk_state); break; case AML_EVENT_OP: status = acpi_ex_create_event (walk_state); break; case AML_DATA_REGION_OP: status = acpi_ex_create_table_region (walk_state); break; case AML_ALIAS_OP: status = acpi_ex_create_alias (walk_state); break; default: /* Unknown opcode */ status = AE_OK; goto cleanup; break; } /* Delete operands */ for (i = 1; i < walk_state->num_operands; i++) { acpi_ut_remove_reference (walk_state->operands[i]); walk_state->operands[i] = NULL; } break; case AML_TYPE_NAMED_COMPLEX: switch (op->opcode) { case AML_METHOD_OP: /* * Method_op Pkg_length Names_string Method_flags Term_list */ ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "LOADING-Method: State=%p Op=%p Named_obj=%p\n", walk_state, op, node)); if (!node->object) { status = acpi_ds_create_operands (walk_state, arg); if (ACPI_FAILURE (status)) { goto cleanup; } status = acpi_ex_create_method (((acpi_parse2_object *) op)->data, ((acpi_parse2_object *) op)->length, walk_state); } break; case AML_REGION_OP: /* * The Op_region is not fully parsed at this time. Only valid argument is the Space_id. * (We must save the address of the AML of the address and length operands) */ status = acpi_ex_create_region (((acpi_parse2_object *) op)->data, ((acpi_parse2_object *) op)->length, (ACPI_ADR_SPACE_TYPE) arg->value.integer, walk_state); break; case AML_NAME_OP: status = acpi_ds_create_node (walk_state, node, op); break; } break; case AML_CLASS_INTERNAL: /* case AML_INT_NAMEPATH_OP: */ break; case AML_CLASS_METHOD_CALL: ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "RESOLVING-Method_call: State=%p Op=%p Named_obj=%p\n", walk_state, op, node)); /* * Lookup the method name and save the Node */ status = acpi_ns_lookup (walk_state->scope_info, arg->value.string, ACPI_TYPE_ANY, IMODE_LOAD_PASS2, NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, walk_state, &(new_node)); if (ACPI_SUCCESS (status)) { /* TBD: has name already been resolved by here ??*/ /* TBD: [Restructure] Make sure that what we found is indeed a method! */ /* We didn't search for a method on purpose, to see if the name would resolve! */ /* We could put the returned object (Node) on the object stack for later, but * for now, we will put it in the "op" object that the parser uses, so we * can get it again at the end of this scope */ op->node = new_node; } break; default: break; } cleanup: /* Remove the Node pushed at the very beginning */ walk_state->operands[0] = NULL; walk_state->num_operands = 0; return (status); }
acpi_status acpi_ds_load2_begin_op ( acpi_walk_state *walk_state, acpi_parse_object **out_op) { acpi_parse_object *op; acpi_namespace_node *node; acpi_status status; acpi_object_type8 data_type; NATIVE_CHAR *buffer_ptr; void *original = NULL; PROC_NAME ("Ds_load2_begin_op"); op = walk_state->op; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); if (op) { /* We only care about Namespace opcodes here */ if (!(walk_state->op_info->flags & AML_NSOPCODE) && walk_state->opcode != AML_INT_NAMEPATH_OP) { return (AE_OK); } /* TBD: [Restructure] Temp! same code as in psparse */ if (!(walk_state->op_info->flags & AML_NAMED)) { return (AE_OK); } /* * Get the name we are going to enter or lookup in the namespace */ if (walk_state->opcode == AML_INT_NAMEPATH_OP) { /* For Namepath op, get the path string */ buffer_ptr = op->value.string; if (!buffer_ptr) { /* No name, just exit */ return (AE_OK); } } else { /* Get name from the op */ buffer_ptr = (NATIVE_CHAR *) &((acpi_parse2_object *)op)->name; } } else { buffer_ptr = acpi_ps_get_next_namestring (&walk_state->parser_state); } /* Map the raw opcode into an internal object type */ data_type = acpi_ds_map_named_opcode_to_data_type (walk_state->opcode); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "State=%p Op=%p Type=%x\n", walk_state, op, data_type)); if (walk_state->opcode == AML_FIELD_OP || walk_state->opcode == AML_BANK_FIELD_OP || walk_state->opcode == AML_INDEX_FIELD_OP) { node = NULL; status = AE_OK; } else if (walk_state->opcode == AML_INT_NAMEPATH_OP) { /* * The Name_path is an object reference to an existing object. Don't enter the * name into the namespace, but look it up for use later */ status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type, IMODE_EXECUTE, NS_SEARCH_PARENT, walk_state, &(node)); } else { if (op && op->node) { original = op->node; node = op->node; if (acpi_ns_opens_scope (data_type)) { status = acpi_ds_scope_stack_push (node, data_type, walk_state); if (ACPI_FAILURE (status)) { return (status); } } return (AE_OK); } /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that involve * arguments to the opcode must be created as we go back up the parse tree later. */ status = acpi_ns_lookup (walk_state->scope_info, buffer_ptr, data_type, IMODE_EXECUTE, NS_NO_UPSEARCH, walk_state, &(node)); } if (ACPI_SUCCESS (status)) { if (!op) { /* Create a new op */ op = acpi_ps_alloc_op (walk_state->opcode); if (!op) { return (AE_NO_MEMORY); } /* Initialize */ ((acpi_parse2_object *)op)->name = node->name; *out_op = op; } /* * Put the Node in the "op" object that the parser uses, so we * can get it again quickly when this scope is closed */ op->node = node; if (original) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "old %p new %p\n", original, node)); if (original != node) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Lookup match error: old %p new %p\n", original, node)); } } } return (status); }
acpi_status acpi_ds_load1_begin_op ( acpi_walk_state *walk_state, acpi_parse_object **out_op) { acpi_parse_object *op; acpi_namespace_node *node; acpi_status status; acpi_object_type8 data_type; NATIVE_CHAR *path; PROC_NAME ("Ds_load1_begin_op"); op = walk_state->op; ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "Op=%p State=%p\n", op, walk_state)); /* We are only interested in opcodes that have an associated name */ if (walk_state->op) { if (!(walk_state->op_info->flags & AML_NAMED)) { *out_op = op; return (AE_OK); } /* Check if this object has already been installed in the namespace */ if (op->node) { *out_op = op; return (AE_OK); } } path = acpi_ps_get_next_namestring (&walk_state->parser_state); /* Map the raw opcode into an internal object type */ data_type = acpi_ds_map_named_opcode_to_data_type (walk_state->opcode); ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "State=%p Op=%p Type=%x\n", walk_state, op, data_type)); if (walk_state->opcode == AML_SCOPE_OP) { ACPI_DEBUG_PRINT ((ACPI_DB_DISPATCH, "State=%p Op=%p Type=%x\n", walk_state, op, data_type)); } /* * Enter the named type into the internal namespace. We enter the name * as we go downward in the parse tree. Any necessary subobjects that involve * arguments to the opcode must be created as we go back up the parse tree later. */ status = acpi_ns_lookup (walk_state->scope_info, path, data_type, IMODE_LOAD_PASS1, NS_NO_UPSEARCH, walk_state, &(node)); if (ACPI_FAILURE (status)) { return (status); } if (!op) { /* Create a new op */ op = acpi_ps_alloc_op (walk_state->opcode); if (!op) { return (AE_NO_MEMORY); } } /* Initialize */ ((acpi_parse2_object *)op)->name = node->name; /* * Put the Node in the "op" object that the parser uses, so we * can get it again quickly when this scope is closed */ op->node = node; acpi_ps_append_arg (acpi_ps_get_parent_scope (&walk_state->parser_state), op); *out_op = op; return (status); }
/* * TODO: The kernel doesn't have a 'down_timeout' function -- had to * improvise. The process is to sleep for one scheduler quantum * until the semaphore becomes available. Downside is that this * may result in starvation for timeout-based waits when there's * lots of semaphore activity. * * TODO: Support for units > 1? */ acpi_status acpi_os_wait_semaphore( acpi_handle handle, u32 units, u32 timeout) { acpi_status status = AE_OK; struct semaphore *sem = (struct semaphore*)handle; int ret = 0; PROC_NAME("acpi_os_wait_semaphore"); if (!sem || (units < 1)) return AE_BAD_PARAMETER; if (units > 1) return AE_SUPPORT; ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Waiting for semaphore[%p|%d|%d]\n", handle, units, timeout)); switch (timeout) { /* * No Wait: * -------- * A zero timeout value indicates that we shouldn't wait - just * acquire the semaphore if available otherwise return AE_TIME * (a.k.a. 'would block'). */ case 0: if(down_trylock(sem)) status = AE_TIME; break; /* * Wait Indefinitely: * ------------------ */ case WAIT_FOREVER: ret = down_interruptible(sem); if (ret < 0) status = AE_ERROR; break; /* * Wait w/ Timeout: * ---------------- */ default: // TODO: A better timeout algorithm? { int i = 0; static const int quantum_ms = 1000/HZ; ret = down_trylock(sem); for (i = timeout; (i > 0 && ret < 0); i -= quantum_ms) { current->state = TASK_INTERRUPTIBLE; schedule_timeout(1); ret = down_trylock(sem); } if (ret != 0) status = AE_TIME; } break; } if (ACPI_FAILURE(status)) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Failed to acquire semaphore[%p|%d|%d]\n", handle, units, timeout)); } else { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Acquired semaphore[%p|%d|%d]\n", handle, units, timeout)); } return status; }
ACPI_STATUS AcpiUtReleaseMutex ( ACPI_MUTEX_HANDLE MutexId) { ACPI_STATUS Status; UINT32 i; UINT32 ThisThreadId; PROC_NAME ("UtReleaseMutex"); ThisThreadId = AcpiOsGetThreadId (); ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X releasing Mutex [%s]\n", ThisThreadId, AcpiUtGetMutexName (MutexId))); if (MutexId > MAX_MTX) { return (AE_BAD_PARAMETER); } /* * Mutex must be acquired in order to release it! */ if (AcpiGbl_AcpiMutexInfo[MutexId].OwnerId == ACPI_MUTEX_NOT_ACQUIRED) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Mutex [%s] is not acquired, cannot release\n", AcpiUtGetMutexName (MutexId))); return (AE_NOT_ACQUIRED); } /* * Deadlock prevention. Check if this thread owns any mutexes of value * greater than this one. If so, the thread has violated the mutex * ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ for (i = MutexId; i < MAX_MTX; i++) { if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId) { if (i == MutexId) { continue; } ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid release order: owns [%s], releasing [%s]\n", AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId))); return (AE_RELEASE_DEADLOCK); } } /* Mark unlocked FIRST */ AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ACPI_MUTEX_NOT_ACQUIRED; Status = AcpiOsSignalSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 1); if (ACPI_FAILURE (Status)) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not release Mutex [%s] %s\n", ThisThreadId, AcpiUtGetMutexName (MutexId), AcpiFormatException (Status))); } else { ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X released Mutex [%s]\n", ThisThreadId, AcpiUtGetMutexName (MutexId))); } return (Status); }
static ACPI_STATUS AcpiNsDumpOneObject ( ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **ReturnValue) { ACPI_WALK_INFO *Info = (ACPI_WALK_INFO *) Context; ACPI_NAMESPACE_NODE *ThisNode; UINT8 *Value; ACPI_OPERAND_OBJECT *ObjDesc = NULL; ACPI_OBJECT_TYPE8 ObjType; ACPI_OBJECT_TYPE8 Type; UINT32 BytesToDump; UINT32 DownstreamSiblingMask = 0; UINT32 LevelTmp; UINT32 WhichBit; PROC_NAME ("NsDumpOneObject"); ThisNode = AcpiNsConvertHandleToEntry (ObjHandle); LevelTmp = Level; Type = ThisNode->Type; WhichBit = 1; if (!(AcpiDbgLevel & Info->DebugLevel)) { return (AE_OK); } if (!ObjHandle) { ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n")); return (AE_OK); } /* Check if the owner matches */ if ((Info->OwnerId != ACPI_UINT32_MAX) && (Info->OwnerId != ThisNode->OwnerId)) { return (AE_OK); } /* Indent the object according to the level */ while (LevelTmp--) { /* Print appropriate characters to form tree structure */ if (LevelTmp) { if (DownstreamSiblingMask & WhichBit) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "|")); } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " ")); } WhichBit <<= 1; } else { if (AcpiNsExistDownstreamSibling (ThisNode + 1)) { DownstreamSiblingMask |= (1 << (Level - 1)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); } else { DownstreamSiblingMask &= ACPI_UINT32_MAX ^ (1 << (Level - 1)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); } if (ThisNode->Child == NULL) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-")); } else if (AcpiNsExistDownstreamSibling (ThisNode->Child)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+")); } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-")); } } } /* Check the integrity of our data */ if (Type > INTERNAL_TYPE_MAX) { Type = INTERNAL_TYPE_DEF_ANY; /* prints as *ERROR* */ } if (!AcpiUtValidAcpiName (ThisNode->Name)) { REPORT_WARNING (("Invalid ACPI Name %08X\n", ThisNode->Name)); } /* * Now we can print out the pertinent information */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %4.4s %-9s ", &ThisNode->Name, AcpiUtGetTypeName (Type))); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "%p S:%p O:%p", ThisNode, ThisNode->Child, ThisNode->Object)); if (!ThisNode->Object) { /* No attached object, we are done */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); return (AE_OK); } switch (Type) { case ACPI_TYPE_METHOD: /* Name is a Method and its AML offset/length are set */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " M:%p-%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Method.Pcode, ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Method.PcodeLength)); break; case ACPI_TYPE_INTEGER: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " N:%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Integer.Value)); break; case ACPI_TYPE_STRING: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " S:%p-%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->String.Pointer, ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->String.Length)); break; case ACPI_TYPE_BUFFER: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " B:%p-%X\n", ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Buffer.Pointer, ((ACPI_OPERAND_OBJECT *) ThisNode->Object)->Buffer.Length)); break; default: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); break; } /* If debug turned off, done */ if (!(AcpiDbgLevel & ACPI_LV_VALUES)) { return (AE_OK); } /* If there is an attached object, display it */ Value = ThisNode->Object; /* Dump attached objects */ while (Value) { ObjType = INTERNAL_TYPE_INVALID; /* Decode the type of attached object and dump the contents */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " Attached Object %p: ", Value)); if (AcpiTbSystemTablePointer (Value)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to AML Code)\n")); BytesToDump = 16; } else if (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_NAMED)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to Node)\n")); BytesToDump = sizeof (ACPI_NAMESPACE_NODE); } else if (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_INTERNAL)) { ObjDesc = (ACPI_OPERAND_OBJECT *) Value; ObjType = ObjDesc->Common.Type; if (ObjType > INTERNAL_TYPE_MAX) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [UNKNOWN])\n", ObjType)); BytesToDump = 32; } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [%s])\n", ObjType, AcpiUtGetTypeName (ObjType))); BytesToDump = sizeof (ACPI_OPERAND_OBJECT); } } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(String or Buffer - not descriptor)\n", Value)); BytesToDump = 16; } DUMP_BUFFER (Value, BytesToDump); /* If value is NOT an internal object, we are done */ if ((AcpiTbSystemTablePointer (Value)) || (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_NAMED))) { goto Cleanup; } /* * Valid object, get the pointer to next level, if any */ switch (ObjType) { case ACPI_TYPE_STRING: Value = (UINT8 *) ObjDesc->String.Pointer; break; case ACPI_TYPE_BUFFER: Value = (UINT8 *) ObjDesc->Buffer.Pointer; break; case ACPI_TYPE_BUFFER_FIELD: Value = (UINT8 *) ObjDesc->BufferField.BufferObj; break; case ACPI_TYPE_PACKAGE: Value = (UINT8 *) ObjDesc->Package.Elements; break; case ACPI_TYPE_METHOD: Value = (UINT8 *) ObjDesc->Method.Pcode; break; case INTERNAL_TYPE_REGION_FIELD: Value = (UINT8 *) ObjDesc->Field.RegionObj; break; case INTERNAL_TYPE_BANK_FIELD: Value = (UINT8 *) ObjDesc->BankField.RegionObj; break; case INTERNAL_TYPE_INDEX_FIELD: Value = (UINT8 *) ObjDesc->IndexField.IndexObj; break; default: goto Cleanup; } ObjType = INTERNAL_TYPE_INVALID; /* Terminate loop after next pass */ } Cleanup: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n")); return (AE_OK); }
acpi_status acpi_ns_init_one_object ( acpi_handle obj_handle, u32 level, void *context, void **return_value) { acpi_object_type8 type; acpi_status status; acpi_init_walk_info *info = (acpi_init_walk_info *) context; acpi_namespace_node *node = (acpi_namespace_node *) obj_handle; acpi_operand_object *obj_desc; PROC_NAME ("Ns_init_one_object"); info->object_count++; /* And even then, we are only interested in a few object types */ type = acpi_ns_get_type (obj_handle); obj_desc = node->object; if (!obj_desc) { return (AE_OK); } if ((type != ACPI_TYPE_REGION) && (type != ACPI_TYPE_BUFFER_FIELD)) { return (AE_OK); } /* * Must lock the interpreter before executing AML code */ status = acpi_ex_enter_interpreter (); if (ACPI_FAILURE (status)) { return (status); } switch (type) { case ACPI_TYPE_REGION: info->op_region_count++; if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { break; } info->op_region_init++; status = acpi_ds_get_region_arguments (obj_desc); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n")); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s while getting region arguments [%4.4s]\n", acpi_format_exception (status), (char*)&node->name)); } if (!(acpi_dbg_level & ACPI_LV_INIT)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, ".")); } break; case ACPI_TYPE_BUFFER_FIELD: info->field_count++; if (obj_desc->common.flags & AOPOBJ_DATA_VALID) { break; } info->field_init++; status = acpi_ds_get_buffer_field_arguments (obj_desc); if (ACPI_FAILURE (status)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_ERROR, "\n")); ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "%s while getting buffer field arguments [%4.4s]\n", acpi_format_exception (status), (char*)&node->name)); } if (!(acpi_dbg_level & ACPI_LV_INIT)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OK, ".")); } break; default: break; } /* * We ignore errors from above, and always return OK, since * we don't want to abort the walk on a single error. */ acpi_ex_exit_interpreter (); return (AE_OK); }
void bm_print_node ( BM_NODE *node, u32 flags) { #ifdef ACPI_DEBUG acpi_buffer buffer; BM_DEVICE *device = NULL; char *type_string = NULL; PROC_NAME("bm_print_node"); if (!node) { return; } device = &(node->device); if (flags & BM_PRINT_PRESENT) { if (!BM_DEVICE_PRESENT(device)) { return; } } buffer.length = 256; buffer.pointer = acpi_os_callocate(buffer.length); if (!buffer.pointer) { return; } acpi_get_name(device->acpi_handle, ACPI_FULL_PATHNAME, &buffer); switch(device->id.type) { case BM_TYPE_SYSTEM: type_string = " System"; break; case BM_TYPE_SCOPE: type_string = " Scope"; break; case BM_TYPE_PROCESSOR: type_string = " Proc"; break; case BM_TYPE_THERMAL_ZONE: type_string = "Thermal"; break; case BM_TYPE_POWER_RESOURCE: type_string = " Power"; break; case BM_TYPE_FIXED_BUTTON: type_string = " Button"; break; case BM_TYPE_DEVICE: type_string = " Device"; break; default: type_string = "Unknown"; break; } if (!(flags & BM_PRINT_GROUP)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+-------------------------------------------------------------------------------\n")); } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| %s[%02x]:[%p] flags[%02x] hid[%s] %s\n", type_string, device->handle, device->acpi_handle, device->flags, (device->id.hid[0] ? device->id.hid : " "), (char*)buffer.pointer)); if (flags & BM_PRINT_IDENTIFICATION) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| identification: uid[%s] adr[%08x]\n", device->id.uid, device->id.adr)); } if (flags & BM_PRINT_LINKAGE) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| linkage: this[%p] parent[%p] next[%p]\n", node, node->parent, node->next)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| scope.head[%p] scope.tail[%p]\n", node->scope.head, node->scope.tail)); } if (flags & BM_PRINT_POWER) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| power: state[D%d] flags[%08x]\n", device->power.state, device->power.flags)); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| S0[%02x] S1[%02x] S2[%02x] S3[%02x] S4[%02x] S5[%02x]\n", device->power.dx_supported[0], device->power.dx_supported[1], device->power.dx_supported[2], device->power.dx_supported[3], device->power.dx_supported[4], device->power.dx_supported[5])); } if (!(flags & BM_PRINT_GROUP)) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+-------------------------------------------------------------------------------\n")); } acpi_os_free(buffer.pointer); #endif /*ACPI_DEBUG*/ return; }
ACPI_STATUS AcpiUtAcquireMutex ( ACPI_MUTEX_HANDLE MutexId) { ACPI_STATUS Status; UINT32 i; UINT32 ThisThreadId; PROC_NAME ("UtAcquireMutex"); if (MutexId > MAX_MTX) { return (AE_BAD_PARAMETER); } ThisThreadId = AcpiOsGetThreadId (); /* * Deadlock prevention. Check if this thread owns any mutexes of value * greater than or equal to this one. If so, the thread has violated * the mutex ordering rule. This indicates a coding error somewhere in * the ACPI subsystem code. */ for (i = MutexId; i < MAX_MTX; i++) { if (AcpiGbl_AcpiMutexInfo[i].OwnerId == ThisThreadId) { if (i == MutexId) { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Mutex [%s] already acquired by this thread [%X]\n", AcpiUtGetMutexName (MutexId), ThisThreadId)); return (AE_ALREADY_ACQUIRED); } ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid acquire order: Thread %X owns [%s], wants [%s]\n", ThisThreadId, AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId))); return (AE_ACQUIRE_DEADLOCK); } } ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X attempting to acquire Mutex [%s]\n", ThisThreadId, AcpiUtGetMutexName (MutexId))); Status = AcpiOsWaitSemaphore (AcpiGbl_AcpiMutexInfo[MutexId].Mutex, 1, WAIT_FOREVER); if (ACPI_SUCCESS (Status)) { ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %X acquired Mutex [%s]\n", ThisThreadId, AcpiUtGetMutexName (MutexId))); AcpiGbl_AcpiMutexInfo[MutexId].UseCount++; AcpiGbl_AcpiMutexInfo[MutexId].OwnerId = ThisThreadId; } else { ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Thread %X could not acquire Mutex [%s] %s\n", ThisThreadId, AcpiUtGetMutexName (MutexId), AcpiFormatException (Status))); } return (Status); }