From 118175a9fbe11649d0454dd0e377ddbbc512e450 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Mal=C3=BD?= Date: Sun, 27 Jul 2014 15:55:30 +0200 Subject: [PATCH] Initial commit --- Makefile | 16 +++++ klgdtm.c | 191 +++++++++++++++++++++++++++++++++++++++++++++++++++++ test_me.sh | 21 ++++++ 3 files changed, 228 insertions(+) create mode 100644 Makefile create mode 100644 klgdtm.c create mode 100755 test_me.sh diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..72cff1f --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +KBUILD_EXTRA_SYMBOLS := /home/madcat/Devel/KLGD/Module.symvers + +ifneq ($(KERNELRELEASE),) + obj-m += klgdtm.o + +else + KERNELDIR ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) + +default: + $(MAKE) -C $(KERNELDIR) M=$(PWD) + +clean: + $(MAKE) -C $(KERNELDIR) M=$(PWD) clean + +endif diff --git a/klgdtm.c b/klgdtm.c new file mode 100644 index 0000000..13597be --- /dev/null +++ b/klgdtm.c @@ -0,0 +1,191 @@ +#include +#include +#include +#include +#include "../KLGD/klgd.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Michal \"MadCatX\" Maly"); +MODULE_DESCRIPTION("..."); + +static ssize_t klgdtm_num_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf); +static ssize_t klgdtm_num_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count); + +static struct kobject *klgdtm_obj; +static int klgdtm_number; + +static struct klgd_main klgd; + +static struct kobj_attribute put_num_attr = + __ATTR(num, 0666, klgdtm_num_show, klgdtm_num_store); + +static struct attribute *attrs[] = { + &put_num_attr.attr, + NULL +}; + +static struct attribute_group attrs_grp = { + .attrs = attrs +}; + +/* KLGD plugin */ + +struct klgd_plugin_private { + int old_n; + int n; +}; + +static struct klgd_plugin_private plugin_private = { + 0 +}; + +static struct klgd_command_stream * klgdtm_plugin_get_commands(struct klgd_plugin *self, const unsigned long now) +{ + struct klgd_plugin_private *p = self->private; + struct klgd_command_stream *s; + struct klgd_command *c; + + s = kzalloc(sizeof(struct klgd_command_stream), GFP_KERNEL); + if (!s) + return NULL; + s->commands = kzalloc(sizeof(struct klgd_command *) * 2, GFP_KERNEL); + if (!s->commands) { + kfree(s); + return NULL; + } + + c = kzalloc(sizeof(struct klgd_command), GFP_KERNEL); + if (!c) + return NULL; + + c->bytes = kzalloc(sizeof(int), GFP_KERNEL); + if (!c->bytes) { + kfree(s->commands); + kfree(s); + kfree(c); + return NULL; + } + c->length = sizeof(int); + + *(int*)(c->bytes) = p->n; + *(int*)(c->bytes + sizeof(int)) = p->old_n; + + s->commands[0] = c; + s->count = 1; + + p->old_n = p->n; + + return s; +} + +bool klgdtm_plugin_get_update_time(struct klgd_plugin *self, const unsigned long now, unsigned long *t) +{ + struct klgd_plugin_private *p = self->private; + + if (p->n) { + *t = now + msecs_to_jiffies(1000); + return true; + } + return false; +} + + +int klgdtm_plugin_post_event(struct klgd_plugin *self, void *data) +{ + struct klgd_plugin_private *p = self->private; + int num = *(int*)data; + + p->n = num; + if (num == 0) + p->old_n = 0; + + return 0; +} + +static struct klgd_plugin klgdtm_plugin = { + &plugin_private, + NULL, + klgdtm_plugin_get_commands, + klgdtm_plugin_get_update_time, + NULL, + NULL, + klgdtm_plugin_post_event +}; + + +/** END of plugin definition */ + +static enum klgd_send_status klgdtm_callback(void *data, struct klgd_command_stream *s) +{ + int num, old_num; + if (!s) { + printk(KERN_NOTICE "Empty stream\n"); + return KLGD_SS_DONE; + } + if (s->commands[0]->length != sizeof(int)) { + printk(KERN_WARNING "Malformed stream\n"); + return KLGD_SS_FAILED; + } + + num = *(int*)s->commands[0]->bytes; + old_num = *(int*)(s->commands[0]->bytes + sizeof(int)); + printk(KERN_NOTICE "KLGDTM: Value %d, prev: %d\n", num, old_num); + + return KLGD_SS_DONE; +} + +static ssize_t klgdtm_num_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d\n", klgdtm_number); +} + +static ssize_t klgdtm_num_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) +{ + int n; + sscanf(buf, "%d", &n); + klgdtm_number = n; + + klgd_post_event(&klgd, 0, &n); + return count; +} + +static void __exit klgdtm_exit(void) +{ + klgd_deinit(&klgd); + sysfs_remove_group(klgdtm_obj, &attrs_grp); + kobject_put(klgdtm_obj); + printk(KERN_NOTICE "KLGD sample module removed\n"); +} + +static int __init klgdtm_init(void) +{ + int ret; + + klgdtm_obj = kobject_create_and_add("klgdtm_obj", kernel_kobj); + if (!klgdtm_obj) + return -ENOMEM; + + ret = sysfs_create_group(klgdtm_obj, &attrs_grp); + if (ret) + goto errout_sysfs; + + ret = klgd_init(&klgd, NULL, klgdtm_callback, 1); + if (ret) { + printk(KERN_ERR "Cannot initialize KLGD\n"); + goto errout_klgd; + } + + klgd_register_plugin(&klgd, 0, &klgdtm_plugin); + + printk(KERN_NOTICE "KLGD sample module loaded\n"); + return 0; + +errout_klgd: + sysfs_remove_group(klgdtm_obj, &attrs_grp); +errout_sysfs: + kobject_put(klgdtm_obj); + return ret; +} + +module_exit(klgdtm_exit) +module_init(klgdtm_init); diff --git a/test_me.sh b/test_me.sh new file mode 100755 index 0000000..4c37636 --- /dev/null +++ b/test_me.sh @@ -0,0 +1,21 @@ +#! /bin/bash + +(( ctr=0 )) + +while (true) +do + n=$RANDOM + (( n=(n%9)+1 )) + (( ctr=ctr+1 )) + + if [ $ctr -eq 10 ]; then + echo ">> "$n + (( ctr=0 )) + else + echo $n + fi + + echo $n > /sys/kernel/klgdtm_obj/num + sleep 0.1 +done + -- 2.43.5