This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
#ifndef _INPUT_ECHO_
|
||||
#define _INPUT_ECHO_
|
||||
|
||||
#include "fixedptc.h"
|
||||
#include "linux/cdev.h"
|
||||
#include "linux/fs.h"
|
||||
#include "speed.h"
|
||||
#include <linux/version.h>
|
||||
|
||||
int create_char_device(void);
|
||||
void destroy_char_device(void);
|
||||
|
||||
static struct cdev device;
|
||||
static struct class *device_class;
|
||||
static dev_t device_number;
|
||||
|
||||
/*
|
||||
* Convert an int into an array of four/eight bytes, in big endian (MSB first)
|
||||
*/
|
||||
static void fpt_to_int_be_bytes(fpt num, char bytes[sizeof(fpt)]) {
|
||||
#define byte(i) (FIXEDPT_BITS - (i * 8))
|
||||
bytes[0] = (num >> byte(1)) & 0xFF; // Most significant byte
|
||||
bytes[1] = (num >> byte(2)) & 0xFF;
|
||||
bytes[2] = (num >> byte(3)) & 0xFF;
|
||||
#if FIXEDPT_BITS == 64
|
||||
if (sizeof(fpt) == 8) {
|
||||
bytes[3] = (num >> byte(4)) & 0xFF;
|
||||
bytes[4] = (num >> byte(5)) & 0xFF;
|
||||
bytes[5] = (num >> byte(6)) & 0xFF;
|
||||
bytes[6] = (num >> byte(7)) & 0xFF;
|
||||
bytes[7] = num & 0xFF; // Least significant byte
|
||||
return;
|
||||
}
|
||||
#else
|
||||
bytes[3] = num & 0xFF; // Least significant byte
|
||||
#endif
|
||||
}
|
||||
|
||||
static ssize_t read(struct file *f, char __user *user_buffer, size_t size,
|
||||
loff_t *offset) {
|
||||
dbg("echoing speed to userspace: %s", fptoa(LAST_INPUT_MOUSE_SPEED));
|
||||
|
||||
char be_bytes_for_int[sizeof(fpt)] = {0};
|
||||
fpt_to_int_be_bytes(LAST_INPUT_MOUSE_SPEED, be_bytes_for_int);
|
||||
|
||||
int err =
|
||||
copy_to_user(user_buffer, be_bytes_for_int, sizeof(be_bytes_for_int));
|
||||
if (err)
|
||||
return -EFAULT;
|
||||
|
||||
return sizeof(be_bytes_for_int);
|
||||
}
|
||||
|
||||
struct file_operations fops = {.owner = THIS_MODULE, .read = read};
|
||||
|
||||
int create_char_device(void) {
|
||||
int err;
|
||||
err = alloc_chrdev_region(&device_number, 0, 1, "maccel");
|
||||
if (err)
|
||||
return -EIO;
|
||||
|
||||
cdev_init(&device, &fops);
|
||||
cdev_add(&device, device_number, 1);
|
||||
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0))
|
||||
device_class = class_create(THIS_MODULE, "maccel");
|
||||
#else
|
||||
device.owner = THIS_MODULE;
|
||||
device_class = class_create("maccel");
|
||||
#endif
|
||||
|
||||
if (IS_ERR(device_class)) {
|
||||
goto err_free_cdev;
|
||||
}
|
||||
|
||||
device_create(device_class, NULL, device_number, NULL, "maccel");
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_cdev:
|
||||
cdev_del(&device);
|
||||
unregister_chrdev_region(device_number, 1);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
void destroy_char_device(void) {
|
||||
device_destroy(device_class, device_number);
|
||||
class_destroy(device_class);
|
||||
cdev_del(&device);
|
||||
unregister_chrdev_region(device_number, 1);
|
||||
}
|
||||
|
||||
#endif // !_INPUT_ECHO_
|
||||
Reference in New Issue
Block a user