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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  driver.c - ACPI driver
  3.  *
  4.  *  Copyright (C) 2000 Andrew Henroid
  5.  *  Copyright (C) 2001 Andrew Grover
  6.  *
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20.  */
  21. /*
  22.  * Changes
  23.  * David Woodhouse <dwmw2@redhat.com> 2000-12-6
  24.  * - Fix interruptible_sleep_on() races
  25.  * Andrew Grover <andrew.grover@intel.com> 2001-2-28
  26.  * - Major revamping
  27.  * Peter Breuer <ptb@it.uc3m.es> 2001-5-20
  28.  * - parse boot time params.
  29.  */
  30. #include <linux/config.h>
  31. #include <linux/module.h>
  32. #include <linux/init.h>
  33. #include <linux/kernel.h>
  34. #include <linux/types.h>
  35. #include <linux/slab.h>
  36. #include <linux/proc_fs.h>
  37. #include <linux/sysctl.h>
  38. #include <linux/pm.h>
  39. #include <linux/acpi.h>
  40. #include <asm/uaccess.h>
  41. #include "acpi.h"
  42. #define _COMPONENT OS_DEPENDENT
  43. MODULE_NAME ("driver")
  44. FADT_DESCRIPTOR acpi_fadt;
  45. static int acpi_disabled = 0;
  46. enum acpi_blacklist_predicates
  47. {
  48. all_versions,
  49. less_than_or_equal,
  50. equal,
  51. greater_than_or_equal,
  52. };
  53. struct acpi_blacklist_item
  54. {
  55. char oem_id[7];
  56. char oem_table_id[9];
  57. u32  oem_revision;
  58. enum acpi_blacklist_predicates oem_revision_predicate;
  59. };
  60. /*
  61.  * Currently, this blacklists based on items in the FADT. We may want to
  62.  * expand this to using other ACPI tables in the future, too.
  63.  */
  64. static struct acpi_blacklist_item acpi_blacklist[] __initdata = 
  65. {
  66. {"TOSHIB", "750     ", 0x970814, less_than_or_equal}, /* Portege 7020, BIOS 8.10 */
  67. {""}
  68. };
  69. int
  70. acpi_blacklisted(FADT_DESCRIPTOR *fadt)
  71. {
  72. int i = 0;
  73. while (acpi_blacklist[i].oem_id[0] != '')
  74. {
  75. if (strncmp(acpi_blacklist[i].oem_id, fadt->header.oem_id, 6)) {
  76. i++;
  77. continue;
  78. }
  79. if (strncmp(acpi_blacklist[i].oem_table_id, fadt->header.oem_table_id, 8)) {
  80. i++;
  81. continue;
  82. }
  83. if (acpi_blacklist[i].oem_revision_predicate == all_versions)
  84. return TRUE;
  85. if (acpi_blacklist[i].oem_revision_predicate == less_than_or_equal
  86.     && fadt->header.oem_revision <= acpi_blacklist[i].oem_revision)
  87. return TRUE;
  88. if (acpi_blacklist[i].oem_revision_predicate == greater_than_or_equal
  89.     && fadt->header.oem_revision >= acpi_blacklist[i].oem_revision)
  90. return TRUE;
  91. if (acpi_blacklist[i].oem_revision_predicate == equal
  92.     && fadt->header.oem_revision == acpi_blacklist[i].oem_revision)
  93. return TRUE;
  94. i++;
  95. }
  96. return FALSE;
  97. }
  98. /*
  99.  * Start the interpreter
  100.  */
  101. int
  102. acpi_init(void)
  103. {
  104. acpi_buffer buffer;
  105. acpi_system_info sys_info;
  106. if (PM_IS_ACTIVE()) {
  107. printk(KERN_NOTICE "ACPI: APM is already active, exitingn");
  108. return -ENODEV;
  109. }
  110. if (acpi_disabled) {
  111. printk(KERN_NOTICE "ACPI: disabled by cmdline, exitingn");
  112. return -ENODEV;
  113. }
  114. if (!ACPI_SUCCESS(acpi_initialize_subsystem())) {
  115. printk(KERN_ERR "ACPI: Driver initialization failedn");
  116. return -ENODEV;
  117. }
  118. /* from this point on, on error we must call acpi_terminate() */
  119. if (!ACPI_SUCCESS(acpi_load_tables())) {
  120. printk(KERN_ERR "ACPI: System description table load failedn");
  121. acpi_terminate();
  122. return -ENODEV;
  123. }
  124. /* get a separate copy of the FADT for use by other drivers */
  125. memset(&acpi_fadt, 0, sizeof(acpi_fadt));
  126. buffer.pointer = &acpi_fadt;
  127. buffer.length = sizeof(acpi_fadt);
  128. if (!ACPI_SUCCESS(acpi_get_table(ACPI_TABLE_FADT, 1, &buffer))) {
  129. printk(KERN_ERR "ACPI: Could not get FADTn");
  130. acpi_terminate();
  131. return -ENODEV;
  132. }
  133. if (acpi_blacklisted(&acpi_fadt)) {
  134. printk(KERN_ERR "ACPI: On blacklist -- BIOS not fully ACPI compliantn");
  135. acpi_terminate();
  136. return -ENODEV;
  137. }
  138. buffer.length  = sizeof(sys_info);
  139. buffer.pointer = &sys_info;
  140. if (!ACPI_SUCCESS (acpi_get_system_info(&buffer))) {
  141. printk(KERN_ERR "ACPI: Could not get system infon");
  142. acpi_terminate();
  143. return -ENODEV;
  144. }
  145. printk(KERN_INFO "ACPI: Core Subsystem version [%x]n", sys_info.acpi_ca_version);
  146. if (!ACPI_SUCCESS(acpi_enable_subsystem(ACPI_FULL_INITIALIZATION))) {
  147. printk(KERN_ERR "ACPI: Subsystem enable failedn");
  148. acpi_terminate();
  149. return -ENODEV;
  150. }
  151. printk(KERN_INFO "ACPI: Subsystem enabledn");
  152. pm_active = 1;
  153. return 0;
  154. }
  155. /*
  156.  * Terminate the interpreter
  157.  */
  158. void
  159. acpi_exit(void)
  160. {
  161. acpi_terminate();
  162. pm_active = 0;
  163. printk(KERN_ERR "ACPI: Subsystem disabledn");
  164. }
  165. module_init(acpi_init);
  166. module_exit(acpi_exit);
  167. #ifndef MODULE
  168. static int __init acpi_setup(char *str) {
  169. while (str && *str) {
  170. if (strncmp(str, "off", 3) == 0)
  171. acpi_disabled = 1;
  172. str = strchr(str, ',');
  173. if (str)
  174. str += strspn(str, ", t");
  175. }
  176. return 1;
  177. }
  178. __setup("acpi=", acpi_setup);
  179. #endif