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