ReactOS 0.4.17-dev-1190-g4c812f4
opregion.c File Reference
Include dependency graph for opregion.c:

Go to the source code of this file.

Classes

struct  opregion_iter_ctx
 
struct  reg_run_ctx
 

Macros

#define PCC_COMMAND_OFFSET   8
 
#define PCC_COMMAND_SIZE   4
 

Enumerations

enum  unreg { UNREG_NO = 0 , UNREG_YES }
 
enum  opregion_iter_action { OPREGION_ITER_ACTION_UNINSTALL , OPREGION_ITER_ACTION_INSTALL }
 

Functions

uacpi_status uacpi_initialize_opregion (void)
 
void uacpi_deinitialize_opregion (void)
 
void uacpi_trace_region_error (uacpi_namespace_node *node, uacpi_char *message, uacpi_status ret)
 
static void trace_region_io (uacpi_field_unit *field, uacpi_address_space space, uacpi_u64 offset, uacpi_region_op op, union uacpi_opregion_io_data data)
 
static uacpi_bool space_needs_reg (enum uacpi_address_space space)
 
static uacpi_status run_reg (uacpi_namespace_node *scope, uacpi_u16 space, uacpi_u8 connection_code)
 
uacpi_address_space_handlers * uacpi_node_get_address_space_handlers (uacpi_namespace_node *node)
 
static uacpi_address_space_handler * find_handler (uacpi_address_space_handlers *handlers, enum uacpi_address_space space)
 
static uacpi_operation_region * find_previous_region_link (uacpi_operation_region *region)
 
uacpi_status uacpi_opregion_attach (uacpi_namespace_node *node)
 
static void region_install_handler (uacpi_operation_region *region, uacpi_address_space_handler *handler)
 
static void region_uninstall_handler (uacpi_namespace_node *node, enum unreg unreg)
 
uacpi_status uacpi_upgrade_to_opregion_lock (void)
 
void uacpi_release_opregion_lock (void)
 
void uacpi_opregion_uninstall_handler (uacpi_namespace_node *node)
 
uacpi_bool uacpi_address_space_handler_is_default (uacpi_address_space_handler *handler)
 
static uacpi_bool handler_is_installed (struct opregion_iter_ctx *ctx)
 
static uacpi_iteration_decision do_install_or_uninstall_handler (uacpi_handle opaque, uacpi_namespace_node *node, uacpi_u32 depth)
 
static uacpi_iteration_decision do_run_reg (void *opaque, uacpi_namespace_node *node, uacpi_u32 depth)
 
static void run_orphan_reg (uacpi_namespace_node *node, enum uacpi_address_space space)
 
static uacpi_bool node_has_handler (uacpi_namespace_node *node, enum uacpi_address_space space)
 
static uacpi_iteration_decision do_run_orphan_ec_reg (void *opaque, uacpi_namespace_node *node, uacpi_u32 depth)
 
static void run_orphan_ec_regs (uacpi_namespace_node *device_node)
 
static uacpi_status reg_all_opregions (uacpi_namespace_node *device_node, enum uacpi_address_space space)
 
static uacpi_address_space_handlers * extract_handlers (uacpi_namespace_node *node)
 
uacpi_status uacpi_reg_all_opregions (uacpi_namespace_node *device_node, enum uacpi_address_space space)
 
uacpi_status uacpi_install_address_space_handler_with_flags (uacpi_namespace_node *device_node, enum uacpi_address_space space, uacpi_region_handler handler, uacpi_handle handler_context, uacpi_u16 flags)
 
uacpi_status uacpi_install_address_space_handler (uacpi_namespace_node *device_node, enum uacpi_address_space space, uacpi_region_handler handler, uacpi_handle handler_context)
 
uacpi_status uacpi_uninstall_address_space_handler (uacpi_namespace_node *device_node, enum uacpi_address_space space, uacpi_region_handler handler)
 
uacpi_status uacpi_initialize_opregion_node (uacpi_namespace_node *node)
 
uacpi_bool uacpi_is_buffer_access_address_space (uacpi_address_space space)
 
static uacpi_bool space_needs_bounds_checking (uacpi_address_space space)
 
static uacpi_bool pcc_write_completes_command (uacpi_field_unit *field, uacpi_u32 offset)
 
uacpi_status uacpi_dispatch_opregion_io (uacpi_field_unit *field, uacpi_u32 offset, uacpi_region_op op, union uacpi_opregion_io_data data)
 

Variables

struct uacpi_recursive_lock g_opregion_lock
 

Macro Definition Documentation

◆ PCC_COMMAND_OFFSET

#define PCC_COMMAND_OFFSET   8

Definition at line 1140 of file opregion.c.

◆ PCC_COMMAND_SIZE

#define PCC_COMMAND_SIZE   4

Definition at line 1141 of file opregion.c.

Enumeration Type Documentation

◆ opregion_iter_action

Enumerator
OPREGION_ITER_ACTION_UNINSTALL 
OPREGION_ITER_ACTION_INSTALL 

Definition at line 509 of file opregion.c.

509 {
512};
@ OPREGION_ITER_ACTION_UNINSTALL
Definition: opregion.c:510
@ OPREGION_ITER_ACTION_INSTALL
Definition: opregion.c:511

◆ unreg

Enumerator
UNREG_NO 
UNREG_YES 

Definition at line 367 of file opregion.c.

367 {
368 UNREG_NO = 0,
369 UNREG_YES,
370};
@ UNREG_YES
Definition: opregion.c:369
@ UNREG_NO
Definition: opregion.c:368

Function Documentation

◆ do_install_or_uninstall_handler()

static uacpi_iteration_decision do_install_or_uninstall_handler ( uacpi_handle  opaque,
uacpi_namespace_node *  node,
uacpi_u32  depth 
)
static

Definition at line 527 of file opregion.c.

530{
531 struct opregion_iter_ctx *ctx = opaque;
534
536
539 uacpi_operation_region *region = object->op_region;
540
541 if (region->space != ctx->handler->space)
543
544 if (ctx->action == OPREGION_ITER_ACTION_INSTALL) {
545 if (region->handler) {
547
548 /*
549 * The previous handler was invoked by the above, and might've
550 * uninstalled the one that we're in the middle of installing.
551 * There's nothing left for us to do in that case.
552 */
555
556 /*
557 * The previous handler was just told that the region is being
558 * detached, and is free to have done whatever it wanted to it
559 * in response, which includes getting rid of it. Make sure
560 * that there's still something to install the handler for.
561 */
564 );
565 if (uacpi_unlikely(object == UACPI_NULL))
567
568 region = object->op_region;
569 if (uacpi_unlikely(region->space != ctx->handler->space ||
570 region->handler != UACPI_NULL))
572 }
573
575 } else {
576 /*
577 * A region that has no handler is not ours to uninstall, and is
578 * nothing to complain about either: it's one that was left this
579 * way by a closer handler that is gone by now, or one that is in
580 * the middle of being detached by whoever has called us.
581 */
582 if (region->handler == UACPI_NULL)
584
585 if (uacpi_unlikely(region->handler != ctx->handler)) {
587 node, "handler mismatch for",
589 );
591 }
592
594 }
595
597 }
598
600 if (handlers == UACPI_NULL)
602
603 // Device already has a handler for this space installed
604 if (find_handler(handlers, ctx->handler->space) != UACPI_NULL)
606
608}
#define UACPI_UNUSED(x)
Definition: helpers.h:7
uacpi_object * uacpi_namespace_node_get_object_typed(const uacpi_namespace_node *node, uacpi_object_type_bits type_mask)
Definition: namespace.c:661
uacpi_object * uacpi_namespace_node_get_object(const uacpi_namespace_node *node)
Definition: namespace.c:653
#define uacpi_unlikely(expr)
Definition: compiler.h:88
#define UACPI_NULL
Definition: types.h:33
@ UACPI_STATUS_INTERNAL_ERROR
Definition: status.h:21
@ 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_OBJECT_OPERATION_REGION_BIT
Definition: types.h:144
@ UACPI_OBJECT_OPERATION_REGION
Definition: types.h:121
static xmlCharEncodingHandlerPtr * handlers
Definition: encoding.c:1380
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
static uacpi_address_space_handler * find_handler(uacpi_address_space_handlers *handlers, enum uacpi_address_space space)
Definition: opregion.c:202
void uacpi_trace_region_error(uacpi_namespace_node *node, uacpi_char *message, uacpi_status ret)
Definition: opregion.c:25
static void region_uninstall_handler(uacpi_namespace_node *node, enum unreg unreg)
Definition: opregion.c:372
static uacpi_bool handler_is_installed(struct opregion_iter_ctx *ctx)
Definition: opregion.c:522
static void region_install_handler(uacpi_operation_region *region, uacpi_address_space_handler *handler)
Definition: opregion.c:356
uacpi_address_space_handlers * uacpi_node_get_address_space_handlers(uacpi_namespace_node *node)
Definition: opregion.c:179
enum object_type type
Definition: dlist.c:348

Referenced by uacpi_install_address_space_handler_with_flags(), and uacpi_uninstall_address_space_handler().

◆ do_run_orphan_ec_reg()

static uacpi_iteration_decision do_run_orphan_ec_reg ( void *  opaque,
uacpi_namespace_node *  node,
uacpi_u32  depth 
)
static

Definition at line 710 of file opregion.c.

713{
714 static const uacpi_char *const ec_ids[] = { "PNP0C09", UACPI_NULL };
715 uacpi_namespace_node *device_node = opaque;
716 uacpi_bool has_own_handler = UACPI_FALSE;
717
719
722
723 if (node != device_node) {
724 has_own_handler = node_has_handler(
726 );
727 }
729
730 // That handler takes care of everything underneath it
731 if (has_own_handler)
733
734 // This might execute AML, so it's done with the namespace unlocked
735 if (!uacpi_device_matches_pnp_id(node, ec_ids))
737
740
741 // The handler might've been uninstalled while the namespace was unlocked
742 has_own_handler = node_has_handler(
744 );
745
746 if (has_own_handler)
748
751}
uacpi_status uacpi_namespace_write_unlock(void)
Definition: namespace.c:51
uacpi_status uacpi_namespace_write_lock(void)
Definition: namespace.c:46
bool uacpi_bool
Definition: types.h:31
#define UACPI_FALSE
Definition: types.h:30
char uacpi_char
Definition: types.h:44
#define uacpi_unlikely_error(expr)
Definition: status.h:50
@ UACPI_ADDRESS_SPACE_EMBEDDED_CONTROLLER
Definition: types.h:46
static void run_orphan_reg(uacpi_namespace_node *node, enum uacpi_address_space space)
Definition: opregion.c:671
static uacpi_bool node_has_handler(uacpi_namespace_node *node, enum uacpi_address_space space)
Definition: opregion.c:697
uacpi_bool uacpi_device_matches_pnp_id(uacpi_namespace_node *node, const uacpi_char *const *list)
Definition: utilities.c:905

Referenced by run_orphan_ec_regs().

◆ do_run_reg()

static uacpi_iteration_decision do_run_reg ( void *  opaque,
uacpi_namespace_node *  node,
uacpi_u32  depth 
)
static

Definition at line 616 of file opregion.c.

619{
620 struct reg_run_ctx *ctx = opaque;
624
626
628 region = obj->op_region;
629
630 if (region->space != ctx->space)
632
635
636 /*
637 * A region that has no handler is not accessible, so there's nothing for
638 * it to be connected to. The same goes for one that is in the middle of
639 * being disconnected, as its handler is about to be gone.
640 */
641 if (region->handler == UACPI_NULL ||
644
645 /*
646 * The _REG method is free to do whatever it wants to the region, which
647 * includes getting rid of it, e.g. by overwriting it via CopyObject. Keep
648 * it alive until we're done with it.
649 */
651
652 ret = run_reg(node->parent, region->space, ACPI_REG_CONNECT);
654 goto out;
655
657 ctx->reg_executed++;
658
660 ctx->reg_errors++;
661
662out:
665}
#define ACPI_REG_CONNECT
Definition: actypes.h:890
#define UACPI_OP_REGION_STATE_REG_EXECUTED
Definition: types.h:111
#define UACPI_OP_REGION_STATE_DISCONNECTING
Definition: types.h:117
uacpi_status
Definition: status.h:10
@ UACPI_STATUS_NOT_FOUND
Definition: status.h:17
void uacpi_object_ref(uacpi_object *obj)
Definition: types.c:733
void uacpi_object_unref(uacpi_object *obj)
Definition: types.c:761
return ret
Definition: mutex.c:147
static uacpi_status run_reg(uacpi_namespace_node *scope, uacpi_u16 space, uacpi_u8 connection_code)
Definition: opregion.c:123
wchar_t tm const _CrtWcstime_Writes_and_advances_ptr_ count wchar_t ** out
Definition: wcsftime.cpp:383

Referenced by reg_all_opregions().

◆ extract_handlers()

static uacpi_address_space_handlers * extract_handlers ( uacpi_namespace_node *  node)
static

Definition at line 827 of file opregion.c.

830{
831 uacpi_object *handlers_obj;
832
833 if (node == uacpi_namespace_root())
834 return g_uacpi_rt_ctx.root_object->address_space_handlers;
835
837 node,
840 );
841 if (uacpi_unlikely(handlers_obj == UACPI_NULL))
842 return UACPI_NULL;
843
844 return handlers_obj->address_space_handlers;
845}
struct uacpi_runtime_context g_uacpi_rt_ctx
Definition: uacpi.c:18
uacpi_namespace_node * uacpi_namespace_root(void)
Definition: namespace.c:264
@ UACPI_OBJECT_PROCESSOR_BIT
Definition: types.h:146
@ UACPI_OBJECT_THERMAL_ZONE_BIT
Definition: types.h:147
@ UACPI_OBJECT_DEVICE_BIT
Definition: types.h:140
uacpi_address_space_handlers * address_space_handlers
Definition: types.h:276

Referenced by uacpi_install_address_space_handler_with_flags(), uacpi_reg_all_opregions(), and uacpi_uninstall_address_space_handler().

◆ find_handler()

static uacpi_address_space_handler * find_handler ( uacpi_address_space_handlers *  handlers,
enum uacpi_address_space  space 
)
static

◆ find_previous_region_link()

static uacpi_operation_region * find_previous_region_link ( uacpi_operation_region *  region)
static

Definition at line 219 of file opregion.c.

222{
225
226 if (parent == region)
227 // This is the last attached region, it has no previous link
228 return region;
229
230 while (parent->next != region) {
231 parent = parent->next;
232
234 return UACPI_NULL;
235 }
236
237 return parent;
238}
r parent
Definition: btrfs.c:3010

Referenced by region_uninstall_handler().

◆ handler_is_installed()

static uacpi_bool handler_is_installed ( struct opregion_iter_ctx *  ctx)
static

Definition at line 522 of file opregion.c.

523{
524 return find_handler(ctx->handlers, ctx->handler->space) == ctx->handler;
525}

Referenced by do_install_or_uninstall_handler(), and uacpi_install_address_space_handler_with_flags().

◆ node_has_handler()

static uacpi_bool node_has_handler ( uacpi_namespace_node *  node,
enum uacpi_address_space  space 
)
static

Definition at line 697 of file opregion.c.

Referenced by do_run_orphan_ec_reg().

◆ pcc_write_completes_command()

static uacpi_bool pcc_write_completes_command ( uacpi_field_unit *  field,
uacpi_u32  offset 
)
static

Definition at line 1143 of file opregion.c.

1146{
1147 uacpi_u32 access_bits, last_bit, last_offset;
1148
1149 if (field->byte_offset < PCC_COMMAND_OFFSET ||
1150 field->byte_offset >= PCC_COMMAND_OFFSET + PCC_COMMAND_SIZE)
1151 return UACPI_FALSE;
1152
1153 access_bits = field->access_width_bytes * 8;
1154 last_bit = field->bit_offset_within_first_byte + field->bit_length - 1;
1155
1156 last_offset = field->byte_offset;
1157 last_offset += (last_bit / access_bits) * field->access_width_bytes;
1158
1159 return offset == last_offset;
1160}
uint32_t uacpi_u32
Definition: types.h:21
GLintptr offset
Definition: glext.h:5920
#define PCC_COMMAND_OFFSET
Definition: opregion.c:1140
#define PCC_COMMAND_SIZE
Definition: opregion.c:1141
Definition: parser.c:44

Referenced by uacpi_dispatch_opregion_io().

◆ reg_all_opregions()

static uacpi_status reg_all_opregions ( uacpi_namespace_node *  device_node,
enum uacpi_address_space  space 
)
static

Definition at line 780 of file opregion.c.

783{
785 struct reg_run_ctx ctx = { 0 };
786
787 ctx.space = space;
788
792
795
796 /*
797 * Registering non-permanent opregions is handled separately and should
798 * not be done by us.
799 */
801 device_node, do_run_reg, UACPI_NULL,
804 );
805
807 "activated all '%s' opregions controlled by '%.4s', "
808 "%zu _REG() calls (%zu errors)",
810 device_node->name.text, ctx.reg_executed, ctx.reg_errors
811 );
812
814 run_orphan_ec_regs(device_node);
815
816 /*
817 * Unlike an EC, a GPIO controller has no common PNP id to be looked for
818 * by. Its handler is normally installed to the controller itself though,
819 * so that is the only one that is checked.
820 */
822 run_orphan_reg(device_node, space);
823
824 return UACPI_STATUS_OK;
825}
#define uacpi_trace(...)
Definition: log.h:33
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)
Definition: namespace.c:841
@ UACPI_PERMANENT_ONLY_YES
Definition: namespace.h:94
@ UACPI_SHOULD_LOCK_NO
Definition: namespace.h:98
#define UACPI_MAX_DEPTH_ANY
Definition: namespace.h:102
@ UACPI_STATUS_INVALID_ARGUMENT
Definition: status.h:18
@ UACPI_STATUS_OK
Definition: status.h:11
@ UACPI_STATUS_NO_HANDLER
Definition: status.h:25
const uacpi_char * uacpi_address_space_to_string(uacpi_address_space space)
Definition: types.c:12
@ UACPI_ADDRESS_SPACE_GENERAL_PURPOSE_IO
Definition: types.h:51
static uacpi_iteration_decision do_run_reg(void *opaque, uacpi_namespace_node *node, uacpi_u32 depth)
Definition: opregion.c:616
static void run_orphan_ec_regs(uacpi_namespace_node *device_node)
Definition: opregion.c:762
uacpi_u8 space
Definition: opregion.c:611
uacpi_object_name name
Definition: namespace.h:29
uacpi_char text[4]
Definition: types.h:24

Referenced by uacpi_install_address_space_handler_with_flags(), and uacpi_reg_all_opregions().

◆ region_install_handler()

static void region_install_handler ( uacpi_operation_region *  region,
uacpi_address_space_handler *  handler 
)
static

Definition at line 356 of file opregion.c.

359{
360 region->handler = handler;
362
363 region->next = handler->regions;
364 handler->regions = region;
365}
static uacpi_u32 uacpi_shareable_ref(uacpi_handle handle)
Definition: shareable.h:40

Referenced by do_install_or_uninstall_handler(), and uacpi_initialize_opregion_node().

◆ region_uninstall_handler()

static void region_uninstall_handler ( uacpi_namespace_node *  node,
enum unreg  unreg 
)
static

Definition at line 372 of file opregion.c.

375{
380 uacpi_bool was_attached;
381
384 );
386 return;
387
388 region = obj->op_region;
389
390 handler = region->handler;
391 if (handler == UACPI_NULL)
392 return;
393
394 // We're in the middle of doing this already, see below
396 return;
397
400 uacpi_error("operation region @%p not in the handler@%p list(?)",
401 region, handler);
402 goto out;
403 } else if (link == region) {
404 link = link->next;
405 handler->regions = link;
406 } else {
407 link->next = region->next;
408 }
409
410out:
411 /*
412 * Both the _REG method and the handler are free to do whatever they want
413 * to the region once we invoke them, which includes getting rid of it,
414 * e.g. by overwriting it via CopyObject. That leads right back here, so
415 * make sure there's nothing left to do if it happens. It's also up to us
416 * to keep the region alive until we're done.
417 */
419
420 /*
421 * This is done while the region still has its handler, as _REG is what
422 * lets AML know that it's about to lose access to the region, and is
423 * thus its last chance to make use of it.
424 */
425 if ((region->state_flags & UACPI_OP_REGION_STATE_REG_EXECUTED) &&
426 unreg == UNREG_YES) {
427 region->state_flags &= ~UACPI_OP_REGION_STATE_REG_EXECUTED;
429
430 run_reg(node->parent, region->space, ACPI_REG_DISCONNECT);
431
432 region->state_flags &= ~UACPI_OP_REGION_STATE_DISCONNECTING;
433 }
434
435 /*
436 * The region has no handler as far as anyone else is concerned from this
437 * point on, which includes whatever the handler decides to do while it's
438 * detaching it. Note that the region might've only been attached by the
439 * _REG method above, so this is not something to check any earlier.
440 */
441 was_attached = region->state_flags & UACPI_OP_REGION_STATE_ATTACHED;
442
443 region->handler = UACPI_NULL;
444 region->state_flags &= ~UACPI_OP_REGION_STATE_ATTACHED;
445
446 if (was_attached) {
447 uacpi_region_detach_data detach_data = { 0 };
448
449 detach_data.region_node = node;
450 detach_data.region_context = region->user_context;
451 detach_data.handler_context = handler->user_context;
452
455
456 ret = handler->callback(UACPI_REGION_OP_DETACH, &detach_data);
457
460
463 node, "error during handler detach for", ret
464 );
465 }
466 }
467
470}
#define ACPI_REG_DISCONNECT
Definition: actypes.h:889
const WCHAR * link
Definition: db.cpp:998
#define uacpi_error(...)
Definition: log.h:36
void uacpi_namespace_node_unref(uacpi_namespace_node *node)
Definition: namespace.c:294
void uacpi_address_space_handler_unref(uacpi_address_space_handler *handler)
Definition: types.c:552
#define UACPI_OP_REGION_STATE_ATTACHED
Definition: types.h:114
@ UACPI_REGION_OP_DETACH
Definition: types.h:377
static uacpi_operation_region * find_previous_region_link(uacpi_operation_region *region)
Definition: opregion.c:219
unreg
Definition: opregion.c:367
uacpi_namespace_node * region_node
Definition: types.h:517

Referenced by do_install_or_uninstall_handler(), and uacpi_opregion_uninstall_handler().

◆ run_orphan_ec_regs()

static void run_orphan_ec_regs ( uacpi_namespace_node *  device_node)
static

Definition at line 762 of file opregion.c.

763{
765
767
768 decision = do_run_orphan_ec_reg(device_node, device_node, 0);
769 if (decision == UACPI_ITERATION_DECISION_CONTINUE) {
771 device_node, do_run_orphan_ec_reg, UACPI_NULL,
774 );
775 }
776
778}
@ UACPI_SHOULD_LOCK_YES
Definition: namespace.h:99
uacpi_iteration_decision
Definition: types.h:28
static uacpi_iteration_decision do_run_orphan_ec_reg(void *opaque, uacpi_namespace_node *node, uacpi_u32 depth)
Definition: opregion.c:710

Referenced by reg_all_opregions().

◆ run_orphan_reg()

static void run_orphan_reg ( uacpi_namespace_node *  node,
enum uacpi_address_space  space 
)
static

Definition at line 671 of file opregion.c.

674{
676
677 for (;;) {
679
682 );
683 if (ret != UACPI_STATUS_OK)
684 /*
685 * No opregion child of this device is of this address space, so
686 * this _REG is indeed orphan as far as we're concerned.
687 */
688 break;
689
690 if (uacpi_namespace_node_get_object(child)->op_region->space == space)
691 return;
692 }
693
695}
uacpi_status uacpi_namespace_node_next_typed_unlocked(uacpi_namespace_node *parent, uacpi_namespace_node **iter, uacpi_object_type_bits type_mask)
Definition: namespace.c:967
static HWND child
Definition: cursoricon.c:298

Referenced by do_run_orphan_ec_reg(), and reg_all_opregions().

◆ run_reg()

static uacpi_status run_reg ( uacpi_namespace_node *  scope,
uacpi_u16  space,
uacpi_u8  connection_code 
)
static

Definition at line 123 of file opregion.c.

126{
128 uacpi_namespace_node *reg_node;
129 uacpi_object_array method_args;
130 uacpi_object *reg_obj, *args[2];
131
133 scope, "_REG", UACPI_SHOULD_LOCK_NO,
135 );
137 return ret;
138
141 );
142 if (uacpi_unlikely(reg_obj == UACPI_NULL))
143 return UACPI_STATUS_OK;
144
146 if (uacpi_unlikely(args[0] == UACPI_NULL))
148
150 if (uacpi_unlikely(args[1] == UACPI_NULL)) {
153 }
154
155 args[0]->integer = space;
156 args[1]->integer = connection_code;
157 method_args.objects = args;
158 method_args.count = 2;
159
161 reg_node, reg_obj->method, &method_args, UACPI_NULL
162 );
164 const uacpi_char *path;
165
168 "error during _REG execution for %s (%s): %s", path,
170 );
172 }
173
176 return ret;
177}
@ UACPI_PERMANENT_ONLY_NO
Definition: namespace.h:93
@ UACPI_MAY_SEARCH_ABOVE_PARENT_NO
Definition: namespace.h:88
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: namespace.c:498
uacpi_object * uacpi_create_object(uacpi_object_type type)
Definition: types.c:328
const uacpi_char * uacpi_namespace_node_generate_absolute_path(const uacpi_namespace_node *node)
Definition: namespace.c:1053
@ UACPI_STATUS_OUT_OF_MEMORY
Definition: status.h:13
const uacpi_char * uacpi_status_to_string(uacpi_status)
Definition: uacpi.c:61
@ UACPI_OBJECT_METHOD_BIT
Definition: types.h:142
@ UACPI_OBJECT_INTEGER
Definition: types.h:112
void uacpi_free_dynamic_string(const uacpi_char *str)
Definition: utilities.c:1148
uacpi_status uacpi_execute_control_method(uacpi_namespace_node *scope, uacpi_control_method *method, const uacpi_object_array *args, uacpi_object **ret)
Definition: interpreter.c:6479
#define args
Definition: format.c:66
Definition: match.c:390
uacpi_object ** objects
Definition: types.h:290
uacpi_size count
Definition: types.h:291
uacpi_control_method * method
Definition: types.h:267

Referenced by do_run_reg(), region_uninstall_handler(), run_orphan_reg(), and uacpi_initialize_opregion_node().

◆ space_needs_bounds_checking()

static uacpi_bool space_needs_bounds_checking ( uacpi_address_space  space)
static

Definition at line 1125 of file opregion.c.

1126{
1129}
uacpi_bool uacpi_is_buffer_access_address_space(uacpi_address_space space)
Definition: opregion.c:1111

Referenced by uacpi_dispatch_opregion_io().

◆ space_needs_reg()

static uacpi_bool space_needs_reg ( enum uacpi_address_space  space)
static

Definition at line 112 of file opregion.c.

113{
117 return UACPI_FALSE;
118
119 return UACPI_TRUE;
120}
#define UACPI_TRUE
Definition: types.h:29
@ UACPI_ADDRESS_SPACE_SYSTEM_MEMORY
Definition: types.h:43
@ UACPI_ADDRESS_SPACE_TABLE_DATA
Definition: types.h:58
@ UACPI_ADDRESS_SPACE_SYSTEM_IO
Definition: types.h:44

Referenced by uacpi_initialize_opregion_node(), uacpi_install_address_space_handler_with_flags(), and uacpi_reg_all_opregions().

◆ trace_region_io()

static void trace_region_io ( uacpi_field_unit *  field,
uacpi_address_space  space,
uacpi_u64  offset,
uacpi_region_op  op,
union uacpi_opregion_io_data  data 
)
static

Definition at line 47 of file opregion.c.

51{
52 const uacpi_char *path;
53 const uacpi_char *type_str;
54
56 return;
57
58 switch (op) {
60 type_str = "read from";
61 break;
63 type_str = "write to";
64 break;
65 default:
66 type_str = "<INVALID-OP>";
67 }
68
70
71 switch (space) {
76 "write-then-read from [%s] %s[0x%016"UACPI_PRIX64"] = "
77 "<buffer of %zu bytes>", path,
79 UACPI_FMT64(offset), data.buffer.length
80 );
81 break;
85 "%s [%s] %s[0x%016"UACPI_PRIX64"] = "
86 "<buffer of %zu bytes>", type_str, path,
88 UACPI_FMT64(offset), data.buffer.length
89 );
90 break;
93 "%s [%s] %s pins[%u..%u] = 0x%"UACPI_PRIX64,
95 field->pin_offset, (field->pin_offset + field->bit_length) - 1,
96 UACPI_FMT64(*data.integer)
97 );
98 break;
99 default:
101 "%s [%s] (%d bytes) %s[0x%016"UACPI_PRIX64"] = 0x%"UACPI_PRIX64,
102 type_str, path, field->access_width_bytes,
105 );
106 break;
107 }
108
110}
UINT op
Definition: effect.c:235
static uacpi_bool uacpi_should_log(enum uacpi_log_level lvl)
Definition: context.h:95
@ UACPI_LOG_TRACE
Definition: log.h:18
#define UACPI_PRIX64
Definition: types.h:61
#define UACPI_FMT64(val)
Definition: types.h:62
@ UACPI_REGION_OP_WRITE
Definition: types.h:381
@ UACPI_REGION_OP_READ
Definition: types.h:380
@ UACPI_ADDRESS_SPACE_IPMI
Definition: types.h:50
@ UACPI_ADDRESS_SPACE_PRM
Definition: types.h:54
@ UACPI_ADDRESS_SPACE_FFIXEDHW
Definition: types.h:55
@ UACPI_ADDRESS_SPACE_GENERIC_SERIAL_BUS
Definition: types.h:52
@ UACPI_ADDRESS_SPACE_SMBUS
Definition: types.h:47
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

Referenced by uacpi_dispatch_opregion_io().

◆ uacpi_address_space_handler_is_default()

uacpi_bool uacpi_address_space_handler_is_default ( uacpi_address_space_handler *  handler)

Definition at line 502 of file opregion.c.

505{
507}
#define UACPI_ADDRESS_SPACE_HANDLER_DEFAULT
Definition: types.h:73

Referenced by uacpi_namespace_initialize().

◆ uacpi_deinitialize_opregion()

void uacpi_deinitialize_opregion ( void  )

Definition at line 20 of file opregion.c.

21{
23}
uacpi_status uacpi_recursive_lock_deinit(struct uacpi_recursive_lock *lock)
Definition: mutex.c:265
struct uacpi_recursive_lock g_opregion_lock
Definition: opregion.c:13

Referenced by uacpi_state_reset().

◆ uacpi_dispatch_opregion_io()

uacpi_status uacpi_dispatch_opregion_io ( uacpi_field_unit *  field,
uacpi_u32  offset,
uacpi_region_op  op,
union uacpi_opregion_io_data  data 
)

Definition at line 1162 of file opregion.c.

1166{
1172 uacpi_u64 abs_offset, offset_end = offset;
1173 uacpi_bool is_oob = UACPI_FALSE;
1174 uacpi_region_op orig_op = op;
1175
1176 union {
1184 } handler_data;
1185
1186 ret = uacpi_opregion_attach(field->region);
1189 field->region, "unable to attach", ret
1190 );
1191 return ret;
1192 }
1193
1196 );
1199
1200 region = obj->op_region;
1201 space = region->space;
1202 handler = region->handler;
1203
1204 abs_offset = region->offset + offset;
1205 offset_end += field->access_width_bytes;
1206
1208 is_oob = region->length < offset_end || abs_offset < offset;
1209 if (uacpi_unlikely(is_oob)) {
1210 const uacpi_char *path;
1211
1214 "out-of-bounds access to opregion %s[0x%"UACPI_PRIX64"->"
1215 "0x%"UACPI_PRIX64"] at 0x%"UACPI_PRIX64" (idx=%u, width=%d)",
1216 path, UACPI_FMT64(region->offset),
1217 UACPI_FMT64(region->offset + region->length),
1218 UACPI_FMT64(abs_offset), offset, field->access_width_bytes
1219 );
1222 }
1223
1224 handler_data.rw.region_context = region->user_context;
1225 handler_data.rw.handler_context = handler->user_context;
1226
1227 switch (region->space) {
1230
1231 cursor = region->internal_buffer + offset;
1232
1233 /*
1234 * Reads from PCC just return the current contents of the internal
1235 * buffer.
1236 */
1237 if (op == UACPI_REGION_OP_READ) {
1239 data.integer, cursor, sizeof(*data.integer),
1240 field->access_width_bytes
1241 );
1242 goto io_done;
1243 }
1244
1245 uacpi_memcpy(cursor, data.integer, field->access_width_bytes);
1246
1247 /*
1248 * Dispatch a PCC send command if this was a write to the command field
1249 *
1250 * ACPI 6.5: 14.3. Extended PCC Subspace Shared Memory Region
1251 *
1252 * Note that a PCC region covers whatever follows the signature that
1253 * the shared memory region starts with, so the offset of every field
1254 * is 4 bytes less than what it is there.
1255 */
1257 uacpi_memzero(&handler_data.pcc.buffer, sizeof(handler_data.pcc.buffer));
1258 handler_data.pcc.buffer.bytes = region->internal_buffer;
1259 handler_data.pcc.buffer.length = region->length;
1260
1262 break;
1263 }
1264
1265 // No dispatch needed, IO is done
1266 goto io_done;
1267 }
1269 handler_data.gpio.pin_offset = field->pin_offset;
1270 handler_data.gpio.num_pins = field->bit_length;
1271 handler_data.gpio.value = *data.integer;
1272
1274 field->connection, &handler_data.gpio.connection
1275 );
1277 goto io_done;
1278
1281 break;
1283 handler_data.ipmi.in_out_message = data.buffer;
1284 handler_data.ipmi.command = abs_offset;
1286 break;
1288 handler_data.ffixedhw.in_out_message = data.buffer;
1289 handler_data.ffixedhw.command = abs_offset;
1291 break;
1293 handler_data.prm.in_out_message = data.buffer;
1295 break;
1299 field->connection, &handler_data.serial.connection
1300 );
1302 goto io_done;
1303
1304 handler_data.serial.command = abs_offset;
1305 handler_data.serial.in_out_buffer = data.buffer;
1306 handler_data.serial.access_attribute = field->attributes;
1307
1308 switch (field->attributes) {
1312 handler_data.serial.access_length = field->access_length;
1313 break;
1314 default:
1315 handler_data.serial.access_length = 0;
1316 }
1317
1320 break;
1321 default:
1322 handler_data.rw.byte_width = field->access_width_bytes;
1323 handler_data.rw.offset = abs_offset;
1324 handler_data.rw.value = *data.integer;
1325 break;
1326 }
1327
1330
1331 ret = handler->callback(op, &handler_data);
1332
1335
1336io_done:
1338 uacpi_trace_region_error(field->region, "unable to perform IO", ret);
1339 return ret;
1340 }
1341
1342 if (orig_op == UACPI_REGION_OP_READ) {
1343 switch (space) {
1350 break;
1352 *data.integer = handler_data.gpio.value;
1353 break;
1354 default:
1355 *data.integer = handler_data.rw.value;
1356 break;
1357 }
1358 }
1359
1360 trace_region_io(field, space, abs_offset, orig_op, data);
1361 return ret;
1362}
#define uacpi_memzero(ptr, size)
Definition: stdlib.h:99
#define uacpi_memcpy
Definition: stdlib.h:34
void uacpi_memcpy_zerout(void *dst, const void *src, uacpi_size dst_size, uacpi_size src_size)
Definition: stdlib.c:112
#define uacpi_likely(expr)
Definition: compiler.h:89
uint64_t uacpi_u64
Definition: types.h:22
uint8_t uacpi_u8
Definition: types.h:19
@ UACPI_STATUS_AML_OUT_OF_BOUNDS_INDEX
Definition: status.h:40
@ UACPI_ACCESS_ATTRIBUTE_RAW_BYTES
Definition: types.h:493
@ UACPI_ACCESS_ATTRIBUTE_RAW_PROCESS_BYTES
Definition: types.h:494
@ UACPI_ACCESS_ATTRIBUTE_BYTES
Definition: types.h:490
uacpi_region_op
Definition: types.h:373
@ UACPI_REGION_OP_FFIXEDHW_COMMAND
Definition: types.h:394
@ UACPI_REGION_OP_PCC_SEND
Definition: types.h:384
@ UACPI_REGION_OP_GPIO_READ
Definition: types.h:387
@ UACPI_REGION_OP_SERIAL_WRITE
Definition: types.h:401
@ UACPI_REGION_OP_PRM_COMMAND
Definition: types.h:397
@ UACPI_REGION_OP_GPIO_WRITE
Definition: types.h:388
@ UACPI_REGION_OP_SERIAL_READ
Definition: types.h:400
@ UACPI_REGION_OP_IPMI_COMMAND
Definition: types.h:391
uacpi_address_space
Definition: types.h:42
@ UACPI_ADDRESS_SPACE_PCC
Definition: types.h:53
uacpi_status uacpi_object_get_string_or_buffer(uacpi_object *, uacpi_data_view *out)
Definition: types.c:1058
uint32_t serial
Definition: fsck.fat.h:29
const char cursor[]
Definition: icontest.c:13
static void trace_region_io(uacpi_field_unit *field, uacpi_address_space space, uacpi_u64 offset, uacpi_region_op op, union uacpi_opregion_io_data data)
Definition: opregion.c:47
static uacpi_bool space_needs_bounds_checking(uacpi_address_space space)
Definition: opregion.c:1125
uacpi_status uacpi_opregion_attach(uacpi_namespace_node *node)
Definition: opregion.c:240
static uacpi_bool pcc_write_completes_command(uacpi_field_unit *field, uacpi_u32 offset)
Definition: opregion.c:1143
#define rw
Definition: rosglue.h:38

Referenced by access_field_unit().

◆ uacpi_initialize_opregion()

uacpi_status uacpi_initialize_opregion ( void  )

Definition at line 15 of file opregion.c.

16{
18}
uacpi_status uacpi_recursive_lock_init(struct uacpi_recursive_lock *lock)
Definition: mutex.c:253

Referenced by uacpi_initialize().

◆ uacpi_initialize_opregion_node()

uacpi_status uacpi_initialize_opregion_node ( uacpi_namespace_node *  node)

Definition at line 1065 of file opregion.c.

1066{
1068 uacpi_namespace_node *parent = node->parent;
1072
1075 return ret;
1076
1079
1080 while (parent) {
1082 if (handlers != UACPI_NULL) {
1084
1085 if (handler != UACPI_NULL) {
1088 break;
1089 }
1090 }
1091
1092 parent = parent->parent;
1093 }
1094
1095 if (ret != UACPI_STATUS_OK)
1096 goto out;
1097 if (!space_needs_reg(region->space))
1098 goto out;
1100 goto out;
1101
1102 if (run_reg(node->parent, region->space, ACPI_REG_CONNECT) !=
1105
1106out:
1108 return ret;
1109}
uacpi_status uacpi_recursive_lock_release(struct uacpi_recursive_lock *lock)
Definition: mutex.c:305
@ UACPI_INIT_LEVEL_NAMESPACE_LOADED
Definition: types.h:78
uacpi_status uacpi_upgrade_to_opregion_lock(void)
Definition: opregion.c:472
static uacpi_bool space_needs_reg(enum uacpi_address_space space)
Definition: opregion.c:112
uacpi_operation_region * op_region
Definition: types.h:272
uacpi_init_level uacpi_get_current_init_level(void)
Definition: uacpi.c:322

Referenced by handle_create_data_region(), and handle_create_op_region().

◆ uacpi_install_address_space_handler()

uacpi_status uacpi_install_address_space_handler ( uacpi_namespace_node *  device_node,
enum uacpi_address_space  space,
uacpi_region_handler  handler,
uacpi_handle  handler_context 
)

Install an address space handler to a device node. The handler is recursively connected to all of the operation regions of type 'space' underneath 'device_node'. Note that this recursion stops as soon as another device node that already has an address space handler of this type installed is encountered.

Definition at line 977 of file opregion.c.

981{
983 device_node, space, handler, handler_context, 0
984 );
985}
uacpi_status uacpi_install_address_space_handler_with_flags(uacpi_namespace_node *device_node, enum uacpi_address_space space, uacpi_region_handler handler, uacpi_handle handler_context, uacpi_u16 flags)
Definition: opregion.c:882

◆ uacpi_install_address_space_handler_with_flags()

uacpi_status uacpi_install_address_space_handler_with_flags ( uacpi_namespace_node *  device_node,
enum uacpi_address_space  space,
uacpi_region_handler  handler,
uacpi_handle  handler_context,
uacpi_u16  flags 
)

Definition at line 882 of file opregion.c.

887{
890 uacpi_address_space_handler *this_handler, *new_handler;
891 struct opregion_iter_ctx iter_ctx;
892
895 return ret;
896
900 return ret;
901 }
902
903 handlers = extract_handlers(device_node);
906 goto out;
907 }
908
909 this_handler = find_handler(handlers, space);
910 if (this_handler != UACPI_NULL) {
912 goto out;
913 }
914
915 new_handler = uacpi_kernel_alloc(sizeof(*new_handler));
916 if (new_handler == UACPI_NULL) {
918 goto out;
919 }
920 uacpi_shareable_init(new_handler);
921
922 new_handler->next = handlers->head;
923 new_handler->space = space;
924 new_handler->user_context = handler_context;
925 new_handler->callback = handler;
926 new_handler->regions = UACPI_NULL;
927 new_handler->flags = flags;
928 handlers->head = new_handler;
929
930 /*
931 * The handlers that some of the regions already have are invoked as the
932 * regions are taken away from them below, and are free to do whatever they
933 * want in response, which includes uninstalling the handler that we have
934 * just put on the list. Keep it alive until we're done.
935 */
936 uacpi_shareable_ref(new_handler);
937
938 iter_ctx.handler = new_handler;
939 iter_ctx.handlers = handlers;
940 iter_ctx.action = OPREGION_ITER_ACTION_INSTALL;
941
945 UACPI_PERMANENT_ONLY_YES, &iter_ctx
946 );
947
948 if (uacpi_unlikely(!handler_is_installed(&iter_ctx))) {
950 goto out_unref;
951 }
952
954 goto out_unref;
955
956 /*
957 * Installing an early address space handler, obviously not possible to
958 * execute any _REG methods here. Just return and hope that it is either
959 * a global address space handler, or a handler installed by a user who
960 * will run uacpi_reg_all_opregions manually after loading/initializing
961 * the namespace.
962 */
964 goto out_unref;
965
966 // Init level is NAMESPACE_INITIALIZED, so we can safely run _REG now
967 ret = reg_all_opregions(device_node, space);
968
969out_unref:
971out:
974 return ret;
975}
uacpi_status uacpi_recursive_lock_acquire(struct uacpi_recursive_lock *lock)
Definition: mutex.c:285
@ UACPI_STATUS_ALREADY_EXISTS
Definition: status.h:20
@ UACPI_OBJECT_ANY_BIT
Definition: types.h:152
GLbitfield flags
Definition: glext.h:7161
void * uacpi_kernel_alloc(uacpi_size size)
Definition: uacpiosl.c:111
static uacpi_status reg_all_opregions(uacpi_namespace_node *device_node, enum uacpi_address_space space)
Definition: opregion.c:780
static uacpi_iteration_decision do_install_or_uninstall_handler(uacpi_handle opaque, uacpi_namespace_node *node, uacpi_u32 depth)
Definition: opregion.c:527
static uacpi_address_space_handlers * extract_handlers(uacpi_namespace_node *node)
Definition: opregion.c:827
static void uacpi_shareable_init(uacpi_handle handle)
Definition: shareable.h:14
uacpi_region_handler callback
Definition: types.h:67
uacpi_handle user_context
Definition: types.h:68
struct uacpi_address_space_handler * next
Definition: types.h:69
struct uacpi_operation_region * regions
Definition: types.h:70

Referenced by uacpi_install_address_space_handler(), and uacpi_install_default_address_space_handlers().

◆ uacpi_is_buffer_access_address_space()

uacpi_bool uacpi_is_buffer_access_address_space ( uacpi_address_space  space)

Definition at line 1111 of file opregion.c.

1112{
1113 switch (space) {
1119 return UACPI_TRUE;
1120 default:
1121 return UACPI_FALSE;
1122 }
1123}

Referenced by space_needs_bounds_checking(), uacpi_field_unit_get_bit_length(), and uacpi_field_unit_get_read_type().

◆ uacpi_node_get_address_space_handlers()

uacpi_address_space_handlers * uacpi_node_get_address_space_handlers ( uacpi_namespace_node *  node)

Definition at line 179 of file opregion.c.

182{
184
185 if (node == uacpi_namespace_root())
186 return g_uacpi_rt_ctx.root_object->address_space_handlers;
187
189 if (uacpi_unlikely(object == UACPI_NULL))
190 return UACPI_NULL;
191
192 switch (object->type) {
196 return object->address_space_handlers;
197 default:
198 return UACPI_NULL;
199 }
200}
@ UACPI_OBJECT_PROCESSOR
Definition: types.h:123
@ UACPI_OBJECT_DEVICE
Definition: types.h:117
@ UACPI_OBJECT_THERMAL_ZONE
Definition: types.h:124

Referenced by do_install_or_uninstall_handler(), node_has_handler(), reg_all_opregions(), uacpi_initialize_opregion_node(), and uacpi_namespace_initialize().

◆ uacpi_opregion_attach()

uacpi_status uacpi_opregion_attach ( uacpi_namespace_node *  node)

Definition at line 240 of file opregion.c.

241{
246 uacpi_region_attach_data attach_data = { 0 };
247
250
253 );
256
257 region = obj->op_region;
258
259 if (region->handler == UACPI_NULL)
261 if (region->state_flags & UACPI_OP_REGION_STATE_ATTACHED)
262 return UACPI_STATUS_OK;
263
264 handler = region->handler;
265 attach_data.region_node = node;
266
267 switch (region->space) {
269 if (region->length) {
270 region->internal_buffer = uacpi_kernel_alloc_zeroed(region->length);
271 if (uacpi_unlikely(region->internal_buffer == UACPI_NULL))
273 }
274
275 attach_data.pcc_info.buffer.bytes = region->internal_buffer;
276 attach_data.pcc_info.buffer.length = region->length;
277 attach_data.pcc_info.subspace_id = region->offset;
278 break;
280 attach_data.gpio_info.num_pins = region->length;
281 break;
282 default:
283 attach_data.generic_info.base = region->offset;
284 attach_data.generic_info.length = region->length;
285 break;
286 }
287
288 attach_data.handler_context = handler->user_context;
289
290 /*
291 * The handler is invoked with the namespace unlocked, and is free to do
292 * whatever it wants in the meantime, which includes evaluating a method
293 * that gets rid of the region, as well as uninstalling itself. Keep both
294 * of them alive until we're done.
295 */
298
300 ret = handler->callback(UACPI_REGION_OP_ATTACH, &attach_data);
302
304 goto out;
305
306 if (uacpi_unlikely(region->handler != handler)) {
307 uacpi_region_detach_data detach_data = { 0 };
308
309 /*
310 * The region was taken away from the handler before it was done
311 * attaching it. This is not something that the handler was told
312 * about, as the region was not attached at the time, so do it now:
313 * a region that was attached is always detached as well.
314 */
315 detach_data.region_node = node;
316 detach_data.region_context = attach_data.out_region_context;
317 detach_data.handler_context = handler->user_context;
318
320 handler->callback(UACPI_REGION_OP_DETACH, &detach_data);
322
324 goto out;
325 }
326
328 uacpi_region_detach_data detach_data = { 0 };
329
330 /*
331 * The region was attached once more in the meantime, which is what
332 * happens if the handler ends up accessing the region that it's still
333 * in the middle of attaching. It only gets to be attached once, and
334 * that one was there first, so this is the one to be undone.
335 */
336 detach_data.region_node = node;
337 detach_data.region_context = attach_data.out_region_context;
338 detach_data.handler_context = handler->user_context;
339
341 handler->callback(UACPI_REGION_OP_DETACH, &detach_data);
343
344 goto out;
345 }
346
348 region->user_context = attach_data.out_region_context;
349
350out:
353 return ret;
354}
uacpi_bool uacpi_namespace_node_is_dangling(uacpi_namespace_node *node)
Definition: namespace.c:340
#define uacpi_kernel_alloc_zeroed
Definition: stdlib.h:127
@ UACPI_STATUS_NAMESPACE_NODE_DANGLING
Definition: status.h:24
@ UACPI_REGION_OP_ATTACH
Definition: types.h:375
uacpi_size length
Definition: types.h:105
uacpi_u8 * bytes
Definition: types.h:96
uacpi_u64 num_pins
Definition: types.h:426
uacpi_data_view buffer
Definition: types.h:420
uacpi_u8 subspace_id
Definition: types.h:421
void * out_region_context
Definition: types.h:437
uacpi_gpio_region_info gpio_info
Definition: types.h:435
uacpi_pcc_region_info pcc_info
Definition: types.h:434
uacpi_namespace_node * region_node
Definition: types.h:431
uacpi_generic_region_info generic_info
Definition: types.h:433

Referenced by uacpi_dispatch_opregion_io().

◆ uacpi_opregion_uninstall_handler()

void uacpi_opregion_uninstall_handler ( uacpi_namespace_node *  node)

◆ uacpi_reg_all_opregions()

uacpi_status uacpi_reg_all_opregions ( uacpi_namespace_node *  device_node,
enum uacpi_address_space  space 
)

Execute _REG(space, ACPI_REG_CONNECT) for all of the opregions with this address space underneath this device. This should only be called manually if you want to register an early handler that must be available before the call to uacpi_namespace_initialize().

Definition at line 847 of file opregion.c.

851{
853
855
857 return UACPI_STATUS_OK;
858
861 return ret;
862
866 return ret;
867 }
868
869 if (uacpi_unlikely(extract_handlers(device_node) == UACPI_NULL)) {
871 goto out;
872 }
873
874 ret = reg_all_opregions(device_node, space);
875
876out:
879 return ret;
880}
#define UACPI_ENSURE_INIT_LEVEL_AT_LEAST(lvl)
Definition: context.h:127

Referenced by uacpi_namespace_initialize().

◆ uacpi_release_opregion_lock()

void uacpi_release_opregion_lock ( void  )

Definition at line 487 of file opregion.c.

Referenced by unlock_field_unit_transaction().

◆ uacpi_trace_region_error()

void uacpi_trace_region_error ( uacpi_namespace_node *  node,
uacpi_char *  message,
uacpi_status  ret 
)

◆ uacpi_uninstall_address_space_handler()

uacpi_status uacpi_uninstall_address_space_handler ( uacpi_namespace_node *  device_node,
enum uacpi_address_space  space,
uacpi_region_handler  handler 
)

Uninstall a handler of type 'space' previously installed to a device node.

'handler' must be the handler that is currently installed there, otherwise nothing is uninstalled, and UACPI_STATUS_INVALID_ARGUMENT is returned. This makes sure that a handler that was installed by somebody else in the meantime is not uninstalled by mistake.

Definition at line 987 of file opregion.c.

991{
994 uacpi_address_space_handler *this_handler, *prev_handler;
995 struct opregion_iter_ctx iter_ctx;
996
999 return ret;
1000
1004 return ret;
1005 }
1006
1007 handlers = extract_handlers(device_node);
1010 goto out;
1011 }
1012
1013 this_handler = find_handler(handlers, space);
1014 if (uacpi_unlikely(this_handler == UACPI_NULL)) {
1016 goto out;
1017 }
1018
1019 // This is somebody else's handler, and is thus not ours to uninstall
1020 if (uacpi_unlikely(this_handler->callback != handler)) {
1022 goto out;
1023 }
1024
1025 /*
1026 * Both the handler and the _REG methods are invoked as the regions are
1027 * taken away below, and are free to do whatever they want in response.
1028 * Make sure that the handler is no longer there to be found by then, be
1029 * it by a region that is created in the meantime, or by the handler
1030 * itself in case it decides to uninstall itself as it's told to detach
1031 * a region. The reference that the device had is now ours, which is what
1032 * keeps the handler alive until we're done.
1033 */
1034 prev_handler = handlers->head;
1035
1036 // Are we the last linked handler?
1037 if (prev_handler == this_handler) {
1038 handlers->head = this_handler->next;
1039 } else {
1040 // Nope, we're somewhere in the middle. Do a search.
1041 while (prev_handler->next != this_handler)
1042 prev_handler = prev_handler->next;
1043
1044 prev_handler->next = this_handler->next;
1045 }
1046
1047 iter_ctx.handler = this_handler;
1048 iter_ctx.handlers = handlers;
1049 iter_ctx.action = OPREGION_ITER_ACTION_UNINSTALL;
1050
1054 UACPI_PERMANENT_ONLY_NO, &iter_ctx
1055 );
1056
1058
1059out:
1062 return ret;
1063}

◆ uacpi_upgrade_to_opregion_lock()

uacpi_status uacpi_upgrade_to_opregion_lock ( void  )

Definition at line 472 of file opregion.c.

473{
475
476 /*
477 * Drop the namespace lock, and reacquire it after the opregion lock
478 * so we keep the ordering with user API.
479 */
481
484 return ret;
485}

Referenced by lock_field_unit_transaction(), uacpi_initialize_opregion_node(), and uacpi_opregion_uninstall_handler().

Variable Documentation

◆ g_opregion_lock