#define pr_fmt(fmt) …
#define EVDEV_MINOR_BASE …
#define EVDEV_MINORS …
#define EVDEV_MIN_BUFFER_SIZE …
#define EVDEV_BUF_PACKETS …
#include <linux/poll.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/input/mt.h>
#include <linux/major.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include "input-compat.h"
struct evdev { … };
struct evdev_client { … };
static size_t evdev_get_mask_cnt(unsigned int type)
{ … }
static bool __evdev_is_filtered(struct evdev_client *client,
unsigned int type,
unsigned int code)
{ … }
static void __evdev_flush_queue(struct evdev_client *client, unsigned int type)
{ … }
static void __evdev_queue_syn_dropped(struct evdev_client *client)
{ … }
static void evdev_queue_syn_dropped(struct evdev_client *client)
{ … }
static int evdev_set_clk_type(struct evdev_client *client, unsigned int clkid)
{ … }
static void __pass_event(struct evdev_client *client,
const struct input_event *event)
{ … }
static void evdev_pass_values(struct evdev_client *client,
const struct input_value *vals, unsigned int count,
ktime_t *ev_time)
{ … }
static unsigned int evdev_events(struct input_handle *handle,
struct input_value *vals, unsigned int count)
{ … }
static int evdev_fasync(int fd, struct file *file, int on)
{ … }
static void evdev_free(struct device *dev)
{ … }
static int evdev_grab(struct evdev *evdev, struct evdev_client *client)
{ … }
static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client)
{ … }
static void evdev_attach_client(struct evdev *evdev,
struct evdev_client *client)
{ … }
static void evdev_detach_client(struct evdev *evdev,
struct evdev_client *client)
{ … }
static int evdev_open_device(struct evdev *evdev)
{ … }
static void evdev_close_device(struct evdev *evdev)
{ … }
static void evdev_hangup(struct evdev *evdev)
{ … }
static int evdev_release(struct inode *inode, struct file *file)
{ … }
static unsigned int evdev_compute_buffer_size(struct input_dev *dev)
{ … }
static int evdev_open(struct inode *inode, struct file *file)
{ … }
static ssize_t evdev_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{ … }
static int evdev_fetch_next_event(struct evdev_client *client,
struct input_event *event)
{ … }
static ssize_t evdev_read(struct file *file, char __user *buffer,
size_t count, loff_t *ppos)
{ … }
static __poll_t evdev_poll(struct file *file, poll_table *wait)
{ … }
#ifdef CONFIG_COMPAT
#define BITS_PER_LONG_COMPAT …
#define BITS_TO_LONGS_COMPAT(x) …
#ifdef __BIG_ENDIAN
static int bits_to_user(unsigned long *bits, unsigned int maxbit,
unsigned int maxlen, void __user *p, int compat)
{
int len, i;
if (compat) {
len = BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t);
if (len > maxlen)
len = maxlen;
for (i = 0; i < len / sizeof(compat_long_t); i++)
if (copy_to_user((compat_long_t __user *) p + i,
(compat_long_t *) bits +
i + 1 - ((i % 2) << 1),
sizeof(compat_long_t)))
return -EFAULT;
} else {
len = BITS_TO_LONGS(maxbit) * sizeof(long);
if (len > maxlen)
len = maxlen;
if (copy_to_user(p, bits, len))
return -EFAULT;
}
return len;
}
static int bits_from_user(unsigned long *bits, unsigned int maxbit,
unsigned int maxlen, const void __user *p, int compat)
{
int len, i;
if (compat) {
if (maxlen % sizeof(compat_long_t))
return -EINVAL;
len = BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t);
if (len > maxlen)
len = maxlen;
for (i = 0; i < len / sizeof(compat_long_t); i++)
if (copy_from_user((compat_long_t *) bits +
i + 1 - ((i % 2) << 1),
(compat_long_t __user *) p + i,
sizeof(compat_long_t)))
return -EFAULT;
if (i % 2)
*((compat_long_t *) bits + i - 1) = 0;
} else {
if (maxlen % sizeof(long))
return -EINVAL;
len = BITS_TO_LONGS(maxbit) * sizeof(long);
if (len > maxlen)
len = maxlen;
if (copy_from_user(bits, p, len))
return -EFAULT;
}
return len;
}
#else
static int bits_to_user(unsigned long *bits, unsigned int maxbit,
unsigned int maxlen, void __user *p, int compat)
{ … }
static int bits_from_user(unsigned long *bits, unsigned int maxbit,
unsigned int maxlen, const void __user *p, int compat)
{ … }
#endif
#else
static int bits_to_user(unsigned long *bits, unsigned int maxbit,
unsigned int maxlen, void __user *p, int compat)
{
int len = BITS_TO_LONGS(maxbit) * sizeof(long);
if (len > maxlen)
len = maxlen;
return copy_to_user(p, bits, len) ? -EFAULT : len;
}
static int bits_from_user(unsigned long *bits, unsigned int maxbit,
unsigned int maxlen, const void __user *p, int compat)
{
int len;
if (maxlen % sizeof(long))
return -EINVAL;
len = BITS_TO_LONGS(maxbit) * sizeof(long);
if (len > maxlen)
len = maxlen;
return copy_from_user(bits, p, len) ? -EFAULT : len;
}
#endif
static int str_to_user(const char *str, unsigned int maxlen, void __user *p)
{ … }
static int handle_eviocgbit(struct input_dev *dev,
unsigned int type, unsigned int size,
void __user *p, int compat_mode)
{ … }
static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p)
{ … }
static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p)
{ … }
static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p)
{ … }
static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p)
{ … }
static int evdev_handle_get_val(struct evdev_client *client,
struct input_dev *dev, unsigned int type,
unsigned long *bits, unsigned int maxbit,
unsigned int maxlen, void __user *p,
int compat)
{ … }
static int evdev_handle_mt_request(struct input_dev *dev,
unsigned int size,
int __user *ip)
{ … }
static int evdev_revoke(struct evdev *evdev, struct evdev_client *client,
struct file *file)
{ … }
static int evdev_set_mask(struct evdev_client *client,
unsigned int type,
const void __user *codes,
u32 codes_size,
int compat)
{ … }
static int evdev_get_mask(struct evdev_client *client,
unsigned int type,
void __user *codes,
u32 codes_size,
int compat)
{ … }
static long evdev_do_ioctl(struct file *file, unsigned int cmd,
void __user *p, int compat_mode)
{ … }
static long evdev_ioctl_handler(struct file *file, unsigned int cmd,
void __user *p, int compat_mode)
{ … }
static long evdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{ … }
#ifdef CONFIG_COMPAT
static long evdev_ioctl_compat(struct file *file,
unsigned int cmd, unsigned long arg)
{ … }
#endif
static const struct file_operations evdev_fops = …;
static void evdev_mark_dead(struct evdev *evdev)
{ … }
static void evdev_cleanup(struct evdev *evdev)
{ … }
static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
{ … }
static void evdev_disconnect(struct input_handle *handle)
{ … }
static const struct input_device_id evdev_ids[] = …;
MODULE_DEVICE_TABLE(input, evdev_ids);
static struct input_handler evdev_handler = …;
static int __init evdev_init(void)
{ … }
static void __exit evdev_exit(void)
{ … }
module_init(…) …;
module_exit(evdev_exit);
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;