Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenbutton.c
Go to the documentation of this file.
00001 /* 00002 * acpi_button.c - ACPI Button Driver ($Revision: 29 $) 00003 * 00004 * Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com> 00005 * Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com> 00006 * 00007 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or (at 00012 * your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, but 00015 * WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 * General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License along 00020 * with this program; if not, write to the Free Software Foundation, Inc., 00021 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00022 * 00023 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00024 */ 00025 #include <ntddk.h> 00026 00027 #include <acpi.h> 00028 #include <acpi_bus.h> 00029 #include <acpi_drivers.h> 00030 #include <glue.h> 00031 00032 #define NDEBUG 00033 #include <debug.h> 00034 00035 00036 00037 #define _COMPONENT ACPI_BUTTON_COMPONENT 00038 ACPI_MODULE_NAME ("acpi_button") 00039 00040 00041 static int acpi_button_add (struct acpi_device *device); 00042 static int acpi_button_remove (struct acpi_device *device, int type); 00043 00044 static struct acpi_driver acpi_button_driver = { 00045 {0,0}, 00046 ACPI_BUTTON_DRIVER_NAME, 00047 ACPI_BUTTON_CLASS, 00048 0, 00049 0, 00050 "ACPI_FPB,ACPI_FSB,PNP0C0D,PNP0C0C,PNP0C0E", 00051 {acpi_button_add,acpi_button_remove} 00052 }; 00053 00054 struct acpi_button { 00055 ACPI_HANDLE handle; 00056 struct acpi_device *device; /* Fixed button kludge */ 00057 UINT8 type; 00058 unsigned long pushed; 00059 }; 00060 00061 struct acpi_device *power_button; 00062 struct acpi_device *sleep_button; 00063 struct acpi_device *lid_button; 00064 00065 /* -------------------------------------------------------------------------- 00066 Driver Interface 00067 -------------------------------------------------------------------------- */ 00068 00069 void 00070 acpi_button_notify ( 00071 ACPI_HANDLE handle, 00072 UINT32 event, 00073 void *data) 00074 { 00075 struct acpi_button *button = (struct acpi_button *) data; 00076 00077 ACPI_FUNCTION_TRACE("acpi_button_notify"); 00078 00079 if (!button || !button->device) 00080 return_VOID; 00081 00082 switch (event) { 00083 case ACPI_BUTTON_NOTIFY_STATUS: 00084 acpi_bus_generate_event(button->device, event, ++button->pushed); 00085 break; 00086 default: 00087 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 00088 "Unsupported event [0x%x]\n", event)); 00089 break; 00090 } 00091 00092 return_VOID; 00093 } 00094 00095 00096 ACPI_STATUS 00097 acpi_button_notify_fixed ( 00098 void *data) 00099 { 00100 struct acpi_button *button = (struct acpi_button *) data; 00101 00102 ACPI_FUNCTION_TRACE("acpi_button_notify_fixed"); 00103 00104 if (!button) 00105 return_ACPI_STATUS(AE_BAD_PARAMETER); 00106 00107 acpi_button_notify(button->handle, ACPI_BUTTON_NOTIFY_STATUS, button); 00108 00109 return_ACPI_STATUS(AE_OK); 00110 } 00111 00112 00113 static int 00114 acpi_button_add ( 00115 struct acpi_device *device) 00116 { 00117 int result = 0; 00118 ACPI_STATUS status = AE_OK; 00119 struct acpi_button *button = NULL; 00120 00121 ACPI_FUNCTION_TRACE("acpi_button_add"); 00122 00123 if (!device) 00124 return_VALUE(-1); 00125 00126 button = ExAllocatePoolWithTag(NonPagedPool,sizeof(struct acpi_button), 'IPCA'); 00127 if (!button) 00128 return_VALUE(-4); 00129 memset(button, 0, sizeof(struct acpi_button)); 00130 00131 button->device = device; 00132 button->handle = device->handle; 00133 acpi_driver_data(device) = button; 00134 00135 /* 00136 * Determine the button type (via hid), as fixed-feature buttons 00137 * need to be handled a bit differently than generic-space. 00138 */ 00139 if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWER)) { 00140 button->type = ACPI_BUTTON_TYPE_POWER; 00141 sprintf(acpi_device_name(device), "%s", 00142 ACPI_BUTTON_DEVICE_NAME_POWER); 00143 sprintf(acpi_device_class(device), "%s/%s", 00144 ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER); 00145 } 00146 else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF)) { 00147 button->type = ACPI_BUTTON_TYPE_POWERF; 00148 sprintf(acpi_device_name(device), "%s", 00149 ACPI_BUTTON_DEVICE_NAME_POWERF); 00150 sprintf(acpi_device_class(device), "%s/%s", 00151 ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_POWER); 00152 } 00153 else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEP)) { 00154 button->type = ACPI_BUTTON_TYPE_SLEEP; 00155 sprintf(acpi_device_name(device), "%s", 00156 ACPI_BUTTON_DEVICE_NAME_SLEEP); 00157 sprintf(acpi_device_class(device), "%s/%s", 00158 ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP); 00159 } 00160 else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF)) { 00161 button->type = ACPI_BUTTON_TYPE_SLEEPF; 00162 sprintf(acpi_device_name(device), "%s", 00163 ACPI_BUTTON_DEVICE_NAME_SLEEPF); 00164 sprintf(acpi_device_class(device), "%s/%s", 00165 ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_SLEEP); 00166 } 00167 else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_LID)) { 00168 button->type = ACPI_BUTTON_TYPE_LID; 00169 sprintf(acpi_device_name(device), "%s", 00170 ACPI_BUTTON_DEVICE_NAME_LID); 00171 sprintf(acpi_device_class(device), "%s/%s", 00172 ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); 00173 } 00174 else { 00175 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Unsupported hid [%s]\n", 00176 acpi_device_hid(device))); 00177 result = -15; 00178 goto end; 00179 } 00180 00181 /* 00182 * Ensure only one button of each type is used. 00183 */ 00184 switch (button->type) { 00185 case ACPI_BUTTON_TYPE_POWER: 00186 case ACPI_BUTTON_TYPE_POWERF: 00187 if (!power_button) 00188 power_button = device; 00189 else { 00190 ExFreePoolWithTag(button, 'IPCA'); 00191 return_VALUE(-15); 00192 } 00193 break; 00194 case ACPI_BUTTON_TYPE_SLEEP: 00195 case ACPI_BUTTON_TYPE_SLEEPF: 00196 if (!sleep_button) 00197 sleep_button = device; 00198 else { 00199 ExFreePoolWithTag(button, 'IPCA'); 00200 return_VALUE(-15); 00201 } 00202 break; 00203 case ACPI_BUTTON_TYPE_LID: 00204 if (!lid_button) 00205 lid_button = device; 00206 else { 00207 ExFreePoolWithTag(button, 'IPCA'); 00208 return_VALUE(-15); 00209 } 00210 break; 00211 } 00212 00213 switch (button->type) { 00214 case ACPI_BUTTON_TYPE_POWERF: 00215 status = AcpiInstallFixedEventHandler ( 00216 ACPI_EVENT_POWER_BUTTON, 00217 acpi_button_notify_fixed, 00218 button); 00219 break; 00220 case ACPI_BUTTON_TYPE_SLEEPF: 00221 status = AcpiInstallFixedEventHandler ( 00222 ACPI_EVENT_SLEEP_BUTTON, 00223 acpi_button_notify_fixed, 00224 button); 00225 break; 00226 case ACPI_BUTTON_TYPE_LID: 00227 status = AcpiInstallFixedEventHandler ( 00228 ACPI_BUTTON_TYPE_LID, 00229 acpi_button_notify_fixed, 00230 button); 00231 break; 00232 default: 00233 status = AcpiInstallNotifyHandler ( 00234 button->handle, 00235 ACPI_DEVICE_NOTIFY, 00236 acpi_button_notify, 00237 button); 00238 break; 00239 } 00240 00241 if (ACPI_FAILURE(status)) { 00242 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 00243 "Error installing notify handler\n")); 00244 result = -15; 00245 goto end; 00246 } 00247 00248 DPRINT("%s [%s]\n", 00249 acpi_device_name(device), acpi_device_bid(device)); 00250 00251 end: 00252 if (result) { 00253 ExFreePoolWithTag(button, 'IPCA'); 00254 } 00255 00256 return_VALUE(result); 00257 } 00258 00259 00260 static int 00261 acpi_button_remove (struct acpi_device *device, int type) 00262 { 00263 ACPI_STATUS status = 0; 00264 struct acpi_button *button = NULL; 00265 00266 ACPI_FUNCTION_TRACE("acpi_button_remove"); 00267 00268 if (!device || !acpi_driver_data(device)) 00269 return_VALUE(-1); 00270 00271 button = acpi_driver_data(device); 00272 00273 /* Unregister for device notifications. */ 00274 switch (button->type) { 00275 case ACPI_BUTTON_TYPE_POWERF: 00276 status = AcpiRemoveFixedEventHandler( 00277 ACPI_EVENT_POWER_BUTTON, acpi_button_notify_fixed); 00278 break; 00279 case ACPI_BUTTON_TYPE_SLEEPF: 00280 status = AcpiRemoveFixedEventHandler( 00281 ACPI_EVENT_SLEEP_BUTTON, acpi_button_notify_fixed); 00282 break; 00283 case ACPI_BUTTON_TYPE_LID: 00284 status = AcpiRemoveFixedEventHandler( 00285 ACPI_BUTTON_TYPE_LID, acpi_button_notify_fixed); 00286 break; 00287 default: 00288 status = AcpiRemoveNotifyHandler(button->handle, 00289 ACPI_DEVICE_NOTIFY, acpi_button_notify); 00290 break; 00291 } 00292 00293 if (ACPI_FAILURE(status)) 00294 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 00295 "Error removing notify handler\n")); 00296 00297 ExFreePoolWithTag(button, 'IPCA'); 00298 00299 return_VALUE(0); 00300 } 00301 00302 00303 int 00304 acpi_button_init (void) 00305 { 00306 int result = 0; 00307 00308 ACPI_FUNCTION_TRACE("acpi_button_init"); 00309 00310 result = acpi_bus_register_driver(&acpi_button_driver); 00311 if (result < 0) { 00312 return_VALUE(-15); 00313 } 00314 00315 return_VALUE(0); 00316 } 00317 00318 00319 void 00320 acpi_button_exit (void) 00321 { 00322 ACPI_FUNCTION_TRACE("acpi_button_exit"); 00323 00324 acpi_bus_unregister_driver(&acpi_button_driver); 00325 00326 return_VOID; 00327 } 00328 00329 Generated on Sun May 27 2012 04:27:24 for ReactOS by
1.7.6.1
|