ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

utils.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.