Skip to content

Commit b5b3159

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
Pull input fixes from Dmitry Torokhov: "Just a few small fixups here" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: imx_sc_key - only take the valid data from SCU firmware as key state Input: add safety guards to input_set_keycode() Input: input_event - fix struct padding on sparc64 Input: uinput - always report EPOLLOUT
2 parents e69ec48 + 1021dcf commit b5b3159

File tree

5 files changed

+43
-25
lines changed

5 files changed

+43
-25
lines changed

drivers/input/evdev.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -224,13 +224,13 @@ static void __pass_event(struct evdev_client *client,
224224
*/
225225
client->tail = (client->head - 2) & (client->bufsize - 1);
226226

227-
client->buffer[client->tail].input_event_sec =
228-
event->input_event_sec;
229-
client->buffer[client->tail].input_event_usec =
230-
event->input_event_usec;
231-
client->buffer[client->tail].type = EV_SYN;
232-
client->buffer[client->tail].code = SYN_DROPPED;
233-
client->buffer[client->tail].value = 0;
227+
client->buffer[client->tail] = (struct input_event) {
228+
.input_event_sec = event->input_event_sec,
229+
.input_event_usec = event->input_event_usec,
230+
.type = EV_SYN,
231+
.code = SYN_DROPPED,
232+
.value = 0,
233+
};
234234

235235
client->packet_head = client->tail;
236236
}

drivers/input/input.c

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -878,16 +878,18 @@ static int input_default_setkeycode(struct input_dev *dev,
878878
}
879879
}
880880

881-
__clear_bit(*old_keycode, dev->keybit);
882-
__set_bit(ke->keycode, dev->keybit);
883-
884-
for (i = 0; i < dev->keycodemax; i++) {
885-
if (input_fetch_keycode(dev, i) == *old_keycode) {
886-
__set_bit(*old_keycode, dev->keybit);
887-
break; /* Setting the bit twice is useless, so break */
881+
if (*old_keycode <= KEY_MAX) {
882+
__clear_bit(*old_keycode, dev->keybit);
883+
for (i = 0; i < dev->keycodemax; i++) {
884+
if (input_fetch_keycode(dev, i) == *old_keycode) {
885+
__set_bit(*old_keycode, dev->keybit);
886+
/* Setting the bit twice is useless, so break */
887+
break;
888+
}
888889
}
889890
}
890891

892+
__set_bit(ke->keycode, dev->keybit);
891893
return 0;
892894
}
893895

@@ -943,9 +945,13 @@ int input_set_keycode(struct input_dev *dev,
943945
* Simulate keyup event if keycode is not present
944946
* in the keymap anymore
945947
*/
946-
if (test_bit(EV_KEY, dev->evbit) &&
947-
!is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
948-
__test_and_clear_bit(old_keycode, dev->key)) {
948+
if (old_keycode > KEY_MAX) {
949+
dev_warn(dev->dev.parent ?: &dev->dev,
950+
"%s: got too big old keycode %#x\n",
951+
__func__, old_keycode);
952+
} else if (test_bit(EV_KEY, dev->evbit) &&
953+
!is_event_supported(old_keycode, dev->keybit, KEY_MAX) &&
954+
__test_and_clear_bit(old_keycode, dev->key)) {
949955
struct input_value vals[] = {
950956
{ EV_KEY, old_keycode, 0 },
951957
input_value_sync

drivers/input/keyboard/imx_sc_key.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,13 @@ static void imx_sc_check_for_events(struct work_struct *work)
7878
return;
7979
}
8080

81-
state = (bool)msg.state;
81+
/*
82+
* The response data from SCU firmware is 4 bytes,
83+
* but ONLY the first byte is the key state, other
84+
* 3 bytes could be some dirty data, so we should
85+
* ONLY take the first byte as key state.
86+
*/
87+
state = (bool)(msg.state & 0xff);
8288

8389
if (state ^ priv->keystate) {
8490
priv->keystate = state;

drivers/input/misc/uinput.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,16 @@ static int uinput_dev_event(struct input_dev *dev,
7474
struct uinput_device *udev = input_get_drvdata(dev);
7575
struct timespec64 ts;
7676

77-
udev->buff[udev->head].type = type;
78-
udev->buff[udev->head].code = code;
79-
udev->buff[udev->head].value = value;
8077
ktime_get_ts64(&ts);
81-
udev->buff[udev->head].input_event_sec = ts.tv_sec;
82-
udev->buff[udev->head].input_event_usec = ts.tv_nsec / NSEC_PER_USEC;
78+
79+
udev->buff[udev->head] = (struct input_event) {
80+
.input_event_sec = ts.tv_sec,
81+
.input_event_usec = ts.tv_nsec / NSEC_PER_USEC,
82+
.type = type,
83+
.code = code,
84+
.value = value,
85+
};
86+
8387
udev->head = (udev->head + 1) % UINPUT_BUFFER_SIZE;
8488

8589
wake_up_interruptible(&udev->waitq);
@@ -689,13 +693,14 @@ static ssize_t uinput_read(struct file *file, char __user *buffer,
689693
static __poll_t uinput_poll(struct file *file, poll_table *wait)
690694
{
691695
struct uinput_device *udev = file->private_data;
696+
__poll_t mask = EPOLLOUT | EPOLLWRNORM; /* uinput is always writable */
692697

693698
poll_wait(file, &udev->waitq, wait);
694699

695700
if (udev->head != udev->tail)
696-
return EPOLLIN | EPOLLRDNORM;
701+
mask |= EPOLLIN | EPOLLRDNORM;
697702

698-
return EPOLLOUT | EPOLLWRNORM;
703+
return mask;
699704
}
700705

701706
static int uinput_release(struct inode *inode, struct file *file)

include/uapi/linux/input.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ struct input_event {
3434
__kernel_ulong_t __sec;
3535
#if defined(__sparc__) && defined(__arch64__)
3636
unsigned int __usec;
37+
unsigned int __pad;
3738
#else
3839
__kernel_ulong_t __usec;
3940
#endif

0 commit comments

Comments
 (0)