exsystem.c 8.9 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8

/******************************************************************************
 *
 * Module Name: exsystem - Interface to OS services
 *
 *****************************************************************************/

/*
9
 * Copyright (C) 2000 - 2010, Intel Corp.
L
Linus Torvalds 已提交
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions, and the following disclaimer,
 *    without modification.
 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
 *    substantially similar to the "NO WARRANTY" disclaimer below
 *    ("Disclaimer") and any redistribution must be conditioned upon
 *    including a substantially similar Disclaimer requirement for further
 *    binary redistribution.
 * 3. Neither the names of the above-listed copyright holders nor the names
 *    of any contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 *
 * NO WARRANTY
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 */

#include <acpi/acpi.h>
L
Len Brown 已提交
46 47
#include "accommon.h"
#include "acinterp.h"
L
Linus Torvalds 已提交
48 49

#define _COMPONENT          ACPI_EXECUTER
L
Len Brown 已提交
50
ACPI_MODULE_NAME("exsystem")
L
Linus Torvalds 已提交
51 52 53 54 55

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_wait_semaphore
 *
R
Robert Moore 已提交
56 57
 * PARAMETERS:  Semaphore       - Semaphore to wait on
 *              Timeout         - Max time to wait
L
Linus Torvalds 已提交
58 59 60 61 62
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Implements a semaphore wait with a check to see if the
 *              semaphore is available immediately.  If it is not, the
B
Bob Moore 已提交
63
 *              interpreter is released before waiting.
L
Linus Torvalds 已提交
64 65
 *
 ******************************************************************************/
B
Bob Moore 已提交
66
acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout)
L
Linus Torvalds 已提交
67
{
L
Len Brown 已提交
68
	acpi_status status;
L
Linus Torvalds 已提交
69

B
Bob Moore 已提交
70
	ACPI_FUNCTION_TRACE(ex_system_wait_semaphore);
L
Linus Torvalds 已提交
71

B
Bob Moore 已提交
72
	status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT);
L
Len Brown 已提交
73 74
	if (ACPI_SUCCESS(status)) {
		return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
75 76 77
	}

	if (status == AE_TIME) {
B
Bob Moore 已提交
78

L
Linus Torvalds 已提交
79 80
		/* We must wait, so unlock the interpreter */

81
		acpi_ex_relinquish_interpreter();
L
Linus Torvalds 已提交
82

L
Len Brown 已提交
83
		status = acpi_os_wait_semaphore(semaphore, 1, timeout);
L
Linus Torvalds 已提交
84

L
Len Brown 已提交
85 86 87
		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
				  "*** Thread awake after blocking, %s\n",
				  acpi_format_exception(status)));
L
Linus Torvalds 已提交
88 89 90

		/* Reacquire the interpreter */

91
		acpi_ex_reacquire_interpreter();
L
Linus Torvalds 已提交
92 93
	}

L
Len Brown 已提交
94
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
95 96
}

B
Bob Moore 已提交
97 98 99 100 101 102 103 104 105
/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_wait_mutex
 *
 * PARAMETERS:  Mutex           - Mutex to wait on
 *              Timeout         - Max time to wait
 *
 * RETURN:      Status
 *
B
Bob Moore 已提交
106 107 108
 * DESCRIPTION: Implements a mutex wait with a check to see if the
 *              mutex is available immediately.  If it is not, the
 *              interpreter is released before waiting.
B
Bob Moore 已提交
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
 *
 ******************************************************************************/

acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout)
{
	acpi_status status;

	ACPI_FUNCTION_TRACE(ex_system_wait_mutex);

	status = acpi_os_acquire_mutex(mutex, ACPI_DO_NOT_WAIT);
	if (ACPI_SUCCESS(status)) {
		return_ACPI_STATUS(status);
	}

	if (status == AE_TIME) {

		/* We must wait, so unlock the interpreter */

127
		acpi_ex_relinquish_interpreter();
B
Bob Moore 已提交
128 129 130 131 132 133 134 135 136

		status = acpi_os_acquire_mutex(mutex, timeout);

		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
				  "*** Thread awake after blocking, %s\n",
				  acpi_format_exception(status)));

		/* Reacquire the interpreter */

137
		acpi_ex_reacquire_interpreter();
B
Bob Moore 已提交
138 139 140 141 142
	}

	return_ACPI_STATUS(status);
}

L
Linus Torvalds 已提交
143 144 145 146
/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_do_stall
 *
R
Robert Moore 已提交
147 148
 * PARAMETERS:  how_long        - The amount of time to stall,
 *                                in microseconds
L
Linus Torvalds 已提交
149 150 151 152 153 154 155 156 157 158 159
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Suspend running thread for specified amount of time.
 *              Note: ACPI specification requires that Stall() does not
 *              relinquish the processor, and delays longer than 100 usec
 *              should use Sleep() instead.  We allow stalls up to 255 usec
 *              for compatibility with other interpreters and existing BIOSs.
 *
 ******************************************************************************/

L
Len Brown 已提交
160
acpi_status acpi_ex_system_do_stall(u32 how_long)
L
Linus Torvalds 已提交
161
{
L
Len Brown 已提交
162
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
163

L
Len Brown 已提交
164
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
165

L
Len Brown 已提交
166
	if (how_long > 255) {	/* 255 microseconds */
L
Linus Torvalds 已提交
167 168 169 170 171 172
		/*
		 * Longer than 255 usec, this is an error
		 *
		 * (ACPI specifies 100 usec as max, but this gives some slack in
		 * order to support existing BIOSs)
		 */
173
		ACPI_ERROR((AE_INFO, "Time parameter is too large (%u)",
B
Bob Moore 已提交
174
			    how_long));
L
Linus Torvalds 已提交
175
		status = AE_AML_OPERAND_VALUE;
L
Len Brown 已提交
176 177
	} else {
		acpi_os_stall(how_long);
L
Linus Torvalds 已提交
178 179 180 181 182 183 184 185 186
	}

	return (status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_do_suspend
 *
R
Robert Moore 已提交
187 188
 * PARAMETERS:  how_long        - The amount of time to suspend,
 *                                in milliseconds
L
Linus Torvalds 已提交
189 190 191 192 193 194 195
 *
 * RETURN:      None
 *
 * DESCRIPTION: Suspend running thread for specified amount of time.
 *
 ******************************************************************************/

196
acpi_status acpi_ex_system_do_suspend(u64 how_long)
L
Linus Torvalds 已提交
197
{
L
Len Brown 已提交
198
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
199 200 201

	/* Since this thread will sleep, we must release the interpreter */

202
	acpi_ex_relinquish_interpreter();
L
Linus Torvalds 已提交
203

L
Len Brown 已提交
204
	acpi_os_sleep(how_long);
L
Linus Torvalds 已提交
205 206 207

	/* And now we must get the interpreter again */

208 209
	acpi_ex_reacquire_interpreter();
	return (AE_OK);
L
Linus Torvalds 已提交
210 211 212 213 214 215
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_signal_event
 *
R
Robert Moore 已提交
216
 * PARAMETERS:  obj_desc        - The object descriptor for this op
L
Linus Torvalds 已提交
217
 *
R
Robert Moore 已提交
218
 * RETURN:      Status
L
Linus Torvalds 已提交
219 220 221 222 223 224
 *
 * DESCRIPTION: Provides an access point to perform synchronization operations
 *              within the AML.
 *
 ******************************************************************************/

225
acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc)
L
Linus Torvalds 已提交
226
{
L
Len Brown 已提交
227
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
228

B
Bob Moore 已提交
229
	ACPI_FUNCTION_TRACE(ex_system_signal_event);
L
Linus Torvalds 已提交
230 231

	if (obj_desc) {
B
Bob Moore 已提交
232 233
		status =
		    acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1);
L
Linus Torvalds 已提交
234 235
	}

L
Len Brown 已提交
236
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
237 238 239 240 241 242
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_wait_event
 *
R
Robert Moore 已提交
243 244
 * PARAMETERS:  time_desc       - The 'time to delay' object descriptor
 *              obj_desc        - The object descriptor for this op
L
Linus Torvalds 已提交
245 246 247 248 249 250 251 252 253 254
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Provides an access point to perform synchronization operations
 *              within the AML.  This operation is a request to wait for an
 *              event.
 *
 ******************************************************************************/

acpi_status
L
Len Brown 已提交
255 256
acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
			  union acpi_operand_object *obj_desc)
L
Linus Torvalds 已提交
257
{
L
Len Brown 已提交
258
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
259

B
Bob Moore 已提交
260
	ACPI_FUNCTION_TRACE(ex_system_wait_event);
L
Linus Torvalds 已提交
261 262

	if (obj_desc) {
L
Len Brown 已提交
263
		status =
B
Bob Moore 已提交
264
		    acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore,
L
Len Brown 已提交
265 266
						  (u16) time_desc->integer.
						  value);
L
Linus Torvalds 已提交
267 268
	}

L
Len Brown 已提交
269
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
270 271 272 273 274 275
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_reset_event
 *
R
Robert Moore 已提交
276
 * PARAMETERS:  obj_desc        - The object descriptor for this op
L
Linus Torvalds 已提交
277 278 279 280 281 282 283
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Reset an event to a known state.
 *
 ******************************************************************************/

L
Len Brown 已提交
284
acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc)
L
Linus Torvalds 已提交
285
{
L
Len Brown 已提交
286
	acpi_status status = AE_OK;
B
Bob Moore 已提交
287
	acpi_semaphore temp_semaphore;
L
Linus Torvalds 已提交
288

L
Len Brown 已提交
289
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
290 291 292 293 294

	/*
	 * We are going to simply delete the existing semaphore and
	 * create a new one!
	 */
L
Len Brown 已提交
295 296 297
	status =
	    acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
	if (ACPI_SUCCESS(status)) {
B
Bob Moore 已提交
298 299
		(void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore);
		obj_desc->event.os_semaphore = temp_semaphore;
L
Linus Torvalds 已提交
300 301 302 303
	}

	return (status);
}