Beispiel #1
0
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;
}
Beispiel #3
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
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);
}
Beispiel #7
0
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;
}
Beispiel #8
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);
}
Beispiel #10
0
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);
}
Beispiel #11
0
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);
}
Beispiel #12
0
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);
}
Beispiel #13
0
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);
}
Beispiel #14
0
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);
}
Beispiel #15
0
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;
}
Beispiel #16
0
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);
}
Beispiel #17
0
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;
}
Beispiel #18
0
Datei: bus.c Projekt: 710leo/LVS
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);
	}
Beispiel #19
0
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);
}
Beispiel #20
0
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);
}
Beispiel #21
0
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);
}
Beispiel #22
0
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);
}
Beispiel #23
0
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);
}
Beispiel #24
0
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;
}
Beispiel #26
0
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);
    }
}
Beispiel #27
0
/******************************************************************************
 *
 * 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);
}
Beispiel #28
0
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 */
}
Beispiel #29
0
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);
}
Beispiel #30
0
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);
}