diff options
Diffstat (limited to 'drivers/acpi/acpica/dsfield.c')
| -rw-r--r-- | drivers/acpi/acpica/dsfield.c | 103 | 
1 files changed, 92 insertions, 11 deletions
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c index cd243cf2cab..3da6fd8530c 100644 --- a/drivers/acpi/acpica/dsfield.c +++ b/drivers/acpi/acpica/dsfield.c @@ -53,16 +53,84 @@  ACPI_MODULE_NAME("dsfield")  /* Local prototypes */ +#ifdef ACPI_ASL_COMPILER +#include "acdisasm.h" +static acpi_status +acpi_ds_create_external_region(acpi_status lookup_status, +			       union acpi_parse_object *op, +			       char *path, +			       struct acpi_walk_state *walk_state, +			       struct acpi_namespace_node **node); +#endif +  static acpi_status  acpi_ds_get_field_names(struct acpi_create_field_info *info,  			struct acpi_walk_state *walk_state,  			union acpi_parse_object *arg); +#ifdef ACPI_ASL_COMPILER +/******************************************************************************* + * + * FUNCTION:    acpi_ds_create_external_region (iASL Disassembler only) + * + * PARAMETERS:  lookup_status   - Status from ns_lookup operation + *              op              - Op containing the Field definition and args + *              path            - Pathname of the region + *  `           walk_state      - Current method state + *              node            - Where the new region node is returned + * + * RETURN:      Status + * + * DESCRIPTION: Add region to the external list if NOT_FOUND. Create a new + *              region node/object. + * + ******************************************************************************/ + +static acpi_status +acpi_ds_create_external_region(acpi_status lookup_status, +			       union acpi_parse_object *op, +			       char *path, +			       struct acpi_walk_state *walk_state, +			       struct acpi_namespace_node **node) +{ +	acpi_status status; +	union acpi_operand_object *obj_desc; + +	if (lookup_status != AE_NOT_FOUND) { +		return (lookup_status); +	} + +	/* +	 * Table disassembly: +	 * operation_region not found. Generate an External for it, and +	 * insert the name into the namespace. +	 */ +	acpi_dm_add_to_external_list(op, path, ACPI_TYPE_REGION, 0); +	status = acpi_ns_lookup(walk_state->scope_info, path, ACPI_TYPE_REGION, +				ACPI_IMODE_LOAD_PASS1, ACPI_NS_SEARCH_PARENT, +				walk_state, node); +	if (ACPI_FAILURE(status)) { +		return (status); +	} + +	/* Must create and install a region object for the new node */ + +	obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_REGION); +	if (!obj_desc) { +		return (AE_NO_MEMORY); +	} + +	obj_desc->region.node = *node; +	status = acpi_ns_attach_object(*node, obj_desc, ACPI_TYPE_REGION); +	return (status); +} +#endif +  /*******************************************************************************   *   * FUNCTION:    acpi_ds_create_buffer_field   * - * PARAMETERS:  Op                  - Current parse op (create_xXField) + * PARAMETERS:  op                  - Current parse op (create_XXField)   *              walk_state          - Current state   *   * RETURN:      Status @@ -99,7 +167,7 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,  		arg = acpi_ps_get_arg(op, 3);  	} else { -		/* For all other create_xXXField operators, name is the 3rd argument */ +		/* For all other create_XXXField operators, name is the 3rd argument */  		arg = acpi_ps_get_arg(op, 2);  	} @@ -203,9 +271,9 @@ acpi_ds_create_buffer_field(union acpi_parse_object *op,   *   * FUNCTION:    acpi_ds_get_field_names   * - * PARAMETERS:  Info            - create_field info structure + * PARAMETERS:  info            - create_field info structure   *  `           walk_state      - Current method state - *              Arg             - First parser arg for the field name list + *              arg             - First parser arg for the field name list   *   * RETURN:      Status   * @@ -234,10 +302,10 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,  	while (arg) {  		/*  		 * Four types of field elements are handled: -		 * 1) Name - Enters a new named field into the namespace -		 * 2) Offset - specifies a bit offset +		 * 1) name - Enters a new named field into the namespace +		 * 2) offset - specifies a bit offset  		 * 3) access_as - changes the access mode/attributes -		 * 4) Connection - Associate a resource template with the field +		 * 4) connection - Associate a resource template with the field  		 */  		switch (arg->common.aml_opcode) {  		case AML_INT_RESERVEDFIELD_OP: @@ -389,7 +457,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,   *   * FUNCTION:    acpi_ds_create_field   * - * PARAMETERS:  Op              - Op containing the Field definition and args + * PARAMETERS:  op              - Op containing the Field definition and args   *              region_node     - Object for the containing Operation Region   *  `           walk_state      - Current method state   * @@ -413,12 +481,19 @@ acpi_ds_create_field(union acpi_parse_object *op,  	/* First arg is the name of the parent op_region (must already exist) */  	arg = op->common.value.arg; +  	if (!region_node) {  		status =  		    acpi_ns_lookup(walk_state->scope_info,  				   arg->common.value.name, ACPI_TYPE_REGION,  				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,  				   walk_state, ®ion_node); +#ifdef ACPI_ASL_COMPILER +		status = acpi_ds_create_external_region(status, arg, +							arg->common.value.name, +							walk_state, +							®ion_node); +#endif  		if (ACPI_FAILURE(status)) {  			ACPI_ERROR_NAMESPACE(arg->common.value.name, status);  			return_ACPI_STATUS(status); @@ -446,7 +521,7 @@ acpi_ds_create_field(union acpi_parse_object *op,   *   * FUNCTION:    acpi_ds_init_field_objects   * - * PARAMETERS:  Op              - Op containing the Field definition and args + * PARAMETERS:  op              - Op containing the Field definition and args   *  `           walk_state      - Current method state   *   * RETURN:      Status @@ -561,7 +636,7 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,   *   * FUNCTION:    acpi_ds_create_bank_field   * - * PARAMETERS:  Op              - Op containing the Field definition and args + * PARAMETERS:  op              - Op containing the Field definition and args   *              region_node     - Object for the containing Operation Region   *              walk_state      - Current method state   * @@ -591,6 +666,12 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,  				   arg->common.value.name, ACPI_TYPE_REGION,  				   ACPI_IMODE_EXECUTE, ACPI_NS_SEARCH_PARENT,  				   walk_state, ®ion_node); +#ifdef ACPI_ASL_COMPILER +		status = acpi_ds_create_external_region(status, arg, +							arg->common.value.name, +							walk_state, +							®ion_node); +#endif  		if (ACPI_FAILURE(status)) {  			ACPI_ERROR_NAMESPACE(arg->common.value.name, status);  			return_ACPI_STATUS(status); @@ -645,7 +726,7 @@ acpi_ds_create_bank_field(union acpi_parse_object *op,   *   * FUNCTION:    acpi_ds_create_index_field   * - * PARAMETERS:  Op              - Op containing the Field definition and args + * PARAMETERS:  op              - Op containing the Field definition and args   *              region_node     - Object for the containing Operation Region   *  `           walk_state      - Current method state   *  |