ReactOS 0.4.17-dev-1190-g4c812f4
namespace.h File Reference
#include <uacpi/types.h>
#include <uacpi/internal/shareable.h>
#include <uacpi/status.h>
#include <uacpi/namespace.h>
Include dependency graph for namespace.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  uacpi_namespace_node
 

Macros

#define UACPI_NAMESPACE_NODE_FLAG_ALIAS   (1 << 0)
 
#define UACPI_NAMESPACE_NODE_FLAG_DANGLING   (1u << 1)
 
#define UACPI_NAMESPACE_NODE_FLAG_TEMPORARY   (1u << 2)
 

Typedefs

typedef struct uacpi_namespace_node uacpi_namespace_node
 

Enumerations

enum  uacpi_may_search_above_parent { UACPI_MAY_SEARCH_ABOVE_PARENT_NO , UACPI_MAY_SEARCH_ABOVE_PARENT_YES }
 
enum  uacpi_permanent_only { UACPI_PERMANENT_ONLY_NO , UACPI_PERMANENT_ONLY_YES }
 
enum  uacpi_should_lock { UACPI_SHOULD_LOCK_NO , UACPI_SHOULD_LOCK_YES }
 

Functions

uacpi_status uacpi_initialize_namespace (void)
 
void uacpi_deinitialize_namespace (void)
 
uacpi_namespace_node * uacpi_namespace_node_alloc (uacpi_object_name name)
 
void uacpi_namespace_node_unref (uacpi_namespace_node *node)
 
uacpi_status uacpi_namespace_node_type_unlocked (const uacpi_namespace_node *node, uacpi_object_type *out_type)
 
uacpi_status uacpi_namespace_node_is_one_of_unlocked (const uacpi_namespace_node *node, uacpi_object_type_bits type_mask, uacpi_bool *out)
 
uacpi_status uacpi_namespace_node_next_typed_unlocked (uacpi_namespace_node *parent, uacpi_namespace_node **iter, uacpi_object_type_bits type_mask)
 
uacpi_object * uacpi_namespace_node_get_object (const uacpi_namespace_node *node)
 
uacpi_object * uacpi_namespace_node_get_object_typed (const uacpi_namespace_node *node, uacpi_object_type_bits type_mask)
 
uacpi_status uacpi_namespace_node_acquire_object (const uacpi_namespace_node *node, uacpi_object **out_obj)
 
uacpi_status uacpi_namespace_node_acquire_object_typed (const uacpi_namespace_node *node, uacpi_object_type_bits, uacpi_object **out_obj)
 
uacpi_status uacpi_namespace_node_reacquire_object (uacpi_object *obj)
 
uacpi_status uacpi_namespace_node_release_object (uacpi_object *obj)
 
uacpi_status uacpi_namespace_node_install (uacpi_namespace_node *parent, uacpi_namespace_node *node)
 
uacpi_status uacpi_namespace_node_uninstall (uacpi_namespace_node *node)
 
uacpi_namespace_node * uacpi_namespace_node_find_sub_node (uacpi_namespace_node *parent, uacpi_object_name name)
 
uacpi_status uacpi_namespace_node_resolve (uacpi_namespace_node *scope, const uacpi_char *path, enum uacpi_should_lock, enum uacpi_may_search_above_parent, enum uacpi_permanent_only, uacpi_namespace_node **out_node)
 
uacpi_status uacpi_namespace_do_for_each_child (uacpi_namespace_node *parent, uacpi_iteration_callback descending_callback, uacpi_iteration_callback ascending_callback, uacpi_object_type_bits, uacpi_u32 max_depth, enum uacpi_should_lock, enum uacpi_permanent_only, void *user)
 
uacpi_bool uacpi_namespace_node_is_dangling (uacpi_namespace_node *node)
 
uacpi_bool uacpi_namespace_node_is_temporary (uacpi_namespace_node *node)
 
uacpi_bool uacpi_namespace_node_is_predefined (uacpi_namespace_node *node)
 
uacpi_status uacpi_namespace_read_lock (void)
 
uacpi_status uacpi_namespace_read_unlock (void)
 
uacpi_status uacpi_namespace_write_lock (void)
 
uacpi_status uacpi_namespace_write_unlock (void)
 

Macro Definition Documentation

◆ UACPI_NAMESPACE_NODE_FLAG_ALIAS

#define UACPI_NAMESPACE_NODE_FLAG_ALIAS   (1 << 0)

Definition at line 10 of file namespace.h.

◆ UACPI_NAMESPACE_NODE_FLAG_DANGLING

#define UACPI_NAMESPACE_NODE_FLAG_DANGLING   (1u << 1)

Definition at line 19 of file namespace.h.

◆ UACPI_NAMESPACE_NODE_FLAG_TEMPORARY

#define UACPI_NAMESPACE_NODE_FLAG_TEMPORARY   (1u << 2)

Definition at line 25 of file namespace.h.

Typedef Documentation

◆ uacpi_namespace_node

Enumeration Type Documentation

◆ uacpi_may_search_above_parent

Enumerator
UACPI_MAY_SEARCH_ABOVE_PARENT_NO 
UACPI_MAY_SEARCH_ABOVE_PARENT_YES 

Definition at line 87 of file namespace.h.

87 {
90};
@ UACPI_MAY_SEARCH_ABOVE_PARENT_NO
Definition: namespace.h:88
@ UACPI_MAY_SEARCH_ABOVE_PARENT_YES
Definition: namespace.h:89

◆ uacpi_permanent_only

Enumerator
UACPI_PERMANENT_ONLY_NO 
UACPI_PERMANENT_ONLY_YES 

Definition at line 92 of file namespace.h.

92 {
95};
@ UACPI_PERMANENT_ONLY_YES
Definition: namespace.h:94
@ UACPI_PERMANENT_ONLY_NO
Definition: namespace.h:93

◆ uacpi_should_lock

Enumerator
UACPI_SHOULD_LOCK_NO 
UACPI_SHOULD_LOCK_YES 

Definition at line 97 of file namespace.h.

97 {
100};
@ UACPI_SHOULD_LOCK_YES
Definition: namespace.h:99
@ UACPI_SHOULD_LOCK_NO
Definition: namespace.h:98

Function Documentation

◆ uacpi_deinitialize_namespace()

void uacpi_deinitialize_namespace ( void  )

Definition at line 205 of file namespace.c.

206{
209 uacpi_u32 depth = 1;
210
212
214
215 while (depth) {
216 next = next == UACPI_NULL ? current->child : next->next;
217
218 /*
219 * The previous value of 'next' was the last child of this subtree,
220 * we can now remove the entire scope of 'current->child'
221 */
222 if (next == UACPI_NULL) {
223 depth--;
224
225 // Wipe the subtree
226 while (current->child != UACPI_NULL)
228
229 // Reset the pointers back as if this iteration never happened
230 next = current;
231 current = current->parent;
232
233 continue;
234 }
235
236 /*
237 * We have more nodes to process, proceed to the next one, either the
238 * child of the 'next' node, if one exists, or its peer
239 */
240 if (next->child) {
241 depth++;
242 current = next;
244 }
245
246 // This node has no children, move on to its peer
247 }
248
251
252 if (ret == UACPI_STATUS_OK)
254
256 g_uacpi_rt_ctx.root_object = UACPI_NULL;
257
258 uacpi_mutex_unref(g_uacpi_rt_ctx.global_lock_mutex);
259 g_uacpi_rt_ctx.global_lock_mutex = UACPI_NULL;
260
262}
uacpi_status uacpi_rw_lock_deinit(struct uacpi_rw_lock *lock)
Definition: mutex.c:331
struct uacpi_runtime_context g_uacpi_rt_ctx
Definition: uacpi.c:18
void uacpi_mutex_unref(uacpi_mutex *)
Definition: types.c:496
uint32_t uacpi_u32
Definition: types.h:21
#define UACPI_NULL
Definition: types.h:33
uacpi_status
Definition: status.h:10
@ UACPI_STATUS_OK
Definition: status.h:11
void uacpi_object_unref(uacpi_object *obj)
Definition: types.c:761
return ret
Definition: mutex.c:147
uacpi_status uacpi_namespace_write_unlock(void)
Definition: namespace.c:51
static void free_namespace_node(uacpi_handle handle)
Definition: namespace.c:140
static struct uacpi_rw_lock namespace_lock
Definition: namespace.c:34
uacpi_status uacpi_namespace_node_uninstall(uacpi_namespace_node *node)
Definition: namespace.c:356
uacpi_namespace_node * uacpi_namespace_root(void)
Definition: namespace.c:264
uacpi_status uacpi_namespace_write_lock(void)
Definition: namespace.c:46
static void namespace_node_detach_object(uacpi_namespace_node *node)
Definition: namespace.c:126
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
struct task_struct * current
Definition: linux.c:32
PSYMCRYPT_PARALLEL_HASH_OPERATION next
PSYMCRYPT_PARALLEL_HASH_OPERATION next

Referenced by uacpi_state_reset().

◆ uacpi_initialize_namespace()

uacpi_status uacpi_initialize_namespace ( void  )

Definition at line 156 of file namespace.c.

157{
162
165 return ret;
166
167 for (ns = 0; ns <= UACPI_PREDEFINED_NAMESPACE_MAX; ns++) {
170
174
177 );
178 if (uacpi_unlikely(node->object == UACPI_NULL)) {
181 }
182
184 }
185
188
189 /*
190 * Skip the installation of \_OSI if it was disabled by user.
191 * We still create the object, but it's not attached to the namespace.
192 */
195 continue;
196
199 );
200 }
201
202 return UACPI_STATUS_OK;
203}
uacpi_status uacpi_rw_lock_init(struct uacpi_rw_lock *lock)
Definition: mutex.c:314
static uacpi_bool uacpi_check_flag(uacpi_u64 flag)
Definition: context.h:90
struct uacpi_object * uacpi_create_internal_reference(enum uacpi_reference_kind kind, uacpi_object *child)
Definition: types.c:1456
@ UACPI_REFERENCE_KIND_NAMED
Definition: types.h:14
uacpi_predefined_namespace
Definition: namespace.h:16
@ UACPI_PREDEFINED_NAMESPACE_GPE
Definition: namespace.h:18
@ UACPI_PREDEFINED_NAMESPACE_MAX
Definition: namespace.h:27
@ UACPI_PREDEFINED_NAMESPACE_OSI
Definition: namespace.h:25
#define uacpi_unlikely(expr)
Definition: compiler.h:88
#define uacpi_unlikely_error(expr)
Definition: status.h:50
@ UACPI_STATUS_OUT_OF_MEMORY
Definition: status.h:13
static uacpi_object * make_object_for_predefined(enum uacpi_predefined_namespace ns)
Definition: namespace.c:56
uacpi_status uacpi_namespace_node_install(uacpi_namespace_node *parent, uacpi_namespace_node *node)
Definition: namespace.c:299
static uacpi_namespace_node predefined_namespaces[UACPI_PREDEFINED_NAMESPACE_MAX+1]
Definition: namespace.c:21
static void uacpi_shareable_init(uacpi_handle handle)
Definition: shareable.h:14
Definition: mxnamespace.c:38
#define UACPI_FLAG_NO_OSI
Definition: uacpi.h:100
Definition: dlist.c:348

Referenced by uacpi_initialize().

◆ uacpi_namespace_do_for_each_child()

uacpi_status uacpi_namespace_do_for_each_child ( uacpi_namespace_node *  parent,
uacpi_iteration_callback  descending_callback,
uacpi_iteration_callback  ascending_callback,
uacpi_object_type_bits  type_mask,
uacpi_u32  max_depth,
enum  uacpi_should_lock,
enum  uacpi_permanent_only,
void *  user 
)

Definition at line 841 of file namespace.c.

848{
853 uacpi_u32 depth = 1;
854
856
857 if (uacpi_unlikely(descending_callback == UACPI_NULL &&
858 ascending_callback == UACPI_NULL))
860
861 if (uacpi_unlikely(node == UACPI_NULL || max_depth == 0))
863
864 if (should_lock == UACPI_SHOULD_LOCK_YES) {
867 return ret;
868 }
869
870 if (node->child == UACPI_NULL)
871 goto out;
872
873 node = node->child;
874
875 while (depth) {
877 if (!matches) {
879 goto do_next;
880 }
881
882 if (permanent_only == UACPI_PERMANENT_ONLY_YES &&
885 goto do_next;
886 }
887
888 cb = walking_up ? ascending_callback : descending_callback;
889 if (cb != UACPI_NULL) {
890 if (should_lock == UACPI_SHOULD_LOCK_YES) {
893 return ret;
894 }
895
896 decision = cb(user, node, depth);
897 if (decision == UACPI_ITERATION_DECISION_BREAK)
898 return ret;
899
900 if (should_lock == UACPI_SHOULD_LOCK_YES) {
903 return ret;
904 }
905 } else {
907 }
908
909 do_next:
910 if (walking_up) {
911 if (node->next) {
912 node = node->next;
913 walking_up = UACPI_FALSE;
914 continue;
915 }
916
917 depth--;
918 node = node->parent;
919 continue;
920 }
921
922 switch (decision) {
924 if ((depth != max_depth) && (node->child != UACPI_NULL)) {
925 node = node->child;
926 depth++;
927 continue;
928 }
931 walking_up = UACPI_TRUE;
932 continue;
933 default:
935 goto out;
936 }
937 }
938
939out:
940 if (should_lock == UACPI_SHOULD_LOCK_YES)
942 return ret;
943}
void user(int argc, const char *argv[])
Definition: cmds.c:1350
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
#define UACPI_ENSURE_INIT_LEVEL_AT_LEAST(lvl)
Definition: context.h:127
uacpi_iteration_decision(* uacpi_iteration_callback)(void *user, uacpi_namespace_node *node, uacpi_u32 node_depth)
Definition: namespace.h:98
#define UACPI_FALLTHROUGH
Definition: compiler.h:100
bool uacpi_bool
Definition: types.h:31
#define UACPI_FALSE
Definition: types.h:30
#define UACPI_TRUE
Definition: types.h:29
@ UACPI_STATUS_INVALID_ARGUMENT
Definition: status.h:18
uacpi_iteration_decision
Definition: types.h:28
@ UACPI_ITERATION_DECISION_BREAK
Definition: types.h:30
@ UACPI_ITERATION_DECISION_NEXT_PEER
Definition: types.h:39
@ UACPI_ITERATION_DECISION_CONTINUE
Definition: types.h:29
@ UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED
Definition: types.h:72
uacpi_status uacpi_namespace_read_unlock(void)
Definition: namespace.c:41
uacpi_bool uacpi_namespace_node_is_temporary(uacpi_namespace_node *node)
Definition: namespace.c:345
uacpi_status uacpi_namespace_read_lock(void)
Definition: namespace.c:36
uacpi_status uacpi_namespace_node_is_one_of_unlocked(const uacpi_namespace_node *node, uacpi_object_type_bits type_mask, uacpi_bool *out)
Definition: namespace.c:797
#define matches(FN)
Definition: match.h:70
void * next
Definition: dlist.c:360
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by create_gpe_block(), object_replace_child(), reg_all_opregions(), run_orphan_ec_regs(), uacpi_events_match_post_dynamic_table_load(), uacpi_install_address_space_handler_with_flags(), uacpi_namespace_for_each_child(), uacpi_namespace_for_each_child_simple(), and uacpi_uninstall_address_space_handler().

◆ uacpi_namespace_node_acquire_object()

uacpi_status uacpi_namespace_node_acquire_object ( const uacpi_namespace_node *  node,
uacpi_object **  out_obj 
)

Definition at line 705 of file namespace.c.

708{
710 node, UACPI_OBJECT_ANY_BIT, out_obj
711 );
712}
@ UACPI_OBJECT_ANY_BIT
Definition: types.h:152
uacpi_status uacpi_namespace_node_acquire_object_typed(const uacpi_namespace_node *node, uacpi_object_type_bits type_mask, uacpi_object **out_obj)
Definition: namespace.c:677

◆ uacpi_namespace_node_acquire_object_typed()

uacpi_status uacpi_namespace_node_acquire_object_typed ( const uacpi_namespace_node *  node,
uacpi_object_type_bits  type_mask,
uacpi_object **  out_obj 
)

Definition at line 677 of file namespace.c.

681{
684
687 return ret;
688
690
691 if (uacpi_unlikely(obj == UACPI_NULL) ||
692 !uacpi_object_is_one_of(obj, type_mask)) {
694 goto out;
695 }
696
698 *out_obj = obj;
699
700out:
702 return ret;
703}
void uacpi_object_ref(uacpi_object *obj)
Definition: types.c:733
uacpi_bool uacpi_object_is_one_of(uacpi_object *, uacpi_object_type_bits type_mask)
Definition: types.c:996
uacpi_object * uacpi_namespace_node_get_object(const uacpi_namespace_node *node)
Definition: namespace.c:653

Referenced by uacpi_install_notify_handler(), uacpi_namespace_node_acquire_object(), and uacpi_uninstall_notify_handler().

◆ uacpi_namespace_node_alloc()

uacpi_namespace_node * uacpi_namespace_node_alloc ( uacpi_object_name  name)

Definition at line 281 of file namespace.c.

282{
284
287 return ret;
288
290 ret->name = name;
291 return ret;
292}
#define uacpi_kernel_alloc_zeroed
Definition: stdlib.h:127
Definition: name.c:39

Referenced by resolve_name_string().

◆ uacpi_namespace_node_find_sub_node()

uacpi_namespace_node * uacpi_namespace_node_find_sub_node ( uacpi_namespace_node *  parent,
uacpi_object_name  name 
)

Definition at line 453 of file namespace.c.

457{
459
460 if (parent == UACPI_NULL)
462
463 node = parent->child;
464
465 while (node) {
466 if (node->name.id == name.id)
467 return node;
468
469 node = node->next;
470 }
471
472 return UACPI_NULL;
473}
r parent
Definition: btrfs.c:3010

Referenced by resolve_name_string(), and uacpi_namespace_node_resolve().

◆ uacpi_namespace_node_get_object()

◆ uacpi_namespace_node_get_object_typed()

◆ uacpi_namespace_node_install()

uacpi_status uacpi_namespace_node_install ( uacpi_namespace_node *  parent,
uacpi_namespace_node *  node 
)

Definition at line 299 of file namespace.c.

303{
304 if (parent == UACPI_NULL)
306
308 uacpi_warn("attempting to install a dangling namespace node %.4s",
309 node->name.text);
311 }
312
313 if (parent->child == UACPI_NULL) {
314 parent->child = node;
315 } else {
316 uacpi_namespace_node *prev = parent->child;
317
318 for (;;) {
319 if (uacpi_unlikely(prev->name.id == node->name.id))
321
322 if (prev->next == UACPI_NULL)
323 break;
324
325 prev = prev->next;
326 }
327
328 prev->next = node;
329 }
330
331 node->parent = parent;
332 return UACPI_STATUS_OK;
333}
#define uacpi_warn(...)
Definition: log.h:35
@ UACPI_STATUS_AML_OBJECT_ALREADY_EXISTS
Definition: status.h:36
@ UACPI_STATUS_NAMESPACE_NODE_DANGLING
Definition: status.h:24
uacpi_bool uacpi_namespace_node_is_dangling(uacpi_namespace_node *node)
Definition: namespace.c:340
uacpi_object_name name
Definition: namespace.h:29
struct uacpi_namespace_node * next
Definition: namespace.h:34
uacpi_u32 id
Definition: types.h:25

Referenced by do_install_node_item(), and uacpi_initialize_namespace().

◆ uacpi_namespace_node_is_dangling()

uacpi_bool uacpi_namespace_node_is_dangling ( uacpi_namespace_node *  node)

Definition at line 340 of file namespace.c.

341{
343}
#define UACPI_NAMESPACE_NODE_FLAG_DANGLING
Definition: namespace.h:19

Referenced by uacpi_namespace_node_install(), uacpi_namespace_node_uninstall(), and uacpi_opregion_attach().

◆ uacpi_namespace_node_is_one_of_unlocked()

uacpi_status uacpi_namespace_node_is_one_of_unlocked ( const uacpi_namespace_node *  node,
uacpi_object_type_bits  type_mask,
uacpi_bool *  out 
)

◆ uacpi_namespace_node_is_predefined()

uacpi_bool uacpi_namespace_node_is_predefined ( uacpi_namespace_node *  node)

Definition at line 350 of file namespace.c.

Referenced by free_namespace_node().

◆ uacpi_namespace_node_is_temporary()

uacpi_bool uacpi_namespace_node_is_temporary ( uacpi_namespace_node *  node)

Definition at line 345 of file namespace.c.

346{
348}
#define UACPI_NAMESPACE_NODE_FLAG_TEMPORARY
Definition: namespace.h:25

Referenced by uacpi_namespace_do_for_each_child(), uacpi_namespace_node_next_typed_unlocked(), and uacpi_namespace_node_resolve().

◆ uacpi_namespace_node_next_typed_unlocked()

uacpi_status uacpi_namespace_node_next_typed_unlocked ( uacpi_namespace_node *  parent,
uacpi_namespace_node **  iter,
uacpi_object_type_bits  type_mask 
)

Definition at line 967 of file namespace.c.

971{
975
976 node = *iter;
977 if (node == UACPI_NULL)
978 node = parent->child;
979 else
980 node = node->next;
981
982 for (; node != UACPI_NULL; node = node->next) {
984 continue;
985
987 node, type_mask, &is_one_of
988 );
990 break;
991 if (is_one_of)
992 break;
993 }
994
995 if (node == UACPI_NULL)
997
999 *iter = node;
1000 return ret;
1001}
#define uacpi_likely_success(expr)
Definition: status.h:54
static uacpi_bool is_one_of(uacpi_char c, const uacpi_char *list)
Definition: stdlib.c:436

Referenced by run_orphan_reg(), and uacpi_namespace_node_next_typed().

◆ uacpi_namespace_node_reacquire_object()

uacpi_status uacpi_namespace_node_reacquire_object ( uacpi_object *  obj)

Definition at line 747 of file namespace.c.

750{
752}
static uacpi_status object_mutate_refcount(uacpi_object *obj, void(*cb)(uacpi_object *))
Definition: namespace.c:719

◆ uacpi_namespace_node_release_object()

uacpi_status uacpi_namespace_node_release_object ( uacpi_object *  obj)

Definition at line 754 of file namespace.c.

Referenced by free_notification_ctx().

◆ uacpi_namespace_node_resolve()

uacpi_status uacpi_namespace_node_resolve ( uacpi_namespace_node *  scope,
const uacpi_char *  path,
enum  uacpi_should_lock,
enum  uacpi_may_search_above_parent,
enum  uacpi_permanent_only,
uacpi_namespace_node **  out_node 
)

Definition at line 498 of file namespace.c.

505{
506 uacpi_namespace_node *cur_node = parent;
508 const uacpi_char *cursor = path;
509 uacpi_size bytes_left;
510 uacpi_char prev_char = 0;
511 uacpi_bool single_nameseg = UACPI_TRUE;
512
513 if (cur_node == UACPI_NULL)
514 cur_node = uacpi_namespace_root();
515
516 bytes_left = uacpi_strlen(path);
517
518 if (should_lock == UACPI_SHOULD_LOCK_YES) {
521 return ret;
522 }
523
524 for (;;) {
525 if (bytes_left == 0)
526 goto out;
527
528 switch (*cursor) {
529 case '\\':
530 single_nameseg = UACPI_FALSE;
531
532 if (prev_char == '^') {
534 goto out;
535 }
536
537 cur_node = uacpi_namespace_root();
538 break;
539 case '^':
540 single_nameseg = UACPI_FALSE;
541
542 // Tried to go behind root
543 if (uacpi_unlikely(cur_node == uacpi_namespace_root())) {
545 goto out;
546 }
547
548 cur_node = cur_node->parent;
549 break;
550 default:
551 break;
552 }
553
554 prev_char = *cursor;
555
556 switch (prev_char) {
557 case '^':
558 case '\\':
559 cursor++;
560 bytes_left--;
561 break;
562 default:
563 break;
564 }
565
566 if (prev_char != '^')
567 break;
568 }
569
570 while (bytes_left != 0) {
571 uacpi_object_name nameseg;
572
573 if (*cursor == '.') {
574 cursor++;
575 bytes_left--;
576 }
577
578 nameseg = segment_to_name(&cursor, &bytes_left);
579 if (bytes_left != 0 && single_nameseg)
580 single_nameseg = UACPI_FALSE;
581
582 cur_node = uacpi_namespace_node_find_sub_node(cur_node, nameseg);
583 if (cur_node == UACPI_NULL) {
584 if (may_search_above_parent == UACPI_MAY_SEARCH_ABOVE_PARENT_NO ||
585 !single_nameseg)
586 goto out;
587
588 parent = parent->parent;
589
590 while (parent) {
591 cur_node = uacpi_namespace_node_find_sub_node(parent, nameseg);
592 if (cur_node != UACPI_NULL)
593 goto out;
594
595 parent = parent->parent;
596 }
597
598 goto out;
599 }
600 }
601
602out:
604 uacpi_warn("invalid path '%s'", path);
605 goto out_read_unlock;
606 }
607
608 if (cur_node == UACPI_NULL) {
610 goto out_read_unlock;
611 }
612
613 if (uacpi_namespace_node_is_temporary(cur_node) &&
614 permanent_only == UACPI_PERMANENT_ONLY_YES) {
615 uacpi_warn("denying access to temporary namespace node '%.4s'",
616 cur_node->name.text);
618 goto out_read_unlock;
619 }
620
621 if (out_node != UACPI_NULL)
622 *out_node = cur_node;
623
624out_read_unlock:
625 if (should_lock == UACPI_SHOULD_LOCK_YES)
627 return ret;
628}
uacpi_size uacpi_strlen(const uacpi_char *str)
Definition: stdlib.c:72
size_t uacpi_size
Definition: types.h:37
char uacpi_char
Definition: types.h:44
@ UACPI_STATUS_DENIED
Definition: status.h:31
static uacpi_object_name segment_to_name(const uacpi_char **string, uacpi_size *in_out_size)
Definition: namespace.c:475
uacpi_namespace_node * uacpi_namespace_node_find_sub_node(uacpi_namespace_node *parent, uacpi_object_name name)
Definition: namespace.c:453
const char cursor[]
Definition: icontest.c:13
struct uacpi_namespace_node * parent
Definition: namespace.h:32
uacpi_char text[4]
Definition: types.h:24

Referenced by handle_load_table(), run_reg(), uacpi_eval(), uacpi_namespace_node_find(), and uacpi_namespace_node_resolve_from_aml_namepath().

◆ uacpi_namespace_node_type_unlocked()

uacpi_status uacpi_namespace_node_type_unlocked ( const uacpi_namespace_node *  node,
uacpi_object_type *  out_type 
)

Definition at line 764 of file namespace.c.

767{
769
772
776
777 *out_type = obj->type;
778 return UACPI_STATUS_OK;
779}

Referenced by uacpi_namespace_node_type().

◆ uacpi_namespace_node_uninstall()

uacpi_status uacpi_namespace_node_uninstall ( uacpi_namespace_node *  node)

Definition at line 356 of file namespace.c.

357{
359
361 uacpi_warn("attempting to uninstall a dangling namespace node %.4s",
362 node->name.text);
364 }
365
366 /*
367 * The way to trigger this is as follows:
368 *
369 * Method (FOO) {
370 * // Temporary device, will be deleted upon returning from FOO
371 * Device (\BAR) {
372 * }
373 *
374 * //
375 * // Load TBL where TBL is:
376 * // Scope (\BAR) {
377 * // Name (TEST, 123)
378 * // }
379 * //
380 * Load(TBL)
381 * }
382 *
383 * In the above example, TEST is a permanent node attached by bad AML to a
384 * temporary node created inside the FOO method at \BAR. The cleanup code
385 * will attempt to remove the \BAR device upon exit from FOO, but that is
386 * no longer possible as there's now a permanent child attached to it.
387 */
388 if (uacpi_unlikely(node->child != UACPI_NULL)) {
390 "refusing to uninstall node %.4s with a child (%.4s)",
391 node->name.text, node->child->name.text
392 );
393 return UACPI_STATUS_DENIED;
394 }
395
396 /*
397 * Even though namespace_node is reference-counted it still has an 'invalid'
398 * state that is entered after it is uninstalled from the global namespace.
399 *
400 * Reference counting is only needed to combat dangling pointer issues
401 * whereas bad AML might try to prolong a local object lifetime by
402 * returning it from a method, or CopyObject it somewhere. In that case the
403 * namespace node object itself is still alive, but no longer has a valid
404 * object associated with it.
405 *
406 * Example:
407 * Method (BAD) {
408 * OperationRegion(REG, SystemMemory, 0xDEADBEEF, 4)
409 * Field (REG, AnyAcc, NoLock) {
410 * FILD, 8,
411 * }
412 *
413 * Return (RefOf(FILD))
414 * }
415 *
416 * // Local0 is now the sole owner of the 'FILD' object that under the
417 * // hood is still referencing the 'REG' operation region object from
418 * // the 'BAD' method.
419 * Local0 = DerefOf(BAD())
420 *
421 * This is done to prevent potential very deep recursion where an object
422 * frees a namespace node that frees an attached object that frees a
423 * namespace node as well as potential infinite cycles between a namespace
424 * node and an object.
425 */
427
428 prev = node->parent ? node->parent->child : UACPI_NULL;
429
430 if (prev == node) {
431 node->parent->child = node->next;
432 } else {
433 while (uacpi_likely(prev != UACPI_NULL) && prev->next != node)
434 prev = prev->next;
435
436 if (uacpi_unlikely(prev == UACPI_NULL)) {
438 "trying to uninstall a node %.4s (%p) not linked to any peer",
439 node->name.text, node
440 );
442 }
443
444 prev->next = node->next;
445 }
446
449
450 return UACPI_STATUS_OK;
451}
#define uacpi_likely(expr)
Definition: compiler.h:89
@ UACPI_STATUS_INTERNAL_ERROR
Definition: status.h:21
void uacpi_namespace_node_unref(uacpi_namespace_node *node)
Definition: namespace.c:294

Referenced by call_frame_clear(), and uacpi_deinitialize_namespace().

◆ uacpi_namespace_node_unref()

void uacpi_namespace_node_unref ( uacpi_namespace_node *  node)

Definition at line 294 of file namespace.c.

295{
297}
static void uacpi_shareable_unref_and_delete_if_last(uacpi_handle handle, void(*do_free)(uacpi_handle))
Definition: shareable.h:60

Referenced by exec_op(), free_field_unit(), free_notification_ctx(), pop_item(), region_uninstall_handler(), and uacpi_namespace_node_uninstall().

◆ uacpi_namespace_read_lock()

◆ uacpi_namespace_read_unlock()

◆ uacpi_namespace_write_lock()

◆ uacpi_namespace_write_unlock()