Merge branches 'bugzilla-14446', 'bugzilla-14753' and 'bugzilla-14824' into release
authorLen Brown <len.brown@intel.com>
Thu, 24 Dec 2009 06:17:01 +0000 (01:17 -0500)
committerLen Brown <len.brown@intel.com>
Thu, 24 Dec 2009 06:17:01 +0000 (01:17 -0500)
1  2  3  4 
drivers/acpi/bus.c
drivers/acpi/ec.c

@@@@@ -344,162 -344,6 -344,6 -344,152 +344,162 @@@@@ bool acpi_bus_can_wakeup(acpi_handle ha
    
    EXPORT_SYMBOL(acpi_bus_can_wakeup);
    
   -    status = acpi_evaluate_object(handle, "_OSC", &input, &context->ret);
 ++ static void acpi_print_osc_error(acpi_handle handle,
 ++     struct acpi_osc_context *context, char *error)
 ++ {
 ++     struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER};
 ++     int i;
 ++ 
 ++     if (ACPI_FAILURE(acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer)))
 ++             printk(KERN_DEBUG "%s\n", error);
 ++     else {
 ++             printk(KERN_DEBUG "%s:%s\n", (char *)buffer.pointer, error);
 ++             kfree(buffer.pointer);
 ++     }
 ++     printk(KERN_DEBUG"_OSC request data:");
 ++     for (i = 0; i < context->cap.length; i += sizeof(u32))
 ++             printk("%x ", *((u32 *)(context->cap.pointer + i)));
 ++     printk("\n");
 ++ }
 ++ 
 ++ static u8 hex_val(unsigned char c)
 ++ {
 ++     return isdigit(c) ? c - '0' : toupper(c) - 'A' + 10;
 ++ }
 ++ 
 ++ static acpi_status acpi_str_to_uuid(char *str, u8 *uuid)
 ++ {
 ++     int i;
 ++     static int opc_map_to_uuid[16] = {6, 4, 2, 0, 11, 9, 16, 14, 19, 21,
 ++             24, 26, 28, 30, 32, 34};
 ++ 
 ++     if (strlen(str) != 36)
 ++             return AE_BAD_PARAMETER;
 ++     for (i = 0; i < 36; i++) {
 ++             if (i == 8 || i == 13 || i == 18 || i == 23) {
 ++                     if (str[i] != '-')
 ++                             return AE_BAD_PARAMETER;
 ++             } else if (!isxdigit(str[i]))
 ++                     return AE_BAD_PARAMETER;
 ++     }
 ++     for (i = 0; i < 16; i++) {
 ++             uuid[i] = hex_val(str[opc_map_to_uuid[i]]) << 4;
 ++             uuid[i] |= hex_val(str[opc_map_to_uuid[i] + 1]);
 ++     }
 ++     return AE_OK;
 ++ }
 ++ 
 ++ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
 ++ {
 ++     acpi_status status;
 ++     struct acpi_object_list input;
 ++     union acpi_object in_params[4];
 ++     union acpi_object *out_obj;
 ++     u8 uuid[16];
 ++     u32 errors;
 +++    struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
 ++ 
 ++     if (!context)
 ++             return AE_ERROR;
 ++     if (ACPI_FAILURE(acpi_str_to_uuid(context->uuid_str, uuid)))
 ++             return AE_ERROR;
 ++     context->ret.length = ACPI_ALLOCATE_BUFFER;
 ++     context->ret.pointer = NULL;
 ++ 
 ++     /* Setting up input parameters */
 ++     input.count = 4;
 ++     input.pointer = in_params;
 ++     in_params[0].type               = ACPI_TYPE_BUFFER;
 ++     in_params[0].buffer.length      = 16;
 ++     in_params[0].buffer.pointer     = uuid;
 ++     in_params[1].type               = ACPI_TYPE_INTEGER;
 ++     in_params[1].integer.value      = context->rev;
 ++     in_params[2].type               = ACPI_TYPE_INTEGER;
 ++     in_params[2].integer.value      = context->cap.length/sizeof(u32);
 ++     in_params[3].type               = ACPI_TYPE_BUFFER;
 ++     in_params[3].buffer.length      = context->cap.length;
 ++     in_params[3].buffer.pointer     = context->cap.pointer;
 ++ 
   -    /* return buffer should have the same length as cap buffer */
   -    if (context->ret.length != context->cap.length)
 +++    status = acpi_evaluate_object(handle, "_OSC", &input, &output);
 ++     if (ACPI_FAILURE(status))
 ++             return status;
 ++ 
   -    out_obj = context->ret.pointer;
   -    if (out_obj->type != ACPI_TYPE_BUFFER) {
 +++    if (!output.length)
 ++             return AE_NULL_OBJECT;
 ++ 
   -    return AE_OK;
 +++    out_obj = output.pointer;
 +++    if (out_obj->type != ACPI_TYPE_BUFFER
 +++            || out_obj->buffer.length != context->cap.length) {
 ++             acpi_print_osc_error(handle, context,
 ++                     "_OSC evaluation returned wrong type");
 ++             status = AE_TYPE;
 ++             goto out_kfree;
 ++     }
 ++     /* Need to ignore the bit0 in result code */
 ++     errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
 ++     if (errors) {
 ++             if (errors & OSC_REQUEST_ERROR)
 ++                     acpi_print_osc_error(handle, context,
 ++                             "_OSC request failed");
 ++             if (errors & OSC_INVALID_UUID_ERROR)
 ++                     acpi_print_osc_error(handle, context,
 ++                             "_OSC invalid UUID");
 ++             if (errors & OSC_INVALID_REVISION_ERROR)
 ++                     acpi_print_osc_error(handle, context,
 ++                             "_OSC invalid revision");
 ++             if (errors & OSC_CAPABILITIES_MASK_ERROR) {
 ++                     if (((u32 *)context->cap.pointer)[OSC_QUERY_TYPE]
 ++                         & OSC_QUERY_ENABLE)
 ++                             goto out_success;
 ++                     status = AE_SUPPORT;
 ++                     goto out_kfree;
 ++             }
 ++             status = AE_ERROR;
 ++             goto out_kfree;
 ++     }
 ++ out_success:
   -    kfree(context->ret.pointer);
   -    context->ret.pointer = NULL;
 +++    context->ret.length = out_obj->buffer.length;
 +++    context->ret.pointer = kmalloc(context->ret.length, GFP_KERNEL);
 +++    if (!context->ret.pointer) {
 +++            status =  AE_NO_MEMORY;
 +++            goto out_kfree;
 +++    }
 +++    memcpy(context->ret.pointer, out_obj->buffer.pointer,
 +++            context->ret.length);
 +++    status =  AE_OK;
 ++ 
 ++ out_kfree:
 +++    kfree(output.pointer);
 +++    if (status != AE_OK)
 +++            context->ret.pointer = NULL;
 ++     return status;
 ++ }
 ++ EXPORT_SYMBOL(acpi_run_osc);
 ++ 
 ++ static u8 sb_uuid_str[] = "0811B06E-4A27-44F9-8D60-3CBBC22E7B48";
 ++ static void acpi_bus_osc_support(void)
 ++ {
 ++     u32 capbuf[2];
 ++     struct acpi_osc_context context = {
 ++             .uuid_str = sb_uuid_str,
 ++             .rev = 1,
 ++             .cap.length = 8,
 ++             .cap.pointer = capbuf,
 ++     };
 ++     acpi_handle handle;
 ++ 
 ++     capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
 ++     capbuf[OSC_SUPPORT_TYPE] = OSC_SB_PR3_SUPPORT; /* _PR3 is in use */
 ++ #ifdef CONFIG_ACPI_PROCESSOR_AGGREGATOR
 ++     capbuf[OSC_SUPPORT_TYPE] |= OSC_SB_PAD_SUPPORT;
 ++ #endif
 ++     if (ACPI_FAILURE(acpi_get_handle(NULL, "\\_SB", &handle)))
 ++             return;
 ++     if (ACPI_SUCCESS(acpi_run_osc(handle, &context)))
 ++             kfree(context.ret.pointer);
 ++     /* do we need to check the returned cap? Sounds no */
 ++ }
 ++ 
    /* --------------------------------------------------------------------------
                                    Event Management
       -------------------------------------------------------------------------- */
Simple merge