1 /* 2 * Channel IO definitions 3 * 4 * Copyright (c) 2013 Alexander Graf <agraf@suse.de> 5 * 6 * Inspired by various s390 headers in Linux 3.9. 7 * 8 * This work is licensed under the terms of the GNU GPL, version 2 or (at 9 * your option) any later version. See the COPYING file in the top-level 10 * directory. 11 */ 12 13 #ifndef CIO_H 14 #define CIO_H 15 16 /* 17 * path management control word 18 */ 19 struct pmcw { 20 __u32 intparm; /* interruption parameter */ 21 __u32 qf : 1; /* qdio facility */ 22 __u32 w : 1; 23 __u32 isc : 3; /* interruption sublass */ 24 __u32 res5 : 3; /* reserved zeros */ 25 __u32 ena : 1; /* enabled */ 26 __u32 lm : 2; /* limit mode */ 27 __u32 mme : 2; /* measurement-mode enable */ 28 __u32 mp : 1; /* multipath mode */ 29 __u32 tf : 1; /* timing facility */ 30 __u32 dnv : 1; /* device number valid */ 31 __u32 dev : 16; /* device number */ 32 __u8 lpm; /* logical path mask */ 33 __u8 pnom; /* path not operational mask */ 34 __u8 lpum; /* last path used mask */ 35 __u8 pim; /* path installed mask */ 36 __u16 mbi; /* measurement-block index */ 37 __u8 pom; /* path operational mask */ 38 __u8 pam; /* path available mask */ 39 __u8 chpid[8]; /* CHPID 0-7 (if available) */ 40 __u32 unused1 : 8; /* reserved zeros */ 41 __u32 st : 3; /* subchannel type */ 42 __u32 unused2 : 18; /* reserved zeros */ 43 __u32 mbfc : 1; /* measurement block format control */ 44 __u32 xmwme : 1; /* extended measurement word mode enable */ 45 __u32 csense : 1; /* concurrent sense; can be enabled ...*/ 46 /* ... per MSCH, however, if facility */ 47 /* ... is not installed, this results */ 48 /* ... in an operand exception. */ 49 } __attribute__ ((packed)); 50 51 /* Target SCHIB configuration. */ 52 struct schib_config { 53 __u64 mba; 54 __u32 intparm; 55 __u16 mbi; 56 __u32 isc:3; 57 __u32 ena:1; 58 __u32 mme:2; 59 __u32 mp:1; 60 __u32 csense:1; 61 __u32 mbfc:1; 62 } __attribute__ ((packed)); 63 64 struct scsw { 65 __u16 flags; 66 __u16 ctrl; 67 __u32 cpa; 68 __u8 dstat; 69 __u8 cstat; 70 __u16 count; 71 } __attribute__ ((packed)); 72 73 #define SCSW_FCTL_CLEAR_FUNC 0x1000 74 #define SCSW_FCTL_HALT_FUNC 0x2000 75 #define SCSW_FCTL_START_FUNC 0x4000 76 77 /* 78 * subchannel information block 79 */ 80 struct schib { 81 struct pmcw pmcw; /* path management control word */ 82 struct scsw scsw; /* subchannel status word */ 83 __u64 mba; /* measurement block address */ 84 __u8 mda[4]; /* model dependent area */ 85 } __attribute__ ((packed,aligned(4))); 86 87 struct subchannel_id { 88 __u32 cssid : 8; 89 __u32 : 4; 90 __u32 m : 1; 91 __u32 ssid : 2; 92 __u32 one : 1; 93 __u32 sch_no : 16; 94 } __attribute__ ((packed, aligned(4))); 95 96 struct chsc_header { 97 __u16 length; 98 __u16 code; 99 } __attribute__((packed)); 100 101 struct chsc_area_sda { 102 struct chsc_header request; 103 __u8 reserved1:4; 104 __u8 format:4; 105 __u8 reserved2; 106 __u16 operation_code; 107 __u32 reserved3; 108 __u32 reserved4; 109 __u32 operation_data_area[252]; 110 struct chsc_header response; 111 __u32 reserved5:4; 112 __u32 format2:4; 113 __u32 reserved6:24; 114 } __attribute__((packed)); 115 116 /* 117 * TPI info structure 118 */ 119 struct tpi_info { 120 struct subchannel_id schid; 121 __u32 intparm; /* interruption parameter */ 122 __u32 adapter_IO : 1; 123 __u32 reserved2 : 1; 124 __u32 isc : 3; 125 __u32 reserved3 : 12; 126 __u32 int_type : 3; 127 __u32 reserved4 : 12; 128 } __attribute__ ((packed)); 129 130 /* channel command word (type 1) */ 131 struct ccw1 { 132 __u8 cmd_code; 133 __u8 flags; 134 __u16 count; 135 __u32 cda; 136 } __attribute__ ((packed, aligned(8))); 137 138 #define CCW_FLAG_DC 0x80 139 #define CCW_FLAG_CC 0x40 140 #define CCW_FLAG_SLI 0x20 141 #define CCW_FLAG_SKIP 0x10 142 #define CCW_FLAG_PCI 0x08 143 #define CCW_FLAG_IDA 0x04 144 #define CCW_FLAG_SUSPEND 0x02 145 146 #define CCW_CMD_NOOP 0x03 147 #define CCW_CMD_BASIC_SENSE 0x04 148 #define CCW_CMD_TIC 0x08 149 #define CCW_CMD_SENSE_ID 0xe4 150 151 #define CCW_CMD_SET_VQ 0x13 152 #define CCW_CMD_VDEV_RESET 0x33 153 #define CCW_CMD_READ_FEAT 0x12 154 #define CCW_CMD_WRITE_FEAT 0x11 155 #define CCW_CMD_READ_CONF 0x22 156 #define CCW_CMD_WRITE_CONF 0x21 157 #define CCW_CMD_WRITE_STATUS 0x31 158 #define CCW_CMD_SET_IND 0x43 159 #define CCW_CMD_SET_CONF_IND 0x53 160 #define CCW_CMD_READ_VQ_CONF 0x32 161 162 /* 163 * Command-mode operation request block 164 */ 165 struct cmd_orb { 166 __u32 intparm; /* interruption parameter */ 167 __u32 key:4; /* flags, like key, suspend control, etc. */ 168 __u32 spnd:1; /* suspend control */ 169 __u32 res1:1; /* reserved */ 170 __u32 mod:1; /* modification control */ 171 __u32 sync:1; /* synchronize control */ 172 __u32 fmt:1; /* format control */ 173 __u32 pfch:1; /* prefetch control */ 174 __u32 isic:1; /* initial-status-interruption control */ 175 __u32 alcc:1; /* address-limit-checking control */ 176 __u32 ssic:1; /* suppress-suspended-interr. control */ 177 __u32 res2:1; /* reserved */ 178 __u32 c64:1; /* IDAW/QDIO 64 bit control */ 179 __u32 i2k:1; /* IDAW 2/4kB block size control */ 180 __u32 lpm:8; /* logical path mask */ 181 __u32 ils:1; /* incorrect length */ 182 __u32 zero:6; /* reserved zeros */ 183 __u32 orbx:1; /* ORB extension control */ 184 __u32 cpa; /* channel program address */ 185 } __attribute__ ((packed, aligned(4))); 186 187 struct ciw { 188 __u8 type; 189 __u8 command; 190 __u16 count; 191 }; 192 193 /* 194 * sense-id response buffer layout 195 */ 196 struct senseid { 197 /* common part */ 198 __u8 reserved; /* always 0x'FF' */ 199 __u16 cu_type; /* control unit type */ 200 __u8 cu_model; /* control unit model */ 201 __u16 dev_type; /* device type */ 202 __u8 dev_model; /* device model */ 203 __u8 unused; /* padding byte */ 204 /* extended part */ 205 struct ciw ciw[62]; 206 } __attribute__ ((packed, aligned(4))); 207 208 /* interruption response block */ 209 struct irb { 210 struct scsw scsw; 211 __u32 esw[5]; 212 __u32 ecw[8]; 213 __u32 emw[8]; 214 } __attribute__ ((packed, aligned(4))); 215 216 /* 217 * Some S390 specific IO instructions as inline 218 */ 219 220 static inline int stsch_err(struct subchannel_id schid, struct schib *addr) 221 { 222 register struct subchannel_id reg1 asm ("1") = schid; 223 int ccode = -EIO; 224 225 asm volatile( 226 " stsch 0(%3)\n" 227 "0: ipm %0\n" 228 " srl %0,28\n" 229 "1:\n" 230 : "+d" (ccode), "=m" (*addr) 231 : "d" (reg1), "a" (addr) 232 : "cc"); 233 return ccode; 234 } 235 236 static inline int msch(struct subchannel_id schid, struct schib *addr) 237 { 238 register struct subchannel_id reg1 asm ("1") = schid; 239 int ccode; 240 241 asm volatile( 242 " msch 0(%2)\n" 243 " ipm %0\n" 244 " srl %0,28" 245 : "=d" (ccode) 246 : "d" (reg1), "a" (addr), "m" (*addr) 247 : "cc"); 248 return ccode; 249 } 250 251 static inline int msch_err(struct subchannel_id schid, struct schib *addr) 252 { 253 register struct subchannel_id reg1 asm ("1") = schid; 254 int ccode = -EIO; 255 256 asm volatile( 257 " msch 0(%2)\n" 258 "0: ipm %0\n" 259 " srl %0,28\n" 260 "1:\n" 261 : "+d" (ccode) 262 : "d" (reg1), "a" (addr), "m" (*addr) 263 : "cc"); 264 return ccode; 265 } 266 267 static inline int tsch(struct subchannel_id schid, struct irb *addr) 268 { 269 register struct subchannel_id reg1 asm ("1") = schid; 270 int ccode; 271 272 asm volatile( 273 " tsch 0(%3)\n" 274 " ipm %0\n" 275 " srl %0,28" 276 : "=d" (ccode), "=m" (*addr) 277 : "d" (reg1), "a" (addr) 278 : "cc"); 279 return ccode; 280 } 281 282 static inline int ssch(struct subchannel_id schid, struct cmd_orb *addr) 283 { 284 register struct subchannel_id reg1 asm("1") = schid; 285 int ccode = -EIO; 286 287 asm volatile( 288 " ssch 0(%2)\n" 289 "0: ipm %0\n" 290 " srl %0,28\n" 291 "1:\n" 292 : "+d" (ccode) 293 : "d" (reg1), "a" (addr), "m" (*addr) 294 : "cc", "memory"); 295 return ccode; 296 } 297 298 static inline int csch(struct subchannel_id schid) 299 { 300 register struct subchannel_id reg1 asm("1") = schid; 301 int ccode; 302 303 asm volatile( 304 " csch\n" 305 " ipm %0\n" 306 " srl %0,28" 307 : "=d" (ccode) 308 : "d" (reg1) 309 : "cc"); 310 return ccode; 311 } 312 313 static inline int tpi(struct tpi_info *addr) 314 { 315 int ccode; 316 317 asm volatile( 318 " tpi 0(%2)\n" 319 " ipm %0\n" 320 " srl %0,28" 321 : "=d" (ccode), "=m" (*addr) 322 : "a" (addr) 323 : "cc"); 324 return ccode; 325 } 326 327 static inline int chsc(void *chsc_area) 328 { 329 typedef struct { char _[4096]; } addr_type; 330 int cc; 331 332 asm volatile( 333 " .insn rre,0xb25f0000,%2,0\n" 334 " ipm %0\n" 335 " srl %0,28\n" 336 : "=d" (cc), "=m" (*(addr_type *) chsc_area) 337 : "d" (chsc_area), "m" (*(addr_type *) chsc_area) 338 : "cc"); 339 return cc; 340 } 341 342 #endif /* CIO_H */ 343