2 * streamable.c: streamable devices. /dev/gfx
3 * (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
5 * Major 10 is the streams clone device. The IRIX Xsgi server just
6 * opens /dev/gfx and closes it inmediately.
11 #include <linux/miscdevice.h>
12 #include <linux/sched.h>
13 #include <linux/kbd_kern.h>
14 #include <linux/vt_kern.h>
15 #include <asm/uaccess.h>
16 #include <asm/shmiq.h>
17 #include <asm/keyboard.h>
21 extern struct kbd_struct kbd_table
[MAX_NR_CONSOLES
];
23 /* console number where forwarding is enabled */
26 /* To which shmiq this keyboard is assigned */
27 int kbd_assigned_device
;
29 /* previous kbd_mode for the forward_chars terminal */
32 /* Fetchs the strioctl information from user space for I_STR ioctls */
34 get_sioc (struct strioctl
*sioc
, unsigned long arg
)
38 v
= verify_area (VERIFY_WRITE
, (void *) arg
, sizeof (struct strioctl
));
41 if (copy_from_user (sioc
, (void *) arg
, sizeof (struct strioctl
)))
44 v
= verify_area (VERIFY_WRITE
, (void *) sioc
->ic_dp
, sioc
->ic_len
);
52 sgi_gfx_open (struct inode
*inode
, struct file
*file
)
54 printk ("GFX: Opened by %d\n", current
->pid
);
59 sgi_gfx_close (struct inode
*inode
, struct file
*file
)
61 printk ("GFX: Closed by %d\n", current
->pid
);
66 sgi_gfx_ioctl (struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
68 printk ("GFX: ioctl 0x%x %ld called\n", cmd
, arg
);
73 struct file_operations sgi_gfx_fops
= {
79 sgi_gfx_ioctl
, /* ioctl */
81 sgi_gfx_open
, /* open */
83 sgi_gfx_close
, /* release */
85 NULL
, /* check_media_change */
86 NULL
, /* revalidate */
90 static struct miscdevice dev_gfx
= {
91 SGI_GFX_MINOR
, "sgi-gfx", &sgi_gfx_fops
94 /* /dev/input/keyboard streams device */
95 static idevDesc sgi_kbd_desc
= {
96 "keyboard", /* devName */
97 "KEYBOARD", /* devType */
104 IDEV_HAS_KEYMAP
| IDEV_HAS_PCKBD
108 sgi_kbd_sioc (idevInfo
*dinfo
, int cmd
, int size
, char *data
, int *found
)
117 case IDEVGETDEVICEDESC
:
118 if (size
>= sizeof (idevDesc
)){
119 if (copy_to_user (data
, &sgi_kbd_desc
, sizeof (sgi_kbd_desc
)))
125 case IDEVGETKEYMAPDESC
:
126 if (size
>= sizeof (idevKeymapDesc
)){
127 if (copy_to_user (data
, "US", 3))
138 sgi_keyb_ioctl (struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
140 struct strioctl sioc
;
143 /* IRIX calls I_PUSH on the opened device, go figure */
148 v
= get_sioc (&sioc
, arg
);
152 /* Why like this? Because this is a sample piece of code
153 * that can be copied into other drivers and shows how to
154 * call a stock IRIX xxx_wioctl routine
156 * The NULL is supposed to be a idevInfo, right now we
157 * do not support this in our kernel.
159 return sgi_kbd_sioc (NULL
, sioc
.ic_cmd
, sioc
.ic_len
, sioc
.ic_dp
, &f
);
162 if (cmd
== SHMIQ_ON
){
163 kbd_assigned_device
= arg
;
164 forward_chars
= fg_console
+ 1;
165 kbd_prev_mode
= kbd_table
[fg_console
].kbdmode
;
167 kbd_table
[fg_console
].kbdmode
= VC_RAW
;
168 } else if (cmd
== SHMIQ_OFF
&& forward_chars
){
169 kbd_table
[forward_chars
-1].kbdmode
= kbd_prev_mode
;
177 kbd_forward_char (int ch
)
179 static struct shmqevent ev
;
181 ev
.data
.flags
= (ch
& 0200) ? 0 : 1;
183 ev
.data
.device
= kbd_assigned_device
+ 0x11;
184 shmiq_push_event (&ev
);
188 sgi_keyb_open (struct inode
*inode
, struct file
*file
)
190 /* Nothing, but required by the misc driver */
194 struct file_operations sgi_keyb_fops
= {
200 sgi_keyb_ioctl
, /* ioctl */
202 sgi_keyb_open
, /* open */
206 NULL
, /* check_media_change */
207 NULL
, /* revalidate */
211 static struct miscdevice dev_input_keyboard
= {
212 SGI_STREAMS_KEYBOARD
, "streams-keyboard", &sgi_keyb_fops
215 /* /dev/input/mouse streams device */
216 #define MOUSE_VALUATORS 2
217 static idevDesc sgi_mouse_desc
= {
218 "mouse", /* devName */
219 "MOUSE", /* devType */
221 MOUSE_VALUATORS
, /* nValuators */
229 static idevValuatorDesc mouse_default_valuator
= {
233 65000, /* hwMaxVal */
234 IDEV_EITHER
, /* possibleModes */
235 IDEV_ABSOLUTE
, /* default mode */
236 200, /* resolution */
241 static int mouse_opened
;
242 static idevValuatorDesc mouse_valuators
[MOUSE_VALUATORS
];
245 sgi_mouse_open (struct inode
*inode
, struct file
*file
)
253 for (i
= 0; i
< MOUSE_VALUATORS
; i
++)
254 mouse_valuators
[i
] = mouse_default_valuator
;
259 sgi_mouse_close (struct inode
*inode
, struct file
*filp
)
266 sgi_mouse_sioc (idevInfo
*dinfo
, int cmd
, int size
, char *data
, int *found
)
274 case IDEVGETDEVICEDESC
:
275 if (size
>= sizeof (idevDesc
)){
276 if (copy_to_user (data
, &sgi_mouse_desc
, sizeof (sgi_mouse_desc
)))
282 case IDEVGETVALUATORDESC
: {
283 idevGetSetValDesc request
, *ureq
= (idevGetSetValDesc
*) data
;
285 if (size
< sizeof (idevGetSetValDesc
))
288 if (copy_from_user (&request
, data
, sizeof (request
)))
290 if (request
.valNum
>= MOUSE_VALUATORS
)
292 if (copy_to_user ((void *)&ureq
->desc
,
293 (void *)&mouse_valuators
[request
.valNum
],
294 sizeof (idevValuatorDesc
)))
304 sgi_mouse_ioctl (struct inode
*inode
, struct file
*file
, unsigned int cmd
, unsigned long arg
)
306 struct strioctl sioc
;
309 /* IRIX calls I_PUSH on the opened device, go figure */
315 v
= get_sioc (&sioc
, arg
);
319 /* Why like this? Because this is a sample piece of code
320 * that can be copied into other drivers and shows how to
321 * call a stock IRIX xxx_wioctl routine
323 * The NULL is supposed to be a idevInfo, right now we
324 * do not support this in our kernel.
326 return sgi_mouse_sioc (NULL
, sioc
.ic_cmd
, sioc
.ic_len
, sioc
.ic_dp
, &f
);
335 struct file_operations sgi_mouse_fops
= {
341 sgi_mouse_ioctl
, /* ioctl */
343 sgi_mouse_open
, /* open */
345 sgi_mouse_close
, /* release */
347 NULL
, /* check_media_change */
348 NULL
, /* revalidate */
352 /* /dev/input/mouse */
353 static struct miscdevice dev_input_mouse
= {
354 SGI_STREAMS_KEYBOARD
, "streams-mouse", &sgi_mouse_fops
358 streamable_init (void)
360 printk ("streamable misc devices registered (keyb:%d, gfx:%d)\n",
361 SGI_STREAMS_KEYBOARD
, SGI_GFX_MINOR
);
363 misc_register (&dev_gfx
);
364 misc_register (&dev_input_keyboard
);
365 misc_register (&dev_input_mouse
);