Import 2.1.118
[davej-history.git] / drivers / sgi / char / streamable.c
bloba1f4b07b215f7e743ab17d81d18ece078b0af89e
1 /*
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.
8 */
10 #include <linux/fs.h>
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>
18 #include "graphics.h"
21 extern struct kbd_struct kbd_table [MAX_NR_CONSOLES];
23 /* console number where forwarding is enabled */
24 int forward_chars;
26 /* To which shmiq this keyboard is assigned */
27 int kbd_assigned_device;
29 /* previous kbd_mode for the forward_chars terminal */
30 int kbd_prev_mode;
32 /* Fetchs the strioctl information from user space for I_STR ioctls */
33 int
34 get_sioc (struct strioctl *sioc, unsigned long arg)
36 int v;
38 v = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct strioctl));
39 if (v)
40 return v;
41 if (copy_from_user (sioc, (void *) arg, sizeof (struct strioctl)))
42 return -EFAULT;
44 v = verify_area (VERIFY_WRITE, (void *) sioc->ic_dp, sioc->ic_len);
45 if (v)
46 return v;
47 return 0;
50 /* /dev/gfx device */
51 static int
52 sgi_gfx_open (struct inode *inode, struct file *file)
54 printk ("GFX: Opened by %d\n", current->pid);
55 return 0;
58 static int
59 sgi_gfx_close (struct inode *inode, struct file *file)
61 printk ("GFX: Closed by %d\n", current->pid);
62 return 0;
65 static int
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);
69 return 0;
70 return -EINVAL;
73 struct file_operations sgi_gfx_fops = {
74 NULL, /* llseek */
75 NULL, /* read */
76 NULL, /* write */
77 NULL, /* readdir */
78 NULL, /* poll */
79 sgi_gfx_ioctl, /* ioctl */
80 NULL, /* mmap */
81 sgi_gfx_open, /* open */
82 NULL, /* flush */
83 sgi_gfx_close, /* release */
84 NULL, /* fsync */
85 NULL, /* check_media_change */
86 NULL, /* revalidate */
87 NULL /* lock */
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 */
98 240, /* nButtons */
99 0, /* nValuators */
100 0, /* nLEDs */
101 0, /* nStrDpys */
102 0, /* nIntDpys */
103 0, /* nBells */
104 IDEV_HAS_KEYMAP | IDEV_HAS_PCKBD
107 static int
108 sgi_kbd_sioc (idevInfo *dinfo, int cmd, int size, char *data, int *found)
110 *found = 1;
112 switch (cmd){
114 case IDEVINITDEVICE:
115 return 0;
117 case IDEVGETDEVICEDESC:
118 if (size >= sizeof (idevDesc)){
119 if (copy_to_user (data, &sgi_kbd_desc, sizeof (sgi_kbd_desc)))
120 return -EFAULT;
121 return 0;
123 return -EINVAL;
125 case IDEVGETKEYMAPDESC:
126 if (size >= sizeof (idevKeymapDesc)){
127 if (copy_to_user (data, "US", 3))
128 return -EFAULT;
129 return 0;
131 return -EINVAL;
133 *found = 0;
134 return -EINVAL;
137 static int
138 sgi_keyb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
140 struct strioctl sioc;
141 int f, v;
143 /* IRIX calls I_PUSH on the opened device, go figure */
144 if (cmd == I_PUSH)
145 return 0;
147 if (cmd == I_STR){
148 v = get_sioc (&sioc, arg);
149 if (v)
150 return v;
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;
170 forward_chars = 0;
171 } else
172 return -EINVAL;
173 return 0;
176 void
177 kbd_forward_char (int ch)
179 static struct shmqevent ev;
181 ev.data.flags = (ch & 0200) ? 0 : 1;
182 ev.data.which = ch;
183 ev.data.device = kbd_assigned_device + 0x11;
184 shmiq_push_event (&ev);
187 static int
188 sgi_keyb_open (struct inode *inode, struct file *file)
190 /* Nothing, but required by the misc driver */
191 return 0;
194 struct file_operations sgi_keyb_fops = {
195 NULL, /* llseek */
196 NULL, /* read */
197 NULL, /* write */
198 NULL, /* readdir */
199 NULL, /* poll */
200 sgi_keyb_ioctl, /* ioctl */
201 NULL, /* mmap */
202 sgi_keyb_open, /* open */
203 NULL, /* flush */
204 NULL, /* release */
205 NULL, /* fsync */
206 NULL, /* check_media_change */
207 NULL, /* revalidate */
208 NULL /* lock */
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 */
220 3, /* nButtons */
221 MOUSE_VALUATORS, /* nValuators */
222 0, /* nLEDs */
223 0, /* nStrDpys */
224 0, /* nIntDpys */
225 0, /* nBells */
226 0 /* flags */
229 static idevValuatorDesc mouse_default_valuator = {
230 200, /* hwMinRes */
231 200, /* hwMaxRes */
232 0, /* hwMinVal */
233 65000, /* hwMaxVal */
234 IDEV_EITHER, /* possibleModes */
235 IDEV_ABSOLUTE, /* default mode */
236 200, /* resolution */
237 0, /* minVal */
238 65000 /* maxVal */
241 static int mouse_opened;
242 static idevValuatorDesc mouse_valuators [MOUSE_VALUATORS];
245 sgi_mouse_open (struct inode *inode, struct file *file)
247 int i;
249 if (mouse_opened)
250 return -EBUSY;
252 mouse_opened = 1;
253 for (i = 0; i < MOUSE_VALUATORS; i++)
254 mouse_valuators [i] = mouse_default_valuator;
255 return 0;
258 static int
259 sgi_mouse_close (struct inode *inode, struct file *filp)
261 mouse_opened = 0;
262 return 0;
265 static int
266 sgi_mouse_sioc (idevInfo *dinfo, int cmd, int size, char *data, int *found)
268 *found = 1;
270 switch (cmd){
271 case IDEVINITDEVICE:
272 return 0;
274 case IDEVGETDEVICEDESC:
275 if (size >= sizeof (idevDesc)){
276 if (copy_to_user (data, &sgi_mouse_desc, sizeof (sgi_mouse_desc)))
277 return -EFAULT;
278 return 0;
280 return -EINVAL;
282 case IDEVGETVALUATORDESC: {
283 idevGetSetValDesc request, *ureq = (idevGetSetValDesc *) data;
285 if (size < sizeof (idevGetSetValDesc))
286 return -EINVAL;
288 if (copy_from_user (&request, data, sizeof (request)))
289 return -EFAULT;
290 if (request.valNum >= MOUSE_VALUATORS)
291 return -EINVAL;
292 if (copy_to_user ((void *)&ureq->desc,
293 (void *)&mouse_valuators [request.valNum],
294 sizeof (idevValuatorDesc)))
295 return -EFAULT;
296 return 0;
299 *found = 0;
300 return -EINVAL;
303 static int
304 sgi_mouse_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
306 struct strioctl sioc;
307 int f, v;
309 /* IRIX calls I_PUSH on the opened device, go figure */
310 switch (cmd){
311 case I_PUSH:
312 return 0;
314 case I_STR:
315 v = get_sioc (&sioc, arg);
316 if (v)
317 return v;
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);
328 case SHMIQ_ON:
329 case SHMIQ_OFF:
330 return 0;
332 return 0;
335 struct file_operations sgi_mouse_fops = {
336 NULL, /* llseek */
337 NULL, /* read */
338 NULL, /* write */
339 NULL, /* readdir */
340 NULL, /* poll */
341 sgi_mouse_ioctl, /* ioctl */
342 NULL, /* mmap */
343 sgi_mouse_open, /* open */
344 NULL, /* flush */
345 sgi_mouse_close, /* release */
346 NULL, /* fsync */
347 NULL, /* check_media_change */
348 NULL, /* revalidate */
349 NULL /* lock */
352 /* /dev/input/mouse */
353 static struct miscdevice dev_input_mouse = {
354 SGI_STREAMS_KEYBOARD, "streams-mouse", &sgi_mouse_fops
357 void
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);