Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: fix typo in keycode validation supporting large scancodes Input: aiptek - tighten up permissions on sysfs attributes Input: sysrq - pass along lone Alt + SysRq
This commit is contained in:
commit
864ee6cb22
@ -752,7 +752,7 @@ static int input_default_setkeycode(struct input_dev *dev,
|
|||||||
if (index >= dev->keycodemax)
|
if (index >= dev->keycodemax)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (dev->keycodesize < sizeof(dev->keycode) &&
|
if (dev->keycodesize < sizeof(ke->keycode) &&
|
||||||
(ke->keycode >> (dev->keycodesize * 8)))
|
(ke->keycode >> (dev->keycodesize * 8)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -1097,7 +1097,7 @@ store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(pointer_mode,
|
static DEVICE_ATTR(pointer_mode,
|
||||||
S_IRUGO | S_IWUGO,
|
S_IRUGO | S_IWUSR,
|
||||||
show_tabletPointerMode, store_tabletPointerMode);
|
show_tabletPointerMode, store_tabletPointerMode);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1134,7 +1134,7 @@ store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(coordinate_mode,
|
static DEVICE_ATTR(coordinate_mode,
|
||||||
S_IRUGO | S_IWUGO,
|
S_IRUGO | S_IWUSR,
|
||||||
show_tabletCoordinateMode, store_tabletCoordinateMode);
|
show_tabletCoordinateMode, store_tabletCoordinateMode);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1176,7 +1176,7 @@ store_tabletToolMode(struct device *dev, struct device_attribute *attr, const ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(tool_mode,
|
static DEVICE_ATTR(tool_mode,
|
||||||
S_IRUGO | S_IWUGO,
|
S_IRUGO | S_IWUSR,
|
||||||
show_tabletToolMode, store_tabletToolMode);
|
show_tabletToolMode, store_tabletToolMode);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1219,7 +1219,7 @@ store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(xtilt,
|
static DEVICE_ATTR(xtilt,
|
||||||
S_IRUGO | S_IWUGO, show_tabletXtilt, store_tabletXtilt);
|
S_IRUGO | S_IWUSR, show_tabletXtilt, store_tabletXtilt);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* support routines for the 'ytilt' file. Note that this file
|
* 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
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(ytilt,
|
static DEVICE_ATTR(ytilt,
|
||||||
S_IRUGO | S_IWUGO, show_tabletYtilt, store_tabletYtilt);
|
S_IRUGO | S_IWUSR, show_tabletYtilt, store_tabletYtilt);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* support routines for the 'jitter' file. Note that this file
|
* support routines for the 'jitter' file. Note that this file
|
||||||
@ -1288,7 +1288,7 @@ store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(jitter,
|
static DEVICE_ATTR(jitter,
|
||||||
S_IRUGO | S_IWUGO,
|
S_IRUGO | S_IWUSR,
|
||||||
show_tabletJitterDelay, store_tabletJitterDelay);
|
show_tabletJitterDelay, store_tabletJitterDelay);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1317,7 +1317,7 @@ store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(delay,
|
static DEVICE_ATTR(delay,
|
||||||
S_IRUGO | S_IWUGO,
|
S_IRUGO | S_IWUSR,
|
||||||
show_tabletProgrammableDelay, store_tabletProgrammableDelay);
|
show_tabletProgrammableDelay, store_tabletProgrammableDelay);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1406,7 +1406,7 @@ store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(stylus_upper,
|
static DEVICE_ATTR(stylus_upper,
|
||||||
S_IRUGO | S_IWUGO,
|
S_IRUGO | S_IWUSR,
|
||||||
show_tabletStylusUpper, store_tabletStylusUpper);
|
show_tabletStylusUpper, store_tabletStylusUpper);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1437,7 +1437,7 @@ store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(stylus_lower,
|
static DEVICE_ATTR(stylus_lower,
|
||||||
S_IRUGO | S_IWUGO,
|
S_IRUGO | S_IWUSR,
|
||||||
show_tabletStylusLower, store_tabletStylusLower);
|
show_tabletStylusLower, store_tabletStylusLower);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1475,7 +1475,7 @@ store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const c
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(mouse_left,
|
static DEVICE_ATTR(mouse_left,
|
||||||
S_IRUGO | S_IWUGO,
|
S_IRUGO | S_IWUSR,
|
||||||
show_tabletMouseLeft, store_tabletMouseLeft);
|
show_tabletMouseLeft, store_tabletMouseLeft);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1505,7 +1505,7 @@ store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(mouse_middle,
|
static DEVICE_ATTR(mouse_middle,
|
||||||
S_IRUGO | S_IWUGO,
|
S_IRUGO | S_IWUSR,
|
||||||
show_tabletMouseMiddle, store_tabletMouseMiddle);
|
show_tabletMouseMiddle, store_tabletMouseMiddle);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1535,7 +1535,7 @@ store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(mouse_right,
|
static DEVICE_ATTR(mouse_right,
|
||||||
S_IRUGO | S_IWUGO,
|
S_IRUGO | S_IWUSR,
|
||||||
show_tabletMouseRight, store_tabletMouseRight);
|
show_tabletMouseRight, store_tabletMouseRight);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
@ -1567,7 +1567,7 @@ store_tabletWheel(struct device *dev, struct device_attribute *attr, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(wheel,
|
static DEVICE_ATTR(wheel,
|
||||||
S_IRUGO | S_IWUGO, show_tabletWheel, store_tabletWheel);
|
S_IRUGO | S_IWUSR, show_tabletWheel, store_tabletWheel);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* support routines for the 'execute' file. Note that this file
|
* 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
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DEVICE_ATTR(execute,
|
static DEVICE_ATTR(execute,
|
||||||
S_IRUGO | S_IWUGO, show_tabletExecute, store_tabletExecute);
|
S_IRUGO | S_IWUSR, show_tabletExecute, store_tabletExecute);
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* support routines for the 'odm_code' file. Note that this file
|
* support routines for the 'odm_code' file. Note that this file
|
||||||
|
@ -554,7 +554,7 @@ EXPORT_SYMBOL(handle_sysrq);
|
|||||||
#ifdef CONFIG_INPUT
|
#ifdef CONFIG_INPUT
|
||||||
|
|
||||||
/* Simple translation table for the SysRq keys */
|
/* Simple translation table for the SysRq keys */
|
||||||
static const unsigned char sysrq_xlate[KEY_MAX + 1] =
|
static const unsigned char sysrq_xlate[KEY_CNT] =
|
||||||
"\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
|
"\000\0331234567890-=\177\t" /* 0x00 - 0x0f */
|
||||||
"qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
|
"qwertyuiop[]\r\000as" /* 0x10 - 0x1f */
|
||||||
"dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
|
"dfghjkl;'`\000\\zxcv" /* 0x20 - 0x2f */
|
||||||
@ -563,53 +563,129 @@ static const unsigned char sysrq_xlate[KEY_MAX + 1] =
|
|||||||
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
|
"230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
|
||||||
"\r\000/"; /* 0x60 - 0x6f */
|
"\r\000/"; /* 0x60 - 0x6f */
|
||||||
|
|
||||||
static bool sysrq_down;
|
struct sysrq_state {
|
||||||
static int sysrq_alt_use;
|
struct input_handle handle;
|
||||||
static int sysrq_alt;
|
struct work_struct reinject_work;
|
||||||
static DEFINE_SPINLOCK(sysrq_event_lock);
|
unsigned long key_down[BITS_TO_LONGS(KEY_CNT)];
|
||||||
|
unsigned int alt;
|
||||||
|
unsigned int alt_use;
|
||||||
|
bool active;
|
||||||
|
bool need_reinject;
|
||||||
|
};
|
||||||
|
|
||||||
static bool sysrq_filter(struct input_handle *handle, unsigned int type,
|
static void sysrq_reinject_alt_sysrq(struct work_struct *work)
|
||||||
unsigned int code, int value)
|
|
||||||
{
|
{
|
||||||
|
struct sysrq_state *sysrq =
|
||||||
|
container_of(work, struct sysrq_state, reinject_work);
|
||||||
|
struct input_handle *handle = &sysrq->handle;
|
||||||
|
unsigned int alt_code = sysrq->alt_use;
|
||||||
|
|
||||||
|
if (sysrq->need_reinject) {
|
||||||
|
/* Simulate press and release of Alt + SysRq */
|
||||||
|
input_inject_event(handle, EV_KEY, alt_code, 1);
|
||||||
|
input_inject_event(handle, EV_KEY, KEY_SYSRQ, 1);
|
||||||
|
input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
|
||||||
|
|
||||||
|
input_inject_event(handle, EV_KEY, KEY_SYSRQ, 0);
|
||||||
|
input_inject_event(handle, EV_KEY, alt_code, 0);
|
||||||
|
input_inject_event(handle, EV_SYN, SYN_REPORT, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool sysrq_filter(struct input_handle *handle,
|
||||||
|
unsigned int type, unsigned int code, int value)
|
||||||
|
{
|
||||||
|
struct sysrq_state *sysrq = handle->private;
|
||||||
|
bool was_active = sysrq->active;
|
||||||
bool suppress;
|
bool suppress;
|
||||||
|
|
||||||
/* We are called with interrupts disabled, just take the lock */
|
switch (type) {
|
||||||
spin_lock(&sysrq_event_lock);
|
|
||||||
|
|
||||||
if (type != EV_KEY)
|
case EV_SYN:
|
||||||
goto out;
|
suppress = false;
|
||||||
|
|
||||||
switch (code) {
|
|
||||||
|
|
||||||
case KEY_LEFTALT:
|
|
||||||
case KEY_RIGHTALT:
|
|
||||||
if (value)
|
|
||||||
sysrq_alt = code;
|
|
||||||
else {
|
|
||||||
if (sysrq_down && code == sysrq_alt_use)
|
|
||||||
sysrq_down = false;
|
|
||||||
|
|
||||||
sysrq_alt = 0;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case KEY_SYSRQ:
|
case EV_KEY:
|
||||||
if (value == 1 && sysrq_alt) {
|
switch (code) {
|
||||||
sysrq_down = true;
|
|
||||||
sysrq_alt_use = sysrq_alt;
|
case KEY_LEFTALT:
|
||||||
|
case KEY_RIGHTALT:
|
||||||
|
if (!value) {
|
||||||
|
/* One of ALTs is being released */
|
||||||
|
if (sysrq->active && code == sysrq->alt_use)
|
||||||
|
sysrq->active = false;
|
||||||
|
|
||||||
|
sysrq->alt = KEY_RESERVED;
|
||||||
|
|
||||||
|
} else if (value != 2) {
|
||||||
|
sysrq->alt = code;
|
||||||
|
sysrq->need_reinject = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case KEY_SYSRQ:
|
||||||
|
if (value == 1 && sysrq->alt != KEY_RESERVED) {
|
||||||
|
sysrq->active = true;
|
||||||
|
sysrq->alt_use = sysrq->alt;
|
||||||
|
/*
|
||||||
|
* If nothing else will be pressed we'll need
|
||||||
|
* to * re-inject Alt-SysRq keysroke.
|
||||||
|
*/
|
||||||
|
sysrq->need_reinject = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pretend that sysrq was never pressed at all. This
|
||||||
|
* is needed to properly handle KGDB which will try
|
||||||
|
* to release all keys after exiting debugger. If we
|
||||||
|
* do not clear key bit it KGDB will end up sending
|
||||||
|
* release events for Alt and SysRq, potentially
|
||||||
|
* triggering print screen function.
|
||||||
|
*/
|
||||||
|
if (sysrq->active)
|
||||||
|
clear_bit(KEY_SYSRQ, handle->dev->key);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (sysrq->active && value && value != 2) {
|
||||||
|
sysrq->need_reinject = false;
|
||||||
|
__handle_sysrq(sysrq_xlate[code], true);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
suppress = sysrq->active;
|
||||||
|
|
||||||
|
if (!sysrq->active) {
|
||||||
|
/*
|
||||||
|
* If we are not suppressing key presses keep track of
|
||||||
|
* keyboard state so we can release keys that have been
|
||||||
|
* pressed before entering SysRq mode.
|
||||||
|
*/
|
||||||
|
if (value)
|
||||||
|
set_bit(code, sysrq->key_down);
|
||||||
|
else
|
||||||
|
clear_bit(code, sysrq->key_down);
|
||||||
|
|
||||||
|
if (was_active)
|
||||||
|
schedule_work(&sysrq->reinject_work);
|
||||||
|
|
||||||
|
} else if (value == 0 &&
|
||||||
|
test_and_clear_bit(code, sysrq->key_down)) {
|
||||||
|
/*
|
||||||
|
* Pass on release events for keys that was pressed before
|
||||||
|
* entering SysRq mode.
|
||||||
|
*/
|
||||||
|
suppress = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (sysrq_down && value && value != 2)
|
suppress = sysrq->active;
|
||||||
__handle_sysrq(sysrq_xlate[code], true);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
suppress = sysrq_down;
|
|
||||||
spin_unlock(&sysrq_event_lock);
|
|
||||||
|
|
||||||
return suppress;
|
return suppress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,28 +693,28 @@ static int sysrq_connect(struct input_handler *handler,
|
|||||||
struct input_dev *dev,
|
struct input_dev *dev,
|
||||||
const struct input_device_id *id)
|
const struct input_device_id *id)
|
||||||
{
|
{
|
||||||
struct input_handle *handle;
|
struct sysrq_state *sysrq;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
sysrq_down = false;
|
sysrq = kzalloc(sizeof(struct sysrq_state), GFP_KERNEL);
|
||||||
sysrq_alt = 0;
|
if (!sysrq)
|
||||||
|
|
||||||
handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
|
|
||||||
if (!handle)
|
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
handle->dev = dev;
|
INIT_WORK(&sysrq->reinject_work, sysrq_reinject_alt_sysrq);
|
||||||
handle->handler = handler;
|
|
||||||
handle->name = "sysrq";
|
|
||||||
|
|
||||||
error = input_register_handle(handle);
|
sysrq->handle.dev = dev;
|
||||||
|
sysrq->handle.handler = handler;
|
||||||
|
sysrq->handle.name = "sysrq";
|
||||||
|
sysrq->handle.private = sysrq;
|
||||||
|
|
||||||
|
error = input_register_handle(&sysrq->handle);
|
||||||
if (error) {
|
if (error) {
|
||||||
pr_err("Failed to register input sysrq handler, error %d\n",
|
pr_err("Failed to register input sysrq handler, error %d\n",
|
||||||
error);
|
error);
|
||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
error = input_open_device(handle);
|
error = input_open_device(&sysrq->handle);
|
||||||
if (error) {
|
if (error) {
|
||||||
pr_err("Failed to open input device, error %d\n", error);
|
pr_err("Failed to open input device, error %d\n", error);
|
||||||
goto err_unregister;
|
goto err_unregister;
|
||||||
@ -647,17 +723,20 @@ static int sysrq_connect(struct input_handler *handler,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_unregister:
|
err_unregister:
|
||||||
input_unregister_handle(handle);
|
input_unregister_handle(&sysrq->handle);
|
||||||
err_free:
|
err_free:
|
||||||
kfree(handle);
|
kfree(sysrq);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sysrq_disconnect(struct input_handle *handle)
|
static void sysrq_disconnect(struct input_handle *handle)
|
||||||
{
|
{
|
||||||
|
struct sysrq_state *sysrq = handle->private;
|
||||||
|
|
||||||
input_close_device(handle);
|
input_close_device(handle);
|
||||||
|
cancel_work_sync(&sysrq->reinject_work);
|
||||||
input_unregister_handle(handle);
|
input_unregister_handle(handle);
|
||||||
kfree(handle);
|
kfree(sysrq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user