#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // para get_ds(), set_fs() /* Prototipos de funciones de servicio del driver */ static ssize_t led_write(struct file *filp, const char *buf, size_t count, loff_t *pos); extern void *sys_call_table[]; static int (*mi_mknod)(const char *, int, int); static int (*mi_unlink)(const char *); static int (*mi_chmod)(const char * , mode_t); /* Registra cada función que será suministrada por el driver a los usuarios que lo utilicen */ static struct file_operations led_fops = { owner: THIS_MODULE, open: NULL, release: NULL, read: NULL, write: led_write, }; static int estado = 0; /* Función de inicialización del módulo */ int init_module(void) { mode_t mode; dev_t dev_id; mi_mknod = sys_call_table[__NR_mknod]; mi_unlink = sys_call_table[__NR_unlink]; mi_chmod = sys_call_table[__NR_chmod]; /* Registrar el driver con el major number 55 y el nombre "led" */ if (register_chrdev(55, "led", &led_fops)) return -EIO; set_fs( get_ds() ); mi_unlink( "/dev/led" ); mode = S_IFCHR; dev_id = MKDEV( 55, 0 ); mi_mknod( "/dev/led", mode, dev_id ); mode = 0666; mi_chmod( "/dev/led", mode ); return 0; } /* Función de descarga del módulo */ void cleanup_module(void) { /* Deregistra el driver */ unregister_chrdev(55, "led"); } static ssize_t led_write(struct file *filp, const char *buf, size_t count, loff_t *pos) { estado = buf[0] & 7; while (inb(KBD_STATUS_REG) & KBD_STAT_IBF) mdelay(1); cli(); while (inb(KBD_STATUS_REG) & KBD_STAT_IBF) mdelay(1); // Salida: comando de set leds outb(KBD_CMD_SET_LEDS, KBD_DATA_REG); mdelay(1); while (inb(KBD_STATUS_REG) & KBD_STAT_IBF) mdelay(1); mdelay(1); // Salida: valor de los leds outb(estado, KBD_DATA_REG); mdelay(1); sti(); while (inb(KBD_STATUS_REG) & KBD_STAT_IBF) mdelay(1); mdelay(1); return 1; } MODULE_LICENSE("GPL");