1
2#ifndef _S390_RWSEM_H
3#define _S390_RWSEM_H
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#ifndef _LINUX_RWSEM_H
40#error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead"
41#endif
42
43#define RWSEM_UNLOCKED_VALUE 0x0000000000000000L
44#define RWSEM_ACTIVE_BIAS 0x0000000000000001L
45#define RWSEM_ACTIVE_MASK 0x00000000ffffffffL
46#define RWSEM_WAITING_BIAS (-0x0000000100000000L)
47#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
48#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
49
50
51
52
53static inline void __down_read(struct rw_semaphore *sem)
54{
55 signed long old, new;
56
57 asm volatile(
58 " lg %0,%2\n"
59 "0: lgr %1,%0\n"
60 " aghi %1,%4\n"
61 " csg %0,%1,%2\n"
62 " jl 0b"
63 : "=&d" (old), "=&d" (new), "=Q" (sem->count)
64 : "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS)
65 : "cc", "memory");
66 if (old < 0)
67 rwsem_down_read_failed(sem);
68}
69
70
71
72
73static inline int __down_read_trylock(struct rw_semaphore *sem)
74{
75 signed long old, new;
76
77 asm volatile(
78 " lg %0,%2\n"
79 "0: ltgr %1,%0\n"
80 " jm 1f\n"
81 " aghi %1,%4\n"
82 " csg %0,%1,%2\n"
83 " jl 0b\n"
84 "1:"
85 : "=&d" (old), "=&d" (new), "=Q" (sem->count)
86 : "Q" (sem->count), "i" (RWSEM_ACTIVE_READ_BIAS)
87 : "cc", "memory");
88 return old >= 0 ? 1 : 0;
89}
90
91
92
93
94static inline long ___down_write(struct rw_semaphore *sem)
95{
96 signed long old, new, tmp;
97
98 tmp = RWSEM_ACTIVE_WRITE_BIAS;
99 asm volatile(
100 " lg %0,%2\n"
101 "0: lgr %1,%0\n"
102 " ag %1,%4\n"
103 " csg %0,%1,%2\n"
104 " jl 0b"
105 : "=&d" (old), "=&d" (new), "=Q" (sem->count)
106 : "Q" (sem->count), "m" (tmp)
107 : "cc", "memory");
108
109 return old;
110}
111
112static inline void __down_write(struct rw_semaphore *sem)
113{
114 if (___down_write(sem))
115 rwsem_down_write_failed(sem);
116}
117
118static inline int __down_write_killable(struct rw_semaphore *sem)
119{
120 if (___down_write(sem))
121 if (IS_ERR(rwsem_down_write_failed_killable(sem)))
122 return -EINTR;
123
124 return 0;
125}
126
127
128
129
130static inline int __down_write_trylock(struct rw_semaphore *sem)
131{
132 signed long old;
133
134 asm volatile(
135 " lg %0,%1\n"
136 "0: ltgr %0,%0\n"
137 " jnz 1f\n"
138 " csg %0,%3,%1\n"
139 " jl 0b\n"
140 "1:"
141 : "=&d" (old), "=Q" (sem->count)
142 : "Q" (sem->count), "d" (RWSEM_ACTIVE_WRITE_BIAS)
143 : "cc", "memory");
144 return (old == RWSEM_UNLOCKED_VALUE) ? 1 : 0;
145}
146
147
148
149
150static inline void __up_read(struct rw_semaphore *sem)
151{
152 signed long old, new;
153
154 asm volatile(
155 " lg %0,%2\n"
156 "0: lgr %1,%0\n"
157 " aghi %1,%4\n"
158 " csg %0,%1,%2\n"
159 " jl 0b"
160 : "=&d" (old), "=&d" (new), "=Q" (sem->count)
161 : "Q" (sem->count), "i" (-RWSEM_ACTIVE_READ_BIAS)
162 : "cc", "memory");
163 if (new < 0)
164 if ((new & RWSEM_ACTIVE_MASK) == 0)
165 rwsem_wake(sem);
166}
167
168
169
170
171static inline void __up_write(struct rw_semaphore *sem)
172{
173 signed long old, new, tmp;
174
175 tmp = -RWSEM_ACTIVE_WRITE_BIAS;
176 asm volatile(
177 " lg %0,%2\n"
178 "0: lgr %1,%0\n"
179 " ag %1,%4\n"
180 " csg %0,%1,%2\n"
181 " jl 0b"
182 : "=&d" (old), "=&d" (new), "=Q" (sem->count)
183 : "Q" (sem->count), "m" (tmp)
184 : "cc", "memory");
185 if (new < 0)
186 if ((new & RWSEM_ACTIVE_MASK) == 0)
187 rwsem_wake(sem);
188}
189
190
191
192
193static inline void __downgrade_write(struct rw_semaphore *sem)
194{
195 signed long old, new, tmp;
196
197 tmp = -RWSEM_WAITING_BIAS;
198 asm volatile(
199 " lg %0,%2\n"
200 "0: lgr %1,%0\n"
201 " ag %1,%4\n"
202 " csg %0,%1,%2\n"
203 " jl 0b"
204 : "=&d" (old), "=&d" (new), "=Q" (sem->count)
205 : "Q" (sem->count), "m" (tmp)
206 : "cc", "memory");
207 if (new > 1)
208 rwsem_downgrade_wake(sem);
209}
210
211#endif
212