tbxface.c revision 82367
1228692Sdes/******************************************************************************
2141098Sdes *
3117610Sdes * Module Name: tbxface - Public interfaces to the ACPI subsystem
4141098Sdes *                         ACPI table oriented interfaces
5228692Sdes *              $Revision: 42 $
6228692Sdes *
7117610Sdes *****************************************************************************/
8117610Sdes
9117610Sdes/******************************************************************************
10117610Sdes *
11117610Sdes * 1. Copyright Notice
12117610Sdes *
13117610Sdes * Some or all of this work - Copyright (c) 1999, 2000, 2001, Intel Corp.
14117610Sdes * All rights reserved.
15117610Sdes *
16117610Sdes * 2. License
17147455Sdes *
18236109Sdes * 2.1. This is your license from Intel Corp. under its intellectual property
19117610Sdes * rights.  You may have additional license terms from the party that provided
20117610Sdes * you this software, covering your right to use that party's intellectual
21228692Sdes * property rights.
22117610Sdes *
23228692Sdes * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
24141098Sdes * copy of the source code appearing in this file ("Covered Code") an
25141098Sdes * irrevocable, perpetual, worldwide license under Intel's copyrights in the
26141098Sdes * base code distributed originally by Intel ("Original Intel Code") to copy,
27141098Sdes * make derivatives, distribute, use and display any portion of the Covered
28117610Sdes * Code in any form, with the right to sublicense such rights; and
29141098Sdes *
30117610Sdes * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
31117610Sdes * license (with the right to sublicense), under only those claims of Intel
32117610Sdes * patents that are infringed by the Original Intel Code, to make, use, sell,
33117610Sdes * offer to sell, and import the Covered Code and derivative works thereof
34117610Sdes * solely to the minimum extent necessary to exercise the above copyright
35117610Sdes * license, and in no event shall the patent license extend to any additions
36117610Sdes * to or modifications of the Original Intel Code.  No other license or right
37117610Sdes * is granted directly or by implication, estoppel or otherwise;
38174832Sdes *
39228692Sdes * The above copyright and patent license is granted only if the following
40141098Sdes * conditions are met:
41141098Sdes *
42236109Sdes * 3. Conditions
43236109Sdes *
44141098Sdes * 3.1. Redistribution of Source with Rights to Further Distribute Source.
45141098Sdes * Redistribution of source code of any substantial portion of the Covered
46141098Sdes * Code or modification with rights to further distribute source must include
47141098Sdes * the above Copyright Notice, the above License, this list of Conditions,
48141098Sdes * and the following Disclaimer and Export Compliance provision.  In addition,
49228692Sdes * Licensee must cause all Covered Code to which Licensee contributes to
50174832Sdes * contain a file documenting the changes Licensee made to create that Covered
51141098Sdes * Code and the date of any change.  Licensee must include in that file the
52236109Sdes * documentation of any changes made by any predecessor Licensee.  Licensee
53228692Sdes * must include a prominent statement that the modification is derived,
54141098Sdes * directly or indirectly, from Original Intel Code.
55141098Sdes *
56141098Sdes * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
57141098Sdes * Redistribution of source code of any substantial portion of the Covered
58228692Sdes * Code or modification without rights to further distribute source must
59228692Sdes * include the following Disclaimer and Export Compliance provision in the
60228692Sdes * documentation and/or other materials provided with distribution.  In
61228692Sdes * addition, Licensee may not authorize further sublicense of source of any
62228692Sdes * portion of the Covered Code, and must include terms to the effect that the
63228692Sdes * license from Licensee to its licensee is limited to the intellectual
64228692Sdes * property embodied in the software Licensee provides to its licensee, and
65228692Sdes * not to intellectual property embodied in modifications its licensee may
66228692Sdes * make.
67228692Sdes *
68141098Sdes * 3.3. Redistribution of Executable. Redistribution in executable form of any
69141098Sdes * substantial portion of the Covered Code or modification must reproduce the
70236109Sdes * above Copyright Notice, and the following Disclaimer and Export Compliance
71141098Sdes * provision in the documentation and/or other materials provided with the
72141098Sdes * distribution.
73141098Sdes *
74141098Sdes * 3.4. Intel retains all right, title, and interest in and to the Original
75228692Sdes * Intel Code.
76228692Sdes *
77228692Sdes * 3.5. Neither the name Intel nor any other trademark owned or controlled by
78228692Sdes * Intel shall be used in advertising or otherwise to promote the sale, use or
79228692Sdes * other dealings in products derived from or relating to the Covered Code
80228692Sdes * without prior written authorization from Intel.
81228692Sdes *
82228692Sdes * 4. Disclaimer and Export Compliance
83228692Sdes *
84228692Sdes * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
85228692Sdes * HERE.  ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
86228692Sdes * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT,  ASSISTANCE,
87228692Sdes * INSTALLATION, TRAINING OR OTHER SERVICES.  INTEL WILL NOT PROVIDE ANY
88228692Sdes * UPDATES, ENHANCEMENTS OR EXTENSIONS.  INTEL SPECIFICALLY DISCLAIMS ANY
89228692Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
90228692Sdes * PARTICULAR PURPOSE.
91228692Sdes *
92228692Sdes * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
93228692Sdes * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
94228692Sdes * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
95228692Sdes * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
96228692Sdes * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
97228692Sdes * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.  THESE LIMITATIONS
98228692Sdes * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
99228692Sdes * LIMITED REMEDY.
100228692Sdes *
101228692Sdes * 4.3. Licensee shall not export, either directly or indirectly, any of this
102228692Sdes * software or system incorporating such software without first obtaining any
103141098Sdes * required license or other approval from the U. S. Department of Commerce or
104141098Sdes * any other agency or department of the United States Government.  In the
105141098Sdes * event Licensee exports any such software from the United States or
106141098Sdes * re-exports any such software from a foreign destination, Licensee shall
107141098Sdes * ensure that the distribution and export/re-export of the software is in
108117610Sdes * compliance with all laws, regulations, orders, or other restrictions of the
109141098Sdes * U.S. Export Administration Regulations. Licensee agrees that neither it nor
110141098Sdes * any of its subsidiaries will export/re-export any technical data, process,
111141098Sdes * software, or service, directly or indirectly, to any country for which the
112141098Sdes * United States government or any agency thereof requires an export license,
113117610Sdes * other governmental approval, or letter of assurance, without first obtaining
114117610Sdes * such license, approval or letter.
115141098Sdes *
116117610Sdes *****************************************************************************/
117141098Sdes
118117610Sdes#define __TBXFACE_C__
119117610Sdes
120141098Sdes#include "acpi.h"
121141098Sdes#include "acnamesp.h"
122117610Sdes#include "acinterp.h"
123228692Sdes#include "actables.h"
124117610Sdes
125228692Sdes
126228692Sdes#define _COMPONENT          ACPI_TABLES
127141098Sdes        MODULE_NAME         ("tbxface")
128141098Sdes
129141098Sdes
130141098Sdes/*******************************************************************************
131117610Sdes *
132228692Sdes * FUNCTION:    AcpiLoadTables
133174832Sdes *
134228692Sdes * PARAMETERS:  None
135141098Sdes *
136141098Sdes * RETURN:      Status
137141098Sdes *
138117610Sdes * DESCRIPTION: This function is called to load the ACPI tables from the
139228692Sdes *              provided RSDT
140141098Sdes *
141141098Sdes ******************************************************************************/
142141098Sdes
143117610SdesACPI_STATUS
144117610SdesAcpiLoadTables (void)
145228692Sdes{
146117610Sdes    ACPI_PHYSICAL_ADDRESS   RsdpPhysicalAddress;
147141098Sdes    ACPI_STATUS             Status;
148141098Sdes    UINT32                  NumberOfTables = 0;
149228692Sdes
150228692Sdes
151228692Sdes    FUNCTION_TRACE ("AcpiLoadTables");
152228692Sdes
153228692Sdes
154117610Sdes    /* Ensure that ACPI has been initialized */
155117610Sdes
156228692Sdes    ACPI_IS_INITIALIZATION_COMPLETE (Status);
157228692Sdes    if (ACPI_FAILURE (Status))
158117610Sdes    {
159141098Sdes        return_ACPI_STATUS (Status);
160141098Sdes    }
161141098Sdes
162141098Sdes
163228692Sdes    /* Get the RSDP */
164141098Sdes
165141098Sdes    Status = AcpiOsGetRootPointer (ACPI_LOGICAL_ADDRESSING,
166117610Sdes                    &RsdpPhysicalAddress);
167174832Sdes    if (ACPI_FAILURE (Status))
168141098Sdes    {
169141098Sdes        REPORT_ERROR (("AcpiLoadTables: Could not get RSDP, %s\n",
170141098Sdes                        AcpiFormatException (Status)));
171117610Sdes        goto ErrorExit;
172228692Sdes    }
173228692Sdes
174228692Sdes    /* Map and validate the RSDP */
175228692Sdes
176228692Sdes    Status = AcpiTbVerifyRsdp (RsdpPhysicalAddress);
177141098Sdes    if (ACPI_FAILURE (Status))
178228692Sdes    {
179117610Sdes        REPORT_ERROR (("AcpiLoadTables: RSDP Failed validation: %s\n",
180141098Sdes                        AcpiFormatException (Status)));
181117610Sdes        goto ErrorExit;
182174832Sdes    }
183174832Sdes
184141098Sdes    /* Get the RSDT via the RSDP */
185141098Sdes
186141098Sdes    Status = AcpiTbGetTableRsdt (&NumberOfTables);
187141098Sdes    if (ACPI_FAILURE (Status))
188141098Sdes    {
189141098Sdes        REPORT_ERROR (("AcpiLoadTables: Could not load RSDT: %s\n",
190228692Sdes                        AcpiFormatException (Status)));
191141098Sdes        goto ErrorExit;
192174832Sdes    }
193174832Sdes
194174832Sdes    /* Now get the rest of the tables */
195141098Sdes
196141098Sdes    Status = AcpiTbGetAllTables (NumberOfTables, NULL);
197141098Sdes    if (ACPI_FAILURE (Status))
198141098Sdes    {
199141098Sdes        REPORT_ERROR (("AcpiLoadTables: Error getting required tables (DSDT/FADT/FACS): %s\n",
200141098Sdes                        AcpiFormatException (Status)));
201174832Sdes        goto ErrorExit;
202141098Sdes    }
203141098Sdes
204117610Sdes    ACPI_DEBUG_PRINT ((ACPI_DB_OK, "ACPI Tables successfully loaded\n"));
205141098Sdes
206141098Sdes
207174832Sdes    /* Load the namespace from the tables */
208141098Sdes
209141098Sdes    Status = AcpiNsLoadNamespace ();
210141098Sdes    if (ACPI_FAILURE (Status))
211141098Sdes    {
212174832Sdes        REPORT_ERROR (("AcpiLoadTables: Could not load namespace: %s\n",
213141098Sdes                        AcpiFormatException (Status)));
214141098Sdes        goto ErrorExit;
215174832Sdes    }
216141098Sdes
217141098Sdes    return_ACPI_STATUS (AE_OK);
218228692Sdes
219141098Sdes
220141098SdesErrorExit:
221228692Sdes    REPORT_ERROR (("AcpiLoadTables: Could not load tables: %s\n",
222228692Sdes                    AcpiFormatException (Status)));
223228692Sdes
224228692Sdes    return_ACPI_STATUS (Status);
225236109Sdes}
226174832Sdes
227174832Sdes
228174832Sdes/*******************************************************************************
229174832Sdes *
230174832Sdes * FUNCTION:    AcpiLoadTable
231174832Sdes *
232174832Sdes * PARAMETERS:  TablePtr        - pointer to a buffer containing the entire
233174832Sdes *                                table to be loaded
234174832Sdes *
235174832Sdes * RETURN:      Status
236117610Sdes *
237117610Sdes * DESCRIPTION: This function is called to load a table from the caller's
238117610Sdes *              buffer.  The buffer must contain an entire ACPI Table including
239117610Sdes *              a valid header.  The header fields will be verified, and if it
240141098Sdes *              is determined that the table is invalid, the call will fail.
241141098Sdes *
242141098Sdes ******************************************************************************/
243141098Sdes
244141098SdesACPI_STATUS
245141098SdesAcpiLoadTable (
246228692Sdes    ACPI_TABLE_HEADER       *TablePtr)
247228692Sdes{
248141098Sdes    ACPI_STATUS             Status;
249141098Sdes    ACPI_TABLE_DESC         TableInfo;
250141098Sdes
251141098Sdes
252228692Sdes    FUNCTION_TRACE ("AcpiLoadTable");
253228692Sdes
254228692Sdes
255141098Sdes    /* Ensure that ACPI has been initialized */
256141098Sdes
257141098Sdes    ACPI_IS_INITIALIZATION_COMPLETE (Status);
258141098Sdes    if (ACPI_FAILURE (Status))
259141098Sdes    {
260141098Sdes        return_ACPI_STATUS (Status);
261141098Sdes    }
262141098Sdes
263141098Sdes    if (!TablePtr)
264141098Sdes    {
265117610Sdes        return_ACPI_STATUS (AE_BAD_PARAMETER);
266141098Sdes    }
267117610Sdes
268141098Sdes    /* Copy the table to a local buffer */
269141098Sdes
270228692Sdes    Status = AcpiTbGetTable (0, TablePtr, &TableInfo);
271141098Sdes    if (ACPI_FAILURE (Status))
272228692Sdes    {
273228692Sdes        return_ACPI_STATUS (Status);
274117610Sdes    }
275141098Sdes
276117610Sdes    /* Install the new table into the local data structures */
277141098Sdes
278228692Sdes    Status = AcpiTbInstallTable (NULL, &TableInfo);
279117610Sdes    if (ACPI_FAILURE (Status))
280141098Sdes    {
281141098Sdes        /* Free table allocated by AcpiTbGetTable */
282141098Sdes
283141098Sdes        AcpiTbDeleteSingleTable (&TableInfo);
284141098Sdes        return_ACPI_STATUS (Status);
285228692Sdes    }
286141098Sdes
287141098Sdes
288117610Sdes    Status = AcpiNsLoadTable (TableInfo.InstalledDesc, AcpiGbl_RootNode);
289117610Sdes    if (ACPI_FAILURE (Status))
290141098Sdes    {
291236109Sdes        /* Uninstall table and free the buffer */
292236109Sdes
293141098Sdes        AcpiTbUninstallTable (TableInfo.InstalledDesc);
294141098Sdes        return_ACPI_STATUS (Status);
295141098Sdes    }
296141098Sdes
297141098Sdes
298141098Sdes    return_ACPI_STATUS (Status);
299141098Sdes}
300141098Sdes
301228692Sdes
302117610Sdes/*******************************************************************************
303117610Sdes *
304117610Sdes * FUNCTION:    AcpiUnloadTable
305117610Sdes *
306117610Sdes * PARAMETERS:  TableType     - Type of table to be unloaded
307117610Sdes *
308117610Sdes * RETURN:      Status
309117610Sdes *
310228692Sdes * DESCRIPTION: This routine is used to force the unload of a table
311174832Sdes *
312174832Sdes ******************************************************************************/
313174832Sdes
314174832SdesACPI_STATUS
315174832SdesAcpiUnloadTable (
316174832Sdes    ACPI_TABLE_TYPE         TableType)
317117610Sdes{
318117610Sdes    ACPI_TABLE_DESC         *ListHead;
319117610Sdes    ACPI_STATUS             Status;
320117610Sdes
321117610Sdes
322117610Sdes    FUNCTION_TRACE ("AcpiUnloadTable");
323117610Sdes
324117610Sdes
325117610Sdes    /* Ensure that ACPI has been initialized */
326117610Sdes
327228692Sdes    ACPI_IS_INITIALIZATION_COMPLETE (Status);
328174832Sdes    if (ACPI_FAILURE (Status))
329117610Sdes    {
330117610Sdes        return_ACPI_STATUS (Status);
331117610Sdes    }
332117610Sdes
333117610Sdes    /* Parameter validation */
334228692Sdes
335228692Sdes    if (TableType > ACPI_TABLE_MAX)
336174832Sdes    {
337174832Sdes        return_ACPI_STATUS (AE_BAD_PARAMETER);
338174832Sdes    }
339174832Sdes
340174832Sdes
341174832Sdes    /* Find all tables of the requested type */
342117610Sdes
343117610Sdes    ListHead = &AcpiGbl_AcpiTables[TableType];
344117610Sdes    do
345117610Sdes    {
346117610Sdes        /*
347117610Sdes         * Delete all namespace entries owned by this table.  Note that these
348117610Sdes         * entries can appear anywhere in the namespace by virtue of the AML
349117610Sdes         * "Scope" operator.  Thus, we need to track ownership by an ID, not
350117610Sdes         * simply a position within the hierarchy
351117610Sdes         */
352117610Sdes        AcpiNsDeleteNamespaceByOwner (ListHead->TableId);
353117610Sdes
354117610Sdes        /* Delete (or unmap) the actual table */
355117610Sdes
356117610Sdes        AcpiTbDeleteAcpiTable (TableType);
357117610Sdes
358117610Sdes    } while (ListHead != &AcpiGbl_AcpiTables[TableType]);
359117610Sdes
360117610Sdes    return_ACPI_STATUS (AE_OK);
361228692Sdes}
362174832Sdes
363117610Sdes
364117610Sdes/*******************************************************************************
365117610Sdes *
366228692Sdes * FUNCTION:    AcpiGetTableHeader
367117610Sdes *
368141098Sdes * PARAMETERS:  TableType       - one of the defined table types
369141098Sdes *              Instance        - the non zero instance of the table, allows
370228692Sdes *                                support for multiple tables of the same type
371141098Sdes *                                see AcpiGbl_AcpiTableFlag
372117610Sdes *              OutTableHeader  - pointer to the ACPI_TABLE_HEADER if successful
373117610Sdes *
374141098Sdes * DESCRIPTION: This function is called to get an ACPI table header.  The caller
375117610Sdes *              supplies an pointer to a data area sufficient to contain an ACPI
376117610Sdes *              ACPI_TABLE_HEADER structure.
377117610Sdes *
378228692Sdes *              The header contains a length field that can be used to determine
379228692Sdes *              the size of the buffer needed to contain the entire table.  This
380141098Sdes *              function is not valid for the RSD PTR table since it does not
381141098Sdes *              have a standard header and is fixed length.
382117610Sdes *
383117610Sdes ******************************************************************************/
384117610Sdes
385228692SdesACPI_STATUS
386117610SdesAcpiGetTableHeader (
387141098Sdes    ACPI_TABLE_TYPE         TableType,
388141098Sdes    UINT32                  Instance,
389141098Sdes    ACPI_TABLE_HEADER       *OutTableHeader)
390141098Sdes{
391141098Sdes    ACPI_TABLE_HEADER       *TblPtr;
392141098Sdes    ACPI_STATUS             Status;
393141098Sdes
394117610Sdes
395117610Sdes    FUNCTION_TRACE ("AcpiGetTableHeader");
396141098Sdes
397228692Sdes
398117610Sdes    /* Ensure that ACPI has been initialized */
399117610Sdes
400141098Sdes    ACPI_IS_INITIALIZATION_COMPLETE (Status);
401117610Sdes    if (ACPI_FAILURE (Status))
402117610Sdes    {
403117610Sdes        return_ACPI_STATUS (Status);
404228692Sdes    }
405228692Sdes
406228692Sdes    if ((Instance == 0)                 ||
407228692Sdes        (TableType == ACPI_TABLE_RSDP)  ||
408141098Sdes        (!OutTableHeader))
409228692Sdes    {
410228692Sdes        return_ACPI_STATUS (AE_BAD_PARAMETER);
411228692Sdes    }
412228692Sdes
413228692Sdes    /* Check the table type and instance */
414228692Sdes
415228692Sdes    if ((TableType > ACPI_TABLE_MAX)    ||
416141098Sdes        (IS_SINGLE_TABLE (AcpiGbl_AcpiTableData[TableType].Flags) &&
417141098Sdes         Instance > 1))
418141098Sdes    {
419141098Sdes        return_ACPI_STATUS (AE_BAD_PARAMETER);
420141098Sdes    }
421141098Sdes
422141098Sdes
423141098Sdes    /* Get a pointer to the entire table */
424228692Sdes
425228692Sdes    Status = AcpiTbGetTablePtr (TableType, Instance, &TblPtr);
426228692Sdes    if (ACPI_FAILURE (Status))
427141098Sdes    {
428228692Sdes        return_ACPI_STATUS (Status);
429117610Sdes    }
430117610Sdes
431141098Sdes    /*
432228692Sdes     * The function will return a NULL pointer if the table is not loaded
433228692Sdes     */
434117610Sdes    if (TblPtr == NULL)
435117610Sdes    {
436141098Sdes        return_ACPI_STATUS (AE_NOT_EXIST);
437117610Sdes    }
438117610Sdes
439141098Sdes    /*
440228692Sdes     * Copy the header to the caller's buffer
441228692Sdes     */
442228692Sdes    MEMCPY ((void *) OutTableHeader, (void *) TblPtr,
443228692Sdes                sizeof (ACPI_TABLE_HEADER));
444228692Sdes
445228692Sdes    return_ACPI_STATUS (Status);
446228692Sdes}
447228692Sdes
448228692Sdes
449228692Sdes/*******************************************************************************
450228692Sdes *
451228692Sdes * FUNCTION:    AcpiGetTable
452228692Sdes *
453141098Sdes * PARAMETERS:  TableType       - one of the defined table types
454117610Sdes *              Instance        - the non zero instance of the table, allows
455228692Sdes *                                support for multiple tables of the same type
456228692Sdes *                                see AcpiGbl_AcpiTableFlag
457228692Sdes *              RetBuffer       - pointer to a structure containing a buffer to
458228692Sdes *                                receive the table
459141098Sdes *
460228692Sdes * RETURN:      Status
461228692Sdes *
462141098Sdes * DESCRIPTION: This function is called to get an ACPI table.  The caller
463228692Sdes *              supplies an OutBuffer large enough to contain the entire ACPI
464117610Sdes *              table.  The caller should call the AcpiGetTableHeader function
465228692Sdes *              first to determine the buffer size needed.  Upon completion
466228692Sdes *              the OutBuffer->Length field will indicate the number of bytes
467117610Sdes *              copied into the OutBuffer->BufPtr buffer.  This table will be
468117610Sdes *              a complete table including the header.
469117610Sdes *
470228692Sdes ******************************************************************************/
471117610Sdes
472141098SdesACPI_STATUS
473228692SdesAcpiGetTable (
474117610Sdes    ACPI_TABLE_TYPE         TableType,
475228692Sdes    UINT32                  Instance,
476228692Sdes    ACPI_BUFFER             *RetBuffer)
477228692Sdes{
478228692Sdes    ACPI_TABLE_HEADER       *TblPtr;
479228692Sdes    ACPI_STATUS             Status;
480228692Sdes    UINT32                  RetBufLen;
481228692Sdes
482228692Sdes
483228692Sdes    FUNCTION_TRACE ("AcpiGetTable");
484228692Sdes
485228692Sdes
486228692Sdes    /* Ensure that ACPI has been initialized */
487228692Sdes
488117610Sdes    ACPI_IS_INITIALIZATION_COMPLETE (Status);
489228692Sdes    if (ACPI_FAILURE (Status))
490228692Sdes    {
491228692Sdes        return_ACPI_STATUS (Status);
492228692Sdes    }
493228692Sdes
494117610Sdes    /*
495117610Sdes     *  If we have a buffer, we must have a length too
496117610Sdes     */
497117610Sdes    if ((Instance == 0)                 ||
498228692Sdes        (!RetBuffer)                    ||
499228692Sdes        ((!RetBuffer->Pointer) && (RetBuffer->Length)))
500228692Sdes    {
501117610Sdes        return_ACPI_STATUS (AE_BAD_PARAMETER);
502117610Sdes    }
503228692Sdes
504228692Sdes    /* Check the table type and instance */
505141098Sdes
506174832Sdes    if ((TableType > ACPI_TABLE_MAX)    ||
507141098Sdes        (IS_SINGLE_TABLE (AcpiGbl_AcpiTableData[TableType].Flags) &&
508117610Sdes         Instance > 1))
509141098Sdes    {
510174832Sdes        return_ACPI_STATUS (AE_BAD_PARAMETER);
511141098Sdes    }
512141098Sdes
513228692Sdes
514228692Sdes    /* Get a pointer to the entire table */
515228692Sdes
516228692Sdes    Status = AcpiTbGetTablePtr (TableType, Instance, &TblPtr);
517228692Sdes    if (ACPI_FAILURE (Status))
518228692Sdes    {
519228692Sdes        return_ACPI_STATUS (Status);
520228692Sdes    }
521141098Sdes
522174832Sdes    /*
523141098Sdes     * AcpiTbGetTablePtr will return a NULL pointer if the
524141098Sdes     * table is not loaded.
525141098Sdes     */
526141098Sdes    if (TblPtr == NULL)
527141098Sdes    {
528141098Sdes        return_ACPI_STATUS (AE_NOT_EXIST);
529141098Sdes    }
530141098Sdes
531141098Sdes    /*
532141098Sdes     * Got a table ptr, assume it's ok and copy it to the user's buffer
533141098Sdes     */
534141098Sdes    if (TableType == ACPI_TABLE_RSDP)
535174832Sdes    {
536141098Sdes        /*
537141098Sdes         *  RSD PTR is the only "table" without a header
538117610Sdes         */
539117610Sdes        RetBufLen = sizeof (RSDP_DESCRIPTOR);
540117610Sdes    }
541117610Sdes    else
542141098Sdes    {
543141098Sdes        RetBufLen = TblPtr->Length;
544228692Sdes    }
545141098Sdes
546228692Sdes    /*
547228692Sdes     * Verify we have space in the caller's buffer for the table
548228692Sdes     */
549228692Sdes    if (RetBuffer->Length < RetBufLen)
550228692Sdes    {
551141098Sdes        RetBuffer->Length = RetBufLen;
552174832Sdes        return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
553141098Sdes    }
554228692Sdes
555141098Sdes    RetBuffer->Length = RetBufLen;
556141098Sdes
557141098Sdes    MEMCPY ((void *) RetBuffer->Pointer, (void *) TblPtr, RetBufLen);
558117610Sdes
559141098Sdes    return_ACPI_STATUS (AE_OK);
560141098Sdes}
561117610Sdes
562228692Sdes
563141098Sdes