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"));