at v2.6.28 302 lines 9.1 kB view raw
1 2/****************************************************************************** 3 * 4 * Module Name: exsystem - Interface to OS services 5 * 6 *****************************************************************************/ 7 8/* 9 * Copyright (C) 2000 - 2008, Intel Corp. 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 48#define _COMPONENT ACPI_EXECUTER 49ACPI_MODULE_NAME("exsystem") 50 51/******************************************************************************* 52 * 53 * FUNCTION: acpi_ex_system_wait_semaphore 54 * 55 * PARAMETERS: Semaphore - Semaphore to wait on 56 * Timeout - Max time to wait 57 * 58 * RETURN: Status 59 * 60 * DESCRIPTION: Implements a semaphore wait with a check to see if the 61 * semaphore is available immediately. If it is not, the 62 * interpreter is released before waiting. 63 * 64 ******************************************************************************/ 65acpi_status acpi_ex_system_wait_semaphore(acpi_semaphore semaphore, u16 timeout) 66{ 67 acpi_status status; 68 69 ACPI_FUNCTION_TRACE(ex_system_wait_semaphore); 70 71 status = acpi_os_wait_semaphore(semaphore, 1, ACPI_DO_NOT_WAIT); 72 if (ACPI_SUCCESS(status)) { 73 return_ACPI_STATUS(status); 74 } 75 76 if (status == AE_TIME) { 77 78 /* We must wait, so unlock the interpreter */ 79 80 acpi_ex_relinquish_interpreter(); 81 82 status = acpi_os_wait_semaphore(semaphore, 1, timeout); 83 84 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 85 "*** Thread awake after blocking, %s\n", 86 acpi_format_exception(status))); 87 88 /* Reacquire the interpreter */ 89 90 acpi_ex_reacquire_interpreter(); 91 } 92 93 return_ACPI_STATUS(status); 94} 95 96/******************************************************************************* 97 * 98 * FUNCTION: acpi_ex_system_wait_mutex 99 * 100 * PARAMETERS: Mutex - Mutex to wait on 101 * Timeout - Max time to wait 102 * 103 * RETURN: Status 104 * 105 * DESCRIPTION: Implements a mutex wait with a check to see if the 106 * mutex is available immediately. If it is not, the 107 * interpreter is released before waiting. 108 * 109 ******************************************************************************/ 110 111acpi_status acpi_ex_system_wait_mutex(acpi_mutex mutex, u16 timeout) 112{ 113 acpi_status status; 114 115 ACPI_FUNCTION_TRACE(ex_system_wait_mutex); 116 117 status = acpi_os_acquire_mutex(mutex, ACPI_DO_NOT_WAIT); 118 if (ACPI_SUCCESS(status)) { 119 return_ACPI_STATUS(status); 120 } 121 122 if (status == AE_TIME) { 123 124 /* We must wait, so unlock the interpreter */ 125 126 acpi_ex_relinquish_interpreter(); 127 128 status = acpi_os_acquire_mutex(mutex, timeout); 129 130 ACPI_DEBUG_PRINT((ACPI_DB_EXEC, 131 "*** Thread awake after blocking, %s\n", 132 acpi_format_exception(status))); 133 134 /* Reacquire the interpreter */ 135 136 acpi_ex_reacquire_interpreter(); 137 } 138 139 return_ACPI_STATUS(status); 140} 141 142/******************************************************************************* 143 * 144 * FUNCTION: acpi_ex_system_do_stall 145 * 146 * PARAMETERS: how_long - The amount of time to stall, 147 * in microseconds 148 * 149 * RETURN: Status 150 * 151 * DESCRIPTION: Suspend running thread for specified amount of time. 152 * Note: ACPI specification requires that Stall() does not 153 * relinquish the processor, and delays longer than 100 usec 154 * should use Sleep() instead. We allow stalls up to 255 usec 155 * for compatibility with other interpreters and existing BIOSs. 156 * 157 ******************************************************************************/ 158 159acpi_status acpi_ex_system_do_stall(u32 how_long) 160{ 161 acpi_status status = AE_OK; 162 163 ACPI_FUNCTION_ENTRY(); 164 165 if (how_long > 255) { /* 255 microseconds */ 166 /* 167 * Longer than 255 usec, this is an error 168 * 169 * (ACPI specifies 100 usec as max, but this gives some slack in 170 * order to support existing BIOSs) 171 */ 172 ACPI_ERROR((AE_INFO, "Time parameter is too large (%d)", 173 how_long)); 174 status = AE_AML_OPERAND_VALUE; 175 } else { 176 acpi_os_stall(how_long); 177 } 178 179 return (status); 180} 181 182/******************************************************************************* 183 * 184 * FUNCTION: acpi_ex_system_do_suspend 185 * 186 * PARAMETERS: how_long - The amount of time to suspend, 187 * in milliseconds 188 * 189 * RETURN: None 190 * 191 * DESCRIPTION: Suspend running thread for specified amount of time. 192 * 193 ******************************************************************************/ 194 195acpi_status acpi_ex_system_do_suspend(acpi_integer how_long) 196{ 197 ACPI_FUNCTION_ENTRY(); 198 199 /* Since this thread will sleep, we must release the interpreter */ 200 201 acpi_ex_relinquish_interpreter(); 202 203 acpi_os_sleep(how_long); 204 205 /* And now we must get the interpreter again */ 206 207 acpi_ex_reacquire_interpreter(); 208 return (AE_OK); 209} 210 211/******************************************************************************* 212 * 213 * FUNCTION: acpi_ex_system_signal_event 214 * 215 * PARAMETERS: obj_desc - The object descriptor for this op 216 * 217 * RETURN: Status 218 * 219 * DESCRIPTION: Provides an access point to perform synchronization operations 220 * within the AML. 221 * 222 ******************************************************************************/ 223 224acpi_status acpi_ex_system_signal_event(union acpi_operand_object * obj_desc) 225{ 226 acpi_status status = AE_OK; 227 228 ACPI_FUNCTION_TRACE(ex_system_signal_event); 229 230 if (obj_desc) { 231 status = 232 acpi_os_signal_semaphore(obj_desc->event.os_semaphore, 1); 233 } 234 235 return_ACPI_STATUS(status); 236} 237 238/******************************************************************************* 239 * 240 * FUNCTION: acpi_ex_system_wait_event 241 * 242 * PARAMETERS: time_desc - The 'time to delay' object descriptor 243 * obj_desc - The object descriptor for this op 244 * 245 * RETURN: Status 246 * 247 * DESCRIPTION: Provides an access point to perform synchronization operations 248 * within the AML. This operation is a request to wait for an 249 * event. 250 * 251 ******************************************************************************/ 252 253acpi_status 254acpi_ex_system_wait_event(union acpi_operand_object *time_desc, 255 union acpi_operand_object *obj_desc) 256{ 257 acpi_status status = AE_OK; 258 259 ACPI_FUNCTION_TRACE(ex_system_wait_event); 260 261 if (obj_desc) { 262 status = 263 acpi_ex_system_wait_semaphore(obj_desc->event.os_semaphore, 264 (u16) time_desc->integer. 265 value); 266 } 267 268 return_ACPI_STATUS(status); 269} 270 271/******************************************************************************* 272 * 273 * FUNCTION: acpi_ex_system_reset_event 274 * 275 * PARAMETERS: obj_desc - The object descriptor for this op 276 * 277 * RETURN: Status 278 * 279 * DESCRIPTION: Reset an event to a known state. 280 * 281 ******************************************************************************/ 282 283acpi_status acpi_ex_system_reset_event(union acpi_operand_object *obj_desc) 284{ 285 acpi_status status = AE_OK; 286 acpi_semaphore temp_semaphore; 287 288 ACPI_FUNCTION_ENTRY(); 289 290 /* 291 * We are going to simply delete the existing semaphore and 292 * create a new one! 293 */ 294 status = 295 acpi_os_create_semaphore(ACPI_NO_UNIT_LIMIT, 0, &temp_semaphore); 296 if (ACPI_SUCCESS(status)) { 297 (void)acpi_os_delete_semaphore(obj_desc->event.os_semaphore); 298 obj_desc->event.os_semaphore = temp_semaphore; 299 } 300 301 return (status); 302}