Merge /spare/repo/linux-2.6/
[linux-2.6] / drivers / acpi / tables / tbget.c
1 /******************************************************************************
2  *
3  * Module Name: tbget - ACPI Table get* routines
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2005, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44
45 #include <acpi/acpi.h>
46 #include <acpi/actables.h>
47
48
49 #define _COMPONENT          ACPI_TABLES
50          ACPI_MODULE_NAME    ("tbget")
51
52 /* Local prototypes */
53
54 static acpi_status
55 acpi_tb_get_this_table (
56         struct acpi_pointer             *address,
57         struct acpi_table_header        *header,
58         struct acpi_table_desc          *table_info);
59
60 static acpi_status
61 acpi_tb_table_override (
62         struct acpi_table_header        *header,
63         struct acpi_table_desc          *table_info);
64
65
66 /*******************************************************************************
67  *
68  * FUNCTION:    acpi_tb_get_table
69  *
70  * PARAMETERS:  Address             - Address of table to retrieve.  Can be
71  *                                    Logical or Physical
72  *              table_info          - Where table info is returned
73  *
74  * RETURN:      None
75  *
76  * DESCRIPTION: Get entire table of unknown size.
77  *
78  ******************************************************************************/
79
80 acpi_status
81 acpi_tb_get_table (
82         struct acpi_pointer             *address,
83         struct acpi_table_desc          *table_info)
84 {
85         acpi_status                     status;
86         struct acpi_table_header        header;
87
88
89         ACPI_FUNCTION_TRACE ("tb_get_table");
90
91
92         /* Get the header in order to get signature and table size */
93
94         status = acpi_tb_get_table_header (address, &header);
95         if (ACPI_FAILURE (status)) {
96                 return_ACPI_STATUS (status);
97         }
98
99         /* Get the entire table */
100
101         status = acpi_tb_get_table_body (address, &header, table_info);
102         if (ACPI_FAILURE (status)) {
103                 ACPI_REPORT_ERROR (("Could not get ACPI table (size %X), %s\n",
104                         header.length, acpi_format_exception (status)));
105                 return_ACPI_STATUS (status);
106         }
107
108         return_ACPI_STATUS (AE_OK);
109 }
110
111
112 /*******************************************************************************
113  *
114  * FUNCTION:    acpi_tb_get_table_header
115  *
116  * PARAMETERS:  Address             - Address of table to retrieve.  Can be
117  *                                    Logical or Physical
118  *              return_header       - Where the table header is returned
119  *
120  * RETURN:      Status
121  *
122  * DESCRIPTION: Get an ACPI table header.  Works in both physical or virtual
123  *              addressing mode.  Works with both physical or logical pointers.
124  *              Table is either copied or mapped, depending on the pointer
125  *              type and mode of the processor.
126  *
127  ******************************************************************************/
128
129 acpi_status
130 acpi_tb_get_table_header (
131         struct acpi_pointer             *address,
132         struct acpi_table_header        *return_header)
133 {
134         acpi_status                     status = AE_OK;
135         struct acpi_table_header        *header = NULL;
136
137
138         ACPI_FUNCTION_TRACE ("tb_get_table_header");
139
140
141         /*
142          * Flags contains the current processor mode (Virtual or Physical
143          * addressing) The pointer_type is either Logical or Physical
144          */
145         switch (address->pointer_type) {
146         case ACPI_PHYSMODE_PHYSPTR:
147         case ACPI_LOGMODE_LOGPTR:
148
149                 /* Pointer matches processor mode, copy the header */
150
151                 ACPI_MEMCPY (return_header, address->pointer.logical,
152                         sizeof (struct acpi_table_header));
153                 break;
154
155
156         case ACPI_LOGMODE_PHYSPTR:
157
158                 /* Create a logical address for the physical pointer*/
159
160                 status = acpi_os_map_memory (address->pointer.physical,
161                                  sizeof (struct acpi_table_header), (void *) &header);
162                 if (ACPI_FAILURE (status)) {
163                         ACPI_REPORT_ERROR ((
164                                 "Could not map memory at %8.8X%8.8X for length %X\n",
165                                 ACPI_FORMAT_UINT64 (address->pointer.physical),
166                                 sizeof (struct acpi_table_header)));
167                         return_ACPI_STATUS (status);
168                 }
169
170                 /* Copy header and delete mapping */
171
172                 ACPI_MEMCPY (return_header, header, sizeof (struct acpi_table_header));
173                 acpi_os_unmap_memory (header, sizeof (struct acpi_table_header));
174                 break;
175
176
177         default:
178
179                 ACPI_REPORT_ERROR (("Invalid address flags %X\n",
180                         address->pointer_type));
181                 return_ACPI_STATUS (AE_BAD_PARAMETER);
182         }
183
184         ACPI_DEBUG_PRINT ((ACPI_DB_TABLES, "Table Signature: [%4.4s]\n",
185                 return_header->signature));
186
187         return_ACPI_STATUS (AE_OK);
188 }
189
190
191 /*******************************************************************************
192  *
193  * FUNCTION:    acpi_tb_get_table_body
194  *
195  * PARAMETERS:  Address             - Address of table to retrieve.  Can be
196  *                                    Logical or Physical
197  *              Header              - Header of the table to retrieve
198  *              table_info          - Where the table info is returned
199  *
200  * RETURN:      Status
201  *
202  * DESCRIPTION: Get an entire ACPI table with support to allow the host OS to
203  *              replace the table with a newer version (table override.)
204  *              Works in both physical or virtual
205  *              addressing mode.  Works with both physical or logical pointers.
206  *              Table is either copied or mapped, depending on the pointer
207  *              type and mode of the processor.
208  *
209  ******************************************************************************/
210
211 acpi_status
212 acpi_tb_get_table_body (
213         struct acpi_pointer             *address,
214         struct acpi_table_header        *header,
215         struct acpi_table_desc          *table_info)
216 {
217         acpi_status                     status;
218
219
220         ACPI_FUNCTION_TRACE ("tb_get_table_body");
221
222
223         if (!table_info || !address) {
224                 return_ACPI_STATUS (AE_BAD_PARAMETER);
225         }
226
227         /* Attempt table override. */
228
229         status = acpi_tb_table_override (header, table_info);
230         if (ACPI_SUCCESS (status)) {
231                 /* Table was overridden by the host OS */
232
233                 return_ACPI_STATUS (status);
234         }
235
236         /* No override, get the original table */
237
238         status = acpi_tb_get_this_table (address, header, table_info);
239         return_ACPI_STATUS (status);
240 }
241
242
243 /*******************************************************************************
244  *
245  * FUNCTION:    acpi_tb_table_override
246  *
247  * PARAMETERS:  Header              - Pointer to table header
248  *              table_info          - Return info if table is overridden
249  *
250  * RETURN:      None
251  *
252  * DESCRIPTION: Attempts override of current table with a new one if provided
253  *              by the host OS.
254  *
255  ******************************************************************************/
256
257 static acpi_status
258 acpi_tb_table_override (
259         struct acpi_table_header        *header,
260         struct acpi_table_desc          *table_info)
261 {
262         struct acpi_table_header        *new_table;
263         acpi_status                     status;
264         struct acpi_pointer             address;
265
266
267         ACPI_FUNCTION_TRACE ("tb_table_override");
268
269
270         /*
271          * The OSL will examine the header and decide whether to override this
272          * table.  If it decides to override, a table will be returned in new_table,
273          * which we will then copy.
274          */
275         status = acpi_os_table_override (header, &new_table);
276         if (ACPI_FAILURE (status)) {
277                 /* Some severe error from the OSL, but we basically ignore it */
278
279                 ACPI_REPORT_ERROR (("Could not override ACPI table, %s\n",
280                         acpi_format_exception (status)));
281                 return_ACPI_STATUS (status);
282         }
283
284         if (!new_table) {
285                 /* No table override */
286
287                 return_ACPI_STATUS (AE_NO_ACPI_TABLES);
288         }
289
290         /*
291          * We have a new table to override the old one.  Get a copy of
292          * the new one.  We know that the new table has a logical pointer.
293          */
294         address.pointer_type    = ACPI_LOGICAL_POINTER | ACPI_LOGICAL_ADDRESSING;
295         address.pointer.logical = new_table;
296
297         status = acpi_tb_get_this_table (&address, new_table, table_info);
298         if (ACPI_FAILURE (status)) {
299                 ACPI_REPORT_ERROR (("Could not copy override ACPI table, %s\n",
300                         acpi_format_exception (status)));
301                 return_ACPI_STATUS (status);
302         }
303
304         /* Copy the table info */
305
306         ACPI_REPORT_INFO (("Table [%4.4s] replaced by host OS\n",
307                 table_info->pointer->signature));
308
309         return_ACPI_STATUS (AE_OK);
310 }
311
312
313 /*******************************************************************************
314  *
315  * FUNCTION:    acpi_tb_get_this_table
316  *
317  * PARAMETERS:  Address             - Address of table to retrieve.  Can be
318  *                                    Logical or Physical
319  *              Header              - Header of the table to retrieve
320  *              table_info          - Where the table info is returned
321  *
322  * RETURN:      Status
323  *
324  * DESCRIPTION: Get an entire ACPI table.  Works in both physical or virtual
325  *              addressing mode.  Works with both physical or logical pointers.
326  *              Table is either copied or mapped, depending on the pointer
327  *              type and mode of the processor.
328  *
329  ******************************************************************************/
330
331 static acpi_status
332 acpi_tb_get_this_table (
333         struct acpi_pointer             *address,
334         struct acpi_table_header        *header,
335         struct acpi_table_desc          *table_info)
336 {
337         struct acpi_table_header        *full_table = NULL;
338         u8                              allocation;
339         acpi_status                     status = AE_OK;
340
341
342         ACPI_FUNCTION_TRACE ("tb_get_this_table");
343
344
345         /*
346          * Flags contains the current processor mode (Virtual or Physical
347          * addressing) The pointer_type is either Logical or Physical
348          */
349         switch (address->pointer_type) {
350         case ACPI_PHYSMODE_PHYSPTR:
351         case ACPI_LOGMODE_LOGPTR:
352
353                 /* Pointer matches processor mode, copy the table to a new buffer */
354
355                 full_table = ACPI_MEM_ALLOCATE (header->length);
356                 if (!full_table) {
357                         ACPI_REPORT_ERROR ((
358                                 "Could not allocate table memory for [%4.4s] length %X\n",
359                                 header->signature, header->length));
360                         return_ACPI_STATUS (AE_NO_MEMORY);
361                 }
362
363                 /* Copy the entire table (including header) to the local buffer */
364
365                 ACPI_MEMCPY (full_table, address->pointer.logical, header->length);
366
367                 /* Save allocation type */
368
369                 allocation = ACPI_MEM_ALLOCATED;
370                 break;
371
372
373         case ACPI_LOGMODE_PHYSPTR:
374
375                 /*
376                  * Just map the table's physical memory
377                  * into our address space.
378                  */
379                 status = acpi_os_map_memory (address->pointer.physical,
380                                  (acpi_size) header->length, (void *) &full_table);
381                 if (ACPI_FAILURE (status)) {
382                         ACPI_REPORT_ERROR ((
383                                 "Could not map memory for table [%4.4s] at %8.8X%8.8X for length %X\n",
384                                 header->signature,
385                                 ACPI_FORMAT_UINT64 (address->pointer.physical),
386                                 header->length));
387                         return (status);
388                 }
389
390                 /* Save allocation type */
391
392                 allocation = ACPI_MEM_MAPPED;
393                 break;
394
395
396         default:
397
398                 ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "Invalid address flags %X\n",
399                         address->pointer_type));
400                 return_ACPI_STATUS (AE_BAD_PARAMETER);
401         }
402
403         /*
404          * Validate checksum for _most_ tables,
405          * even the ones whose signature we don't recognize
406          */
407         if (table_info->type != ACPI_TABLE_FACS) {
408                 status = acpi_tb_verify_table_checksum (full_table);
409
410 #if (!ACPI_CHECKSUM_ABORT)
411                 if (ACPI_FAILURE (status)) {
412                         /* Ignore the error if configuration says so */
413
414                         status = AE_OK;
415                 }
416 #endif
417         }
418
419         /* Return values */
420
421         table_info->pointer     = full_table;
422         table_info->length      = (acpi_size) header->length;
423         table_info->allocation  = allocation;
424
425         ACPI_DEBUG_PRINT ((ACPI_DB_INFO,
426                 "Found table [%4.4s] at %8.8X%8.8X, mapped/copied to %p\n",
427                 full_table->signature,
428                 ACPI_FORMAT_UINT64 (address->pointer.physical), full_table));
429
430         return_ACPI_STATUS (status);
431 }
432
433
434 /*******************************************************************************
435  *
436  * FUNCTION:    acpi_tb_get_table_ptr
437  *
438  * PARAMETERS:  table_type      - one of the defined table types
439  *              Instance        - Which table of this type
440  *              table_ptr_loc   - pointer to location to place the pointer for
441  *                                return
442  *
443  * RETURN:      Status
444  *
445  * DESCRIPTION: This function is called to get the pointer to an ACPI table.
446  *
447  ******************************************************************************/
448
449 acpi_status
450 acpi_tb_get_table_ptr (
451         acpi_table_type                 table_type,
452         u32                             instance,
453         struct acpi_table_header        **table_ptr_loc)
454 {
455         struct acpi_table_desc          *table_desc;
456         u32                             i;
457
458
459         ACPI_FUNCTION_TRACE ("tb_get_table_ptr");
460
461
462         if (!acpi_gbl_DSDT) {
463                 return_ACPI_STATUS (AE_NO_ACPI_TABLES);
464         }
465
466         if (table_type > ACPI_TABLE_MAX) {
467                 return_ACPI_STATUS (AE_BAD_PARAMETER);
468         }
469
470         /*
471          * For all table types (Single/Multiple), the first
472          * instance is always in the list head.
473          */
474         if (instance == 1) {
475                 /* Get the first */
476
477                 *table_ptr_loc = NULL;
478                 if (acpi_gbl_table_lists[table_type].next) {
479                         *table_ptr_loc = acpi_gbl_table_lists[table_type].next->pointer;
480                 }
481                 return_ACPI_STATUS (AE_OK);
482         }
483
484         /* Check for instance out of range */
485
486         if (instance > acpi_gbl_table_lists[table_type].count) {
487                 return_ACPI_STATUS (AE_NOT_EXIST);
488         }
489
490         /* Walk the list to get the desired table
491          * Since the if (Instance == 1) check above checked for the
492          * first table, setting table_desc equal to the .Next member
493          * is actually pointing to the second table.  Therefore, we
494          * need to walk from the 2nd table until we reach the Instance
495          * that the user is looking for and return its table pointer.
496          */
497         table_desc = acpi_gbl_table_lists[table_type].next;
498         for (i = 2; i < instance; i++) {
499                 table_desc = table_desc->next;
500         }
501
502         /* We are now pointing to the requested table's descriptor */
503
504         *table_ptr_loc = table_desc->pointer;
505
506         return_ACPI_STATUS (AE_OK);
507 }
508