diff options
| author | Matthew Garrett <mjg@redhat.com> | 2010-08-23 15:52:34 -0400 |
|---|---|---|
| committer | Matthew Garrett <mjg@redhat.com> | 2010-08-23 16:27:08 -0400 |
| commit | a8ec105c0764c848d59f18a31f91fa00c99b2e7f (patch) | |
| tree | eb4c68789aae5d4ffaeb6acaff40af5b0823c944 | |
| parent | c76a3e1d6c52c5cc1371f1abc7381c5715ebdf7f (diff) | |
hp-wmi: Fix query interface
The machines I have appear to provide their return value in the arguments
structure, not the output structure. Rework the driver to use that again
in order to get rfkill working again.
Signed-off-by: Matthew Garrett <mjg@redhat.com>
| -rw-r--r-- | drivers/platform/x86/hp-wmi.c | 64 |
1 files changed, 25 insertions, 39 deletions
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index f15516374987..c1741142a4cb 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
| @@ -79,12 +79,13 @@ struct bios_args { | |||
| 79 | u32 command; | 79 | u32 command; |
| 80 | u32 commandtype; | 80 | u32 commandtype; |
| 81 | u32 datasize; | 81 | u32 datasize; |
| 82 | char *data; | 82 | u32 data; |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | struct bios_return { | 85 | struct bios_return { |
| 86 | u32 sigpass; | 86 | u32 sigpass; |
| 87 | u32 return_code; | 87 | u32 return_code; |
| 88 | u32 value; | ||
| 88 | }; | 89 | }; |
| 89 | 90 | ||
| 90 | struct key_entry { | 91 | struct key_entry { |
| @@ -148,7 +149,7 @@ static struct platform_driver hp_wmi_driver = { | |||
| 148 | * buffer = kzalloc(128, GFP_KERNEL); | 149 | * buffer = kzalloc(128, GFP_KERNEL); |
| 149 | * ret = hp_wmi_perform_query(0x7, 0, buffer, 128) | 150 | * ret = hp_wmi_perform_query(0x7, 0, buffer, 128) |
| 150 | */ | 151 | */ |
| 151 | static int hp_wmi_perform_query(int query, int write, char *buffer, | 152 | static int hp_wmi_perform_query(int query, int write, u32 *buffer, |
| 152 | int buffersize) | 153 | int buffersize) |
| 153 | { | 154 | { |
| 154 | struct bios_return bios_return; | 155 | struct bios_return bios_return; |
| @@ -159,7 +160,7 @@ static int hp_wmi_perform_query(int query, int write, char *buffer, | |||
| 159 | .command = write ? 0x2 : 0x1, | 160 | .command = write ? 0x2 : 0x1, |
| 160 | .commandtype = query, | 161 | .commandtype = query, |
| 161 | .datasize = buffersize, | 162 | .datasize = buffersize, |
| 162 | .data = buffer, | 163 | .data = *buffer, |
| 163 | }; | 164 | }; |
| 164 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; | 165 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; |
| 165 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 166 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; |
| @@ -177,29 +178,14 @@ static int hp_wmi_perform_query(int query, int write, char *buffer, | |||
| 177 | 178 | ||
| 178 | bios_return = *((struct bios_return *)obj->buffer.pointer); | 179 | bios_return = *((struct bios_return *)obj->buffer.pointer); |
| 179 | 180 | ||
| 180 | if (bios_return.return_code) { | 181 | memcpy(buffer, &bios_return.value, sizeof(bios_return.value)); |
| 181 | printk(KERN_WARNING PREFIX "Query %d returned %d\n", query, | ||
| 182 | bios_return.return_code); | ||
| 183 | kfree(obj); | ||
| 184 | return bios_return.return_code; | ||
| 185 | } | ||
| 186 | if (obj->buffer.length - sizeof(bios_return) > buffersize) { | ||
| 187 | kfree(obj); | ||
| 188 | return -EINVAL; | ||
| 189 | } | ||
| 190 | |||
| 191 | memset(buffer, 0, buffersize); | ||
| 192 | memcpy(buffer, | ||
| 193 | ((char *)obj->buffer.pointer) + sizeof(struct bios_return), | ||
| 194 | obj->buffer.length - sizeof(bios_return)); | ||
| 195 | kfree(obj); | ||
| 196 | return 0; | 182 | return 0; |
| 197 | } | 183 | } |
| 198 | 184 | ||
| 199 | static int hp_wmi_display_state(void) | 185 | static int hp_wmi_display_state(void) |
| 200 | { | 186 | { |
| 201 | int state; | 187 | int state = 0; |
| 202 | int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, (char *)&state, | 188 | int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, &state, |
| 203 | sizeof(state)); | 189 | sizeof(state)); |
| 204 | if (ret) | 190 | if (ret) |
| 205 | return -EINVAL; | 191 | return -EINVAL; |
| @@ -208,8 +194,8 @@ static int hp_wmi_display_state(void) | |||
| 208 | 194 | ||
| 209 | static int hp_wmi_hddtemp_state(void) | 195 | static int hp_wmi_hddtemp_state(void) |
| 210 | { | 196 | { |
| 211 | int state; | 197 | int state = 0; |
| 212 | int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, (char *)&state, | 198 | int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, &state, |
| 213 | sizeof(state)); | 199 | sizeof(state)); |
| 214 | if (ret) | 200 | if (ret) |
| 215 | return -EINVAL; | 201 | return -EINVAL; |
| @@ -218,8 +204,8 @@ static int hp_wmi_hddtemp_state(void) | |||
| 218 | 204 | ||
| 219 | static int hp_wmi_als_state(void) | 205 | static int hp_wmi_als_state(void) |
| 220 | { | 206 | { |
| 221 | int state; | 207 | int state = 0; |
| 222 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, (char *)&state, | 208 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, &state, |
| 223 | sizeof(state)); | 209 | sizeof(state)); |
| 224 | if (ret) | 210 | if (ret) |
| 225 | return -EINVAL; | 211 | return -EINVAL; |
| @@ -228,8 +214,8 @@ static int hp_wmi_als_state(void) | |||
| 228 | 214 | ||
| 229 | static int hp_wmi_dock_state(void) | 215 | static int hp_wmi_dock_state(void) |
| 230 | { | 216 | { |
| 231 | int state; | 217 | int state = 0; |
| 232 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, (char *)&state, | 218 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state, |
| 233 | sizeof(state)); | 219 | sizeof(state)); |
| 234 | 220 | ||
| 235 | if (ret) | 221 | if (ret) |
| @@ -240,8 +226,8 @@ static int hp_wmi_dock_state(void) | |||
| 240 | 226 | ||
| 241 | static int hp_wmi_tablet_state(void) | 227 | static int hp_wmi_tablet_state(void) |
| 242 | { | 228 | { |
| 243 | int state; | 229 | int state = 0; |
| 244 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, (char *)&state, | 230 | int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state, |
| 245 | sizeof(state)); | 231 | sizeof(state)); |
| 246 | if (ret) | 232 | if (ret) |
| 247 | return ret; | 233 | return ret; |
| @@ -256,7 +242,7 @@ static int hp_wmi_set_block(void *data, bool blocked) | |||
| 256 | int ret; | 242 | int ret; |
| 257 | 243 | ||
| 258 | ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, | 244 | ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1, |
| 259 | (char *)&query, sizeof(query)); | 245 | &query, sizeof(query)); |
| 260 | if (ret) | 246 | if (ret) |
| 261 | return -EINVAL; | 247 | return -EINVAL; |
| 262 | return 0; | 248 | return 0; |
| @@ -268,10 +254,10 @@ static const struct rfkill_ops hp_wmi_rfkill_ops = { | |||
| 268 | 254 | ||
| 269 | static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) | 255 | static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) |
| 270 | { | 256 | { |
| 271 | int wireless; | 257 | int wireless = 0; |
| 272 | int mask; | 258 | int mask; |
| 273 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, | 259 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, |
| 274 | (char *)&wireless, sizeof(wireless)); | 260 | &wireless, sizeof(wireless)); |
| 275 | /* TBD: Pass error */ | 261 | /* TBD: Pass error */ |
| 276 | 262 | ||
| 277 | mask = 0x200 << (r * 8); | 263 | mask = 0x200 << (r * 8); |
| @@ -284,10 +270,10 @@ static bool hp_wmi_get_sw_state(enum hp_wmi_radio r) | |||
| 284 | 270 | ||
| 285 | static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) | 271 | static bool hp_wmi_get_hw_state(enum hp_wmi_radio r) |
| 286 | { | 272 | { |
| 287 | int wireless; | 273 | int wireless = 0; |
| 288 | int mask; | 274 | int mask; |
| 289 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, | 275 | hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, |
| 290 | (char *)&wireless, sizeof(wireless)); | 276 | &wireless, sizeof(wireless)); |
| 291 | /* TBD: Pass error */ | 277 | /* TBD: Pass error */ |
| 292 | 278 | ||
| 293 | mask = 0x800 << (r * 8); | 279 | mask = 0x800 << (r * 8); |
| @@ -347,7 +333,7 @@ static ssize_t set_als(struct device *dev, struct device_attribute *attr, | |||
| 347 | const char *buf, size_t count) | 333 | const char *buf, size_t count) |
| 348 | { | 334 | { |
| 349 | u32 tmp = simple_strtoul(buf, NULL, 10); | 335 | u32 tmp = simple_strtoul(buf, NULL, 10); |
| 350 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, (char *)&tmp, | 336 | int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, &tmp, |
| 351 | sizeof(tmp)); | 337 | sizeof(tmp)); |
| 352 | if (ret) | 338 | if (ret) |
| 353 | return -EINVAL; | 339 | return -EINVAL; |
| @@ -421,7 +407,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
| 421 | static struct key_entry *key; | 407 | static struct key_entry *key; |
| 422 | union acpi_object *obj; | 408 | union acpi_object *obj; |
| 423 | u32 event_id, event_data; | 409 | u32 event_id, event_data; |
| 424 | int key_code, ret; | 410 | int key_code = 0, ret; |
| 425 | u32 *location; | 411 | u32 *location; |
| 426 | acpi_status status; | 412 | acpi_status status; |
| 427 | 413 | ||
| @@ -475,7 +461,7 @@ static void hp_wmi_notify(u32 value, void *context) | |||
| 475 | break; | 461 | break; |
| 476 | case HPWMI_BEZEL_BUTTON: | 462 | case HPWMI_BEZEL_BUTTON: |
| 477 | ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, | 463 | ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0, |
| 478 | (char *)&key_code, | 464 | &key_code, |
| 479 | sizeof(key_code)); | 465 | sizeof(key_code)); |
| 480 | if (ret) | 466 | if (ret) |
| 481 | break; | 467 | break; |
| @@ -578,9 +564,9 @@ static void cleanup_sysfs(struct platform_device *device) | |||
| 578 | static int __devinit hp_wmi_bios_setup(struct platform_device *device) | 564 | static int __devinit hp_wmi_bios_setup(struct platform_device *device) |
| 579 | { | 565 | { |
| 580 | int err; | 566 | int err; |
| 581 | int wireless; | 567 | int wireless = 0; |
| 582 | 568 | ||
| 583 | err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, (char *)&wireless, | 569 | err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, &wireless, |
| 584 | sizeof(wireless)); | 570 | sizeof(wireless)); |
| 585 | if (err) | 571 | if (err) |
| 586 | return err; | 572 | return err; |
