[ACPI] ACPICA 20060210
[linux-2.6] / drivers / acpi / events / evrgnini.c
1 /******************************************************************************
2  *
3  * Module Name: evrgnini- ACPI address_space (op_region) init
4  *
5  *****************************************************************************/
6
7 /*
8  * Copyright (C) 2000 - 2006, R. Byron Moore
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43
44 #include <acpi/acpi.h>
45 #include <acpi/acevents.h>
46 #include <acpi/acnamesp.h>
47
48 #define _COMPONENT          ACPI_EVENTS
49 ACPI_MODULE_NAME("evrgnini")
50
51 /*******************************************************************************
52  *
53  * FUNCTION:    acpi_ev_system_memory_region_setup
54  *
55  * PARAMETERS:  Handle              - Region we are interested in
56  *              Function            - Start or stop
57  *              handler_context     - Address space handler context
58  *              region_context      - Region specific context
59  *
60  * RETURN:      Status
61  *
62  * DESCRIPTION: Setup a system_memory operation region
63  *
64  ******************************************************************************/
65 acpi_status
66 acpi_ev_system_memory_region_setup(acpi_handle handle,
67                                    u32 function,
68                                    void *handler_context, void **region_context)
69 {
70         union acpi_operand_object *region_desc =
71             (union acpi_operand_object *)handle;
72         struct acpi_mem_space_context *local_region_context;
73
74         ACPI_FUNCTION_TRACE("ev_system_memory_region_setup");
75
76         if (function == ACPI_REGION_DEACTIVATE) {
77                 if (*region_context) {
78                         ACPI_MEM_FREE(*region_context);
79                         *region_context = NULL;
80                 }
81                 return_ACPI_STATUS(AE_OK);
82         }
83
84         /* Create a new context */
85
86         local_region_context =
87             ACPI_MEM_CALLOCATE(sizeof(struct acpi_mem_space_context));
88         if (!(local_region_context)) {
89                 return_ACPI_STATUS(AE_NO_MEMORY);
90         }
91
92         /* Save the region length and address for use in the handler */
93
94         local_region_context->length = region_desc->region.length;
95         local_region_context->address = region_desc->region.address;
96
97         *region_context = local_region_context;
98         return_ACPI_STATUS(AE_OK);
99 }
100
101 /*******************************************************************************
102  *
103  * FUNCTION:    acpi_ev_io_space_region_setup
104  *
105  * PARAMETERS:  Handle              - Region we are interested in
106  *              Function            - Start or stop
107  *              handler_context     - Address space handler context
108  *              region_context      - Region specific context
109  *
110  * RETURN:      Status
111  *
112  * DESCRIPTION: Setup a IO operation region
113  *
114  ******************************************************************************/
115
116 acpi_status
117 acpi_ev_io_space_region_setup(acpi_handle handle,
118                               u32 function,
119                               void *handler_context, void **region_context)
120 {
121         ACPI_FUNCTION_TRACE("ev_io_space_region_setup");
122
123         if (function == ACPI_REGION_DEACTIVATE) {
124                 *region_context = NULL;
125         } else {
126                 *region_context = handler_context;
127         }
128
129         return_ACPI_STATUS(AE_OK);
130 }
131
132 /*******************************************************************************
133  *
134  * FUNCTION:    acpi_ev_pci_config_region_setup
135  *
136  * PARAMETERS:  Handle              - Region we are interested in
137  *              Function            - Start or stop
138  *              handler_context     - Address space handler context
139  *              region_context      - Region specific context
140  *
141  * RETURN:      Status
142  *
143  * DESCRIPTION: Setup a PCI_Config operation region
144  *
145  * MUTEX:       Assumes namespace is not locked
146  *
147  ******************************************************************************/
148
149 acpi_status
150 acpi_ev_pci_config_region_setup(acpi_handle handle,
151                                 u32 function,
152                                 void *handler_context, void **region_context)
153 {
154         acpi_status status = AE_OK;
155         acpi_integer pci_value;
156         struct acpi_pci_id *pci_id = *region_context;
157         union acpi_operand_object *handler_obj;
158         struct acpi_namespace_node *parent_node;
159         struct acpi_namespace_node *pci_root_node;
160         union acpi_operand_object *region_obj =
161             (union acpi_operand_object *)handle;
162         struct acpi_device_id object_hID;
163
164         ACPI_FUNCTION_TRACE("ev_pci_config_region_setup");
165
166         handler_obj = region_obj->region.handler;
167         if (!handler_obj) {
168                 /*
169                  * No installed handler. This shouldn't happen because the dispatch
170                  * routine checks before we get here, but we check again just in case.
171                  */
172                 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
173                                   "Attempting to init a region %p, with no handler\n",
174                                   region_obj));
175                 return_ACPI_STATUS(AE_NOT_EXIST);
176         }
177
178         *region_context = NULL;
179         if (function == ACPI_REGION_DEACTIVATE) {
180                 if (pci_id) {
181                         ACPI_MEM_FREE(pci_id);
182                 }
183                 return_ACPI_STATUS(status);
184         }
185
186         parent_node = acpi_ns_get_parent_node(region_obj->region.node);
187
188         /*
189          * Get the _SEG and _BBN values from the device upon which the handler
190          * is installed.
191          *
192          * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
193          * This is the device the handler has been registered to handle.
194          */
195
196         /*
197          * If the address_space.Node is still pointing to the root, we need
198          * to scan upward for a PCI Root bridge and re-associate the op_region
199          * handlers with that device.
200          */
201         if (handler_obj->address_space.node == acpi_gbl_root_node) {
202
203                 /* Start search from the parent object */
204
205                 pci_root_node = parent_node;
206                 while (pci_root_node != acpi_gbl_root_node) {
207                         status =
208                             acpi_ut_execute_HID(pci_root_node, &object_hID);
209                         if (ACPI_SUCCESS(status)) {
210                                 /*
211                                  * Got a valid _HID string, check if this is a PCI root.
212                                  * New for ACPI 3.0: check for a PCI Express root also.
213                                  */
214                                 if (!
215                                     (ACPI_STRNCMP
216                                      (object_hID.value, PCI_ROOT_HID_STRING,
217                                       sizeof(PCI_ROOT_HID_STRING))
218                                      ||
219                                      !(ACPI_STRNCMP
220                                        (object_hID.value,
221                                         PCI_EXPRESS_ROOT_HID_STRING,
222                                         sizeof(PCI_EXPRESS_ROOT_HID_STRING)))))
223                                 {
224
225                                         /* Install a handler for this PCI root bridge */
226
227                                         status =
228                                             acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
229                                         if (ACPI_FAILURE(status)) {
230                                                 if (status == AE_SAME_HANDLER) {
231                                                         /*
232                                                          * It is OK if the handler is already installed on the root
233                                                          * bridge.  Still need to return a context object for the
234                                                          * new PCI_Config operation region, however.
235                                                          */
236                                                         status = AE_OK;
237                                                 } else {
238                                                         ACPI_EXCEPTION((AE_INFO,
239                                                                         status,
240                                                                         "Could not install pci_config handler for Root Bridge %4.4s",
241                                                                         acpi_ut_get_node_name
242                                                                         (pci_root_node)));
243                                                 }
244                                         }
245                                         break;
246                                 }
247                         }
248
249                         pci_root_node = acpi_ns_get_parent_node(pci_root_node);
250                 }
251
252                 /* PCI root bridge not found, use namespace root node */
253         } else {
254                 pci_root_node = handler_obj->address_space.node;
255         }
256
257         /*
258          * If this region is now initialized, we are done.
259          * (install_address_space_handler could have initialized it)
260          */
261         if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
262                 return_ACPI_STATUS(AE_OK);
263         }
264
265         /* Region is still not initialized. Create a new context */
266
267         pci_id = ACPI_MEM_CALLOCATE(sizeof(struct acpi_pci_id));
268         if (!pci_id) {
269                 return_ACPI_STATUS(AE_NO_MEMORY);
270         }
271
272         /*
273          * For PCI_Config space access, we need the segment, bus,
274          * device and function numbers.  Acquire them here.
275          */
276
277         /*
278          * Get the PCI device and function numbers from the _ADR object
279          * contained in the parent's scope.
280          */
281         status =
282             acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, parent_node,
283                                             &pci_value);
284
285         /*
286          * The default is zero, and since the allocation above zeroed
287          * the data, just do nothing on failure.
288          */
289         if (ACPI_SUCCESS(status)) {
290                 pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value));
291                 pci_id->function = ACPI_LOWORD(ACPI_LODWORD(pci_value));
292         }
293
294         /* The PCI segment number comes from the _SEG method */
295
296         status =
297             acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
298                                             &pci_value);
299         if (ACPI_SUCCESS(status)) {
300                 pci_id->segment = ACPI_LOWORD(pci_value);
301         }
302
303         /* The PCI bus number comes from the _BBN method */
304
305         status =
306             acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
307                                             &pci_value);
308         if (ACPI_SUCCESS(status)) {
309                 pci_id->bus = ACPI_LOWORD(pci_value);
310         }
311
312         /* Complete this device's pci_id */
313
314         acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id);
315
316         *region_context = pci_id;
317         return_ACPI_STATUS(AE_OK);
318 }
319
320 /*******************************************************************************
321  *
322  * FUNCTION:    acpi_ev_pci_bar_region_setup
323  *
324  * PARAMETERS:  Handle              - Region we are interested in
325  *              Function            - Start or stop
326  *              handler_context     - Address space handler context
327  *              region_context      - Region specific context
328  *
329  * RETURN:      Status
330  *
331  * DESCRIPTION: Setup a pci_bAR operation region
332  *
333  * MUTEX:       Assumes namespace is not locked
334  *
335  ******************************************************************************/
336
337 acpi_status
338 acpi_ev_pci_bar_region_setup(acpi_handle handle,
339                              u32 function,
340                              void *handler_context, void **region_context)
341 {
342         ACPI_FUNCTION_TRACE("ev_pci_bar_region_setup");
343
344         return_ACPI_STATUS(AE_OK);
345 }
346
347 /*******************************************************************************
348  *
349  * FUNCTION:    acpi_ev_cmos_region_setup
350  *
351  * PARAMETERS:  Handle              - Region we are interested in
352  *              Function            - Start or stop
353  *              handler_context     - Address space handler context
354  *              region_context      - Region specific context
355  *
356  * RETURN:      Status
357  *
358  * DESCRIPTION: Setup a CMOS operation region
359  *
360  * MUTEX:       Assumes namespace is not locked
361  *
362  ******************************************************************************/
363
364 acpi_status
365 acpi_ev_cmos_region_setup(acpi_handle handle,
366                           u32 function,
367                           void *handler_context, void **region_context)
368 {
369         ACPI_FUNCTION_TRACE("ev_cmos_region_setup");
370
371         return_ACPI_STATUS(AE_OK);
372 }
373
374 /*******************************************************************************
375  *
376  * FUNCTION:    acpi_ev_default_region_setup
377  *
378  * PARAMETERS:  Handle              - Region we are interested in
379  *              Function            - Start or stop
380  *              handler_context     - Address space handler context
381  *              region_context      - Region specific context
382  *
383  * RETURN:      Status
384  *
385  * DESCRIPTION: Default region initialization
386  *
387  ******************************************************************************/
388
389 acpi_status
390 acpi_ev_default_region_setup(acpi_handle handle,
391                              u32 function,
392                              void *handler_context, void **region_context)
393 {
394         ACPI_FUNCTION_TRACE("ev_default_region_setup");
395
396         if (function == ACPI_REGION_DEACTIVATE) {
397                 *region_context = NULL;
398         } else {
399                 *region_context = handler_context;
400         }
401
402         return_ACPI_STATUS(AE_OK);
403 }
404
405 /*******************************************************************************
406  *
407  * FUNCTION:    acpi_ev_initialize_region
408  *
409  * PARAMETERS:  region_obj      - Region we are initializing
410  *              acpi_ns_locked  - Is namespace locked?
411  *
412  * RETURN:      Status
413  *
414  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
415  *              for execution at a later time
416  *
417  *              Get the appropriate address space handler for a newly
418  *              created region.
419  *
420  *              This also performs address space specific initialization.  For
421  *              example, PCI regions must have an _ADR object that contains
422  *              a PCI address in the scope of the definition.  This address is
423  *              required to perform an access to PCI config space.
424  *
425  ******************************************************************************/
426
427 acpi_status
428 acpi_ev_initialize_region(union acpi_operand_object *region_obj,
429                           u8 acpi_ns_locked)
430 {
431         union acpi_operand_object *handler_obj;
432         union acpi_operand_object *obj_desc;
433         acpi_adr_space_type space_id;
434         struct acpi_namespace_node *node;
435         acpi_status status;
436         struct acpi_namespace_node *method_node;
437         acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
438         union acpi_operand_object *region_obj2;
439
440         ACPI_FUNCTION_TRACE_U32("ev_initialize_region", acpi_ns_locked);
441
442         if (!region_obj) {
443                 return_ACPI_STATUS(AE_BAD_PARAMETER);
444         }
445
446         if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) {
447                 return_ACPI_STATUS(AE_OK);
448         }
449
450         region_obj2 = acpi_ns_get_secondary_object(region_obj);
451         if (!region_obj2) {
452                 return_ACPI_STATUS(AE_NOT_EXIST);
453         }
454
455         node = acpi_ns_get_parent_node(region_obj->region.node);
456         space_id = region_obj->region.space_id;
457
458         /* Setup defaults */
459
460         region_obj->region.handler = NULL;
461         region_obj2->extra.method_REG = NULL;
462         region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
463         region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
464
465         /* Find any "_REG" method associated with this region definition */
466
467         status = acpi_ns_search_node(*reg_name_ptr, node,
468                                      ACPI_TYPE_METHOD, &method_node);
469         if (ACPI_SUCCESS(status)) {
470                 /*
471                  * The _REG method is optional and there can be only one per region
472                  * definition.  This will be executed when the handler is attached
473                  * or removed
474                  */
475                 region_obj2->extra.method_REG = method_node;
476         }
477
478         /*
479          * The following loop depends upon the root Node having no parent
480          * ie: acpi_gbl_root_node->parent_entry being set to NULL
481          */
482         while (node) {
483
484                 /* Check to see if a handler exists */
485
486                 handler_obj = NULL;
487                 obj_desc = acpi_ns_get_attached_object(node);
488                 if (obj_desc) {
489
490                         /* Can only be a handler if the object exists */
491
492                         switch (node->type) {
493                         case ACPI_TYPE_DEVICE:
494
495                                 handler_obj = obj_desc->device.handler;
496                                 break;
497
498                         case ACPI_TYPE_PROCESSOR:
499
500                                 handler_obj = obj_desc->processor.handler;
501                                 break;
502
503                         case ACPI_TYPE_THERMAL:
504
505                                 handler_obj = obj_desc->thermal_zone.handler;
506                                 break;
507
508                         default:
509                                 /* Ignore other objects */
510                                 break;
511                         }
512
513                         while (handler_obj) {
514
515                                 /* Is this handler of the correct type? */
516
517                                 if (handler_obj->address_space.space_id ==
518                                     space_id) {
519
520                                         /* Found correct handler */
521
522                                         ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
523                                                           "Found handler %p for region %p in obj %p\n",
524                                                           handler_obj,
525                                                           region_obj,
526                                                           obj_desc));
527
528                                         status =
529                                             acpi_ev_attach_region(handler_obj,
530                                                                   region_obj,
531                                                                   acpi_ns_locked);
532
533                                         /*
534                                          * Tell all users that this region is usable by running the _REG
535                                          * method
536                                          */
537                                         if (acpi_ns_locked) {
538                                                 status =
539                                                     acpi_ut_release_mutex
540                                                     (ACPI_MTX_NAMESPACE);
541                                                 if (ACPI_FAILURE(status)) {
542                                                         return_ACPI_STATUS
543                                                             (status);
544                                                 }
545                                         }
546
547                                         status =
548                                             acpi_ev_execute_reg_method
549                                             (region_obj, 1);
550
551                                         if (acpi_ns_locked) {
552                                                 status =
553                                                     acpi_ut_acquire_mutex
554                                                     (ACPI_MTX_NAMESPACE);
555                                                 if (ACPI_FAILURE(status)) {
556                                                         return_ACPI_STATUS
557                                                             (status);
558                                                 }
559                                         }
560
561                                         return_ACPI_STATUS(AE_OK);
562                                 }
563
564                                 /* Try next handler in the list */
565
566                                 handler_obj = handler_obj->address_space.next;
567                         }
568                 }
569
570                 /*
571                  * This node does not have the handler we need;
572                  * Pop up one level
573                  */
574                 node = acpi_ns_get_parent_node(node);
575         }
576
577         /* If we get here, there is no handler for this region */
578
579         ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
580                           "No handler for region_type %s(%X) (region_obj %p)\n",
581                           acpi_ut_get_region_name(space_id), space_id,
582                           region_obj));
583
584         return_ACPI_STATUS(AE_NOT_EXIST);
585 }