Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
evregion.c
Go to the documentation of this file.
1 /******************************************************************************
2  *
3  * Module Name: evregion - ACPI address_space (op_region) handler dispatch
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2012, Intel Corp.
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 "accommon.h"
46 #include "acevents.h"
47 #include "acnamesp.h"
48 #include "acinterp.h"
49 
50 #define _COMPONENT ACPI_EVENTS
51 ACPI_MODULE_NAME("evregion")
52 
53 /* Local prototypes */
54 static u8
55 acpi_ev_has_default_handler(struct acpi_namespace_node *node,
56  acpi_adr_space_type space_id);
57 
58 static void acpi_ev_orphan_ec_reg_method(void);
59 
60 static acpi_status
61 acpi_ev_reg_run(acpi_handle obj_handle,
62  u32 level, void *context, void **return_value);
63 
64 static acpi_status
65 acpi_ev_install_handler(acpi_handle obj_handle,
66  u32 level, void *context, void **return_value);
67 
68 /* These are the address spaces that will get default handlers */
69 
70 #define ACPI_NUM_DEFAULT_SPACES 4
71 
72 static u8 acpi_gbl_default_address_spaces[ACPI_NUM_DEFAULT_SPACES] = {
77 };
78 
79 /*******************************************************************************
80  *
81  * FUNCTION: acpi_ev_install_region_handlers
82  *
83  * PARAMETERS: None
84  *
85  * RETURN: Status
86  *
87  * DESCRIPTION: Installs the core subsystem default address space handlers.
88  *
89  ******************************************************************************/
90 
92 {
94  u32 i;
95 
96  ACPI_FUNCTION_TRACE(ev_install_region_handlers);
97 
99  if (ACPI_FAILURE(status)) {
100  return_ACPI_STATUS(status);
101  }
102 
103  /*
104  * All address spaces (PCI Config, EC, SMBus) are scope dependent and
105  * registration must occur for a specific device.
106  *
107  * In the case of the system memory and IO address spaces there is
108  * currently no device associated with the address space. For these we
109  * use the root.
110  *
111  * We install the default PCI config space handler at the root so that
112  * this space is immediately available even though the we have not
113  * enumerated all the PCI Root Buses yet. This is to conform to the ACPI
114  * specification which states that the PCI config space must be always
115  * available -- even though we are nowhere near ready to find the PCI root
116  * buses at this point.
117  *
118  * NOTE: We ignore AE_ALREADY_EXISTS because this means that a handler
119  * has already been installed (via acpi_install_address_space_handler).
120  * Similar for AE_SAME_HANDLER.
121  */
122  for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
124  acpi_gbl_default_address_spaces
125  [i],
127  NULL, NULL);
128  switch (status) {
129  case AE_OK:
130  case AE_SAME_HANDLER:
131  case AE_ALREADY_EXISTS:
132 
133  /* These exceptions are all OK */
134 
135  status = AE_OK;
136  break;
137 
138  default:
139 
140  goto unlock_and_exit;
141  }
142  }
143 
144  unlock_and_exit:
146  return_ACPI_STATUS(status);
147 }
148 
149 /*******************************************************************************
150  *
151  * FUNCTION: acpi_ev_has_default_handler
152  *
153  * PARAMETERS: node - Namespace node for the device
154  * space_id - The address space ID
155  *
156  * RETURN: TRUE if default handler is installed, FALSE otherwise
157  *
158  * DESCRIPTION: Check if the default handler is installed for the requested
159  * space ID.
160  *
161  ******************************************************************************/
162 
163 static u8
164 acpi_ev_has_default_handler(struct acpi_namespace_node *node,
165  acpi_adr_space_type space_id)
166 {
167  union acpi_operand_object *obj_desc;
168  union acpi_operand_object *handler_obj;
169 
170  /* Must have an existing internal object */
171 
172  obj_desc = acpi_ns_get_attached_object(node);
173  if (obj_desc) {
174  handler_obj = obj_desc->device.handler;
175 
176  /* Walk the linked list of handlers for this object */
177 
178  while (handler_obj) {
179  if (handler_obj->address_space.space_id == space_id) {
180  if (handler_obj->address_space.handler_flags &
182  return (TRUE);
183  }
184  }
185 
186  handler_obj = handler_obj->address_space.next;
187  }
188  }
189 
190  return (FALSE);
191 }
192 
193 /*******************************************************************************
194  *
195  * FUNCTION: acpi_ev_initialize_op_regions
196  *
197  * PARAMETERS: None
198  *
199  * RETURN: Status
200  *
201  * DESCRIPTION: Execute _REG methods for all Operation Regions that have
202  * an installed default region handler.
203  *
204  ******************************************************************************/
205 
207 {
209  u32 i;
210 
211  ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
212 
214  if (ACPI_FAILURE(status)) {
215  return_ACPI_STATUS(status);
216  }
217 
218  /* Run the _REG methods for op_regions in each default address space */
219 
220  for (i = 0; i < ACPI_NUM_DEFAULT_SPACES; i++) {
221  /*
222  * Make sure the installed handler is the DEFAULT handler. If not the
223  * default, the _REG methods will have already been run (when the
224  * handler was installed)
225  */
226  if (acpi_ev_has_default_handler(acpi_gbl_root_node,
227  acpi_gbl_default_address_spaces
228  [i])) {
229  status =
231  acpi_gbl_default_address_spaces
232  [i]);
233  }
234  }
235 
237 
239  return_ACPI_STATUS(status);
240 }
241 
242 /*******************************************************************************
243  *
244  * FUNCTION: acpi_ev_execute_reg_method
245  *
246  * PARAMETERS: region_obj - Region object
247  * function - Passed to _REG: On (1) or Off (0)
248  *
249  * RETURN: Status
250  *
251  * DESCRIPTION: Execute _REG method for a region
252  *
253  ******************************************************************************/
254 
257 {
258  struct acpi_evaluate_info *info;
259  union acpi_operand_object *args[3];
260  union acpi_operand_object *region_obj2;
262 
263  ACPI_FUNCTION_TRACE(ev_execute_reg_method);
264 
265  region_obj2 = acpi_ns_get_secondary_object(region_obj);
266  if (!region_obj2) {
268  }
269 
270  if (region_obj2->extra.method_REG == NULL) {
272  }
273 
274  /* Allocate and initialize the evaluation information block */
275 
276  info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
277  if (!info) {
279  }
280 
281  info->prefix_node = region_obj2->extra.method_REG;
282  info->pathname = NULL;
283  info->parameters = args;
285 
286  /*
287  * The _REG method has two arguments:
288  *
289  * arg0 - Integer:
290  * Operation region space ID Same value as region_obj->Region.space_id
291  *
292  * arg1 - Integer:
293  * connection status 1 for connecting the handler, 0 for disconnecting
294  * the handler (Passed as a parameter)
295  */
296  args[0] =
297  acpi_ut_create_integer_object((u64) region_obj->region.space_id);
298  if (!args[0]) {
299  status = AE_NO_MEMORY;
300  goto cleanup1;
301  }
302 
303  args[1] = acpi_ut_create_integer_object((u64) function);
304  if (!args[1]) {
305  status = AE_NO_MEMORY;
306  goto cleanup2;
307  }
308 
309  args[2] = NULL; /* Terminate list */
310 
311  /* Execute the method, no return value */
312 
313  ACPI_DEBUG_EXEC(acpi_ut_display_init_pathname
314  (ACPI_TYPE_METHOD, info->prefix_node, NULL));
315 
316  status = acpi_ns_evaluate(info);
317  acpi_ut_remove_reference(args[1]);
318 
319  cleanup2:
320  acpi_ut_remove_reference(args[0]);
321 
322  cleanup1:
323  ACPI_FREE(info);
324  return_ACPI_STATUS(status);
325 }
326 
327 /*******************************************************************************
328  *
329  * FUNCTION: acpi_ev_address_space_dispatch
330  *
331  * PARAMETERS: region_obj - Internal region object
332  * field_obj - Corresponding field. Can be NULL.
333  * function - Read or Write operation
334  * region_offset - Where in the region to read or write
335  * bit_width - Field width in bits (8, 16, 32, or 64)
336  * value - Pointer to in or out value, must be
337  * a full 64-bit integer
338  *
339  * RETURN: Status
340  *
341  * DESCRIPTION: Dispatch an address space or operation region access to
342  * a previously installed handler.
343  *
344  ******************************************************************************/
345 
348  union acpi_operand_object *field_obj,
349  u32 function,
350  u32 region_offset, u32 bit_width, u64 *value)
351 {
354  acpi_adr_space_setup region_setup;
355  union acpi_operand_object *handler_desc;
356  union acpi_operand_object *region_obj2;
357  void *region_context = NULL;
359 
360  ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
361 
362  region_obj2 = acpi_ns_get_secondary_object(region_obj);
363  if (!region_obj2) {
365  }
366 
367  /* Ensure that there is a handler associated with this region */
368 
369  handler_desc = region_obj->region.handler;
370  if (!handler_desc) {
372  "No handler for Region [%4.4s] (%p) [%s]",
373  acpi_ut_get_node_name(region_obj->region.node),
374  region_obj,
375  acpi_ut_get_region_name(region_obj->region.
376  space_id)));
377 
379  }
380 
381  context = handler_desc->address_space.context;
382 
383  /*
384  * It may be the case that the region has never been initialized.
385  * Some types of regions require special init code
386  */
387  if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
388 
389  /* This region has not been initialized yet, do it */
390 
391  region_setup = handler_desc->address_space.setup;
392  if (!region_setup) {
393 
394  /* No initialization routine, exit with error */
395 
397  "No init routine for region(%p) [%s]",
398  region_obj,
399  acpi_ut_get_region_name(region_obj->region.
400  space_id)));
402  }
403 
404  /*
405  * We must exit the interpreter because the region setup will
406  * potentially execute control methods (for example, the _REG method
407  * for this region)
408  */
410 
411  status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
412  context, &region_context);
413 
414  /* Re-enter the interpreter */
415 
417 
418  /* Check for failure of the Region Setup */
419 
420  if (ACPI_FAILURE(status)) {
421  ACPI_EXCEPTION((AE_INFO, status,
422  "During region initialization: [%s]",
423  acpi_ut_get_region_name(region_obj->
424  region.
425  space_id)));
426  return_ACPI_STATUS(status);
427  }
428 
429  /* Region initialization may have been completed by region_setup */
430 
431  if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
432  region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
433 
434  if (region_obj2->extra.region_context) {
435 
436  /* The handler for this region was already installed */
437 
438  ACPI_FREE(region_context);
439  } else {
440  /*
441  * Save the returned context for use in all accesses to
442  * this particular region
443  */
444  region_obj2->extra.region_context =
445  region_context;
446  }
447  }
448  }
449 
450  /* We have everything we need, we can invoke the address space handler */
451 
452  handler = handler_desc->address_space.handler;
453 
455  "Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
456  &region_obj->region.handler->address_space, handler,
457  ACPI_FORMAT_NATIVE_UINT(region_obj->region.address +
458  region_offset),
459  acpi_ut_get_region_name(region_obj->region.
460  space_id)));
461 
462  /*
463  * Special handling for generic_serial_bus and general_purpose_io:
464  * There are three extra parameters that must be passed to the
465  * handler via the context:
466  * 1) Connection buffer, a resource template from Connection() op.
467  * 2) Length of the above buffer.
468  * 3) Actual access length from the access_as() op.
469  */
470  if (((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) ||
471  (region_obj->region.space_id == ACPI_ADR_SPACE_GPIO)) &&
472  context && field_obj) {
473 
474  /* Get the Connection (resource_template) buffer */
475 
476  context->connection = field_obj->field.resource_buffer;
477  context->length = field_obj->field.resource_length;
478  context->access_length = field_obj->field.access_length;
479  }
480 
481  if (!(handler_desc->address_space.handler_flags &
483  /*
484  * For handlers other than the default (supplied) handlers, we must
485  * exit the interpreter because the handler *might* block -- we don't
486  * know what it will do, so we can't hold the lock on the intepreter.
487  */
489  }
490 
491  /* Call the handler */
492 
493  status = handler(function,
494  (region_obj->region.address + region_offset),
495  bit_width, value, context,
496  region_obj2->extra.region_context);
497 
498  if (ACPI_FAILURE(status)) {
499  ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]",
500  acpi_ut_get_region_name(region_obj->region.
501  space_id)));
502  }
503 
504  if (!(handler_desc->address_space.handler_flags &
506  /*
507  * We just returned from a non-default handler, we must re-enter the
508  * interpreter
509  */
511  }
512 
513  return_ACPI_STATUS(status);
514 }
515 
516 /*******************************************************************************
517  *
518  * FUNCTION: acpi_ev_detach_region
519  *
520  * PARAMETERS: region_obj - Region Object
521  * acpi_ns_is_locked - Namespace Region Already Locked?
522  *
523  * RETURN: None
524  *
525  * DESCRIPTION: Break the association between the handler and the region
526  * this is a two way association.
527  *
528  ******************************************************************************/
529 
530 void
532  u8 acpi_ns_is_locked)
533 {
534  union acpi_operand_object *handler_obj;
535  union acpi_operand_object *obj_desc;
536  union acpi_operand_object **last_obj_ptr;
537  acpi_adr_space_setup region_setup;
538  void **region_context;
539  union acpi_operand_object *region_obj2;
541 
542  ACPI_FUNCTION_TRACE(ev_detach_region);
543 
544  region_obj2 = acpi_ns_get_secondary_object(region_obj);
545  if (!region_obj2) {
546  return_VOID;
547  }
548  region_context = &region_obj2->extra.region_context;
549 
550  /* Get the address handler from the region object */
551 
552  handler_obj = region_obj->region.handler;
553  if (!handler_obj) {
554 
555  /* This region has no handler, all done */
556 
557  return_VOID;
558  }
559 
560  /* Find this region in the handler's list */
561 
562  obj_desc = handler_obj->address_space.region_list;
563  last_obj_ptr = &handler_obj->address_space.region_list;
564 
565  while (obj_desc) {
566 
567  /* Is this the correct Region? */
568 
569  if (obj_desc == region_obj) {
571  "Removing Region %p from address handler %p\n",
572  region_obj, handler_obj));
573 
574  /* This is it, remove it from the handler's list */
575 
576  *last_obj_ptr = obj_desc->region.next;
577  obj_desc->region.next = NULL; /* Must clear field */
578 
579  if (acpi_ns_is_locked) {
580  status =
582  if (ACPI_FAILURE(status)) {
583  return_VOID;
584  }
585  }
586 
587  /* Now stop region accesses by executing the _REG method */
588 
589  status =
590  acpi_ev_execute_reg_method(region_obj,
592  if (ACPI_FAILURE(status)) {
593  ACPI_EXCEPTION((AE_INFO, status,
594  "from region _REG, [%s]",
596  (region_obj->region.space_id)));
597  }
598 
599  if (acpi_ns_is_locked) {
600  status =
602  if (ACPI_FAILURE(status)) {
603  return_VOID;
604  }
605  }
606 
607  /*
608  * If the region has been activated, call the setup handler with
609  * the deactivate notification
610  */
611  if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
612  region_setup = handler_obj->address_space.setup;
613  status =
614  region_setup(region_obj,
616  handler_obj->address_space.
617  context, region_context);
618 
619  /* Init routine may fail, Just ignore errors */
620 
621  if (ACPI_FAILURE(status)) {
622  ACPI_EXCEPTION((AE_INFO, status,
623  "from region handler - deactivate, [%s]",
625  (region_obj->region.
626  space_id)));
627  }
628 
629  region_obj->region.flags &=
631  }
632 
633  /*
634  * Remove handler reference in the region
635  *
636  * NOTE: this doesn't mean that the region goes away, the region
637  * is just inaccessible as indicated to the _REG method
638  *
639  * If the region is on the handler's list, this must be the
640  * region's handler
641  */
642  region_obj->region.handler = NULL;
643  acpi_ut_remove_reference(handler_obj);
644 
645  return_VOID;
646  }
647 
648  /* Walk the linked list of handlers */
649 
650  last_obj_ptr = &obj_desc->region.next;
651  obj_desc = obj_desc->region.next;
652  }
653 
654  /* If we get here, the region was not in the handler's region list */
655 
657  "Cannot remove region %p from address handler %p\n",
658  region_obj, handler_obj));
659 
660  return_VOID;
661 }
662 
663 /*******************************************************************************
664  *
665  * FUNCTION: acpi_ev_attach_region
666  *
667  * PARAMETERS: handler_obj - Handler Object
668  * region_obj - Region Object
669  * acpi_ns_is_locked - Namespace Region Already Locked?
670  *
671  * RETURN: None
672  *
673  * DESCRIPTION: Create the association between the handler and the region
674  * this is a two way association.
675  *
676  ******************************************************************************/
677 
680  union acpi_operand_object *region_obj,
681  u8 acpi_ns_is_locked)
682 {
683 
684  ACPI_FUNCTION_TRACE(ev_attach_region);
685 
687  "Adding Region [%4.4s] %p to address handler %p [%s]\n",
688  acpi_ut_get_node_name(region_obj->region.node),
689  region_obj, handler_obj,
690  acpi_ut_get_region_name(region_obj->region.
691  space_id)));
692 
693  /* Link this region to the front of the handler's list */
694 
695  region_obj->region.next = handler_obj->address_space.region_list;
696  handler_obj->address_space.region_list = region_obj;
697 
698  /* Install the region's handler */
699 
700  if (region_obj->region.handler) {
702  }
703 
704  region_obj->region.handler = handler_obj;
705  acpi_ut_add_reference(handler_obj);
706 
708 }
709 
710 /*******************************************************************************
711  *
712  * FUNCTION: acpi_ev_install_handler
713  *
714  * PARAMETERS: walk_namespace callback
715  *
716  * DESCRIPTION: This routine installs an address handler into objects that are
717  * of type Region or Device.
718  *
719  * If the Object is a Device, and the device has a handler of
720  * the same type then the search is terminated in that branch.
721  *
722  * This is because the existing handler is closer in proximity
723  * to any more regions than the one we are trying to install.
724  *
725  ******************************************************************************/
726 
727 static acpi_status
728 acpi_ev_install_handler(acpi_handle obj_handle,
729  u32 level, void *context, void **return_value)
730 {
731  union acpi_operand_object *handler_obj;
732  union acpi_operand_object *next_handler_obj;
733  union acpi_operand_object *obj_desc;
734  struct acpi_namespace_node *node;
736 
737  ACPI_FUNCTION_NAME(ev_install_handler);
738 
739  handler_obj = (union acpi_operand_object *)context;
740 
741  /* Parameter validation */
742 
743  if (!handler_obj) {
744  return (AE_OK);
745  }
746 
747  /* Convert and validate the device handle */
748 
749  node = acpi_ns_validate_handle(obj_handle);
750  if (!node) {
751  return (AE_BAD_PARAMETER);
752  }
753 
754  /*
755  * We only care about regions and objects that are allowed to have
756  * address space handlers
757  */
758  if ((node->type != ACPI_TYPE_DEVICE) &&
759  (node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
760  return (AE_OK);
761  }
762 
763  /* Check for an existing internal object */
764 
765  obj_desc = acpi_ns_get_attached_object(node);
766  if (!obj_desc) {
767 
768  /* No object, just exit */
769 
770  return (AE_OK);
771  }
772 
773  /* Devices are handled different than regions */
774 
775  if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
776 
777  /* Check if this Device already has a handler for this address space */
778 
779  next_handler_obj = obj_desc->device.handler;
780  while (next_handler_obj) {
781 
782  /* Found a handler, is it for the same address space? */
783 
784  if (next_handler_obj->address_space.space_id ==
785  handler_obj->address_space.space_id) {
787  "Found handler for region [%s] in device %p(%p) "
788  "handler %p\n",
790  (handler_obj->address_space.
791  space_id), obj_desc,
792  next_handler_obj,
793  handler_obj));
794 
795  /*
796  * Since the object we found it on was a device, then it
797  * means that someone has already installed a handler for
798  * the branch of the namespace from this device on. Just
799  * bail out telling the walk routine to not traverse this
800  * branch. This preserves the scoping rule for handlers.
801  */
802  return (AE_CTRL_DEPTH);
803  }
804 
805  /* Walk the linked list of handlers attached to this device */
806 
807  next_handler_obj = next_handler_obj->address_space.next;
808  }
809 
810  /*
811  * As long as the device didn't have a handler for this space we
812  * don't care about it. We just ignore it and proceed.
813  */
814  return (AE_OK);
815  }
816 
817  /* Object is a Region */
818 
819  if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
820 
821  /* This region is for a different address space, just ignore it */
822 
823  return (AE_OK);
824  }
825 
826  /*
827  * Now we have a region and it is for the handler's address space type.
828  *
829  * First disconnect region for any previous handler (if any)
830  */
831  acpi_ev_detach_region(obj_desc, FALSE);
832 
833  /* Connect the region to the new handler */
834 
835  status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
836  return (status);
837 }
838 
839 /*******************************************************************************
840  *
841  * FUNCTION: acpi_ev_install_space_handler
842  *
843  * PARAMETERS: node - Namespace node for the device
844  * space_id - The address space ID
845  * handler - Address of the handler
846  * setup - Address of the setup function
847  * context - Value passed to the handler on each access
848  *
849  * RETURN: Status
850  *
851  * DESCRIPTION: Install a handler for all op_regions of a given space_id.
852  * Assumes namespace is locked
853  *
854  ******************************************************************************/
855 
858  acpi_adr_space_type space_id,
859  acpi_adr_space_handler handler,
860  acpi_adr_space_setup setup, void *context)
861 {
862  union acpi_operand_object *obj_desc;
863  union acpi_operand_object *handler_obj;
866  u8 flags = 0;
867 
868  ACPI_FUNCTION_TRACE(ev_install_space_handler);
869 
870  /*
871  * This registration is valid for only the types below and the root. This
872  * is where the default handlers get placed.
873  */
874  if ((node->type != ACPI_TYPE_DEVICE) &&
875  (node->type != ACPI_TYPE_PROCESSOR) &&
876  (node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
877  status = AE_BAD_PARAMETER;
878  goto unlock_and_exit;
879  }
880 
881  if (handler == ACPI_DEFAULT_HANDLER) {
883 
884  switch (space_id) {
888  break;
889 
893  break;
894 
898  break;
899 
900  case ACPI_ADR_SPACE_CMOS:
901  handler = acpi_ex_cmos_space_handler;
903  break;
904 
908  break;
909 
912  setup = NULL;
913  break;
914 
915  default:
916  status = AE_BAD_PARAMETER;
917  goto unlock_and_exit;
918  }
919  }
920 
921  /* If the caller hasn't specified a setup routine, use the default */
922 
923  if (!setup) {
925  }
926 
927  /* Check for an existing internal object */
928 
929  obj_desc = acpi_ns_get_attached_object(node);
930  if (obj_desc) {
931  /*
932  * The attached device object already exists. Make sure the handler
933  * is not already installed.
934  */
935  handler_obj = obj_desc->device.handler;
936 
937  /* Walk the handler list for this device */
938 
939  while (handler_obj) {
940 
941  /* Same space_id indicates a handler already installed */
942 
943  if (handler_obj->address_space.space_id == space_id) {
944  if (handler_obj->address_space.handler ==
945  handler) {
946  /*
947  * It is (relatively) OK to attempt to install the SAME
948  * handler twice. This can easily happen with the
949  * PCI_Config space.
950  */
951  status = AE_SAME_HANDLER;
952  goto unlock_and_exit;
953  } else {
954  /* A handler is already installed */
955 
956  status = AE_ALREADY_EXISTS;
957  }
958  goto unlock_and_exit;
959  }
960 
961  /* Walk the linked list of handlers */
962 
963  handler_obj = handler_obj->address_space.next;
964  }
965  } else {
967  "Creating object on Device %p while installing handler\n",
968  node));
969 
970  /* obj_desc does not exist, create one */
971 
972  if (node->type == ACPI_TYPE_ANY) {
973  type = ACPI_TYPE_DEVICE;
974  } else {
975  type = node->type;
976  }
977 
978  obj_desc = acpi_ut_create_internal_object(type);
979  if (!obj_desc) {
980  status = AE_NO_MEMORY;
981  goto unlock_and_exit;
982  }
983 
984  /* Init new descriptor */
985 
986  obj_desc->common.type = (u8) type;
987 
988  /* Attach the new object to the Node */
989 
990  status = acpi_ns_attach_object(node, obj_desc, type);
991 
992  /* Remove local reference to the object */
993 
994  acpi_ut_remove_reference(obj_desc);
995 
996  if (ACPI_FAILURE(status)) {
997  goto unlock_and_exit;
998  }
999  }
1000 
1002  "Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
1003  acpi_ut_get_region_name(space_id), space_id,
1004  acpi_ut_get_node_name(node), node, obj_desc));
1005 
1006  /*
1007  * Install the handler
1008  *
1009  * At this point there is no existing handler. Just allocate the object
1010  * for the handler and link it into the list.
1011  */
1012  handler_obj =
1014  if (!handler_obj) {
1015  status = AE_NO_MEMORY;
1016  goto unlock_and_exit;
1017  }
1018 
1019  /* Init handler obj */
1020 
1021  handler_obj->address_space.space_id = (u8) space_id;
1022  handler_obj->address_space.handler_flags = flags;
1023  handler_obj->address_space.region_list = NULL;
1024  handler_obj->address_space.node = node;
1025  handler_obj->address_space.handler = handler;
1026  handler_obj->address_space.context = context;
1027  handler_obj->address_space.setup = setup;
1028 
1029  /* Install at head of Device.address_space list */
1030 
1031  handler_obj->address_space.next = obj_desc->device.handler;
1032 
1033  /*
1034  * The Device object is the first reference on the handler_obj.
1035  * Each region that uses the handler adds a reference.
1036  */
1037  obj_desc->device.handler = handler_obj;
1038 
1039  /*
1040  * Walk the namespace finding all of the regions this
1041  * handler will manage.
1042  *
1043  * Start at the device and search the branch toward
1044  * the leaf nodes until either the leaf is encountered or
1045  * a device is detected that has an address handler of the
1046  * same type.
1047  *
1048  * In either case, back up and search down the remainder
1049  * of the branch
1050  */
1053  acpi_ev_install_handler, NULL,
1054  handler_obj, NULL);
1055 
1056  unlock_and_exit:
1057  return_ACPI_STATUS(status);
1058 }
1059 
1060 /*******************************************************************************
1061  *
1062  * FUNCTION: acpi_ev_execute_reg_methods
1063  *
1064  * PARAMETERS: node - Namespace node for the device
1065  * space_id - The address space ID
1066  *
1067  * RETURN: Status
1068  *
1069  * DESCRIPTION: Run all _REG methods for the input Space ID;
1070  * Note: assumes namespace is locked, or system init time.
1071  *
1072  ******************************************************************************/
1073 
1076  acpi_adr_space_type space_id)
1077 {
1079 
1080  ACPI_FUNCTION_TRACE(ev_execute_reg_methods);
1081 
1082  /*
1083  * Run all _REG methods for all Operation Regions for this space ID. This
1084  * is a separate walk in order to handle any interdependencies between
1085  * regions and _REG methods. (i.e. handlers must be installed for all
1086  * regions of this Space ID before we can run any _REG methods)
1087  */
1089  ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
1090  NULL, &space_id, NULL);
1091 
1092  /* Special case for EC: handle "orphan" _REG methods with no region */
1093 
1094  if (space_id == ACPI_ADR_SPACE_EC) {
1095  acpi_ev_orphan_ec_reg_method();
1096  }
1097 
1098  return_ACPI_STATUS(status);
1099 }
1100 
1101 /*******************************************************************************
1102  *
1103  * FUNCTION: acpi_ev_reg_run
1104  *
1105  * PARAMETERS: walk_namespace callback
1106  *
1107  * DESCRIPTION: Run _REG method for region objects of the requested spaceID
1108  *
1109  ******************************************************************************/
1110 
1111 static acpi_status
1112 acpi_ev_reg_run(acpi_handle obj_handle,
1113  u32 level, void *context, void **return_value)
1114 {
1115  union acpi_operand_object *obj_desc;
1116  struct acpi_namespace_node *node;
1117  acpi_adr_space_type space_id;
1119 
1120  space_id = *ACPI_CAST_PTR(acpi_adr_space_type, context);
1121 
1122  /* Convert and validate the device handle */
1123 
1124  node = acpi_ns_validate_handle(obj_handle);
1125  if (!node) {
1126  return (AE_BAD_PARAMETER);
1127  }
1128 
1129  /*
1130  * We only care about regions.and objects that are allowed to have address
1131  * space handlers
1132  */
1133  if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
1134  return (AE_OK);
1135  }
1136 
1137  /* Check for an existing internal object */
1138 
1139  obj_desc = acpi_ns_get_attached_object(node);
1140  if (!obj_desc) {
1141 
1142  /* No object, just exit */
1143 
1144  return (AE_OK);
1145  }
1146 
1147  /* Object is a Region */
1148 
1149  if (obj_desc->region.space_id != space_id) {
1150 
1151  /* This region is for a different address space, just ignore it */
1152 
1153  return (AE_OK);
1154  }
1155 
1156  status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT);
1157  return (status);
1158 }
1159 
1160 /*******************************************************************************
1161  *
1162  * FUNCTION: acpi_ev_orphan_ec_reg_method
1163  *
1164  * PARAMETERS: None
1165  *
1166  * RETURN: None
1167  *
1168  * DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
1169  * device. This is a _REG method that has no corresponding region
1170  * within the EC device scope. The orphan _REG method appears to
1171  * have been enabled by the description of the ECDT in the ACPI
1172  * specification: "The availability of the region space can be
1173  * detected by providing a _REG method object underneath the
1174  * Embedded Controller device."
1175  *
1176  * To quickly access the EC device, we use the EC_ID that appears
1177  * within the ECDT. Otherwise, we would need to perform a time-
1178  * consuming namespace walk, executing _HID methods to find the
1179  * EC device.
1180  *
1181  ******************************************************************************/
1182 
1183 static void acpi_ev_orphan_ec_reg_method(void)
1184 {
1185  struct acpi_table_ecdt *table;
1187  struct acpi_object_list args;
1188  union acpi_object objects[2];
1189  struct acpi_namespace_node *ec_device_node;
1190  struct acpi_namespace_node *reg_method;
1192 
1193  ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);
1194 
1195  /* Get the ECDT (if present in system) */
1196 
1197  status = acpi_get_table(ACPI_SIG_ECDT, 0,
1199  &table));
1200  if (ACPI_FAILURE(status)) {
1201  return_VOID;
1202  }
1203 
1204  /* We need a valid EC_ID string */
1205 
1206  if (!(*table->id)) {
1207  return_VOID;
1208  }
1209 
1210  /* Namespace is currently locked, must release */
1211 
1213 
1214  /* Get a handle to the EC device referenced in the ECDT */
1215 
1216  status = acpi_get_handle(NULL,
1217  ACPI_CAST_PTR(char, table->id),
1218  ACPI_CAST_PTR(acpi_handle, &ec_device_node));
1219  if (ACPI_FAILURE(status)) {
1220  goto exit;
1221  }
1222 
1223  /* Get a handle to a _REG method immediately under the EC device */
1224 
1225  status = acpi_get_handle(ec_device_node,
1227  &reg_method));
1228  if (ACPI_FAILURE(status)) {
1229  goto exit;
1230  }
1231 
1232  /*
1233  * Execute the _REG method only if there is no Operation Region in
1234  * this scope with the Embedded Controller space ID. Otherwise, it
1235  * will already have been executed. Note, this allows for Regions
1236  * with other space IDs to be present; but the code below will then
1237  * execute the _REG method with the EC space ID argument.
1238  */
1239  next_node = acpi_ns_get_next_node(ec_device_node, NULL);
1240  while (next_node) {
1241  if ((next_node->type == ACPI_TYPE_REGION) &&
1242  (next_node->object) &&
1243  (next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) {
1244  goto exit; /* Do not execute _REG */
1245  }
1246  next_node = acpi_ns_get_next_node(ec_device_node, next_node);
1247  }
1248 
1249  /* Evaluate the _REG(EC,Connect) method */
1250 
1251  args.count = 2;
1252  args.pointer = objects;
1253  objects[0].type = ACPI_TYPE_INTEGER;
1254  objects[0].integer.value = ACPI_ADR_SPACE_EC;
1255  objects[1].type = ACPI_TYPE_INTEGER;
1256  objects[1].integer.value = ACPI_REG_CONNECT;
1257 
1258  status = acpi_evaluate_object(reg_method, NULL, &args, NULL);
1259 
1260  exit:
1261  /* We ignore all errors from above, don't care */
1262 
1264  return_VOID;
1265 }