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