Merge branch 'suspend' into release
[linux-2.6] / arch / ia64 / include / asm / syscall.h
1 /*
2  * Access to user system call parameters and results
3  *
4  * Copyright (C) 2008 Intel Corp.  Shaohua Li <shaohua.li@intel.com>
5  *
6  * This copyrighted material is made available to anyone wishing to use,
7  * modify, copy, or redistribute it subject to the terms and conditions
8  * of the GNU General Public License v.2.
9  *
10  * See asm-generic/syscall.h for descriptions of what we must do here.
11  */
12
13 #ifndef _ASM_SYSCALL_H
14 #define _ASM_SYSCALL_H  1
15
16 #include <linux/sched.h>
17 #include <linux/err.h>
18
19 static inline long syscall_get_nr(struct task_struct *task,
20                                   struct pt_regs *regs)
21 {
22         if ((long)regs->cr_ifs < 0) /* Not a syscall */
23                 return -1;
24
25 #ifdef CONFIG_IA32_SUPPORT
26         if (IS_IA32_PROCESS(regs))
27                 return regs->r1;
28 #endif
29
30         return regs->r15;
31 }
32
33 static inline void syscall_rollback(struct task_struct *task,
34                                     struct pt_regs *regs)
35 {
36 #ifdef CONFIG_IA32_SUPPORT
37         if (IS_IA32_PROCESS(regs))
38                 regs->r8 = regs->r1;
39 #endif
40
41         /* do nothing */
42 }
43
44 static inline long syscall_get_error(struct task_struct *task,
45                                      struct pt_regs *regs)
46 {
47 #ifdef CONFIG_IA32_SUPPORT
48         if (IS_IA32_PROCESS(regs))
49                 return regs->r8;
50 #endif
51
52         return regs->r10 == -1 ? regs->r8:0;
53 }
54
55 static inline long syscall_get_return_value(struct task_struct *task,
56                                             struct pt_regs *regs)
57 {
58         return regs->r8;
59 }
60
61 static inline void syscall_set_return_value(struct task_struct *task,
62                                             struct pt_regs *regs,
63                                             int error, long val)
64 {
65 #ifdef CONFIG_IA32_SUPPORT
66         if (IS_IA32_PROCESS(regs)) {
67                 regs->r8 = (long) error ? error : val;
68                 return;
69         }
70 #endif
71
72         if (error) {
73                 /* error < 0, but ia64 uses > 0 return value */
74                 regs->r8 = -error;
75                 regs->r10 = -1;
76         } else {
77                 regs->r8 = val;
78                 regs->r10 = 0;
79         }
80 }
81
82 extern void ia64_syscall_get_set_arguments(struct task_struct *task,
83         struct pt_regs *regs, unsigned int i, unsigned int n,
84         unsigned long *args, int rw);
85 static inline void syscall_get_arguments(struct task_struct *task,
86                                          struct pt_regs *regs,
87                                          unsigned int i, unsigned int n,
88                                          unsigned long *args)
89 {
90         BUG_ON(i + n > 6);
91
92 #ifdef CONFIG_IA32_SUPPORT
93         if (IS_IA32_PROCESS(regs)) {
94                 switch (i + n) {
95                 case 6:
96                         if (!n--) break;
97                         *args++ = regs->r13;
98                 case 5:
99                         if (!n--) break;
100                         *args++ = regs->r15;
101                 case 4:
102                         if (!n--) break;
103                         *args++ = regs->r14;
104                 case 3:
105                         if (!n--) break;
106                         *args++ = regs->r10;
107                 case 2:
108                         if (!n--) break;
109                         *args++ = regs->r9;
110                 case 1:
111                         if (!n--) break;
112                         *args++ = regs->r11;
113                 case 0:
114                         if (!n--) break;
115                 default:
116                         BUG();
117                         break;
118                 }
119
120                 return;
121         }
122 #endif
123         ia64_syscall_get_set_arguments(task, regs, i, n, args, 0);
124 }
125
126 static inline void syscall_set_arguments(struct task_struct *task,
127                                          struct pt_regs *regs,
128                                          unsigned int i, unsigned int n,
129                                          unsigned long *args)
130 {
131         BUG_ON(i + n > 6);
132
133 #ifdef CONFIG_IA32_SUPPORT
134         if (IS_IA32_PROCESS(regs)) {
135                 switch (i + n) {
136                 case 6:
137                         if (!n--) break;
138                         regs->r13 = *args++;
139                 case 5:
140                         if (!n--) break;
141                         regs->r15 = *args++;
142                 case 4:
143                         if (!n--) break;
144                         regs->r14 = *args++;
145                 case 3:
146                         if (!n--) break;
147                         regs->r10 = *args++;
148                 case 2:
149                         if (!n--) break;
150                         regs->r9 = *args++;
151                 case 1:
152                         if (!n--) break;
153                         regs->r11 = *args++;
154                 case 0:
155                         if (!n--) break;
156                 }
157
158                 return;
159         }
160 #endif
161         ia64_syscall_get_set_arguments(task, regs, i, n, args, 1);
162 }
163 #endif  /* _ASM_SYSCALL_H */