diff options
| -rw-r--r-- | drivers/input/input.c | 2 | ||||
| -rw-r--r-- | drivers/input/tablet/aiptek.c | 28 | ||||
| -rw-r--r-- | drivers/tty/sysrq.c | 169 |
3 files changed, 139 insertions, 60 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index 90b7ecfb6257..db409d6bd5d2 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -752,7 +752,7 @@ static int input_default_setkeycode(struct input_dev *dev, | |||
| 752 | if (index >= dev->keycodemax) | 752 | if (index >= dev->keycodemax) |
| 753 | return -EINVAL; | 753 | return -EINVAL; |
| 754 | 754 | ||
| 755 | if (dev->keycodesize < sizeof(dev->keycode) && | 755 | if (dev->keycodesize < sizeof(ke->keycode) && |
| 756 | (ke->keycode >> (dev->keycodesize * 8))) | 756 | (ke->keycode >> (dev->keycodesize * 8))) |
| 757 | return -EINVAL; | 757 | return -EINVAL; |
| 758 | 758 | ||
diff --git a/drivers/input/tablet/aiptek.c b/drivers/input/tablet/aiptek.c index 57b25b84d1fc..0a619c558bfb 100644 --- a/drivers/input/tablet/aiptek.c +++ b/drivers/input/tablet/aiptek.c | |||
| @@ -1097,7 +1097,7 @@ store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const | |||
| 1097 | } | 1097 | } |
| 1098 | 1098 | ||
| 1099 | static DEVICE_ATTR(pointer_mode, | 1099 | static DEVICE_ATTR(pointer_mode, |
| 1100 | S_IRUGO | S_IWUGO, | 1100 | S_IRUGO | S_IWUSR, |
| 1101 | show_tabletPointerMode, store_tabletPointerMode); | 1101 | show_tabletPointerMode, store_tabletPointerMode); |
| 1102 | 1102 | ||
| 1103 | /*********************************************************************** | 1103 | /*********************************************************************** |
| @@ -1134,7 +1134,7 @@ store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, co | |||
| 1134 | } | 1134 | } |
| 1135 | 1135 | ||
| 1136 | static DEVICE_ATTR(coordinate_mode, | 1136 | static DEVICE_ATTR(coordinate_mode, |
| 1137 | S_IRUGO | S_IWUGO, | 1137 | S_IRUGO | S_IWUSR, |
| 1138 | show_tabletCoordinateMode, store_tabletCoordinateMode); | 1138 | show_tabletCoordinateMode, store_tabletCoordinateMode); |
| 1139 | 1139 | ||
| 1140 | /*********************************************************************** | 1140 | /*********************************************************************** |
| @@ -1176,7 +1176,7 @@ store_tabletToolMode(struct device *dev, struct device_attribute *attr, const ch | |||
| 1176 | } | 1176 | } |
| 1177 | 1177 | ||
| 1178 | static DEVICE_ATTR(tool_mode, | 1178 | static DEVICE_ATTR(tool_mode, |
| 1179 | S_IRUGO | S_IWUGO, | 1179 | S_IRUGO | S_IWUSR, |
| 1180 | show_tabletToolMode, store_tabletToolMode); | 1180 | show_tabletToolMode, store_tabletToolMode); |
| 1181 | 1181 | ||
| 1182 | /*********************************************************************** | 1182 | /*********************************************************************** |
| @@ -1219,7 +1219,7 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char | |||
| 1219 | } | 1219 | } |
| 1220 | 1220 | ||
| 1221 | static DEVICE_ATTR(xtilt, | 1221 | static DEVICE_ATTR(xtilt, |
| 1222 | S_IRUGO | S_IWUGO, show_tabletXtilt, store_tabletXtilt); | 1222 | S_IRUGO | S_IWUSR, show_tabletXtilt, store_tabletXtilt); |
| 1223 | 1223 | ||
| 1224 | /*********************************************************************** | 1224 | /*********************************************************************** |
| 1225 | * support routines for the 'ytilt' file. Note that this file | 1225 | * support routines for the 'ytilt' file. Note that this file |
| @@ -1261,7 +1261,7 @@ store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char | |||
| 1261 | } | 1261 | } |
| 1262 | 1262 | ||
| 1263 | static DEVICE_ATTR(ytilt, | 1263 | static DEVICE_ATTR(ytilt, |
| 1264 | S_IRUGO | S_IWUGO, show_tabletYtilt, store_tabletYtilt); | 1264 | S_IRUGO | S_IWUSR, show_tabletYtilt, store_tabletYtilt); |
| 1265 | 1265 | ||
| 1266 | /*********************************************************************** | 1266 | /*********************************************************************** |
| 1267 | * support routines for the 'jitter' file. Note that this file | 1267 | * support routines for the 'jitter' file. Note that this file |
| @@ -1288,7 +1288,7 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const | |||
| 1288 | } | 1288 | } |
| 1289 | 1289 | ||
| 1290 | static DEVICE_ATTR(jitter, | 1290 | static DEVICE_ATTR(jitter, |
| 1291 | S_IRUGO | S_IWUGO, | 1291 | S_IRUGO | S_IWUSR, |
| 1292 | show_tabletJitterDelay, store_tabletJitterDelay); | 1292 | show_tabletJitterDelay, store_tabletJitterDelay); |
| 1293 | 1293 | ||
| 1294 | /*********************************************************************** | 1294 | /*********************************************************************** |
| @@ -1317,7 +1317,7 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, | |||
| 1317 | } | 1317 | } |
| 1318 | 1318 | ||
| 1319 | static DEVICE_ATTR(delay, | 1319 | static DEVICE_ATTR(delay, |
| 1320 | S_IRUGO | S_IWUGO, | 1320 | S_IRUGO | S_IWUSR, |
| 1321 | show_tabletProgrammableDelay, store_tabletProgrammableDelay); | 1321 | show_tabletProgrammableDelay, store_tabletProgrammableDelay); |
| 1322 | 1322 | ||
| 1323 | /*********************************************************************** | 1323 | /*********************************************************************** |
| @@ -1406,7 +1406,7 @@ store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const | |||
| 1406 | } | 1406 | } |
| 1407 | 1407 | ||
| 1408 | static DEVICE_ATTR(stylus_upper, | 1408 | static DEVICE_ATTR(stylus_upper, |
| 1409 | S_IRUGO | S_IWUGO, | 1409 | S_IRUGO | S_IWUSR, |
| 1410 | show_tabletStylusUpper, store_tabletStylusUpper); | 1410 | show_tabletStylusUpper, store_tabletStylusUpper); |
| 1411 | 1411 | ||
| 1412 | /*********************************************************************** | 1412 | /*********************************************************************** |
| @@ -1437,7 +1437,7 @@ store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const | |||
| 1437 | } | 1437 | } |
| 1438 | 1438 | ||
| 1439 | static DEVICE_ATTR(stylus_lower, | 1439 | static DEVICE_ATTR(stylus_lower, |
| 1440 | S_IRUGO | S_IWUGO, | 1440 | S_IRUGO | S_IWUSR, |
| 1441 | show_tabletStylusLower, store_tabletStylusLower); | 1441 | show_tabletStylusLower, store_tabletStylusLower); |
| 1442 | 1442 | ||
| 1443 | /*********************************************************************** | 1443 | /*********************************************************************** |
| @@ -1475,7 +1475,7 @@ store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const c | |||
| 1475 | } | 1475 | } |
| 1476 | 1476 | ||
| 1477 | static DEVICE_ATTR(mouse_left, | 1477 | static DEVICE_ATTR(mouse_left, |
| 1478 | S_IRUGO | S_IWUGO, | 1478 | S_IRUGO | S_IWUSR, |
| 1479 | show_tabletMouseLeft, store_tabletMouseLeft); | 1479 | show_tabletMouseLeft, store_tabletMouseLeft); |
| 1480 | 1480 | ||
| 1481 | /*********************************************************************** | 1481 | /*********************************************************************** |
| @@ -1505,7 +1505,7 @@ store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const | |||
| 1505 | } | 1505 | } |
| 1506 | 1506 | ||
| 1507 | static DEVICE_ATTR(mouse_middle, | 1507 | static DEVICE_ATTR(mouse_middle, |
| 1508 | S_IRUGO | S_IWUGO, | 1508 | S_IRUGO | S_IWUSR, |
| 1509 | show_tabletMouseMiddle, store_tabletMouseMiddle); | 1509 | show_tabletMouseMiddle, store_tabletMouseMiddle); |
| 1510 | 1510 | ||
| 1511 | /*********************************************************************** | 1511 | /*********************************************************************** |
| @@ -1535,7 +1535,7 @@ store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const | |||
| 1535 | } | 1535 | } |
| 1536 | 1536 | ||
| 1537 | static DEVICE_ATTR(mouse_right, | 1537 | static DEVICE_ATTR(mouse_right, |
| 1538 | S_IRUGO | S_IWUGO, | 1538 | S_IRUGO | S_IWUSR, |
| 1539 | show_tabletMouseRight, store_tabletMouseRight); | 1539 | show_tabletMouseRight, store_tabletMouseRight); |
| 1540 | 1540 | ||
| 1541 | /*********************************************************************** | 1541 | /*********************************************************************** |
| @@ -1567,7 +1567,7 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char | |||
| 1567 | } | 1567 | } |
| 1568 | 1568 | ||
| 1569 | static DEVICE_ATTR(wheel, | 1569 | static DEVICE_ATTR(wheel, |
| 1570 | S_IRUGO | S_IWUGO, show_tabletWheel, store_tabletWheel); | 1570 | S_IRUGO | S_IWUSR, show_tabletWheel, store_tabletWheel); |
| 1571 | 1571 | ||
| 1572 | /*********************************************************************** | 1572 | /*********************************************************************** |
| 1573 | * support routines for the 'execute' file. Note that this file | 1573 | * support routines for the 'execute' file. Note that this file |
| @@ -1600,7 +1600,7 @@ store_tabletExecute(struct device *dev, struct device_attribute *attr, const cha | |||
| 1600 | } | 1600 | } |
| 1601 | 1601 | ||
| 1602 | static DEVICE_ATTR(execute, | 1602 | static DEVICE_ATTR(execute, |
| 1603 | S_IRUGO | S_IWUGO, show_tabletExecute, store_tabletExecute); | 1603 | S_IRUGO | S_IWUSR, show_tabletExecute, store_tabletExecute); |
| 1604 | 1604 | ||
| 1605 | /*********************************************************************** | 1605 | /*********************************************************************** |
| 1606 | * support routines for the 'odm_code' file. Note that this file | 1606 | * support routines for the 'odm_code' file. Note that this file |
diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c index eaa5d3efa79d..c556ed9db13d 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c | |||
| @@ -554,7 +554,7 @@ EXPORT_SYMBOL(handle_sysrq); | |||
| 554 | #ifdef CONFIG_INPUT | 554 | #ifdef CONFIG_INPUT |
| 555 | 555 | ||
| 556 | /* Simple translation table for the SysRq keys */ | 556 | /* Simple translation table for the SysRq keys */ |
| 557 | static const unsigned char sysrq_xlate[KEY_MAX + 1] = | 557 | static const unsigned char sysrq_xlate[KEY_CNT] = |
| 558 | "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ | 558 | "\000\0331234567890-=\177\t" /* 0x00 - 0x0f */ |
| 559 | "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ | 559 | "qwertyuiop[]\r\000as" /* 0x10 - 0x1f */ |
| 560 | "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ | 560 | "dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */ |
| @@ -563,53 +563,129 @@ static const unsigned char sysrq_xlate[KEY_MAX + 1] = | |||
| 563 | "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ | 563 | "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */ |
| 564 | "\r\000/"; /* 0x60 - 0x6f */ | 564 | "\r\000/"; /* 0x60 - 0x6f */ |
| 565 | 565 | ||
| 566 | static bool sysrq_down; | 566 | struct sysrq_state { |
| 567 | static int sysrq_alt_use; | 567 | struct input_handle handle; |
| 568 | static int sysrq_alt; | 568 | struct work_struct reinject_work; |
| 569 | static DEFINE_SPINLOCK(sysrq_event_lock); | 569 | unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; |
| 570 | unsigned int alt; | ||
| 571 | unsigned int alt_use; | ||
| 572 | bool active; | ||
| 573 | bool need_reinject; | ||
| 574 | }; | ||
| 575 | |||
| 576 | static void sysrq_reinject_alt_sysrq(struct work_struct *work) | ||
| 577 | { | ||
| 578 | struct sysrq_state *sysrq = | ||
| 579 | container_of(work, struct sysrq_state, reinject_work); | ||
| 580 | struct input_handle *handle = &sysrq->handle; | ||
| 581 | unsigned int alt_code = sysrq->alt_use; | ||
| 582 | |||
| 583 | if (sysrq->need_reinject) { | ||
| 584 | /* Simulate press and release of Alt + SysRq */ | ||
| 585 | input_inject_event(handle, EV_KEY, alt_code, 1); | ||
| 586 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1); | ||
| 587 | input_inject_event(handle, EV_SYN, SYN_REPORT, 1); | ||
| 588 | |||
| 589 | input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0); | ||
| 590 | input_inject_event(handle, EV_KEY, alt_code, 0); | ||
| 591 | input_inject_event(handle, EV_SYN, SYN_REPORT, 1); | ||
| 592 | } | ||
| 593 | } | ||
| 570 | 594 | ||
| 571 | static bool sysrq_filter(struct input_handle *handle, unsigned int type, | 595 | static bool sysrq_filter(struct input_handle *handle, |
| 572 | unsigned int code, int value) | 596 | unsigned int type, unsigned int code, int value) |
| 573 | { | 597 | { |
| 598 | struct sysrq_state *sysrq = handle->private; | ||
| 599 | bool was_active = sysrq->active; | ||
| 574 | bool suppress; | 600 | bool suppress; |
| 575 | 601 | ||
| 576 | /* We are called with interrupts disabled, just take the lock */ | 602 | switch (type) { |
| 577 | spin_lock(&sysrq_event_lock); | ||
| 578 | 603 | ||
| 579 | if (type != EV_KEY) | 604 | case EV_SYN: |
| 580 | goto out; | 605 | suppress = false; |
| 606 | break; | ||
| 581 | 607 | ||
| 582 | switch (code) { | 608 | case EV_KEY: |
| 609 | switch (code) { | ||
| 583 | 610 | ||
| 584 | case KEY_LEFTALT: | 611 | case KEY_LEFTALT: |
| 585 | case KEY_RIGHTALT: | 612 | case KEY_RIGHTALT: |
| 586 | if (value) | 613 | if (!value) { |
| 587 | sysrq_alt = code; | 614 | /* One of ALTs is being released */ |
| 588 | else { | 615 | if (sysrq->active && code == sysrq->alt_use) |
| 589 | if (sysrq_down && code == sysrq_alt_use) | 616 | sysrq->active = false; |
| 590 | sysrq_down = false; | ||
| 591 | 617 | ||
| 592 | sysrq_alt = 0; | 618 | sysrq->alt = KEY_RESERVED; |
| 619 | |||
| 620 | } else if (value != 2) { | ||
| 621 | sysrq->alt = code; | ||
| 622 | sysrq->need_reinject = false; | ||
| 623 | } | ||
| 624 | break; | ||
| 625 | |||
| 626 | case KEY_SYSRQ: | ||
| 627 | if (value == 1 && sysrq->alt != KEY_RESERVED) { | ||
| 628 | sysrq->active = true; | ||
| 629 | sysrq->alt_use = sysrq->alt; | ||
| 630 | /* | ||
| 631 | * If nothing else will be pressed we'll need | ||
| 632 | * to * re-inject Alt-SysRq keysroke. | ||
| 633 | */ | ||
| 634 | sysrq->need_reinject = true; | ||
| 635 | } | ||
| 636 | |||
| 637 | /* | ||
| 638 | * Pretend that sysrq was never pressed at all. This | ||
| 639 | * is needed to properly handle KGDB which will try | ||
| 640 | * to release all keys after exiting debugger. If we | ||
| 641 | * do not clear key bit it KGDB will end up sending | ||
| 642 | * release events for Alt and SysRq, potentially | ||
| 643 | * triggering print screen function. | ||
| 644 | */ | ||
| 645 | if (sysrq->active) | ||
| 646 | clear_bit(KEY_SYSRQ, handle->dev->key); | ||
| 647 | |||
| 648 | break; | ||
| 649 | |||
| 650 | default: | ||
| 651 | if (sysrq->active && value && value != 2) { | ||
| 652 | sysrq->need_reinject = false; | ||
| 653 | __handle_sysrq(sysrq_xlate[code], true); | ||
| 654 | } | ||
| 655 | break; | ||
| 593 | } | 656 | } |
| 594 | break; | ||
| 595 | 657 | ||
| 596 | case KEY_SYSRQ: | 658 | suppress = sysrq->active; |
| 597 | if (value == 1 && sysrq_alt) { | 659 | |
| 598 | sysrq_down = true; | 660 | if (!sysrq->active) { |
| 599 | sysrq_alt_use = sysrq_alt; | 661 | /* |
| 662 | * If we are not suppressing key presses keep track of | ||
| 663 | * keyboard state so we can release keys that have been | ||
| 664 | * pressed before entering SysRq mode. | ||
| 665 | */ | ||
| 666 | if (value) | ||
| 667 | set_bit(code, sysrq->key_down); | ||
| 668 | else | ||
| 669 | clear_bit(code, sysrq->key_down); | ||
| 670 | |||
| 671 | if (was_active) | ||
| 672 | schedule_work(&sysrq->reinject_work); | ||
| 673 | |||
| 674 | } else if (value == 0 && | ||
| 675 | test_and_clear_bit(code, sysrq->key_down)) { | ||
| 676 | /* | ||
| 677 | * Pass on release events for keys that was pressed before | ||
| 678 | * entering SysRq mode. | ||
| 679 | */ | ||
| 680 | suppress = false; | ||
| 600 | } | 681 | } |
| 601 | break; | 682 | break; |
| 602 | 683 | ||
| 603 | default: | 684 | default: |
| 604 | if (sysrq_down && value && value != 2) | 685 | suppress = sysrq->active; |
| 605 | __handle_sysrq(sysrq_xlate[code], true); | ||
| 606 | break; | 686 | break; |
| 607 | } | 687 | } |
| 608 | 688 | ||
| 609 | out: | ||
| 610 | suppress = sysrq_down; | ||
| 611 | spin_unlock(&sysrq_event_lock); | ||
| 612 | |||
| 613 | return suppress; | 689 | return suppress; |
| 614 | } | 690 | } |
| 615 | 691 | ||
| @@ -617,28 +693,28 @@ static int sysrq_connect(struct input_handler *handler, | |||
| 617 | struct input_dev *dev, | 693 | struct input_dev *dev, |
| 618 | const struct input_device_id *id) | 694 | const struct input_device_id *id) |
| 619 | { | 695 | { |
| 620 | struct input_handle *handle; | 696 | struct sysrq_state *sysrq; |
| 621 | int error; | 697 | int error; |
| 622 | 698 | ||
| 623 | sysrq_down = false; | 699 | sysrq = kzalloc(sizeof(struct sysrq_state), GFP_KERNEL); |
| 624 | sysrq_alt = 0; | 700 | if (!sysrq) |
| 625 | |||
| 626 | handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL); | ||
| 627 | if (!handle) | ||
| 628 | return -ENOMEM; | 701 | return -ENOMEM; |
| 629 | 702 | ||
| 630 | handle->dev = dev; | 703 | INIT_WORK(&sysrq->reinject_work, sysrq_reinject_alt_sysrq); |
| 631 | handle->handler = handler; | 704 | |
| 632 | handle->name = "sysrq"; | 705 | sysrq->handle.dev = dev; |
| 706 | sysrq->handle.handler = handler; | ||
| 707 | sysrq->handle.name = "sysrq"; | ||
| 708 | sysrq->handle.private = sysrq; | ||
| 633 | 709 | ||
| 634 | error = input_register_handle(handle); | 710 | error = input_register_handle(&sysrq->handle); |
| 635 | if (error) { | 711 | if (error) { |
| 636 | pr_err("Failed to register input sysrq handler, error %d\n", | 712 | pr_err("Failed to register input sysrq handler, error %d\n", |
| 637 | error); | 713 | error); |
| 638 | goto err_free; | 714 | goto err_free; |
| 639 | } | 715 | } |
| 640 | 716 | ||
| 641 | error = input_open_device(handle); | 717 | error = input_open_device(&sysrq->handle); |
| 642 | if (error) { | 718 | if (error) { |
| 643 | pr_err("Failed to open input device, error %d\n", error); | 719 | pr_err("Failed to open input device, error %d\n", error); |
| 644 | goto err_unregister; | 720 | goto err_unregister; |
| @@ -647,17 +723,20 @@ static int sysrq_connect(struct input_handler *handler, | |||
| 647 | return 0; | 723 | return 0; |
| 648 | 724 | ||
| 649 | err_unregister: | 725 | err_unregister: |
| 650 | input_unregister_handle(handle); | 726 | input_unregister_handle(&sysrq->handle); |
| 651 | err_free: | 727 | err_free: |
| 652 | kfree(handle); | 728 | kfree(sysrq); |
| 653 | return error; | 729 | return error; |
| 654 | } | 730 | } |
| 655 | 731 | ||
| 656 | static void sysrq_disconnect(struct input_handle *handle) | 732 | static void sysrq_disconnect(struct input_handle *handle) |
| 657 | { | 733 | { |
| 734 | struct sysrq_state *sysrq = handle->private; | ||
| 735 | |||
| 658 | input_close_device(handle); | 736 | input_close_device(handle); |
| 737 | cancel_work_sync(&sysrq->reinject_work); | ||
| 659 | input_unregister_handle(handle); | 738 | input_unregister_handle(handle); |
| 660 | kfree(handle); | 739 | kfree(sysrq); |
| 661 | } | 740 | } |
| 662 | 741 | ||
| 663 | /* | 742 | /* |
