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