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