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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * usema.c: software semaphore driver (see IRIX's usema(7M))
  3.  * written 1997 Mike Shaver (shaver@neon.ingenia.ca)
  4.  *         1997 Miguel de Icaza (miguel@kernel.org)
  5.  *
  6.  * This file contains the implementation of /dev/usemaclone,
  7.  * the devices used by IRIX's us* semaphore routines.
  8.  *
  9.  * /dev/usemaclone is used to create a new semaphore device, and then
  10.  * the semaphore is manipulated via ioctls.
  11.  *
  12.  * At least for the zero-contention case, lock set and unset as well
  13.  * as semaphore P and V are done in userland, which makes things a
  14.  * little bit better.  I suspect that the ioctls are used to register
  15.  * the process as blocking, etc.
  16.  *
  17.  * Much inspiration and structure stolen from Miguel's shmiq work.
  18.  *
  19.  * For more information:
  20.  * usema(7m), usinit(3p), usnewsema(3p)
  21.  * /usr/include/sys/usioctl.h 
  22.  *
  23.  */
  24. #include <linux/fs.h>
  25. #include <linux/miscdevice.h>
  26. #include <linux/sched.h>
  27. #include <linux/file.h>
  28. #include <linux/major.h>
  29. #include <linux/poll.h>
  30. #include <linux/string.h>
  31. #include <linux/dcache.h>
  32. #include <linux/mm.h>
  33. #include <linux/module.h>
  34. #include <linux/slab.h>
  35. #include <linux/smp_lock.h>
  36. #include "usema.h"
  37. #include <asm/usioctl.h>
  38. #include <asm/mman.h>
  39. #include <asm/uaccess.h>
  40. struct irix_usema {
  41. struct file *filp;
  42. wait_queue_head_t proc_list;
  43. };
  44. static int
  45. sgi_usema_attach (usattach_t * attach, struct irix_usema *usema)
  46. {
  47. int newfd;
  48. newfd = get_unused_fd();
  49. if (newfd < 0)
  50. return newfd;
  51. get_file(usema->filp);
  52. fd_install(newfd, usema->filp);
  53. /* Is that it? */
  54. printk("UIOCATTACHSEMA: new usema fd is %d", newfd);
  55. return newfd;
  56. }
  57. static int
  58. sgi_usemaclone_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
  59. unsigned long arg)
  60. {
  61. struct irix_usema *usema = file->private_data;
  62. int retval;
  63. printk("[%s:%d] wants ioctl 0x%xd (arg 0x%lx)",
  64.        current->comm, current->pid, cmd, arg);
  65. switch(cmd) {
  66. case UIOCATTACHSEMA: {
  67. /* They pass us information about the semaphore to
  68.    which they wish to be attached, and we create&return
  69.    a new fd corresponding to the appropriate semaphore.
  70.    */
  71. usattach_t *attach = (usattach_t *)arg;
  72. retval = verify_area(VERIFY_READ, attach, sizeof(usattach_t));
  73. if (retval) {
  74. printk("[%s:%d] sgi_usema_ioctl(UIOCATTACHSEMA): "
  75.        "verify_area failure",
  76.        current->comm, current->pid);
  77. return retval;
  78. }
  79. if (usema == 0)
  80. return -EINVAL;
  81. printk("UIOCATTACHSEMA: attaching usema %p to process %dn",
  82.        usema, current->pid);
  83. /* XXX what is attach->us_handle for? */
  84. return sgi_usema_attach(attach, usema);
  85. break;
  86. }
  87. case UIOCABLOCK: /* XXX make `async' */
  88. case UIOCNOIBLOCK: /* XXX maybe? */
  89. case UIOCBLOCK: {
  90. /* Block this process on the semaphore */
  91. usattach_t *attach = (usattach_t *)arg;
  92. retval = verify_area(VERIFY_READ, attach, sizeof(usattach_t));
  93. if (retval) {
  94. printk("[%s:%d] sgi_usema_ioctl(UIOC*BLOCK): "
  95.        "verify_area failure",
  96.        current->comm, current->pid);
  97. return retval;
  98. }
  99. printk("UIOC*BLOCK: putting process %d to sleep on usema %p",
  100.        current->pid, usema);
  101. if (cmd == UIOCNOIBLOCK)
  102. interruptible_sleep_on(&usema->proc_list);
  103. else
  104. sleep_on(&usema->proc_list);
  105. return 0;
  106. }
  107. case UIOCAUNBLOCK: /* XXX make `async' */
  108. case UIOCUNBLOCK: {
  109. /* Wake up all process waiting on this semaphore */
  110. usattach_t *attach = (usattach_t *)arg;
  111. retval = verify_area(VERIFY_READ, attach, sizeof(usattach_t));
  112. if (retval) {
  113. printk("[%s:%d] sgi_usema_ioctl(UIOC*BLOCK): "
  114.        "verify_area failure",
  115.        current->comm, current->pid);
  116. return retval;
  117. }
  118. printk("[%s:%d] releasing usema %p",
  119.        current->comm, current->pid, usema);
  120. wake_up(&usema->proc_list);
  121. return 0;
  122. }
  123. }
  124. return -ENOSYS;
  125. }
  126. static unsigned int
  127. sgi_usemaclone_poll(struct file *filp, poll_table *wait)
  128. {
  129. struct irix_usema *usema = filp->private_data;
  130. printk("[%s:%d] wants to poll usema %p",
  131.        current->comm, current->pid, usema);
  132. return 0;
  133. }
  134. static int
  135. sgi_usemaclone_open(struct inode *inode, struct file *filp)
  136. {
  137. struct irix_usema *usema;
  138. usema = kmalloc (sizeof (struct irix_usema), GFP_KERNEL);
  139. if (!usema)
  140. return -ENOMEM;
  141. usema->filp        = filp;
  142. init_waitqueue_head(&usema->proc_list);
  143. filp->private_data = usema;
  144. return 0;
  145. }
  146. struct file_operations sgi_usemaclone_fops = {
  147. poll: sgi_usemaclone_poll,
  148. ioctl: sgi_usemaclone_ioctl,
  149. open: sgi_usemaclone_open,
  150. };
  151. static struct miscdevice dev_usemaclone = {
  152. SGI_USEMACLONE, "usemaclone", &sgi_usemaclone_fops
  153. };
  154. void
  155. usema_init(void)
  156. {
  157. printk("usemaclone misc device registered (minor: %d)n",
  158.        SGI_USEMACLONE);
  159. misc_register(&dev_usemaclone);
  160. }
  161. EXPORT_SYMBOL(usema_init);