On 2014年04月22日 05:38, Rafael J. Wysocki wrote:
> Hi,
> 
> On Wednesday, April 16, 2014 09:24:34 PM Lan Tianyu wrote:
>> From: Lv Zheng <lv.zh...@intel.com>
>>
>> The size of the buffer allocated for generic_serial_bus region access
>> is not correct.  This patch introduces acpi_ex_get_serial_access_length()
>> to be invoked to obtain correct data buffer length.  Reported by
>> Lan Tianyu, Fixed by Lv Zheng.
>>
>> Signed-off-by: Lv Zheng <lv.zh...@intel.com>
>> Signed-off-by: Lan Tianyu <tianyu....@intel.com>
> 
> I'm queueing up this patch as a fix for 3.15, but can you please resend the
> whole series with a CC to linux-acpi?
> 

Ok. I will do that.

> 
>> ---
>>  drivers/acpi/acpica/exfield.c | 104 
>> +++++++++++++++++++++++++++++++++++++++---
>>  1 file changed, 97 insertions(+), 7 deletions(-)
>>
>> diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
>> index 68d9744..12878e1 100644
>> --- a/drivers/acpi/acpica/exfield.c
>> +++ b/drivers/acpi/acpica/exfield.c
>> @@ -45,10 +45,71 @@
>>  #include "accommon.h"
>>  #include "acdispat.h"
>>  #include "acinterp.h"
>> +#include "amlcode.h"
>>  
>>  #define _COMPONENT          ACPI_EXECUTER
>>  ACPI_MODULE_NAME("exfield")
>>  
>> +/* Local prototypes */
>> +static u32
>> +acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length);
>> +
>> +/*******************************************************************************
>> + *
>> + * FUNCTION:    acpi_get_serial_access_bytes
>> + *
>> + * PARAMETERS:  accessor_type   - The type of the protocol indicated by 
>> region
>> + *                                field access attributes
>> + *              access_length   - The access length of the region field
>> + *
>> + * RETURN:      Decoded access length
>> + *
>> + * DESCRIPTION: This routine returns the length of the generic_serial_bus
>> + *              protocol bytes
>> + *
>> + 
>> ******************************************************************************/
>> +
>> +static u32
>> +acpi_ex_get_serial_access_length(u32 accessor_type, u32 access_length)
>> +{
>> +    u32 length;
>> +
>> +    switch (accessor_type) {
>> +    case AML_FIELD_ATTRIB_QUICK:
>> +
>> +            length = 0;
>> +            break;
>> +
>> +    case AML_FIELD_ATTRIB_SEND_RCV:
>> +    case AML_FIELD_ATTRIB_BYTE:
>> +
>> +            length = 1;
>> +            break;
>> +
>> +    case AML_FIELD_ATTRIB_WORD:
>> +    case AML_FIELD_ATTRIB_WORD_CALL:
>> +
>> +            length = 2;
>> +            break;
>> +
>> +    case AML_FIELD_ATTRIB_MULTIBYTE:
>> +    case AML_FIELD_ATTRIB_RAW_BYTES:
>> +    case AML_FIELD_ATTRIB_RAW_PROCESS:
>> +
>> +            length = access_length;
>> +            break;
>> +
>> +    case AML_FIELD_ATTRIB_BLOCK:
>> +    case AML_FIELD_ATTRIB_BLOCK_CALL:
>> +    default:
>> +
>> +            length = ACPI_GSBUS_BUFFER_SIZE;
>> +            break;
>> +    }
>> +
>> +    return (length);
>> +}
>> +
>>  
>> /*******************************************************************************
>>   *
>>   * FUNCTION:    acpi_ex_read_data_from_field
>> @@ -63,8 +124,9 @@ ACPI_MODULE_NAME("exfield")
>>   *              Buffer, depending on the size of the field.
>>   *
>>   
>> ******************************************************************************/
>> +
>>  acpi_status
>> -acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
>> +acpi_ex_read_data_from_field(struct acpi_walk_state * walk_state,
>>                           union acpi_operand_object *obj_desc,
>>                           union acpi_operand_object **ret_buffer_desc)
>>  {
>> @@ -73,6 +135,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state 
>> *walk_state,
>>      acpi_size length;
>>      void *buffer;
>>      u32 function;
>> +    u16 accessor_type;
>>  
>>      ACPI_FUNCTION_TRACE_PTR(ex_read_data_from_field, obj_desc);
>>  
>> @@ -116,9 +179,22 @@ acpi_ex_read_data_from_field(struct acpi_walk_state 
>> *walk_state,
>>                          ACPI_READ | (obj_desc->field.attribute << 16);
>>              } else if (obj_desc->field.region_obj->region.space_id ==
>>                         ACPI_ADR_SPACE_GSBUS) {
>> -                    length = ACPI_GSBUS_BUFFER_SIZE;
>> -                    function =
>> -                        ACPI_READ | (obj_desc->field.attribute << 16);
>> +                    accessor_type = obj_desc->field.attribute;
>> +                    length = acpi_ex_get_serial_access_length(accessor_type,
>> +                                                              obj_desc->
>> +                                                              field.
>> +                                                              
>> access_length);
>> +
>> +                    /*
>> +                     * Add additional 2 bytes for modeled 
>> generic_serial_bus data buffer:
>> +                     * typedef struct {
>> +                     *     BYTEStatus; // Byte 0 of the data buffer
>> +                     *     BYTELength; // Byte 1 of the data buffer
>> +                     *     BYTE[x-1]Data; // Bytes 2-x of the arbitrary 
>> length data buffer,
>> +                     * }
>> +                     */
>> +                    length += 2;
>> +                    function = ACPI_READ | (accessor_type << 16);
>>              } else {        /* IPMI */
>>  
>>                      length = ACPI_IPMI_BUFFER_SIZE;
>> @@ -231,6 +307,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object 
>> *source_desc,
>>      void *buffer;
>>      union acpi_operand_object *buffer_desc;
>>      u32 function;
>> +    u16 accessor_type;
>>  
>>      ACPI_FUNCTION_TRACE_PTR(ex_write_data_to_field, obj_desc);
>>  
>> @@ -284,9 +361,22 @@ acpi_ex_write_data_to_field(union acpi_operand_object 
>> *source_desc,
>>                          ACPI_WRITE | (obj_desc->field.attribute << 16);
>>              } else if (obj_desc->field.region_obj->region.space_id ==
>>                         ACPI_ADR_SPACE_GSBUS) {
>> -                    length = ACPI_GSBUS_BUFFER_SIZE;
>> -                    function =
>> -                        ACPI_WRITE | (obj_desc->field.attribute << 16);
>> +                    accessor_type = obj_desc->field.attribute;
>> +                    length = acpi_ex_get_serial_access_length(accessor_type,
>> +                                                              obj_desc->
>> +                                                              field.
>> +                                                              
>> access_length);
>> +
>> +                    /*
>> +                     * Add additional 2 bytes for modeled 
>> generic_serial_bus data buffer:
>> +                     * typedef struct {
>> +                     *     BYTEStatus; // Byte 0 of the data buffer
>> +                     *     BYTELength; // Byte 1 of the data buffer
>> +                     *     BYTE[x-1]Data; // Bytes 2-x of the arbitrary 
>> length data buffer,
>> +                     * }
>> +                     */
>> +                    length += 2;
>> +                    function = ACPI_WRITE | (accessor_type << 16);
>>              } else {        /* IPMI */
>>  
>>                      length = ACPI_IPMI_BUFFER_SIZE;
>>
> 


-- 
Best regards
Tianyu Lan
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to