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