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