streamable.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:7k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: streamable.c,v 1.10 2000/02/05 06:47:30 ralf Exp $
  2.  *
  3.  * streamable.c: streamable devices. /dev/gfx
  4.  * (C) 1997 Miguel de Icaza (miguel@nuclecu.unam.mx)
  5.  *
  6.  * Major 10 is the streams clone device.  The IRIX Xsgi server just
  7.  * opens /dev/gfx and closes it inmediately.
  8.  *
  9.  */
  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 <linux/smp_lock.h>
  16. #include <asm/uaccess.h>
  17. #include <asm/shmiq.h>
  18. #include <asm/keyboard.h>
  19. #include "graphics.h"
  20. extern struct kbd_struct kbd_table [MAX_NR_CONSOLES];
  21. /* console number where forwarding is enabled */
  22. int forward_chars;
  23. /* To which shmiq this keyboard is assigned */
  24. int kbd_assigned_device;
  25. /* previous kbd_mode for the forward_chars terminal */
  26. int kbd_prev_mode;
  27. /* Fetchs the strioctl information from user space for I_STR ioctls */
  28. int
  29. get_sioc (struct strioctl *sioc, unsigned long arg)
  30. {
  31. int v;
  32. v = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct strioctl));
  33. if (v)
  34. return v;
  35. if (copy_from_user (sioc, (void *) arg, sizeof (struct strioctl)))
  36. return -EFAULT;
  37. v = verify_area (VERIFY_WRITE, (void *) sioc->ic_dp, sioc->ic_len);
  38. if (v)
  39. return v;
  40. return 0;
  41. }
  42. /* /dev/gfx device */
  43. static int
  44. sgi_gfx_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  45. {
  46. printk ("GFX: ioctl 0x%x %ld calledn", cmd, arg);
  47. return 0;
  48. return -EINVAL;
  49. }
  50. struct file_operations sgi_gfx_fops = {
  51. ioctl: sgi_gfx_ioctl,
  52. };
  53.  
  54. static struct miscdevice dev_gfx = {
  55. SGI_GFX_MINOR, "sgi-gfx", &sgi_gfx_fops
  56. };
  57. /* /dev/input/keyboard streams device */
  58. static idevDesc sgi_kbd_desc = {
  59.         "keyboard",             /* devName */
  60.         "KEYBOARD",             /* devType */
  61.         240,                    /* nButtons */
  62.         0,                      /* nValuators */
  63.         0,                      /* nLEDs */
  64.         0,                      /* nStrDpys */
  65.         0,                      /* nIntDpys */
  66.         0,                      /* nBells */
  67. IDEV_HAS_KEYMAP | IDEV_HAS_PCKBD
  68. };
  69. static int
  70. sgi_kbd_sioc (idevInfo *dinfo, int cmd, int size, char *data, int *found)
  71. {
  72. *found = 1;
  73. switch (cmd){
  74. case IDEVINITDEVICE:
  75. return 0;
  76. case IDEVGETDEVICEDESC:
  77. if (size >= sizeof (idevDesc)){
  78. if (copy_to_user (data, &sgi_kbd_desc, sizeof (sgi_kbd_desc)))
  79. return -EFAULT;
  80. return 0;
  81. }
  82. return -EINVAL;
  83. case IDEVGETKEYMAPDESC:
  84. if (size >= sizeof (idevKeymapDesc)){
  85. if (copy_to_user (data, "US", 3))
  86. return -EFAULT;
  87. return 0;
  88. }
  89. return -EINVAL;
  90. }
  91. *found = 0;
  92. return -EINVAL;
  93. }
  94. static int
  95. sgi_keyb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  96. {
  97. struct strioctl sioc;
  98. int    f, v;
  99. /* IRIX calls I_PUSH on the opened device, go figure */
  100. if (cmd == I_PUSH)
  101. return 0;
  102. if (cmd == I_STR){
  103. v = get_sioc (&sioc, arg);
  104. if (v)
  105. return v;
  106. /* Why like this?  Because this is a sample piece of code
  107.  * that can be copied into other drivers and shows how to
  108.  * call a stock IRIX xxx_wioctl routine
  109.  *
  110.  * The NULL is supposed to be a idevInfo, right now we
  111.  * do not support this in our kernel.  
  112.  */
  113. return sgi_kbd_sioc (NULL, sioc.ic_cmd, sioc.ic_len, sioc.ic_dp, &f);
  114. }
  115. if (cmd == SHMIQ_ON){
  116. kbd_assigned_device = arg;
  117. forward_chars = fg_console + 1;
  118. kbd_prev_mode = kbd_table [fg_console].kbdmode;
  119.         kbd_table [fg_console].kbdmode = VC_RAW;
  120. } else if (cmd == SHMIQ_OFF && forward_chars){
  121. kbd_table [forward_chars-1].kbdmode = kbd_prev_mode;
  122. forward_chars = 0;
  123. } else
  124. return -EINVAL;
  125. return 0;
  126. }
  127. void
  128. kbd_forward_char (int ch)
  129. {
  130. static struct shmqevent ev;
  131. ev.data.flags  = (ch & 0200) ? 0 : 1;
  132. ev.data.which  = ch;
  133. ev.data.device = kbd_assigned_device + 0x11;
  134. shmiq_push_event (&ev);
  135. }
  136. static int
  137. sgi_keyb_open (struct inode *inode, struct file *file)
  138. {
  139. /* Nothing, but required by the misc driver */
  140. return 0;
  141. }
  142. struct file_operations sgi_keyb_fops = {
  143. ioctl: sgi_keyb_ioctl,
  144. open: sgi_keyb_open,
  145. };
  146. static struct miscdevice dev_input_keyboard = {
  147. SGI_STREAMS_KEYBOARD, "streams-keyboard", &sgi_keyb_fops
  148. };
  149. /* /dev/input/mouse streams device */
  150. #define MOUSE_VALUATORS 2
  151. static idevDesc sgi_mouse_desc = {
  152.         "mouse",                /* devName */
  153.         "MOUSE",                /* devType */
  154.         3,                      /* nButtons */
  155.         MOUSE_VALUATORS, /* nValuators */
  156.         0,                      /* nLEDs */
  157.         0,                      /* nStrDpys */
  158.         0,                      /* nIntDpys */
  159.         0,                      /* nBells */
  160. 0 /* flags */
  161. };
  162. static idevValuatorDesc mouse_default_valuator = {
  163. 200, /* hwMinRes */
  164.         200, /* hwMaxRes */
  165.         0, /* hwMinVal */
  166.         65000, /* hwMaxVal */
  167.         IDEV_EITHER, /* possibleModes */
  168.         IDEV_ABSOLUTE, /* default mode */
  169.         200, /* resolution */
  170.         0, /* minVal */
  171.         65000 /* maxVal */
  172. };
  173. static int mouse_opened;
  174. static idevValuatorDesc mouse_valuators [MOUSE_VALUATORS];
  175. int
  176. sgi_mouse_open (struct inode *inode, struct file *file)
  177. {
  178. int i;
  179. if (mouse_opened)
  180. return -EBUSY;
  181. mouse_opened = 1;
  182. for (i = 0; i < MOUSE_VALUATORS; i++)
  183. mouse_valuators [i] = mouse_default_valuator;
  184. return 0;
  185. }
  186. static int
  187. sgi_mouse_close (struct inode *inode, struct file *filp)
  188. {
  189. lock_kernel();
  190. mouse_opened = 0;
  191. unlock_kernel();
  192. return 0;
  193. }
  194. static int
  195. sgi_mouse_sioc (idevInfo *dinfo, int cmd, int size, char *data, int *found)
  196. {
  197. *found = 1;
  198. switch (cmd){
  199. case IDEVINITDEVICE:
  200. return 0;
  201. case IDEVGETDEVICEDESC:
  202. if (size >= sizeof (idevDesc)){
  203. if (copy_to_user (data, &sgi_mouse_desc, sizeof (sgi_mouse_desc)))
  204. return -EFAULT;
  205. return 0;
  206. }
  207. return -EINVAL;
  208. case IDEVGETVALUATORDESC: {
  209. idevGetSetValDesc request, *ureq = (idevGetSetValDesc *) data;
  210. if (size < sizeof (idevGetSetValDesc))
  211. return -EINVAL;
  212. if (copy_from_user (&request, data, sizeof (request)))
  213. return -EFAULT;
  214. if (request.valNum >= MOUSE_VALUATORS)
  215. return -EINVAL;
  216. if (copy_to_user ((void *)&ureq->desc, 
  217.   (void *)&mouse_valuators [request.valNum],
  218.   sizeof (idevValuatorDesc)))
  219. return -EFAULT;
  220. return 0;
  221. }
  222. }
  223. *found = 0;
  224. return -EINVAL;
  225. }
  226. static int
  227. sgi_mouse_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  228. {
  229. struct strioctl sioc;
  230. int    f, v;
  231. /* IRIX calls I_PUSH on the opened device, go figure */
  232. switch (cmd){
  233. case I_PUSH:
  234. return 0;
  235. case I_STR:
  236. v = get_sioc (&sioc, arg);
  237. if (v)
  238. return v;
  239. /* Why like this?  Because this is a sample piece of code
  240.  * that can be copied into other drivers and shows how to
  241.  * call a stock IRIX xxx_wioctl routine
  242.  *
  243.  * The NULL is supposed to be a idevInfo, right now we
  244.  * do not support this in our kernel.  
  245.  */
  246. return sgi_mouse_sioc (NULL, sioc.ic_cmd, sioc.ic_len, sioc.ic_dp, &f);
  247. case SHMIQ_ON:
  248. case SHMIQ_OFF:
  249. return 0;
  250. }
  251. return 0;
  252. }
  253. struct file_operations sgi_mouse_fops = {
  254. ioctl: sgi_mouse_ioctl,
  255. open: sgi_mouse_open,
  256. release: sgi_mouse_close,
  257. };
  258. /* /dev/input/mouse */
  259. static struct miscdevice dev_input_mouse = {
  260. SGI_STREAMS_KEYBOARD, "streams-mouse", &sgi_mouse_fops
  261. };
  262. void
  263. streamable_init (void)
  264. {
  265. printk ("streamable misc devices registered (keyb:%d, gfx:%d)n",
  266. SGI_STREAMS_KEYBOARD, SGI_GFX_MINOR);
  267. misc_register (&dev_gfx);
  268. misc_register (&dev_input_keyboard);
  269. misc_register (&dev_input_mouse);
  270. }