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 /* 97 * TPI info structure 98 */ 99 struct tpi_info { 100 struct subchannel_id schid; 101 __u32 intparm; /* interruption parameter */ 102 __u32 adapter_IO : 1; 103 __u32 reserved2 : 1; 104 __u32 isc : 3; 105 __u32 reserved3 : 12; 106 __u32 int_type : 3; 107 __u32 reserved4 : 12; 108 } __attribute__ ((packed)); 109 110 /* channel command word (type 1) */ 111 struct ccw1 { 112 __u8 cmd_code; 113 __u8 flags; 114 __u16 count; 115 __u32 cda; 116 } __attribute__ ((packed)); 117 118 #define CCW_FLAG_DC 0x80 119 #define CCW_FLAG_CC 0x40 120 #define CCW_FLAG_SLI 0x20 121 #define CCW_FLAG_SKIP 0x10 122 #define CCW_FLAG_PCI 0x08 123 #define CCW_FLAG_IDA 0x04 124 #define CCW_FLAG_SUSPEND 0x02 125 126 #define CCW_CMD_NOOP 0x03 127 #define CCW_CMD_BASIC_SENSE 0x04 128 #define CCW_CMD_TIC 0x08 129 #define CCW_CMD_SENSE_ID 0xe4 130 131 #define CCW_CMD_SET_VQ 0x13 132 #define CCW_CMD_VDEV_RESET 0x33 133 #define CCW_CMD_READ_FEAT 0x12 134 #define CCW_CMD_WRITE_FEAT 0x11 135 #define CCW_CMD_READ_CONF 0x22 136 #define CCW_CMD_WRITE_CONF 0x21 137 #define CCW_CMD_WRITE_STATUS 0x31 138 #define CCW_CMD_SET_IND 0x43 139 #define CCW_CMD_SET_CONF_IND 0x53 140 #define CCW_CMD_READ_VQ_CONF 0x32 141 142 /* 143 * Command-mode operation request block 144 */ 145 struct cmd_orb { 146 __u32 intparm; /* interruption parameter */ 147 __u32 key:4; /* flags, like key, suspend control, etc. */ 148 __u32 spnd:1; /* suspend control */ 149 __u32 res1:1; /* reserved */ 150 __u32 mod:1; /* modification control */ 151 __u32 sync:1; /* synchronize control */ 152 __u32 fmt:1; /* format control */ 153 __u32 pfch:1; /* prefetch control */ 154 __u32 isic:1; /* initial-status-interruption control */ 155 __u32 alcc:1; /* address-limit-checking control */ 156 __u32 ssic:1; /* suppress-suspended-interr. control */ 157 __u32 res2:1; /* reserved */ 158 __u32 c64:1; /* IDAW/QDIO 64 bit control */ 159 __u32 i2k:1; /* IDAW 2/4kB block size control */ 160 __u32 lpm:8; /* logical path mask */ 161 __u32 ils:1; /* incorrect length */ 162 __u32 zero:6; /* reserved zeros */ 163 __u32 orbx:1; /* ORB extension control */ 164 __u32 cpa; /* channel program address */ 165 } __attribute__ ((packed, aligned(4))); 166 167 struct ciw { 168 __u8 type; 169 __u8 command; 170 __u16 count; 171 }; 172 173 /* 174 * sense-id response buffer layout 175 */ 176 struct senseid { 177 /* common part */ 178 __u8 reserved; /* always 0x'FF' */ 179 __u16 cu_type; /* control unit type */ 180 __u8 cu_model; /* control unit model */ 181 __u16 dev_type; /* device type */ 182 __u8 dev_model; /* device model */ 183 __u8 unused; /* padding byte */ 184 /* extended part */ 185 struct ciw ciw[62]; 186 } __attribute__ ((packed, aligned(4))); 187 188 /* interruption response block */ 189 struct irb { 190 struct scsw scsw; 191 __u32 esw[5]; 192 __u32 ecw[8]; 193 __u32 emw[8]; 194 } __attribute__ ((packed, aligned(4))); 195 196 /* 197 * Some S390 specific IO instructions as inline 198 */ 199 200 static inline int stsch_err(struct subchannel_id schid, struct schib *addr) 201 { 202 register struct subchannel_id reg1 asm ("1") = schid; 203 int ccode = -EIO; 204 205 asm volatile( 206 " stsch 0(%3)\n" 207 "0: ipm %0\n" 208 " srl %0,28\n" 209 "1:\n" 210 : "+d" (ccode), "=m" (*addr) 211 : "d" (reg1), "a" (addr) 212 : "cc"); 213 return ccode; 214 } 215 216 static inline int msch(struct subchannel_id schid, struct schib *addr) 217 { 218 register struct subchannel_id reg1 asm ("1") = schid; 219 int ccode; 220 221 asm volatile( 222 " msch 0(%2)\n" 223 " ipm %0\n" 224 " srl %0,28" 225 : "=d" (ccode) 226 : "d" (reg1), "a" (addr), "m" (*addr) 227 : "cc"); 228 return ccode; 229 } 230 231 static inline int msch_err(struct subchannel_id schid, struct schib *addr) 232 { 233 register struct subchannel_id reg1 asm ("1") = schid; 234 int ccode = -EIO; 235 236 asm volatile( 237 " msch 0(%2)\n" 238 "0: ipm %0\n" 239 " srl %0,28\n" 240 "1:\n" 241 : "+d" (ccode) 242 : "d" (reg1), "a" (addr), "m" (*addr) 243 : "cc"); 244 return ccode; 245 } 246 247 static inline int tsch(struct subchannel_id schid, struct irb *addr) 248 { 249 register struct subchannel_id reg1 asm ("1") = schid; 250 int ccode; 251 252 asm volatile( 253 " tsch 0(%3)\n" 254 " ipm %0\n" 255 " srl %0,28" 256 : "=d" (ccode), "=m" (*addr) 257 : "d" (reg1), "a" (addr) 258 : "cc"); 259 return ccode; 260 } 261 262 static inline int ssch(struct subchannel_id schid, struct cmd_orb *addr) 263 { 264 register struct subchannel_id reg1 asm("1") = schid; 265 int ccode = -EIO; 266 267 asm volatile( 268 " ssch 0(%2)\n" 269 "0: ipm %0\n" 270 " srl %0,28\n" 271 "1:\n" 272 : "+d" (ccode) 273 : "d" (reg1), "a" (addr), "m" (*addr) 274 : "cc", "memory"); 275 return ccode; 276 } 277 278 static inline int csch(struct subchannel_id schid) 279 { 280 register struct subchannel_id reg1 asm("1") = schid; 281 int ccode; 282 283 asm volatile( 284 " csch\n" 285 " ipm %0\n" 286 " srl %0,28" 287 : "=d" (ccode) 288 : "d" (reg1) 289 : "cc"); 290 return ccode; 291 } 292 293 static inline int tpi(struct tpi_info *addr) 294 { 295 int ccode; 296 297 asm volatile( 298 " tpi 0(%2)\n" 299 " ipm %0\n" 300 " srl %0,28" 301 : "=d" (ccode), "=m" (*addr) 302 : "a" (addr) 303 : "cc"); 304 return ccode; 305 } 306 307 static inline int chsc(void *chsc_area) 308 { 309 typedef struct { char _[4096]; } addr_type; 310 int cc; 311 312 asm volatile( 313 " .insn rre,0xb25f0000,%2,0\n" 314 " ipm %0\n" 315 " srl %0,28\n" 316 : "=d" (cc), "=m" (*(addr_type *) chsc_area) 317 : "d" (chsc_area), "m" (*(addr_type *) chsc_area) 318 : "cc"); 319 return cc; 320 } 321 322 #endif /* CIO_H */ 323