ACPI: ACPICA 20060331
[sfrench/cifs-2.6.git] / 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                         local_region_context =
79                             (struct acpi_mem_space_context *)*region_context;
80
81                         /* Delete a cached mapping if present */
82
83                         if (local_region_context->mapped_length) {
84                                 acpi_os_unmap_memory(local_region_context->
85                                                      mapped_logical_address,
86                                                      local_region_context->
87                                                      mapped_length);
88                         }
89                         ACPI_FREE(local_region_context);
90                         *region_context = NULL;
91                 }
92                 return_ACPI_STATUS(AE_OK);
93         }
94
95         /* Create a new context */
96
97         local_region_context =
98             ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_mem_space_context));
99         if (!(local_region_context)) {
100                 return_ACPI_STATUS(AE_NO_MEMORY);
101         }
102
103         /* Save the region length and address for use in the handler */
104
105         local_region_context->length = region_desc->region.length;
106         local_region_context->address = region_desc->region.address;
107
108         *region_context = local_region_context;
109         return_ACPI_STATUS(AE_OK);
110 }
111
112 /*******************************************************************************
113  *
114  * FUNCTION:    acpi_ev_io_space_region_setup
115  *
116  * PARAMETERS:  Handle              - Region we are interested in
117  *              Function            - Start or stop
118  *              handler_context     - Address space handler context
119  *              region_context      - Region specific context
120  *
121  * RETURN:      Status
122  *
123  * DESCRIPTION: Setup a IO operation region
124  *
125  ******************************************************************************/
126
127 acpi_status
128 acpi_ev_io_space_region_setup(acpi_handle handle,
129                               u32 function,
130                               void *handler_context, void **region_context)
131 {
132         ACPI_FUNCTION_TRACE("ev_io_space_region_setup");
133
134         if (function == ACPI_REGION_DEACTIVATE) {
135                 *region_context = NULL;
136         } else {
137                 *region_context = handler_context;
138         }
139
140         return_ACPI_STATUS(AE_OK);
141 }
142
143 /*******************************************************************************
144  *
145  * FUNCTION:    acpi_ev_pci_config_region_setup
146  *
147  * PARAMETERS:  Handle              - Region we are interested in
148  *              Function            - Start or stop
149  *              handler_context     - Address space handler context
150  *              region_context      - Region specific context
151  *
152  * RETURN:      Status
153  *
154  * DESCRIPTION: Setup a PCI_Config operation region
155  *
156  * MUTEX:       Assumes namespace is not locked
157  *
158  ******************************************************************************/
159
160 acpi_status
161 acpi_ev_pci_config_region_setup(acpi_handle handle,
162                                 u32 function,
163                                 void *handler_context, void **region_context)
164 {
165         acpi_status status = AE_OK;
166         acpi_integer pci_value;
167         struct acpi_pci_id *pci_id = *region_context;
168         union acpi_operand_object *handler_obj;
169         struct acpi_namespace_node *parent_node;
170         struct acpi_namespace_node *pci_root_node;
171         union acpi_operand_object *region_obj =
172             (union acpi_operand_object *)handle;
173         struct acpi_device_id object_hID;
174
175         ACPI_FUNCTION_TRACE("ev_pci_config_region_setup");
176
177         handler_obj = region_obj->region.handler;
178         if (!handler_obj) {
179                 /*
180                  * No installed handler. This shouldn't happen because the dispatch
181                  * routine checks before we get here, but we check again just in case.
182                  */
183                 ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
184                                   "Attempting to init a region %p, with no handler\n",
185                                   region_obj));
186                 return_ACPI_STATUS(AE_NOT_EXIST);
187         }
188
189         *region_context = NULL;
190         if (function == ACPI_REGION_DEACTIVATE) {
191                 if (pci_id) {
192                         ACPI_FREE(pci_id);
193                 }
194                 return_ACPI_STATUS(status);
195         }
196
197         parent_node = acpi_ns_get_parent_node(region_obj->region.node);
198
199         /*
200          * Get the _SEG and _BBN values from the device upon which the handler
201          * is installed.
202          *
203          * We need to get the _SEG and _BBN objects relative to the PCI BUS device.
204          * This is the device the handler has been registered to handle.
205          */
206
207         /*
208          * If the address_space.Node is still pointing to the root, we need
209          * to scan upward for a PCI Root bridge and re-associate the op_region
210          * handlers with that device.
211          */
212         if (handler_obj->address_space.node == acpi_gbl_root_node) {
213
214                 /* Start search from the parent object */
215
216                 pci_root_node = parent_node;
217                 while (pci_root_node != acpi_gbl_root_node) {
218                         status =
219                             acpi_ut_execute_HID(pci_root_node, &object_hID);
220                         if (ACPI_SUCCESS(status)) {
221                                 /*
222                                  * Got a valid _HID string, check if this is a PCI root.
223                                  * New for ACPI 3.0: check for a PCI Express root also.
224                                  */
225                                 if (!
226                                     (ACPI_STRNCMP
227                                      (object_hID.value, PCI_ROOT_HID_STRING,
228                                       sizeof(PCI_ROOT_HID_STRING))
229                                      ||
230                                      !(ACPI_STRNCMP
231                                        (object_hID.value,
232                                         PCI_EXPRESS_ROOT_HID_STRING,
233                                         sizeof(PCI_EXPRESS_ROOT_HID_STRING)))))
234                                 {
235
236                                         /* Install a handler for this PCI root bridge */
237
238                                         status =
239                                             acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
240                                         if (ACPI_FAILURE(status)) {
241                                                 if (status == AE_SAME_HANDLER) {
242                                                         /*
243                                                          * It is OK if the handler is already installed on the root
244                                                          * bridge.  Still need to return a context object for the
245                                                          * new PCI_Config operation region, however.
246                                                          */
247                                                         status = AE_OK;
248                                                 } else {
249                                                         ACPI_EXCEPTION((AE_INFO,
250                                                                         status,
251                                                                         "Could not install pci_config handler for Root Bridge %4.4s",
252                                                                         acpi_ut_get_node_name
253                                                                         (pci_root_node)));
254                                                 }
255                                         }
256                                         break;
257                                 }
258                         }
259
260                         pci_root_node = acpi_ns_get_parent_node(pci_root_node);
261                 }
262
263                 /* PCI root bridge not found, use namespace root node */
264         } else {
265                 pci_root_node = handler_obj->address_space.node;
266         }
267
268         /*
269          * If this region is now initialized, we are done.
270          * (install_address_space_handler could have initialized it)
271          */
272         if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
273                 return_ACPI_STATUS(AE_OK);
274         }
275
276         /* Region is still not initialized. Create a new context */
277
278         pci_id = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_pci_id));
279         if (!pci_id) {
280                 return_ACPI_STATUS(AE_NO_MEMORY);
281         }
282
283         /*
284          * For PCI_Config space access, we need the segment, bus,
285          * device and function numbers.  Acquire them here.
286          */
287
288         /*
289          * Get the PCI device and function numbers from the _ADR object
290          * contained in the parent's scope.
291          */
292         status =
293             acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, parent_node,
294                                             &pci_value);
295
296         /*
297          * The default is zero, and since the allocation above zeroed
298          * the data, just do nothing on failure.
299          */
300         if (ACPI_SUCCESS(status)) {
301                 pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value));
302                 pci_id->function = ACPI_LOWORD(ACPI_LODWORD(pci_value));
303         }
304
305         /* The PCI segment number comes from the _SEG method */
306
307         status =
308             acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
309                                             &pci_value);
310         if (ACPI_SUCCESS(status)) {
311                 pci_id->segment = ACPI_LOWORD(pci_value);
312         }
313
314         /* The PCI bus number comes from the _BBN method */
315
316         status =
317             acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
318                                             &pci_value);
319         if (ACPI_SUCCESS(status)) {
320                 pci_id->bus = ACPI_LOWORD(pci_value);
321         }
322
323         /* Complete this device's pci_id */
324
325         acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id);
326
327         *region_context = pci_id;
328         return_ACPI_STATUS(AE_OK);
329 }
330
331 /*******************************************************************************
332  *
333  * FUNCTION:    acpi_ev_pci_bar_region_setup
334  *
335  * PARAMETERS:  Handle              - Region we are interested in
336  *              Function            - Start or stop
337  *              handler_context     - Address space handler context
338  *              region_context      - Region specific context
339  *
340  * RETURN:      Status
341  *
342  * DESCRIPTION: Setup a pci_bAR operation region
343  *
344  * MUTEX:       Assumes namespace is not locked
345  *
346  ******************************************************************************/
347
348 acpi_status
349 acpi_ev_pci_bar_region_setup(acpi_handle handle,
350                              u32 function,
351                              void *handler_context, void **region_context)
352 {
353         ACPI_FUNCTION_TRACE("ev_pci_bar_region_setup");
354
355         return_ACPI_STATUS(AE_OK);
356 }
357
358 /*******************************************************************************
359  *
360  * FUNCTION:    acpi_ev_cmos_region_setup
361  *
362  * PARAMETERS:  Handle              - Region we are interested in
363  *              Function            - Start or stop
364  *              handler_context     - Address space handler context
365  *              region_context      - Region specific context
366  *
367  * RETURN:      Status
368  *
369  * DESCRIPTION: Setup a CMOS operation region
370  *
371  * MUTEX:       Assumes namespace is not locked
372  *
373  ******************************************************************************/
374
375 acpi_status
376 acpi_ev_cmos_region_setup(acpi_handle handle,
377                           u32 function,
378                           void *handler_context, void **region_context)
379 {
380         ACPI_FUNCTION_TRACE("ev_cmos_region_setup");
381
382         return_ACPI_STATUS(AE_OK);
383 }
384
385 /*******************************************************************************
386  *
387  * FUNCTION:    acpi_ev_default_region_setup
388  *
389  * PARAMETERS:  Handle              - Region we are interested in
390  *              Function            - Start or stop
391  *              handler_context     - Address space handler context
392  *              region_context      - Region specific context
393  *
394  * RETURN:      Status
395  *
396  * DESCRIPTION: Default region initialization
397  *
398  ******************************************************************************/
399
400 acpi_status
401 acpi_ev_default_region_setup(acpi_handle handle,
402                              u32 function,
403                              void *handler_context, void **region_context)
404 {
405         ACPI_FUNCTION_TRACE("ev_default_region_setup");
406
407         if (function == ACPI_REGION_DEACTIVATE) {
408                 *region_context = NULL;
409         } else {
410                 *region_context = handler_context;
411         }
412
413         return_ACPI_STATUS(AE_OK);
414 }
415
416 /*******************************************************************************
417  *
418  * FUNCTION:    acpi_ev_initialize_region
419  *
420  * PARAMETERS:  region_obj      - Region we are initializing
421  *              acpi_ns_locked  - Is namespace locked?
422  *
423  * RETURN:      Status
424  *
425  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
426  *              for execution at a later time
427  *
428  *              Get the appropriate address space handler for a newly
429  *              created region.
430  *
431  *              This also performs address space specific initialization.  For
432  *              example, PCI regions must have an _ADR object that contains
433  *              a PCI address in the scope of the definition.  This address is
434  *              required to perform an access to PCI config space.
435  *
436  ******************************************************************************/
437
438 acpi_status
439 acpi_ev_initialize_region(union acpi_operand_object *region_obj,
440                           u8 acpi_ns_locked)
441 {
442         union acpi_operand_object *handler_obj;
443         union acpi_operand_object *obj_desc;
444         acpi_adr_space_type space_id;
445         struct acpi_namespace_node *node;
446         acpi_status status;
447         struct acpi_namespace_node *method_node;
448         acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
449         union acpi_operand_object *region_obj2;
450
451         ACPI_FUNCTION_TRACE_U32("ev_initialize_region", acpi_ns_locked);
452
453         if (!region_obj) {
454                 return_ACPI_STATUS(AE_BAD_PARAMETER);
455         }
456
457         if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) {
458                 return_ACPI_STATUS(AE_OK);
459         }
460
461         region_obj2 = acpi_ns_get_secondary_object(region_obj);
462         if (!region_obj2) {
463                 return_ACPI_STATUS(AE_NOT_EXIST);
464         }
465
466         node = acpi_ns_get_parent_node(region_obj->region.node);
467         space_id = region_obj->region.space_id;
468
469         /* Setup defaults */
470
471         region_obj->region.handler = NULL;
472         region_obj2->extra.method_REG = NULL;
473         region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
474         region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
475
476         /* Find any "_REG" method associated with this region definition */
477
478         status = acpi_ns_search_node(*reg_name_ptr, node,
479                                      ACPI_TYPE_METHOD, &method_node);
480         if (ACPI_SUCCESS(status)) {
481                 /*
482                  * The _REG method is optional and there can be only one per region
483                  * definition.  This will be executed when the handler is attached
484                  * or removed
485                  */
486                 region_obj2->extra.method_REG = method_node;
487         }
488
489         /*
490          * The following loop depends upon the root Node having no parent
491          * ie: acpi_gbl_root_node->parent_entry being set to NULL
492          */
493         while (node) {
494
495                 /* Check to see if a handler exists */
496
497                 handler_obj = NULL;
498                 obj_desc = acpi_ns_get_attached_object(node);
499                 if (obj_desc) {
500
501                         /* Can only be a handler if the object exists */
502
503                         switch (node->type) {
504                         case ACPI_TYPE_DEVICE:
505
506                                 handler_obj = obj_desc->device.handler;
507                                 break;
508
509                         case ACPI_TYPE_PROCESSOR:
510
511                                 handler_obj = obj_desc->processor.handler;
512                                 break;
513
514                         case ACPI_TYPE_THERMAL:
515
516                                 handler_obj = obj_desc->thermal_zone.handler;
517                                 break;
518
519                         default:
520                                 /* Ignore other objects */
521                                 break;
522                         }
523
524                         while (handler_obj) {
525
526                                 /* Is this handler of the correct type? */
527
528                                 if (handler_obj->address_space.space_id ==
529                                     space_id) {
530
531                                         /* Found correct handler */
532
533                                         ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
534                                                           "Found handler %p for region %p in obj %p\n",
535                                                           handler_obj,
536                                                           region_obj,
537                                                           obj_desc));
538
539                                         status =
540                                             acpi_ev_attach_region(handler_obj,
541                                                                   region_obj,
542                                                                   acpi_ns_locked);
543
544                                         /*
545                                          * Tell all users that this region is usable by running the _REG
546                                          * method
547                                          */
548                                         if (acpi_ns_locked) {
549                                                 status =
550                                                     acpi_ut_release_mutex
551                                                     (ACPI_MTX_NAMESPACE);
552                                                 if (ACPI_FAILURE(status)) {
553                                                         return_ACPI_STATUS
554                                                             (status);
555                                                 }
556                                         }
557
558                                         status =
559                                             acpi_ev_execute_reg_method
560                                             (region_obj, 1);
561
562                                         if (acpi_ns_locked) {
563                                                 status =
564                                                     acpi_ut_acquire_mutex
565                                                     (ACPI_MTX_NAMESPACE);
566                                                 if (ACPI_FAILURE(status)) {
567                                                         return_ACPI_STATUS
568                                                             (status);
569                                                 }
570                                         }
571
572                                         return_ACPI_STATUS(AE_OK);
573                                 }
574
575                                 /* Try next handler in the list */
576
577                                 handler_obj = handler_obj->address_space.next;
578                         }
579                 }
580
581                 /*
582                  * This node does not have the handler we need;
583                  * Pop up one level
584                  */
585                 node = acpi_ns_get_parent_node(node);
586         }
587
588         /* If we get here, there is no handler for this region */
589
590         ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
591                           "No handler for region_type %s(%X) (region_obj %p)\n",
592                           acpi_ut_get_region_name(space_id), space_id,
593                           region_obj));
594
595         return_ACPI_STATUS(AE_NOT_EXIST);
596 }