aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/hotkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi/hotkey.c')
-rw-r--r--drivers/acpi/hotkey.c417
1 files changed, 166 insertions, 251 deletions
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
index c25b2b92edcf..1ba2db671865 100644
--- a/drivers/acpi/hotkey.c
+++ b/drivers/acpi/hotkey.c
@@ -91,6 +91,14 @@ enum {
91 HK_EVENT_ENTERRING_S5, 91 HK_EVENT_ENTERRING_S5,
92}; 92};
93 93
94enum conf_entry_enum {
95 bus_handle = 0,
96 bus_method = 1,
97 action_handle = 2,
98 method = 3,
99 LAST_CONF_ENTRY
100};
101
94/* procdir we use */ 102/* procdir we use */
95static struct proc_dir_entry *hotkey_proc_dir; 103static struct proc_dir_entry *hotkey_proc_dir;
96static struct proc_dir_entry *hotkey_config; 104static struct proc_dir_entry *hotkey_config;
@@ -184,7 +192,7 @@ static union acpi_hotkey *get_hotkey_by_event(struct
184 *hotkey_list, int event); 192 *hotkey_list, int event);
185 193
186/* event based config */ 194/* event based config */
187static struct file_operations hotkey_config_fops = { 195static const struct file_operations hotkey_config_fops = {
188 .open = hotkey_open_config, 196 .open = hotkey_open_config,
189 .read = seq_read, 197 .read = seq_read,
190 .write = hotkey_write_config, 198 .write = hotkey_write_config,
@@ -193,7 +201,7 @@ static struct file_operations hotkey_config_fops = {
193}; 201};
194 202
195/* polling based config */ 203/* polling based config */
196static struct file_operations hotkey_poll_config_fops = { 204static const struct file_operations hotkey_poll_config_fops = {
197 .open = hotkey_poll_open_config, 205 .open = hotkey_poll_open_config,
198 .read = seq_read, 206 .read = seq_read,
199 .write = hotkey_write_config, 207 .write = hotkey_write_config,
@@ -202,7 +210,7 @@ static struct file_operations hotkey_poll_config_fops = {
202}; 210};
203 211
204/* hotkey driver info */ 212/* hotkey driver info */
205static struct file_operations hotkey_info_fops = { 213static const struct file_operations hotkey_info_fops = {
206 .open = hotkey_info_open_fs, 214 .open = hotkey_info_open_fs,
207 .read = seq_read, 215 .read = seq_read,
208 .llseek = seq_lseek, 216 .llseek = seq_lseek,
@@ -210,7 +218,7 @@ static struct file_operations hotkey_info_fops = {
210}; 218};
211 219
212/* action */ 220/* action */
213static struct file_operations hotkey_action_fops = { 221static const struct file_operations hotkey_action_fops = {
214 .open = hotkey_action_open_fs, 222 .open = hotkey_action_open_fs,
215 .read = seq_read, 223 .read = seq_read,
216 .write = hotkey_execute_aml_method, 224 .write = hotkey_execute_aml_method,
@@ -219,7 +227,7 @@ static struct file_operations hotkey_action_fops = {
219}; 227};
220 228
221/* polling results */ 229/* polling results */
222static struct file_operations hotkey_polling_fops = { 230static const struct file_operations hotkey_polling_fops = {
223 .open = hotkey_polling_open_fs, 231 .open = hotkey_polling_open_fs,
224 .read = seq_read, 232 .read = seq_read,
225 .llseek = seq_lseek, 233 .llseek = seq_lseek,
@@ -231,11 +239,10 @@ struct list_head hotkey_entries; /* head of the list of hotkey_list */
231 239
232static int hotkey_info_seq_show(struct seq_file *seq, void *offset) 240static int hotkey_info_seq_show(struct seq_file *seq, void *offset)
233{ 241{
234 ACPI_FUNCTION_TRACE("hotkey_info_seq_show");
235 242
236 seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION); 243 seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION);
237 244
238 return_VALUE(0); 245 return 0;
239} 246}
240 247
241static int hotkey_info_open_fs(struct inode *inode, struct file *file) 248static int hotkey_info_open_fs(struct inode *inode, struct file *file)
@@ -245,19 +252,15 @@ static int hotkey_info_open_fs(struct inode *inode, struct file *file)
245 252
246static char *format_result(union acpi_object *object) 253static char *format_result(union acpi_object *object)
247{ 254{
248 char *buf = NULL; 255 char *buf;
249
250 buf = (char *)kmalloc(RESULT_STR_LEN, GFP_KERNEL);
251 if (buf)
252 memset(buf, 0, RESULT_STR_LEN);
253 else
254 goto do_fail;
255 256
257 buf = kzalloc(RESULT_STR_LEN, GFP_KERNEL);
258 if (!buf)
259 return NULL;
256 /* Now, just support integer type */ 260 /* Now, just support integer type */
257 if (object->type == ACPI_TYPE_INTEGER) 261 if (object->type == ACPI_TYPE_INTEGER)
258 sprintf(buf, "%d\n", (u32) object->integer.value); 262 sprintf(buf, "%d\n", (u32) object->integer.value);
259 do_fail: 263 return buf;
260 return (buf);
261} 264}
262 265
263static int hotkey_polling_seq_show(struct seq_file *seq, void *offset) 266static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
@@ -266,7 +269,6 @@ static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
266 (struct acpi_polling_hotkey *)seq->private; 269 (struct acpi_polling_hotkey *)seq->private;
267 char *buf; 270 char *buf;
268 271
269 ACPI_FUNCTION_TRACE("hotkey_polling_seq_show");
270 272
271 if (poll_hotkey->poll_result) { 273 if (poll_hotkey->poll_result) {
272 buf = format_result(poll_hotkey->poll_result); 274 buf = format_result(poll_hotkey->poll_result);
@@ -274,7 +276,7 @@ static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
274 seq_printf(seq, "%s", buf); 276 seq_printf(seq, "%s", buf);
275 kfree(buf); 277 kfree(buf);
276 } 278 }
277 return_VALUE(0); 279 return 0;
278} 280}
279 281
280static int hotkey_polling_open_fs(struct inode *inode, struct file *file) 282static int hotkey_polling_open_fs(struct inode *inode, struct file *file)
@@ -293,7 +295,6 @@ static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
293 struct list_head *entries; 295 struct list_head *entries;
294 int val = -1; 296 int val = -1;
295 297
296 ACPI_FUNCTION_TRACE("hotkey_get_internal_event");
297 298
298 list_for_each(entries, list->entries) { 299 list_for_each(entries, list->entries) {
299 union acpi_hotkey *key = 300 union acpi_hotkey *key =
@@ -305,7 +306,7 @@ static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
305 } 306 }
306 } 307 }
307 308
308 return_VALUE(val); 309 return val;
309} 310}
310 311
311static void 312static void
@@ -314,15 +315,14 @@ acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data)
314 struct acpi_device *device = NULL; 315 struct acpi_device *device = NULL;
315 u32 internal_event; 316 u32 internal_event;
316 317
317 ACPI_FUNCTION_TRACE("acpi_hotkey_notify_handler");
318 318
319 if (acpi_bus_get_device(handle, &device)) 319 if (acpi_bus_get_device(handle, &device))
320 return_VOID; 320 return;
321 321
322 internal_event = hotkey_get_internal_event(event, &global_hotkey_list); 322 internal_event = hotkey_get_internal_event(event, &global_hotkey_list);
323 acpi_bus_generate_event(device, internal_event, 0); 323 acpi_bus_generate_event(device, internal_event, 0);
324 324
325 return_VOID; 325 return;
326} 326}
327 327
328/* Need to invent automatically hotkey add method */ 328/* Need to invent automatically hotkey add method */
@@ -346,7 +346,6 @@ static int create_polling_proc(union acpi_hotkey *device)
346 char proc_name[80]; 346 char proc_name[80];
347 mode_t mode; 347 mode_t mode;
348 348
349 ACPI_FUNCTION_TRACE("create_polling_proc");
350 mode = S_IFREG | S_IRUGO | S_IWUGO; 349 mode = S_IFREG | S_IRUGO | S_IWUGO;
351 350
352 sprintf(proc_name, "%d", device->link.hotkey_standard_num); 351 sprintf(proc_name, "%d", device->link.hotkey_standard_num);
@@ -356,10 +355,7 @@ static int create_polling_proc(union acpi_hotkey *device)
356 proc = create_proc_entry(proc_name, mode, hotkey_proc_dir); 355 proc = create_proc_entry(proc_name, mode, hotkey_proc_dir);
357 356
358 if (!proc) { 357 if (!proc) {
359 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, 358 return -ENODEV;
360 "Hotkey: Unable to create %s entry\n",
361 device->poll_hotkey.poll_method));
362 return_VALUE(-ENODEV);
363 } else { 359 } else {
364 proc->proc_fops = &hotkey_polling_fops; 360 proc->proc_fops = &hotkey_polling_fops;
365 proc->owner = THIS_MODULE; 361 proc->owner = THIS_MODULE;
@@ -368,7 +364,7 @@ static int create_polling_proc(union acpi_hotkey *device)
368 proc->gid = 0; 364 proc->gid = 0;
369 device->poll_hotkey.proc = proc; 365 device->poll_hotkey.proc = proc;
370 } 366 }
371 return_VALUE(0); 367 return 0;
372} 368}
373 369
374static int hotkey_add(union acpi_hotkey *device) 370static int hotkey_add(union acpi_hotkey *device)
@@ -376,7 +372,6 @@ static int hotkey_add(union acpi_hotkey *device)
376 int status = 0; 372 int status = 0;
377 struct acpi_device *dev = NULL; 373 struct acpi_device *dev = NULL;
378 374
379 ACPI_FUNCTION_TRACE("hotkey_add");
380 375
381 if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) { 376 if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) {
382 acpi_bus_get_device(device->event_hotkey.bus_handle, &dev); 377 acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
@@ -391,14 +386,13 @@ static int hotkey_add(union acpi_hotkey *device)
391 386
392 list_add_tail(&device->link.entries, global_hotkey_list.entries); 387 list_add_tail(&device->link.entries, global_hotkey_list.entries);
393 388
394 return_VALUE(status); 389 return status;
395} 390}
396 391
397static int hotkey_remove(union acpi_hotkey *device) 392static int hotkey_remove(union acpi_hotkey *device)
398{ 393{
399 struct list_head *entries, *next; 394 struct list_head *entries, *next;
400 395
401 ACPI_FUNCTION_TRACE("hotkey_remove");
402 396
403 list_for_each_safe(entries, next, global_hotkey_list.entries) { 397 list_for_each_safe(entries, next, global_hotkey_list.entries) {
404 union acpi_hotkey *key = 398 union acpi_hotkey *key =
@@ -412,14 +406,13 @@ static int hotkey_remove(union acpi_hotkey *device)
412 } 406 }
413 } 407 }
414 kfree(device); 408 kfree(device);
415 return_VALUE(0); 409 return 0;
416} 410}
417 411
418static int hotkey_update(union acpi_hotkey *key) 412static int hotkey_update(union acpi_hotkey *key)
419{ 413{
420 struct list_head *entries; 414 struct list_head *entries;
421 415
422 ACPI_FUNCTION_TRACE("hotkey_update");
423 416
424 list_for_each(entries, global_hotkey_list.entries) { 417 list_for_each(entries, global_hotkey_list.entries) {
425 union acpi_hotkey *tmp = 418 union acpi_hotkey *tmp =
@@ -461,19 +454,18 @@ static int hotkey_update(union acpi_hotkey *key)
461 */ 454 */
462 kfree(key); 455 kfree(key);
463 } 456 }
464 return_VALUE(0); 457 return 0;
465 break; 458 break;
466 } 459 }
467 } 460 }
468 461
469 return_VALUE(-ENODEV); 462 return -ENODEV;
470} 463}
471 464
472static void free_hotkey_device(union acpi_hotkey *key) 465static void free_hotkey_device(union acpi_hotkey *key)
473{ 466{
474 struct acpi_device *dev; 467 struct acpi_device *dev;
475 468
476 ACPI_FUNCTION_TRACE("free_hotkey_device");
477 469
478 if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) { 470 if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
479 acpi_bus_get_device(key->event_hotkey.bus_handle, &dev); 471 acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
@@ -493,119 +485,119 @@ static void free_hotkey_device(union acpi_hotkey *key)
493 free_poll_hotkey_buffer(key); 485 free_poll_hotkey_buffer(key);
494 } 486 }
495 kfree(key); 487 kfree(key);
496 return_VOID; 488 return;
497} 489}
498 490
499static void free_hotkey_buffer(union acpi_hotkey *key) 491static void free_hotkey_buffer(union acpi_hotkey *key)
500{ 492{
493 /* key would never be null, action method could be */
501 kfree(key->event_hotkey.action_method); 494 kfree(key->event_hotkey.action_method);
502} 495}
503 496
504static void free_poll_hotkey_buffer(union acpi_hotkey *key) 497static void free_poll_hotkey_buffer(union acpi_hotkey *key)
505{ 498{
499 /* key would never be null, others could be*/
506 kfree(key->poll_hotkey.action_method); 500 kfree(key->poll_hotkey.action_method);
507 kfree(key->poll_hotkey.poll_method); 501 kfree(key->poll_hotkey.poll_method);
508 kfree(key->poll_hotkey.poll_result); 502 kfree(key->poll_hotkey.poll_result);
509} 503}
510static int 504static int
511init_hotkey_device(union acpi_hotkey *key, char *bus_str, char *action_str, 505init_hotkey_device(union acpi_hotkey *key, char **config_entry,
512 char *method, int std_num, int external_num) 506 int std_num, int external_num)
513{ 507{
514 acpi_handle tmp_handle; 508 acpi_handle tmp_handle;
515 acpi_status status = AE_OK; 509 acpi_status status = AE_OK;
516 510
517 ACPI_FUNCTION_TRACE("init_hotkey_device");
518
519 if (std_num < 0 || IS_POLL(std_num) || !key) 511 if (std_num < 0 || IS_POLL(std_num) || !key)
520 goto do_fail; 512 goto do_fail;
521 513
522 if (!bus_str || !action_str || !method) 514 if (!config_entry[bus_handle] || !config_entry[action_handle]
515 || !config_entry[method])
523 goto do_fail; 516 goto do_fail;
524 517
525 key->link.hotkey_type = ACPI_HOTKEY_EVENT; 518 key->link.hotkey_type = ACPI_HOTKEY_EVENT;
526 key->link.hotkey_standard_num = std_num; 519 key->link.hotkey_standard_num = std_num;
527 key->event_hotkey.flag = 0; 520 key->event_hotkey.flag = 0;
528 key->event_hotkey.action_method = method; 521 key->event_hotkey.action_method = config_entry[method];
529 522
530 status = 523 status = acpi_get_handle(NULL, config_entry[bus_handle],
531 acpi_get_handle(NULL, bus_str, &(key->event_hotkey.bus_handle)); 524 &(key->event_hotkey.bus_handle));
532 if (ACPI_FAILURE(status)) 525 if (ACPI_FAILURE(status))
533 goto do_fail; 526 goto do_fail_zero;
534 key->event_hotkey.external_hotkey_num = external_num; 527 key->event_hotkey.external_hotkey_num = external_num;
535 status = 528 status = acpi_get_handle(NULL, config_entry[action_handle],
536 acpi_get_handle(NULL, action_str,
537 &(key->event_hotkey.action_handle)); 529 &(key->event_hotkey.action_handle));
538 if (ACPI_FAILURE(status)) 530 if (ACPI_FAILURE(status))
539 goto do_fail; 531 goto do_fail_zero;
540 status = acpi_get_handle(key->event_hotkey.action_handle, 532 status = acpi_get_handle(key->event_hotkey.action_handle,
541 method, &tmp_handle); 533 config_entry[method], &tmp_handle);
542 if (ACPI_FAILURE(status)) 534 if (ACPI_FAILURE(status))
543 goto do_fail; 535 goto do_fail_zero;
544 return_VALUE(AE_OK); 536 return AE_OK;
545 do_fail: 537do_fail_zero:
546 return_VALUE(-ENODEV); 538 key->event_hotkey.action_method = NULL;
539do_fail:
540 return -ENODEV;
547} 541}
548 542
549static int 543static int
550init_poll_hotkey_device(union acpi_hotkey *key, 544init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry,
551 char *poll_str, 545 int std_num)
552 char *poll_method,
553 char *action_str, char *action_method, int std_num)
554{ 546{
555 acpi_status status = AE_OK; 547 acpi_status status = AE_OK;
556 acpi_handle tmp_handle; 548 acpi_handle tmp_handle;
557 549
558 ACPI_FUNCTION_TRACE("init_poll_hotkey_device");
559
560 if (std_num < 0 || IS_EVENT(std_num) || !key) 550 if (std_num < 0 || IS_EVENT(std_num) || !key)
561 goto do_fail; 551 goto do_fail;
562 552 if (!config_entry[bus_handle] ||!config_entry[bus_method] ||
563 if (!poll_str || !poll_method || !action_str || !action_method) 553 !config_entry[action_handle] || !config_entry[method])
564 goto do_fail; 554 goto do_fail;
565 555
566 key->link.hotkey_type = ACPI_HOTKEY_POLLING; 556 key->link.hotkey_type = ACPI_HOTKEY_POLLING;
567 key->link.hotkey_standard_num = std_num; 557 key->link.hotkey_standard_num = std_num;
568 key->poll_hotkey.flag = 0; 558 key->poll_hotkey.flag = 0;
569 key->poll_hotkey.poll_method = poll_method; 559 key->poll_hotkey.poll_method = config_entry[bus_method];
570 key->poll_hotkey.action_method = action_method; 560 key->poll_hotkey.action_method = config_entry[method];
571 561
572 status = 562 status = acpi_get_handle(NULL, config_entry[bus_handle],
573 acpi_get_handle(NULL, poll_str, &(key->poll_hotkey.poll_handle)); 563 &(key->poll_hotkey.poll_handle));
574 if (ACPI_FAILURE(status)) 564 if (ACPI_FAILURE(status))
575 goto do_fail; 565 goto do_fail_zero;
576 status = acpi_get_handle(key->poll_hotkey.poll_handle, 566 status = acpi_get_handle(key->poll_hotkey.poll_handle,
577 poll_method, &tmp_handle); 567 config_entry[bus_method], &tmp_handle);
578 if (ACPI_FAILURE(status)) 568 if (ACPI_FAILURE(status))
579 goto do_fail; 569 goto do_fail_zero;
580 status = 570 status =
581 acpi_get_handle(NULL, action_str, 571 acpi_get_handle(NULL, config_entry[action_handle],
582 &(key->poll_hotkey.action_handle)); 572 &(key->poll_hotkey.action_handle));
583 if (ACPI_FAILURE(status)) 573 if (ACPI_FAILURE(status))
584 goto do_fail; 574 goto do_fail_zero;
585 status = acpi_get_handle(key->poll_hotkey.action_handle, 575 status = acpi_get_handle(key->poll_hotkey.action_handle,
586 action_method, &tmp_handle); 576 config_entry[method], &tmp_handle);
587 if (ACPI_FAILURE(status)) 577 if (ACPI_FAILURE(status))
588 goto do_fail; 578 goto do_fail_zero;
589 key->poll_hotkey.poll_result = 579 key->poll_hotkey.poll_result =
590 (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL); 580 (union acpi_object *)kmalloc(sizeof(union acpi_object), GFP_KERNEL);
591 if (!key->poll_hotkey.poll_result) 581 if (!key->poll_hotkey.poll_result)
592 goto do_fail; 582 goto do_fail_zero;
593 return_VALUE(AE_OK); 583 return AE_OK;
594 do_fail: 584
595 return_VALUE(-ENODEV); 585do_fail_zero:
586 key->poll_hotkey.poll_method = NULL;
587 key->poll_hotkey.action_method = NULL;
588do_fail:
589 return -ENODEV;
596} 590}
597 591
598static int hotkey_open_config(struct inode *inode, struct file *file) 592static int hotkey_open_config(struct inode *inode, struct file *file)
599{ 593{
600 ACPI_FUNCTION_TRACE("hotkey_open_config"); 594 return (single_open
601 return_VALUE(single_open
602 (file, hotkey_config_seq_show, PDE(inode)->data)); 595 (file, hotkey_config_seq_show, PDE(inode)->data));
603} 596}
604 597
605static int hotkey_poll_open_config(struct inode *inode, struct file *file) 598static int hotkey_poll_open_config(struct inode *inode, struct file *file)
606{ 599{
607 ACPI_FUNCTION_TRACE("hotkey_poll_open_config"); 600 return (single_open
608 return_VALUE(single_open
609 (file, hotkey_poll_config_seq_show, PDE(inode)->data)); 601 (file, hotkey_poll_config_seq_show, PDE(inode)->data));
610} 602}
611 603
@@ -618,7 +610,6 @@ static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
618 struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name }; 610 struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
619 struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name }; 611 struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
620 612
621 ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));
622 613
623 list_for_each(entries, hotkey_list->entries) { 614 list_for_each(entries, hotkey_list->entries) {
624 union acpi_hotkey *key = 615 union acpi_hotkey *key =
@@ -636,7 +627,7 @@ static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
636 } 627 }
637 } 628 }
638 seq_puts(seq, "\n"); 629 seq_puts(seq, "\n");
639 return_VALUE(0); 630 return 0;
640} 631}
641 632
642static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset) 633static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
@@ -648,7 +639,6 @@ static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
648 struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name }; 639 struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
649 struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name }; 640 struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
650 641
651 ACPI_FUNCTION_TRACE(("hotkey_config_seq_show"));
652 642
653 list_for_each(entries, hotkey_list->entries) { 643 list_for_each(entries, hotkey_list->entries) {
654 union acpi_hotkey *key = 644 union acpi_hotkey *key =
@@ -666,22 +656,22 @@ static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
666 } 656 }
667 } 657 }
668 seq_puts(seq, "\n"); 658 seq_puts(seq, "\n");
669 return_VALUE(0); 659 return 0;
670} 660}
671 661
672static int 662static int
673get_parms(char *config_record, 663get_parms(char *config_record, int *cmd, char **config_entry,
674 int *cmd, 664 int *internal_event_num, int *external_event_num)
675 char **bus_handle,
676 char **bus_method,
677 char **action_handle,
678 char **method, int *internal_event_num, int *external_event_num)
679{ 665{
666/* the format of *config_record =
667 * "1:\d+:*" : "cmd:internal_event_num"
668 * "\d+:\w+:\w+:\w+:\w+:\d+:\d+" :
669 * "cmd:bus_handle:bus_method:action_handle:method:internal_event_num:external_event_num"
670 */
680 char *tmp, *tmp1, count; 671 char *tmp, *tmp1, count;
681 ACPI_FUNCTION_TRACE(("get_parms")); 672 int i;
682 673
683 sscanf(config_record, "%d", cmd); 674 sscanf(config_record, "%d", cmd);
684
685 if (*cmd == 1) { 675 if (*cmd == 1) {
686 if (sscanf(config_record, "%d:%d", cmd, internal_event_num) != 676 if (sscanf(config_record, "%d:%d", cmd, internal_event_num) !=
687 2) 677 2)
@@ -693,60 +683,28 @@ get_parms(char *config_record,
693 if (!tmp) 683 if (!tmp)
694 goto do_fail; 684 goto do_fail;
695 tmp++; 685 tmp++;
696 tmp1 = strchr(tmp, ':'); 686 for (i = 0; i < LAST_CONF_ENTRY; i++) {
697 if (!tmp1) 687 tmp1 = strchr(tmp, ':');
698 goto do_fail; 688 if (!tmp1) {
699 689 goto do_fail;
700 count = tmp1 - tmp; 690 }
701 *bus_handle = (char *)kmalloc(count + 1, GFP_KERNEL); 691 count = tmp1 - tmp;
702 if (!*bus_handle) 692 config_entry[i] = kzalloc(count + 1, GFP_KERNEL);
703 goto do_fail; 693 if (!config_entry[i])
704 strncpy(*bus_handle, tmp, count); 694 goto handle_failure;
705 *(*bus_handle + count) = 0; 695 strncpy(config_entry[i], tmp, count);
706 696 tmp = tmp1 + 1;
707 tmp = tmp1; 697 }
708 tmp++; 698 if (sscanf(tmp, "%d:%d", internal_event_num, external_event_num) <= 0)
709 tmp1 = strchr(tmp, ':'); 699 goto handle_failure;
710 if (!tmp1) 700 if (!IS_OTHERS(*internal_event_num)) {
711 goto do_fail; 701 return 6;
712 count = tmp1 - tmp; 702 }
713 *bus_method = (char *)kmalloc(count + 1, GFP_KERNEL); 703handle_failure:
714 if (!*bus_method) 704 while (i-- > 0)
715 goto do_fail; 705 kfree(config_entry[i]);
716 strncpy(*bus_method, tmp, count); 706do_fail:
717 *(*bus_method + count) = 0; 707 return -1;
718
719 tmp = tmp1;
720 tmp++;
721 tmp1 = strchr(tmp, ':');
722 if (!tmp1)
723 goto do_fail;
724 count = tmp1 - tmp;
725 *action_handle = (char *)kmalloc(count + 1, GFP_KERNEL);
726 if (!*action_handle)
727 goto do_fail;
728 strncpy(*action_handle, tmp, count);
729 *(*action_handle + count) = 0;
730
731 tmp = tmp1;
732 tmp++;
733 tmp1 = strchr(tmp, ':');
734 if (!tmp1)
735 goto do_fail;
736 count = tmp1 - tmp;
737 *method = (char *)kmalloc(count + 1, GFP_KERNEL);
738 if (!*method)
739 goto do_fail;
740 strncpy(*method, tmp, count);
741 *(*method + count) = 0;
742
743 if (sscanf(tmp1 + 1, "%d:%d", internal_event_num, external_event_num) <=
744 0)
745 goto do_fail;
746
747 return_VALUE(6);
748 do_fail:
749 return_VALUE(-1);
750} 708}
751 709
752/* count is length for one input record */ 710/* count is length for one input record */
@@ -755,91 +713,58 @@ static ssize_t hotkey_write_config(struct file *file,
755 size_t count, loff_t * data) 713 size_t count, loff_t * data)
756{ 714{
757 char *config_record = NULL; 715 char *config_record = NULL;
758 char *bus_handle = NULL; 716 char *config_entry[LAST_CONF_ENTRY];
759 char *bus_method = NULL;
760 char *action_handle = NULL;
761 char *method = NULL;
762 int cmd, internal_event_num, external_event_num; 717 int cmd, internal_event_num, external_event_num;
763 int ret = 0; 718 int ret = 0;
764 union acpi_hotkey *key = NULL; 719 union acpi_hotkey *key = kzalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
765 720
766 ACPI_FUNCTION_TRACE(("hotkey_write_config")); 721 if (!key)
722 return -ENOMEM;
767 723
768 config_record = (char *)kmalloc(count + 1, GFP_KERNEL); 724 config_record = kzalloc(count + 1, GFP_KERNEL);
769 if (!config_record) 725 if (!config_record) {
770 return_VALUE(-ENOMEM); 726 kfree(key);
727 return -ENOMEM;
728 }
771 729
772 if (copy_from_user(config_record, buffer, count)) { 730 if (copy_from_user(config_record, buffer, count)) {
773 kfree(config_record); 731 kfree(config_record);
774 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data \n")); 732 kfree(key);
775 return_VALUE(-EINVAL); 733 printk(KERN_ERR PREFIX "Invalid data\n");
734 return -EINVAL;
776 } 735 }
777 config_record[count] = 0; 736 ret = get_parms(config_record, &cmd, config_entry,
778 737 &internal_event_num, &external_event_num);
779 ret = get_parms(config_record,
780 &cmd,
781 &bus_handle,
782 &bus_method,
783 &action_handle,
784 &method, &internal_event_num, &external_event_num);
785
786 kfree(config_record); 738 kfree(config_record);
787 if (IS_OTHERS(internal_event_num))
788 goto do_fail;
789 if (ret != 6) { 739 if (ret != 6) {
790 do_fail: 740 printk(KERN_ERR PREFIX "Invalid data format ret=%d\n", ret);
791 kfree(bus_handle); 741 return -EINVAL;
792 kfree(bus_method);
793 kfree(action_handle);
794 kfree(method);
795 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
796 "Invalid data format ret=%d\n", ret));
797 return_VALUE(-EINVAL);
798 } 742 }
799 743
800 key = kmalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
801 if (!key)
802 goto do_fail;
803 memset(key, 0, sizeof(union acpi_hotkey));
804 if (cmd == 1) { 744 if (cmd == 1) {
805 union acpi_hotkey *tmp = NULL; 745 union acpi_hotkey *tmp = NULL;
806 tmp = get_hotkey_by_event(&global_hotkey_list, 746 tmp = get_hotkey_by_event(&global_hotkey_list,
807 internal_event_num); 747 internal_event_num);
808 if (!tmp) 748 if (!tmp)
809 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid key")); 749 printk(KERN_ERR PREFIX "Invalid key\n");
810 else 750 else
811 memcpy(key, tmp, sizeof(union acpi_hotkey)); 751 memcpy(key, tmp, sizeof(union acpi_hotkey));
812 goto cont_cmd; 752 goto cont_cmd;
813 } 753 }
814 if (IS_EVENT(internal_event_num)) { 754 if (IS_EVENT(internal_event_num)) {
815 kfree(bus_method); 755 if (init_hotkey_device(key, config_entry,
816 ret = init_hotkey_device(key, bus_handle, action_handle, method, 756 internal_event_num, external_event_num))
817 internal_event_num, 757 goto init_hotkey_fail;
818 external_event_num); 758 } else {
819 } else 759 if (init_poll_hotkey_device(key, config_entry,
820 ret = init_poll_hotkey_device(key, bus_handle, bus_method, 760 internal_event_num))
821 action_handle, method, 761 goto init_poll_hotkey_fail;
822 internal_event_num);
823 if (ret) {
824 kfree(bus_handle);
825 kfree(action_handle);
826 if (IS_EVENT(internal_event_num))
827 free_hotkey_buffer(key);
828 else
829 free_poll_hotkey_buffer(key);
830 kfree(key);
831 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid hotkey \n"));
832 return_VALUE(-EINVAL);
833 } 762 }
834 763cont_cmd:
835 cont_cmd:
836 kfree(bus_handle);
837 kfree(action_handle);
838
839 switch (cmd) { 764 switch (cmd) {
840 case 0: 765 case 0:
841 if (get_hotkey_by_event 766 if (get_hotkey_by_event(&global_hotkey_list,
842 (&global_hotkey_list, key->link.hotkey_standard_num)) 767 key->link.hotkey_standard_num))
843 goto fail_out; 768 goto fail_out;
844 else 769 else
845 hotkey_add(key); 770 hotkey_add(key);
@@ -848,6 +773,7 @@ static ssize_t hotkey_write_config(struct file *file,
848 hotkey_remove(key); 773 hotkey_remove(key);
849 break; 774 break;
850 case 2: 775 case 2:
776 /* key is kfree()ed if matched*/
851 if (hotkey_update(key)) 777 if (hotkey_update(key))
852 goto fail_out; 778 goto fail_out;
853 break; 779 break;
@@ -855,15 +781,26 @@ static ssize_t hotkey_write_config(struct file *file,
855 goto fail_out; 781 goto fail_out;
856 break; 782 break;
857 } 783 }
858 return_VALUE(count); 784 return count;
859 fail_out: 785
860 if (IS_EVENT(internal_event_num)) 786init_poll_hotkey_fail: /* failed init_poll_hotkey_device */
861 free_hotkey_buffer(key); 787 kfree(config_entry[bus_method]);
862 else 788 config_entry[bus_method] = NULL;
863 free_poll_hotkey_buffer(key); 789init_hotkey_fail: /* failed init_hotkey_device */
790 kfree(config_entry[method]);
791fail_out:
792 kfree(config_entry[bus_handle]);
793 kfree(config_entry[action_handle]);
794 /* No double free since elements =NULL for error cases */
795 if (IS_EVENT(internal_event_num)) {
796 if (config_entry[bus_method])
797 kfree(config_entry[bus_method]);
798 free_hotkey_buffer(key); /* frees [method] */
799 } else
800 free_poll_hotkey_buffer(key); /* frees [bus_method]+[method] */
864 kfree(key); 801 kfree(key);
865 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "invalid key\n")); 802 printk(KERN_ERR PREFIX "invalid key\n");
866 return_VALUE(-EINVAL); 803 return -EINVAL;
867} 804}
868 805
869/* 806/*
@@ -880,7 +817,6 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
880 union acpi_object in_obj; /* the only param we use */ 817 union acpi_object in_obj; /* the only param we use */
881 acpi_status status; 818 acpi_status status;
882 819
883 ACPI_FUNCTION_TRACE("write_acpi_int");
884 params.count = 1; 820 params.count = 1;
885 params.pointer = &in_obj; 821 params.pointer = &in_obj;
886 in_obj.type = ACPI_TYPE_INTEGER; 822 in_obj.type = ACPI_TYPE_INTEGER;
@@ -888,7 +824,7 @@ static int write_acpi_int(acpi_handle handle, const char *method, int val,
888 824
889 status = acpi_evaluate_object(handle, (char *)method, &params, output); 825 status = acpi_evaluate_object(handle, (char *)method, &params, output);
890 826
891 return_VALUE(status == AE_OK); 827 return (status == AE_OK);
892} 828}
893 829
894static int read_acpi_int(acpi_handle handle, const char *method, 830static int read_acpi_int(acpi_handle handle, const char *method,
@@ -898,7 +834,6 @@ static int read_acpi_int(acpi_handle handle, const char *method,
898 union acpi_object out_obj; 834 union acpi_object out_obj;
899 acpi_status status; 835 acpi_status status;
900 836
901 ACPI_FUNCTION_TRACE("read_acpi_int");
902 output.length = sizeof(out_obj); 837 output.length = sizeof(out_obj);
903 output.pointer = &out_obj; 838 output.pointer = &out_obj;
904 839
@@ -907,8 +842,8 @@ static int read_acpi_int(acpi_handle handle, const char *method,
907 val->integer.value = out_obj.integer.value; 842 val->integer.value = out_obj.integer.value;
908 val->type = out_obj.type; 843 val->type = out_obj.type;
909 } else 844 } else
910 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "null val pointer")); 845 printk(KERN_ERR PREFIX "null val pointer\n");
911 return_VALUE((status == AE_OK) 846 return ((status == AE_OK)
912 && (out_obj.type == ACPI_TYPE_INTEGER)); 847 && (out_obj.type == ACPI_TYPE_INTEGER));
913} 848}
914 849
@@ -945,24 +880,22 @@ static ssize_t hotkey_execute_aml_method(struct file *file,
945 int event, method_type, type, value; 880 int event, method_type, type, value;
946 union acpi_hotkey *key; 881 union acpi_hotkey *key;
947 882
948 ACPI_FUNCTION_TRACE("hotkey_execte_aml_method");
949 883
950 arg = (char *)kmalloc(count + 1, GFP_KERNEL); 884 arg = kzalloc(count + 1, GFP_KERNEL);
951 if (!arg) 885 if (!arg)
952 return_VALUE(-ENOMEM); 886 return -ENOMEM;
953 arg[count] = 0;
954 887
955 if (copy_from_user(arg, buffer, count)) { 888 if (copy_from_user(arg, buffer, count)) {
956 kfree(arg); 889 kfree(arg);
957 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 2")); 890 printk(KERN_ERR PREFIX "Invalid argument 2\n");
958 return_VALUE(-EINVAL); 891 return -EINVAL;
959 } 892 }
960 893
961 if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) != 894 if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) !=
962 4) { 895 4) {
963 kfree(arg); 896 kfree(arg);
964 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument 3")); 897 printk(KERN_ERR PREFIX "Invalid argument 3\n");
965 return_VALUE(-EINVAL); 898 return -EINVAL;
966 } 899 }
967 kfree(arg); 900 kfree(arg);
968 if (type == ACPI_TYPE_INTEGER) { 901 if (type == ACPI_TYPE_INTEGER) {
@@ -987,12 +920,12 @@ static ssize_t hotkey_execute_aml_method(struct file *file,
987 920
988 } 921 }
989 } else { 922 } else {
990 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Not supported")); 923 printk(KERN_WARNING "Not supported\n");
991 return_VALUE(-EINVAL); 924 return -EINVAL;
992 } 925 }
993 return_VALUE(count); 926 return count;
994 do_fail: 927 do_fail:
995 return_VALUE(-EINVAL); 928 return -EINVAL;
996 929
997} 930}
998 931
@@ -1001,7 +934,6 @@ static int __init hotkey_init(void)
1001 int result; 934 int result;
1002 mode_t mode = S_IFREG | S_IRUGO | S_IWUGO; 935 mode_t mode = S_IFREG | S_IRUGO | S_IWUGO;
1003 936
1004 ACPI_FUNCTION_TRACE("hotkey_init");
1005 937
1006 if (acpi_disabled) 938 if (acpi_disabled)
1007 return -ENODEV; 939 return -ENODEV;
@@ -1013,9 +945,6 @@ static int __init hotkey_init(void)
1013 945
1014 hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir); 946 hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir);
1015 if (!hotkey_proc_dir) { 947 if (!hotkey_proc_dir) {
1016 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1017 "Hotkey: Unable to create %s entry\n",
1018 HOTKEY_PROC));
1019 return (-ENODEV); 948 return (-ENODEV);
1020 } 949 }
1021 hotkey_proc_dir->owner = THIS_MODULE; 950 hotkey_proc_dir->owner = THIS_MODULE;
@@ -1023,9 +952,6 @@ static int __init hotkey_init(void)
1023 hotkey_config = 952 hotkey_config =
1024 create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir); 953 create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir);
1025 if (!hotkey_config) { 954 if (!hotkey_config) {
1026 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1027 "Hotkey: Unable to create %s entry\n",
1028 HOTKEY_EV_CONFIG));
1029 goto do_fail1; 955 goto do_fail1;
1030 } else { 956 } else {
1031 hotkey_config->proc_fops = &hotkey_config_fops; 957 hotkey_config->proc_fops = &hotkey_config_fops;
@@ -1038,10 +964,6 @@ static int __init hotkey_init(void)
1038 hotkey_poll_config = 964 hotkey_poll_config =
1039 create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir); 965 create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir);
1040 if (!hotkey_poll_config) { 966 if (!hotkey_poll_config) {
1041 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1042 "Hotkey: Unable to create %s entry\n",
1043 HOTKEY_EV_CONFIG));
1044
1045 goto do_fail2; 967 goto do_fail2;
1046 } else { 968 } else {
1047 hotkey_poll_config->proc_fops = &hotkey_poll_config_fops; 969 hotkey_poll_config->proc_fops = &hotkey_poll_config_fops;
@@ -1053,9 +975,6 @@ static int __init hotkey_init(void)
1053 975
1054 hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir); 976 hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir);
1055 if (!hotkey_action) { 977 if (!hotkey_action) {
1056 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1057 "Hotkey: Unable to create %s entry\n",
1058 HOTKEY_ACTION));
1059 goto do_fail3; 978 goto do_fail3;
1060 } else { 979 } else {
1061 hotkey_action->proc_fops = &hotkey_action_fops; 980 hotkey_action->proc_fops = &hotkey_action_fops;
@@ -1066,9 +985,6 @@ static int __init hotkey_init(void)
1066 985
1067 hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir); 986 hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir);
1068 if (!hotkey_info) { 987 if (!hotkey_info) {
1069 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1070 "Hotkey: Unable to create %s entry\n",
1071 HOTKEY_INFO));
1072 goto do_fail4; 988 goto do_fail4;
1073 } else { 989 } else {
1074 hotkey_info->proc_fops = &hotkey_info_fops; 990 hotkey_info->proc_fops = &hotkey_info_fops;
@@ -1104,7 +1020,6 @@ static void __exit hotkey_exit(void)
1104{ 1020{
1105 struct list_head *entries, *next; 1021 struct list_head *entries, *next;
1106 1022
1107 ACPI_FUNCTION_TRACE("hotkey_exit");
1108 1023
1109 list_for_each_safe(entries, next, global_hotkey_list.entries) { 1024 list_for_each_safe(entries, next, global_hotkey_list.entries) {
1110 union acpi_hotkey *key = 1025 union acpi_hotkey *key =