diff options
author | Miguel de Icaza <miguel@nuclecu.unam.mx> | 1997-08-02 21:35:30 +0000 |
---|---|---|
committer | Miguel de Icaza <miguel@nuclecu.unam.mx> | 1997-08-02 21:35:30 +0000 |
commit | d2e20e7951dbc28e8b995cbc6b74da2fabdabc0b (patch) | |
tree | 65437cbf0b5494c958fdb813264e53aebd129518 /drivers/sgi | |
parent | dbacf4028db08dd44bda48f4d4662270865e0f9a (diff) |
More streams ioctls for the keyboard, as used by the Xsgi server, should
be enough for now in the keyboard arena.
Diffstat (limited to 'drivers/sgi')
-rw-r--r-- | drivers/sgi/char/shmiq.c | 7 | ||||
-rw-r--r-- | drivers/sgi/char/streamable.c | 84 |
2 files changed, 82 insertions, 9 deletions
diff --git a/drivers/sgi/char/shmiq.c b/drivers/sgi/char/shmiq.c index 9b3011873..39ea0b4f8 100644 --- a/drivers/sgi/char/shmiq.c +++ b/drivers/sgi/char/shmiq.c @@ -223,15 +223,10 @@ shmiq_ioctl (struct inode *inode, struct file *f, unsigned int cmd, unsigned lon return v; case I_STR: - v = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct strioctl)); + v = get_sioc (&sioc, arg); if (v) return v; - if (copy_from_user (&sioc, (void *) arg, sizeof (sioc))) - return -EFAULT; - v = verify_area (VERIFY_WRITE, (void *) sioc.ic_dp, sioc.ic_len); - if (v) - return v; /* FIXME: This forces device = 0 */ return shmiq_sioc (0, sioc.ic_cmd, &sioc); } diff --git a/drivers/sgi/char/streamable.c b/drivers/sgi/char/streamable.c index b241fce56..d2a20651d 100644 --- a/drivers/sgi/char/streamable.c +++ b/drivers/sgi/char/streamable.c @@ -10,12 +10,13 @@ #include <linux/fs.h> #include <linux/miscdevice.h> #include <linux/sched.h> +#include <linux/kbd_kern.h> +#include <linux/vt_kern.h> +#include <asm/uaccess.h> #include <asm/shmiq.h> +#include <asm/keyboard.h> #include "graphics.h" -#include <asm/keyboard.h> -#include <linux/kbd_kern.h> -#include <linux/vt_kern.h> extern struct kbd_struct kbd_table [MAX_NR_CONSOLES]; @@ -28,6 +29,24 @@ int kbd_assigned_device; /* previous kbd_mode for the forward_chars terminal */ int kbd_prev_mode; +/* Fetchs the strioctl information from user space for I_STR ioctls */ +int +get_sioc (struct strioctl *sioc, unsigned long arg) +{ + int v; + + v = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct strioctl)); + if (v) + return v; + if (copy_from_user (sioc, (void *) arg, sizeof (struct strioctl))) + return -EFAULT; + + v = verify_area (VERIFY_WRITE, (void *) sioc->ic_dp, sioc->ic_len); + if (v) + return v; + return 0; +} + static int sgi_gfx_open (struct inode *inode, struct file *file) { @@ -49,13 +68,72 @@ sgi_gfx_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigne return -EINVAL; } +static idevDesc sgi_kbd_desc = { + "keyboard", /* devName */ + "KEYBOARD", /* devType */ + 240, /* nButtons */ + 0, /* nValuators */ + 0, /* nLEDs */ + 0, /* nStrDpys */ + 0, /* nIntDpys */ + 0, /* nBells */ + IDEV_HAS_KEYMAP | IDEV_HAS_PCKBD +}; + +static int +sgi_kbd_sioc (idevInfo *dinfo, int cmd, int size, char *data, int *found) +{ + *found = 1; + + switch (cmd){ + + case IDEVINITDEVICE: + return 0; + + case IDEVGETDEVICEDESC: + if (size >= sizeof (idevDesc)){ + if (copy_to_user (data, &sgi_kbd_desc, sizeof (sgi_kbd_desc))) + return -EFAULT; + return 0; + } + return -EINVAL; + + case IDEVGETKEYMAPDESC: + if (size >= sizeof (idevKeymapDesc)){ + if (copy_to_user (data, "US", 3)) + return -EFAULT; + return 0; + } + return -EINVAL; + } + *found = 0; + return -EINVAL; +} + static int sgi_keyb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { + struct strioctl sioc; + int f, v; /* IRIX calls I_PUSH on the opened device, go figure */ if (cmd == I_PUSH) return 0; + + if (cmd == I_STR){ + v = get_sioc (&sioc, arg); + if (v) + return v; + + /* Why like this? Because this is a sample piece of code + * that can be copied into other drivers and shows how to + * call a stock IRIX xxx_wioctl routine + * + * The NULL is supposed to be a idevInfo, right now we + * do not support this in our kernel. + */ + return sgi_kbd_sioc (NULL, sioc.ic_cmd, sioc.ic_len, sioc.ic_dp, &f); + } if (cmd == SHMIQ_ON){ kbd_assigned_device = arg; |