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

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

/*
B
Bob Moore 已提交
9
 * Copyright (C) 2000 - 2006, R. Byron Moore
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 46 47 48 49
 * 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>
#include <acpi/acinterp.h>
#include <acpi/acevents.h>

#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 63 64 65
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Implements a semaphore wait with a check to see if the
 *              semaphore is available immediately.  If it is not, the
 *              interpreter is released.
 *
 ******************************************************************************/
L
Len Brown 已提交
66
acpi_status acpi_ex_system_wait_semaphore(acpi_handle semaphore, u16 timeout)
L
Linus Torvalds 已提交
67
{
L
Len Brown 已提交
68 69
	acpi_status status;
	acpi_status status2;
L
Linus Torvalds 已提交
70

L
Len Brown 已提交
71
	ACPI_FUNCTION_TRACE("ex_system_wait_semaphore");
L
Linus Torvalds 已提交
72

L
Len Brown 已提交
73 74 75
	status = acpi_os_wait_semaphore(semaphore, 1, 0);
	if (ACPI_SUCCESS(status)) {
		return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
76 77 78 79 80
	}

	if (status == AE_TIME) {
		/* We must wait, so unlock the interpreter */

L
Len Brown 已提交
81
		acpi_ex_exit_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 */

L
Len Brown 已提交
91 92
		status2 = acpi_ex_enter_interpreter();
		if (ACPI_FAILURE(status2)) {
L
Linus Torvalds 已提交
93 94
			/* Report fatal error, could not acquire interpreter */

L
Len Brown 已提交
95
			return_ACPI_STATUS(status2);
L
Linus Torvalds 已提交
96 97 98
		}
	}

L
Len Brown 已提交
99
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
100 101 102 103 104 105
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_do_stall
 *
R
Robert Moore 已提交
106 107
 * PARAMETERS:  how_long        - The amount of time to stall,
 *                                in microseconds
L
Linus Torvalds 已提交
108 109 110 111 112 113 114 115 116 117 118
 *
 * 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 已提交
119
acpi_status acpi_ex_system_do_stall(u32 how_long)
L
Linus Torvalds 已提交
120
{
L
Len Brown 已提交
121
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
122

L
Len Brown 已提交
123
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
124

L
Len Brown 已提交
125
	if (how_long > 255) {	/* 255 microseconds */
L
Linus Torvalds 已提交
126 127 128 129 130 131
		/*
		 * 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)
		 */
B
Bob Moore 已提交
132 133
		ACPI_ERROR((AE_INFO, "Time parameter is too large (%d)",
			    how_long));
L
Linus Torvalds 已提交
134
		status = AE_AML_OPERAND_VALUE;
L
Len Brown 已提交
135 136
	} else {
		acpi_os_stall(how_long);
L
Linus Torvalds 已提交
137 138 139 140 141 142 143 144 145
	}

	return (status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_do_suspend
 *
R
Robert Moore 已提交
146 147
 * PARAMETERS:  how_long        - The amount of time to suspend,
 *                                in milliseconds
L
Linus Torvalds 已提交
148 149 150 151 152 153 154
 *
 * RETURN:      None
 *
 * DESCRIPTION: Suspend running thread for specified amount of time.
 *
 ******************************************************************************/

L
Len Brown 已提交
155
acpi_status acpi_ex_system_do_suspend(acpi_integer how_long)
L
Linus Torvalds 已提交
156
{
L
Len Brown 已提交
157
	acpi_status status;
L
Linus Torvalds 已提交
158

L
Len Brown 已提交
159
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
160 161 162

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

L
Len Brown 已提交
163
	acpi_ex_exit_interpreter();
L
Linus Torvalds 已提交
164

L
Len Brown 已提交
165
	acpi_os_sleep(how_long);
L
Linus Torvalds 已提交
166 167 168

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

L
Len Brown 已提交
169
	status = acpi_ex_enter_interpreter();
L
Linus Torvalds 已提交
170 171 172 173 174 175 176
	return (status);
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_acquire_mutex
 *
R
Robert Moore 已提交
177 178
 * PARAMETERS:  time_desc       - The 'time to delay' object descriptor
 *              obj_desc        - The object descriptor for this op
L
Linus Torvalds 已提交
179 180 181 182 183 184 185 186 187 188
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Provides an access point to perform synchronization operations
 *              within the AML.  This function will cause a lock to be generated
 *              for the Mutex pointed to by obj_desc.
 *
 ******************************************************************************/

acpi_status
L
Len Brown 已提交
189 190
acpi_ex_system_acquire_mutex(union acpi_operand_object * time_desc,
			     union acpi_operand_object * obj_desc)
L
Linus Torvalds 已提交
191
{
L
Len Brown 已提交
192
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
193

L
Len Brown 已提交
194
	ACPI_FUNCTION_TRACE_PTR("ex_system_acquire_mutex", obj_desc);
L
Linus Torvalds 已提交
195 196

	if (!obj_desc) {
L
Len Brown 已提交
197
		return_ACPI_STATUS(AE_BAD_PARAMETER);
L
Linus Torvalds 已提交
198 199
	}

R
Robert Moore 已提交
200 201
	/* Support for the _GL_ Mutex object -- go get the global lock */

L
Linus Torvalds 已提交
202
	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
L
Len Brown 已提交
203 204 205
		status =
		    acpi_ev_acquire_global_lock((u16) time_desc->integer.value);
		return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
206 207
	}

L
Len Brown 已提交
208 209 210
	status = acpi_ex_system_wait_semaphore(obj_desc->mutex.semaphore,
					       (u16) time_desc->integer.value);
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
211 212 213 214 215 216
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_release_mutex
 *
R
Robert Moore 已提交
217
 * PARAMETERS:  obj_desc        - The object descriptor for this op
L
Linus Torvalds 已提交
218 219 220 221 222 223 224 225 226 227
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Provides an access point to perform synchronization operations
 *              within the AML.  This operation is a request to release a
 *              previously acquired Mutex.  If the Mutex variable is set then
 *              it will be decremented.
 *
 ******************************************************************************/

L
Len Brown 已提交
228
acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc)
L
Linus Torvalds 已提交
229
{
L
Len Brown 已提交
230
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
231

L
Len Brown 已提交
232
	ACPI_FUNCTION_TRACE("ex_system_release_mutex");
L
Linus Torvalds 已提交
233 234

	if (!obj_desc) {
L
Len Brown 已提交
235
		return_ACPI_STATUS(AE_BAD_PARAMETER);
L
Linus Torvalds 已提交
236 237
	}

R
Robert Moore 已提交
238 239
	/* Support for the _GL_ Mutex object -- release the global lock */

L
Linus Torvalds 已提交
240
	if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) {
L
Len Brown 已提交
241 242
		status = acpi_ev_release_global_lock();
		return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
243 244
	}

L
Len Brown 已提交
245 246
	status = acpi_os_signal_semaphore(obj_desc->mutex.semaphore, 1);
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
247 248 249 250 251 252
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_signal_event
 *
R
Robert Moore 已提交
253
 * PARAMETERS:  obj_desc        - The object descriptor for this op
L
Linus Torvalds 已提交
254
 *
R
Robert Moore 已提交
255
 * RETURN:      Status
L
Linus Torvalds 已提交
256 257 258 259 260 261
 *
 * DESCRIPTION: Provides an access point to perform synchronization operations
 *              within the AML.
 *
 ******************************************************************************/

L
Len Brown 已提交
262
acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc)
L
Linus Torvalds 已提交
263
{
L
Len Brown 已提交
264
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
265

L
Len Brown 已提交
266
	ACPI_FUNCTION_TRACE("ex_system_signal_event");
L
Linus Torvalds 已提交
267 268

	if (obj_desc) {
L
Len Brown 已提交
269
		status = acpi_os_signal_semaphore(obj_desc->event.semaphore, 1);
L
Linus Torvalds 已提交
270 271
	}

L
Len Brown 已提交
272
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
273 274 275 276 277 278
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_wait_event
 *
R
Robert Moore 已提交
279 280
 * PARAMETERS:  time_desc       - The 'time to delay' object descriptor
 *              obj_desc        - The object descriptor for this op
L
Linus Torvalds 已提交
281 282 283 284 285 286 287 288 289 290
 *
 * 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 已提交
291 292
acpi_ex_system_wait_event(union acpi_operand_object *time_desc,
			  union acpi_operand_object *obj_desc)
L
Linus Torvalds 已提交
293
{
L
Len Brown 已提交
294
	acpi_status status = AE_OK;
L
Linus Torvalds 已提交
295

L
Len Brown 已提交
296
	ACPI_FUNCTION_TRACE("ex_system_wait_event");
L
Linus Torvalds 已提交
297 298

	if (obj_desc) {
L
Len Brown 已提交
299 300 301 302
		status =
		    acpi_ex_system_wait_semaphore(obj_desc->event.semaphore,
						  (u16) time_desc->integer.
						  value);
L
Linus Torvalds 已提交
303 304
	}

L
Len Brown 已提交
305
	return_ACPI_STATUS(status);
L
Linus Torvalds 已提交
306 307 308 309 310 311
}

/*******************************************************************************
 *
 * FUNCTION:    acpi_ex_system_reset_event
 *
R
Robert Moore 已提交
312
 * PARAMETERS:  obj_desc        - The object descriptor for this op
L
Linus Torvalds 已提交
313 314 315 316 317 318 319
 *
 * RETURN:      Status
 *
 * DESCRIPTION: Reset an event to a known state.
 *
 ******************************************************************************/

L
Len Brown 已提交
320
acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc)
L
Linus Torvalds 已提交
321
{
L
Len Brown 已提交
322 323
	acpi_status status = AE_OK;
	void *temp_semaphore;
L
Linus Torvalds 已提交
324

L
Len Brown 已提交
325
	ACPI_FUNCTION_ENTRY();
L
Linus Torvalds 已提交
326 327 328 329 330

	/*
	 * We are going to simply delete the existing semaphore and
	 * create a new one!
	 */
L
Len Brown 已提交
331 332 333 334
	status =
	    acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore);
	if (ACPI_SUCCESS(status)) {
		(void)acpi_os_delete_semaphore(obj_desc->event.semaphore);
L
Linus Torvalds 已提交
335 336 337 338 339
		obj_desc->event.semaphore = temp_semaphore;
	}

	return (status);
}