at v2.6.21 319 lines 9.5 kB view raw
1 2/****************************************************************************** 3 * 4 * Module Name: exsystem - Interface to OS services 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2007, R. Byron Moore 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions, and the following disclaimer, 17 * without modification. 18 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 19 * substantially similar to the "NO WARRANTY" disclaimer below 20 * ("Disclaimer") and any redistribution must be conditioned upon 21 * including a substantially similar Disclaimer requirement for further 22 * binary redistribution. 23 * 3. Neither the names of the above-listed copyright holders nor the names 24 * of any contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * Alternatively, this software may be distributed under the terms of the 28 * GNU General Public License ("GPL") version 2 as published by the Free 29 * Software Foundation. 30 * 31 * NO WARRANTY 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 35 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 36 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 38 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 39 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 40 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 41 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 42 * POSSIBILITY OF SUCH DAMAGES. 43 */ 44 45#include <acpi/acpi.h> 46#include <acpi/acinterp.h> 47#include <acpi/acevents.h> 48 49#define _COMPONENT ACPI_EXECUTER 50ACPI_MODULE_NAME("exsystem") 51 52/******************************************************************************* 53 * 54 * FUNCTION: acpi_ex_system_wait_semaphore 55 * 56 * PARAMETERS: Semaphore - Semaphore to wait on 57 * Timeout - Max time to wait 58 * 59 * RETURN: Status 60 * 61 * DESCRIPTION: Implements a semaphore wait with a check to see if the 62 * semaphore is available immediately. If it is not, the 63 * interpreter is released before waiting. 64 * 65 ******************************************************************************/ 66acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) 67{ 68 acpi_status status; 69 acpi_status status2; 70 71 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); 72 73 status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT); 74 if (ACPI_SUCCESS(status)) { 75 return_ACPI_STATUS(status); 76 } 77 78 if (status == AE_TIME) { 79 80 /* We must wait, so unlock the interpreter */ 81 82 acpi_ex_exit_interpreter(); 83 84 status = acpi_os_wait_semaphore(semaphore, 1, timeout); 85 86 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 87 "*** Thread awake after blocking, %s\n", 88 acpi_format_exception(status))); 89 90 /* Reacquire the interpreter */ 91 92 status2 = acpi_ex_enter_interpreter(); 93 if (ACPI_FAILURE(status2)) { 94 95 /* Report fatal error, could not acquire interpreter */ 96 97 return_ACPI_STATUS(status2); 98 } 99 } 100 101 return_ACPI_STATUS(status); 102} 103 104/******************************************************************************* 105 * 106 * FUNCTION: acpi_ex_system_wait_mutex 107 * 108 * PARAMETERS: Mutex - Mutex to wait on 109 * Timeout - Max time to wait 110 * 111 * RETURN: Status 112 * 113 * DESCRIPTION: Implements a mutex wait with a check to see if the 114 * mutex is available immediately. If it is not, the 115 * interpreter is released before waiting. 116 * 117 ******************************************************************************/ 118 119acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) 120{ 121 acpi_status status; 122 acpi_status status2; 123 124 ACPI_FUNCTION_TRACE(ex_system_wait_mutex); 125 126 status = acpi_os_acquire_mutex(mutex, ACPI_DO_NOT_WAIT); 127 if (ACPI_SUCCESS(status)) { 128 return_ACPI_STATUS(status); 129 } 130 131 if (status == AE_TIME) { 132 133 /* We must wait, so unlock the interpreter */ 134 135 acpi_ex_exit_interpreter(); 136 137 status = acpi_os_acquire_mutex(mutex, timeout); 138 139 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 140 "*** Thread awake after blocking, %s\n", 141 acpi_format_exception(status))); 142 143 /* Reacquire the interpreter */ 144 145 status2 = acpi_ex_enter_interpreter(); 146 if (ACPI_FAILURE(status2)) { 147 148 /* Report fatal error, could not acquire interpreter */ 149 150 return_ACPI_STATUS(status2); 151 } 152 } 153 154 return_ACPI_STATUS(status); 155} 156 157/******************************************************************************* 158 * 159 * FUNCTION: acpi_ex_system_do_stall 160 * 161 * PARAMETERS: how_long - The amount of time to stall, 162 * in microseconds 163 * 164 * RETURN: Status 165 * 166 * DESCRIPTION: Suspend running thread for specified amount of time. 167 * Note: ACPI specification requires that Stall() does not 168 * relinquish the processor, and delays longer than 100 usec 169 * should use Sleep() instead. We allow stalls up to 255 usec 170 * for compatibility with other interpreters and existing BIOSs. 171 * 172 ******************************************************************************/ 173 174acpi_status acpi_ex_system_do_stall(u32 how_long) 175{ 176 acpi_status status = AE_OK; 177 178 ACPI_FUNCTION_ENTRY(); 179 180 if (how_long > 255) { /* 255 microseconds */ 181 /* 182 * Longer than 255 usec, this is an error 183 * 184 * (ACPI specifies 100 usec as max, but this gives some slack in 185 * order to support existing BIOSs) 186 */ 187 ACPI_ERROR((AE_INFO, "Time parameter is too large (%d)", 188 how_long)); 189 status = AE_AML_OPERAND_VALUE; 190 } else { 191 acpi_os_stall(how_long); 192 } 193 194 return (status); 195} 196 197/******************************************************************************* 198 * 199 * FUNCTION: acpi_ex_system_do_suspend 200 * 201 * PARAMETERS: how_long - The amount of time to suspend, 202 * in milliseconds 203 * 204 * RETURN: None 205 * 206 * DESCRIPTION: Suspend running thread for specified amount of time. 207 * 208 ******************************************************************************/ 209 210acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) 211{ 212 acpi_status status; 213 214 ACPI_FUNCTION_ENTRY(); 215 216 /* Since this thread will sleep, we must release the interpreter */ 217 218 acpi_ex_exit_interpreter(); 219 220 acpi_os_sleep(how_long); 221 222 /* And now we must get the interpreter again */ 223 224 status = acpi_ex_enter_interpreter(); 225 return (status); 226} 227 228/******************************************************************************* 229 * 230 * FUNCTION: acpi_ex_system_signal_event 231 * 232 * PARAMETERS: obj_desc - The object descriptor for this op 233 * 234 * RETURN: Status 235 * 236 * DESCRIPTION: Provides an access point to perform synchronization operations 237 * within the AML. 238 * 239 ******************************************************************************/ 240 241acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc) 242{ 243 acpi_status status = AE_OK; 244 245 ACPI_FUNCTION_TRACE(ex_system_signal_event); 246 247 if (obj_desc) { 248 status = 249 acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1); 250 } 251 252 return_ACPI_STATUS(status); 253} 254 255/******************************************************************************* 256 * 257 * FUNCTION: acpi_ex_system_wait_event 258 * 259 * PARAMETERS: time_desc - The 'time to delay' object descriptor 260 * obj_desc - The object descriptor for this op 261 * 262 * RETURN: Status 263 * 264 * DESCRIPTION: Provides an access point to perform synchronization operations 265 * within the AML. This operation is a request to wait for an 266 * event. 267 * 268 ******************************************************************************/ 269 270acpi_status 271acpi_ex_system_wait_event(union acpi_operand_object *time_desc, 272 union acpi_operand_object *obj_desc) 273{ 274 acpi_status status = AE_OK; 275 276 ACPI_FUNCTION_TRACE(ex_system_wait_event); 277 278 if (obj_desc) { 279 status = 280 acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore, 281 (u16) time_desc->integer. 282 value); 283 } 284 285 return_ACPI_STATUS(status); 286} 287 288/******************************************************************************* 289 * 290 * FUNCTION: acpi_ex_system_reset_event 291 * 292 * PARAMETERS: obj_desc - The object descriptor for this op 293 * 294 * RETURN: Status 295 * 296 * DESCRIPTION: Reset an event to a known state. 297 * 298 ******************************************************************************/ 299 300acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc) 301{ 302 acpi_status status = AE_OK; 303 acpi_semaphore temp_semaphore; 304 305 ACPI_FUNCTION_ENTRY(); 306 307 /* 308 * We are going to simply delete the existing semaphore and 309 * create a new one! 310 */ 311 status = 312 acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore); 313 if (ACPI_SUCCESS(status)) { 314 (void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore); 315 obj_desc->event.os_semaphore = temp_semaphore; 316 } 317 318 return (status); 319}