summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@nuclecu.unam.mx>1997-08-02 21:35:30 +0000
committerMiguel de Icaza <miguel@nuclecu.unam.mx>1997-08-02 21:35:30 +0000
commitd2e20e7951dbc28e8b995cbc6b74da2fabdabc0b (patch)
tree65437cbf0b5494c958fdb813264e53aebd129518 /drivers
parentdbacf4028db08dd44bda48f4d4662270865e0f9a (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')
-rw-r--r--drivers/sgi/char/shmiq.c7
-rw-r--r--drivers/sgi/char/streamable.c84
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;