Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenutils.c
Go to the documentation of this file.
00001 /* 00002 * acpi_utils.c - ACPI Utility Functions ($Revision: 10 $) 00003 * 00004 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 00005 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 00006 * 00007 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or (at 00012 * your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, but 00015 * WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License along 00020 * with this program; if not, write to the Free Software Foundation, Inc., 00021 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00022 * 00023 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00024 */ 00025 00026 #include <ntddk.h> 00027 00028 #include <acpi.h> 00029 #include <acpi_bus.h> 00030 #include <acpi_drivers.h> 00031 #include <glue.h> 00032 00033 #define NDEBUG 00034 #include <debug.h> 00035 00036 /* Modified for ReactOS and latest ACPICA 00037 * Copyright (C)2009 Samuel Serapion 00038 */ 00039 00040 #define _COMPONENT ACPI_BUS_COMPONENT 00041 ACPI_MODULE_NAME ("acpi_utils") 00042 00043 static void 00044 acpi_util_eval_error(ACPI_HANDLE h, ACPI_STRING p, ACPI_STATUS s) 00045 { 00046 #ifdef ACPI_DEBUG_OUTPUT 00047 char prefix[80] = {'\0'}; 00048 ACPI_BUFFER buffer = {sizeof(prefix), prefix}; 00049 AcpiGetName(h, ACPI_FULL_PATHNAME, &buffer); 00050 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n", 00051 (char *) prefix, p, AcpiFormatException(s))); 00052 #else 00053 return; 00054 #endif 00055 } 00056 00057 00058 /* -------------------------------------------------------------------------- 00059 Object Evaluation Helpers 00060 -------------------------------------------------------------------------- */ 00061 00062 00063 ACPI_STATUS 00064 acpi_extract_package ( 00065 ACPI_OBJECT *package, 00066 ACPI_BUFFER *format, 00067 ACPI_BUFFER *buffer) 00068 { 00069 UINT32 size_required = 0; 00070 UINT32 tail_offset = 0; 00071 char *format_string = NULL; 00072 UINT32 format_count = 0; 00073 UINT32 i = 0; 00074 UINT8 *head = NULL; 00075 UINT8 *tail = NULL; 00076 00077 if (!package || (package->Type != ACPI_TYPE_PACKAGE) || (package->Package.Count < 1)) { 00078 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'package' argument\n")); 00079 return_ACPI_STATUS(AE_BAD_PARAMETER); 00080 } 00081 00082 if (!format || !format->Pointer || (format->Length < 1)) { 00083 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'format' argument\n")); 00084 return_ACPI_STATUS(AE_BAD_PARAMETER); 00085 } 00086 00087 if (!buffer) { 00088 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'buffer' argument\n")); 00089 return_ACPI_STATUS(AE_BAD_PARAMETER); 00090 } 00091 00092 format_count = (format->Length/sizeof(char)) - 1; 00093 if (format_count > package->Package.Count) { 00094 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Format specifies more objects [%d] than exist in package [%d].", format_count, package->package.count)); 00095 return_ACPI_STATUS(AE_BAD_DATA); 00096 } 00097 00098 format_string = format->Pointer; 00099 00100 /* 00101 * Calculate size_required. 00102 */ 00103 for (i=0; i<format_count; i++) { 00104 00105 ACPI_OBJECT *element = &(package->Package.Elements[i]); 00106 00107 if (!element) { 00108 return_ACPI_STATUS(AE_BAD_DATA); 00109 } 00110 00111 switch (element->Type) { 00112 00113 case ACPI_TYPE_INTEGER: 00114 switch (format_string[i]) { 00115 case 'N': 00116 size_required += sizeof(ACPI_INTEGER); 00117 tail_offset += sizeof(ACPI_INTEGER); 00118 break; 00119 case 'S': 00120 size_required += sizeof(char*) + sizeof(ACPI_INTEGER) + sizeof(char); 00121 tail_offset += sizeof(char*); 00122 break; 00123 default: 00124 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d]: got number, expecing [%c].\n", i, format_string[i])); 00125 return_ACPI_STATUS(AE_BAD_DATA); 00126 break; 00127 } 00128 break; 00129 00130 case ACPI_TYPE_STRING: 00131 case ACPI_TYPE_BUFFER: 00132 switch (format_string[i]) { 00133 case 'S': 00134 size_required += sizeof(char*) + (element->String.Length * sizeof(char)) + sizeof(char); 00135 tail_offset += sizeof(char*); 00136 break; 00137 case 'B': 00138 size_required += sizeof(UINT8*) + (element->Buffer.Length * sizeof(UINT8)); 00139 tail_offset += sizeof(UINT8*); 00140 break; 00141 default: 00142 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d] got string/buffer, expecing [%c].\n", i, format_string[i])); 00143 return_ACPI_STATUS(AE_BAD_DATA); 00144 break; 00145 } 00146 break; 00147 00148 case ACPI_TYPE_PACKAGE: 00149 default: 00150 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unsupported element at index=%d\n", i)); 00151 /* TBD: handle nested packages... */ 00152 return_ACPI_STATUS(AE_SUPPORT); 00153 break; 00154 } 00155 } 00156 00157 /* 00158 * Validate output buffer. 00159 */ 00160 if (buffer->Length < size_required) { 00161 buffer->Length = size_required; 00162 return_ACPI_STATUS(AE_BUFFER_OVERFLOW); 00163 } 00164 else if (buffer->Length != size_required || !buffer->Pointer) { 00165 return_ACPI_STATUS(AE_BAD_PARAMETER); 00166 } 00167 00168 head = buffer->Pointer; 00169 tail = ((PUCHAR)buffer->Pointer) + tail_offset; 00170 00171 /* 00172 * Extract package data. 00173 */ 00174 for (i=0; i<format_count; i++) { 00175 00176 UINT8 **pointer = NULL; 00177 ACPI_OBJECT *element = &(package->Package.Elements[i]); 00178 00179 if (!element) { 00180 return_ACPI_STATUS(AE_BAD_DATA); 00181 } 00182 00183 switch (element->Type) { 00184 00185 case ACPI_TYPE_INTEGER: 00186 switch (format_string[i]) { 00187 case 'N': 00188 *((ACPI_INTEGER*)head) = element->Integer.Value; 00189 head += sizeof(ACPI_INTEGER); 00190 break; 00191 case 'S': 00192 pointer = (UINT8**)head; 00193 *pointer = tail; 00194 *((ACPI_INTEGER*)tail) = element->Integer.Value; 00195 head += sizeof(ACPI_INTEGER*); 00196 tail += sizeof(ACPI_INTEGER); 00197 /* NULL terminate string */ 00198 *tail = (char)0; 00199 tail += sizeof(char); 00200 break; 00201 default: 00202 /* Should never get here */ 00203 break; 00204 } 00205 break; 00206 00207 case ACPI_TYPE_STRING: 00208 case ACPI_TYPE_BUFFER: 00209 switch (format_string[i]) { 00210 case 'S': 00211 pointer = (UINT8**)head; 00212 *pointer = tail; 00213 memcpy(tail, element->String.Pointer, element->String.Length); 00214 head += sizeof(char*); 00215 tail += element->String.Length * sizeof(char); 00216 /* NULL terminate string */ 00217 *tail = (char)0; 00218 tail += sizeof(char); 00219 break; 00220 case 'B': 00221 pointer = (UINT8**)head; 00222 *pointer = tail; 00223 memcpy(tail, element->Buffer.Pointer, element->Buffer.Length); 00224 head += sizeof(UINT8*); 00225 tail += element->Buffer.Length * sizeof(UINT8); 00226 break; 00227 default: 00228 /* Should never get here */ 00229 break; 00230 } 00231 break; 00232 00233 case ACPI_TYPE_PACKAGE: 00234 /* TBD: handle nested packages... */ 00235 default: 00236 /* Should never get here */ 00237 break; 00238 } 00239 } 00240 00241 return_ACPI_STATUS(AE_OK); 00242 } 00243 00244 00245 ACPI_STATUS 00246 acpi_evaluate_integer ( 00247 ACPI_HANDLE handle, 00248 ACPI_STRING pathname, 00249 ACPI_OBJECT_LIST *arguments, 00250 unsigned long long *data) 00251 { 00252 ACPI_STATUS status = AE_OK; 00253 ACPI_OBJECT element; 00254 ACPI_BUFFER buffer = {sizeof(ACPI_OBJECT), &element}; 00255 00256 ACPI_FUNCTION_TRACE("acpi_evaluate_integer"); 00257 00258 if (!data) 00259 return_ACPI_STATUS(AE_BAD_PARAMETER); 00260 00261 status = AcpiEvaluateObject(handle, pathname, arguments, &buffer); 00262 if (ACPI_FAILURE(status)) { 00263 acpi_util_eval_error(handle, pathname, status); 00264 return_ACPI_STATUS(status); 00265 } 00266 00267 if (element.Type != ACPI_TYPE_INTEGER) { 00268 acpi_util_eval_error(handle, pathname, AE_BAD_DATA); 00269 return_ACPI_STATUS(AE_BAD_DATA); 00270 } 00271 00272 *data = element.Integer.Value; 00273 00274 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%lu]\n", *data)); 00275 00276 return_ACPI_STATUS(AE_OK); 00277 } 00278 00279 00280 ACPI_STATUS 00281 acpi_evaluate_reference ( 00282 ACPI_HANDLE handle, 00283 ACPI_STRING pathname, 00284 ACPI_OBJECT_LIST *arguments, 00285 struct acpi_handle_list *list) 00286 { 00287 ACPI_STATUS status = AE_OK; 00288 ACPI_OBJECT *package = NULL; 00289 ACPI_OBJECT *element = NULL; 00290 ACPI_BUFFER buffer = {ACPI_ALLOCATE_BUFFER, NULL}; 00291 UINT32 i = 0; 00292 00293 ACPI_FUNCTION_TRACE("acpi_evaluate_reference"); 00294 00295 if (!list) { 00296 return_ACPI_STATUS(AE_BAD_PARAMETER); 00297 } 00298 00299 /* Evaluate object. */ 00300 00301 status = AcpiEvaluateObject(handle, pathname, arguments, &buffer); 00302 if (ACPI_FAILURE(status)) 00303 goto end; 00304 00305 package = (ACPI_OBJECT *) buffer.Pointer; 00306 00307 if ((buffer.Length == 0) || !package) { 00308 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 00309 "No return object (len %X ptr %p)\n", 00310 buffer.Length, package)); 00311 status = AE_BAD_DATA; 00312 acpi_util_eval_error(handle, pathname, status); 00313 goto end; 00314 } 00315 if (package->Type != ACPI_TYPE_PACKAGE) { 00316 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 00317 "Expecting a [Package], found type %X\n", 00318 package->Type)); 00319 status = AE_BAD_DATA; 00320 acpi_util_eval_error(handle, pathname, status); 00321 goto end; 00322 } 00323 if (!package->Package.Count) { 00324 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 00325 "[Package] has zero elements (%p)\n", 00326 package)); 00327 status = AE_BAD_DATA; 00328 acpi_util_eval_error(handle, pathname, status); 00329 goto end; 00330 } 00331 00332 if (package->Package.Count > ACPI_MAX_HANDLES) { 00333 return AE_NO_MEMORY; 00334 } 00335 list->count = package->Package.Count; 00336 00337 /* Extract package data. */ 00338 00339 for (i = 0; i < list->count; i++) { 00340 00341 element = &(package->Package.Elements[i]); 00342 00343 if (element->Type != ACPI_TYPE_LOCAL_REFERENCE) { 00344 status = AE_BAD_DATA; 00345 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 00346 "Expecting a [Reference] package element, found type %X\n", 00347 element->type)); 00348 acpi_util_eval_error(handle, pathname, status); 00349 break; 00350 } 00351 00352 if (!element->Reference.Handle) { 00353 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid reference in" 00354 " package %s\n", pathname)); 00355 status = AE_NULL_ENTRY; 00356 break; 00357 } 00358 /* Get the ACPI_HANDLE. */ 00359 00360 list->handles[i] = element->Reference.Handle; 00361 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]\n", 00362 list->handles[i])); 00363 } 00364 00365 end: 00366 if (ACPI_FAILURE(status)) { 00367 list->count = 0; 00368 //ExFreePool(list->handles); 00369 } 00370 00371 if (buffer.Pointer) 00372 AcpiOsFree(buffer.Pointer); 00373 00374 return_ACPI_STATUS(status); 00375 } 00376 00377 Generated on Thu May 24 2012 04:22:31 for ReactOS by
1.7.6.1
|