printf: Remove unused 'bprintf'
[drm/drm-misc.git] / drivers / s390 / cio / ioasm.c
blob5ff1e51cddf399dc431b9ad2b44d31df4f959fd3
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Channel subsystem I/O instructions.
4 */
6 #include <linux/export.h>
8 #include <asm/asm-extable.h>
9 #include <asm/chpid.h>
10 #include <asm/schid.h>
11 #include <asm/asm.h>
12 #include <asm/crw.h>
14 #include "ioasm.h"
15 #include "orb.h"
16 #include "cio.h"
17 #include "cio_inject.h"
19 static inline int __stsch(struct subchannel_id schid, struct schib *addr)
21 unsigned long r1 = *(unsigned int *)&schid;
22 int ccode, exception;
24 exception = 1;
25 asm volatile(
26 " lgr 1,%[r1]\n"
27 " stsch %[addr]\n"
28 "0: lhi %[exc],0\n"
29 "1:\n"
30 CC_IPM(cc)
31 EX_TABLE(0b, 1b)
32 : CC_OUT(cc, ccode), [addr] "=Q" (*addr), [exc] "+d" (exception)
33 : [r1] "d" (r1)
34 : CC_CLOBBER_LIST("1"));
35 return exception ? -EIO : CC_TRANSFORM(ccode);
38 int stsch(struct subchannel_id schid, struct schib *addr)
40 int ccode;
42 ccode = __stsch(schid, addr);
43 trace_s390_cio_stsch(schid, addr, ccode);
45 return ccode;
47 EXPORT_SYMBOL(stsch);
49 static inline int __msch(struct subchannel_id schid, struct schib *addr)
51 unsigned long r1 = *(unsigned int *)&schid;
52 int ccode, exception;
54 exception = 1;
55 asm volatile(
56 " lgr 1,%[r1]\n"
57 " msch %[addr]\n"
58 "0: lhi %[exc],0\n"
59 "1:\n"
60 CC_IPM(cc)
61 EX_TABLE(0b, 1b)
62 : CC_OUT(cc, ccode), [exc] "+d" (exception)
63 : [r1] "d" (r1), [addr] "Q" (*addr)
64 : CC_CLOBBER_LIST("1"));
65 return exception ? -EIO : CC_TRANSFORM(ccode);
68 int msch(struct subchannel_id schid, struct schib *addr)
70 int ccode;
72 ccode = __msch(schid, addr);
73 trace_s390_cio_msch(schid, addr, ccode);
75 return ccode;
78 static inline int __tsch(struct subchannel_id schid, struct irb *addr)
80 unsigned long r1 = *(unsigned int *)&schid;
81 int ccode;
83 asm volatile(
84 " lgr 1,%[r1]\n"
85 " tsch %[addr]\n"
86 CC_IPM(cc)
87 : CC_OUT(cc, ccode), [addr] "=Q" (*addr)
88 : [r1] "d" (r1)
89 : CC_CLOBBER_LIST("1"));
90 return CC_TRANSFORM(ccode);
93 int tsch(struct subchannel_id schid, struct irb *addr)
95 int ccode;
97 ccode = __tsch(schid, addr);
98 trace_s390_cio_tsch(schid, addr, ccode);
100 return ccode;
103 static inline int __ssch(struct subchannel_id schid, union orb *addr)
105 unsigned long r1 = *(unsigned int *)&schid;
106 int ccode, exception;
108 exception = 1;
109 asm volatile(
110 " lgr 1,%[r1]\n"
111 " ssch %[addr]\n"
112 "0: lhi %[exc],0\n"
113 "1:\n"
114 CC_IPM(cc)
115 EX_TABLE(0b, 1b)
116 : CC_OUT(cc, ccode), [exc] "+d" (exception)
117 : [r1] "d" (r1), [addr] "Q" (*addr)
118 : CC_CLOBBER_LIST("memory", "1"));
119 return CC_TRANSFORM(ccode);
122 int ssch(struct subchannel_id schid, union orb *addr)
124 int ccode;
126 ccode = __ssch(schid, addr);
127 trace_s390_cio_ssch(schid, addr, ccode);
129 return ccode;
131 EXPORT_SYMBOL(ssch);
133 static inline int __csch(struct subchannel_id schid)
135 unsigned long r1 = *(unsigned int *)&schid;
136 int ccode;
138 asm volatile(
139 " lgr 1,%[r1]\n"
140 " csch\n"
141 CC_IPM(cc)
142 : CC_OUT(cc, ccode)
143 : [r1] "d" (r1)
144 : CC_CLOBBER_LIST("1"));
145 return CC_TRANSFORM(ccode);
148 int csch(struct subchannel_id schid)
150 int ccode;
152 ccode = __csch(schid);
153 trace_s390_cio_csch(schid, ccode);
155 return ccode;
157 EXPORT_SYMBOL(csch);
159 int tpi(struct tpi_info *addr)
161 int ccode;
163 asm volatile(
164 " tpi %[addr]\n"
165 CC_IPM(cc)
166 : CC_OUT(cc, ccode), [addr] "=Q" (*addr)
168 : CC_CLOBBER);
169 ccode = CC_TRANSFORM(ccode);
170 trace_s390_cio_tpi(addr, ccode);
172 return ccode;
175 int chsc(void *chsc_area)
177 typedef struct { char _[4096]; } addr_type;
178 int cc, exception;
180 exception = 1;
181 asm volatile(
182 " .insn rre,0xb25f0000,%[chsc_area],0\n"
183 "0: lhi %[exc],0\n"
184 "1:\n"
185 CC_IPM(cc)
186 EX_TABLE(0b, 1b)
187 : CC_OUT(cc, cc), "+m" (*(addr_type *)chsc_area), [exc] "+d" (exception)
188 : [chsc_area] "d" (chsc_area)
189 : CC_CLOBBER);
190 cc = exception ? -EIO : CC_TRANSFORM(cc);
191 trace_s390_cio_chsc(chsc_area, cc);
193 return cc;
195 EXPORT_SYMBOL(chsc);
197 static inline int __rsch(struct subchannel_id schid)
199 unsigned long r1 = *(unsigned int *)&schid;
200 int ccode;
202 asm volatile(
203 " lgr 1,%[r1]\n"
204 " rsch\n"
205 CC_IPM(cc)
206 : CC_OUT(cc, ccode)
207 : [r1] "d" (r1)
208 : CC_CLOBBER_LIST("memory", "1"));
209 return CC_TRANSFORM(ccode);
212 int rsch(struct subchannel_id schid)
214 int ccode;
216 ccode = __rsch(schid);
217 trace_s390_cio_rsch(schid, ccode);
219 return ccode;
222 static inline int __hsch(struct subchannel_id schid)
224 unsigned long r1 = *(unsigned int *)&schid;
225 int ccode;
227 asm volatile(
228 " lgr 1,%[r1]\n"
229 " hsch\n"
230 CC_IPM(cc)
231 : CC_OUT(cc, ccode)
232 : [r1] "d" (r1)
233 : CC_CLOBBER_LIST("1"));
234 return CC_TRANSFORM(ccode);
237 int hsch(struct subchannel_id schid)
239 int ccode;
241 ccode = __hsch(schid);
242 trace_s390_cio_hsch(schid, ccode);
244 return ccode;
246 EXPORT_SYMBOL(hsch);
248 static inline int __xsch(struct subchannel_id schid)
250 unsigned long r1 = *(unsigned int *)&schid;
251 int ccode;
253 asm volatile(
254 " lgr 1,%[r1]\n"
255 " xsch\n"
256 " ipm %[cc]\n"
257 " srl %[cc],28\n"
258 : [cc] "=&d" (ccode)
259 : [r1] "d" (r1)
260 : "cc", "1");
261 return CC_TRANSFORM(ccode);
264 int xsch(struct subchannel_id schid)
266 int ccode;
268 ccode = __xsch(schid);
269 trace_s390_cio_xsch(schid, ccode);
271 return ccode;
274 static inline int __stcrw(struct crw *crw)
276 int ccode;
278 asm volatile(
279 " stcrw %[crw]\n"
280 CC_IPM(cc)
281 : CC_OUT(cc, ccode), [crw] "=Q" (*crw)
283 : CC_CLOBBER);
284 return CC_TRANSFORM(ccode);
287 static inline int _stcrw(struct crw *crw)
289 #ifdef CONFIG_CIO_INJECT
290 if (static_branch_unlikely(&cio_inject_enabled)) {
291 if (stcrw_get_injected(crw) == 0)
292 return 0;
294 #endif
296 return __stcrw(crw);
299 int stcrw(struct crw *crw)
301 int ccode;
303 ccode = _stcrw(crw);
304 trace_s390_cio_stcrw(crw, ccode);
306 return ccode;