diff options
-rw-r--r-- | drivers/platform/x86/hp-wmi.c | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 0df4209648d1..c2ca5c22f8d2 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c @@ -188,6 +188,22 @@ struct rfkill2_device { static int rfkill2_count; static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES]; +/* map output size to the corresponding WMI method id */ +static inline int encode_outsize_for_pvsz(int outsize) +{ + if (outsize > 4096) + return -EINVAL; + if (outsize > 1024) + return 5; + if (outsize > 128) + return 4; + if (outsize > 4) + return 3; + if (outsize > 0) + return 2; + return 1; +} + /* * hp_wmi_perform_query * @@ -211,6 +227,7 @@ static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES]; static int hp_wmi_perform_query(int query, enum hp_wmi_command command, void *buffer, int insize, int outsize) { + int mid; struct bios_return *bios_return; int actual_outsize; union acpi_object *obj; @@ -225,11 +242,15 @@ static int hp_wmi_perform_query(int query, enum hp_wmi_command command, struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; int ret = 0; + mid = encode_outsize_for_pvsz(outsize); + if (WARN_ON(mid < 0)) + return mid; + if (WARN_ON(insize > sizeof(args.data))) return -EINVAL; memcpy(&args.data, buffer, insize); - wmi_evaluate_method(HPWMI_BIOS_GUID, 0, 0x3, &input, &output); + wmi_evaluate_method(HPWMI_BIOS_GUID, 0, mid, &input, &output); obj = output.pointer; |