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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  *
  3.  * Module Name: ecmain.c
  4.  *   $Revision: 29 $
  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 "ec.h"
  26. #define _COMPONENT ACPI_EC
  27. MODULE_NAME ("ecmain")
  28. /****************************************************************************
  29.  *                            Internal Functions
  30.  ****************************************************************************/
  31. /****************************************************************************
  32.  *
  33.  * FUNCTION:    ec_print
  34.  *
  35.  * PARAMETERS:
  36.  *
  37.  * RETURN:
  38.  *
  39.  * DESCRIPTION: Prints out information on a specific ec.
  40.  *
  41.  ****************************************************************************/
  42. void
  43. ec_print (
  44. EC_CONTEXT              *ec)
  45. {
  46. #ifdef ACPI_DEBUG
  47. acpi_buffer             buffer;
  48. #endif /*ACPI_DEBUG*/
  49. PROC_NAME("ec_print");
  50. if (!ec) {
  51. return;
  52. }
  53. acpi_os_printf("EC: found, GPE %dn", ec->gpe_bit);
  54. #ifdef ACPI_DEBUG
  55. buffer.length = 256;
  56. buffer.pointer = acpi_os_callocate(buffer.length);
  57. if (!buffer.pointer) {
  58. return;
  59. }
  60. /*
  61.  * Get the full pathname for this ACPI object.
  62.  */
  63. acpi_get_name(ec->acpi_handle, ACPI_FULL_PATHNAME, &buffer);
  64. /*
  65.  * Print out basic thermal zone information.
  66.  */
  67. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------n"));
  68. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "| Embedded_controller[%02x]:[%p] %sn", ec->device_handle, ec->acpi_handle, (char*)buffer.pointer));
  69. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "|   gpe_bit[%02x] status/command_port[%02x] data_port[%02x]n", ec->gpe_bit, ec->status_port, ec->data_port));
  70. ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO, "+------------------------------------------------------------n"));
  71. acpi_os_free(buffer.pointer);
  72. #endif /*ACPI_DEBUG*/
  73. return;
  74. }
  75. /****************************************************************************
  76.  *
  77.  * FUNCTION:    ec_get_port_values
  78.  *
  79.  * PARAMETERS:
  80.  *
  81.  * RETURN:
  82.  *
  83.  * DESCRIPTION: Evaluate _CRS to get the current resources (I/O port
  84.  *              addresses) for this EC.
  85.  *
  86.  ****************************************************************************/
  87. acpi_status
  88. ec_get_port_values(
  89. EC_CONTEXT              *ec)
  90. {
  91. acpi_status             status = AE_OK;
  92. acpi_buffer             buffer;
  93. acpi_resource           *resource = NULL;
  94. FUNCTION_TRACE("ec_get_port_values");
  95. if (!ec) {
  96. return_ACPI_STATUS(AE_BAD_PARAMETER);
  97. }
  98. buffer.length = 0;
  99. buffer.pointer = NULL;
  100. status = acpi_get_current_resources(ec->acpi_handle, &buffer);
  101. if (status != AE_BUFFER_OVERFLOW) {
  102. return_ACPI_STATUS(status);
  103. }
  104. buffer.pointer = acpi_os_callocate(buffer.length);
  105. if (!buffer.pointer) {
  106. return_ACPI_STATUS(AE_NO_MEMORY);
  107. }
  108. status = acpi_get_current_resources(ec->acpi_handle, &buffer);
  109. if (ACPI_FAILURE(status)) {
  110. goto end;
  111. }
  112. resource = (acpi_resource *) buffer.pointer;
  113. ec->data_port = resource->data.io.min_base_address;
  114. resource = NEXT_RESOURCE(resource);
  115. ec->status_port = ec->command_port =
  116. resource->data.io.min_base_address;
  117. end:
  118. acpi_os_free(buffer.pointer);
  119. return_ACPI_STATUS(status);
  120. }
  121. /****************************************************************************
  122.  *
  123.  * FUNCTION:    ec_add_device
  124.  *
  125.  * PARAMETERS:
  126.  *
  127.  * RETURN:
  128.  *
  129.  * DESCRIPTION:
  130.  *
  131.  ****************************************************************************/
  132. acpi_status
  133. ec_add_device(
  134. BM_HANDLE               device_handle,
  135. void                    **context)
  136. {
  137. acpi_status             status = AE_OK;
  138. BM_DEVICE *device = NULL;
  139. EC_CONTEXT              *ec = NULL;
  140. u8                      gpe_handler = FALSE;
  141. u8                      space_handler = FALSE;
  142. FUNCTION_TRACE("ec_add_device");
  143. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Adding EC device [%02x].n", device_handle));
  144. if (!context || *context) {
  145. return_ACPI_STATUS(AE_BAD_PARAMETER);
  146. }
  147. /*
  148.  * Get information on this device.
  149.  */
  150. status = bm_get_device_info(device_handle, &device);
  151. if (ACPI_FAILURE(status)) {
  152. return_ACPI_STATUS(status);
  153. }
  154. /*
  155.  * Allocate a new EC_CONTEXT structure.
  156.  */
  157. ec = acpi_os_callocate(sizeof(EC_CONTEXT));
  158. if (!ec) {
  159. return_ACPI_STATUS(AE_NO_MEMORY);
  160. }
  161. ec->device_handle = device->handle;
  162. ec->acpi_handle = device->acpi_handle;
  163. /*
  164.  * Get the I/O port addresses for the command/status and data ports.
  165.  */
  166. status = ec_get_port_values(ec);
  167. if (ACPI_FAILURE(status)) {
  168. goto end;
  169. }
  170. /*
  171.  * See if we need to obtain the global lock for EC transactions.
  172.  */
  173. status = bm_evaluate_simple_integer(ec->acpi_handle, "_GLK",
  174. &ec->use_global_lock);
  175. if (status == AE_NOT_FOUND) {
  176. ec->use_global_lock = 0;
  177. }
  178. else if (ACPI_FAILURE(status)) {
  179. ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "EC _GLK failedn"));
  180. goto end;
  181. }
  182. /*
  183.  * Install a handler for servicing this EC's GPE.
  184.  */
  185. status = ec_install_gpe_handler(ec);
  186. if (ACPI_FAILURE(status)) {
  187. goto end;
  188. }
  189. else {
  190. gpe_handler = TRUE;
  191. }
  192. /*
  193.  * Install a handler for servicing this EC's address space.
  194.  */
  195. status = ec_install_space_handler(ec);
  196. if (ACPI_FAILURE(status)) {
  197. goto end;
  198. }
  199. else {
  200. space_handler = TRUE;
  201. }
  202. /*
  203.  * Create a semaphore to serialize EC transactions.
  204.  */
  205. status = acpi_os_create_semaphore(1,1, &(ec->mutex));
  206. if (ACPI_FAILURE(status)) {
  207. goto end;
  208. }
  209. /*
  210.  * Context now contains information specific to this EC.  Note
  211.  * that we'll get this pointer back on every ec_request() and
  212.  * ec_notify().
  213.  */
  214. *context = ec;
  215. ec_print(ec);
  216. end:
  217. if (ACPI_FAILURE(status)) {
  218. if (gpe_handler) {
  219. ec_remove_gpe_handler(ec);
  220. }
  221. if (space_handler) {
  222. ec_remove_space_handler(ec);
  223. }
  224. if (ec->mutex) {
  225. acpi_os_delete_semaphore(ec->mutex);
  226. }
  227. acpi_os_free(ec);
  228. }
  229. return_ACPI_STATUS(status);
  230. }
  231. /****************************************************************************
  232.  *
  233.  * FUNCTION:    ec_remove_device
  234.  *
  235.  * PARAMETERS:
  236.  *
  237.  * RETURN:
  238.  *
  239.  * DESCRIPTION:
  240.  *
  241.  ****************************************************************************/
  242. acpi_status
  243. ec_remove_device(
  244. void                    **context)
  245. {
  246. acpi_status             status = AE_OK;
  247. EC_CONTEXT              *ec = NULL;
  248. FUNCTION_TRACE("ec_remove_device");
  249. if (!context || !*context) {
  250. return_ACPI_STATUS(AE_BAD_PARAMETER);
  251. }
  252. ec = (EC_CONTEXT*)*context;
  253. ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Removing EC device [%02x].n", ec->device_handle));
  254. ec_remove_space_handler(ec);
  255. ec_remove_gpe_handler(ec);
  256. if (ec->mutex) {
  257. acpi_os_delete_semaphore(ec->mutex);
  258. }
  259. acpi_os_free(ec);
  260. *context = NULL;
  261. return_ACPI_STATUS(status);
  262. }
  263. /****************************************************************************
  264.  *                             External Functions
  265.  ****************************************************************************/
  266. /****************************************************************************
  267.  *
  268.  * FUNCTION:    ec_initialize
  269.  *
  270.  * PARAMETERS:
  271.  *
  272.  * RETURN:
  273.  *
  274.  * DESCRIPTION:
  275.  *
  276.  ****************************************************************************/
  277. acpi_status
  278. ec_initialize (void)
  279. {
  280. acpi_status             status = AE_OK;
  281. BM_DEVICE_ID criteria;
  282. BM_DRIVER driver;
  283. FUNCTION_TRACE("ec_initialize");
  284. MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
  285. MEMSET(&driver, 0, sizeof(BM_DRIVER));
  286. /*
  287.  * Register driver for AC Adapter devices.
  288.  */
  289. MEMCPY(criteria.hid, EC_HID_EC, sizeof(EC_HID_EC));
  290. driver.notify = &ec_notify;
  291. driver.request = &ec_request;
  292. status = bm_register_driver(&criteria, &driver);
  293. return_ACPI_STATUS(status);
  294. }
  295. /****************************************************************************
  296.  *
  297.  * FUNCTION:    ec_terminate
  298.  *
  299.  * PARAMETERS:
  300.  *
  301.  * RETURN:
  302.  *
  303.  * DESCRIPTION:
  304.  *
  305.  ****************************************************************************/
  306. acpi_status
  307. ec_terminate(void)
  308. {
  309. acpi_status             status = AE_OK;
  310. BM_DEVICE_ID criteria;
  311. BM_DRIVER driver;
  312. FUNCTION_TRACE("ec_terminate");
  313. MEMSET(&criteria, 0, sizeof(BM_DEVICE_ID));
  314. MEMSET(&driver, 0, sizeof(BM_DRIVER));
  315. /*
  316.  * Unregister driver for AC Adapter devices.
  317.  */
  318. MEMCPY(criteria.hid, EC_HID_EC, sizeof(EC_HID_EC));
  319. driver.notify = &ec_notify;
  320. driver.request = &ec_request;
  321. status = bm_unregister_driver(&criteria, &driver);
  322. return_ACPI_STATUS(status);
  323. }
  324. /****************************************************************************
  325.  *
  326.  * FUNCTION:    ec_notify
  327.  *
  328.  * PARAMETERS:
  329.  *
  330.  * RETURN:
  331.  *
  332.  * DESCRIPTION:
  333.  *
  334.  ****************************************************************************/
  335. acpi_status
  336. ec_notify (
  337. BM_NOTIFY               notify,
  338. BM_HANDLE               device_handle,
  339. void                    **context)
  340. {
  341. acpi_status             status = AE_OK;
  342. FUNCTION_TRACE("ec_notify");
  343. switch (notify) {
  344. case BM_NOTIFY_DEVICE_ADDED:
  345. status = ec_add_device(device_handle, context);
  346. break;
  347. case BM_NOTIFY_DEVICE_REMOVED:
  348. status = ec_remove_device(context);
  349. break;
  350. default:
  351. status = AE_SUPPORT;
  352. break;
  353. }
  354. return_ACPI_STATUS(status);
  355. }
  356. /****************************************************************************
  357.  *
  358.  * FUNCTION:    ec_request
  359.  *
  360.  * PARAMETERS:
  361.  *
  362.  * RETURN:
  363.  *
  364.  * DESCRIPTION:
  365.  *
  366.  ****************************************************************************/
  367. acpi_status
  368. ec_request (
  369. BM_REQUEST              *request,
  370. void                    *context)
  371. {
  372. acpi_status             status = AE_OK;
  373. EC_REQUEST              *ec_request = NULL;
  374. EC_CONTEXT              *ec = NULL;
  375. FUNCTION_TRACE("ec_request");
  376. /*
  377.  * Must have a valid request structure and context.
  378.  */
  379. if (!request || !context)
  380. return_ACPI_STATUS(AE_BAD_PARAMETER);
  381. /*
  382.  * buffer must contain a valid EC_REQUEST structure.
  383.  */
  384. status = bm_cast_buffer(&(request->buffer), (void**)&ec_request,
  385. sizeof(EC_REQUEST));
  386. if (ACPI_FAILURE(status))
  387. return_ACPI_STATUS(status);
  388. /*
  389.  * context contains information specific to this EC.
  390.  */
  391. ec = (EC_CONTEXT*)context;
  392. /*
  393.  * Perform the Transaction.
  394.  */
  395. status = ec_transaction(ec, ec_request);
  396. return_ACPI_STATUS(status);
  397. }