diff options
Diffstat (limited to 'drivers/acpi/acpica/exfield.c')
-rw-r--r-- | drivers/acpi/acpica/exfield.c | 104 |
1 files changed, 97 insertions, 7 deletions
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index 68d97441432c..12878e1982f7 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c | |||
@@ -45,10 +45,71 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acdispat.h" | 46 | #include "acdispat.h" |
47 | #include "acinterp.h" | 47 | #include "acinterp.h" |
48 | #include "amlcode.h" | ||
48 | 49 | ||
49 | #define _COMPONENT ACPI_EXECUTER | 50 | #define _COMPONENT ACPI_EXECUTER |
50 | ACPI_MODULE_NAME("exfield") | 51 | ACPI_MODULE_NAME("exfield") |
51 | 52 | ||
53 | /* Local prototypes */ | ||
54 | static u32 | ||
55 | acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length); | ||
56 | |||
57 | /******************************************************************************* | ||
58 | * | ||
59 | * FUNCTION: acpi_get_serial_access_bytes | ||
60 | * | ||
61 | * PARAMETERS: accessor_type - The type of the protocol indicated by region | ||
62 | * field access attributes | ||
63 | * access_length - The access length of the region field | ||
64 | * | ||
65 | * RETURN: Decoded access length | ||
66 | * | ||
67 | * DESCRIPTION: This routine returns the length of the generic_serial_bus | ||
68 | * protocol bytes | ||
69 | * | ||
70 | ******************************************************************************/ | ||
71 | |||
72 | static u32 | ||
73 | acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length) | ||
74 | { | ||
75 | u32 length; | ||
76 | |||
77 | switch (accessor_type) { | ||
78 | case AML_FIELD_ATTRIB_QUICK: | ||
79 | |||
80 | length = 0; | ||
81 | break; | ||
82 | |||
83 | case AML_FIELD_ATTRIB_SEND_RCV: | ||
84 | case AML_FIELD_ATTRIB_BYTE: | ||
85 | |||
86 | length = 1; | ||
87 | break; | ||
88 | |||
89 | case AML_FIELD_ATTRIB_WORD: | ||
90 | case AML_FIELD_ATTRIB_WORD_CALL: | ||
91 | |||
92 | length = 2; | ||
93 | break; | ||
94 | |||
95 | case AML_FIELD_ATTRIB_MULTIBYTE: | ||
96 | case AML_FIELD_ATTRIB_RAW_BYTES: | ||
97 | case AML_FIELD_ATTRIB_RAW_PROCESS: | ||
98 | |||
99 | length = access_length; | ||
100 | break; | ||
101 | |||
102 | case AML_FIELD_ATTRIB_BLOCK: | ||
103 | case AML_FIELD_ATTRIB_BLOCK_CALL: | ||
104 | default: | ||
105 | |||
106 | length = ACPI_GSBUS_BUFFER_SIZE; | ||
107 | break; | ||
108 | } | ||
109 | |||
110 | return (length); | ||
111 | } | ||
112 | |||
52 | /******************************************************************************* | 113 | /******************************************************************************* |
53 | * | 114 | * |
54 | * FUNCTION: acpi_ex_read_data_from_field | 115 | * FUNCTION: acpi_ex_read_data_from_field |
@@ -63,8 +124,9 @@ ACPI_MODULE_NAME("exfield") | |||
63 | * Buffer, depending on the size of the field. | 124 | * Buffer, depending on the size of the field. |
64 | * | 125 | * |
65 | ******************************************************************************/ | 126 | ******************************************************************************/ |
127 | |||
66 | acpi_status | 128 | acpi_status |
67 | acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | 129 | acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state, |
68 | union acpi_operand_object *obj_desc, | 130 | union acpi_operand_object *obj_desc, |
69 | union acpi_operand_object **ret_buffer_desc) | 131 | union acpi_operand_object **ret_buffer_desc) |
70 | { | 132 | { |
@@ -73,6 +135,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
73 | acpi_size length; | 135 | acpi_size length; |
74 | void *buffer; | 136 | void *buffer; |
75 | u32 function; | 137 | u32 function; |
138 | u16 accessor_type; | ||
76 | 139 | ||
77 | ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); | 140 | ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc); |
78 | 141 | ||
@@ -116,9 +179,22 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state, | |||
116 | ACPI_READ | (obj_desc->field.attribute << 16); | 179 | ACPI_READ | (obj_desc->field.attribute << 16); |
117 | } else if (obj_desc->field.region_obj->region.space_id == | 180 | } else if (obj_desc->field.region_obj->region.space_id == |
118 | ACPI_ADR_SPACE_GSBUS) { | 181 | ACPI_ADR_SPACE_GSBUS) { |
119 | length = ACPI_GSBUS_BUFFER_SIZE; | 182 | accessor_type = obj_desc->field.attribute; |
120 | function = | 183 | length = acpi_ex_get_serial_access_length(accessor_type, |
121 | ACPI_READ | (obj_desc->field.attribute << 16); | 184 | obj_desc-> |
185 | field. | ||
186 | access_length); | ||
187 | |||
188 | /* | ||
189 | * Add additional 2 bytes for modeled generic_serial_bus data buffer: | ||
190 | * typedef struct { | ||
191 | * BYTEStatus; // Byte 0 of the data buffer | ||
192 | * BYTELength; // Byte 1 of the data buffer | ||
193 | * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer, | ||
194 | * } | ||
195 | */ | ||
196 | length += 2; | ||
197 | function = ACPI_READ | (accessor_type << 16); | ||
122 | } else { /* IPMI */ | 198 | } else { /* IPMI */ |
123 | 199 | ||
124 | length = ACPI_IPMI_BUFFER_SIZE; | 200 | length = ACPI_IPMI_BUFFER_SIZE; |
@@ -231,6 +307,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
231 | void *buffer; | 307 | void *buffer; |
232 | union acpi_operand_object *buffer_desc; | 308 | union acpi_operand_object *buffer_desc; |
233 | u32 function; | 309 | u32 function; |
310 | u16 accessor_type; | ||
234 | 311 | ||
235 | ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); | 312 | ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc); |
236 | 313 | ||
@@ -284,9 +361,22 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
284 | ACPI_WRITE | (obj_desc->field.attribute << 16); | 361 | ACPI_WRITE | (obj_desc->field.attribute << 16); |
285 | } else if (obj_desc->field.region_obj->region.space_id == | 362 | } else if (obj_desc->field.region_obj->region.space_id == |
286 | ACPI_ADR_SPACE_GSBUS) { | 363 | ACPI_ADR_SPACE_GSBUS) { |
287 | length = ACPI_GSBUS_BUFFER_SIZE; | 364 | accessor_type = obj_desc->field.attribute; |
288 | function = | 365 | length = acpi_ex_get_serial_access_length(accessor_type, |
289 | ACPI_WRITE | (obj_desc->field.attribute << 16); | 366 | obj_desc-> |
367 | field. | ||
368 | access_length); | ||
369 | |||
370 | /* | ||
371 | * Add additional 2 bytes for modeled generic_serial_bus data buffer: | ||
372 | * typedef struct { | ||
373 | * BYTEStatus; // Byte 0 of the data buffer | ||
374 | * BYTELength; // Byte 1 of the data buffer | ||
375 | * BYTE[x-1]Data; // Bytes 2-x of the arbitrary length data buffer, | ||
376 | * } | ||
377 | */ | ||
378 | length += 2; | ||
379 | function = ACPI_WRITE | (accessor_type << 16); | ||
290 | } else { /* IPMI */ | 380 | } else { /* IPMI */ |
291 | 381 | ||
292 | length = ACPI_IPMI_BUFFER_SIZE; | 382 | length = ACPI_IPMI_BUFFER_SIZE; |