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