at v2.6.16 339 lines 10 kB view raw
1 2/****************************************************************************** 3 * 4 * Module Name: exsystem - Interface to OS services 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2006, 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. 64 * 65 ******************************************************************************/ 66acpi_status acpi_ex_system_wait_semaphore(acpi_handle 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, 0); 74 if (ACPI_SUCCESS(status)) { 75 return_ACPI_STATUS(status); 76 } 77 78 if (status == AE_TIME) { 79 /* We must wait, so unlock the interpreter */ 80 81 acpi_ex_exit_interpreter(); 82 83 status = acpi_os_wait_semaphore(semaphore, 1, timeout); 84 85 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 86 "*** Thread awake after blocking, %s\n", 87 acpi_format_exception(status))); 88 89 /* Reacquire the interpreter */ 90 91 status2 = acpi_ex_enter_interpreter(); 92 if (ACPI_FAILURE(status2)) { 93 /* Report fatal error, could not acquire interpreter */ 94 95 return_ACPI_STATUS(status2); 96 } 97 } 98 99 return_ACPI_STATUS(status); 100} 101 102/******************************************************************************* 103 * 104 * FUNCTION: acpi_ex_system_do_stall 105 * 106 * PARAMETERS: how_long - The amount of time to stall, 107 * in microseconds 108 * 109 * RETURN: Status 110 * 111 * DESCRIPTION: Suspend running thread for specified amount of time. 112 * Note: ACPI specification requires that Stall() does not 113 * relinquish the processor, and delays longer than 100 usec 114 * should use Sleep() instead. We allow stalls up to 255 usec 115 * for compatibility with other interpreters and existing BIOSs. 116 * 117 ******************************************************************************/ 118 119acpi_status acpi_ex_system_do_stall(u32 how_long) 120{ 121 acpi_status status = AE_OK; 122 123 ACPI_FUNCTION_ENTRY(); 124 125 if (how_long > 255) { /* 255 microseconds */ 126 /* 127 * Longer than 255 usec, this is an error 128 * 129 * (ACPI specifies 100 usec as max, but this gives some slack in 130 * order to support existing BIOSs) 131 */ 132 ACPI_ERROR((AE_INFO, "Time parameter is too large (%d)", 133 how_long)); 134 status = AE_AML_OPERAND_VALUE; 135 } else { 136 acpi_os_stall(how_long); 137 } 138 139 return (status); 140} 141 142/******************************************************************************* 143 * 144 * FUNCTION: acpi_ex_system_do_suspend 145 * 146 * PARAMETERS: how_long - The amount of time to suspend, 147 * in milliseconds 148 * 149 * RETURN: None 150 * 151 * DESCRIPTION: Suspend running thread for specified amount of time. 152 * 153 ******************************************************************************/ 154 155acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) 156{ 157 acpi_status status; 158 159 ACPI_FUNCTION_ENTRY(); 160 161 /* Since this thread will sleep, we must release the interpreter */ 162 163 acpi_ex_exit_interpreter(); 164 165 acpi_os_sleep(how_long); 166 167 /* And now we must get the interpreter again */ 168 169 status = acpi_ex_enter_interpreter(); 170 return (status); 171} 172 173/******************************************************************************* 174 * 175 * FUNCTION: acpi_ex_system_acquire_mutex 176 * 177 * PARAMETERS: time_desc - The 'time to delay' object descriptor 178 * obj_desc - The object descriptor for this op 179 * 180 * RETURN: Status 181 * 182 * DESCRIPTION: Provides an access point to perform synchronization operations 183 * within the AML. This function will cause a lock to be generated 184 * for the Mutex pointed to by obj_desc. 185 * 186 ******************************************************************************/ 187 188acpi_status 189acpi_ex_system_acquire_mutex(union acpi_operand_object * time_desc, 190 union acpi_operand_object * obj_desc) 191{ 192 acpi_status status = AE_OK; 193 194 ACPI_FUNCTION_TRACE_PTR("ex_system_acquire_mutex", obj_desc); 195 196 if (!obj_desc) { 197 return_ACPI_STATUS(AE_BAD_PARAMETER); 198 } 199 200 /* Support for the _GL_ Mutex object -- go get the global lock */ 201 202 if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) { 203 status = 204 acpi_ev_acquire_global_lock((u16) time_desc->integer.value); 205 return_ACPI_STATUS(status); 206 } 207 208 status = acpi_ex_system_wait_semaphore(obj_desc->mutex.semaphore, 209 (u16) time_desc->integer.value); 210 return_ACPI_STATUS(status); 211} 212 213/******************************************************************************* 214 * 215 * FUNCTION: acpi_ex_system_release_mutex 216 * 217 * PARAMETERS: obj_desc - The object descriptor for this op 218 * 219 * RETURN: Status 220 * 221 * DESCRIPTION: Provides an access point to perform synchronization operations 222 * within the AML. This operation is a request to release a 223 * previously acquired Mutex. If the Mutex variable is set then 224 * it will be decremented. 225 * 226 ******************************************************************************/ 227 228acpi_status acpi_ex_system_release_mutex(union acpi_operand_object *obj_desc) 229{ 230 acpi_status status = AE_OK; 231 232 ACPI_FUNCTION_TRACE("ex_system_release_mutex"); 233 234 if (!obj_desc) { 235 return_ACPI_STATUS(AE_BAD_PARAMETER); 236 } 237 238 /* Support for the _GL_ Mutex object -- release the global lock */ 239 240 if (obj_desc->mutex.semaphore == acpi_gbl_global_lock_semaphore) { 241 status = acpi_ev_release_global_lock(); 242 return_ACPI_STATUS(status); 243 } 244 245 status = acpi_os_signal_semaphore(obj_desc->mutex.semaphore, 1); 246 return_ACPI_STATUS(status); 247} 248 249/******************************************************************************* 250 * 251 * FUNCTION: acpi_ex_system_signal_event 252 * 253 * PARAMETERS: obj_desc - The object descriptor for this op 254 * 255 * RETURN: Status 256 * 257 * DESCRIPTION: Provides an access point to perform synchronization operations 258 * within the AML. 259 * 260 ******************************************************************************/ 261 262acpi_status acpi_ex_system_signal_event(union acpi_operand_object *obj_desc) 263{ 264 acpi_status status = AE_OK; 265 266 ACPI_FUNCTION_TRACE("ex_system_signal_event"); 267 268 if (obj_desc) { 269 status = acpi_os_signal_semaphore(obj_desc->event.semaphore, 1); 270 } 271 272 return_ACPI_STATUS(status); 273} 274 275/******************************************************************************* 276 * 277 * FUNCTION: acpi_ex_system_wait_event 278 * 279 * PARAMETERS: time_desc - The 'time to delay' object descriptor 280 * obj_desc - The object descriptor for this op 281 * 282 * RETURN: Status 283 * 284 * DESCRIPTION: Provides an access point to perform synchronization operations 285 * within the AML. This operation is a request to wait for an 286 * event. 287 * 288 ******************************************************************************/ 289 290acpi_status 291acpi_ex_system_wait_event(union acpi_operand_object *time_desc, 292 union acpi_operand_object *obj_desc) 293{ 294 acpi_status status = AE_OK; 295 296 ACPI_FUNCTION_TRACE("ex_system_wait_event"); 297 298 if (obj_desc) { 299 status = 300 acpi_ex_system_wait_semaphore(obj_desc->event.semaphore, 301 (u16) time_desc->integer. 302 value); 303 } 304 305 return_ACPI_STATUS(status); 306} 307 308/******************************************************************************* 309 * 310 * FUNCTION: acpi_ex_system_reset_event 311 * 312 * PARAMETERS: obj_desc - The object descriptor for this op 313 * 314 * RETURN: Status 315 * 316 * DESCRIPTION: Reset an event to a known state. 317 * 318 ******************************************************************************/ 319 320acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc) 321{ 322 acpi_status status = AE_OK; 323 void *temp_semaphore; 324 325 ACPI_FUNCTION_ENTRY(); 326 327 /* 328 * We are going to simply delete the existing semaphore and 329 * create a new one! 330 */ 331 status = 332 acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore); 333 if (ACPI_SUCCESS(status)) { 334 (void)acpi_os_delete_semaphore(obj_desc->event.semaphore); 335 obj_desc->event.semaphore = temp_semaphore; 336 } 337 338 return (status); 339}