diff options
Diffstat (limited to 'drivers/acpi/acpica/exfield.c')
-rw-r--r-- | drivers/acpi/acpica/exfield.c | 74 |
1 files changed, 42 insertions, 32 deletions
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c index c95fd186ded2..ad7080ba65e2 100644 --- a/drivers/acpi/acpica/exfield.c +++ b/drivers/acpi/acpica/exfield.c | |||
@@ -167,10 +167,11 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state, | |||
167 | || obj_desc->field.region_obj->region.space_id == | 167 | || obj_desc->field.region_obj->region.space_id == |
168 | ACPI_ADR_SPACE_IPMI)) { | 168 | ACPI_ADR_SPACE_IPMI)) { |
169 | /* | 169 | /* |
170 | * This is an SMBus, GSBus or IPMI read. We must create a buffer to hold | 170 | * This is an SMBus, GSBus or IPMI read. We must create a buffer to |
171 | * the data and then directly access the region handler. | 171 | * hold the data and then directly access the region handler. |
172 | * | 172 | * |
173 | * Note: SMBus and GSBus protocol value is passed in upper 16-bits of Function | 173 | * Note: SMBus and GSBus protocol value is passed in upper 16-bits |
174 | * of Function | ||
174 | */ | 175 | */ |
175 | if (obj_desc->field.region_obj->region.space_id == | 176 | if (obj_desc->field.region_obj->region.space_id == |
176 | ACPI_ADR_SPACE_SMBUS) { | 177 | ACPI_ADR_SPACE_SMBUS) { |
@@ -180,17 +181,17 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state, | |||
180 | } else if (obj_desc->field.region_obj->region.space_id == | 181 | } else if (obj_desc->field.region_obj->region.space_id == |
181 | ACPI_ADR_SPACE_GSBUS) { | 182 | ACPI_ADR_SPACE_GSBUS) { |
182 | accessor_type = obj_desc->field.attribute; | 183 | accessor_type = obj_desc->field.attribute; |
183 | length = acpi_ex_get_serial_access_length(accessor_type, | 184 | length = |
184 | obj_desc-> | 185 | acpi_ex_get_serial_access_length(accessor_type, |
185 | field. | 186 | obj_desc->field. |
186 | access_length); | 187 | access_length); |
187 | 188 | ||
188 | /* | 189 | /* |
189 | * Add additional 2 bytes for the generic_serial_bus data buffer: | 190 | * Add additional 2 bytes for the generic_serial_bus data buffer: |
190 | * | 191 | * |
191 | * Status; (Byte 0 of the data buffer) | 192 | * Status; (Byte 0 of the data buffer) |
192 | * Length; (Byte 1 of the data buffer) | 193 | * Length; (Byte 1 of the data buffer) |
193 | * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer) | 194 | * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) |
194 | */ | 195 | */ |
195 | length += 2; | 196 | length += 2; |
196 | function = ACPI_READ | (accessor_type << 16); | 197 | function = ACPI_READ | (accessor_type << 16); |
@@ -216,6 +217,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state, | |||
216 | buffer_desc-> | 217 | buffer_desc-> |
217 | buffer.pointer), | 218 | buffer.pointer), |
218 | function); | 219 | function); |
220 | |||
219 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | 221 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
220 | goto exit; | 222 | goto exit; |
221 | } | 223 | } |
@@ -232,6 +234,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state, | |||
232 | */ | 234 | */ |
233 | length = | 235 | length = |
234 | (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.bit_length); | 236 | (acpi_size) ACPI_ROUND_BITS_UP_TO_BYTES(obj_desc->field.bit_length); |
237 | |||
235 | if (length > acpi_gbl_integer_byte_width) { | 238 | if (length > acpi_gbl_integer_byte_width) { |
236 | 239 | ||
237 | /* Field is too large for an Integer, create a Buffer instead */ | 240 | /* Field is too large for an Integer, create a Buffer instead */ |
@@ -273,8 +276,10 @@ acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state, | |||
273 | 276 | ||
274 | /* Perform the write */ | 277 | /* Perform the write */ |
275 | 278 | ||
276 | status = acpi_ex_access_region(obj_desc, 0, | 279 | status = |
277 | (u64 *)buffer, ACPI_READ); | 280 | acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, |
281 | ACPI_READ); | ||
282 | |||
278 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | 283 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
279 | if (ACPI_FAILURE(status)) { | 284 | if (ACPI_FAILURE(status)) { |
280 | acpi_ut_remove_reference(buffer_desc); | 285 | acpi_ut_remove_reference(buffer_desc); |
@@ -366,19 +371,22 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
366 | || obj_desc->field.region_obj->region.space_id == | 371 | || obj_desc->field.region_obj->region.space_id == |
367 | ACPI_ADR_SPACE_IPMI)) { | 372 | ACPI_ADR_SPACE_IPMI)) { |
368 | /* | 373 | /* |
369 | * This is an SMBus, GSBus or IPMI write. We will bypass the entire field | 374 | * This is an SMBus, GSBus or IPMI write. We will bypass the entire |
370 | * mechanism and handoff the buffer directly to the handler. For | 375 | * field mechanism and handoff the buffer directly to the handler. |
371 | * these address spaces, the buffer is bi-directional; on a write, | 376 | * For these address spaces, the buffer is bi-directional; on a |
372 | * return data is returned in the same buffer. | 377 | * write, return data is returned in the same buffer. |
373 | * | 378 | * |
374 | * Source must be a buffer of sufficient size: | 379 | * Source must be a buffer of sufficient size: |
375 | * ACPI_SMBUS_BUFFER_SIZE, ACPI_GSBUS_BUFFER_SIZE, or ACPI_IPMI_BUFFER_SIZE. | 380 | * ACPI_SMBUS_BUFFER_SIZE, ACPI_GSBUS_BUFFER_SIZE, or |
381 | * ACPI_IPMI_BUFFER_SIZE. | ||
376 | * | 382 | * |
377 | * Note: SMBus and GSBus protocol type is passed in upper 16-bits of Function | 383 | * Note: SMBus and GSBus protocol type is passed in upper 16-bits |
384 | * of Function | ||
378 | */ | 385 | */ |
379 | if (source_desc->common.type != ACPI_TYPE_BUFFER) { | 386 | if (source_desc->common.type != ACPI_TYPE_BUFFER) { |
380 | ACPI_ERROR((AE_INFO, | 387 | ACPI_ERROR((AE_INFO, |
381 | "SMBus/IPMI/GenericSerialBus write requires Buffer, found type %s", | 388 | "SMBus/IPMI/GenericSerialBus write requires " |
389 | "Buffer, found type %s", | ||
382 | acpi_ut_get_object_type_name(source_desc))); | 390 | acpi_ut_get_object_type_name(source_desc))); |
383 | 391 | ||
384 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); | 392 | return_ACPI_STATUS(AE_AML_OPERAND_TYPE); |
@@ -392,17 +400,17 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
392 | } else if (obj_desc->field.region_obj->region.space_id == | 400 | } else if (obj_desc->field.region_obj->region.space_id == |
393 | ACPI_ADR_SPACE_GSBUS) { | 401 | ACPI_ADR_SPACE_GSBUS) { |
394 | accessor_type = obj_desc->field.attribute; | 402 | accessor_type = obj_desc->field.attribute; |
395 | length = acpi_ex_get_serial_access_length(accessor_type, | 403 | length = |
396 | obj_desc-> | 404 | acpi_ex_get_serial_access_length(accessor_type, |
397 | field. | 405 | obj_desc->field. |
398 | access_length); | 406 | access_length); |
399 | 407 | ||
400 | /* | 408 | /* |
401 | * Add additional 2 bytes for the generic_serial_bus data buffer: | 409 | * Add additional 2 bytes for the generic_serial_bus data buffer: |
402 | * | 410 | * |
403 | * Status; (Byte 0 of the data buffer) | 411 | * Status; (Byte 0 of the data buffer) |
404 | * Length; (Byte 1 of the data buffer) | 412 | * Length; (Byte 1 of the data buffer) |
405 | * Data[x-1]; (Bytes 2-x of the arbitrary length data buffer) | 413 | * Data[x-1]: (Bytes 2-x of the arbitrary length data buffer) |
406 | */ | 414 | */ |
407 | length += 2; | 415 | length += 2; |
408 | function = ACPI_WRITE | (accessor_type << 16); | 416 | function = ACPI_WRITE | (accessor_type << 16); |
@@ -414,7 +422,8 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
414 | 422 | ||
415 | if (source_desc->buffer.length < length) { | 423 | if (source_desc->buffer.length < length) { |
416 | ACPI_ERROR((AE_INFO, | 424 | ACPI_ERROR((AE_INFO, |
417 | "SMBus/IPMI/GenericSerialBus write requires Buffer of length %u, found length %u", | 425 | "SMBus/IPMI/GenericSerialBus write requires " |
426 | "Buffer of length %u, found length %u", | ||
418 | length, source_desc->buffer.length)); | 427 | length, source_desc->buffer.length)); |
419 | 428 | ||
420 | return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); | 429 | return_ACPI_STATUS(AE_AML_BUFFER_LIMIT); |
@@ -438,8 +447,8 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
438 | * Perform the write (returns status and perhaps data in the | 447 | * Perform the write (returns status and perhaps data in the |
439 | * same buffer) | 448 | * same buffer) |
440 | */ | 449 | */ |
441 | status = acpi_ex_access_region(obj_desc, 0, | 450 | status = |
442 | (u64 *)buffer, function); | 451 | acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, function); |
443 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | 452 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
444 | 453 | ||
445 | *result_desc = buffer_desc; | 454 | *result_desc = buffer_desc; |
@@ -460,7 +469,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
460 | } | 469 | } |
461 | 470 | ||
462 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, | 471 | ACPI_DEBUG_PRINT((ACPI_DB_BFIELD, |
463 | "GPIO FieldWrite [FROM]: (%s:%X), Val %.8X [TO]: Pin %u Bits %u\n", | 472 | "GPIO FieldWrite [FROM]: (%s:%X), Val %.8X [TO]: Pin %u Bits %u\n", |
464 | acpi_ut_get_type_name(source_desc->common. | 473 | acpi_ut_get_type_name(source_desc->common. |
465 | type), | 474 | type), |
466 | source_desc->common.type, | 475 | source_desc->common.type, |
@@ -476,8 +485,9 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, | |||
476 | 485 | ||
477 | /* Perform the write */ | 486 | /* Perform the write */ |
478 | 487 | ||
479 | status = acpi_ex_access_region(obj_desc, 0, | 488 | status = |
480 | (u64 *)buffer, ACPI_WRITE); | 489 | acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, |
490 | ACPI_WRITE); | ||
481 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); | 491 | acpi_ex_release_global_lock(obj_desc->common_field.field_flags); |
482 | return_ACPI_STATUS(status); | 492 | return_ACPI_STATUS(status); |
483 | } | 493 | } |