]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/s390/char/keyboard.c
iwlwifi: unregister to upper stack before releasing resources
[linux-2.6-omap-h63xx.git] / drivers / s390 / char / keyboard.c
index 3e86fd1756e5dc5b43df29fb6c7fd480fd2160b4..cee4d4e4242907bb7a917070b0e3ac7b706cb794 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/sched.h>
 #include <linux/sysrq.h>
 
+#include <linux/consolemap.h>
 #include <linux/kbd_kern.h>
 #include <linux/kbd_diacr.h>
 #include <asm/uaccess.h>
@@ -82,11 +83,11 @@ kbd_alloc(void) {
        if (!kbd->fn_handler)
                goto out_func;
        kbd->accent_table =
-               kmalloc(sizeof(struct kbdiacr)*MAX_DIACR, GFP_KERNEL);
+               kmalloc(sizeof(struct kbdiacruc)*MAX_DIACR, GFP_KERNEL);
        if (!kbd->accent_table)
                goto out_fn_handler;
        memcpy(kbd->accent_table, accent_table,
-              sizeof(struct kbdiacr)*MAX_DIACR);
+              sizeof(struct kbdiacruc)*MAX_DIACR);
        kbd->accent_table_size = accent_table_size;
        return kbd;
 
@@ -148,6 +149,7 @@ kbd_ascebc(struct kbd_data *kbd, unsigned char *ascebc)
        }
 }
 
+#if 0
 /*
  * Generate ebcdic -> ascii translation table from kbd_data.
  */
@@ -173,6 +175,7 @@ kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc)
                }
        }
 }
+#endif
 
 /*
  * We have a combining character DIACR here, followed by the character CH.
@@ -181,8 +184,8 @@ kbd_ebcasc(struct kbd_data *kbd, unsigned char *ebcasc)
  * Otherwise, conclude that DIACR was not combining after all,
  * queue it and return CH.
  */
-static unsigned char
-handle_diacr(struct kbd_data *kbd, unsigned char ch)
+static unsigned int
+handle_diacr(struct kbd_data *kbd, unsigned int ch)
 {
        int i, d;
 
@@ -458,7 +461,6 @@ int
 kbd_ioctl(struct kbd_data *kbd, struct file *file,
          unsigned int cmd, unsigned long arg)
 {
-       struct kbdiacrs __user *a;
        void __user *argp;
        int ct, perm;
 
@@ -479,17 +481,60 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file,
        case KDSKBSENT:
                return do_kdgkb_ioctl(kbd, argp, cmd, perm);
        case KDGKBDIACR:
-               a = argp;
+       {
+               struct kbdiacrs __user *a = argp;
+               struct kbdiacr diacr;
+               int i;
 
                if (put_user(kbd->accent_table_size, &a->kb_cnt))
                        return -EFAULT;
+               for (i = 0; i < kbd->accent_table_size; i++) {
+                       diacr.diacr = kbd->accent_table[i].diacr;
+                       diacr.base = kbd->accent_table[i].base;
+                       diacr.result = kbd->accent_table[i].result;
+                       if (copy_to_user(a->kbdiacr + i, &diacr, sizeof(struct kbdiacr)))
+                       return -EFAULT;
+               }
+               return 0;
+       }
+       case KDGKBDIACRUC:
+       {
+               struct kbdiacrsuc __user *a = argp;
+
                ct = kbd->accent_table_size;
-               if (copy_to_user(a->kbdiacr, kbd->accent_table,
-                                ct * sizeof(struct kbdiacr)))
+               if (put_user(ct, &a->kb_cnt))
+                       return -EFAULT;
+               if (copy_to_user(a->kbdiacruc, kbd->accent_table,
+                                ct * sizeof(struct kbdiacruc)))
                        return -EFAULT;
                return 0;
+       }
        case KDSKBDIACR:
-               a = argp;
+       {
+               struct kbdiacrs __user *a = argp;
+               struct kbdiacr diacr;
+               int i;
+
+               if (!perm)
+                       return -EPERM;
+               if (get_user(ct, &a->kb_cnt))
+                       return -EFAULT;
+               if (ct >= MAX_DIACR)
+                       return -EINVAL;
+               kbd->accent_table_size = ct;
+               for (i = 0; i < ct; i++) {
+                       if (copy_from_user(&diacr, a->kbdiacr + i, sizeof(struct kbdiacr)))
+                               return -EFAULT;
+                       kbd->accent_table[i].diacr = diacr.diacr;
+                       kbd->accent_table[i].base = diacr.base;
+                       kbd->accent_table[i].result = diacr.result;
+               }
+               return 0;
+       }
+       case KDSKBDIACRUC:
+       {
+               struct kbdiacrsuc __user *a = argp;
+
                if (!perm)
                        return -EPERM;
                if (get_user(ct, &a->kb_cnt))
@@ -497,10 +542,11 @@ kbd_ioctl(struct kbd_data *kbd, struct file *file,
                if (ct >= MAX_DIACR)
                        return -EINVAL;
                kbd->accent_table_size = ct;
-               if (copy_from_user(kbd->accent_table, a->kbdiacr,
-                                  ct * sizeof(struct kbdiacr)))
+               if (copy_from_user(kbd->accent_table, a->kbdiacruc,
+                                  ct * sizeof(struct kbdiacruc)))
                        return -EFAULT;
                return 0;
+       }
        default:
                return -ENOIOCTLCMD;
        }