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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: sys_cris.c,v 1.10 2001/06/27 21:16:15 hp Exp $
  2.  *
  3.  * linux/arch/cris/kernel/sys_cris.c
  4.  *
  5.  * This file contains various random system calls that
  6.  * have a non-standard calling sequence on some platforms.
  7.  * Since we don't have to do any backwards compatibility, our
  8.  * versions are done in the most "normal" way possible.
  9.  *
  10.  */
  11. #include <linux/errno.h>
  12. #include <linux/sched.h>
  13. #include <linux/mm.h>
  14. #include <linux/smp.h>
  15. #include <linux/smp_lock.h>
  16. #include <linux/sem.h>
  17. #include <linux/msg.h>
  18. #include <linux/shm.h>
  19. #include <linux/stat.h>
  20. #include <linux/mman.h>
  21. #include <linux/file.h>
  22. #include <asm/uaccess.h>
  23. #include <asm/ipc.h>
  24. #include <asm/segment.h>
  25. /*
  26.  * sys_pipe() is the normal C calling standard for creating
  27.  * a pipe. It's not the way Unix traditionally does this, though.
  28.  */
  29. asmlinkage int sys_pipe(unsigned long * fildes)
  30. {
  31.         int fd[2];
  32.         int error;
  33.         lock_kernel();
  34.         error = do_pipe(fd);
  35.         unlock_kernel();
  36.         if (!error) {
  37.                 if (copy_to_user(fildes, fd, 2*sizeof(int)))
  38.                         error = -EFAULT;
  39.         }
  40.         return error;
  41. }
  42. /* common code for old and new mmaps */
  43. static inline long
  44. do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
  45.         unsigned long flags, unsigned long fd, unsigned long pgoff)
  46. {
  47.         int error = -EBADF;
  48.         struct file * file = NULL;
  49.         flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  50.         if (!(flags & MAP_ANONYMOUS)) {
  51.                 file = fget(fd);
  52.                 if (!file)
  53.                         goto out;
  54.         }
  55.         down_write(&current->mm->mmap_sem);
  56.         error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  57.         up_write(&current->mm->mmap_sem);
  58.         if (file)
  59.                 fput(file);
  60. out:
  61.         return error;
  62. }
  63. asmlinkage unsigned long old_mmap(unsigned long *args)
  64. {        
  65. unsigned long buffer[6];
  66. int err = -EFAULT;
  67. if (copy_from_user(&buffer, args, sizeof(buffer)))
  68. goto out;
  69. err = -EINVAL;
  70. if (buffer[5] & ~PAGE_MASK) /* verify that offset is on page boundary */
  71. goto out;
  72. err = do_mmap2(buffer[0], buffer[1], buffer[2], buffer[3],
  73.                        buffer[4], buffer[5] >> PAGE_SHIFT);
  74. out:
  75. return err;
  76. }
  77. asmlinkage long
  78. sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
  79.           unsigned long flags, unsigned long fd, unsigned long pgoff)
  80. {
  81.         return do_mmap2(addr, len, prot, flags, fd, pgoff);
  82. }
  83. /*
  84.  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  85.  *
  86.  * This is really horribly ugly. (same as arch/i386)
  87.  */
  88. asmlinkage int sys_ipc (uint call, int first, int second,
  89. int third, void *ptr, long fifth)
  90. {
  91. int version, ret;
  92. version = call >> 16; /* hack for backward compatibility */
  93. call &= 0xffff;
  94. switch (call) {
  95. case SEMOP:
  96. return sys_semop (first, (struct sembuf *)ptr, second);
  97. case SEMGET:
  98. return sys_semget (first, second, third);
  99. case SEMCTL: {
  100. union semun fourth;
  101. if (!ptr)
  102. return -EINVAL;
  103. if (get_user(fourth.__pad, (void **) ptr))
  104. return -EFAULT;
  105. return sys_semctl (first, second, third, fourth);
  106. }
  107. case MSGSND:
  108. return sys_msgsnd (first, (struct msgbuf *) ptr, 
  109.    second, third);
  110. case MSGRCV:
  111. switch (version) {
  112. case 0: {
  113. struct ipc_kludge tmp;
  114. if (!ptr)
  115. return -EINVAL;
  116. if (copy_from_user(&tmp,
  117.    (struct ipc_kludge *) ptr, 
  118.    sizeof (tmp)))
  119. return -EFAULT;
  120. return sys_msgrcv (first, tmp.msgp, second,
  121.    tmp.msgtyp, third);
  122. }
  123. default:
  124. return sys_msgrcv (first,
  125.    (struct msgbuf *) ptr,
  126.    second, fifth, third);
  127. }
  128. case MSGGET:
  129. return sys_msgget ((key_t) first, second);
  130. case MSGCTL:
  131. return sys_msgctl (first, second, (struct msqid_ds *) ptr);
  132. case SHMAT: {
  133.                 ulong raddr;
  134.                 ret = sys_shmat (first, (char *) ptr, second, &raddr);
  135.                 if (ret)
  136.                         return ret;
  137.                 return put_user (raddr, (ulong *) third);
  138.         }
  139. case SHMDT: 
  140. return sys_shmdt ((char *)ptr);
  141. case SHMGET:
  142. return sys_shmget (first, second, third);
  143. case SHMCTL:
  144. return sys_shmctl (first, second,
  145.    (struct shmid_ds *) ptr);
  146. default:
  147. return -EINVAL;
  148. }
  149. }
  150. /* apparently this is legacy - if we don't need this in Linux/CRIS we can remove it. */
  151. asmlinkage int sys_pause(void)
  152. {
  153.         current->state = TASK_INTERRUPTIBLE;
  154.         schedule();
  155.         return -ERESTARTNOHAND;
  156. }