aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBob Moore <robert.moore@intel.com>2011-11-16 00:39:07 -0500
committerLen Brown <len.brown@intel.com>2012-01-17 03:36:29 -0500
commit9ce81784c9c0396a6a6be05248928a71134fe60b (patch)
treecccb8fc3a3514276ed0b1801f7bb26ba2319d62d /drivers
parentffef68273b6278e98a99dd4051671d4854b20fe0 (diff)
ACPI 5.0: Implement Connection() and AccessAs() changes
Support within the interpreter and operation region dispatch. Signed-off-by: Bob Moore <robert.moore@intel.com> Signed-off-by: Lin Ming <ming.m.lin@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/acpica/acevents.h1
-rw-r--r--drivers/acpi/acpica/aclocal.h6
-rw-r--r--drivers/acpi/acpica/acobject.h5
-rw-r--r--drivers/acpi/acpica/acopcode.h4
-rw-r--r--drivers/acpi/acpica/amlcode.h10
-rw-r--r--drivers/acpi/acpica/dsfield.c81
-rw-r--r--drivers/acpi/acpica/evregion.c29
-rw-r--r--drivers/acpi/acpica/exconfig.c6
-rw-r--r--drivers/acpi/acpica/exdump.c7
-rw-r--r--drivers/acpi/acpica/exfldio.c11
-rw-r--r--drivers/acpi/acpica/exprep.c25
-rw-r--r--drivers/acpi/acpica/psargs.c141
-rw-r--r--drivers/acpi/acpica/psopcode.c13
-rw-r--r--drivers/acpi/acpica/pstree.c6
14 files changed, 300 insertions, 45 deletions
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h
index bea3b4899183..f763b88ed772 100644
--- a/drivers/acpi/acpica/acevents.h
+++ b/drivers/acpi/acpica/acevents.h
@@ -162,6 +162,7 @@ acpi_status acpi_ev_initialize_op_regions(void);
162 162
163acpi_status 163acpi_status
164acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, 164acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
165 union acpi_operand_object *field_obj,
165 u32 function, 166 u32 function,
166 u32 region_offset, u32 bit_width, u64 *value); 167 u32 region_offset, u32 bit_width, u64 *value);
167 168
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 5552125d8340..52c4ebddbcf1 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -53,7 +53,7 @@ typedef u32 acpi_mutex_handle;
53 53
54/* Total number of aml opcodes defined */ 54/* Total number of aml opcodes defined */
55 55
56#define AML_NUM_OPCODES 0x7F 56#define AML_NUM_OPCODES 0x81
57 57
58/* Forward declarations */ 58/* Forward declarations */
59 59
@@ -249,12 +249,16 @@ struct acpi_create_field_info {
249 struct acpi_namespace_node *field_node; 249 struct acpi_namespace_node *field_node;
250 struct acpi_namespace_node *register_node; 250 struct acpi_namespace_node *register_node;
251 struct acpi_namespace_node *data_register_node; 251 struct acpi_namespace_node *data_register_node;
252 struct acpi_namespace_node *connection_node;
253 u8 *resource_buffer;
252 u32 bank_value; 254 u32 bank_value;
253 u32 field_bit_position; 255 u32 field_bit_position;
254 u32 field_bit_length; 256 u32 field_bit_length;
257 u16 resource_length;
255 u8 field_flags; 258 u8 field_flags;
256 u8 attribute; 259 u8 attribute;
257 u8 field_type; 260 u8 field_type;
261 u8 access_length;
258}; 262};
259 263
260typedef 264typedef
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h
index 6d276c20b57b..435dd2f847bb 100644
--- a/drivers/acpi/acpica/acobject.h
+++ b/drivers/acpi/acpica/acobject.h
@@ -254,6 +254,7 @@ ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_NOTIFY_INFO};
254 u32 base_byte_offset; /* Byte offset within containing object */\ 254 u32 base_byte_offset; /* Byte offset within containing object */\
255 u32 value; /* Value to store into the Bank or Index register */\ 255 u32 value; /* Value to store into the Bank or Index register */\
256 u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\ 256 u8 start_field_bit_offset;/* Bit offset within first field datum (0-63) */\
257 u8 access_length; /* For serial regions/fields */
257 258
258 259
259struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */ 260struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and INDEX fields) */
@@ -261,7 +262,9 @@ struct acpi_object_field_common { /* COMMON FIELD (for BUFFER, REGION, BANK, and
261}; 262};
262 263
263struct acpi_object_region_field { 264struct acpi_object_region_field {
264 ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO union acpi_operand_object *region_obj; /* Containing op_region object */ 265 ACPI_OBJECT_COMMON_HEADER ACPI_COMMON_FIELD_INFO u16 resource_length;
266 union acpi_operand_object *region_obj; /* Containing op_region object */
267 u8 *resource_buffer; /* resource_template for serial regions/fields */
265}; 268};
266 269
267struct acpi_object_bank_field { 270struct acpi_object_bank_field {
diff --git a/drivers/acpi/acpica/acopcode.h b/drivers/acpi/acpica/acopcode.h
index bb2ccfad7376..9896c77e94f9 100644
--- a/drivers/acpi/acpica/acopcode.h
+++ b/drivers/acpi/acpica/acopcode.h
@@ -93,6 +93,7 @@
93#define ARGP_CONCAT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) 93#define ARGP_CONCAT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
94#define ARGP_CONCAT_RES_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) 94#define ARGP_CONCAT_RES_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
95#define ARGP_COND_REF_OF_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SUPERNAME) 95#define ARGP_COND_REF_OF_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SUPERNAME)
96#define ARGP_CONNECTFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
96#define ARGP_CONTINUE_OP ARG_NONE 97#define ARGP_CONTINUE_OP ARG_NONE
97#define ARGP_COPY_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_SIMPLENAME) 98#define ARGP_COPY_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_SIMPLENAME)
98#define ARGP_CREATE_BIT_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME) 99#define ARGP_CREATE_BIT_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME)
@@ -164,6 +165,7 @@
164#define ARGP_RETURN_OP ARGP_LIST1 (ARGP_TERMARG) 165#define ARGP_RETURN_OP ARGP_LIST1 (ARGP_TERMARG)
165#define ARGP_REVISION_OP ARG_NONE 166#define ARGP_REVISION_OP ARG_NONE
166#define ARGP_SCOPE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_TERMLIST) 167#define ARGP_SCOPE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_TERMLIST)
168#define ARGP_SERIALFIELD_OP ARGP_LIST1 (ARGP_NAMESTRING)
167#define ARGP_SHIFT_LEFT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) 169#define ARGP_SHIFT_LEFT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
168#define ARGP_SHIFT_RIGHT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) 170#define ARGP_SHIFT_RIGHT_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET)
169#define ARGP_SIGNAL_OP ARGP_LIST1 (ARGP_SUPERNAME) 171#define ARGP_SIGNAL_OP ARGP_LIST1 (ARGP_SUPERNAME)
@@ -223,6 +225,7 @@
223#define ARGI_CONCAT_OP ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA, ARGI_TARGETREF) 225#define ARGI_CONCAT_OP ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA, ARGI_TARGETREF)
224#define ARGI_CONCAT_RES_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_BUFFER, ARGI_TARGETREF) 226#define ARGI_CONCAT_RES_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_BUFFER, ARGI_TARGETREF)
225#define ARGI_COND_REF_OF_OP ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF) 227#define ARGI_COND_REF_OF_OP ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF)
228#define ARGI_CONNECTFIELD_OP ARGI_INVALID_OPCODE
226#define ARGI_CONTINUE_OP ARGI_INVALID_OPCODE 229#define ARGI_CONTINUE_OP ARGI_INVALID_OPCODE
227#define ARGI_COPY_OP ARGI_LIST2 (ARGI_ANYTYPE, ARGI_SIMPLE_TARGET) 230#define ARGI_COPY_OP ARGI_LIST2 (ARGI_ANYTYPE, ARGI_SIMPLE_TARGET)
228#define ARGI_CREATE_BIT_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) 231#define ARGI_CREATE_BIT_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE)
@@ -294,6 +297,7 @@
294#define ARGI_RETURN_OP ARGI_INVALID_OPCODE 297#define ARGI_RETURN_OP ARGI_INVALID_OPCODE
295#define ARGI_REVISION_OP ARG_NONE 298#define ARGI_REVISION_OP ARG_NONE
296#define ARGI_SCOPE_OP ARGI_INVALID_OPCODE 299#define ARGI_SCOPE_OP ARGI_INVALID_OPCODE
300#define ARGI_SERIALFIELD_OP ARGI_INVALID_OPCODE
297#define ARGI_SHIFT_LEFT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) 301#define ARGI_SHIFT_LEFT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
298#define ARGI_SHIFT_RIGHT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) 302#define ARGI_SHIFT_RIGHT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF)
299#define ARGI_SIGNAL_OP ARGI_LIST1 (ARGI_EVENT) 303#define ARGI_SIGNAL_OP ARGI_LIST1 (ARGI_EVENT)
diff --git a/drivers/acpi/acpica/amlcode.h b/drivers/acpi/acpica/amlcode.h
index 1077f17859ed..adf7a71ea766 100644
--- a/drivers/acpi/acpica/amlcode.h
+++ b/drivers/acpi/acpica/amlcode.h
@@ -189,6 +189,14 @@
189#define AML_LNOTEQUAL_OP (u16) 0x9293 189#define AML_LNOTEQUAL_OP (u16) 0x9293
190 190
191/* 191/*
192 * Opcodes for "Field" operators
193 */
194#define AML_FIELD_OFFSET_OP (u8) 0x00
195#define AML_FIELD_ACCESS_OP (u8) 0x01
196#define AML_FIELD_CONNECTION_OP (u8) 0x02 /* ACPI 5.0 */
197#define AML_FIELD_EXT_ACCESS_OP (u8) 0x03 /* ACPI 5.0 */
198
199/*
192 * Internal opcodes 200 * Internal opcodes
193 * Use only "Unknown" AML opcodes, don't attempt to use 201 * Use only "Unknown" AML opcodes, don't attempt to use
194 * any valid ACPI ASCII values (A-Z, 0-9, '-') 202 * any valid ACPI ASCII values (A-Z, 0-9, '-')
@@ -202,6 +210,8 @@
202#define AML_INT_METHODCALL_OP (u16) 0x0035 210#define AML_INT_METHODCALL_OP (u16) 0x0035
203#define AML_INT_RETURN_VALUE_OP (u16) 0x0036 211#define AML_INT_RETURN_VALUE_OP (u16) 0x0036
204#define AML_INT_EVAL_SUBTREE_OP (u16) 0x0037 212#define AML_INT_EVAL_SUBTREE_OP (u16) 0x0037
213#define AML_INT_CONNECTION_OP (u16) 0x0038
214#define AML_INT_EXTACCESSFIELD_OP (u16) 0x0039
205 215
206#define ARG_NONE 0x0 216#define ARG_NONE 0x0
207 217
diff --git a/drivers/acpi/acpica/dsfield.c b/drivers/acpi/acpica/dsfield.c
index 34be60c0e448..aa880d992984 100644
--- a/drivers/acpi/acpica/dsfield.c
+++ b/drivers/acpi/acpica/dsfield.c
@@ -221,6 +221,7 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
221{ 221{
222 acpi_status status; 222 acpi_status status;
223 u64 position; 223 u64 position;
224 union acpi_parse_object *child;
224 225
225 ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info); 226 ACPI_FUNCTION_TRACE_PTR(ds_get_field_names, info);
226 227
@@ -232,10 +233,11 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
232 233
233 while (arg) { 234 while (arg) {
234 /* 235 /*
235 * Three types of field elements are handled: 236 * Four types of field elements are handled:
236 * 1) Offset - specifies a bit offset 237 * 1) Name - Enters a new named field into the namespace
237 * 2) access_as - changes the access mode 238 * 2) Offset - specifies a bit offset
238 * 3) Name - Enters a new named field into the namespace 239 * 3) access_as - changes the access mode/attributes
240 * 4) Connection - Associate a resource template with the field
239 */ 241 */
240 switch (arg->common.aml_opcode) { 242 switch (arg->common.aml_opcode) {
241 case AML_INT_RESERVEDFIELD_OP: 243 case AML_INT_RESERVEDFIELD_OP:
@@ -253,21 +255,70 @@ acpi_ds_get_field_names(struct acpi_create_field_info *info,
253 break; 255 break;
254 256
255 case AML_INT_ACCESSFIELD_OP: 257 case AML_INT_ACCESSFIELD_OP:
256 258 case AML_INT_EXTACCESSFIELD_OP:
257 /* 259 /*
258 * Get a new access_type and access_attribute -- to be used for all 260 * Get new access_type, access_attribute, and access_length fields
259 * field units that follow, until field end or another access_as 261 * -- to be used for all field units that follow, until the
260 * keyword. 262 * end-of-field or another access_as keyword is encountered.
263 * NOTE. These three bytes are encoded in the integer value
264 * of the parseop for convenience.
261 * 265 *
262 * In field_flags, preserve the flag bits other than the 266 * In field_flags, preserve the flag bits other than the
263 * ACCESS_TYPE bits 267 * ACCESS_TYPE bits.
264 */ 268 */
269
270 /* access_type (byte_acc, word_acc, etc.) */
271
265 info->field_flags = (u8) 272 info->field_flags = (u8)
266 ((info-> 273 ((info->
267 field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) | 274 field_flags & ~(AML_FIELD_ACCESS_TYPE_MASK)) |
268 ((u8) ((u32) arg->common.value.integer >> 8))); 275 ((u8)((u32)(arg->common.value.integer & 0x07))));
276
277 /* access_attribute (attrib_quick, attrib_byte, etc.) */
278
279 info->attribute =
280 (u8)((arg->common.value.integer >> 8) & 0xFF);
281
282 /* access_length (for serial/buffer protocols) */
283
284 info->access_length =
285 (u8)((arg->common.value.integer >> 16) & 0xFF);
286 break;
287
288 case AML_INT_CONNECTION_OP:
289 /*
290 * Clear any previous connection. New connection is used for all
291 * fields that follow, similar to access_as
292 */
293 info->resource_buffer = NULL;
294 info->connection_node = NULL;
269 295
270 info->attribute = (u8) (arg->common.value.integer); 296 /*
297 * A Connection() is either an actual resource descriptor (buffer)
298 * or a named reference to a resource template
299 */
300 child = arg->common.value.arg;
301 if (child->common.aml_opcode == AML_INT_BYTELIST_OP) {
302 info->resource_buffer = child->named.data;
303 info->resource_length =
304 (u16)child->named.value.integer;
305 } else {
306 /* Lookup the Connection() namepath, it should already exist */
307
308 status = acpi_ns_lookup(walk_state->scope_info,
309 child->common.value.
310 name, ACPI_TYPE_ANY,
311 ACPI_IMODE_EXECUTE,
312 ACPI_NS_DONT_OPEN_SCOPE,
313 walk_state,
314 &info->connection_node);
315 if (ACPI_FAILURE(status)) {
316 ACPI_ERROR_NAMESPACE(child->common.
317 value.name,
318 status);
319 return_ACPI_STATUS(status);
320 }
321 }
271 break; 322 break;
272 323
273 case AML_INT_NAMEDFIELD_OP: 324 case AML_INT_NAMEDFIELD_OP:
@@ -374,6 +425,8 @@ acpi_ds_create_field(union acpi_parse_object *op,
374 } 425 }
375 } 426 }
376 427
428 ACPI_MEMSET(&info, 0, sizeof(struct acpi_create_field_info));
429
377 /* Second arg is the field flags */ 430 /* Second arg is the field flags */
378 431
379 arg = arg->common.next; 432 arg = arg->common.next;
@@ -386,7 +439,6 @@ acpi_ds_create_field(union acpi_parse_object *op,
386 info.region_node = region_node; 439 info.region_node = region_node;
387 440
388 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 441 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
389
390 return_ACPI_STATUS(status); 442 return_ACPI_STATUS(status);
391} 443}
392 444
@@ -474,8 +526,8 @@ acpi_ds_init_field_objects(union acpi_parse_object *op,
474 */ 526 */
475 while (arg) { 527 while (arg) {
476 /* 528 /*
477 * Ignore OFFSET and ACCESSAS terms here; we are only interested in the 529 * Ignore OFFSET/ACCESSAS/CONNECTION terms here; we are only interested
478 * field names in order to enter them into the namespace. 530 * in the field names in order to enter them into the namespace.
479 */ 531 */
480 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) { 532 if (arg->common.aml_opcode == AML_INT_NAMEDFIELD_OP) {
481 status = acpi_ns_lookup(walk_state->scope_info, 533 status = acpi_ns_lookup(walk_state->scope_info,
@@ -651,6 +703,5 @@ acpi_ds_create_index_field(union acpi_parse_object *op,
651 info.region_node = region_node; 703 info.region_node = region_node;
652 704
653 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next); 705 status = acpi_ds_get_field_names(&info, walk_state, arg->common.next);
654
655 return_ACPI_STATUS(status); 706 return_ACPI_STATUS(status);
656} 707}
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index f0edf5c43c03..dcdc7e4a285e 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -329,6 +329,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
329 * FUNCTION: acpi_ev_address_space_dispatch 329 * FUNCTION: acpi_ev_address_space_dispatch
330 * 330 *
331 * PARAMETERS: region_obj - Internal region object 331 * PARAMETERS: region_obj - Internal region object
332 * field_obj - Corresponding field. Can be NULL.
332 * Function - Read or Write operation 333 * Function - Read or Write operation
333 * region_offset - Where in the region to read or write 334 * region_offset - Where in the region to read or write
334 * bit_width - Field width in bits (8, 16, 32, or 64) 335 * bit_width - Field width in bits (8, 16, 32, or 64)
@@ -344,6 +345,7 @@ acpi_ev_execute_reg_method(union acpi_operand_object *region_obj, u32 function)
344 345
345acpi_status 346acpi_status
346acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj, 347acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
348 union acpi_operand_object *field_obj,
347 u32 function, 349 u32 function,
348 u32 region_offset, u32 bit_width, u64 *value) 350 u32 region_offset, u32 bit_width, u64 *value)
349{ 351{
@@ -353,6 +355,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
353 union acpi_operand_object *handler_desc; 355 union acpi_operand_object *handler_desc;
354 union acpi_operand_object *region_obj2; 356 union acpi_operand_object *region_obj2;
355 void *region_context = NULL; 357 void *region_context = NULL;
358 struct acpi_connection_info *context;
356 359
357 ACPI_FUNCTION_TRACE(ev_address_space_dispatch); 360 ACPI_FUNCTION_TRACE(ev_address_space_dispatch);
358 361
@@ -375,6 +378,8 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
375 return_ACPI_STATUS(AE_NOT_EXIST); 378 return_ACPI_STATUS(AE_NOT_EXIST);
376 } 379 }
377 380
381 context = handler_desc->address_space.context;
382
378 /* 383 /*
379 * It may be the case that the region has never been initialized. 384 * It may be the case that the region has never been initialized.
380 * Some types of regions require special init code 385 * Some types of regions require special init code
@@ -404,8 +409,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
404 acpi_ex_exit_interpreter(); 409 acpi_ex_exit_interpreter();
405 410
406 status = region_setup(region_obj, ACPI_REGION_ACTIVATE, 411 status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
407 handler_desc->address_space.context, 412 context, &region_context);
408 &region_context);
409 413
410 /* Re-enter the interpreter */ 414 /* Re-enter the interpreter */
411 415
@@ -455,6 +459,25 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
455 acpi_ut_get_region_name(region_obj->region. 459 acpi_ut_get_region_name(region_obj->region.
456 space_id))); 460 space_id)));
457 461
462 /*
463 * Special handling for generic_serial_bus and general_purpose_io:
464 * There are three extra parameters that must be passed to the
465 * handler via the context:
466 * 1) Connection buffer, a resource template from Connection() op.
467 * 2) Length of the above buffer.
468 * 3) Actual access length from the access_as() op.
469 */
470 if (((region_obj->region.space_id == ACPI_ADR_SPACE_GSBUS) ||
471 (region_obj->region.space_id == ACPI_ADR_SPACE_GPIO)) &&
472 context && field_obj) {
473
474 /* Get the Connection (resource_template) buffer */
475
476 context->connection = field_obj->field.resource_buffer;
477 context->length = field_obj->field.resource_length;
478 context->access_length = field_obj->field.access_length;
479 }
480
458 if (!(handler_desc->address_space.handler_flags & 481 if (!(handler_desc->address_space.handler_flags &
459 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) { 482 ACPI_ADDR_HANDLER_DEFAULT_INSTALLED)) {
460 /* 483 /*
@@ -469,7 +492,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
469 492
470 status = handler(function, 493 status = handler(function,
471 (region_obj->region.address + region_offset), 494 (region_obj->region.address + region_offset),
472 bit_width, value, handler_desc->address_space.context, 495 bit_width, value, context,
473 region_obj2->extra.region_context); 496 region_obj2->extra.region_context);
474 497
475 if (ACPI_FAILURE(status)) { 498 if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 745a42b401f5..efe41f736fab 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -297,9 +297,9 @@ acpi_ex_region_read(union acpi_operand_object *obj_desc, u32 length, u8 *buffer)
297 /* Bytewise reads */ 297 /* Bytewise reads */
298 298
299 for (i = 0; i < length; i++) { 299 for (i = 0; i < length; i++) {
300 status = acpi_ev_address_space_dispatch(obj_desc, ACPI_READ, 300 status =
301 region_offset, 8, 301 acpi_ev_address_space_dispatch(obj_desc, NULL, ACPI_READ,
302 &value); 302 region_offset, 8, &value);
303 if (ACPI_FAILURE(status)) { 303 if (ACPI_FAILURE(status)) {
304 return status; 304 return status;
305 } 305 }
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index 61b8c0e8b74d..c7064f4d4704 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -192,10 +192,13 @@ static struct acpi_exdump_info acpi_ex_dump_buffer_field[3] = {
192 "Buffer Object"} 192 "Buffer Object"}
193}; 193};
194 194
195static struct acpi_exdump_info acpi_ex_dump_region_field[3] = { 195static struct acpi_exdump_info acpi_ex_dump_region_field[5] = {
196 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region_field), NULL}, 196 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_region_field), NULL},
197 {ACPI_EXD_FIELD, 0, NULL}, 197 {ACPI_EXD_FIELD, 0, NULL},
198 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"} 198 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(field.access_length), "AccessLength"},
199 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.region_obj), "Region Object"},
200 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(field.resource_buffer),
201 "ResourceBuffer"}
199}; 202};
200 203
201static struct acpi_exdump_info acpi_ex_dump_bank_field[5] = { 204static struct acpi_exdump_info acpi_ex_dump_bank_field[5] = {
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
index 2a524fc1e851..cc9c5dfa4c45 100644
--- a/drivers/acpi/acpica/exfldio.c
+++ b/drivers/acpi/acpica/exfldio.c
@@ -283,11 +283,12 @@ acpi_ex_access_region(union acpi_operand_object *obj_desc,
283 283
284 /* Invoke the appropriate address_space/op_region handler */ 284 /* Invoke the appropriate address_space/op_region handler */
285 285
286 status = 286 status = acpi_ev_address_space_dispatch(rgn_desc, obj_desc,
287 acpi_ev_address_space_dispatch(rgn_desc, function, region_offset, 287 function, region_offset,
288 ACPI_MUL_8(obj_desc->common_field. 288 ACPI_MUL_8(obj_desc->
289 access_byte_width), 289 common_field.
290 value); 290 access_byte_width),
291 value);
291 292
292 if (ACPI_FAILURE(status)) { 293 if (ACPI_FAILURE(status)) {
293 if (status == AE_NOT_IMPLEMENTED) { 294 if (status == AE_NOT_IMPLEMENTED) {
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
index cc95e2000406..18b75fed626e 100644
--- a/drivers/acpi/acpica/exprep.c
+++ b/drivers/acpi/acpica/exprep.c
@@ -47,6 +47,7 @@
47#include "acinterp.h" 47#include "acinterp.h"
48#include "amlcode.h" 48#include "amlcode.h"
49#include "acnamesp.h" 49#include "acnamesp.h"
50#include "acdispat.h"
50 51
51#define _COMPONENT ACPI_EXECUTER 52#define _COMPONENT ACPI_EXECUTER
52ACPI_MODULE_NAME("exprep") 53ACPI_MODULE_NAME("exprep")
@@ -455,6 +456,30 @@ acpi_status acpi_ex_prep_field_value(struct acpi_create_field_info *info)
455 obj_desc->field.region_obj = 456 obj_desc->field.region_obj =
456 acpi_ns_get_attached_object(info->region_node); 457 acpi_ns_get_attached_object(info->region_node);
457 458
459 /* Fields specific to generic_serial_bus fields */
460
461 obj_desc->field.access_length = info->access_length;
462
463 if (info->connection_node) {
464 second_desc = info->connection_node->object;
465 if (!(second_desc->common.flags & AOPOBJ_DATA_VALID)) {
466 status =
467 acpi_ds_get_buffer_arguments(second_desc);
468 if (ACPI_FAILURE(status)) {
469 acpi_ut_delete_object_desc(obj_desc);
470 return_ACPI_STATUS(status);
471 }
472 }
473
474 obj_desc->field.resource_buffer =
475 second_desc->buffer.pointer;
476 obj_desc->field.resource_length =
477 (u16)second_desc->buffer.length;
478 } else if (info->resource_buffer) {
479 obj_desc->field.resource_buffer = info->resource_buffer;
480 obj_desc->field.resource_length = info->resource_length;
481 }
482
458 /* Allow full data read from EC address space */ 483 /* Allow full data read from EC address space */
459 484
460 if ((obj_desc->field.region_obj->region.space_id == 485 if ((obj_desc->field.region_obj->region.space_id ==
diff --git a/drivers/acpi/acpica/psargs.c b/drivers/acpi/acpica/psargs.c
index e1fad0ee0136..4037f9032481 100644
--- a/drivers/acpi/acpica/psargs.c
+++ b/drivers/acpi/acpica/psargs.c
@@ -484,34 +484,54 @@ acpi_ps_get_next_simple_arg(struct acpi_parse_state *parser_state,
484static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state 484static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
485 *parser_state) 485 *parser_state)
486{ 486{
487 u32 aml_offset = (u32) 487 u32 aml_offset;
488 ACPI_PTR_DIFF(parser_state->aml,
489 parser_state->aml_start);
490 union acpi_parse_object *field; 488 union acpi_parse_object *field;
489 union acpi_parse_object *arg = NULL;
491 u16 opcode; 490 u16 opcode;
492 u32 name; 491 u32 name;
492 u8 access_type;
493 u8 access_attribute;
494 u8 access_length;
495 u32 pkg_length;
496 u8 *pkg_end;
497 u32 buffer_length;
493 498
494 ACPI_FUNCTION_TRACE(ps_get_next_field); 499 ACPI_FUNCTION_TRACE(ps_get_next_field);
495 500
501 aml_offset =
502 (u32)ACPI_PTR_DIFF(parser_state->aml, parser_state->aml_start);
503
496 /* Determine field type */ 504 /* Determine field type */
497 505
498 switch (ACPI_GET8(parser_state->aml)) { 506 switch (ACPI_GET8(parser_state->aml)) {
499 default: 507 case AML_FIELD_OFFSET_OP:
500 508
501 opcode = AML_INT_NAMEDFIELD_OP; 509 opcode = AML_INT_RESERVEDFIELD_OP;
510 parser_state->aml++;
502 break; 511 break;
503 512
504 case 0x00: 513 case AML_FIELD_ACCESS_OP:
505 514
506 opcode = AML_INT_RESERVEDFIELD_OP; 515 opcode = AML_INT_ACCESSFIELD_OP;
507 parser_state->aml++; 516 parser_state->aml++;
508 break; 517 break;
509 518
510 case 0x01: 519 case AML_FIELD_CONNECTION_OP:
511 520
512 opcode = AML_INT_ACCESSFIELD_OP; 521 opcode = AML_INT_CONNECTION_OP;
522 parser_state->aml++;
523 break;
524
525 case AML_FIELD_EXT_ACCESS_OP:
526
527 opcode = AML_INT_EXTACCESSFIELD_OP;
513 parser_state->aml++; 528 parser_state->aml++;
514 break; 529 break;
530
531 default:
532
533 opcode = AML_INT_NAMEDFIELD_OP;
534 break;
515 } 535 }
516 536
517 /* Allocate a new field op */ 537 /* Allocate a new field op */
@@ -549,16 +569,111 @@ static union acpi_parse_object *acpi_ps_get_next_field(struct acpi_parse_state
549 break; 569 break;
550 570
551 case AML_INT_ACCESSFIELD_OP: 571 case AML_INT_ACCESSFIELD_OP:
572 case AML_INT_EXTACCESSFIELD_OP:
552 573
553 /* 574 /*
554 * Get access_type and access_attrib and merge into the field Op 575 * Get access_type and access_attrib and merge into the field Op
555 * access_type is first operand, access_attribute is second 576 * access_type is first operand, access_attribute is second. stuff
577 * these bytes into the node integer value for convenience.
556 */ 578 */
557 field->common.value.integer = 579
558 (((u32) ACPI_GET8(parser_state->aml) << 8)); 580 /* Get the two bytes (Type/Attribute) */
581
582 access_type = ACPI_GET8(parser_state->aml);
559 parser_state->aml++; 583 parser_state->aml++;
560 field->common.value.integer |= ACPI_GET8(parser_state->aml); 584 access_attribute = ACPI_GET8(parser_state->aml);
561 parser_state->aml++; 585 parser_state->aml++;
586
587 field->common.value.integer = (u8)access_type;
588 field->common.value.integer |= (u16)(access_attribute << 8);
589
590 /* This opcode has a third byte, access_length */
591
592 if (opcode == AML_INT_EXTACCESSFIELD_OP) {
593 access_length = ACPI_GET8(parser_state->aml);
594 parser_state->aml++;
595
596 field->common.value.integer |=
597 (u32)(access_length << 16);
598 }
599 break;
600
601 case AML_INT_CONNECTION_OP:
602
603 /*
604 * Argument for Connection operator can be either a Buffer
605 * (resource descriptor), or a name_string.
606 */
607 if (ACPI_GET8(parser_state->aml) == AML_BUFFER_OP) {
608 parser_state->aml++;
609
610 pkg_end = parser_state->aml;
611 pkg_length =
612 acpi_ps_get_next_package_length(parser_state);
613 pkg_end += pkg_length;
614
615 if (parser_state->aml < pkg_end) {
616
617 /* Non-empty list */
618
619 arg = acpi_ps_alloc_op(AML_INT_BYTELIST_OP);
620 if (!arg) {
621 return_PTR(NULL);
622 }
623
624 /* Get the actual buffer length argument */
625
626 opcode = ACPI_GET8(parser_state->aml);
627 parser_state->aml++;
628
629 switch (opcode) {
630 case AML_BYTE_OP: /* AML_BYTEDATA_ARG */
631 buffer_length =
632 ACPI_GET8(parser_state->aml);
633 parser_state->aml += 1;
634 break;
635
636 case AML_WORD_OP: /* AML_WORDDATA_ARG */
637 buffer_length =
638 ACPI_GET16(parser_state->aml);
639 parser_state->aml += 2;
640 break;
641
642 case AML_DWORD_OP: /* AML_DWORDATA_ARG */
643 buffer_length =
644 ACPI_GET32(parser_state->aml);
645 parser_state->aml += 4;
646 break;
647
648 default:
649 buffer_length = 0;
650 break;
651 }
652
653 /* Fill in bytelist data */
654
655 arg->named.value.size = buffer_length;
656 arg->named.data = parser_state->aml;
657 }
658
659 /* Skip to End of byte data */
660
661 parser_state->aml = pkg_end;
662 } else {
663 arg = acpi_ps_alloc_op(AML_INT_NAMEPATH_OP);
664 if (!arg) {
665 return_PTR(NULL);
666 }
667
668 /* Get the Namestring argument */
669
670 arg->common.value.name =
671 acpi_ps_get_next_namestring(parser_state);
672 }
673
674 /* Link the buffer/namestring to parent (CONNECTION_OP) */
675
676 acpi_ps_append_arg(field, arg);
562 break; 677 break;
563 678
564 default: 679 default:
diff --git a/drivers/acpi/acpica/psopcode.c b/drivers/acpi/acpica/psopcode.c
index bed08de7528c..9b3191001b3d 100644
--- a/drivers/acpi/acpica/psopcode.c
+++ b/drivers/acpi/acpica/psopcode.c
@@ -638,7 +638,16 @@ const struct acpi_opcode_info acpi_gbl_aml_op_info[AML_NUM_OPCODES] = {
638 638
639/* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY, 639/* 7E */ ACPI_OP("Timer", ARGP_TIMER_OP, ARGI_TIMER_OP, ACPI_TYPE_ANY,
640 AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R, 640 AML_CLASS_EXECUTE, AML_TYPE_EXEC_0A_0T_1R,
641 AML_FLAGS_EXEC_0A_0T_1R) 641 AML_FLAGS_EXEC_0A_0T_1R),
642
643/* ACPI 5.0 opcodes */
644
645/* 7F */ ACPI_OP("-ConnectField-", ARGP_CONNECTFIELD_OP,
646 ARGI_CONNECTFIELD_OP, ACPI_TYPE_ANY,
647 AML_CLASS_INTERNAL, AML_TYPE_BOGUS, AML_HAS_ARGS),
648/* 80 */ ACPI_OP("-ExtAccessField-", ARGP_CONNECTFIELD_OP,
649 ARGI_CONNECTFIELD_OP, ACPI_TYPE_ANY,
650 AML_CLASS_INTERNAL, AML_TYPE_BOGUS, 0)
642 651
643/*! [End] no source code translation !*/ 652/*! [End] no source code translation !*/
644}; 653};
@@ -657,7 +666,7 @@ static const u8 acpi_gbl_short_op_index[256] = {
657/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 666/* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
658/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX, 667/* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX,
659/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D, 668/* 0x30 */ 0x67, 0x66, 0x68, 0x65, 0x69, 0x64, 0x6A, 0x7D,
660/* 0x38 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 669/* 0x38 */ 0x7F, 0x80, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK,
661/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, 670/* 0x40 */ _UNK, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
662/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, 671/* 0x48 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
663/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, 672/* 0x50 */ _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC, _ASC,
diff --git a/drivers/acpi/acpica/pstree.c b/drivers/acpi/acpica/pstree.c
index f1464c03aa42..04311bbfcccb 100644
--- a/drivers/acpi/acpica/pstree.c
+++ b/drivers/acpi/acpica/pstree.c
@@ -74,6 +74,12 @@ union acpi_parse_object *acpi_ps_get_arg(union acpi_parse_object *op, u32 argn)
74 74
75 ACPI_FUNCTION_ENTRY(); 75 ACPI_FUNCTION_ENTRY();
76 76
77/*
78 if (Op->Common.aml_opcode == AML_INT_CONNECTION_OP)
79 {
80 return (Op->Common.Value.Arg);
81 }
82*/
77 /* Get the info structure for this opcode */ 83 /* Get the info structure for this opcode */
78 84
79 op_info = acpi_ps_get_opcode_info(op->common.aml_opcode); 85 op_info = acpi_ps_get_opcode_info(op->common.aml_opcode);