#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <asm/uaccess.h>

/* Module information */
MODULE_AUTHOR( "Gul-uc3m" );
MODULE_DESCRIPTION( "Modulo de ejemplo" );
MODULE_LICENSE("GPL");


int entero=0;
char * cadena;


struct cdev *my_cdev;
ssize_t midispositivo_write (struct file *fichero, const char __user * datos, size_t tamano, loff_t * offset){
	kfree(cadena);
	cadena=kmalloc(tamano,GFP_KERNEL);
	entero=copy_from_user(cadena,datos,tamano);
	return entero;
}

ssize_t midispositivo_read (struct file *fichero , char __user * destino, size_t tamano, loff_t * offset){
	int ret=tamano>entero?entero:tamano;
	copy_to_user(destino,cadena,ret);
	return ret;
}


int hola(void){
	struct file_operations fops = {
		.owner = THIS_MODULE,
		.read = midispositivo_read,
		.write = midispositivo_write,
	};
	cadena=kmalloc(4,GFP_KERNEL);
	memcpy(cadena,"hola",4);
	my_cdev = cdev_alloc();
	my_cdev->owner = THIS_MODULE;
	my_cdev->ops = &fops;
	cdev_add(my_cdev, MKDEV(250,0), 1);
	

	printk(KERN_INFO "Hola Mundo.entero=%d y cadena=%s.\n",entero, cadena);
	return 0;
}
void adios(void){
	cdev_del(my_cdev);
	printk(KERN_INFO "Adios mundo cruel.entero=%d y cadena=%s.\n",entero, cadena);
	kfree(cadena);
}

module_init(hola);
module_exit(adios);
