Hi Shaohua, Could you also make it take a spec string as argument, not a prepared byte buffer? Regards, Alex. Shaohua Li пишет: > Add an API to execute _OSC. A lot of devices can have this method, so add a > generic API. > > Signed-off-by: Shaohua Li <shaohua.li@xxxxxxxxx> > --- > drivers/acpi/bus.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ > include/linux/acpi.h | 9 ++++++ > 2 files changed, 81 insertions(+) > > Index: linux/drivers/acpi/bus.c > =================================================================== > --- linux.orig/drivers/acpi/bus.c 2009-10-27 13:50:24.000000000 +0800 > +++ linux/drivers/acpi/bus.c 2009-10-27 14:02:30.000000000 +0800 > @@ -344,6 +344,78 @@ bool acpi_bus_can_wakeup(acpi_handle han > > EXPORT_SYMBOL(acpi_bus_can_wakeup); > > +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; > + u32 errors; > + > + if (!context) > + 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 = context->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; > + > + status = acpi_evaluate_object(handle, "_OSC", &input, &context->ret); > + if (ACPI_FAILURE(status)) > + return status; > + > + /* return buffer should have the same length as cap buffer */ > + if (context->ret.length != context->cap.length) > + return AE_NULL_OBJECT; > + > + out_obj = context->ret.pointer; > + if (out_obj->type != ACPI_TYPE_BUFFER) { > + printk(KERN_DEBUG "_OSC evaluation returned wrong type\n"); > + 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) > + printk(KERN_DEBUG "_OSC request failed\n"); > + if (errors & OSC_INVALID_UUID_ERROR) > + printk(KERN_DEBUG "_OSC invalid UUID\n"); > + if (errors & OSC_INVALID_REVISION_ERROR) > + printk(KERN_DEBUG "_OSC invalid revision\n"); > + if (errors & OSC_CAPABILITIES_MASK_ERROR) { > + if (((u32 *)context->cap.pointer)[OSC_QUERY_TYPE] > + & OSC_QUERY_ENABLE) > + goto out_success; > + printk(KERN_DEBUG > + "Firmware did not grant requested _OSC control\n"); > + status = AE_SUPPORT; > + goto out_kfree; > + } > + status = AE_ERROR; > + goto out_kfree; > + } > +out_success: > + return AE_OK; > + > +out_kfree: > + kfree(context->ret.pointer); > + context->ret.pointer = NULL; > + return status; > +} > +EXPORT_SYMBOL(acpi_run_osc); > + > /* -------------------------------------------------------------------------- > Event Management > -------------------------------------------------------------------------- */ > Index: linux/include/linux/acpi.h > =================================================================== > --- linux.orig/include/linux/acpi.h 2009-10-27 13:50:24.000000000 +0800 > +++ linux/include/linux/acpi.h 2009-10-27 13:50:35.000000000 +0800 > @@ -253,6 +253,13 @@ void __init acpi_old_suspend_ordering(vo > void __init acpi_s4_no_nvs(void); > #endif /* CONFIG_PM_SLEEP */ > > +struct acpi_osc_context { > + u8 *uuid; > + int rev; > + struct acpi_buffer cap; /* arg2/arg3 */ > + struct acpi_buffer ret; /* free by caller if success */ > +}; > + > #define OSC_QUERY_TYPE 0 > #define OSC_SUPPORT_TYPE 1 > #define OSC_CONTROL_TYPE 2 > @@ -265,6 +272,8 @@ void __init acpi_s4_no_nvs(void); > #define OSC_INVALID_REVISION_ERROR 8 > #define OSC_CAPABILITIES_MASK_ERROR 16 > > +acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context); > + > /* _OSC DW1 Definition (OS Support Fields) */ > #define OSC_EXT_PCI_CONFIG_SUPPORT 1 > #define OSC_ACTIVE_STATE_PWR_SUPPORT 2 > -- > To unsubscribe from this list: send the line "unsubscribe linux-acpi" in > the body of a message to majordomo@xxxxxxxxxxxxxxx > More majordomo info at http://vger.kernel.org/majordomo-info.html > -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html