OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [acpi/] [utils.c] - Blame information for rev 78

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  acpi_utils.c - ACPI Utility Functions ($Revision: 10 $)
3
 *
4
 *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6
 *
7
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or (at
12
 *  your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful, but
15
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 *  General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License along
20
 *  with this program; if not, write to the Free Software Foundation, Inc.,
21
 *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22
 *
23
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24
 */
25
 
26
#include <linux/kernel.h>
27
#include <linux/module.h>
28
#include <linux/init.h>
29
#include <linux/types.h>
30
#include <acpi/acpi_bus.h>
31
#include <acpi/acpi_drivers.h>
32
 
33
#define _COMPONENT              ACPI_BUS_COMPONENT
34
ACPI_MODULE_NAME("utils");
35
 
36
/* --------------------------------------------------------------------------
37
                            Object Evaluation Helpers
38
   -------------------------------------------------------------------------- */
39
#ifdef ACPI_DEBUG_OUTPUT
40
#define acpi_util_eval_error(h,p,s) {\
41
        char prefix[80] = {'\0'};\
42
        struct acpi_buffer buffer = {sizeof(prefix), prefix};\
43
        acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
44
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate [%s.%s]: %s\n",\
45
                (char *) prefix, p, acpi_format_exception(s))); }
46
#else
47
#define acpi_util_eval_error(h,p,s)
48
#endif
49
acpi_status
50
acpi_extract_package(union acpi_object *package,
51
                     struct acpi_buffer *format, struct acpi_buffer *buffer)
52
{
53
        u32 size_required = 0;
54
        u32 tail_offset = 0;
55
        char *format_string = NULL;
56
        u32 format_count = 0;
57
        u32 i = 0;
58
        u8 *head = NULL;
59
        u8 *tail = NULL;
60
 
61
 
62
        if (!package || (package->type != ACPI_TYPE_PACKAGE)
63
            || (package->package.count < 1)) {
64
                printk(KERN_WARNING PREFIX "Invalid package argument\n");
65
                return AE_BAD_PARAMETER;
66
        }
67
 
68
        if (!format || !format->pointer || (format->length < 1)) {
69
                printk(KERN_WARNING PREFIX "Invalid format argument\n");
70
                return AE_BAD_PARAMETER;
71
        }
72
 
73
        if (!buffer) {
74
                printk(KERN_WARNING PREFIX "Invalid buffer argument\n");
75
                return AE_BAD_PARAMETER;
76
        }
77
 
78
        format_count = (format->length / sizeof(char)) - 1;
79
        if (format_count > package->package.count) {
80
                printk(KERN_WARNING PREFIX "Format specifies more objects [%d]"
81
                              " than exist in package [%d].\n",
82
                              format_count, package->package.count);
83
                return AE_BAD_DATA;
84
        }
85
 
86
        format_string = format->pointer;
87
 
88
        /*
89
         * Calculate size_required.
90
         */
91
        for (i = 0; i < format_count; i++) {
92
 
93
                union acpi_object *element = &(package->package.elements[i]);
94
 
95
                if (!element) {
96
                        return AE_BAD_DATA;
97
                }
98
 
99
                switch (element->type) {
100
 
101
                case ACPI_TYPE_INTEGER:
102
                        switch (format_string[i]) {
103
                        case 'N':
104
                                size_required += sizeof(acpi_integer);
105
                                tail_offset += sizeof(acpi_integer);
106
                                break;
107
                        case 'S':
108
                                size_required +=
109
                                    sizeof(char *) + sizeof(acpi_integer) +
110
                                    sizeof(char);
111
                                tail_offset += sizeof(char *);
112
                                break;
113
                        default:
114
                                printk(KERN_WARNING PREFIX "Invalid package element"
115
                                              " [%d]: got number, expecing"
116
                                              " [%c]\n",
117
                                              i, format_string[i]);
118
                                return AE_BAD_DATA;
119
                                break;
120
                        }
121
                        break;
122
 
123
                case ACPI_TYPE_STRING:
124
                case ACPI_TYPE_BUFFER:
125
                        switch (format_string[i]) {
126
                        case 'S':
127
                                size_required +=
128
                                    sizeof(char *) +
129
                                    (element->string.length * sizeof(char)) +
130
                                    sizeof(char);
131
                                tail_offset += sizeof(char *);
132
                                break;
133
                        case 'B':
134
                                size_required +=
135
                                    sizeof(u8 *) +
136
                                    (element->buffer.length * sizeof(u8));
137
                                tail_offset += sizeof(u8 *);
138
                                break;
139
                        default:
140
                                printk(KERN_WARNING PREFIX "Invalid package element"
141
                                              " [%d] got string/buffer,"
142
                                              " expecing [%c]\n",
143
                                              i, format_string[i]);
144
                                return AE_BAD_DATA;
145
                                break;
146
                        }
147
                        break;
148
 
149
                case ACPI_TYPE_PACKAGE:
150
                default:
151
                        ACPI_DEBUG_PRINT((ACPI_DB_INFO,
152
                                          "Found unsupported element at index=%d\n",
153
                                          i));
154
                        /* TBD: handle nested packages... */
155
                        return AE_SUPPORT;
156
                        break;
157
                }
158
        }
159
 
160
        /*
161
         * Validate output buffer.
162
         */
163
        if (buffer->length < size_required) {
164
                buffer->length = size_required;
165
                return AE_BUFFER_OVERFLOW;
166
        } else if (buffer->length != size_required || !buffer->pointer) {
167
                return AE_BAD_PARAMETER;
168
        }
169
 
170
        head = buffer->pointer;
171
        tail = buffer->pointer + tail_offset;
172
 
173
        /*
174
         * Extract package data.
175
         */
176
        for (i = 0; i < format_count; i++) {
177
 
178
                u8 **pointer = NULL;
179
                union acpi_object *element = &(package->package.elements[i]);
180
 
181
                if (!element) {
182
                        return AE_BAD_DATA;
183
                }
184
 
185
                switch (element->type) {
186
 
187
                case ACPI_TYPE_INTEGER:
188
                        switch (format_string[i]) {
189
                        case 'N':
190
                                *((acpi_integer *) head) =
191
                                    element->integer.value;
192
                                head += sizeof(acpi_integer);
193
                                break;
194
                        case 'S':
195
                                pointer = (u8 **) head;
196
                                *pointer = tail;
197
                                *((acpi_integer *) tail) =
198
                                    element->integer.value;
199
                                head += sizeof(acpi_integer *);
200
                                tail += sizeof(acpi_integer);
201
                                /* NULL terminate string */
202
                                *tail = (char)0;
203
                                tail += sizeof(char);
204
                                break;
205
                        default:
206
                                /* Should never get here */
207
                                break;
208
                        }
209
                        break;
210
 
211
                case ACPI_TYPE_STRING:
212
                case ACPI_TYPE_BUFFER:
213
                        switch (format_string[i]) {
214
                        case 'S':
215
                                pointer = (u8 **) head;
216
                                *pointer = tail;
217
                                memcpy(tail, element->string.pointer,
218
                                       element->string.length);
219
                                head += sizeof(char *);
220
                                tail += element->string.length * sizeof(char);
221
                                /* NULL terminate string */
222
                                *tail = (char)0;
223
                                tail += sizeof(char);
224
                                break;
225
                        case 'B':
226
                                pointer = (u8 **) head;
227
                                *pointer = tail;
228
                                memcpy(tail, element->buffer.pointer,
229
                                       element->buffer.length);
230
                                head += sizeof(u8 *);
231
                                tail += element->buffer.length * sizeof(u8);
232
                                break;
233
                        default:
234
                                /* Should never get here */
235
                                break;
236
                        }
237
                        break;
238
 
239
                case ACPI_TYPE_PACKAGE:
240
                        /* TBD: handle nested packages... */
241
                default:
242
                        /* Should never get here */
243
                        break;
244
                }
245
        }
246
 
247
        return AE_OK;
248
}
249
 
250
EXPORT_SYMBOL(acpi_extract_package);
251
 
252
acpi_status
253
acpi_evaluate_integer(acpi_handle handle,
254
                      acpi_string pathname,
255
                      struct acpi_object_list *arguments, unsigned long *data)
256
{
257
        acpi_status status = AE_OK;
258
        union acpi_object *element;
259
        struct acpi_buffer buffer = { 0, NULL };
260
 
261
 
262
        if (!data)
263
                return AE_BAD_PARAMETER;
264
 
265
        element = kzalloc(sizeof(union acpi_object), irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
266
        if (!element)
267
                return AE_NO_MEMORY;
268
 
269
        buffer.length = sizeof(union acpi_object);
270
        buffer.pointer = element;
271
        status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
272
        if (ACPI_FAILURE(status)) {
273
                acpi_util_eval_error(handle, pathname, status);
274
                kfree(element);
275
                return status;
276
        }
277
 
278
        if (element->type != ACPI_TYPE_INTEGER) {
279
                acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
280
                kfree(element);
281
                return AE_BAD_DATA;
282
        }
283
 
284
        *data = element->integer.value;
285
        kfree(element);
286
 
287
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%lu]\n", *data));
288
 
289
        return AE_OK;
290
}
291
 
292
EXPORT_SYMBOL(acpi_evaluate_integer);
293
 
294
#if 0
295
acpi_status
296
acpi_evaluate_string(acpi_handle handle,
297
                     acpi_string pathname,
298
                     acpi_object_list * arguments, acpi_string * data)
299
{
300
        acpi_status status = AE_OK;
301
        acpi_object *element = NULL;
302
        acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
303
 
304
 
305
        if (!data)
306
                return AE_BAD_PARAMETER;
307
 
308
        status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
309
        if (ACPI_FAILURE(status)) {
310
                acpi_util_eval_error(handle, pathname, status);
311
                return status;
312
        }
313
 
314
        element = (acpi_object *) buffer.pointer;
315
 
316
        if ((element->type != ACPI_TYPE_STRING)
317
            || (element->type != ACPI_TYPE_BUFFER)
318
            || !element->string.length) {
319
                acpi_util_eval_error(handle, pathname, AE_BAD_DATA);
320
                return AE_BAD_DATA;
321
        }
322
 
323
        *data = kzalloc(element->string.length + 1, GFP_KERNEL);
324
        if (!data) {
325
                printk(KERN_ERR PREFIX "Memory allocation\n");
326
                return -ENOMEM;
327
        }
328
 
329
        memcpy(*data, element->string.pointer, element->string.length);
330
 
331
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Return value [%s]\n", *data));
332
 
333
        kfree(buffer.pointer);
334
 
335
        return AE_OK;
336
}
337
#endif
338
 
339
acpi_status
340
acpi_evaluate_reference(acpi_handle handle,
341
                        acpi_string pathname,
342
                        struct acpi_object_list *arguments,
343
                        struct acpi_handle_list *list)
344
{
345
        acpi_status status = AE_OK;
346
        union acpi_object *package = NULL;
347
        union acpi_object *element = NULL;
348
        struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
349
        u32 i = 0;
350
 
351
 
352
        if (!list) {
353
                return AE_BAD_PARAMETER;
354
        }
355
 
356
        /* Evaluate object. */
357
 
358
        status = acpi_evaluate_object(handle, pathname, arguments, &buffer);
359
        if (ACPI_FAILURE(status))
360
                goto end;
361
 
362
        package = buffer.pointer;
363
 
364
        if ((buffer.length == 0) || !package) {
365
                printk(KERN_ERR PREFIX "No return object (len %X ptr %p)\n",
366
                            (unsigned)buffer.length, package);
367
                status = AE_BAD_DATA;
368
                acpi_util_eval_error(handle, pathname, status);
369
                goto end;
370
        }
371
        if (package->type != ACPI_TYPE_PACKAGE) {
372
                printk(KERN_ERR PREFIX "Expecting a [Package], found type %X\n",
373
                            package->type);
374
                status = AE_BAD_DATA;
375
                acpi_util_eval_error(handle, pathname, status);
376
                goto end;
377
        }
378
        if (!package->package.count) {
379
                printk(KERN_ERR PREFIX "[Package] has zero elements (%p)\n",
380
                            package);
381
                status = AE_BAD_DATA;
382
                acpi_util_eval_error(handle, pathname, status);
383
                goto end;
384
        }
385
 
386
        if (package->package.count > ACPI_MAX_HANDLES) {
387
                return AE_NO_MEMORY;
388
        }
389
        list->count = package->package.count;
390
 
391
        /* Extract package data. */
392
 
393
        for (i = 0; i < list->count; i++) {
394
 
395
                element = &(package->package.elements[i]);
396
 
397
                if (element->type != ACPI_TYPE_ANY) {
398
                        status = AE_BAD_DATA;
399
                        printk(KERN_ERR PREFIX
400
                                    "Expecting a [Reference] package element, found type %X\n",
401
                                    element->type);
402
                        acpi_util_eval_error(handle, pathname, status);
403
                        break;
404
                }
405
 
406
                /* Get the  acpi_handle. */
407
 
408
                list->handles[i] = element->reference.handle;
409
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found reference [%p]\n",
410
                                  list->handles[i]));
411
        }
412
 
413
      end:
414
        if (ACPI_FAILURE(status)) {
415
                list->count = 0;
416
                //kfree(list->handles);
417
        }
418
 
419
        kfree(buffer.pointer);
420
 
421
        return status;
422
}
423
 
424
EXPORT_SYMBOL(acpi_evaluate_reference);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.