Merge master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6] / 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