1 /*****************************************************************************
3 * Module Name: bmnotify.c
6 *****************************************************************************/
9 * Copyright (C) 2000, 2001 Andrew Grover
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 #define _COMPONENT ACPI_BUS_MANAGER
32 MODULE_NAME ("bmnotify")
35 /****************************************************************************
37 ****************************************************************************/
39 /****************************************************************************
41 * FUNCTION: bm_generate_notify
49 ****************************************************************************/
56 ACPI_STATUS status = AE_OK;
58 FUNCTION_TRACE("bm_generate_notify");
61 return_ACPI_STATUS(AE_BAD_PARAMETER);
64 DEBUG_PRINT(ACPI_INFO, ("Sending notify [0x%02x] to device [0x%02x].\n", notify_type, node->device.handle));
66 if (!(node->device.flags & BM_FLAGS_DRIVER_CONTROL) ||
67 !(node->driver.notify)) {
68 DEBUG_PRINT(ACPI_WARN, ("No driver installed for device [0x%02x].\n", node->device.handle));
69 return_ACPI_STATUS(AE_NOT_EXIST);
72 status = node->driver.notify(notify_type, node->device.handle,
73 &(node->driver.context));
75 return_ACPI_STATUS(status);
79 /****************************************************************************
81 * FUNCTION: bm_device_check
89 ****************************************************************************/
96 ACPI_STATUS status = AE_OK;
97 BM_DEVICE *device = NULL;
98 BM_DEVICE_STATUS old_status = BM_STATUS_UNKNOWN;
100 FUNCTION_TRACE("bm_device_check");
103 return_ACPI_STATUS(AE_BAD_PARAMETER);
106 device = &(node->device);
109 *status_change = FALSE;
112 old_status = device->status;
117 * Only check this device if its parent is present (which implies
118 * this device MAY be present).
120 if (!BM_NODE_PRESENT(node->parent)) {
121 return_ACPI_STATUS(AE_OK);
127 * And see if the status has changed.
129 status = bm_get_status(device);
130 if (ACPI_FAILURE(status)) {
131 return_ACPI_STATUS(status);
134 if (old_status == node->device.status) {
135 return_ACPI_STATUS(AE_OK);
139 *status_change = TRUE;
146 if ((device->status & BM_STATUS_PRESENT) &&
147 !(old_status & BM_STATUS_PRESENT)) {
148 /* TODO: Make sure driver is loaded, and if not, load. */
149 status = bm_generate_notify(node, BM_NOTIFY_DEVICE_ADDED);
156 else if (!(device->status & BM_STATUS_PRESENT) &&
157 (old_status & BM_STATUS_PRESENT)) {
158 /* TODO: Unload driver if last device instance. */
159 status = bm_generate_notify(node, BM_NOTIFY_DEVICE_REMOVED);
162 return_ACPI_STATUS(AE_OK);
166 /****************************************************************************
168 * FUNCTION: bm_bus_check
176 ****************************************************************************/
180 BM_NODE *parent_node)
182 ACPI_STATUS status = AE_OK;
183 u32 status_change = FALSE;
185 FUNCTION_TRACE("bm_bus_check");
188 return_ACPI_STATUS(AE_BAD_PARAMETER);
195 status = bm_device_check(parent_node, &status_change);
196 if (ACPI_FAILURE(status) || !status_change) {
197 return_ACPI_STATUS(status);
203 * TODO: Enumerate child devices within this device's scope and
204 * run bm_device_check()'s on them...
207 return_ACPI_STATUS(AE_OK);
211 /****************************************************************************
213 ****************************************************************************/
215 /****************************************************************************
217 * FUNCTION: bm_notify
225 ****************************************************************************/
229 ACPI_HANDLE acpi_handle,
233 ACPI_STATUS status = AE_OK;
234 BM_NODE *node = NULL;
236 FUNCTION_TRACE("bm_notify");
239 * Resolve the ACPI handle.
241 status = bm_get_node(0, acpi_handle, &node);
242 if (ACPI_FAILURE(status)) {
243 DEBUG_PRINT(ACPI_INFO, ("Recieved notify [0x%02x] for unknown device [%p].\n", notify_value, acpi_handle));
248 * Device-Specific or Standard?
249 * ----------------------------
250 * Device-specific notifies are forwarded to the control module's
251 * notify() function for processing. Standard notifies are handled
254 if (notify_value > 0x7F) {
255 status = bm_generate_notify(node, notify_value);
258 switch (notify_value) {
260 case BM_NOTIFY_BUS_CHECK:
261 DEBUG_PRINT(ACPI_INFO, ("Received BUS CHECK notification.\n"));
262 status = bm_bus_check(node);
265 case BM_NOTIFY_DEVICE_CHECK:
266 DEBUG_PRINT(ACPI_INFO, ("Received DEVICE CHECK notification.\n"));
267 status = bm_device_check(node, NULL);
270 case BM_NOTIFY_DEVICE_WAKE:
271 DEBUG_PRINT(ACPI_INFO, ("Received DEVICE WAKE notification.\n"));
275 case BM_NOTIFY_EJECT_REQUEST:
276 DEBUG_PRINT(ACPI_INFO, ("Received EJECT REQUEST notification.\n"));
280 case BM_NOTIFY_DEVICE_CHECK_LIGHT:
281 DEBUG_PRINT(ACPI_INFO, ("Received DEVICE CHECK LIGHT notification.\n"));
282 /* TODO: Exactly what does the 'light' mean? */
283 status = bm_device_check(node, NULL);
286 case BM_NOTIFY_FREQUENCY_MISMATCH:
287 DEBUG_PRINT(ACPI_INFO, ("Received FREQUENCY MISMATCH notification.\n"));
291 case BM_NOTIFY_BUS_MODE_MISMATCH:
292 DEBUG_PRINT(ACPI_INFO, ("Received BUS MODE MISMATCH notification.\n"));
296 case BM_NOTIFY_POWER_FAULT:
297 DEBUG_PRINT(ACPI_INFO, ("Received POWER FAULT notification.\n"));
302 DEBUG_PRINT(ACPI_INFO, ("Received unknown/unsupported notification.\n"));