Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef S390_CIO_IOASM_H |
| 2 | #define S390_CIO_IOASM_H |
| 3 | |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 4 | #include "schid.h" |
| 5 | |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 6 | /* |
| 7 | * TPI info structure |
| 8 | */ |
| 9 | struct tpi_info { |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 10 | struct subchannel_id schid; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 11 | __u32 intparm; /* interruption parameter */ |
| 12 | __u32 adapter_IO : 1; |
| 13 | __u32 reserved2 : 1; |
| 14 | __u32 isc : 3; |
| 15 | __u32 reserved3 : 12; |
| 16 | __u32 int_type : 3; |
| 17 | __u32 reserved4 : 12; |
| 18 | } __attribute__ ((packed)); |
| 19 | |
| 20 | |
| 21 | /* |
| 22 | * Some S390 specific IO instructions as inline |
| 23 | */ |
| 24 | |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 25 | static inline int stsch(struct subchannel_id schid, |
| 26 | volatile struct schib *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 27 | { |
| 28 | int ccode; |
| 29 | |
| 30 | __asm__ __volatile__( |
| 31 | " lr 1,%1\n" |
| 32 | " stsch 0(%2)\n" |
| 33 | " ipm %0\n" |
| 34 | " srl %0,28" |
| 35 | : "=d" (ccode) |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 36 | : "d" (schid), "a" (addr), "m" (*addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 37 | : "cc", "1" ); |
| 38 | return ccode; |
| 39 | } |
| 40 | |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 41 | static inline int msch(struct subchannel_id schid, |
| 42 | volatile struct schib *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 43 | { |
| 44 | int ccode; |
| 45 | |
| 46 | __asm__ __volatile__( |
| 47 | " lr 1,%1\n" |
| 48 | " msch 0(%2)\n" |
| 49 | " ipm %0\n" |
| 50 | " srl %0,28" |
| 51 | : "=d" (ccode) |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 52 | : "d" (schid), "a" (addr), "m" (*addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 53 | : "cc", "1" ); |
| 54 | return ccode; |
| 55 | } |
| 56 | |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 57 | static inline int msch_err(struct subchannel_id schid, |
| 58 | volatile struct schib *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 59 | { |
| 60 | int ccode; |
| 61 | |
| 62 | __asm__ __volatile__( |
| 63 | " lhi %0,%3\n" |
| 64 | " lr 1,%1\n" |
| 65 | " msch 0(%2)\n" |
| 66 | "0: ipm %0\n" |
| 67 | " srl %0,28\n" |
| 68 | "1:\n" |
| 69 | #ifdef CONFIG_ARCH_S390X |
| 70 | ".section __ex_table,\"a\"\n" |
| 71 | " .align 8\n" |
| 72 | " .quad 0b,1b\n" |
| 73 | ".previous" |
| 74 | #else |
| 75 | ".section __ex_table,\"a\"\n" |
| 76 | " .align 4\n" |
| 77 | " .long 0b,1b\n" |
| 78 | ".previous" |
| 79 | #endif |
| 80 | : "=&d" (ccode) |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 81 | : "d" (schid), "a" (addr), "K" (-EIO), "m" (*addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 82 | : "cc", "1" ); |
| 83 | return ccode; |
| 84 | } |
| 85 | |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 86 | static inline int tsch(struct subchannel_id schid, |
| 87 | volatile struct irb *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 88 | { |
| 89 | int ccode; |
| 90 | |
| 91 | __asm__ __volatile__( |
| 92 | " lr 1,%1\n" |
| 93 | " tsch 0(%2)\n" |
| 94 | " ipm %0\n" |
| 95 | " srl %0,28" |
| 96 | : "=d" (ccode) |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 97 | : "d" (schid), "a" (addr), "m" (*addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 98 | : "cc", "1" ); |
| 99 | return ccode; |
| 100 | } |
| 101 | |
Cornelia Huck | 4c24da7 | 2005-09-03 15:58:01 -0700 | [diff] [blame] | 102 | static inline int tpi( volatile struct tpi_info *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 103 | { |
| 104 | int ccode; |
| 105 | |
| 106 | __asm__ __volatile__( |
| 107 | " tpi 0(%1)\n" |
| 108 | " ipm %0\n" |
| 109 | " srl %0,28" |
| 110 | : "=d" (ccode) |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 111 | : "a" (addr), "m" (*addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 112 | : "cc", "1" ); |
| 113 | return ccode; |
| 114 | } |
| 115 | |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 116 | static inline int ssch(struct subchannel_id schid, |
| 117 | volatile struct orb *addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 118 | { |
| 119 | int ccode; |
| 120 | |
| 121 | __asm__ __volatile__( |
| 122 | " lr 1,%1\n" |
| 123 | " ssch 0(%2)\n" |
| 124 | " ipm %0\n" |
| 125 | " srl %0,28" |
| 126 | : "=d" (ccode) |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 127 | : "d" (schid), "a" (addr), "m" (*addr) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 128 | : "cc", "1" ); |
| 129 | return ccode; |
| 130 | } |
| 131 | |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 132 | static inline int rsch(struct subchannel_id schid) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 133 | { |
| 134 | int ccode; |
| 135 | |
| 136 | __asm__ __volatile__( |
| 137 | " lr 1,%1\n" |
| 138 | " rsch\n" |
| 139 | " ipm %0\n" |
| 140 | " srl %0,28" |
| 141 | : "=d" (ccode) |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 142 | : "d" (schid) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 143 | : "cc", "1" ); |
| 144 | return ccode; |
| 145 | } |
| 146 | |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 147 | static inline int csch(struct subchannel_id schid) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 148 | { |
| 149 | int ccode; |
| 150 | |
| 151 | __asm__ __volatile__( |
| 152 | " lr 1,%1\n" |
| 153 | " csch\n" |
| 154 | " ipm %0\n" |
| 155 | " srl %0,28" |
| 156 | : "=d" (ccode) |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 157 | : "d" (schid) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 158 | : "cc", "1" ); |
| 159 | return ccode; |
| 160 | } |
| 161 | |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 162 | static inline int hsch(struct subchannel_id schid) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 163 | { |
| 164 | int ccode; |
| 165 | |
| 166 | __asm__ __volatile__( |
| 167 | " lr 1,%1\n" |
| 168 | " hsch\n" |
| 169 | " ipm %0\n" |
| 170 | " srl %0,28" |
| 171 | : "=d" (ccode) |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 172 | : "d" (schid) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 173 | : "cc", "1" ); |
| 174 | return ccode; |
| 175 | } |
| 176 | |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 177 | static inline int xsch(struct subchannel_id schid) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 178 | { |
| 179 | int ccode; |
| 180 | |
| 181 | __asm__ __volatile__( |
| 182 | " lr 1,%1\n" |
| 183 | " .insn rre,0xb2760000,%1,0\n" |
| 184 | " ipm %0\n" |
| 185 | " srl %0,28" |
| 186 | : "=d" (ccode) |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 187 | : "d" (schid) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 188 | : "cc", "1" ); |
| 189 | return ccode; |
| 190 | } |
| 191 | |
Cornelia Huck | 4c24da7 | 2005-09-03 15:58:01 -0700 | [diff] [blame] | 192 | static inline int chsc(void *chsc_area) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 193 | { |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 194 | typedef struct { char _[4096]; } addr_type; |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 195 | int cc; |
| 196 | |
| 197 | __asm__ __volatile__ ( |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 198 | ".insn rre,0xb25f0000,%2,0 \n\t" |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 199 | "ipm %0 \n\t" |
| 200 | "srl %0,28 \n\t" |
Cornelia Huck | a8237fc | 2006-01-06 00:19:21 -0800 | [diff] [blame^] | 201 | : "=d" (cc), "=m" (*(addr_type *) chsc_area) |
| 202 | : "d" (chsc_area), "m" (*(addr_type *) chsc_area) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 203 | : "cc" ); |
| 204 | |
| 205 | return cc; |
| 206 | } |
| 207 | |
Cornelia Huck | 4c24da7 | 2005-09-03 15:58:01 -0700 | [diff] [blame] | 208 | static inline int iac( void) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 209 | { |
| 210 | int ccode; |
| 211 | |
| 212 | __asm__ __volatile__( |
| 213 | " iac 1\n" |
| 214 | " ipm %0\n" |
| 215 | " srl %0,28" |
| 216 | : "=d" (ccode) : : "cc", "1" ); |
| 217 | return ccode; |
| 218 | } |
| 219 | |
Cornelia Huck | 4c24da7 | 2005-09-03 15:58:01 -0700 | [diff] [blame] | 220 | static inline int rchp(int chpid) |
Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 221 | { |
| 222 | int ccode; |
| 223 | |
| 224 | __asm__ __volatile__( |
| 225 | " lr 1,%1\n" |
| 226 | " rchp\n" |
| 227 | " ipm %0\n" |
| 228 | " srl %0,28" |
| 229 | : "=d" (ccode) |
| 230 | : "d" (chpid) |
| 231 | : "cc", "1" ); |
| 232 | return ccode; |
| 233 | } |
| 234 | |
| 235 | #endif |