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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * linux/arch/sh/kernel/sys_sh.c
  3.  *
  4.  * This file contains various random system calls that
  5.  * have a non-standard calling sequence on the Linux/SuperH
  6.  * platform.
  7.  *
  8.  * Taken from i386 version.
  9.  */
  10. #include <linux/errno.h>
  11. #include <linux/sched.h>
  12. #include <linux/mm.h>
  13. #include <linux/smp.h>
  14. #include <linux/smp_lock.h>
  15. #include <linux/sem.h>
  16. #include <linux/msg.h>
  17. #include <linux/shm.h>
  18. #include <linux/stat.h>
  19. #include <linux/mman.h>
  20. #include <linux/file.h>
  21. #include <linux/utsname.h>
  22. #include <asm/uaccess.h>
  23. #include <asm/ipc.h>
  24. /*
  25.  * sys_pipe() is the normal C calling standard for creating
  26.  * a pipe. It's not the way Unix traditionally does this, though.
  27.  */
  28. asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
  29. unsigned long r6, unsigned long r7,
  30. struct pt_regs regs)
  31. {
  32. int fd[2];
  33. int error;
  34. error = do_pipe(fd);
  35. if (!error) {
  36. regs.regs[1] = fd[1];
  37. return fd[0];
  38. }
  39. return error;
  40. }
  41. #if defined(__SH4__)
  42. /*
  43.  * To avoid cache alias, we map the shard page with same color.
  44.  */
  45. #define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(SHMLBA-1))
  46. unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
  47. unsigned long len, unsigned long pgoff, unsigned long flags)
  48. {
  49. struct vm_area_struct *vma;
  50. if (flags & MAP_FIXED) {
  51. /* We do not accept a shared mapping if it would violate
  52.  * cache aliasing constraints.
  53.  */
  54. if ((flags & MAP_SHARED) && (addr & (SHMLBA - 1)))
  55. return -EINVAL;
  56. return addr;
  57. }
  58. if (len > TASK_SIZE)
  59. return -ENOMEM;
  60. if (!addr)
  61. addr = TASK_UNMAPPED_BASE;
  62. if (flags & MAP_PRIVATE)
  63. addr = PAGE_ALIGN(addr);
  64. else
  65. addr = COLOUR_ALIGN(addr);
  66. for (vma = find_vma(current->mm, addr); ; vma = vma->vm_next) {
  67. /* At this point:  (!vma || addr < vma->vm_end). */
  68. if (TASK_SIZE - len < addr)
  69. return -ENOMEM;
  70. if (!vma || addr + len <= vma->vm_start)
  71. return addr;
  72. addr = vma->vm_end;
  73. if (!(flags & MAP_PRIVATE))
  74. addr = COLOUR_ALIGN(addr);
  75. }
  76. }
  77. #endif
  78. static inline long
  79. do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 
  80.  unsigned long flags, int fd, unsigned long pgoff)
  81. {
  82. int error = -EBADF;
  83. struct file *file = NULL;
  84. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  85. if (!(flags & MAP_ANONYMOUS)) {
  86. file = fget(fd);
  87. if (!file)
  88. goto out;
  89. }
  90. down_write(&current->mm->mmap_sem);
  91. error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  92. up_write(&current->mm->mmap_sem);
  93. if (file)
  94. fput(file);
  95. out:
  96. return error;
  97. }
  98. asmlinkage int old_mmap(unsigned long addr, unsigned long len,
  99. unsigned long prot, unsigned long flags,
  100. int fd, unsigned long off)
  101. {
  102. if (off & ~PAGE_MASK)
  103. return -EINVAL;
  104. return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
  105. }
  106. asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
  107. unsigned long prot, unsigned long flags,
  108. unsigned long fd, unsigned long pgoff)
  109. {
  110. return do_mmap2(addr, len, prot, flags, fd, pgoff);
  111. }
  112. /*
  113.  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  114.  *
  115.  * This is really horribly ugly.
  116.  */
  117. asmlinkage int sys_ipc(uint call, int first, int second,
  118.        int third, void *ptr, long fifth)
  119. {
  120. int version, ret;
  121. version = call >> 16; /* hack for backward compatibility */
  122. call &= 0xffff;
  123. if (call <= SEMCTL)
  124. switch (call) {
  125. case SEMOP:
  126. return sys_semop (first, (struct sembuf *)ptr, second);
  127. case SEMGET:
  128. return sys_semget (first, second, third);
  129. case SEMCTL: {
  130. union semun fourth;
  131. if (!ptr)
  132. return -EINVAL;
  133. if (get_user(fourth.__pad, (void **) ptr))
  134. return -EFAULT;
  135. return sys_semctl (first, second, third, fourth);
  136. }
  137. default:
  138. return -EINVAL;
  139. }
  140. if (call <= MSGCTL) 
  141. switch (call) {
  142. case MSGSND:
  143. return sys_msgsnd (first, (struct msgbuf *) ptr, 
  144.   second, third);
  145. case MSGRCV:
  146. switch (version) {
  147. case 0: {
  148. struct ipc_kludge tmp;
  149. if (!ptr)
  150. return -EINVAL;
  151. if (copy_from_user(&tmp,
  152.    (struct ipc_kludge *) ptr, 
  153.    sizeof (tmp)))
  154. return -EFAULT;
  155. return sys_msgrcv (first, tmp.msgp, second,
  156.    tmp.msgtyp, third);
  157. }
  158. default:
  159. return sys_msgrcv (first,
  160.    (struct msgbuf *) ptr,
  161.    second, fifth, third);
  162. }
  163. case MSGGET:
  164. return sys_msgget ((key_t) first, second);
  165. case MSGCTL:
  166. return sys_msgctl (first, second,
  167.    (struct msqid_ds *) ptr);
  168. default:
  169. return -EINVAL;
  170. }
  171. if (call <= SHMCTL) 
  172. switch (call) {
  173. case SHMAT:
  174. switch (version) {
  175. default: {
  176. ulong raddr;
  177. ret = sys_shmat (first, (char *) ptr,
  178.  second, &raddr);
  179. if (ret)
  180. return ret;
  181. return put_user (raddr, (ulong *) third);
  182. }
  183. case 1: /* iBCS2 emulator entry point */
  184. if (!segment_eq(get_fs(), get_ds()))
  185. return -EINVAL;
  186. return sys_shmat (first, (char *) ptr,
  187.   second, (ulong *) third);
  188. }
  189. case SHMDT: 
  190. return sys_shmdt ((char *)ptr);
  191. case SHMGET:
  192. return sys_shmget (first, second, third);
  193. case SHMCTL:
  194. return sys_shmctl (first, second,
  195.    (struct shmid_ds *) ptr);
  196. default:
  197. return -EINVAL;
  198. }
  199. return -EINVAL;
  200. }
  201. asmlinkage int sys_uname(struct old_utsname * name)
  202. {
  203. int err;
  204. if (!name)
  205. return -EFAULT;
  206. down_read(&uts_sem);
  207. err=copy_to_user(name, &system_utsname, sizeof (*name));
  208. up_read(&uts_sem);
  209. return err?-EFAULT:0;
  210. }
  211. asmlinkage int sys_pause(void)
  212. {
  213. current->state = TASK_INTERRUPTIBLE;
  214. schedule();
  215. return -ERESTARTNOHAND;
  216. }