Pull altix-ce1.0-asic into release branch
[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                 /* Start search from the parent object */
203
204                 pci_root_node = parent_node;
205                 while (pci_root_node != acpi_gbl_root_node) {
206                         status =
207                             acpi_ut_execute_HID(pci_root_node, &object_hID);
208                         if (ACPI_SUCCESS(status)) {
209                                 /*
210                                  * Got a valid _HID string, check if this is a PCI root.
211                                  * New for ACPI 3.0: check for a PCI Express root also.
212                                  */
213                                 if (!
214                                     (ACPI_STRNCMP
215                                      (object_hID.value, PCI_ROOT_HID_STRING,
216                                       sizeof(PCI_ROOT_HID_STRING))
217                                      ||
218                                      !(ACPI_STRNCMP
219                                        (object_hID.value,
220                                         PCI_EXPRESS_ROOT_HID_STRING,
221                                         sizeof(PCI_EXPRESS_ROOT_HID_STRING)))))
222                                 {
223                                         /* Install a handler for this PCI root bridge */
224
225                                         status =
226                                             acpi_install_address_space_handler((acpi_handle) pci_root_node, ACPI_ADR_SPACE_PCI_CONFIG, ACPI_DEFAULT_HANDLER, NULL, NULL);
227                                         if (ACPI_FAILURE(status)) {
228                                                 if (status == AE_SAME_HANDLER) {
229                                                         /*
230                                                          * It is OK if the handler is already installed on the root
231                                                          * bridge.  Still need to return a context object for the
232                                                          * new PCI_Config operation region, however.
233                                                          */
234                                                         status = AE_OK;
235                                                 } else {
236                                                         ACPI_EXCEPTION((AE_INFO,
237                                                                         status,
238                                                                         "Could not install pci_config handler for Root Bridge %4.4s",
239                                                                         acpi_ut_get_node_name
240                                                                         (pci_root_node)));
241                                                 }
242                                         }
243                                         break;
244                                 }
245                         }
246
247                         pci_root_node = acpi_ns_get_parent_node(pci_root_node);
248                 }
249
250                 /* PCI root bridge not found, use namespace root node */
251         } else {
252                 pci_root_node = handler_obj->address_space.node;
253         }
254
255         /*
256          * If this region is now initialized, we are done.
257          * (install_address_space_handler could have initialized it)
258          */
259         if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
260                 return_ACPI_STATUS(AE_OK);
261         }
262
263         /* Region is still not initialized. Create a new context */
264
265         pci_id = ACPI_MEM_CALLOCATE(sizeof(struct acpi_pci_id));
266         if (!pci_id) {
267                 return_ACPI_STATUS(AE_NO_MEMORY);
268         }
269
270         /*
271          * For PCI_Config space access, we need the segment, bus,
272          * device and function numbers.  Acquire them here.
273          */
274
275         /*
276          * Get the PCI device and function numbers from the _ADR object
277          * contained in the parent's scope.
278          */
279         status =
280             acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, parent_node,
281                                             &pci_value);
282
283         /*
284          * The default is zero, and since the allocation above zeroed
285          * the data, just do nothing on failure.
286          */
287         if (ACPI_SUCCESS(status)) {
288                 pci_id->device = ACPI_HIWORD(ACPI_LODWORD(pci_value));
289                 pci_id->function = ACPI_LOWORD(ACPI_LODWORD(pci_value));
290         }
291
292         /* The PCI segment number comes from the _SEG method */
293
294         status =
295             acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
296                                             &pci_value);
297         if (ACPI_SUCCESS(status)) {
298                 pci_id->segment = ACPI_LOWORD(pci_value);
299         }
300
301         /* The PCI bus number comes from the _BBN method */
302
303         status =
304             acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
305                                             &pci_value);
306         if (ACPI_SUCCESS(status)) {
307                 pci_id->bus = ACPI_LOWORD(pci_value);
308         }
309
310         /* Complete this device's pci_id */
311
312         acpi_os_derive_pci_id(pci_root_node, region_obj->region.node, &pci_id);
313
314         *region_context = pci_id;
315         return_ACPI_STATUS(AE_OK);
316 }
317
318 /*******************************************************************************
319  *
320  * FUNCTION:    acpi_ev_pci_bar_region_setup
321  *
322  * PARAMETERS:  Handle              - Region we are interested in
323  *              Function            - Start or stop
324  *              handler_context     - Address space handler context
325  *              region_context      - Region specific context
326  *
327  * RETURN:      Status
328  *
329  * DESCRIPTION: Setup a pci_bAR operation region
330  *
331  * MUTEX:       Assumes namespace is not locked
332  *
333  ******************************************************************************/
334
335 acpi_status
336 acpi_ev_pci_bar_region_setup(acpi_handle handle,
337                              u32 function,
338                              void *handler_context, void **region_context)
339 {
340         ACPI_FUNCTION_TRACE("ev_pci_bar_region_setup");
341
342         return_ACPI_STATUS(AE_OK);
343 }
344
345 /*******************************************************************************
346  *
347  * FUNCTION:    acpi_ev_cmos_region_setup
348  *
349  * PARAMETERS:  Handle              - Region we are interested in
350  *              Function            - Start or stop
351  *              handler_context     - Address space handler context
352  *              region_context      - Region specific context
353  *
354  * RETURN:      Status
355  *
356  * DESCRIPTION: Setup a CMOS operation region
357  *
358  * MUTEX:       Assumes namespace is not locked
359  *
360  ******************************************************************************/
361
362 acpi_status
363 acpi_ev_cmos_region_setup(acpi_handle handle,
364                           u32 function,
365                           void *handler_context, void **region_context)
366 {
367         ACPI_FUNCTION_TRACE("ev_cmos_region_setup");
368
369         return_ACPI_STATUS(AE_OK);
370 }
371
372 /*******************************************************************************
373  *
374  * FUNCTION:    acpi_ev_default_region_setup
375  *
376  * PARAMETERS:  Handle              - Region we are interested in
377  *              Function            - Start or stop
378  *              handler_context     - Address space handler context
379  *              region_context      - Region specific context
380  *
381  * RETURN:      Status
382  *
383  * DESCRIPTION: Default region initialization
384  *
385  ******************************************************************************/
386
387 acpi_status
388 acpi_ev_default_region_setup(acpi_handle handle,
389                              u32 function,
390                              void *handler_context, void **region_context)
391 {
392         ACPI_FUNCTION_TRACE("ev_default_region_setup");
393
394         if (function == ACPI_REGION_DEACTIVATE) {
395                 *region_context = NULL;
396         } else {
397                 *region_context = handler_context;
398         }
399
400         return_ACPI_STATUS(AE_OK);
401 }
402
403 /*******************************************************************************
404  *
405  * FUNCTION:    acpi_ev_initialize_region
406  *
407  * PARAMETERS:  region_obj      - Region we are initializing
408  *              acpi_ns_locked  - Is namespace locked?
409  *
410  * RETURN:      Status
411  *
412  * DESCRIPTION: Initializes the region, finds any _REG methods and saves them
413  *              for execution at a later time
414  *
415  *              Get the appropriate address space handler for a newly
416  *              created region.
417  *
418  *              This also performs address space specific initialization.  For
419  *              example, PCI regions must have an _ADR object that contains
420  *              a PCI address in the scope of the definition.  This address is
421  *              required to perform an access to PCI config space.
422  *
423  ******************************************************************************/
424
425 acpi_status
426 acpi_ev_initialize_region(union acpi_operand_object *region_obj,
427                           u8 acpi_ns_locked)
428 {
429         union acpi_operand_object *handler_obj;
430         union acpi_operand_object *obj_desc;
431         acpi_adr_space_type space_id;
432         struct acpi_namespace_node *node;
433         acpi_status status;
434         struct acpi_namespace_node *method_node;
435         acpi_name *reg_name_ptr = (acpi_name *) METHOD_NAME__REG;
436         union acpi_operand_object *region_obj2;
437
438         ACPI_FUNCTION_TRACE_U32("ev_initialize_region", acpi_ns_locked);
439
440         if (!region_obj) {
441                 return_ACPI_STATUS(AE_BAD_PARAMETER);
442         }
443
444         if (region_obj->common.flags & AOPOBJ_OBJECT_INITIALIZED) {
445                 return_ACPI_STATUS(AE_OK);
446         }
447
448         region_obj2 = acpi_ns_get_secondary_object(region_obj);
449         if (!region_obj2) {
450                 return_ACPI_STATUS(AE_NOT_EXIST);
451         }
452
453         node = acpi_ns_get_parent_node(region_obj->region.node);
454         space_id = region_obj->region.space_id;
455
456         /* Setup defaults */
457
458         region_obj->region.handler = NULL;
459         region_obj2->extra.method_REG = NULL;
460         region_obj->common.flags &= ~(AOPOBJ_SETUP_COMPLETE);
461         region_obj->common.flags |= AOPOBJ_OBJECT_INITIALIZED;
462
463         /* Find any "_REG" method associated with this region definition */
464
465         status = acpi_ns_search_node(*reg_name_ptr, node,
466                                      ACPI_TYPE_METHOD, &method_node);
467         if (ACPI_SUCCESS(status)) {
468                 /*
469                  * The _REG method is optional and there can be only one per region
470                  * definition.  This will be executed when the handler is attached
471                  * or removed
472                  */
473                 region_obj2->extra.method_REG = method_node;
474         }
475
476         /*
477          * The following loop depends upon the root Node having no parent
478          * ie: acpi_gbl_root_node->parent_entry being set to NULL
479          */
480         while (node) {
481                 /* Check to see if a handler exists */
482
483                 handler_obj = NULL;
484                 obj_desc = acpi_ns_get_attached_object(node);
485                 if (obj_desc) {
486                         /* Can only be a handler if the object exists */
487
488                         switch (node->type) {
489                         case ACPI_TYPE_DEVICE:
490
491                                 handler_obj = obj_desc->device.handler;
492                                 break;
493
494                         case ACPI_TYPE_PROCESSOR:
495
496                                 handler_obj = obj_desc->processor.handler;
497                                 break;
498
499                         case ACPI_TYPE_THERMAL:
500
501                                 handler_obj = obj_desc->thermal_zone.handler;
502                                 break;
503
504                         default:
505                                 /* Ignore other objects */
506                                 break;
507                         }
508
509                         while (handler_obj) {
510                                 /* Is this handler of the correct type? */
511
512                                 if (handler_obj->address_space.space_id ==
513                                     space_id) {
514                                         /* Found correct handler */
515
516                                         ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
517                                                           "Found handler %p for region %p in obj %p\n",
518                                                           handler_obj,
519                                                           region_obj,
520                                                           obj_desc));
521
522                                         status =
523                                             acpi_ev_attach_region(handler_obj,
524                                                                   region_obj,
525                                                                   acpi_ns_locked);
526
527                                         /*
528                                          * Tell all users that this region is usable by running the _REG
529                                          * method
530                                          */
531                                         if (acpi_ns_locked) {
532                                                 status =
533                                                     acpi_ut_release_mutex
534                                                     (ACPI_MTX_NAMESPACE);
535                                                 if (ACPI_FAILURE(status)) {
536                                                         return_ACPI_STATUS
537                                                             (status);
538                                                 }
539                                         }
540
541                                         status =
542                                             acpi_ev_execute_reg_method
543                                             (region_obj, 1);
544
545                                         if (acpi_ns_locked) {
546                                                 status =
547                                                     acpi_ut_acquire_mutex
548                                                     (ACPI_MTX_NAMESPACE);
549                                                 if (ACPI_FAILURE(status)) {
550                                                         return_ACPI_STATUS
551                                                             (status);
552                                                 }
553                                         }
554
555                                         return_ACPI_STATUS(AE_OK);
556                                 }
557
558                                 /* Try next handler in the list */
559
560                                 handler_obj = handler_obj->address_space.next;
561                         }
562                 }
563
564                 /*
565                  * This node does not have the handler we need;
566                  * Pop up one level
567                  */
568                 node = acpi_ns_get_parent_node(node);
569         }
570
571         /* If we get here, there is no handler for this region */
572
573         ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
574                           "No handler for region_type %s(%X) (region_obj %p)\n",
575                           acpi_ut_get_region_name(space_id), space_id,
576                           region_obj));
577
578         return_ACPI_STATUS(AE_NOT_EXIST);
579 }