xref: /linux/drivers/s390/cio/ioasm.h (revision 42248979d5705e056b509cdcfb548e40f708cba8)
1 #ifndef S390_CIO_IOASM_H
2 #define S390_CIO_IOASM_H
3 
4 #include <asm/chpid.h>
5 #include <asm/schid.h>
6 #include <asm/crw.h>
7 #include "orb.h"
8 #include "cio.h"
9 #include "trace.h"
10 
11 /*
12  * Some S390 specific IO instructions as inline
13  */
14 
15 static inline int stsch(struct subchannel_id schid, struct schib *addr)
16 {
17 	register struct subchannel_id reg1 asm ("1") = schid;
18 	int ccode = -EIO;
19 
20 	asm volatile(
21 		"	stsch	0(%3)\n"
22 		"0:	ipm	%0\n"
23 		"	srl	%0,28\n"
24 		"1:\n"
25 		EX_TABLE(0b,1b)
26 		: "+d" (ccode), "=m" (*addr)
27 		: "d" (reg1), "a" (addr)
28 		: "cc");
29 	trace_s390_cio_stsch(schid, addr, ccode);
30 
31 	return ccode;
32 }
33 
34 static inline int msch(struct subchannel_id schid, struct schib *addr)
35 {
36 	register struct subchannel_id reg1 asm ("1") = schid;
37 	int ccode = -EIO;
38 
39 	asm volatile(
40 		"	msch	0(%2)\n"
41 		"0:	ipm	%0\n"
42 		"	srl	%0,28\n"
43 		"1:\n"
44 		EX_TABLE(0b,1b)
45 		: "+d" (ccode)
46 		: "d" (reg1), "a" (addr), "m" (*addr)
47 		: "cc");
48 	trace_s390_cio_msch(schid, addr, ccode);
49 
50 	return ccode;
51 }
52 
53 static inline int tsch(struct subchannel_id schid, struct irb *addr)
54 {
55 	register struct subchannel_id reg1 asm ("1") = schid;
56 	int ccode;
57 
58 	asm volatile(
59 		"	tsch	0(%3)\n"
60 		"	ipm	%0\n"
61 		"	srl	%0,28"
62 		: "=d" (ccode), "=m" (*addr)
63 		: "d" (reg1), "a" (addr)
64 		: "cc");
65 	trace_s390_cio_tsch(schid, addr, ccode);
66 
67 	return ccode;
68 }
69 
70 static inline int ssch(struct subchannel_id schid, union orb *addr)
71 {
72 	register struct subchannel_id reg1 asm("1") = schid;
73 	int ccode = -EIO;
74 
75 	asm volatile(
76 		"	ssch	0(%2)\n"
77 		"0:	ipm	%0\n"
78 		"	srl	%0,28\n"
79 		"1:\n"
80 		EX_TABLE(0b, 1b)
81 		: "+d" (ccode)
82 		: "d" (reg1), "a" (addr), "m" (*addr)
83 		: "cc", "memory");
84 	trace_s390_cio_ssch(schid, addr, ccode);
85 
86 	return ccode;
87 }
88 
89 static inline int csch(struct subchannel_id schid)
90 {
91 	register struct subchannel_id reg1 asm("1") = schid;
92 	int ccode;
93 
94 	asm volatile(
95 		"	csch\n"
96 		"	ipm	%0\n"
97 		"	srl	%0,28"
98 		: "=d" (ccode)
99 		: "d" (reg1)
100 		: "cc");
101 	trace_s390_cio_csch(schid, ccode);
102 
103 	return ccode;
104 }
105 
106 static inline int tpi(struct tpi_info *addr)
107 {
108 	int ccode;
109 
110 	asm volatile(
111 		"	tpi	0(%2)\n"
112 		"	ipm	%0\n"
113 		"	srl	%0,28"
114 		: "=d" (ccode), "=m" (*addr)
115 		: "a" (addr)
116 		: "cc");
117 	trace_s390_cio_tpi(addr, ccode);
118 
119 	return ccode;
120 }
121 
122 static inline int chsc(void *chsc_area)
123 {
124 	typedef struct { char _[4096]; } addr_type;
125 	int cc;
126 
127 	asm volatile(
128 		"	.insn	rre,0xb25f0000,%2,0\n"
129 		"	ipm	%0\n"
130 		"	srl	%0,28\n"
131 		: "=d" (cc), "=m" (*(addr_type *) chsc_area)
132 		: "d" (chsc_area), "m" (*(addr_type *) chsc_area)
133 		: "cc");
134 	trace_s390_cio_chsc(chsc_area, cc);
135 
136 	return cc;
137 }
138 
139 static inline int rchp(struct chp_id chpid)
140 {
141 	register struct chp_id reg1 asm ("1") = chpid;
142 	int ccode;
143 
144 	asm volatile(
145 		"	lr	1,%1\n"
146 		"	rchp\n"
147 		"	ipm	%0\n"
148 		"	srl	%0,28"
149 		: "=d" (ccode) : "d" (reg1) : "cc");
150 	trace_s390_cio_rchp(chpid, ccode);
151 
152 	return ccode;
153 }
154 
155 static inline int rsch(struct subchannel_id schid)
156 {
157 	register struct subchannel_id reg1 asm("1") = schid;
158 	int ccode;
159 
160 	asm volatile(
161 		"	rsch\n"
162 		"	ipm	%0\n"
163 		"	srl	%0,28"
164 		: "=d" (ccode)
165 		: "d" (reg1)
166 		: "cc", "memory");
167 	trace_s390_cio_rsch(schid, ccode);
168 
169 	return ccode;
170 }
171 
172 static inline int hsch(struct subchannel_id schid)
173 {
174 	register struct subchannel_id reg1 asm("1") = schid;
175 	int ccode;
176 
177 	asm volatile(
178 		"	hsch\n"
179 		"	ipm	%0\n"
180 		"	srl	%0,28"
181 		: "=d" (ccode)
182 		: "d" (reg1)
183 		: "cc");
184 	trace_s390_cio_hsch(schid, ccode);
185 
186 	return ccode;
187 }
188 
189 static inline int xsch(struct subchannel_id schid)
190 {
191 	register struct subchannel_id reg1 asm("1") = schid;
192 	int ccode;
193 
194 	asm volatile(
195 		"	xsch\n"
196 		"	ipm	%0\n"
197 		"	srl	%0,28"
198 		: "=d" (ccode)
199 		: "d" (reg1)
200 		: "cc");
201 	trace_s390_cio_xsch(schid, ccode);
202 
203 	return ccode;
204 }
205 
206 static inline int stcrw(struct crw *crw)
207 {
208 	int ccode;
209 
210 	asm volatile(
211 		"	stcrw	0(%2)\n"
212 		"	ipm	%0\n"
213 		"	srl	%0,28\n"
214 		: "=d" (ccode), "=m" (*crw)
215 		: "a" (crw)
216 		: "cc");
217 	trace_s390_cio_stcrw(crw, ccode);
218 
219 	return ccode;
220 }
221 
222 #endif
223