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