ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

button.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.