static void EcGpeQueryHandler(void *Context) { struct acpi_ec_softc *sc = (struct acpi_ec_softc *)Context; UINT8 Data; ACPI_STATUS Status; int retry, sci_enqueued; char qxx[5]; ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); KASSERT(Context != NULL, ("EcGpeQueryHandler called with NULL")); /* Serialize user access with EcSpaceHandler(). */ Status = EcLock(sc); if (ACPI_FAILURE(Status)) { device_printf(sc->ec_dev, "GpeQuery lock error: %s\n", AcpiFormatException(Status)); return; } /* * Send a query command to the EC to find out which _Qxx call it * wants to make. This command clears the SCI bit and also the * interrupt source since we are edge-triggered. To prevent the GPE * that may arise from running the query from causing another query * to be queued, we clear the pending flag only after running it. */ sci_enqueued = sc->ec_sci_pend; for (retry = 0; retry < 2; retry++) { Status = EcCommand(sc, EC_COMMAND_QUERY); if (ACPI_SUCCESS(Status)) break; if (ACPI_SUCCESS(EcCheckStatus(sc, "retr_check", EC_EVENT_INPUT_BUFFER_EMPTY))) continue; else break; } sc->ec_sci_pend = FALSE; if (ACPI_FAILURE(Status)) { EcUnlock(sc); device_printf(sc->ec_dev, "GPE query failed: %s\n", AcpiFormatException(Status)); return; } Data = EC_GET_DATA(sc); /* * We have to unlock before running the _Qxx method below since that * method may attempt to read/write from EC address space, causing * recursive acquisition of the lock. */ EcUnlock(sc); /* Ignore the value for "no outstanding event". (13.3.5) */ CTR2(KTR_ACPI, "ec query ok,%s running _Q%02X", Data ? "" : " not", Data); if (Data == 0) return; /* Evaluate _Qxx to respond to the controller. */ snprintf(qxx, sizeof(qxx), "_Q%02X", Data); AcpiUtStrupr(qxx); Status = AcpiEvaluateObject(sc->ec_handle, qxx, NULL, NULL); if (ACPI_FAILURE(Status) && Status != AE_NOT_FOUND) { device_printf(sc->ec_dev, "evaluation of query method %s failed: %s\n", qxx, AcpiFormatException(Status)); } /* Reenable runtime GPE if its execution was deferred. */ if (sci_enqueued) { Status = AcpiFinishGpe(sc->ec_gpehandle, sc->ec_gpebit); if (ACPI_FAILURE(Status)) device_printf(sc->ec_dev, "reenabling runtime GPE failed: %s\n", AcpiFormatException(Status)); } }
/** * acpi_dev_pm_get_state - Get preferred power state of ACPI device. * @dev: Device whose preferred target power state to return. * @adev: ACPI device node corresponding to @dev. * @target_state: System state to match the resultant device state. * @d_min_p: Location to store the highest power state available to the device. * @d_max_p: Location to store the lowest power state available to the device. * * Find the lowest power (highest number) and highest power (lowest number) ACPI * device power states that the device can be in while the system is in the * state represented by @target_state. Store the integer numbers representing * those stats in the memory locations pointed to by @d_max_p and @d_min_p, * respectively. * * Callers must ensure that @dev and @adev are valid pointers and that @adev * actually corresponds to @dev before using this function. * * Returns 0 on success or -ENODATA when one of the ACPI methods fails or * returns a value that doesn't make sense. The memory locations pointed to by * @d_max_p and @d_min_p are only modified on success. */ static int acpi_dev_pm_get_state(struct device *dev, struct acpi_device *adev, u32 target_state, int *d_min_p, int *d_max_p) { char method[] = { '_', 'S', '0' + target_state, 'D', '\0' }; acpi_handle handle = adev->handle; unsigned long long ret; int d_min, d_max; bool wakeup = false; acpi_status status; /* * If the system state is S0, the lowest power state the device can be * in is D3cold, unless the device has _S0W and is supposed to signal * wakeup, in which case the return value of _S0W has to be used as the * lowest power state available to the device. */ d_min = ACPI_STATE_D0; d_max = ACPI_STATE_D3_COLD; /* * If present, _SxD methods return the minimum D-state (highest power * state) we can use for the corresponding S-states. Otherwise, the * minimum D-state is D0 (ACPI 3.x). */ if (target_state > ACPI_STATE_S0) { /* * We rely on acpi_evaluate_integer() not clobbering the integer * provided if AE_NOT_FOUND is returned. */ ret = d_min; status = acpi_evaluate_integer(handle, method, NULL, &ret); if ((ACPI_FAILURE(status) && status != AE_NOT_FOUND) || ret > ACPI_STATE_D3_COLD) return -ENODATA; /* * We need to handle legacy systems where D3hot and D3cold are * the same and 3 is returned in both cases, so fall back to * D3cold if D3hot is not a valid state. */ if (!adev->power.states[ret].flags.valid) { if (ret == ACPI_STATE_D3_HOT) ret = ACPI_STATE_D3_COLD; else return -ENODATA; } d_min = ret; wakeup = device_may_wakeup(dev) && adev->wakeup.flags.valid && adev->wakeup.sleep_state >= target_state; } else if (dev_pm_qos_flags(dev, PM_QOS_FLAG_REMOTE_WAKEUP) != PM_QOS_FLAGS_NONE) { wakeup = adev->wakeup.flags.valid; } /* * If _PRW says we can wake up the system from the target sleep state, * the D-state returned by _SxD is sufficient for that (we assume a * wakeup-aware driver if wake is set). Still, if _SxW exists * (ACPI 3.x), it should return the maximum (lowest power) D-state that * can wake the system. _S0W may be valid, too. */ if (wakeup) { method[3] = 'W'; status = acpi_evaluate_integer(handle, method, NULL, &ret); if (status == AE_NOT_FOUND) { if (target_state > ACPI_STATE_S0) d_max = d_min; } else if (ACPI_SUCCESS(status) && ret <= ACPI_STATE_D3_COLD) { /* Fall back to D3cold if ret is not a valid state. */ if (!adev->power.states[ret].flags.valid) ret = ACPI_STATE_D3_COLD; d_max = ret > d_min ? ret : d_min; } else { return -ENODATA; } } if (d_min_p) *d_min_p = d_min; if (d_max_p) *d_max_p = d_max; return 0; }
static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev, bool bind) { struct acpi_device *device = cdev->devdata; struct acpi_thermal *tz = thermal->devdata; struct acpi_device *dev; acpi_status status; acpi_handle handle; int i; int j; int trip = -1; int result = 0; if (tz->trips.critical.flags.valid) trip++; if (tz->trips.hot.flags.valid) trip++; if (tz->trips.passive.flags.valid) { trip++; for (i = 0; i < tz->trips.passive.devices.count; i++) { handle = tz->trips.passive.devices.handles[i]; status = acpi_bus_get_device(handle, &dev); if (ACPI_FAILURE(status) || dev != device) continue; if (bind) result = thermal_zone_bind_cooling_device (thermal, trip, cdev, THERMAL_NO_LIMIT, THERMAL_NO_LIMIT); else result = thermal_zone_unbind_cooling_device (thermal, trip, cdev); if (result) goto failed; } } for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { if (!tz->trips.active[i].flags.valid) break; trip++; for (j = 0; j < tz->trips.active[i].devices.count; j++) { handle = tz->trips.active[i].devices.handles[j]; status = acpi_bus_get_device(handle, &dev); if (ACPI_FAILURE(status) || dev != device) continue; if (bind) result = thermal_zone_bind_cooling_device (thermal, trip, cdev, THERMAL_NO_LIMIT, THERMAL_NO_LIMIT); else result = thermal_zone_unbind_cooling_device (thermal, trip, cdev); if (result) goto failed; } } for (i = 0; i < tz->devices.count; i++) { handle = tz->devices.handles[i]; status = acpi_bus_get_device(handle, &dev); if (ACPI_SUCCESS(status) && (dev == device)) { if (bind) result = thermal_zone_bind_cooling_device (thermal, -1, cdev, THERMAL_NO_LIMIT, THERMAL_NO_LIMIT); else result = thermal_zone_unbind_cooling_device (thermal, -1, cdev); if (result) goto failed; } } failed: return result; }
void AcpiPsGetNextNamepath ( ACPI_PARSE_STATE *ParserState, ACPI_PARSE_OBJECT *Arg, UINT32 *ArgCount, BOOLEAN MethodCall) { NATIVE_CHAR *Path; ACPI_PARSE_OBJECT *NameOp; ACPI_STATUS Status; ACPI_NAMESPACE_NODE *MethodNode = NULL; ACPI_NAMESPACE_NODE *Node; ACPI_GENERIC_STATE ScopeInfo; FUNCTION_TRACE ("PsGetNextNamepath"); Path = AcpiPsGetNextNamestring (ParserState); if (!Path || !MethodCall) { /* Null name case, create a null namepath object */ AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); Arg->Value.Name = Path; return_VOID; } if (MethodCall) { /* * Lookup the name in the internal namespace */ ScopeInfo.Scope.Node = NULL; Node = ParserState->StartNode; if (Node) { ScopeInfo.Scope.Node = Node; } /* * Lookup object. We don't want to add anything new to the namespace * here, however. So we use MODE_EXECUTE. Allow searching of the * parent tree, but don't open a new scope -- we just want to lookup the * object (MUST BE mode EXECUTE to perform upsearch) */ Status = AcpiNsLookup (&ScopeInfo, Path, ACPI_TYPE_ANY, IMODE_EXECUTE, NS_SEARCH_PARENT | NS_DONT_OPEN_SCOPE, NULL, &Node); if (ACPI_SUCCESS (Status)) { if (Node->Type == ACPI_TYPE_METHOD) { MethodNode = Node; ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "method - %p Path=%p\n", MethodNode, Path)); NameOp = AcpiPsAllocOp (AML_INT_NAMEPATH_OP); if (NameOp) { /* Change arg into a METHOD CALL and attach name to it */ AcpiPsInitOp (Arg, AML_INT_METHODCALL_OP); NameOp->Value.Name = Path; /* Point METHODCALL/NAME to the METHOD Node */ NameOp->Node = MethodNode; AcpiPsAppendArg (Arg, NameOp); if (!(ACPI_OPERAND_OBJECT *) MethodNode->Object) { return_VOID; } *ArgCount = ((ACPI_OPERAND_OBJECT *) MethodNode->Object)->Method.ParamCount; } return_VOID; } /* * Else this is normal named object reference. * Just init the NAMEPATH object with the pathname. * (See code below) */ } } /* * Either we didn't find the object in the namespace, or the object is * something other than a control method. Just initialize the Op with the * pathname. */ AcpiPsInitOp (Arg, AML_INT_NAMEPATH_OP); Arg->Value.Name = Path; return_VOID; }
acpi_status acpi_db_command_dispatch(char *input_buffer, struct acpi_walk_state * walk_state, union acpi_parse_object * op) { u32 temp; u32 command_index; u32 param_count; char *command_line; acpi_status status = AE_CTRL_TRUE; /* If acpi_terminate has been called, terminate this thread */ if (acpi_gbl_db_terminate_loop) { return (AE_CTRL_TERMINATE); } /* Find command and add to the history buffer */ param_count = acpi_db_get_line(input_buffer); command_index = acpi_db_match_command(acpi_gbl_db_args[0]); temp = 0; /* * We don't want to add the !! command to the history buffer. It * would cause an infinite loop because it would always be the * previous command. */ if (command_index != CMD_HISTORY_LAST) { acpi_db_add_to_history(input_buffer); } /* Verify that we have the minimum number of params */ if (param_count < acpi_gbl_db_commands[command_index].min_args) { acpi_os_printf ("%u parameters entered, [%s] requires %u parameters\n", param_count, acpi_gbl_db_commands[command_index].name, acpi_gbl_db_commands[command_index].min_args); acpi_db_display_command_info(acpi_gbl_db_commands [command_index].name, FALSE); return (AE_CTRL_TRUE); } /* Decode and dispatch the command */ switch (command_index) { case CMD_NULL: if (op) { return (AE_OK); } break; case CMD_ALLOCATIONS: #ifdef ACPI_DBG_TRACK_ALLOCATIONS acpi_ut_dump_allocations((u32)-1, NULL); #endif break; case CMD_ARGS: case CMD_ARGUMENTS: acpi_db_display_arguments(); break; case CMD_BREAKPOINT: acpi_db_set_method_breakpoint(acpi_gbl_db_args[1], walk_state, op); break; case CMD_BUSINFO: acpi_db_get_bus_info(); break; case CMD_CALL: acpi_db_set_method_call_breakpoint(op); status = AE_OK; break; case CMD_DEBUG: acpi_db_execute(acpi_gbl_db_args[1], &acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2], EX_SINGLE_STEP); break; case CMD_DISASSEMBLE: case CMD_DISASM: (void)acpi_db_disassemble_method(acpi_gbl_db_args[1]); break; case CMD_DUMP: acpi_db_decode_and_display_object(acpi_gbl_db_args[1], acpi_gbl_db_args[2]); break; case CMD_EVALUATE: case CMD_EXECUTE: acpi_db_execute(acpi_gbl_db_args[1], &acpi_gbl_db_args[2], &acpi_gbl_db_arg_types[2], EX_NO_SINGLE_STEP); break; case CMD_FIND: status = acpi_db_find_name_in_namespace(acpi_gbl_db_args[1]); break; case CMD_GO: acpi_gbl_cm_single_step = FALSE; return (AE_OK); case CMD_HANDLERS: acpi_db_display_handlers(); break; case CMD_HELP: case CMD_HELP2: acpi_db_display_help(acpi_gbl_db_args[1]); break; case CMD_HISTORY: acpi_db_display_history(); break; case CMD_HISTORY_EXE: /* ! command */ command_line = acpi_db_get_from_history(acpi_gbl_db_args[1]); if (!command_line) { return (AE_CTRL_TRUE); } status = acpi_db_command_dispatch(command_line, walk_state, op); return (status); case CMD_HISTORY_LAST: /* !! command */ command_line = acpi_db_get_from_history(NULL); if (!command_line) { return (AE_CTRL_TRUE); } status = acpi_db_command_dispatch(command_line, walk_state, op); return (status); case CMD_INFORMATION: acpi_db_display_method_info(op); break; case CMD_INTEGRITY: acpi_db_check_integrity(); break; case CMD_INTO: if (op) { acpi_gbl_cm_single_step = TRUE; return (AE_OK); } break; case CMD_LEVEL: if (param_count == 0) { acpi_os_printf ("Current debug level for file output is: %8.8lX\n", acpi_gbl_db_debug_level); acpi_os_printf ("Current debug level for console output is: %8.8lX\n", acpi_gbl_db_console_debug_level); } else if (param_count == 2) { temp = acpi_gbl_db_console_debug_level; acpi_gbl_db_console_debug_level = strtoul(acpi_gbl_db_args[1], NULL, 16); acpi_os_printf ("Debug Level for console output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_console_debug_level); } else { temp = acpi_gbl_db_debug_level; acpi_gbl_db_debug_level = strtoul(acpi_gbl_db_args[1], NULL, 16); acpi_os_printf ("Debug Level for file output was %8.8lX, now %8.8lX\n", temp, acpi_gbl_db_debug_level); } break; case CMD_LIST: acpi_db_disassemble_aml(acpi_gbl_db_args[1], op); break; case CMD_LOCKS: acpi_db_display_locks(); break; case CMD_LOCALS: acpi_db_display_locals(); break; case CMD_METHODS: status = acpi_db_display_objects("METHOD", acpi_gbl_db_args[1]); break; case CMD_NAMESPACE: acpi_db_dump_namespace(acpi_gbl_db_args[1], acpi_gbl_db_args[2]); break; case CMD_NOTIFY: temp = strtoul(acpi_gbl_db_args[2], NULL, 0); acpi_db_send_notify(acpi_gbl_db_args[1], temp); break; case CMD_OBJECTS: acpi_ut_strupr(acpi_gbl_db_args[1]); status = acpi_db_display_objects(acpi_gbl_db_args[1], acpi_gbl_db_args[2]); break; case CMD_OSI: acpi_db_display_interfaces(acpi_gbl_db_args[1], acpi_gbl_db_args[2]); break; case CMD_OWNER: acpi_db_dump_namespace_by_owner(acpi_gbl_db_args[1], acpi_gbl_db_args[2]); break; case CMD_PATHS: acpi_db_dump_namespace_paths(); break; case CMD_PREFIX: acpi_db_set_scope(acpi_gbl_db_args[1]); break; case CMD_REFERENCES: acpi_db_find_references(acpi_gbl_db_args[1]); break; case CMD_RESOURCES: acpi_db_display_resources(acpi_gbl_db_args[1]); break; case CMD_RESULTS: acpi_db_display_results(); break; case CMD_SET: acpi_db_set_method_data(acpi_gbl_db_args[1], acpi_gbl_db_args[2], acpi_gbl_db_args[3]); break; case CMD_STATS: status = acpi_db_display_statistics(acpi_gbl_db_args[1]); break; case CMD_STOP: return (AE_NOT_IMPLEMENTED); case CMD_TABLES: acpi_db_display_table_info(acpi_gbl_db_args[1]); break; case CMD_TEMPLATE: acpi_db_display_template(acpi_gbl_db_args[1]); break; case CMD_TRACE: acpi_db_trace(acpi_gbl_db_args[1], acpi_gbl_db_args[2], acpi_gbl_db_args[3]); break; case CMD_TREE: acpi_db_display_calling_tree(); break; case CMD_TYPE: acpi_db_display_object_type(acpi_gbl_db_args[1]); break; #ifdef ACPI_APPLICATION /* Hardware simulation commands. */ case CMD_ENABLEACPI: #if (!ACPI_REDUCED_HARDWARE) status = acpi_enable(); if (ACPI_FAILURE(status)) { acpi_os_printf("AcpiEnable failed (Status=%X)\n", status); return (status); } #endif /* !ACPI_REDUCED_HARDWARE */ break; case CMD_EVENT: acpi_os_printf("Event command not implemented\n"); break; case CMD_GPE: acpi_db_generate_gpe(acpi_gbl_db_args[1], acpi_gbl_db_args[2]); break; case CMD_GPES: acpi_db_display_gpes(); break; case CMD_SCI: acpi_db_generate_sci(); break; case CMD_SLEEP: status = acpi_db_sleep(acpi_gbl_db_args[1]); break; /* File I/O commands. */ case CMD_CLOSE: acpi_db_close_debug_file(); break; case CMD_LOAD:{ struct acpi_new_table_desc *list_head = NULL; status = ac_get_all_tables_from_file(acpi_gbl_db_args[1], ACPI_GET_ALL_TABLES, &list_head); if (ACPI_SUCCESS(status)) { acpi_db_load_tables(list_head); } } break; case CMD_OPEN: acpi_db_open_debug_file(acpi_gbl_db_args[1]); break; /* User space commands. */ case CMD_TERMINATE: acpi_db_set_output_destination(ACPI_DB_REDIRECTABLE_OUTPUT); acpi_ut_subsystem_shutdown(); /* * TBD: [Restructure] Need some way to re-initialize without * re-creating the semaphores! */ acpi_gbl_db_terminate_loop = TRUE; /* acpi_initialize (NULL); */ break; case CMD_THREADS: acpi_db_create_execution_threads(acpi_gbl_db_args[1], acpi_gbl_db_args[2], acpi_gbl_db_args[3]); break; /* Debug test commands. */ case CMD_PREDEFINED: acpi_db_check_predefined_names(); break; case CMD_TEST: acpi_db_execute_test(acpi_gbl_db_args[1]); break; case CMD_UNLOAD: acpi_db_unload_acpi_table(acpi_gbl_db_args[1]); break; #endif case CMD_EXIT: case CMD_QUIT: if (op) { acpi_os_printf("Method execution terminated\n"); return (AE_CTRL_TERMINATE); } if (!acpi_gbl_db_output_to_file) { acpi_dbg_level = ACPI_DEBUG_DEFAULT; } #ifdef ACPI_APPLICATION acpi_db_close_debug_file(); #endif acpi_gbl_db_terminate_loop = TRUE; return (AE_CTRL_TERMINATE); case CMD_NOT_FOUND: default: acpi_os_printf("%s: unknown command\n", acpi_gbl_db_args[0]); return (AE_CTRL_TRUE); } if (ACPI_SUCCESS(status)) { status = AE_CTRL_TRUE; } return (status); }
ACPI_STATUS AcpiDbCommandDispatch ( char *InputBuffer, ACPI_WALK_STATE *WalkState, ACPI_PARSE_OBJECT *Op) { UINT32 Temp; UINT32 CommandIndex; UINT32 ParamCount; char *CommandLine; ACPI_STATUS Status = AE_CTRL_TRUE; /* If AcpiTerminate has been called, terminate this thread */ if (AcpiGbl_DbTerminateThreads) { return (AE_CTRL_TERMINATE); } ParamCount = AcpiDbGetLine (InputBuffer); CommandIndex = AcpiDbMatchCommand (AcpiGbl_DbArgs[0]); Temp = 0; /* Verify that we have the minimum number of params */ if (ParamCount < AcpiGbl_DbCommands[CommandIndex].MinArgs) { AcpiOsPrintf ("%u parameters entered, [%s] requires %u parameters\n", ParamCount, AcpiGbl_DbCommands[CommandIndex].Name, AcpiGbl_DbCommands[CommandIndex].MinArgs); AcpiDbDisplayCommandInfo (AcpiGbl_DbCommands[CommandIndex].Name, FALSE); return (AE_CTRL_TRUE); } /* Decode and dispatch the command */ switch (CommandIndex) { case CMD_NULL: if (Op) { return (AE_OK); } break; case CMD_ALLOCATIONS: #ifdef ACPI_DBG_TRACK_ALLOCATIONS AcpiUtDumpAllocations ((UINT32) -1, NULL); #endif break; case CMD_ARGS: case CMD_ARGUMENTS: AcpiDbDisplayArguments (); break; case CMD_BATCH: AcpiDbBatchExecute (AcpiGbl_DbArgs[1]); break; case CMD_BREAKPOINT: AcpiDbSetMethodBreakpoint (AcpiGbl_DbArgs[1], WalkState, Op); break; case CMD_BUSINFO: AcpiDbGetBusInfo (); break; case CMD_CALL: AcpiDbSetMethodCallBreakpoint (Op); Status = AE_OK; break; case CMD_CLOSE: AcpiDbCloseDebugFile (); break; case CMD_DEBUG: AcpiDbExecute (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_SINGLE_STEP); break; case CMD_DISASSEMBLE: case CMD_DISASM: (void) AcpiDbDisassembleMethod (AcpiGbl_DbArgs[1]); break; case CMD_DUMP: AcpiDbDecodeAndDisplayObject (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_ENABLEACPI: #if (!ACPI_REDUCED_HARDWARE) Status = AcpiEnable(); if (ACPI_FAILURE(Status)) { AcpiOsPrintf("AcpiEnable failed (Status=%X)\n", Status); return (Status); } #endif /* !ACPI_REDUCED_HARDWARE */ break; case CMD_EVENT: AcpiOsPrintf ("Event command not implemented\n"); break; case CMD_EVALUATE: case CMD_EXECUTE: AcpiDbExecute (AcpiGbl_DbArgs[1], &AcpiGbl_DbArgs[2], &AcpiGbl_DbArgTypes[2], EX_NO_SINGLE_STEP); break; case CMD_FIND: Status = AcpiDbFindNameInNamespace (AcpiGbl_DbArgs[1]); break; case CMD_GO: AcpiGbl_CmSingleStep = FALSE; return (AE_OK); case CMD_GPE: AcpiDbGenerateGpe (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_GPES: AcpiDbDisplayGpes (); break; case CMD_HANDLERS: AcpiDbDisplayHandlers (); break; case CMD_HELP: case CMD_HELP2: AcpiDbDisplayHelp (AcpiGbl_DbArgs[1]); break; case CMD_HISTORY: AcpiDbDisplayHistory (); break; case CMD_HISTORY_EXE: /* ! command */ CommandLine = AcpiDbGetFromHistory (AcpiGbl_DbArgs[1]); if (!CommandLine) { return (AE_CTRL_TRUE); } Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op); return (Status); case CMD_HISTORY_LAST: /* !! command */ CommandLine = AcpiDbGetFromHistory (NULL); if (!CommandLine) { return (AE_CTRL_TRUE); } Status = AcpiDbCommandDispatch (CommandLine, WalkState, Op); return (Status); case CMD_INFORMATION: AcpiDbDisplayMethodInfo (Op); break; case CMD_INTEGRITY: AcpiDbCheckIntegrity (); break; case CMD_INTO: if (Op) { AcpiGbl_CmSingleStep = TRUE; return (AE_OK); } break; case CMD_LEVEL: if (ParamCount == 0) { AcpiOsPrintf ("Current debug level for file output is: %8.8lX\n", AcpiGbl_DbDebugLevel); AcpiOsPrintf ("Current debug level for console output is: %8.8lX\n", AcpiGbl_DbConsoleDebugLevel); } else if (ParamCount == 2) { Temp = AcpiGbl_DbConsoleDebugLevel; AcpiGbl_DbConsoleDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16); AcpiOsPrintf ( "Debug Level for console output was %8.8lX, now %8.8lX\n", Temp, AcpiGbl_DbConsoleDebugLevel); } else { Temp = AcpiGbl_DbDebugLevel; AcpiGbl_DbDebugLevel = ACPI_STRTOUL (AcpiGbl_DbArgs[1], NULL, 16); AcpiOsPrintf ( "Debug Level for file output was %8.8lX, now %8.8lX\n", Temp, AcpiGbl_DbDebugLevel); } break; case CMD_LIST: AcpiDbDisassembleAml (AcpiGbl_DbArgs[1], Op); break; case CMD_LOAD: Status = AcpiDbGetTableFromFile (AcpiGbl_DbArgs[1], NULL); break; case CMD_LOCKS: AcpiDbDisplayLocks (); break; case CMD_LOCALS: AcpiDbDisplayLocals (); break; case CMD_METHODS: Status = AcpiDbDisplayObjects ("METHOD", AcpiGbl_DbArgs[1]); break; case CMD_NAMESPACE: AcpiDbDumpNamespace (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_NOTIFY: Temp = ACPI_STRTOUL (AcpiGbl_DbArgs[2], NULL, 0); AcpiDbSendNotify (AcpiGbl_DbArgs[1], Temp); break; case CMD_OBJECT: AcpiUtStrupr (AcpiGbl_DbArgs[1]); Status = AcpiDbDisplayObjects (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_OPEN: AcpiDbOpenDebugFile (AcpiGbl_DbArgs[1]); break; case CMD_OSI: AcpiDbDisplayInterfaces (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_OWNER: AcpiDbDumpNamespaceByOwner (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2]); break; case CMD_PATHS: AcpiDbDumpNamespacePaths (); break; case CMD_PREDEFINED: AcpiDbCheckPredefinedNames (); break; case CMD_PREFIX: AcpiDbSetScope (AcpiGbl_DbArgs[1]); break; case CMD_REFERENCES: AcpiDbFindReferences (AcpiGbl_DbArgs[1]); break; case CMD_RESOURCES: AcpiDbDisplayResources (AcpiGbl_DbArgs[1]); break; case CMD_RESULTS: AcpiDbDisplayResults (); break; case CMD_SCI: AcpiDbGenerateSci (); break; case CMD_SET: AcpiDbSetMethodData (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2], AcpiGbl_DbArgs[3]); break; case CMD_SLEEP: Status = AcpiDbSleep (AcpiGbl_DbArgs[1]); break; case CMD_STATS: Status = AcpiDbDisplayStatistics (AcpiGbl_DbArgs[1]); break; case CMD_STOP: return (AE_NOT_IMPLEMENTED); case CMD_TABLES: AcpiDbDisplayTableInfo (AcpiGbl_DbArgs[1]); break; case CMD_TEMPLATE: AcpiDbDisplayTemplate (AcpiGbl_DbArgs[1]); break; case CMD_TERMINATE: AcpiDbSetOutputDestination (ACPI_DB_REDIRECTABLE_OUTPUT); AcpiUtSubsystemShutdown (); /* * TBD: [Restructure] Need some way to re-initialize without * re-creating the semaphores! */ /* AcpiInitialize (NULL); */ break; case CMD_THREADS: AcpiDbCreateExecutionThreads (AcpiGbl_DbArgs[1], AcpiGbl_DbArgs[2], AcpiGbl_DbArgs[3]); break; case CMD_TRACE: (void) AcpiDebugTrace (AcpiGbl_DbArgs[1],0,0,1); break; case CMD_TREE: AcpiDbDisplayCallingTree (); break; case CMD_TYPE: AcpiDbDisplayObjectType (AcpiGbl_DbArgs[1]); break; case CMD_UNLOAD: AcpiDbUnloadAcpiTable (AcpiGbl_DbArgs[1]); break; case CMD_EXIT: case CMD_QUIT: if (Op) { AcpiOsPrintf ("Method execution terminated\n"); return (AE_CTRL_TERMINATE); } if (!AcpiGbl_DbOutputToFile) { AcpiDbgLevel = ACPI_DEBUG_DEFAULT; } AcpiDbCloseDebugFile (); AcpiGbl_DbTerminateThreads = TRUE; return (AE_CTRL_TERMINATE); case CMD_NOT_FOUND: default: AcpiOsPrintf ("Unknown Command\n"); return (AE_CTRL_TRUE); } if (ACPI_SUCCESS (Status)) { Status = AE_CTRL_TRUE; } /* Add all commands that come here to the history buffer */ AcpiDbAddToHistory (InputBuffer); return (Status); }
static void acpi_bus_osc_support(void) { u32 capbuf[2]; struct acpi_osc_context context = { .uuid_str = sb_uuid_str, .rev = 1, .cap.length = 8, .cap.pointer = capbuf, }; acpi_handle handle; capbuf[OSC_QUERY_DWORD] = OSC_QUERY_ENABLE; capbuf[OSC_SUPPORT_DWORD] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */ #if defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) ||\ defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE) capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PAD_SUPPORT; #endif #if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_PPC_OST_SUPPORT; #endif #ifdef ACPI_HOTPLUG_OST capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_HOTPLUG_OST_SUPPORT; #endif if (!ghes_disable) capbuf[OSC_SUPPORT_DWORD] |= OSC_SB_APEI_SUPPORT; if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) return; if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) { u32 *capbuf_ret = context.ret.pointer; if (context.ret.length > OSC_SUPPORT_DWORD) osc_sb_apei_support_acked = capbuf_ret[OSC_SUPPORT_DWORD] & OSC_SB_APEI_SUPPORT; kfree(context.ret.pointer); } /* do we need to check other returned cap? Sounds no */ } /* -------------------------------------------------------------------------- Notification Handling -------------------------------------------------------------------------- */ /** * acpi_bus_notify * --------------- * Callback for all 'system-level' device notifications (values 0x00-0x7F). */ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data) { struct acpi_device *device = NULL; struct acpi_driver *driver; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Notification %#02x to handle %p\n", type, handle)); switch (type) { case ACPI_NOTIFY_BUS_CHECK: /* TBD */ break; case ACPI_NOTIFY_DEVICE_CHECK: /* TBD */ break; case ACPI_NOTIFY_DEVICE_WAKE: /* TBD */ break; case ACPI_NOTIFY_EJECT_REQUEST: /* TBD */ break; case ACPI_NOTIFY_DEVICE_CHECK_LIGHT: /* TBD: Exactly what does 'light' mean? */ break; case ACPI_NOTIFY_FREQUENCY_MISMATCH: /* TBD */ break; case ACPI_NOTIFY_BUS_MODE_MISMATCH: /* TBD */ break; case ACPI_NOTIFY_POWER_FAULT: /* TBD */ break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Received unknown/unsupported notification [%08x]\n", type)); break; } acpi_bus_get_device(handle, &device); if (device) { driver = device->driver; if (driver && driver->ops.notify && (driver->flags & ACPI_DRIVER_ALL_NOTIFY_EVENTS)) driver->ops.notify(device, type); } } /* -------------------------------------------------------------------------- Initialization/Cleanup -------------------------------------------------------------------------- */ static int __init acpi_bus_init_irq(void) { acpi_status status; char *message = NULL; /* * Let the system know what interrupt model we are using by * evaluating the \_PIC object, if exists. */ switch (acpi_irq_model) { case ACPI_IRQ_MODEL_PIC: message = "PIC"; break; case ACPI_IRQ_MODEL_IOAPIC: message = "IOAPIC"; break; case ACPI_IRQ_MODEL_IOSAPIC: message = "IOSAPIC"; break; case ACPI_IRQ_MODEL_PLATFORM: message = "platform specific model"; break; default: printk(KERN_WARNING PREFIX "Unknown interrupt routing model\n"); return -ENODEV; } printk(KERN_INFO PREFIX "Using %s for interrupt routing\n", message); status = acpi_execute_simple_method(NULL, "\\_PIC", acpi_irq_model); if (ACPI_FAILURE(status) && (status != AE_NOT_FOUND)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PIC")); return -ENODEV; } return 0; }
void OptOptimizeNamePath ( ACPI_PARSE_OBJECT *Op, UINT32 Flags, ACPI_WALK_STATE *WalkState, char *AmlNameString, ACPI_NAMESPACE_NODE *TargetNode) { ACPI_STATUS Status; ACPI_BUFFER TargetPath; ACPI_BUFFER CurrentPath; ACPI_SIZE AmlNameStringLength; ACPI_NAMESPACE_NODE *CurrentNode; char *ExternalNameString; char *NewPath = NULL; ACPI_SIZE HowMuchShorter; ACPI_PARSE_OBJECT *NextOp; ACPI_FUNCTION_TRACE (OptOptimizeNamePath); /* This is an optional optimization */ if (!Gbl_ReferenceOptimizationFlag) { return_VOID; } /* Various required items */ if (!TargetNode || !WalkState || !AmlNameString || !Op->Common.Parent) { return_VOID; } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "%5d [%12.12s] [%12.12s] ", Op->Asl.LogicalLineNumber, AcpiPsGetOpcodeName (Op->Common.Parent->Common.AmlOpcode), AcpiPsGetOpcodeName (Op->Common.AmlOpcode))); if (!(Flags & (AML_NAMED | AML_CREATE))) { if (Op->Asl.CompileFlags & NODE_IS_NAME_DECLARATION) { /* We don't want to fuss with actual name declaration nodes here */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "******* NAME DECLARATION\n")); return_VOID; } } /* * The original path must be longer than one NameSeg (4 chars) for there * to be any possibility that it can be optimized to a shorter string */ AmlNameStringLength = ACPI_STRLEN (AmlNameString); if (AmlNameStringLength <= ACPI_NAME_SIZE) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "NAMESEG %4.4s\n", AmlNameString)); return_VOID; } /* * We need to obtain the node that represents the current scope -- where * we are right now in the namespace. We will compare this path * against the Namepath, looking for commonality. */ CurrentNode = AcpiGbl_RootNode; if (WalkState->ScopeInfo) { CurrentNode = WalkState->ScopeInfo->Scope.Node; } if (Flags & (AML_NAMED | AML_CREATE)) { /* This is the declaration of a new name */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "NAME")); /* * The node of interest is the parent of this node (the containing * scope). The actual namespace node may be up more than one level * of parse op or it may not exist at all (if we traverse back * up to the root.) */ NextOp = Op->Asl.Parent; while (NextOp && (!NextOp->Asl.Node)) { NextOp = NextOp->Asl.Parent; } if (NextOp && NextOp->Asl.Node) { CurrentNode = NextOp->Asl.Node; } else { CurrentNode = AcpiGbl_RootNode; } } else { /* This is a reference to an existing named object */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "REF ")); } /* * Obtain the full paths to the two nodes that we are interested in * (Target and current namespace location) in external * format -- something we can easily manipulate */ TargetPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; Status = AcpiNsHandleToPathname (TargetNode, &TargetPath); if (ACPI_FAILURE (Status)) { AslCoreSubsystemError (Op, Status, "Getting Target NamePath", ASL_NO_ABORT); return_VOID; } TargetPath.Length--; /* Subtract one for null terminator */ /* CurrentPath is the path to this scope (where we are in the namespace) */ CurrentPath.Length = ACPI_ALLOCATE_LOCAL_BUFFER; Status = AcpiNsHandleToPathname (CurrentNode, &CurrentPath); if (ACPI_FAILURE (Status)) { AslCoreSubsystemError (Op, Status, "Getting Current NamePath", ASL_NO_ABORT); return_VOID; } CurrentPath.Length--; /* Subtract one for null terminator */ /* Debug output only */ Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, AmlNameString, NULL, &ExternalNameString); if (ACPI_FAILURE (Status)) { AslCoreSubsystemError (Op, Status, "Externalizing NamePath", ASL_NO_ABORT); return_VOID; } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "%37s (%2u) ==> %-32s(%2u) %-32s", (char *) CurrentPath.Pointer, (UINT32) CurrentPath.Length, (char *) TargetPath.Pointer, (UINT32) TargetPath.Length, ExternalNameString)); ACPI_FREE (ExternalNameString); /* * Attempt an optmization depending on the type of namepath */ if (Flags & (AML_NAMED | AML_CREATE)) { /* * This is a named opcode and the namepath is a name declaration, not * a reference. */ Status = OptOptimizeNameDeclaration (Op, WalkState, CurrentNode, TargetNode, AmlNameString, &NewPath); if (ACPI_FAILURE (Status)) { /* * 2) now attempt to * optimize the namestring with carats (up-arrow) */ Status = OptBuildShortestPath (Op, WalkState, CurrentNode, TargetNode, &CurrentPath, &TargetPath, AmlNameStringLength, 1, &NewPath); } } else { /* * This is a reference to an existing named object * * 1) Check if search-to-root can be utilized using the last * NameSeg of the NamePath */ Status = OptSearchToRoot (Op, WalkState, CurrentNode, TargetNode, &TargetPath, &NewPath); if (ACPI_FAILURE (Status)) { /* * 2) Search-to-root could not be used, now attempt to * optimize the namestring with carats (up-arrow) */ Status = OptBuildShortestPath (Op, WalkState, CurrentNode, TargetNode, &CurrentPath, &TargetPath, AmlNameStringLength, 0, &NewPath); } } /* * Success from above indicates that the NamePath was successfully * optimized. We need to update the parse op with the new name */ if (ACPI_SUCCESS (Status)) { HowMuchShorter = (AmlNameStringLength - ACPI_STRLEN (NewPath)); OptTotal += HowMuchShorter; ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " REDUCED %2u (%u)", (UINT32) HowMuchShorter, OptTotal)); if (Flags & AML_NAMED) { if (Op->Asl.AmlOpcode == AML_ALIAS_OP) { /* * ALIAS is the only oddball opcode, the name declaration * (alias name) is the second operand */ Op->Asl.Child->Asl.Next->Asl.Value.String = NewPath; Op->Asl.Child->Asl.Next->Asl.AmlLength = ACPI_STRLEN (NewPath); } else { Op->Asl.Child->Asl.Value.String = NewPath; Op->Asl.Child->Asl.AmlLength = ACPI_STRLEN (NewPath); } } else if (Flags & AML_CREATE) { /* Name must appear as the last parameter */ NextOp = Op->Asl.Child; while (!(NextOp->Asl.CompileFlags & NODE_IS_NAME_DECLARATION)) { NextOp = NextOp->Asl.Next; } /* Update the parse node with the new NamePath */ NextOp->Asl.Value.String = NewPath; NextOp->Asl.AmlLength = ACPI_STRLEN (NewPath); } else { /* Update the parse node with the new NamePath */ Op->Asl.Value.String = NewPath; Op->Asl.AmlLength = ACPI_STRLEN (NewPath); } } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ALREADY OPTIMAL")); } /* Cleanup path buffers */ ACPI_FREE (TargetPath.Pointer); ACPI_FREE (CurrentPath.Pointer); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "\n")); return_VOID; }
ACPI_STATUS AcpiUtOsiImplementation ( ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status; ACPI_OPERAND_OBJECT *StringDesc; ACPI_OPERAND_OBJECT *ReturnDesc; UINT32 ReturnValue; UINT32 i; ACPI_FUNCTION_TRACE (UtOsiImplementation); /* Validate the string input argument */ StringDesc = WalkState->Arguments[0].Object; if (!StringDesc || (StringDesc->Common.Type != ACPI_TYPE_STRING)) { return_ACPI_STATUS (AE_TYPE); } /* Create a return object */ ReturnDesc = AcpiUtCreateInternalObject (ACPI_TYPE_INTEGER); if (!ReturnDesc) { return_ACPI_STATUS (AE_NO_MEMORY); } /* Default return value is 0, NOT SUPPORTED */ ReturnValue = 0; /* Compare input string to static table of supported interfaces */ for (i = 0; i < ACPI_ARRAY_LENGTH (AcpiInterfacesSupported); i++) { if (!ACPI_STRCMP (StringDesc->String.Pointer, AcpiInterfacesSupported[i].Name)) { /* * The interface is supported. * Update the OsiData if necessary. We keep track of the latest * version of Windows that has been requested by the BIOS. */ if (AcpiInterfacesSupported[i].Value > AcpiGbl_OsiData) { AcpiGbl_OsiData = AcpiInterfacesSupported[i].Value; } ReturnValue = ACPI_UINT32_MAX; goto Exit; } } /* * Did not match the string in the static table, call the host OSL to * check for a match with one of the optional strings (such as * "Module Device", "3.0 Thermal Model", etc.) */ Status = AcpiOsValidateInterface (StringDesc->String.Pointer); if (ACPI_SUCCESS (Status)) { /* The interface is supported */ ReturnValue = ACPI_UINT32_MAX; } Exit: ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) is %ssupported\n", StringDesc->String.Pointer, ReturnValue == 0 ? "not " : "")); /* Complete the return value */ ReturnDesc->Integer.Value = ReturnValue; WalkState->ReturnDesc = ReturnDesc; return_ACPI_STATUS (AE_OK); }
static ACPI_STATUS OptBuildShortestPath ( ACPI_PARSE_OBJECT *Op, ACPI_WALK_STATE *WalkState, ACPI_NAMESPACE_NODE *CurrentNode, ACPI_NAMESPACE_NODE *TargetNode, ACPI_BUFFER *CurrentPath, ACPI_BUFFER *TargetPath, ACPI_SIZE AmlNameStringLength, UINT8 IsDeclaration, char **ReturnNewPath) { UINT32 NumCommonSegments; UINT32 MaxCommonSegments; UINT32 Index; UINT32 NumCarats; UINT32 i; char *NewPath; char *NewPathExternal; ACPI_NAMESPACE_NODE *Node; ACPI_GENERIC_STATE ScopeInfo; ACPI_STATUS Status; BOOLEAN SubPath = FALSE; ACPI_FUNCTION_NAME (OptBuildShortestPath); ScopeInfo.Scope.Node = CurrentNode; /* * Determine the maximum number of NameSegs that the Target and Current paths * can possibly have in common. (To optimize, we have to have at least 1) * * Note: The external NamePath string lengths are always a multiple of 5 * (ACPI_NAME_SIZE + separator) */ MaxCommonSegments = TargetPath->Length / ACPI_PATH_SEGMENT_LENGTH; if (CurrentPath->Length < TargetPath->Length) { MaxCommonSegments = CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH; } /* * Determine how many NameSegs the two paths have in common. * (Starting from the root) */ for (NumCommonSegments = 0; NumCommonSegments < MaxCommonSegments; NumCommonSegments++) { /* Compare two single NameSegs */ if (!ACPI_COMPARE_NAME ( &((char *) TargetPath->Pointer)[ (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1], &((char *) CurrentPath->Pointer)[ (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1])) { /* Mismatch */ break; } } ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " COMMON: %u", NumCommonSegments)); /* There must be at least 1 common NameSeg in order to optimize */ if (NumCommonSegments == 0) { return (AE_NOT_FOUND); } if (NumCommonSegments == MaxCommonSegments) { if (CurrentPath->Length == TargetPath->Length) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SAME PATH")); return (AE_NOT_FOUND); } else { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " SUBPATH")); SubPath = TRUE; } } /* Determine how many prefix Carats are required */ NumCarats = (CurrentPath->Length / ACPI_PATH_SEGMENT_LENGTH) - NumCommonSegments; /* * Construct a new target string */ NewPathExternal = ACPI_ALLOCATE_ZEROED ( TargetPath->Length + NumCarats + 1); /* Insert the Carats into the Target string */ for (i = 0; i < NumCarats; i++) { NewPathExternal[i] = AML_PARENT_PREFIX; } /* * Copy only the necessary (optimal) segments from the original * target string */ Index = (NumCommonSegments * ACPI_PATH_SEGMENT_LENGTH) + 1; /* Special handling for exact subpath in a name declaration */ if (IsDeclaration && SubPath && (CurrentPath->Length > TargetPath->Length)) { /* * The current path is longer than the target, and the target is a * subpath of the current path. We must include one more NameSeg of * the target path */ Index -= ACPI_PATH_SEGMENT_LENGTH; /* Special handling for Scope() operator */ if (Op->Asl.AmlOpcode == AML_SCOPE_OP) { NewPathExternal[i] = AML_PARENT_PREFIX; i++; ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "(EXTRA ^)")); } } /* Make sure we haven't gone off the end of the target path */ if (Index > TargetPath->Length) { Index = TargetPath->Length; } ACPI_STRCPY (&NewPathExternal[i], &((char *) TargetPath->Pointer)[Index]); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " %-24s", NewPathExternal)); /* * Internalize the new target string and check it against the original * string to make sure that this is in fact an optimization. If the * original string is already optimal, there is no point in continuing. */ Status = AcpiNsInternalizeName (NewPathExternal, &NewPath); if (ACPI_FAILURE (Status)) { AslCoreSubsystemError (Op, Status, "Internalizing new NamePath", ASL_NO_ABORT); ACPI_FREE (NewPathExternal); return (Status); } if (ACPI_STRLEN (NewPath) >= AmlNameStringLength) { ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " NOT SHORTER (New %u old %u)", (UINT32) ACPI_STRLEN (NewPath), (UINT32) AmlNameStringLength)); ACPI_FREE (NewPathExternal); return (AE_NOT_FOUND); } /* * Check to make sure that the optimization finds the node we are * looking for. This is simply a sanity check on the new * path that has been created. */ Status = AcpiNsLookup (&ScopeInfo, NewPath, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node)); if (ACPI_SUCCESS (Status)) { /* Found the namepath, but make sure the node is correct */ if (Node == TargetNode) { /* The lookup matched the node, accept this optimization */ AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION, Op, NewPathExternal); *ReturnNewPath = NewPath; } else { /* Node is not correct, do not use this optimization */ Status = AE_NOT_FOUND; ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** WRONG NODE")); AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, "Not using optimized name - found wrong node"); } } else { /* The lookup failed, we obviously cannot use this optimization */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** NOT FOUND")); AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, "Not using optimized name - did not find node"); } ACPI_FREE (NewPathExternal); return (Status); }
static ACPI_STATUS OptOptimizeNameDeclaration ( ACPI_PARSE_OBJECT *Op, ACPI_WALK_STATE *WalkState, ACPI_NAMESPACE_NODE *CurrentNode, ACPI_NAMESPACE_NODE *TargetNode, char *AmlNameString, char **NewPath) { ACPI_STATUS Status; char *NewPathExternal; ACPI_NAMESPACE_NODE *Node; ACPI_FUNCTION_TRACE (OptOptimizeNameDeclaration); if (((CurrentNode == AcpiGbl_RootNode) || (Op->Common.Parent->Asl.ParseOpcode == PARSEOP_DEFINITIONBLOCK)) && (ACPI_IS_ROOT_PREFIX (AmlNameString[0]))) { /* * The current scope is the root, and the namepath has a root prefix * that is therefore extraneous. Remove it. */ *NewPath = &AmlNameString[1]; /* Debug output */ Status = AcpiNsExternalizeName (ACPI_UINT32_MAX, *NewPath, NULL, &NewPathExternal); if (ACPI_FAILURE (Status)) { AslCoreSubsystemError (Op, Status, "Externalizing NamePath", ASL_NO_ABORT); return (Status); } /* * Check to make sure that the optimization finds the node we are * looking for. This is simply a sanity check on the new * path that has been created. * * We know that we are at the root, so NULL is used for the scope. */ Status = AcpiNsLookup (NULL, *NewPath, ACPI_TYPE_ANY, ACPI_IMODE_EXECUTE, ACPI_NS_DONT_OPEN_SCOPE, WalkState, &(Node)); if (ACPI_SUCCESS (Status)) { /* Found the namepath, but make sure the node is correct */ if (Node == TargetNode) { /* The lookup matched the node, accept this optimization */ AslError (ASL_OPTIMIZATION, ASL_MSG_NAME_OPTIMIZATION, Op, NewPathExternal); ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, "AT ROOT: %-24s", NewPathExternal)); } else { /* Node is not correct, do not use this optimization */ Status = AE_NOT_FOUND; ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** WRONG NODE")); AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, "Not using optimized name - found wrong node"); } } else { /* The lookup failed, we obviously cannot use this optimization */ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_OPTIMIZATIONS, " ***** NOT FOUND")); AslError (ASL_WARNING, ASL_MSG_COMPILER_INTERNAL, Op, "Not using optimized name - did not find node"); } ACPI_FREE (NewPathExternal); return (Status); } /* Could not optimize */ return (AE_NOT_FOUND); }
ACPI_STATUS AcpiUtAcquireMutex ( ACPI_MUTEX_HANDLE MutexId) { ACPI_STATUS Status; ACPI_THREAD_ID ThisThreadId; ACPI_FUNCTION_NAME (UtAcquireMutex); if (MutexId > ACPI_MAX_MUTEX) { return (AE_BAD_PARAMETER); } ThisThreadId = AcpiOsGetThreadId (); #ifdef ACPI_MUTEX_DEBUG { UINT32 i; /* * Mutex debug code, for internal debugging only. * * 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 < ACPI_NUM_MUTEX; i++) { if (AcpiGbl_MutexInfo[i].ThreadId == ThisThreadId) { if (i == MutexId) { ACPI_ERROR ((AE_INFO, "Mutex [%s] already acquired by this thread [%u]", AcpiUtGetMutexName (MutexId), (UINT32) ThisThreadId)); return (AE_ALREADY_ACQUIRED); } ACPI_ERROR ((AE_INFO, "Invalid acquire order: Thread %u owns [%s], wants [%s]", (UINT32) ThisThreadId, AcpiUtGetMutexName (i), AcpiUtGetMutexName (MutexId))); return (AE_ACQUIRE_DEADLOCK); } } } #endif ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %u attempting to acquire Mutex [%s]\n", (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId))); Status = AcpiOsAcquireMutex (AcpiGbl_MutexInfo[MutexId].Mutex, ACPI_WAIT_FOREVER); if (ACPI_SUCCESS (Status)) { ACPI_DEBUG_PRINT ((ACPI_DB_MUTEX, "Thread %u acquired Mutex [%s]\n", (UINT32) ThisThreadId, AcpiUtGetMutexName (MutexId))); AcpiGbl_MutexInfo[MutexId].UseCount++; AcpiGbl_MutexInfo[MutexId].ThreadId = ThisThreadId; } else { ACPI_EXCEPTION ((AE_INFO, Status, "Thread %u could not acquire Mutex [0x%X]", (UINT32) ThisThreadId, MutexId)); } return (Status); }
static ACPI_STATUS EcWaitEvent(struct acpi_ec_softc *sc, EC_EVENT Event, u_int gen_count) { static int no_intr = 0; ACPI_STATUS Status; int count, i, need_poll, slp_ival; ACPI_SERIAL_ASSERT(ec); Status = AE_NO_HARDWARE_RESPONSE; need_poll = cold || rebooting || ec_polled_mode || sc->ec_suspending; /* Wait for event by polling or GPE (interrupt). */ if (need_poll) { count = (ec_timeout * 1000) / EC_POLL_DELAY; if (count == 0) count = 1; DELAY(10); for (i = 0; i < count; i++) { Status = EcCheckStatus(sc, "poll", Event); if (ACPI_SUCCESS(Status)) break; DELAY(EC_POLL_DELAY); } } else { slp_ival = hz / 1000; if (slp_ival != 0) { count = ec_timeout; } else { /* hz has less than 1 ms resolution so scale timeout. */ slp_ival = 1; count = ec_timeout / (1000 / hz); } /* * Wait for the GPE to signal the status changed, checking the * status register each time we get one. It's possible to get a * GPE for an event we're not interested in here (i.e., SCI for * EC query). */ for (i = 0; i < count; i++) { if (gen_count == sc->ec_gencount) tsleep(sc, 0, "ecgpe", slp_ival); /* * Record new generation count. It's possible the GPE was * just to notify us that a query is needed and we need to * wait for a second GPE to signal the completion of the * event we are actually waiting for. */ Status = EcCheckStatus(sc, "sleep", Event); if (ACPI_SUCCESS(Status)) { if (gen_count == sc->ec_gencount) no_intr++; else no_intr = 0; break; } gen_count = sc->ec_gencount; } /* * We finished waiting for the GPE and it never arrived. Try to * read the register once and trust whatever value we got. This is * the best we can do at this point. */ if (ACPI_FAILURE(Status)) Status = EcCheckStatus(sc, "sleep_end", Event); } if (!need_poll && no_intr > 10) { device_printf(sc->ec_dev, "not getting interrupts, switched to polled mode\n"); ec_polled_mode = 1; } if (ACPI_FAILURE(Status)) CTR0(KTR_ACPI, "error: ec wait timed out"); return (Status); }
static ACPI_STATUS EcSpaceHandler(UINT32 Function, ACPI_PHYSICAL_ADDRESS Address, UINT32 Width, UINT64 *Value, void *Context, void *RegionContext) { struct acpi_ec_softc *sc = (struct acpi_ec_softc *)Context; ACPI_PHYSICAL_ADDRESS EcAddr; UINT8 *EcData; ACPI_STATUS Status; ACPI_FUNCTION_TRACE_U32((char *)(uintptr_t)__func__, (UINT32)Address); if (Function != ACPI_READ && Function != ACPI_WRITE) return_ACPI_STATUS (AE_BAD_PARAMETER); if (Width % 8 != 0 || Value == NULL || Context == NULL) return_ACPI_STATUS (AE_BAD_PARAMETER); if (Address + Width / 8 > 256) return_ACPI_STATUS (AE_BAD_ADDRESS); /* * If booting, check if we need to run the query handler. If so, we * we call it directly here since our thread taskq is not active yet. */ if (cold || rebooting || sc->ec_suspending) { if ((EC_GET_CSR(sc) & EC_EVENT_SCI)) { CTR0(KTR_ACPI, "ec running gpe handler directly"); EcGpeQueryHandler(sc); } } /* Serialize with EcGpeQueryHandler() at transaction granularity. */ Status = EcLock(sc); if (ACPI_FAILURE(Status)) return_ACPI_STATUS (Status); /* If we can't start burst mode, continue anyway. */ Status = EcCommand(sc, EC_COMMAND_BURST_ENABLE); if (ACPI_SUCCESS(Status)) { if (EC_GET_DATA(sc) == EC_BURST_ACK) { CTR0(KTR_ACPI, "ec burst enabled"); sc->ec_burstactive = TRUE; } } /* Perform the transaction(s), based on Width. */ EcAddr = Address; EcData = (UINT8 *)Value; if (Function == ACPI_READ) *Value = 0; do { switch (Function) { case ACPI_READ: Status = EcRead(sc, EcAddr, EcData); break; case ACPI_WRITE: Status = EcWrite(sc, EcAddr, *EcData); break; } if (ACPI_FAILURE(Status)) break; EcAddr++; EcData++; } while (EcAddr < Address + Width / 8); if (sc->ec_burstactive) { sc->ec_burstactive = FALSE; if (ACPI_SUCCESS(EcCommand(sc, EC_COMMAND_BURST_DISABLE))) CTR0(KTR_ACPI, "ec disabled burst ok"); } EcUnlock(sc); return_ACPI_STATUS (Status); }
ACPI_STATUS DisplayOneDevice (ACPI_HANDLE ObjHandle, UINT32 Level, void *Context, void **RetVal) { ACPI_STATUS Status; ACPI_DEVICE_INFO *Info; ACPI_BUFFER Path; ACPI_BUFFER Result; ACPI_OBJECT Obj; char Buffer[256]; uint8 prt_buf[1024]; ACPI_BUFFER Prt = { .Length = sizeof (prt_buf), .Pointer = prt_buf }; ACPI_PCI_ROUTING_TABLE *prtd; uint32 addr=0; uint32 fun = 0; bool pcibus=FALSE; u8 busnum; Path.Length = sizeof (Buffer); Path.Pointer = Buffer; Status = AcpiGetName (ObjHandle, ACPI_FULL_PATHNAME, &Path); if (ACPI_SUCCESS (Status)) { DLOG_COM1 ("%s: \n", Path.Pointer); } Status = AcpiGetObjectInfo (ObjHandle, &Info); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" "); if (Info->Flags & ACPI_PCI_ROOT_BRIDGE) { DLOG_COM1 (" PCI_ROOT"); busnum = 0; pcibus = TRUE; } if (Info->Valid & ACPI_VALID_STA) DLOG_COM1 (" STA %.8X", Info->CurrentStatus); if (Info->Valid & ACPI_VALID_ADR) { DLOG_COM1 (" ADR %.8X", Info->Address); addr = Info->Address >> 16; fun = Info->Address & 0x7; } if (Info->Valid & ACPI_VALID_HID) DLOG_COM1 (" HID %s", Info->HardwareId.String); if (Info->Valid & ACPI_VALID_UID) DLOG_COM1 (" UID %s", Info->UniqueId.String); if (Info->Valid & ACPI_VALID_CID) DLOG_COM1 (" CID"); ACPI_FREE (Info); } Result.Length = sizeof (Obj); Result.Pointer = &Obj; Status = AcpiEvaluateObjectTyped (ObjHandle, "_DDN", NULL, &Result, ACPI_TYPE_STRING); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" DDN=%s", Obj.String.Pointer); } Result.Length = sizeof (Obj); Result.Pointer = &Obj; Status = AcpiEvaluateObjectTyped (ObjHandle, "_STR", NULL, &Result, ACPI_TYPE_STRING); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" STR=%s", Obj.String.Pointer); } Result.Length = sizeof (Obj); Result.Pointer = &Obj; Status = AcpiEvaluateObjectTyped (ObjHandle, "_MLS", NULL, &Result, ACPI_TYPE_STRING); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" MLS=%s", Obj.String.Pointer); } Status = AcpiEvaluateObjectTyped (ObjHandle, "_BBN", NULL, &Result, ACPI_TYPE_INTEGER); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" BBN=%d", Obj.Integer.Value); } else if (Status != AE_NOT_FOUND) DLOG_COM1 (" bbnERR=%d", Status); Status = AcpiEvaluateObjectTyped (ObjHandle, "_PXM", NULL, &Result, ACPI_TYPE_INTEGER); if (ACPI_SUCCESS (Status)) { DLOG_COM1 (" PXM=%d", Obj.Integer.Value); } else if (Status != AE_NOT_FOUND) DLOG_COM1 (" pxmERR=%d", Status); DLOG_COM1 ("\n"); for (;;) { Status = AcpiGetIrqRoutingTable (ObjHandle, &Prt); if (ACPI_FAILURE (Status)) { if (Status == AE_BUFFER_OVERFLOW) { DLOG_COM1 ("AcpiGetIrqRoutingTable failed: BUFFER OVERFLOW\n"); } break; } else break; } if (ACPI_SUCCESS (Status)) { int i; /* Check if ObjHandle refers to a non-root PCI bus */ if (READ (0, addr, fun, 0, dword) != 0xFFFFFFFF) { u8 hdrtype = READ (0, addr, fun, 0x0E, byte); if ((hdrtype & 0x7F) == 1) { /* PCI-to-PCI bridge headerType == 1 */ busnum = READ (0, addr, fun, 0x19, byte); //busnum = READ (0, addr, fun, 0x1A, byte); DLOG_COM1 (" bus=0x%.02X\n", busnum); pcibus = TRUE; } } for (i=0;i<sizeof(prt_buf);) { pci_irq_t irq; prtd = (ACPI_PCI_ROUTING_TABLE *)(&prt_buf[i]); if (prtd->Length == 0) break; if (pcibus) { irq.pin = prtd->Pin + 1; /* ACPI numbers pins from 0 */ irq.gsi = 0; } if (prtd->Source[0]) { DLOG_COM1 (" PRT entry: len=%d pin=%d addr=%p srcidx=0x%x src=%s\n", prtd->Length, prtd->Pin, (uint32)prtd->Address, prtd->SourceIndex, &prtd->Source[0]); GetLnkInfo (&prtd->Source[0], &irq); } else { DLOG_COM1 (" PRT entry: len=%d pin=%d addr=%p fixed IRQ=0x%x\n", prtd->Length, prtd->Pin, (uint32)prtd->Address, prtd->SourceIndex); irq.gsi = prtd->SourceIndex; irq.polarity = POLARITY_DEFAULT; irq.trigger = TRIGGER_DEFAULT; } if (pcibus && irq.gsi != 0) pci_irq_register (&irq); i+=prtd->Length; } } #if 0 ACPI_STATUS DisplayResource (ACPI_RESOURCE *Resource, void *Context); DLOG_COM1 (" _PRS:\n"); AcpiWalkResources (ObjHandle, "_PRS", DisplayResource, NULL); DLOG_COM1 (" _CRS:\n"); AcpiWalkResources (ObjHandle, "_CRS", DisplayResource, NULL); #endif return AE_OK; }
ACPI_STATUS AcpiNsRootInitialize ( void) { ACPI_STATUS Status; const ACPI_PREDEFINED_NAMES *InitVal = NULL; ACPI_NAMESPACE_NODE *NewNode; ACPI_OPERAND_OBJECT *ObjDesc; ACPI_STRING Val = NULL; ACPI_FUNCTION_TRACE (NsRootInitialize); Status = AcpiUtAcquireMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* * The global root ptr is initially NULL, so a non-NULL value indicates * that AcpiNsRootInitialize() has already been called; just return. */ if (AcpiGbl_RootNode) { Status = AE_OK; goto UnlockAndExit; } /* * Tell the rest of the subsystem that the root is initialized * (This is OK because the namespace is locked) */ AcpiGbl_RootNode = &AcpiGbl_RootNodeStruct; /* Enter the pre-defined names in the name table */ ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Entering predefined entries into namespace\n")); for (InitVal = AcpiGbl_PreDefinedNames; InitVal->Name; InitVal++) { /* _OSI is optional for now, will be permanent later */ if (!ACPI_STRCMP (InitVal->Name, "_OSI") && !AcpiGbl_CreateOsiMethod) { continue; } Status = AcpiNsLookup (NULL, InitVal->Name, InitVal->Type, ACPI_IMODE_LOAD_PASS2, ACPI_NS_NO_UPSEARCH, NULL, &NewNode); if (ACPI_FAILURE (Status)) { ACPI_EXCEPTION ((AE_INFO, Status, "Could not create predefined name %s", InitVal->Name)); continue; } /* * Name entered successfully. If entry in PreDefinedNames[] specifies * an initial value, create the initial value. */ if (InitVal->Val) { Status = AcpiOsPredefinedOverride (InitVal, &Val); if (ACPI_FAILURE (Status)) { ACPI_ERROR ((AE_INFO, "Could not override predefined %s", InitVal->Name)); } if (!Val) { Val = InitVal->Val; } /* * Entry requests an initial value, allocate a * descriptor for it. */ ObjDesc = AcpiUtCreateInternalObject (InitVal->Type); if (!ObjDesc) { Status = AE_NO_MEMORY; goto UnlockAndExit; } /* * Convert value string from table entry to * internal representation. Only types actually * used for initial values are implemented here. */ switch (InitVal->Type) { case ACPI_TYPE_METHOD: ObjDesc->Method.ParamCount = (UINT8) ACPI_TO_INTEGER (Val); ObjDesc->Common.Flags |= AOPOBJ_DATA_VALID; #if defined (ACPI_ASL_COMPILER) /* Save the parameter count for the iASL compiler */ NewNode->Value = ObjDesc->Method.ParamCount; #else /* Mark this as a very SPECIAL method */ ObjDesc->Method.InfoFlags = ACPI_METHOD_INTERNAL_ONLY; ObjDesc->Method.Dispatch.Implementation = AcpiUtOsiImplementation; #endif break; case ACPI_TYPE_INTEGER: ObjDesc->Integer.Value = ACPI_TO_INTEGER (Val); break; case ACPI_TYPE_STRING: /* Build an object around the static string */ ObjDesc->String.Length = (UINT32) ACPI_STRLEN (Val); ObjDesc->String.Pointer = Val; ObjDesc->Common.Flags |= AOPOBJ_STATIC_POINTER; break; case ACPI_TYPE_MUTEX: ObjDesc->Mutex.Node = NewNode; ObjDesc->Mutex.SyncLevel = (UINT8) (ACPI_TO_INTEGER (Val) - 1); /* Create a mutex */ Status = AcpiOsCreateMutex (&ObjDesc->Mutex.OsMutex); if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ObjDesc); goto UnlockAndExit; } /* Special case for ACPI Global Lock */ if (ACPI_STRCMP (InitVal->Name, "_GL_") == 0) { AcpiGbl_GlobalLockMutex = ObjDesc; /* Create additional counting semaphore for global lock */ Status = AcpiOsCreateSemaphore ( 1, 0, &AcpiGbl_GlobalLockSemaphore); if (ACPI_FAILURE (Status)) { AcpiUtRemoveReference (ObjDesc); goto UnlockAndExit; } } break; default: ACPI_ERROR ((AE_INFO, "Unsupported initial type value 0x%X", InitVal->Type)); AcpiUtRemoveReference (ObjDesc); ObjDesc = NULL; continue; } /* Store pointer to value descriptor in the Node */ Status = AcpiNsAttachObject (NewNode, ObjDesc, ObjDesc->Common.Type); /* Remove local reference to the object */ AcpiUtRemoveReference (ObjDesc); } } UnlockAndExit: (void) AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); /* Save a handle to "_GPE", it is always present */ if (ACPI_SUCCESS (Status)) { Status = AcpiNsGetNode (NULL, "\\_GPE", ACPI_NS_NO_UPSEARCH, &AcpiGbl_FadtGpeDevice); } return_ACPI_STATUS (Status); }
static int __init pnpacpi_add_device(struct acpi_device *device) { acpi_handle temp = NULL; acpi_status status; struct pnp_dev *dev; /* * If a PnPacpi device is not present , the device * driver should not be loaded. */ status = acpi_get_handle(device->handle, "_CRS", &temp); if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) || is_exclusive_device(device) || (!device->status.present)) return 0; dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device)); if (!dev) return -ENOMEM; dev->data = device->handle; /* .enabled means the device can decode the resources */ dev->active = device->status.enabled; status = acpi_get_handle(device->handle, "_SRS", &temp); if (ACPI_SUCCESS(status)) dev->capabilities |= PNP_CONFIGURABLE; dev->capabilities |= PNP_READ; if (device->flags.dynamic_status && (dev->capabilities & PNP_CONFIGURABLE)) dev->capabilities |= PNP_WRITE; if (device->flags.removable) dev->capabilities |= PNP_REMOVABLE; status = acpi_get_handle(device->handle, "_DIS", &temp); if (ACPI_SUCCESS(status)) dev->capabilities |= PNP_DISABLE; if (strlen(acpi_device_name(device))) strncpy(dev->name, acpi_device_name(device), sizeof(dev->name)); else strncpy(dev->name, acpi_device_bid(device), sizeof(dev->name)); if (dev->active) pnpacpi_parse_allocated_resource(dev); if (dev->capabilities & PNP_CONFIGURABLE) pnpacpi_parse_resource_option_data(dev); if (device->flags.compatible_ids) { struct acpi_compatible_id_list *cid_list = device->pnp.cid_list; int i; for (i = 0; i < cid_list->count; i++) { if (!ispnpidacpi(cid_list->id[i].value)) continue; pnp_add_id(dev, cid_list->id[i].value); } } /* clear out the damaged flags */ if (!dev->active) pnp_init_resources(dev); pnp_add_device(dev); num++; return AE_OK; }
static void acpi_bus_osc_support(void) { u32 capbuf[2]; struct acpi_osc_context context = { .uuid_str = sb_uuid_str, .rev = 1, .cap.length = 8, .cap.pointer = capbuf, }; acpi_handle handle; capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; capbuf[OSC_SUPPORT_TYPE] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */ #if defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) ||\ defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE) capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PAD_SUPPORT; #endif #if defined(CONFIG_ACPI_PROCESSOR) || defined(CONFIG_ACPI_PROCESSOR_MODULE) capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PPC_OST_SUPPORT; #endif if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle))) return; if (is_uv_system() && is_kdump_kernel()) { /* * There is no need to parse the OS Capabilities table * in the crash kernel. And it should not be done, as * that parsing includes destructive writes to io ports to * initialize UV system controller interrupts. */ return; } if (ACPI_SUCCESS(acpi_run_osc(handle, &context))) kfree(context.ret.pointer); /* do we need to check the returned cap? Sounds no */ } /* -------------------------------------------------------------------------- Event Management -------------------------------------------------------------------------- */ #ifdef CONFIG_ACPI_PROC_EVENT static DEFINE_SPINLOCK(acpi_bus_event_lock); LIST_HEAD(acpi_bus_event_list); DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); extern int event_is_open; int acpi_bus_generate_proc_event4(const char *device_class, const char *bus_id, u8 type, int data) { struct acpi_bus_event *event; unsigned long flags = 0; /* drop event on the floor if no one's listening */ if (!event_is_open) return 0; event = kmalloc(sizeof(struct acpi_bus_event), GFP_ATOMIC); if (!event) return -ENOMEM; strcpy(event->device_class, device_class); strcpy(event->bus_id, bus_id); event->type = type; event->data = data; spin_lock_irqsave(&acpi_bus_event_lock, flags); list_add_tail(&event->node, &acpi_bus_event_list); spin_unlock_irqrestore(&acpi_bus_event_lock, flags); wake_up_interruptible(&acpi_bus_event_queue); return 0; } EXPORT_SYMBOL_GPL(acpi_bus_generate_proc_event4); int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) { if (!device) return -EINVAL; return acpi_bus_generate_proc_event4(device->pnp.device_class, device->pnp.bus_id, type, data); } EXPORT_SYMBOL(acpi_bus_generate_proc_event); int acpi_bus_receive_event(struct acpi_bus_event *event) { unsigned long flags = 0; struct acpi_bus_event *entry = NULL; DECLARE_WAITQUEUE(wait, current); if (!event) return -EINVAL; if (list_empty(&acpi_bus_event_list)) { set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&acpi_bus_event_queue, &wait); if (list_empty(&acpi_bus_event_list)) schedule(); remove_wait_queue(&acpi_bus_event_queue, &wait); set_current_state(TASK_RUNNING); if (signal_pending(current)) return -ERESTARTSYS; } spin_lock_irqsave(&acpi_bus_event_lock, flags); if (!list_empty(&acpi_bus_event_list)) { entry = list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node); list_del(&entry->node); }
ACPI_STATUS DtCompileGeneric ( void **List) { ACPI_STATUS Status; DT_SUBTABLE *Subtable; DT_SUBTABLE *ParentTable; DT_FIELD **PFieldList = (DT_FIELD **) List; ACPI_DMTABLE_INFO *Info; ParentTable = DtPeekSubtable (); /* * Compile the "generic" portion of the table. This * part of the table is not predefined and any of the generic * operators may be used. */ /* Find any and all labels in the entire generic portion */ DtDetectAllLabels (*PFieldList); /* Now we can actually compile the parse tree */ while (*PFieldList) { Info = DtGetGenericTableInfo ((*PFieldList)->Name); if (!Info) { sprintf (MsgBuffer, "Generic data type \"%s\" not found", (*PFieldList)->Name); DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, (*PFieldList), MsgBuffer); *PFieldList = (*PFieldList)->Next; continue; } Status = DtCompileTable (PFieldList, Info, &Subtable, TRUE); if (ACPI_SUCCESS (Status)) { DtInsertSubtable (ParentTable, Subtable); } else { *PFieldList = (*PFieldList)->Next; if (Status == AE_NOT_FOUND) { sprintf (MsgBuffer, "Generic data type \"%s\" not found", (*PFieldList)->Name); DtNameError (ASL_ERROR, ASL_MSG_INVALID_FIELD_NAME, (*PFieldList), MsgBuffer); } } } return (AE_OK); }
acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id) { acpi_status status; acpi_thread_id this_thread_id; ACPI_FUNCTION_NAME(ut_acquire_mutex); if (mutex_id > ACPI_MAX_MUTEX) { return (AE_BAD_PARAMETER); } this_thread_id = acpi_os_get_thread_id(); #ifdef ACPI_MUTEX_DEBUG { u32 i; /* * Mutex debug code, for internal debugging only. * * 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 < ACPI_NUM_MUTEX; i++) { if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) { if (i == mutex_id) { ACPI_ERROR((AE_INFO, "Mutex [%s] already acquired by this thread [%u]", acpi_ut_get_mutex_name (mutex_id), (u32)this_thread_id)); return (AE_ALREADY_ACQUIRED); } ACPI_ERROR((AE_INFO, "Invalid acquire order: Thread %u owns [%s], wants [%s]", (u32)this_thread_id, acpi_ut_get_mutex_name(i), acpi_ut_get_mutex_name(mutex_id))); return (AE_ACQUIRE_DEADLOCK); } } } #endif ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u attempting to acquire Mutex [%s]\n", (u32)this_thread_id, acpi_ut_get_mutex_name(mutex_id))); status = acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex, ACPI_WAIT_FOREVER); if (ACPI_SUCCESS(status)) { ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u acquired Mutex [%s]\n", (u32)this_thread_id, acpi_ut_get_mutex_name(mutex_id))); acpi_gbl_mutex_info[mutex_id].use_count++; acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id; } else { ACPI_EXCEPTION((AE_INFO, status, "Thread %u could not acquire Mutex [0x%X]", (u32)this_thread_id, mutex_id)); } return (status); }
void AcpiDbExecute ( char *Name, char **Args, ACPI_OBJECT_TYPE *Types, UINT32 Flags) { ACPI_STATUS Status; ACPI_BUFFER ReturnObj; char *NameString; #ifdef ACPI_DEBUG_OUTPUT UINT32 PreviousAllocations; UINT32 Allocations; #endif /* * Allow one execution to be performed by debugger or single step * execution will be dead locked by the interpreter mutexes. */ if (AcpiGbl_MethodExecuting) { AcpiOsPrintf ("Only one debugger execution is allowed.\n"); return; } #ifdef ACPI_DEBUG_OUTPUT /* Memory allocation tracking */ PreviousAllocations = AcpiDbGetOutstandingAllocations (); #endif if (*Name == '*') { (void) AcpiWalkNamespace (ACPI_TYPE_METHOD, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, AcpiDbExecutionWalk, NULL, NULL, NULL); return; } NameString = ACPI_ALLOCATE (strlen (Name) + 1); if (!NameString) { return; } memset (&AcpiGbl_DbMethodInfo, 0, sizeof (ACPI_DB_METHOD_INFO)); strcpy (NameString, Name); AcpiUtStrupr (NameString); /* Subcommand to Execute all predefined names in the namespace */ if (!strncmp (NameString, "PREDEF", 6)) { AcpiDbEvaluatePredefinedNames (); ACPI_FREE (NameString); return; } AcpiGbl_DbMethodInfo.Name = NameString; AcpiGbl_DbMethodInfo.Args = Args; AcpiGbl_DbMethodInfo.Types = Types; AcpiGbl_DbMethodInfo.Flags = Flags; ReturnObj.Pointer = NULL; ReturnObj.Length = ACPI_ALLOCATE_BUFFER; Status = AcpiDbExecuteSetup (&AcpiGbl_DbMethodInfo); if (ACPI_FAILURE (Status)) { ACPI_FREE (NameString); return; } /* Get the NS node, determines existence also */ Status = AcpiGetHandle (NULL, AcpiGbl_DbMethodInfo.Pathname, &AcpiGbl_DbMethodInfo.Method); if (ACPI_SUCCESS (Status)) { Status = AcpiDbExecuteMethod (&AcpiGbl_DbMethodInfo, &ReturnObj); } ACPI_FREE (NameString); /* * Allow any handlers in separate threads to complete. * (Such as Notify handlers invoked from AML executed above). */ AcpiOsSleep ((UINT64) 10); #ifdef ACPI_DEBUG_OUTPUT /* Memory allocation tracking */ Allocations = AcpiDbGetOutstandingAllocations () - PreviousAllocations; AcpiDbSetOutputDestination (ACPI_DB_DUPLICATE_OUTPUT); if (Allocations > 0) { AcpiOsPrintf ( "0x%X Outstanding allocations after evaluation of %s\n", Allocations, AcpiGbl_DbMethodInfo.Pathname); } #endif if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Evaluation of %s failed with status %s\n", AcpiGbl_DbMethodInfo.Pathname, AcpiFormatException (Status)); } else { /* Display a return object, if any */ if (ReturnObj.Length) { AcpiOsPrintf ( "Evaluation of %s returned object %p, " "external buffer length %X\n", AcpiGbl_DbMethodInfo.Pathname, ReturnObj.Pointer, (UINT32) ReturnObj.Length); AcpiDbDumpExternalObject (ReturnObj.Pointer, 1); /* Dump a _PLD buffer if present */ if (ACPI_COMPARE_NAME ((ACPI_CAST_PTR (ACPI_NAMESPACE_NODE, AcpiGbl_DbMethodInfo.Method)->Name.Ascii), METHOD_NAME__PLD)) { AcpiDbDumpPldBuffer (ReturnObj.Pointer); } } else { AcpiOsPrintf ("No object was returned from evaluation of %s\n", AcpiGbl_DbMethodInfo.Pathname); } } AcpiDbSetOutputDestination (ACPI_DB_CONSOLE_OUTPUT); }
ACPI_STATUS AcpiNsGetObjectValue ( ACPI_NAMESPACE_NODE *Node, ACPI_OPERAND_OBJECT **ReturnObjDesc) { ACPI_STATUS Status = AE_OK; ACPI_NAMESPACE_NODE *ResolvedNode = Node; ACPI_FUNCTION_TRACE ("NsGetObjectValue"); /* * Objects require additional resolution steps (e.g., the * Node may be a field that must be read, etc.) -- we can't just grab * the object out of the node. */ /* * Use ResolveNodeToValue() to get the associated value. This call * always deletes ObjDesc (allocated above). * * NOTE: we can get away with passing in NULL for a walk state * because ObjDesc is guaranteed to not be a reference to either * a method local or a method argument (because this interface can only be * called from the AcpiEvaluate external interface, never called from * a running control method.) * * Even though we do not directly invoke the interpreter * for this, we must enter it because we could access an opregion. * The opregion access code assumes that the interpreter * is locked. * * We must release the namespace lock before entering the * intepreter. */ Status = AcpiUtReleaseMutex (ACPI_MTX_NAMESPACE); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } Status = AcpiExEnterInterpreter (); if (ACPI_SUCCESS (Status)) { Status = AcpiExResolveNodeToValue (&ResolvedNode, NULL); /* * If AcpiExResolveNodeToValue() succeeded, the return value was * placed in ResolvedNode. */ AcpiExExitInterpreter (); if (ACPI_SUCCESS (Status)) { Status = AE_CTRL_RETURN_VALUE; *ReturnObjDesc = ACPI_CAST_PTR (ACPI_OPERAND_OBJECT, ResolvedNode); ACPI_DEBUG_PRINT ((ACPI_DB_NAMES, "Returning object %p [%s]\n", *ReturnObjDesc, AcpiUtGetObjectTypeName (*ReturnObjDesc))); } } /* Namespace is unlocked */ return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiDsEvaluateNamePath ( ACPI_WALK_STATE *WalkState) { ACPI_STATUS Status = AE_OK; ACPI_PARSE_OBJECT *Op = WalkState->Op; ACPI_OPERAND_OBJECT **Operand = &WalkState->Operands[0]; ACPI_OPERAND_OBJECT *NewObjDesc; UINT8 Type; ACPI_FUNCTION_TRACE_PTR (DsEvaluateNamePath, WalkState); if (!Op->Common.Parent) { /* This happens after certain exception processing */ goto Exit; } if ((Op->Common.Parent->Common.AmlOpcode == AML_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_VAR_PACKAGE_OP) || (Op->Common.Parent->Common.AmlOpcode == AML_REF_OF_OP)) { /* TBD: Should we specify this feature as a bit of OpInfo->Flags of these opcodes? */ goto Exit; } Status = AcpiDsCreateOperand (WalkState, Op, 0); if (ACPI_FAILURE (Status)) { goto Exit; } if (Op->Common.Flags & ACPI_PARSEOP_TARGET) { NewObjDesc = *Operand; goto PushResult; } Type = (*Operand)->Common.Type; Status = AcpiExResolveToValue (Operand, WalkState); if (ACPI_FAILURE (Status)) { goto Exit; } if (Type == ACPI_TYPE_INTEGER) { /* It was incremented by AcpiExResolveToValue */ AcpiUtRemoveReference (*Operand); Status = AcpiUtCopyIobjectToIobject (*Operand, &NewObjDesc, WalkState); if (ACPI_FAILURE (Status)) { goto Exit; } } else { /* * The object either was anew created or is * a Namespace node - don't decrement it. */ NewObjDesc = *Operand; } /* Cleanup for name-path operand */ Status = AcpiDsObjStackPop (1, WalkState); if (ACPI_FAILURE (Status)) { WalkState->ResultObj = NewObjDesc; goto Exit; } PushResult: WalkState->ResultObj = NewObjDesc; Status = AcpiDsResultPush (WalkState->ResultObj, WalkState); if (ACPI_SUCCESS (Status)) { /* Force to take it from stack */ Op->Common.Flags |= ACPI_PARSEOP_IN_STACK; } Exit: return_ACPI_STATUS (Status); }
ACPI_STATUS AcpiExGetNameString ( ACPI_OBJECT_TYPE DataType, UINT8 *InAmlAddress, char **OutNameString, UINT32 *OutNameLength) { ACPI_STATUS Status = AE_OK; UINT8 *AmlAddress = InAmlAddress; char *NameString = NULL; UINT32 NumSegments; UINT32 PrefixCount = 0; BOOLEAN HasPrefix = FALSE; ACPI_FUNCTION_TRACE_PTR (ExGetNameString, AmlAddress); if (ACPI_TYPE_LOCAL_REGION_FIELD == DataType || ACPI_TYPE_LOCAL_BANK_FIELD == DataType || ACPI_TYPE_LOCAL_INDEX_FIELD == DataType) { /* Disallow prefixes for types associated with FieldUnit names */ NameString = AcpiExAllocateNameString (0, 1); if (!NameString) { Status = AE_NO_MEMORY; } else { Status = AcpiExNameSegment (&AmlAddress, NameString); } } else { /* * DataType is not a field name. * Examine first character of name for root or parent prefix operators */ switch (*AmlAddress) { case AML_ROOT_PREFIX: ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "RootPrefix(\\) at %p\n", AmlAddress)); /* * Remember that we have a RootPrefix -- * see comment in AcpiExAllocateNameString() */ AmlAddress++; PrefixCount = ACPI_UINT32_MAX; HasPrefix = TRUE; break; case AML_PARENT_PREFIX: /* Increment past possibly multiple parent prefixes */ do { ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "ParentPrefix (^) at %p\n", AmlAddress)); AmlAddress++; PrefixCount++; } while (*AmlAddress == AML_PARENT_PREFIX); HasPrefix = TRUE; break; default: /* Not a prefix character */ break; } /* Examine first character of name for name segment prefix operator */ switch (*AmlAddress) { case AML_DUAL_NAME_PREFIX: ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "DualNamePrefix at %p\n", AmlAddress)); AmlAddress++; NameString = AcpiExAllocateNameString (PrefixCount, 2); if (!NameString) { Status = AE_NO_MEMORY; break; } /* Indicate that we processed a prefix */ HasPrefix = TRUE; Status = AcpiExNameSegment (&AmlAddress, NameString); if (ACPI_SUCCESS (Status)) { Status = AcpiExNameSegment (&AmlAddress, NameString); } break; case AML_MULTI_NAME_PREFIX_OP: ACPI_DEBUG_PRINT ((ACPI_DB_LOAD, "MultiNamePrefix at %p\n", AmlAddress)); /* Fetch count of segments remaining in name path */ AmlAddress++; NumSegments = *AmlAddress; NameString = AcpiExAllocateNameString (PrefixCount, NumSegments); if (!NameString) { Status = AE_NO_MEMORY; break; } /* Indicate that we processed a prefix */ AmlAddress++; HasPrefix = TRUE; while (NumSegments && (Status = AcpiExNameSegment (&AmlAddress, NameString)) == AE_OK) { NumSegments--; } break; case 0: /* NullName valid as of 8-12-98 ASL/AML Grammar Update */ if (PrefixCount == ACPI_UINT32_MAX) { ACPI_DEBUG_PRINT ((ACPI_DB_EXEC, "NameSeg is \"\\\" followed by NULL\n")); } /* Consume the NULL byte */ AmlAddress++; NameString = AcpiExAllocateNameString (PrefixCount, 0); if (!NameString) { Status = AE_NO_MEMORY; break; } break; default: /* Name segment string */ NameString = AcpiExAllocateNameString (PrefixCount, 1); if (!NameString) { Status = AE_NO_MEMORY; break; } Status = AcpiExNameSegment (&AmlAddress, NameString); break; } } if (AE_CTRL_PENDING == Status && HasPrefix) { /* Ran out of segments after processing a prefix */ ACPI_ERROR ((AE_INFO, "Malformed Name at %p", NameString)); Status = AE_AML_BAD_NAME; } if (ACPI_FAILURE (Status)) { if (NameString) { ACPI_FREE (NameString); } return_ACPI_STATUS (Status); } *OutNameString = NameString; *OutNameLength = (UINT32) (AmlAddress - InAmlAddress); return_ACPI_STATUS (Status); }
static acpi_status setup_resource(struct acpi_resource *acpi_res, void *data) { struct pci_root_info *info = data; struct resource *res; struct acpi_resource_address64 addr; acpi_status status; unsigned long flags; struct resource *root, *conflict; u64 start, end; status = resource_to_addr(acpi_res, &addr); if (!ACPI_SUCCESS(status)) return AE_OK; if (addr.resource_type == ACPI_MEMORY_RANGE) { root = &iomem_resource; flags = IORESOURCE_MEM; if (addr.info.mem.caching == ACPI_PREFETCHABLE_MEMORY) flags |= IORESOURCE_PREFETCH; } else if (addr.resource_type == ACPI_IO_RANGE) { root = &ioport_resource; flags = IORESOURCE_IO; } else return AE_OK; start = addr.minimum + addr.translation_offset; end = addr.maximum + addr.translation_offset; res = &info->res[info->res_num]; res->name = info->name; res->flags = flags; res->start = start; res->end = end; res->child = NULL; if (!pci_use_crs) { dev_printk(KERN_DEBUG, &info->bridge->dev, "host bridge window %pR (ignored)\n", res); return AE_OK; } conflict = insert_resource_conflict(root, res); if (conflict) { dev_err(&info->bridge->dev, "address space collision: host bridge window %pR " "conflicts with %s %pR\n", res, conflict->name, conflict); } else { pci_bus_add_resource(info->bus, res, 0); info->res_num++; if (addr.translation_offset) dev_info(&info->bridge->dev, "host bridge window %pR " "(PCI address [%#llx-%#llx])\n", res, res->start - addr.translation_offset, res->end - addr.translation_offset); else dev_info(&info->bridge->dev, "host bridge window %pR\n", res); } return AE_OK; }
static void AfInstallGpeBlock ( void) { ACPI_STATUS Status; ACPI_HANDLE Handle; ACPI_GENERIC_ADDRESS BlockAddress; ACPI_HANDLE GpeDevice; ACPI_OBJECT_TYPE Type; /* _GPE should always exist */ Status = AcpiGetHandle (NULL, "\\_GPE", &Handle); AE_CHECK_OK (AcpiGetHandle, Status); if (ACPI_FAILURE (Status)) { return; } memset (&BlockAddress, 0, sizeof (ACPI_GENERIC_ADDRESS)); BlockAddress.SpaceId = ACPI_ADR_SPACE_SYSTEM_MEMORY; BlockAddress.Address = 0x76540000; /* Attempt to install a GPE block on GPE2 (if present) */ Status = AcpiGetHandle (NULL, "\\GPE2", &Handle); if (ACPI_SUCCESS (Status)) { Status = AcpiGetType (Handle, &Type); if (ACPI_FAILURE (Status) || (Type != ACPI_TYPE_DEVICE)) { return; } Status = AcpiInstallGpeBlock (Handle, &BlockAddress, 7, 8); AE_CHECK_OK (AcpiInstallGpeBlock, Status); Status = AcpiInstallGpeHandler (Handle, 8, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (Handle, 8); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiGetGpeDevice (0x30, &GpeDevice); AE_CHECK_OK (AcpiGetGpeDevice, Status); Status = AcpiGetGpeDevice (0x42, &GpeDevice); AE_CHECK_OK (AcpiGetGpeDevice, Status); Status = AcpiGetGpeDevice (AcpiCurrentGpeCount-1, &GpeDevice); AE_CHECK_OK (AcpiGetGpeDevice, Status); Status = AcpiGetGpeDevice (AcpiCurrentGpeCount, &GpeDevice); AE_CHECK_STATUS (AcpiGetGpeDevice, Status, AE_NOT_EXIST); Status = AcpiRemoveGpeHandler (Handle, 8, AeGpeHandler); AE_CHECK_OK (AcpiRemoveGpeHandler, Status); } /* Attempt to install a GPE block on GPE3 (if present) */ Status = AcpiGetHandle (NULL, "\\GPE3", &Handle); if (ACPI_SUCCESS (Status)) { Status = AcpiGetType (Handle, &Type); if (ACPI_FAILURE (Status) || (Type != ACPI_TYPE_DEVICE)) { return; } Status = AcpiInstallGpeBlock (Handle, &BlockAddress, 8, 11); AE_CHECK_OK (AcpiInstallGpeBlock, Status); } }
/****************************************************************************** * * FUNCTION: acpi_hw_register_read * * PARAMETERS: register_id - ACPI Register ID * return_value - Where the register value is returned * * RETURN: Status and the value read. * * DESCRIPTION: Read from the specified ACPI register * ******************************************************************************/ acpi_status acpi_hw_register_read(u32 register_id, u32 * return_value) { u32 value = 0; acpi_status status; ACPI_FUNCTION_TRACE(hw_register_read); switch (register_id) { case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */ status = acpi_hw_read_multiple(&value, &acpi_gbl_xpm1a_status, &acpi_gbl_xpm1b_status); break; case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */ status = acpi_hw_read_multiple(&value, &acpi_gbl_xpm1a_enable, &acpi_gbl_xpm1b_enable); break; case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */ status = acpi_hw_read_multiple(&value, &acpi_gbl_FADT. xpm1a_control_block, &acpi_gbl_FADT. xpm1b_control_block); /* * Zero the write-only bits. From the ACPI specification, "Hardware * Write-Only Bits": "Upon reads to registers with write-only bits, * software masks out all write-only bits." */ value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS; break; case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */ status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm2_control_block); break; case ACPI_REGISTER_PM_TIMER: /* 32-bit access */ status = acpi_hw_read(&value, &acpi_gbl_FADT.xpm_timer_block); break; case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */ status = acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8); break; default: ACPI_ERROR((AE_INFO, "Unknown Register ID: 0x%X", register_id)); status = AE_BAD_PARAMETER; break; } if (ACPI_SUCCESS(status)) { *return_value = value; } return_ACPI_STATUS(status); }
void AeMiscellaneousTests ( void) { ACPI_BUFFER ReturnBuf; char Buffer[32]; ACPI_STATUS Status; ACPI_STATISTICS Stats; ACPI_HANDLE Handle; #if (!ACPI_REDUCED_HARDWARE) ACPI_VENDOR_UUID Uuid = {0, {ACPI_INIT_UUID (0,0,0,0,0,0,0,0,0,0,0)}}; UINT32 LockHandle1; UINT32 LockHandle2; #endif /* !ACPI_REDUCED_HARDWARE */ Status = AcpiGetHandle (NULL, "\\", &Handle); AE_CHECK_OK (AcpiGetHandle, Status); if (AcpiGbl_DoInterfaceTests) { /* * Tests for AcpiLoadTable and AcpiUnloadParentTable */ /* Attempt unload of DSDT, should fail */ Status = AcpiGetHandle (NULL, "\\_SB_", &Handle); AE_CHECK_OK (AcpiGetHandle, Status); Status = AcpiUnloadParentTable (Handle); AE_CHECK_STATUS (AcpiUnloadParentTable, Status, AE_TYPE); /* Load and unload SSDT4 */ Status = AcpiLoadTable ((ACPI_TABLE_HEADER *) Ssdt4Code); AE_CHECK_OK (AcpiLoadTable, Status); Status = AcpiGetHandle (NULL, "\\_T96", &Handle); AE_CHECK_OK (AcpiGetHandle, Status); Status = AcpiUnloadParentTable (Handle); AE_CHECK_OK (AcpiUnloadParentTable, Status); /* Re-load SSDT4 */ Status = AcpiLoadTable ((ACPI_TABLE_HEADER *) Ssdt4Code); AE_CHECK_OK (AcpiLoadTable, Status); /* Unload and re-load SSDT2 (SSDT2 is in the XSDT) */ Status = AcpiGetHandle (NULL, "\\_T99", &Handle); AE_CHECK_OK (AcpiGetHandle, Status); Status = AcpiUnloadParentTable (Handle); AE_CHECK_OK (AcpiUnloadParentTable, Status); Status = AcpiLoadTable ((ACPI_TABLE_HEADER *) Ssdt2Code); AE_CHECK_OK (AcpiLoadTable, Status); /* Load OEM9 table (causes table override) */ Status = AcpiLoadTable ((ACPI_TABLE_HEADER *) Ssdt3Code); AE_CHECK_OK (AcpiLoadTable, Status); } AeHardwareInterfaces (); AeGenericRegisters (); AeSetupConfiguration (Ssdt3Code); AeTestBufferArgument(); AeTestPackageArgument (); AeMutexInterfaces (); /* Test _OSI install/remove */ Status = AcpiInstallInterface (""); AE_CHECK_STATUS (AcpiInstallInterface, Status, AE_BAD_PARAMETER); Status = AcpiInstallInterface ("TestString"); AE_CHECK_OK (AcpiInstallInterface, Status); Status = AcpiInstallInterface ("TestString"); AE_CHECK_STATUS (AcpiInstallInterface, Status, AE_ALREADY_EXISTS); Status = AcpiRemoveInterface ("Windows 2006"); AE_CHECK_OK (AcpiRemoveInterface, Status); Status = AcpiRemoveInterface ("TestString"); AE_CHECK_OK (AcpiRemoveInterface, Status); Status = AcpiRemoveInterface ("XXXXXX"); AE_CHECK_STATUS (AcpiRemoveInterface, Status, AE_NOT_EXIST); Status = AcpiInstallInterface ("AnotherTestString"); AE_CHECK_OK (AcpiInstallInterface, Status); /* Test _OSI execution */ Status = ExecuteOSI ("Extended Address Space Descriptor", 0xFFFFFFFF); AE_CHECK_OK (ExecuteOSI, Status); Status = ExecuteOSI ("Windows 2001", 0xFFFFFFFF); AE_CHECK_OK (ExecuteOSI, Status); Status = ExecuteOSI ("MichiganTerminalSystem", 0); AE_CHECK_OK (ExecuteOSI, Status); ReturnBuf.Length = 32; ReturnBuf.Pointer = Buffer; Status = AcpiGetName (ACPI_ROOT_OBJECT, ACPI_FULL_PATHNAME, &ReturnBuf); AE_CHECK_OK (AcpiGetName, Status); /* Get Devices */ Status = AcpiGetDevices (NULL, AeGetDevices, NULL, NULL); AE_CHECK_OK (AcpiGetDevices, Status); Status = AcpiGetStatistics (&Stats); AE_CHECK_OK (AcpiGetStatistics, Status); #if (!ACPI_REDUCED_HARDWARE) Status = AcpiInstallGlobalEventHandler (AeGlobalEventHandler, NULL); AE_CHECK_OK (AcpiInstallGlobalEventHandler, Status); /* If Hardware Reduced flag is set, we are all done */ if (AcpiGbl_ReducedHardware) { return; } Status = AcpiEnableEvent (ACPI_EVENT_GLOBAL, 0); AE_CHECK_OK (AcpiEnableEvent, Status); /* * GPEs: Handlers, enable/disable, etc. */ Status = AcpiInstallGpeHandler (NULL, 0, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 0); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiRemoveGpeHandler (NULL, 0, AeGpeHandler); AE_CHECK_OK (AcpiRemoveGpeHandler, Status); Status = AcpiInstallGpeHandler (NULL, 0, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 0); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiSetGpe (NULL, 0, ACPI_GPE_DISABLE); AE_CHECK_OK (AcpiSetGpe, Status); Status = AcpiSetGpe (NULL, 0, ACPI_GPE_ENABLE); AE_CHECK_OK (AcpiSetGpe, Status); Status = AcpiInstallGpeHandler (NULL, 1, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 1); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiInstallGpeHandler (NULL, 2, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 2); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiInstallGpeHandler (NULL, 3, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiInstallGpeHandler (NULL, 4, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiInstallGpeHandler (NULL, 5, ACPI_GPE_EDGE_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiGetHandle (NULL, "\\_SB", &Handle); AE_CHECK_OK (AcpiGetHandle, Status); Status = AcpiSetupGpeForWake (Handle, NULL, 5); AE_CHECK_OK (AcpiSetupGpeForWake, Status); Status = AcpiSetGpeWakeMask (NULL, 5, ACPI_GPE_ENABLE); AE_CHECK_OK (AcpiSetGpeWakeMask, Status); Status = AcpiSetupGpeForWake (Handle, NULL, 6); AE_CHECK_OK (AcpiSetupGpeForWake, Status); Status = AcpiSetupGpeForWake (ACPI_ROOT_OBJECT, NULL, 6); AE_CHECK_OK (AcpiSetupGpeForWake, Status); Status = AcpiSetupGpeForWake (Handle, NULL, 9); AE_CHECK_OK (AcpiSetupGpeForWake, Status); Status = AcpiInstallGpeHandler (NULL, 0x19, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 0x19); AE_CHECK_OK (AcpiEnableGpe, Status); /* GPE block 1 */ Status = AcpiInstallGpeHandler (NULL, 101, ACPI_GPE_LEVEL_TRIGGERED, AeGpeHandler, NULL); AE_CHECK_OK (AcpiInstallGpeHandler, Status); Status = AcpiEnableGpe (NULL, 101); AE_CHECK_OK (AcpiEnableGpe, Status); Status = AcpiDisableGpe (NULL, 101); AE_CHECK_OK (AcpiDisableGpe, Status); AfInstallGpeBlock (); /* Here is where the GPEs are actually "enabled" */ Status = AcpiUpdateAllGpes (); AE_CHECK_OK (AcpiUpdateAllGpes, Status); Status = AcpiGetHandle (NULL, "RSRC", &Handle); if (ACPI_SUCCESS (Status)) { ReturnBuf.Length = ACPI_ALLOCATE_BUFFER; Status = AcpiGetVendorResource (Handle, "_CRS", &Uuid, &ReturnBuf); if (ACPI_SUCCESS (Status)) { AcpiOsFree (ReturnBuf.Pointer); } } /* Test global lock */ Status = AcpiAcquireGlobalLock (0xFFFF, &LockHandle1); AE_CHECK_OK (AcpiAcquireGlobalLock, Status); Status = AcpiAcquireGlobalLock (0x5, &LockHandle2); AE_CHECK_OK (AcpiAcquireGlobalLock, Status); Status = AcpiReleaseGlobalLock (LockHandle1); AE_CHECK_OK (AcpiReleaseGlobalLock, Status); Status = AcpiReleaseGlobalLock (LockHandle2); AE_CHECK_OK (AcpiReleaseGlobalLock, Status); #endif /* !ACPI_REDUCED_HARDWARE */ }
static ACPI_STATUS AcpiDbReadTable ( FILE *fp, ACPI_TABLE_HEADER **Table, UINT32 *TableLength) { ACPI_TABLE_HEADER TableHeader; UINT32 Actual; ACPI_STATUS Status; UINT32 FileSize; BOOLEAN StandardHeader = TRUE; /* Get the file size */ FileSize = CmGetFileSize (fp); if (FileSize == ACPI_UINT32_MAX) { return (AE_ERROR); } if (FileSize < 4) { return (AE_BAD_HEADER); } /* Read the signature */ if (fread (&TableHeader, 1, 4, fp) != 4) { AcpiOsPrintf ("Could not read the table signature\n"); return (AE_BAD_HEADER); } fseek (fp, 0, SEEK_SET); /* The RSDP table does not have standard ACPI header */ if (ACPI_COMPARE_NAME (TableHeader.Signature, "RSD ")) { *TableLength = FileSize; StandardHeader = FALSE; } else { /* Read the table header */ if (fread (&TableHeader, 1, sizeof (ACPI_TABLE_HEADER), fp) != sizeof (ACPI_TABLE_HEADER)) { AcpiOsPrintf ("Could not read the table header\n"); return (AE_BAD_HEADER); } #if 0 /* Validate the table header/length */ Status = AcpiTbValidateTableHeader (&TableHeader); if (ACPI_FAILURE (Status)) { AcpiOsPrintf ("Table header is invalid!\n"); return (Status); } #endif /* File size must be at least as long as the Header-specified length */ if (TableHeader.Length > FileSize) { AcpiOsPrintf ( "TableHeader length [0x%X] greater than the input file size [0x%X]\n", TableHeader.Length, FileSize); #ifdef ACPI_ASL_COMPILER Status = FlCheckForAscii (fp, NULL, FALSE); if (ACPI_SUCCESS (Status)) { AcpiOsPrintf ("File appears to be ASCII only, must be binary\n", TableHeader.Length, FileSize); } #endif return (AE_BAD_HEADER); } #ifdef ACPI_OBSOLETE_CODE /* We only support a limited number of table types */ if (!ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_DSDT) && !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_PSDT) && !ACPI_COMPARE_NAME ((char *) TableHeader.Signature, ACPI_SIG_SSDT)) { AcpiOsPrintf ("Table signature [%4.4s] is invalid or not supported\n", (char *) TableHeader.Signature); ACPI_DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER)); return (AE_ERROR); } #endif *TableLength = TableHeader.Length; } /* Allocate a buffer for the table */ *Table = AcpiOsAllocate ((size_t) FileSize); if (!*Table) { AcpiOsPrintf ( "Could not allocate memory for ACPI table %4.4s (size=0x%X)\n", TableHeader.Signature, *TableLength); return (AE_NO_MEMORY); } /* Get the rest of the table */ fseek (fp, 0, SEEK_SET); Actual = fread (*Table, 1, (size_t) FileSize, fp); if (Actual == FileSize) { if (StandardHeader) { /* Now validate the checksum */ Status = AcpiTbVerifyChecksum ((void *) *Table, ACPI_CAST_PTR (ACPI_TABLE_HEADER, *Table)->Length); if (Status == AE_BAD_CHECKSUM) { Status = AcpiDbCheckTextModeCorruption ((UINT8 *) *Table, FileSize, (*Table)->Length); return (Status); } } return (AE_OK); } if (Actual > 0) { AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n", FileSize, Actual); return (AE_OK); } AcpiOsPrintf ("Error - could not read the table file\n"); AcpiOsFree (*Table); *Table = NULL; *TableLength = 0; return (AE_ERROR); }
ACPI_STATUS AcpiPsParseAml ( ACPI_PARSE_OBJECT *StartScope, UINT8 *Aml, UINT32 AmlSize, UINT32 ParseFlags, ACPI_NAMESPACE_NODE *MethodNode, ACPI_OPERAND_OBJECT **Params, ACPI_OPERAND_OBJECT **CallerReturnDesc, ACPI_PARSE_DOWNWARDS DescendingCallback, ACPI_PARSE_UPWARDS AscendingCallback) { ACPI_STATUS Status; ACPI_PARSE_STATE *ParserState; ACPI_WALK_STATE *WalkState; ACPI_WALK_LIST WalkList; ACPI_WALK_LIST *PrevWalkList = AcpiGbl_CurrentWalkList; ACPI_OPERAND_OBJECT *ReturnDesc; ACPI_OPERAND_OBJECT *MthDesc = NULL; FUNCTION_TRACE ("PsParseAml"); ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Entered with Scope=%p Aml=%p size=%lX\n", StartScope, Aml, AmlSize)); /* Create and initialize a new parser state */ ParserState = AcpiPsCreateState (Aml, AmlSize); if (!ParserState) { return_ACPI_STATUS (AE_NO_MEMORY); } AcpiPsInitScope (ParserState, StartScope); if (MethodNode) { MthDesc = AcpiNsGetAttachedObject (MethodNode); } /* Create and initialize a new walk list */ WalkList.WalkState = NULL; WalkList.AcquiredMutexList.Prev = NULL; WalkList.AcquiredMutexList.Next = NULL; WalkState = AcpiDsCreateWalkState (TABLE_ID_DSDT, ParserState->StartOp, MthDesc, &WalkList); if (!WalkState) { Status = AE_NO_MEMORY; goto Cleanup; } WalkState->MethodNode = MethodNode; WalkState->ParserState = ParserState; WalkState->ParseFlags = ParseFlags; WalkState->DescendingCallback = DescendingCallback; WalkState->AscendingCallback = AscendingCallback; /* TBD: [Restructure] TEMP until we pass WalkState to the interpreter */ AcpiGbl_CurrentWalkList = &WalkList; if (MethodNode) { ParserState->StartNode = MethodNode; WalkState->WalkType = WALK_METHOD; /* Push start scope on scope stack and make it current */ Status = AcpiDsScopeStackPush (MethodNode, ACPI_TYPE_METHOD, WalkState); if (ACPI_FAILURE (Status)) { return_ACPI_STATUS (Status); } /* Init arguments if this is a control method */ /* TBD: [Restructure] add walkstate as a param */ AcpiDsMethodDataInitArgs (Params, MTH_NUM_ARGS, WalkState); } else { /* Setup the current scope */ ParserState->StartNode = ParserState->StartOp->Node; if (ParserState->StartNode) { /* Push start scope on scope stack and make it current */ Status = AcpiDsScopeStackPush (ParserState->StartNode, ParserState->StartNode->Type, WalkState); if (ACPI_FAILURE (Status)) { goto Cleanup; } } } /* * Execute the walk loop as long as there is a valid Walk State. This * handles nested control method invocations without recursion. */ ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "State=%p\n", WalkState)); Status = AE_OK; while (WalkState) { if (ACPI_SUCCESS (Status)) { Status = AcpiPsParseLoop (WalkState); } ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Completed one call to walk loop, State=%p\n", WalkState)); if (Status == AE_CTRL_TRANSFER) { /* * A method call was detected. * Transfer control to the called control method */ Status = AcpiDsCallControlMethod (&WalkList, WalkState, NULL); /* * If the transfer to the new method method call worked, a new walk * state was created -- get it */ WalkState = AcpiDsGetCurrentWalkState (&WalkList); continue; } else if (Status == AE_CTRL_TERMINATE) { Status = AE_OK; } /* We are done with this walk, move on to the parent if any */ WalkState = AcpiDsPopWalkState (&WalkList); /* Extract return value before we delete WalkState */ ReturnDesc = WalkState->ReturnDesc; ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "ReturnValue=%p, State=%p\n", WalkState->ReturnDesc, WalkState)); /* Reset the current scope to the beginning of scope stack */ AcpiDsScopeStackClear (WalkState); /* * If we just returned from the execution of a control method, * there's lots of cleanup to do */ if ((WalkState->ParseFlags & ACPI_PARSE_MODE_MASK) == ACPI_PARSE_EXECUTE) { AcpiDsTerminateControlMethod (WalkState); } /* Delete this walk state and all linked control states */ AcpiPsCleanupScope (WalkState->ParserState); ACPI_MEM_FREE (WalkState->ParserState); AcpiDsDeleteWalkState (WalkState); /* Check if we have restarted a preempted walk */ WalkState = AcpiDsGetCurrentWalkState (&WalkList); if (WalkState && ACPI_SUCCESS (Status)) { /* There is another walk state, restart it */ /* * If the method returned value is not used by the parent, * The object is deleted */ AcpiDsRestartControlMethod (WalkState, ReturnDesc); WalkState->WalkType |= WALK_METHOD_RESTART; } /* * Just completed a 1st-level method, save the final internal return * value (if any) */ else if (CallerReturnDesc) { *CallerReturnDesc = ReturnDesc; /* NULL if no return value */ } else if (ReturnDesc) { /* Caller doesn't want it, must delete it */ AcpiUtRemoveReference (ReturnDesc); } } /* Normal exit */ AcpiExReleaseAllMutexes ((ACPI_OPERAND_OBJECT *) &WalkList.AcquiredMutexList); AcpiGbl_CurrentWalkList = PrevWalkList; return_ACPI_STATUS (Status); Cleanup: /* Cleanup */ AcpiDsDeleteWalkState (WalkState); AcpiPsCleanupScope (ParserState); ACPI_MEM_FREE (ParserState); AcpiExReleaseAllMutexes ((ACPI_OPERAND_OBJECT *)&WalkList.AcquiredMutexList); AcpiGbl_CurrentWalkList = PrevWalkList; return_ACPI_STATUS (Status); }