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