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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  *
  3.  * Module Name: bmutils.c
  4.  *   $Revision: 43 $
  5.  *
  6.  *****************************************************************************/
  7. /*
  8.  *  Copyright (C) 2000, 2001 Andrew Grover
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  23.  */
  24. #include <acpi.h>
  25. #include "bm.h"
  26. #define _COMPONENT ACPI_BUS
  27. MODULE_NAME ("bmutils")
  28. #ifdef ACPI_DEBUG
  29. #define DEBUG_EVAL_ERROR(l,h,p,s)    bm_print_eval_error(l,h,p,s)
  30. #else
  31. #define DEBUG_EVAL_ERROR(l,h,p,s)
  32. #endif
  33. /****************************************************************************
  34.  *                            External Functions
  35.  ****************************************************************************/
  36. /****************************************************************************
  37.  *
  38.  * FUNCTION:    bm_print_eval_error
  39.  *
  40.  * PARAMETERS:
  41.  *
  42.  * RETURN:
  43.  *
  44.  * DESCRIPTION:
  45.  *
  46.  ****************************************************************************/
  47. void
  48. bm_print_eval_error (
  49. u32                     debug_level,
  50. acpi_handle             handle,
  51. acpi_string             pathname,
  52. acpi_status             status)
  53. {
  54. acpi_buffer buffer;
  55. acpi_status local_status;
  56. PROC_NAME("bm_print_eval_error");
  57. buffer.length = 256;
  58. buffer.pointer = acpi_os_callocate(buffer.length);
  59. if (!buffer.pointer) {
  60. return;
  61. }
  62. local_status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer);
  63. if (ACPI_FAILURE(local_status)) {
  64. ACPI_DEBUG_PRINT((ACPI_DEBUG_LEVEL(debug_level), "Evaluate object [%p], %sn", handle,
  65. acpi_format_exception(status)));
  66. return;
  67. }
  68. if (pathname) {
  69. ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate object [%s.%s], %sn", (char*)buffer.pointer, pathname,
  70. acpi_format_exception(status)));
  71. }
  72. else {
  73. ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Evaluate object [%s], %sn", (char*)buffer.pointer,
  74. acpi_format_exception(status)));
  75. }
  76. acpi_os_free(buffer.pointer);
  77. }
  78. /****************************************************************************
  79.  *
  80.  * FUNCTION:    bm_copy_to_buffer
  81.  *
  82.  * PARAMETERS:
  83.  *
  84.  * RETURN:
  85.  *
  86.  * DESCRIPTION:
  87.  *
  88.  ****************************************************************************/
  89. acpi_status
  90. bm_copy_to_buffer (
  91. acpi_buffer             *buffer,
  92. void                    *data,
  93. u32                     length)
  94. {
  95. FUNCTION_TRACE("bm_copy_to_buffer");
  96. if (!buffer || (!buffer->pointer) || !data || (length == 0)) {
  97. return_ACPI_STATUS(AE_BAD_PARAMETER);
  98. }
  99. if (length > buffer->length) {
  100. buffer->length = length;
  101. return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
  102. }
  103. buffer->length = length;
  104. MEMCPY(buffer->pointer, data, length);
  105. return_ACPI_STATUS(AE_OK);
  106. }
  107. /****************************************************************************
  108.  *
  109.  * FUNCTION:    bm_cast_buffer
  110.  *
  111.  * PARAMETERS:
  112.  *
  113.  * RETURN:
  114.  *
  115.  * DESCRIPTION:
  116.  *
  117.  ****************************************************************************/
  118. acpi_status
  119. bm_cast_buffer (
  120. acpi_buffer             *buffer,
  121. void                    **pointer,
  122. u32                     length)
  123. {
  124. FUNCTION_TRACE("bm_cast_buffer");
  125. if (!buffer || !buffer->pointer || !pointer || length == 0) {
  126. return_ACPI_STATUS(AE_BAD_PARAMETER);
  127. }
  128. if (length > buffer->length) {
  129. return_ACPI_STATUS(AE_BAD_DATA);
  130. }
  131. *pointer = buffer->pointer;
  132. return_ACPI_STATUS(AE_OK);
  133. }
  134. /****************************************************************************
  135.  *
  136.  * FUNCTION:    bm_extract_package_data
  137.  *
  138.  * PARAMETERS:
  139.  *
  140.  * RETURN:
  141.  *
  142.  * DESCRIPTION:
  143.  *
  144.  ****************************************************************************/
  145. acpi_status
  146. bm_extract_package_data (
  147. acpi_object             *package,
  148. acpi_buffer             *format,
  149. acpi_buffer             *buffer)
  150. {
  151. u32                     tail_offset = 0;
  152. u32                     size_required = 0;
  153. char *format_string = NULL;
  154. u32                     format_count = 0;
  155. u32                     i = 0;
  156. u8                      *head = NULL;
  157. u8                      *tail = NULL;
  158. FUNCTION_TRACE("bm_extract_package_data");
  159. if (!package || (package->type != ACPI_TYPE_PACKAGE) || (package->package.count < 1)) {
  160. ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'package' argumentn"));
  161. return_ACPI_STATUS(AE_BAD_PARAMETER);
  162. }
  163. if (!format || !format->pointer || (format->length < 1)) {
  164. ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'format' argumentn"));
  165. return_ACPI_STATUS(AE_BAD_PARAMETER);
  166. }
  167. if (!buffer) {
  168. ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid 'buffer' argumentn"));
  169. return_ACPI_STATUS(AE_BAD_PARAMETER);
  170. }
  171. format_count = (format->length/sizeof(char)) - 1;
  172. if (format_count > package->package.count) {
  173. ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Format specifies more objects [%d] than exist in package [%d].", format_count, package->package.count));
  174. return_ACPI_STATUS(AE_BAD_DATA);
  175. }
  176. format_string = (char*)format->pointer;
  177. /*
  178.  * Calculate size_required.
  179.  */
  180. for (i=0; i<format_count; i++) {
  181. acpi_object *element = &(package->package.elements[i]);
  182. if (!element) {
  183. return_ACPI_STATUS(AE_BAD_DATA);
  184. }
  185. switch (element->type) {
  186. case ACPI_TYPE_INTEGER:
  187. switch (format_string[i]) {
  188. case 'N':
  189. size_required += sizeof(acpi_integer);
  190. tail_offset += sizeof(acpi_integer);
  191. break;
  192. case 'S':
  193. size_required += sizeof(char*) + sizeof(acpi_integer) + sizeof(char);
  194. tail_offset += sizeof(char*);
  195. break;
  196. default:
  197. ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d]: got number, expecing [%c].n", i, format_string[i]));
  198. return_ACPI_STATUS(AE_BAD_DATA);
  199. break;
  200. }
  201. break;
  202. case ACPI_TYPE_STRING:
  203. case ACPI_TYPE_BUFFER:
  204. switch (format_string[i]) {
  205. case 'S':
  206. size_required += sizeof(char*) + (element->string.length * sizeof(char)) + sizeof(char);
  207. tail_offset += sizeof(char*);
  208. break;
  209. case 'B':
  210. size_required += sizeof(u8*) + (element->buffer.length * sizeof(u8));
  211. tail_offset += sizeof(u8*);
  212. break;
  213. default:
  214. ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid package element [%d] got string/buffer, expecing [%c].n", i, format_string[i]));
  215. return_ACPI_STATUS(AE_BAD_DATA);
  216. break;
  217. }
  218. break;
  219. case ACPI_TYPE_PACKAGE:
  220. default:
  221. ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found unsupported element at index=%dn", i));
  222. /* TBD: handle nested packages... */
  223. return_ACPI_STATUS(AE_SUPPORT);
  224. break;
  225. }
  226. }
  227. /* 
  228.  * Validate output buffer. 
  229.  */
  230. if (buffer->length < size_required) {
  231. buffer->length = size_required;
  232. return_ACPI_STATUS(AE_BUFFER_OVERFLOW);
  233. }
  234. else if (buffer->length != size_required || !buffer->pointer) {
  235. return_ACPI_STATUS(AE_BAD_PARAMETER);
  236. }
  237. head = buffer->pointer;
  238. tail = buffer->pointer + tail_offset;
  239. /* 
  240.  * Extract package data.
  241.  */
  242. for (i=0; i<format_count; i++) {
  243. u8 **pointer = NULL;
  244. acpi_object *element = &(package->package.elements[i]);
  245. switch (element->type) {
  246. case ACPI_TYPE_INTEGER:
  247. switch (format_string[i]) {
  248. case 'N':
  249. *((acpi_integer*)head) = element->integer.value;
  250. head += sizeof(acpi_integer);
  251. break;
  252. case 'S':
  253. pointer = (u8**)head;
  254. *pointer = tail;
  255. *((acpi_integer*)tail) = element->integer.value;
  256. head += sizeof(acpi_integer*);
  257. tail += sizeof(acpi_integer);
  258. /* NULL terminate string */
  259. *tail = (char)0;
  260. tail += sizeof(char);
  261. break;
  262. default:
  263. /* Should never get here */
  264. break;
  265. }
  266. break;
  267. case ACPI_TYPE_STRING:
  268. case ACPI_TYPE_BUFFER:
  269. switch (format_string[i]) {
  270. case 'S':
  271. pointer = (u8**)head;
  272. *pointer = tail;
  273. memcpy(tail, element->string.pointer, element->string.length);
  274. head += sizeof(char*);
  275. tail += element->string.length * sizeof(char);
  276. /* NULL terminate string */
  277. *tail = (char)0;
  278. tail += sizeof(char);
  279. break;
  280. case 'B':
  281. pointer = (u8**)head;
  282. *pointer = tail;
  283. memcpy(tail, element->buffer.pointer, element->buffer.length);
  284. head += sizeof(u8*);
  285. tail += element->buffer.length * sizeof(u8);
  286. break;
  287. default:
  288. /* Should never get here */
  289. break;
  290. }
  291. break;
  292. case ACPI_TYPE_PACKAGE:
  293. /* TBD: handle nested packages... */
  294. default:
  295. /* Should never get here */
  296. break;
  297. }
  298. }
  299. return_ACPI_STATUS(AE_OK);
  300. }
  301. /****************************************************************************
  302.  *
  303.  * FUNCTION:    bm_evaluate_object
  304.  *
  305.  * PARAMETERS:
  306.  *
  307.  * RETURN:      AE_OK
  308.  *              AE_BUFFER_OVERFLOW  Evaluated object returned data, but
  309.  *                                  caller did not provide buffer.
  310.  *
  311.  * DESCRIPTION: Helper for acpi_evaluate_object that handles buffer
  312.  *              allocation.  Note that the caller is responsible for
  313.  *              freeing buffer->pointer!
  314.  *
  315.  ****************************************************************************/
  316. acpi_status
  317. bm_evaluate_object (
  318. acpi_handle             handle,
  319. acpi_string             pathname,
  320. acpi_object_list        *arguments,
  321. acpi_buffer             *buffer)
  322. {
  323. acpi_status             status = AE_OK;
  324. FUNCTION_TRACE("bm_evaluate_object");
  325. /* If caller provided a buffer it must be unallocated/zero'd. */
  326. if ((buffer) && (buffer->length != 0 || buffer->pointer)) {
  327. return_ACPI_STATUS(AE_BAD_PARAMETER);
  328. }
  329. /*
  330.  * Evalute Object:
  331.  * ---------------
  332.  * The first attempt is just to get the size of the object data
  333.  * (that is unless there's no return data, e.g. _INI); the second
  334.  * gets the data.
  335.  */
  336. status = acpi_evaluate_object(handle, pathname, arguments, buffer);
  337. if (ACPI_SUCCESS(status)) {
  338. return_ACPI_STATUS(status);
  339. }
  340. else if ((buffer) && (status == AE_BUFFER_OVERFLOW)) {
  341. /* Gotta allocate -- CALLER MUST FREE! */
  342. buffer->pointer = acpi_os_callocate(buffer->length);
  343. if (!buffer->pointer) {
  344. return_ACPI_STATUS(AE_NO_MEMORY);
  345. }
  346. /* Re-evaluate -- this time it should work */
  347. status = acpi_evaluate_object(handle, pathname,
  348. arguments, buffer);
  349. }
  350. if (ACPI_FAILURE(status)) {
  351. if (status != AE_NOT_FOUND) {
  352. DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname,
  353. status);
  354. }
  355. if (buffer && buffer->pointer) {
  356. acpi_os_free(buffer->pointer);
  357. buffer->pointer = NULL;
  358. buffer->length = 0;
  359. }
  360. }
  361. return_ACPI_STATUS(status);
  362. }
  363. /****************************************************************************
  364.  *
  365.  * FUNCTION:    bm_evaluate_simple_integer
  366.  *
  367.  * PARAMETERS:
  368.  *
  369.  * RETURN:
  370.  *
  371.  * DESCRIPTION:
  372.  *
  373.  ****************************************************************************/
  374. acpi_status
  375. bm_evaluate_simple_integer (
  376. acpi_handle             handle,
  377. acpi_string             pathname,
  378. u32                     *data)
  379. {
  380. acpi_status             status = AE_OK;
  381. acpi_object             *element = NULL;
  382. acpi_buffer             buffer;
  383. FUNCTION_TRACE("bm_evaluate_simple_integer");
  384. if (!data) {
  385. return_ACPI_STATUS(AE_BAD_PARAMETER);
  386. }
  387. MEMSET(&buffer, 0, sizeof(acpi_buffer));
  388. /*
  389.  * Evaluate Object:
  390.  * ----------------
  391.  */
  392. status = bm_evaluate_object(handle, pathname, NULL, &buffer);
  393. if (ACPI_FAILURE(status)) {
  394. ACPI_DEBUG_PRINT((ACPI_DB_INFO, "failed to evaluate object (%s)n",
  395. acpi_format_exception(status)));
  396. goto end;
  397. }
  398. /*
  399.  * Validate Data:
  400.  * --------------
  401.  */
  402. status = bm_cast_buffer(&buffer, (void**)&element,
  403. sizeof(acpi_object));
  404. if (ACPI_FAILURE(status)) {
  405. DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status);
  406. goto end;
  407. }
  408. if (element->type != ACPI_TYPE_INTEGER) {
  409. status = AE_BAD_DATA;
  410. DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status);
  411. goto end;
  412. }
  413. *data = element->integer.value;
  414. end:
  415. acpi_os_free(buffer.pointer);
  416. return_ACPI_STATUS(status);
  417. }
  418. /****************************************************************************
  419.  *
  420.  * FUNCTION:    bm_evaluate_reference_list
  421.  *
  422.  * PARAMETERS:
  423.  *
  424.  * RETURN:
  425.  *
  426.  * DESCRIPTION:
  427.  *
  428.  ****************************************************************************/
  429. acpi_status  
  430. bm_evaluate_reference_list (
  431. acpi_handle             handle,
  432. acpi_string             pathname,
  433. BM_HANDLE_LIST          *reference_list)
  434. {
  435. acpi_status             status = AE_OK;
  436. acpi_object             *package = NULL;
  437. acpi_object             *element = NULL;
  438. acpi_handle   reference_handle = NULL;
  439. acpi_buffer             buffer;
  440. u32                     i = 0;
  441. FUNCTION_TRACE("bm_evaluate_reference_list");
  442. if (!reference_list) {
  443. return_ACPI_STATUS(AE_BAD_PARAMETER);
  444. }
  445. MEMSET(&buffer, 0, sizeof(acpi_buffer));
  446. /*
  447.  * Evaluate Object:
  448.  * ----------------
  449.  */
  450. status = bm_evaluate_object(handle, pathname, NULL, &buffer);
  451. if (ACPI_FAILURE(status)) {
  452. goto end;
  453. }
  454. /*
  455.  * Validate Package:
  456.  * -----------------
  457.  */
  458. status = bm_cast_buffer(&buffer, (void**)&package,
  459. sizeof(acpi_object));
  460. if (ACPI_FAILURE(status)) {
  461. DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status);
  462. goto end;
  463. }
  464. if (package->type != ACPI_TYPE_PACKAGE) {
  465. status = AE_BAD_DATA;
  466. DEBUG_EVAL_ERROR(ACPI_LV_WARN, handle, pathname, status);
  467. goto end;
  468. }
  469. if (package->package.count > BM_HANDLES_MAX) {
  470. package->package.count = BM_HANDLES_MAX;
  471. }
  472. /*
  473.  * Parse Package Data:
  474.  * -------------------
  475.  */
  476. for (i = 0; i < package->package.count; i++) {
  477. element = &(package->package.elements[i]);
  478. if (!element || (element->type != ACPI_TYPE_STRING)) {
  479. status = AE_BAD_DATA;
  480. ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Invalid element in package (not a device reference).n"));
  481. DEBUG_EVAL_ERROR (ACPI_LV_WARN, handle, pathname, status);
  482. break;
  483. }
  484. /*
  485.  * Resolve reference string (e.g. "_PR_.CPU_") to an
  486.  * acpi_handle.
  487.  */
  488. status = acpi_get_handle(handle,
  489. element->string.pointer, &reference_handle);
  490. if (ACPI_FAILURE(status)) {
  491. status = AE_BAD_DATA;
  492. ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to resolve device reference [%s].n", element->string.pointer));
  493. DEBUG_EVAL_ERROR (ACPI_LV_WARN, handle, pathname, status);
  494. break;
  495. }
  496. /*
  497.  * Resolve acpi_handle to BM_HANDLE.
  498.  */
  499. status = bm_get_handle(reference_handle,
  500. &(reference_list->handles[i]));
  501. if (ACPI_FAILURE(status)) {
  502. status = AE_BAD_DATA;
  503. ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Unable to resolve device reference for [%p].n", reference_handle));
  504. DEBUG_EVAL_ERROR (ACPI_LV_WARN, handle, pathname, status);
  505. break;
  506. }
  507. ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resolved reference [%s]->[%p]->[%02x]n", element->string.pointer, reference_handle, reference_list->handles[i]));
  508. (reference_list->count)++;
  509. }
  510. end:
  511. acpi_os_free(buffer.pointer);
  512. return_ACPI_STATUS(status);
  513. }