tbxface.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:11k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /******************************************************************************
  2.  *
  3.  * Module Name: tbxface - Public interfaces to the ACPI subsystem
  4.  *                         ACPI table oriented interfaces
  5.  *              $Revision: 45 $
  6.  *
  7.  *****************************************************************************/
  8. /*
  9.  *  Copyright (C) 2000, 2001 R. Byron Moore
  10.  *
  11.  *  This program is free software; you can redistribute it and/or modify
  12.  *  it under the terms of the GNU General Public License as published by
  13.  *  the Free Software Foundation; either version 2 of the License, or
  14.  *  (at your option) any later version.
  15.  *
  16.  *  This program is distributed in the hope that it will be useful,
  17.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  *  GNU General Public License for more details.
  20.  *
  21.  *  You should have received a copy of the GNU General Public License
  22.  *  along with this program; if not, write to the Free Software
  23.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  24.  */
  25. #include "acpi.h"
  26. #include "acnamesp.h"
  27. #include "acinterp.h"
  28. #include "actables.h"
  29. #define _COMPONENT          ACPI_TABLES
  30.  MODULE_NAME         ("tbxface")
  31. /*******************************************************************************
  32.  *
  33.  * FUNCTION:    Acpi_load_tables
  34.  *
  35.  * PARAMETERS:  None
  36.  *
  37.  * RETURN:      Status
  38.  *
  39.  * DESCRIPTION: This function is called to load the ACPI tables from the
  40.  *              provided RSDT
  41.  *
  42.  ******************************************************************************/
  43. acpi_status
  44. acpi_load_tables (void)
  45. {
  46. ACPI_PHYSICAL_ADDRESS   rsdp_physical_address;
  47. acpi_status             status;
  48. u32                     number_of_tables = 0;
  49. FUNCTION_TRACE ("Acpi_load_tables");
  50. /* Get the RSDP */
  51. status = acpi_os_get_root_pointer (ACPI_LOGICAL_ADDRESSING,
  52.   &rsdp_physical_address);
  53. if (ACPI_FAILURE (status)) {
  54. REPORT_ERROR (("Acpi_load_tables: Could not get RSDP, %sn",
  55.   acpi_format_exception (status)));
  56. goto error_exit;
  57. }
  58. /* Map and validate the RSDP */
  59. status = acpi_tb_verify_rsdp (rsdp_physical_address);
  60. if (ACPI_FAILURE (status)) {
  61. REPORT_ERROR (("Acpi_load_tables: RSDP Failed validation: %sn",
  62.   acpi_format_exception (status)));
  63. goto error_exit;
  64. }
  65. /* Get the RSDT via the RSDP */
  66. status = acpi_tb_get_table_rsdt (&number_of_tables);
  67. if (ACPI_FAILURE (status)) {
  68. REPORT_ERROR (("Acpi_load_tables: Could not load RSDT: %sn",
  69.   acpi_format_exception (status)));
  70. goto error_exit;
  71. }
  72. /* Now get the rest of the tables */
  73. status = acpi_tb_get_all_tables (number_of_tables, NULL);
  74. if (ACPI_FAILURE (status)) {
  75. REPORT_ERROR (("Acpi_load_tables: Error getting required tables (DSDT/FADT/FACS): %sn",
  76.   acpi_format_exception (status)));
  77. goto error_exit;
  78. }
  79. ACPI_DEBUG_PRINT ((ACPI_DB_OK, "ACPI Tables successfully loadedn"));
  80. /* Load the namespace from the tables */
  81. status = acpi_ns_load_namespace ();
  82. if (ACPI_FAILURE (status)) {
  83. REPORT_ERROR (("Acpi_load_tables: Could not load namespace: %sn",
  84.   acpi_format_exception (status)));
  85. goto error_exit;
  86. }
  87. return_ACPI_STATUS (AE_OK);
  88. error_exit:
  89. REPORT_ERROR (("Acpi_load_tables: Could not load tables: %sn",
  90.   acpi_format_exception (status)));
  91. return_ACPI_STATUS (status);
  92. }
  93. /*******************************************************************************
  94.  *
  95.  * FUNCTION:    Acpi_load_table
  96.  *
  97.  * PARAMETERS:  Table_ptr       - pointer to a buffer containing the entire
  98.  *                                table to be loaded
  99.  *
  100.  * RETURN:      Status
  101.  *
  102.  * DESCRIPTION: This function is called to load a table from the caller's
  103.  *              buffer.  The buffer must contain an entire ACPI Table including
  104.  *              a valid header.  The header fields will be verified, and if it
  105.  *              is determined that the table is invalid, the call will fail.
  106.  *
  107.  ******************************************************************************/
  108. acpi_status
  109. acpi_load_table (
  110. acpi_table_header       *table_ptr)
  111. {
  112. acpi_status             status;
  113. acpi_table_desc         table_info;
  114. FUNCTION_TRACE ("Acpi_load_table");
  115. if (!table_ptr) {
  116. return_ACPI_STATUS (AE_BAD_PARAMETER);
  117. }
  118. /* Copy the table to a local buffer */
  119. status = acpi_tb_get_table (0, table_ptr, &table_info);
  120. if (ACPI_FAILURE (status)) {
  121. return_ACPI_STATUS (status);
  122. }
  123. /* Install the new table into the local data structures */
  124. status = acpi_tb_install_table (NULL, &table_info);
  125. if (ACPI_FAILURE (status)) {
  126. /* Free table allocated by Acpi_tb_get_table */
  127. acpi_tb_delete_single_table (&table_info);
  128. return_ACPI_STATUS (status);
  129. }
  130. status = acpi_ns_load_table (table_info.installed_desc, acpi_gbl_root_node);
  131. if (ACPI_FAILURE (status)) {
  132. /* Uninstall table and free the buffer */
  133. acpi_tb_uninstall_table (table_info.installed_desc);
  134. return_ACPI_STATUS (status);
  135. }
  136. return_ACPI_STATUS (status);
  137. }
  138. /*******************************************************************************
  139.  *
  140.  * FUNCTION:    Acpi_unload_table
  141.  *
  142.  * PARAMETERS:  Table_type    - Type of table to be unloaded
  143.  *
  144.  * RETURN:      Status
  145.  *
  146.  * DESCRIPTION: This routine is used to force the unload of a table
  147.  *
  148.  ******************************************************************************/
  149. acpi_status
  150. acpi_unload_table (
  151. acpi_table_type         table_type)
  152. {
  153. acpi_table_desc         *list_head;
  154. FUNCTION_TRACE ("Acpi_unload_table");
  155. /* Parameter validation */
  156. if (table_type > ACPI_TABLE_MAX) {
  157. return_ACPI_STATUS (AE_BAD_PARAMETER);
  158. }
  159. /* Find all tables of the requested type */
  160. list_head = &acpi_gbl_acpi_tables[table_type];
  161. do {
  162. /*
  163.  * Delete all namespace entries owned by this table.  Note that these
  164.  * entries can appear anywhere in the namespace by virtue of the AML
  165.  * "Scope" operator.  Thus, we need to track ownership by an ID, not
  166.  * simply a position within the hierarchy
  167.  */
  168. acpi_ns_delete_namespace_by_owner (list_head->table_id);
  169. /* Delete (or unmap) the actual table */
  170. acpi_tb_delete_acpi_table (table_type);
  171. } while (list_head != &acpi_gbl_acpi_tables[table_type]);
  172. return_ACPI_STATUS (AE_OK);
  173. }
  174. /*******************************************************************************
  175.  *
  176.  * FUNCTION:    Acpi_get_table_header
  177.  *
  178.  * PARAMETERS:  Table_type      - one of the defined table types
  179.  *              Instance        - the non zero instance of the table, allows
  180.  *                                support for multiple tables of the same type
  181.  *                                see Acpi_gbl_Acpi_table_flag
  182.  *              Out_table_header - pointer to the acpi_table_header if successful
  183.  *
  184.  * DESCRIPTION: This function is called to get an ACPI table header.  The caller
  185.  *              supplies an pointer to a data area sufficient to contain an ACPI
  186.  *              acpi_table_header structure.
  187.  *
  188.  *              The header contains a length field that can be used to determine
  189.  *              the size of the buffer needed to contain the entire table.  This
  190.  *              function is not valid for the RSD PTR table since it does not
  191.  *              have a standard header and is fixed length.
  192.  *
  193.  ******************************************************************************/
  194. acpi_status
  195. acpi_get_table_header (
  196. acpi_table_type         table_type,
  197. u32                     instance,
  198. acpi_table_header       *out_table_header)
  199. {
  200. acpi_table_header       *tbl_ptr;
  201. acpi_status             status;
  202. FUNCTION_TRACE ("Acpi_get_table_header");
  203. if ((instance == 0)                 ||
  204. (table_type == ACPI_TABLE_RSDP) ||
  205. (!out_table_header)) {
  206. return_ACPI_STATUS (AE_BAD_PARAMETER);
  207. }
  208. /* Check the table type and instance */
  209. if ((table_type > ACPI_TABLE_MAX)   ||
  210. (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
  211.  instance > 1)) {
  212. return_ACPI_STATUS (AE_BAD_PARAMETER);
  213. }
  214. /* Get a pointer to the entire table */
  215. status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
  216. if (ACPI_FAILURE (status)) {
  217. return_ACPI_STATUS (status);
  218. }
  219. /*
  220.  * The function will return a NULL pointer if the table is not loaded
  221.  */
  222. if (tbl_ptr == NULL) {
  223. return_ACPI_STATUS (AE_NOT_EXIST);
  224. }
  225. /*
  226.  * Copy the header to the caller's buffer
  227.  */
  228. MEMCPY ((void *) out_table_header, (void *) tbl_ptr,
  229.  sizeof (acpi_table_header));
  230. return_ACPI_STATUS (status);
  231. }
  232. /*******************************************************************************
  233.  *
  234.  * FUNCTION:    Acpi_get_table
  235.  *
  236.  * PARAMETERS:  Table_type      - one of the defined table types
  237.  *              Instance        - the non zero instance of the table, allows
  238.  *                                support for multiple tables of the same type
  239.  *                                see Acpi_gbl_Acpi_table_flag
  240.  *              Ret_buffer      - pointer to a structure containing a buffer to
  241.  *                                receive the table
  242.  *
  243.  * RETURN:      Status
  244.  *
  245.  * DESCRIPTION: This function is called to get an ACPI table.  The caller
  246.  *              supplies an Out_buffer large enough to contain the entire ACPI
  247.  *              table.  The caller should call the Acpi_get_table_header function
  248.  *              first to determine the buffer size needed.  Upon completion
  249.  *              the Out_buffer->Length field will indicate the number of bytes
  250.  *              copied into the Out_buffer->Buf_ptr buffer. This table will be
  251.  *              a complete table including the header.
  252.  *
  253.  ******************************************************************************/
  254. acpi_status
  255. acpi_get_table (
  256. acpi_table_type         table_type,
  257. u32                     instance,
  258. acpi_buffer             *ret_buffer)
  259. {
  260. acpi_table_header       *tbl_ptr;
  261. acpi_status             status;
  262. u32                     ret_buf_len;
  263. FUNCTION_TRACE ("Acpi_get_table");
  264. /*
  265.  *  If we have a buffer, we must have a length too
  266.  */
  267. if ((instance == 0)                 ||
  268. (!ret_buffer)                   ||
  269. ((!ret_buffer->pointer) && (ret_buffer->length))) {
  270. return_ACPI_STATUS (AE_BAD_PARAMETER);
  271. }
  272. /* Check the table type and instance */
  273. if ((table_type > ACPI_TABLE_MAX)   ||
  274. (IS_SINGLE_TABLE (acpi_gbl_acpi_table_data[table_type].flags) &&
  275.  instance > 1)) {
  276. return_ACPI_STATUS (AE_BAD_PARAMETER);
  277. }
  278. /* Get a pointer to the entire table */
  279. status = acpi_tb_get_table_ptr (table_type, instance, &tbl_ptr);
  280. if (ACPI_FAILURE (status)) {
  281. return_ACPI_STATUS (status);
  282. }
  283. /*
  284.  * Acpi_tb_get_table_ptr will return a NULL pointer if the
  285.  * table is not loaded.
  286.  */
  287. if (tbl_ptr == NULL) {
  288. return_ACPI_STATUS (AE_NOT_EXIST);
  289. }
  290. /*
  291.  * Got a table ptr, assume it's ok and copy it to the user's buffer
  292.  */
  293. if (table_type == ACPI_TABLE_RSDP) {
  294. /*
  295.  *  RSD PTR is the only "table" without a header
  296.  */
  297. ret_buf_len = sizeof (RSDP_DESCRIPTOR);
  298. }
  299. else {
  300. ret_buf_len = tbl_ptr->length;
  301. }
  302. /*
  303.  * Verify we have space in the caller's buffer for the table
  304.  */
  305. if (ret_buffer->length < ret_buf_len) {
  306. ret_buffer->length = ret_buf_len;
  307. return_ACPI_STATUS (AE_BUFFER_OVERFLOW);
  308. }
  309. ret_buffer->length = ret_buf_len;
  310. MEMCPY ((void *) ret_buffer->pointer, (void *) tbl_ptr, ret_buf_len);
  311. return_ACPI_STATUS (AE_OK);
  312. }