Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/acpi/acpica/evregion.c
15111 views
1
/******************************************************************************
2
*
3
* Module Name: evregion - ACPI address_space (op_region) handler dispatch
4
*
5
*****************************************************************************/
6
7
/*
8
* Copyright (C) 2000 - 2011, 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] = {
73
ACPI_ADR_SPACE_SYSTEM_MEMORY,
74
ACPI_ADR_SPACE_SYSTEM_IO,
75
ACPI_ADR_SPACE_PCI_CONFIG,
76
ACPI_ADR_SPACE_DATA_TABLE
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
91
acpi_status acpi_ev_install_region_handlers(void)
92
{
93
acpi_status status;
94
u32 i;
95
96
ACPI_FUNCTION_TRACE(ev_install_region_handlers);
97
98
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
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++) {
123
status = acpi_ev_install_space_handler(acpi_gbl_root_node,
124
acpi_gbl_default_address_spaces
125
[i],
126
ACPI_DEFAULT_HANDLER,
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:
145
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
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 &
181
ACPI_ADDR_HANDLER_DEFAULT_INSTALLED) {
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
206
acpi_status acpi_ev_initialize_op_regions(void)
207
{
208
acpi_status status;
209
u32 i;
210
211
ACPI_FUNCTION_TRACE(ev_initialize_op_regions);
212
213
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
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 =
230
acpi_ev_execute_reg_methods(acpi_gbl_root_node,
231
acpi_gbl_default_address_spaces
232
[i]);
233
}
234
}
235
236
acpi_gbl_reg_methods_executed = TRUE;
237
238
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
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
255
acpi_status
256
acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
257
{
258
struct acpi_evaluate_info *info;
259
union acpi_operand_object *args[3];
260
union acpi_operand_object *region_obj2;
261
acpi_status status;
262
263
ACPI_FUNCTION_TRACE(ev_execute_reg_method);
264
265
region_obj2 = acpi_ns_get_secondary_object(region_obj);
266
if (!region_obj2) {
267
return_ACPI_STATUS(AE_NOT_EXIST);
268
}
269
270
if (region_obj2->extra.method_REG == NULL) {
271
return_ACPI_STATUS(AE_OK);
272
}
273
274
/* Allocate and initialize the evaluation information block */
275
276
info = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_evaluate_info));
277
if (!info) {
278
return_ACPI_STATUS(AE_NO_MEMORY);
279
}
280
281
info->prefix_node = region_obj2->extra.method_REG;
282
info->pathname = NULL;
283
info->parameters = args;
284
info->flags = ACPI_IGNORE_RETURN_VALUE;
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
* Function - Read or Write operation
333
* region_offset - Where in the region to read or write
334
* bit_width - Field width in bits (8, 16, 32, or 64)
335
* Value - Pointer to in or out value, must be
336
* a full 64-bit integer
337
*
338
* RETURN: Status
339
*
340
* DESCRIPTION: Dispatch an address space or operation region access to
341
* a previously installed handler.
342
*
343
******************************************************************************/
344
345
acpi_status
346
acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
347
u32 function,
348
u32 region_offset, u32 bit_width, u64 *value)
349
{
350
acpi_status status;
351
acpi_adr_space_handler handler;
352
acpi_adr_space_setup region_setup;
353
union acpi_operand_object *handler_desc;
354
union acpi_operand_object *region_obj2;
355
void *region_context = NULL;
356
357
ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
358
359
region_obj2 = acpi_ns_get_secondary_object(region_obj);
360
if (!region_obj2) {
361
return_ACPI_STATUS(AE_NOT_EXIST);
362
}
363
364
/* Ensure that there is a handler associated with this region */
365
366
handler_desc = region_obj->region.handler;
367
if (!handler_desc) {
368
ACPI_ERROR((AE_INFO,
369
"No handler for Region [%4.4s] (%p) [%s]",
370
acpi_ut_get_node_name(region_obj->region.node),
371
region_obj,
372
acpi_ut_get_region_name(region_obj->region.
373
space_id)));
374
375
return_ACPI_STATUS(AE_NOT_EXIST);
376
}
377
378
/*
379
* It may be the case that the region has never been initialized.
380
* Some types of regions require special init code
381
*/
382
if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
383
384
/* This region has not been initialized yet, do it */
385
386
region_setup = handler_desc->address_space.setup;
387
if (!region_setup) {
388
389
/* No initialization routine, exit with error */
390
391
ACPI_ERROR((AE_INFO,
392
"No init routine for region(%p) [%s]",
393
region_obj,
394
acpi_ut_get_region_name(region_obj->region.
395
space_id)));
396
return_ACPI_STATUS(AE_NOT_EXIST);
397
}
398
399
/*
400
* We must exit the interpreter because the region setup will
401
* potentially execute control methods (for example, the _REG method
402
* for this region)
403
*/
404
acpi_ex_exit_interpreter();
405
406
status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
407
handler_desc->address_space.context,
408
&region_context);
409
410
/* Re-enter the interpreter */
411
412
acpi_ex_enter_interpreter();
413
414
/* Check for failure of the Region Setup */
415
416
if (ACPI_FAILURE(status)) {
417
ACPI_EXCEPTION((AE_INFO, status,
418
"During region initialization: [%s]",
419
acpi_ut_get_region_name(region_obj->
420
region.
421
space_id)));
422
return_ACPI_STATUS(status);
423
}
424
425
/* Region initialization may have been completed by region_setup */
426
427
if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) {
428
region_obj->region.flags |= AOPOBJ_SETUP_COMPLETE;
429
430
if (region_obj2->extra.region_context) {
431
432
/* The handler for this region was already installed */
433
434
ACPI_FREE(region_context);
435
} else {
436
/*
437
* Save the returned context for use in all accesses to
438
* this particular region
439
*/
440
region_obj2->extra.region_context =
441
region_context;
442
}
443
}
444
}
445
446
/* We have everything we need, we can invoke the address space handler */
447
448
handler = handler_desc->address_space.handler;
449
450
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
451
"Handler %p (@%p) Address %8.8X%8.8X [%s]\n",
452
&region_obj->region.handler->address_space, handler,
453
ACPI_FORMAT_NATIVE_UINT(region_obj->region.address +
454
region_offset),
455
acpi_ut_get_region_name(region_obj->region.
456
space_id)));
457
458
if (!(handler_desc->address_space.handler_flags &
459
ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
460
/*
461
* For handlers other than the default (supplied) handlers, we must
462
* exit the interpreter because the handler *might* block -- we don't
463
* know what it will do, so we can't hold the lock on the intepreter.
464
*/
465
acpi_ex_exit_interpreter();
466
}
467
468
/* Call the handler */
469
470
status = handler(function,
471
(region_obj->region.address + region_offset),
472
bit_width, value, handler_desc->address_space.context,
473
region_obj2->extra.region_context);
474
475
if (ACPI_FAILURE(status)) {
476
ACPI_EXCEPTION((AE_INFO, status, "Returned by Handler for [%s]",
477
acpi_ut_get_region_name(region_obj->region.
478
space_id)));
479
}
480
481
if (!(handler_desc->address_space.handler_flags &
482
ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
483
/*
484
* We just returned from a non-default handler, we must re-enter the
485
* interpreter
486
*/
487
acpi_ex_enter_interpreter();
488
}
489
490
return_ACPI_STATUS(status);
491
}
492
493
/*******************************************************************************
494
*
495
* FUNCTION: acpi_ev_detach_region
496
*
497
* PARAMETERS: region_obj - Region Object
498
* acpi_ns_is_locked - Namespace Region Already Locked?
499
*
500
* RETURN: None
501
*
502
* DESCRIPTION: Break the association between the handler and the region
503
* this is a two way association.
504
*
505
******************************************************************************/
506
507
void
508
acpi_ev_detach_region(union acpi_operand_object *region_obj,
509
u8 acpi_ns_is_locked)
510
{
511
union acpi_operand_object *handler_obj;
512
union acpi_operand_object *obj_desc;
513
union acpi_operand_object **last_obj_ptr;
514
acpi_adr_space_setup region_setup;
515
void **region_context;
516
union acpi_operand_object *region_obj2;
517
acpi_status status;
518
519
ACPI_FUNCTION_TRACE(ev_detach_region);
520
521
region_obj2 = acpi_ns_get_secondary_object(region_obj);
522
if (!region_obj2) {
523
return_VOID;
524
}
525
region_context = &region_obj2->extra.region_context;
526
527
/* Get the address handler from the region object */
528
529
handler_obj = region_obj->region.handler;
530
if (!handler_obj) {
531
532
/* This region has no handler, all done */
533
534
return_VOID;
535
}
536
537
/* Find this region in the handler's list */
538
539
obj_desc = handler_obj->address_space.region_list;
540
last_obj_ptr = &handler_obj->address_space.region_list;
541
542
while (obj_desc) {
543
544
/* Is this the correct Region? */
545
546
if (obj_desc == region_obj) {
547
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
548
"Removing Region %p from address handler %p\n",
549
region_obj, handler_obj));
550
551
/* This is it, remove it from the handler's list */
552
553
*last_obj_ptr = obj_desc->region.next;
554
obj_desc->region.next = NULL; /* Must clear field */
555
556
if (acpi_ns_is_locked) {
557
status =
558
acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
559
if (ACPI_FAILURE(status)) {
560
return_VOID;
561
}
562
}
563
564
/* Now stop region accesses by executing the _REG method */
565
566
status =
567
acpi_ev_execute_reg_method(region_obj,
568
ACPI_REG_DISCONNECT);
569
if (ACPI_FAILURE(status)) {
570
ACPI_EXCEPTION((AE_INFO, status,
571
"from region _REG, [%s]",
572
acpi_ut_get_region_name
573
(region_obj->region.space_id)));
574
}
575
576
if (acpi_ns_is_locked) {
577
status =
578
acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
579
if (ACPI_FAILURE(status)) {
580
return_VOID;
581
}
582
}
583
584
/*
585
* If the region has been activated, call the setup handler with
586
* the deactivate notification
587
*/
588
if (region_obj->region.flags & AOPOBJ_SETUP_COMPLETE) {
589
region_setup = handler_obj->address_space.setup;
590
status =
591
region_setup(region_obj,
592
ACPI_REGION_DEACTIVATE,
593
handler_obj->address_space.
594
context, region_context);
595
596
/* Init routine may fail, Just ignore errors */
597
598
if (ACPI_FAILURE(status)) {
599
ACPI_EXCEPTION((AE_INFO, status,
600
"from region handler - deactivate, [%s]",
601
acpi_ut_get_region_name
602
(region_obj->region.
603
space_id)));
604
}
605
606
region_obj->region.flags &=
607
~(AOPOBJ_SETUP_COMPLETE);
608
}
609
610
/*
611
* Remove handler reference in the region
612
*
613
* NOTE: this doesn't mean that the region goes away, the region
614
* is just inaccessible as indicated to the _REG method
615
*
616
* If the region is on the handler's list, this must be the
617
* region's handler
618
*/
619
region_obj->region.handler = NULL;
620
acpi_ut_remove_reference(handler_obj);
621
622
return_VOID;
623
}
624
625
/* Walk the linked list of handlers */
626
627
last_obj_ptr = &obj_desc->region.next;
628
obj_desc = obj_desc->region.next;
629
}
630
631
/* If we get here, the region was not in the handler's region list */
632
633
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
634
"Cannot remove region %p from address handler %p\n",
635
region_obj, handler_obj));
636
637
return_VOID;
638
}
639
640
/*******************************************************************************
641
*
642
* FUNCTION: acpi_ev_attach_region
643
*
644
* PARAMETERS: handler_obj - Handler Object
645
* region_obj - Region Object
646
* acpi_ns_is_locked - Namespace Region Already Locked?
647
*
648
* RETURN: None
649
*
650
* DESCRIPTION: Create the association between the handler and the region
651
* this is a two way association.
652
*
653
******************************************************************************/
654
655
acpi_status
656
acpi_ev_attach_region(union acpi_operand_object *handler_obj,
657
union acpi_operand_object *region_obj,
658
u8 acpi_ns_is_locked)
659
{
660
661
ACPI_FUNCTION_TRACE(ev_attach_region);
662
663
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
664
"Adding Region [%4.4s] %p to address handler %p [%s]\n",
665
acpi_ut_get_node_name(region_obj->region.node),
666
region_obj, handler_obj,
667
acpi_ut_get_region_name(region_obj->region.
668
space_id)));
669
670
/* Link this region to the front of the handler's list */
671
672
region_obj->region.next = handler_obj->address_space.region_list;
673
handler_obj->address_space.region_list = region_obj;
674
675
/* Install the region's handler */
676
677
if (region_obj->region.handler) {
678
return_ACPI_STATUS(AE_ALREADY_EXISTS);
679
}
680
681
region_obj->region.handler = handler_obj;
682
acpi_ut_add_reference(handler_obj);
683
684
return_ACPI_STATUS(AE_OK);
685
}
686
687
/*******************************************************************************
688
*
689
* FUNCTION: acpi_ev_install_handler
690
*
691
* PARAMETERS: walk_namespace callback
692
*
693
* DESCRIPTION: This routine installs an address handler into objects that are
694
* of type Region or Device.
695
*
696
* If the Object is a Device, and the device has a handler of
697
* the same type then the search is terminated in that branch.
698
*
699
* This is because the existing handler is closer in proximity
700
* to any more regions than the one we are trying to install.
701
*
702
******************************************************************************/
703
704
static acpi_status
705
acpi_ev_install_handler(acpi_handle obj_handle,
706
u32 level, void *context, void **return_value)
707
{
708
union acpi_operand_object *handler_obj;
709
union acpi_operand_object *next_handler_obj;
710
union acpi_operand_object *obj_desc;
711
struct acpi_namespace_node *node;
712
acpi_status status;
713
714
ACPI_FUNCTION_NAME(ev_install_handler);
715
716
handler_obj = (union acpi_operand_object *)context;
717
718
/* Parameter validation */
719
720
if (!handler_obj) {
721
return (AE_OK);
722
}
723
724
/* Convert and validate the device handle */
725
726
node = acpi_ns_validate_handle(obj_handle);
727
if (!node) {
728
return (AE_BAD_PARAMETER);
729
}
730
731
/*
732
* We only care about regions and objects that are allowed to have
733
* address space handlers
734
*/
735
if ((node->type != ACPI_TYPE_DEVICE) &&
736
(node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
737
return (AE_OK);
738
}
739
740
/* Check for an existing internal object */
741
742
obj_desc = acpi_ns_get_attached_object(node);
743
if (!obj_desc) {
744
745
/* No object, just exit */
746
747
return (AE_OK);
748
}
749
750
/* Devices are handled different than regions */
751
752
if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
753
754
/* Check if this Device already has a handler for this address space */
755
756
next_handler_obj = obj_desc->device.handler;
757
while (next_handler_obj) {
758
759
/* Found a handler, is it for the same address space? */
760
761
if (next_handler_obj->address_space.space_id ==
762
handler_obj->address_space.space_id) {
763
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
764
"Found handler for region [%s] in device %p(%p) "
765
"handler %p\n",
766
acpi_ut_get_region_name
767
(handler_obj->address_space.
768
space_id), obj_desc,
769
next_handler_obj,
770
handler_obj));
771
772
/*
773
* Since the object we found it on was a device, then it
774
* means that someone has already installed a handler for
775
* the branch of the namespace from this device on. Just
776
* bail out telling the walk routine to not traverse this
777
* branch. This preserves the scoping rule for handlers.
778
*/
779
return (AE_CTRL_DEPTH);
780
}
781
782
/* Walk the linked list of handlers attached to this device */
783
784
next_handler_obj = next_handler_obj->address_space.next;
785
}
786
787
/*
788
* As long as the device didn't have a handler for this space we
789
* don't care about it. We just ignore it and proceed.
790
*/
791
return (AE_OK);
792
}
793
794
/* Object is a Region */
795
796
if (obj_desc->region.space_id != handler_obj->address_space.space_id) {
797
798
/* This region is for a different address space, just ignore it */
799
800
return (AE_OK);
801
}
802
803
/*
804
* Now we have a region and it is for the handler's address space type.
805
*
806
* First disconnect region for any previous handler (if any)
807
*/
808
acpi_ev_detach_region(obj_desc, FALSE);
809
810
/* Connect the region to the new handler */
811
812
status = acpi_ev_attach_region(handler_obj, obj_desc, FALSE);
813
return (status);
814
}
815
816
/*******************************************************************************
817
*
818
* FUNCTION: acpi_ev_install_space_handler
819
*
820
* PARAMETERS: Node - Namespace node for the device
821
* space_id - The address space ID
822
* Handler - Address of the handler
823
* Setup - Address of the setup function
824
* Context - Value passed to the handler on each access
825
*
826
* RETURN: Status
827
*
828
* DESCRIPTION: Install a handler for all op_regions of a given space_id.
829
* Assumes namespace is locked
830
*
831
******************************************************************************/
832
833
acpi_status
834
acpi_ev_install_space_handler(struct acpi_namespace_node * node,
835
acpi_adr_space_type space_id,
836
acpi_adr_space_handler handler,
837
acpi_adr_space_setup setup, void *context)
838
{
839
union acpi_operand_object *obj_desc;
840
union acpi_operand_object *handler_obj;
841
acpi_status status;
842
acpi_object_type type;
843
u8 flags = 0;
844
845
ACPI_FUNCTION_TRACE(ev_install_space_handler);
846
847
/*
848
* This registration is valid for only the types below and the root. This
849
* is where the default handlers get placed.
850
*/
851
if ((node->type != ACPI_TYPE_DEVICE) &&
852
(node->type != ACPI_TYPE_PROCESSOR) &&
853
(node->type != ACPI_TYPE_THERMAL) && (node != acpi_gbl_root_node)) {
854
status = AE_BAD_PARAMETER;
855
goto unlock_and_exit;
856
}
857
858
if (handler == ACPI_DEFAULT_HANDLER) {
859
flags = ACPI_ADDR_HANDLER_DEFAULT_INSTALLED;
860
861
switch (space_id) {
862
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
863
handler = acpi_ex_system_memory_space_handler;
864
setup = acpi_ev_system_memory_region_setup;
865
break;
866
867
case ACPI_ADR_SPACE_SYSTEM_IO:
868
handler = acpi_ex_system_io_space_handler;
869
setup = acpi_ev_io_space_region_setup;
870
break;
871
872
case ACPI_ADR_SPACE_PCI_CONFIG:
873
handler = acpi_ex_pci_config_space_handler;
874
setup = acpi_ev_pci_config_region_setup;
875
break;
876
877
case ACPI_ADR_SPACE_CMOS:
878
handler = acpi_ex_cmos_space_handler;
879
setup = acpi_ev_cmos_region_setup;
880
break;
881
882
case ACPI_ADR_SPACE_PCI_BAR_TARGET:
883
handler = acpi_ex_pci_bar_space_handler;
884
setup = acpi_ev_pci_bar_region_setup;
885
break;
886
887
case ACPI_ADR_SPACE_DATA_TABLE:
888
handler = acpi_ex_data_table_space_handler;
889
setup = NULL;
890
break;
891
892
default:
893
status = AE_BAD_PARAMETER;
894
goto unlock_and_exit;
895
}
896
}
897
898
/* If the caller hasn't specified a setup routine, use the default */
899
900
if (!setup) {
901
setup = acpi_ev_default_region_setup;
902
}
903
904
/* Check for an existing internal object */
905
906
obj_desc = acpi_ns_get_attached_object(node);
907
if (obj_desc) {
908
/*
909
* The attached device object already exists. Make sure the handler
910
* is not already installed.
911
*/
912
handler_obj = obj_desc->device.handler;
913
914
/* Walk the handler list for this device */
915
916
while (handler_obj) {
917
918
/* Same space_id indicates a handler already installed */
919
920
if (handler_obj->address_space.space_id == space_id) {
921
if (handler_obj->address_space.handler ==
922
handler) {
923
/*
924
* It is (relatively) OK to attempt to install the SAME
925
* handler twice. This can easily happen with the
926
* PCI_Config space.
927
*/
928
status = AE_SAME_HANDLER;
929
goto unlock_and_exit;
930
} else {
931
/* A handler is already installed */
932
933
status = AE_ALREADY_EXISTS;
934
}
935
goto unlock_and_exit;
936
}
937
938
/* Walk the linked list of handlers */
939
940
handler_obj = handler_obj->address_space.next;
941
}
942
} else {
943
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
944
"Creating object on Device %p while installing handler\n",
945
node));
946
947
/* obj_desc does not exist, create one */
948
949
if (node->type == ACPI_TYPE_ANY) {
950
type = ACPI_TYPE_DEVICE;
951
} else {
952
type = node->type;
953
}
954
955
obj_desc = acpi_ut_create_internal_object(type);
956
if (!obj_desc) {
957
status = AE_NO_MEMORY;
958
goto unlock_and_exit;
959
}
960
961
/* Init new descriptor */
962
963
obj_desc->common.type = (u8) type;
964
965
/* Attach the new object to the Node */
966
967
status = acpi_ns_attach_object(node, obj_desc, type);
968
969
/* Remove local reference to the object */
970
971
acpi_ut_remove_reference(obj_desc);
972
973
if (ACPI_FAILURE(status)) {
974
goto unlock_and_exit;
975
}
976
}
977
978
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
979
"Installing address handler for region %s(%X) on Device %4.4s %p(%p)\n",
980
acpi_ut_get_region_name(space_id), space_id,
981
acpi_ut_get_node_name(node), node, obj_desc));
982
983
/*
984
* Install the handler
985
*
986
* At this point there is no existing handler. Just allocate the object
987
* for the handler and link it into the list.
988
*/
989
handler_obj =
990
acpi_ut_create_internal_object(ACPI_TYPE_LOCAL_ADDRESS_HANDLER);
991
if (!handler_obj) {
992
status = AE_NO_MEMORY;
993
goto unlock_and_exit;
994
}
995
996
/* Init handler obj */
997
998
handler_obj->address_space.space_id = (u8) space_id;
999
handler_obj->address_space.handler_flags = flags;
1000
handler_obj->address_space.region_list = NULL;
1001
handler_obj->address_space.node = node;
1002
handler_obj->address_space.handler = handler;
1003
handler_obj->address_space.context = context;
1004
handler_obj->address_space.setup = setup;
1005
1006
/* Install at head of Device.address_space list */
1007
1008
handler_obj->address_space.next = obj_desc->device.handler;
1009
1010
/*
1011
* The Device object is the first reference on the handler_obj.
1012
* Each region that uses the handler adds a reference.
1013
*/
1014
obj_desc->device.handler = handler_obj;
1015
1016
/*
1017
* Walk the namespace finding all of the regions this
1018
* handler will manage.
1019
*
1020
* Start at the device and search the branch toward
1021
* the leaf nodes until either the leaf is encountered or
1022
* a device is detected that has an address handler of the
1023
* same type.
1024
*
1025
* In either case, back up and search down the remainder
1026
* of the branch
1027
*/
1028
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
1029
ACPI_NS_WALK_UNLOCK,
1030
acpi_ev_install_handler, NULL,
1031
handler_obj, NULL);
1032
1033
unlock_and_exit:
1034
return_ACPI_STATUS(status);
1035
}
1036
1037
/*******************************************************************************
1038
*
1039
* FUNCTION: acpi_ev_execute_reg_methods
1040
*
1041
* PARAMETERS: Node - Namespace node for the device
1042
* space_id - The address space ID
1043
*
1044
* RETURN: Status
1045
*
1046
* DESCRIPTION: Run all _REG methods for the input Space ID;
1047
* Note: assumes namespace is locked, or system init time.
1048
*
1049
******************************************************************************/
1050
1051
acpi_status
1052
acpi_ev_execute_reg_methods(struct acpi_namespace_node *node,
1053
acpi_adr_space_type space_id)
1054
{
1055
acpi_status status;
1056
1057
ACPI_FUNCTION_TRACE(ev_execute_reg_methods);
1058
1059
/*
1060
* Run all _REG methods for all Operation Regions for this space ID. This
1061
* is a separate walk in order to handle any interdependencies between
1062
* regions and _REG methods. (i.e. handlers must be installed for all
1063
* regions of this Space ID before we can run any _REG methods)
1064
*/
1065
status = acpi_ns_walk_namespace(ACPI_TYPE_ANY, node, ACPI_UINT32_MAX,
1066
ACPI_NS_WALK_UNLOCK, acpi_ev_reg_run,
1067
NULL, &space_id, NULL);
1068
1069
/* Special case for EC: handle "orphan" _REG methods with no region */
1070
1071
if (space_id == ACPI_ADR_SPACE_EC) {
1072
acpi_ev_orphan_ec_reg_method();
1073
}
1074
1075
return_ACPI_STATUS(status);
1076
}
1077
1078
/*******************************************************************************
1079
*
1080
* FUNCTION: acpi_ev_reg_run
1081
*
1082
* PARAMETERS: walk_namespace callback
1083
*
1084
* DESCRIPTION: Run _REG method for region objects of the requested space_iD
1085
*
1086
******************************************************************************/
1087
1088
static acpi_status
1089
acpi_ev_reg_run(acpi_handle obj_handle,
1090
u32 level, void *context, void **return_value)
1091
{
1092
union acpi_operand_object *obj_desc;
1093
struct acpi_namespace_node *node;
1094
acpi_adr_space_type space_id;
1095
acpi_status status;
1096
1097
space_id = *ACPI_CAST_PTR(acpi_adr_space_type, context);
1098
1099
/* Convert and validate the device handle */
1100
1101
node = acpi_ns_validate_handle(obj_handle);
1102
if (!node) {
1103
return (AE_BAD_PARAMETER);
1104
}
1105
1106
/*
1107
* We only care about regions.and objects that are allowed to have address
1108
* space handlers
1109
*/
1110
if ((node->type != ACPI_TYPE_REGION) && (node != acpi_gbl_root_node)) {
1111
return (AE_OK);
1112
}
1113
1114
/* Check for an existing internal object */
1115
1116
obj_desc = acpi_ns_get_attached_object(node);
1117
if (!obj_desc) {
1118
1119
/* No object, just exit */
1120
1121
return (AE_OK);
1122
}
1123
1124
/* Object is a Region */
1125
1126
if (obj_desc->region.space_id != space_id) {
1127
1128
/* This region is for a different address space, just ignore it */
1129
1130
return (AE_OK);
1131
}
1132
1133
status = acpi_ev_execute_reg_method(obj_desc, ACPI_REG_CONNECT);
1134
return (status);
1135
}
1136
1137
/*******************************************************************************
1138
*
1139
* FUNCTION: acpi_ev_orphan_ec_reg_method
1140
*
1141
* PARAMETERS: None
1142
*
1143
* RETURN: None
1144
*
1145
* DESCRIPTION: Execute an "orphan" _REG method that appears under the EC
1146
* device. This is a _REG method that has no corresponding region
1147
* within the EC device scope. The orphan _REG method appears to
1148
* have been enabled by the description of the ECDT in the ACPI
1149
* specification: "The availability of the region space can be
1150
* detected by providing a _REG method object underneath the
1151
* Embedded Controller device."
1152
*
1153
* To quickly access the EC device, we use the EC_ID that appears
1154
* within the ECDT. Otherwise, we would need to perform a time-
1155
* consuming namespace walk, executing _HID methods to find the
1156
* EC device.
1157
*
1158
******************************************************************************/
1159
1160
static void acpi_ev_orphan_ec_reg_method(void)
1161
{
1162
struct acpi_table_ecdt *table;
1163
acpi_status status;
1164
struct acpi_object_list args;
1165
union acpi_object objects[2];
1166
struct acpi_namespace_node *ec_device_node;
1167
struct acpi_namespace_node *reg_method;
1168
struct acpi_namespace_node *next_node;
1169
1170
ACPI_FUNCTION_TRACE(ev_orphan_ec_reg_method);
1171
1172
/* Get the ECDT (if present in system) */
1173
1174
status = acpi_get_table(ACPI_SIG_ECDT, 0,
1175
ACPI_CAST_INDIRECT_PTR(struct acpi_table_header,
1176
&table));
1177
if (ACPI_FAILURE(status)) {
1178
return_VOID;
1179
}
1180
1181
/* We need a valid EC_ID string */
1182
1183
if (!(*table->id)) {
1184
return_VOID;
1185
}
1186
1187
/* Namespace is currently locked, must release */
1188
1189
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
1190
1191
/* Get a handle to the EC device referenced in the ECDT */
1192
1193
status = acpi_get_handle(NULL,
1194
ACPI_CAST_PTR(char, table->id),
1195
ACPI_CAST_PTR(acpi_handle, &ec_device_node));
1196
if (ACPI_FAILURE(status)) {
1197
goto exit;
1198
}
1199
1200
/* Get a handle to a _REG method immediately under the EC device */
1201
1202
status = acpi_get_handle(ec_device_node,
1203
METHOD_NAME__REG, ACPI_CAST_PTR(acpi_handle,
1204
&reg_method));
1205
if (ACPI_FAILURE(status)) {
1206
goto exit;
1207
}
1208
1209
/*
1210
* Execute the _REG method only if there is no Operation Region in
1211
* this scope with the Embedded Controller space ID. Otherwise, it
1212
* will already have been executed. Note, this allows for Regions
1213
* with other space IDs to be present; but the code below will then
1214
* execute the _REG method with the EC space ID argument.
1215
*/
1216
next_node = acpi_ns_get_next_node(ec_device_node, NULL);
1217
while (next_node) {
1218
if ((next_node->type == ACPI_TYPE_REGION) &&
1219
(next_node->object) &&
1220
(next_node->object->region.space_id == ACPI_ADR_SPACE_EC)) {
1221
goto exit; /* Do not execute _REG */
1222
}
1223
next_node = acpi_ns_get_next_node(ec_device_node, next_node);
1224
}
1225
1226
/* Evaluate the _REG(EC,Connect) method */
1227
1228
args.count = 2;
1229
args.pointer = objects;
1230
objects[0].type = ACPI_TYPE_INTEGER;
1231
objects[0].integer.value = ACPI_ADR_SPACE_EC;
1232
objects[1].type = ACPI_TYPE_INTEGER;
1233
objects[1].integer.value = ACPI_REG_CONNECT;
1234
1235
status = acpi_evaluate_object(reg_method, NULL, &args, NULL);
1236
1237
exit:
1238
/* We ignore all errors from above, don't care */
1239
1240
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
1241
return_VOID;
1242
}
1243
1244