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 /* Function Control */ 74 #define SCSW_FCTL_START_FUNC 0x4000 75 #define SCSW_FCTL_HALT_FUNC 0x2000 76 #define SCSW_FCTL_CLEAR_FUNC 0x1000 77 78 /* Activity Control */ 79 #define SCSW_ACTL_RESUME_PEND 0x0800 80 #define SCSW_ACTL_START_PEND 0x0400 81 #define SCSW_ACTL_HALT_PEND 0x0200 82 #define SCSW_ACTL_CLEAR_PEND 0x0100 83 #define SCSW_ACTL_CH_ACTIVE 0x0080 84 #define SCSW_ACTL_DEV_ACTIVE 0x0040 85 #define SCSW_ACTL_SUSPENDED 0x0020 86 87 /* Status Control */ 88 #define SCSW_SCTL_ALERT 0x0010 89 #define SCSW_SCTL_INTERMED 0x0008 90 #define SCSW_SCTL_PRIMARY 0x0004 91 #define SCSW_SCTL_SECONDARY 0x0002 92 #define SCSW_SCTL_STATUS_PEND 0x0001 93 94 /* SCSW Device Status Flags */ 95 #define SCSW_DSTAT_ATTN 0x80 96 #define SCSW_DSTAT_STATMOD 0x40 97 #define SCSW_DSTAT_CUEND 0x20 98 #define SCSW_DSTAT_BUSY 0x10 99 #define SCSW_DSTAT_CHEND 0x08 100 #define SCSW_DSTAT_DEVEND 0x04 101 #define SCSW_DSTAT_UCHK 0x02 102 #define SCSW_DSTAT_UEXCP 0x01 103 104 /* SCSW Subchannel Status Flags */ 105 #define SCSW_CSTAT_PCINT 0x80 106 #define SCSW_CSTAT_BADLEN 0x40 107 #define SCSW_CSTAT_PROGCHK 0x20 108 #define SCSW_CSTAT_PROTCHK 0x10 109 #define SCSW_CSTAT_CHDCHK 0x08 110 #define SCSW_CSTAT_CHCCHK 0x04 111 #define SCSW_CSTAT_ICCHK 0x02 112 #define SCSW_CSTAT_CHAINCHK 0x01 113 114 /* 115 * subchannel information block 116 */ 117 typedef struct schib { 118 struct pmcw pmcw; /* path management control word */ 119 struct scsw scsw; /* subchannel status word */ 120 __u64 mba; /* measurement block address */ 121 __u8 mda[4]; /* model dependent area */ 122 } __attribute__ ((packed, aligned(4))) Schib; 123 124 typedef struct subchannel_id { 125 union { 126 struct { 127 __u16 cssid:8; 128 __u16 reserved:4; 129 __u16 m:1; 130 __u16 ssid:2; 131 __u16 one:1; 132 }; 133 __u16 sch_id; 134 }; 135 __u16 sch_no; 136 } __attribute__ ((packed, aligned(4))) SubChannelId; 137 138 struct chsc_header { 139 __u16 length; 140 __u16 code; 141 } __attribute__((packed)); 142 143 typedef struct chsc_area_sda { 144 struct chsc_header request; 145 __u8 reserved1:4; 146 __u8 format:4; 147 __u8 reserved2; 148 __u16 operation_code; 149 __u32 reserved3; 150 __u32 reserved4; 151 __u32 operation_data_area[252]; 152 struct chsc_header response; 153 __u32 reserved5:4; 154 __u32 format2:4; 155 __u32 reserved6:24; 156 } __attribute__((packed)) ChscAreaSda; 157 158 /* 159 * TPI info structure 160 */ 161 struct tpi_info { 162 struct subchannel_id schid; 163 __u32 intparm; /* interruption parameter */ 164 __u32 adapter_IO:1; 165 __u32 reserved2:1; 166 __u32 isc:3; 167 __u32 reserved3:12; 168 __u32 int_type:3; 169 __u32 reserved4:12; 170 } __attribute__ ((packed, aligned(4))); 171 172 /* channel command word (format 0) */ 173 typedef struct ccw0 { 174 __u8 cmd_code; 175 __u32 cda:24; 176 __u32 chainData:1; 177 __u32 chain:1; 178 __u32 sli:1; 179 __u32 skip:1; 180 __u32 pci:1; 181 __u32 ida:1; 182 __u32 suspend:1; 183 __u32 mida:1; 184 __u8 reserved; 185 __u16 count; 186 } __attribute__ ((packed, aligned(8))) Ccw0; 187 188 /* channel command word (format 1) */ 189 typedef struct ccw1 { 190 __u8 cmd_code; 191 __u8 flags; 192 __u16 count; 193 __u32 cda; 194 } __attribute__ ((packed, aligned(8))) Ccw1; 195 196 /* do_cio() CCW formats */ 197 #define CCW_FMT0 0x00 198 #define CCW_FMT1 0x01 199 200 #define CCW_FLAG_DC 0x80 201 #define CCW_FLAG_CC 0x40 202 #define CCW_FLAG_SLI 0x20 203 #define CCW_FLAG_SKIP 0x10 204 #define CCW_FLAG_PCI 0x08 205 #define CCW_FLAG_IDA 0x04 206 #define CCW_FLAG_SUSPEND 0x02 207 208 /* Common CCW commands */ 209 #define CCW_CMD_READ_IPL 0x02 210 #define CCW_CMD_NOOP 0x03 211 #define CCW_CMD_BASIC_SENSE 0x04 212 #define CCW_CMD_TIC 0x08 213 #define CCW_CMD_SENSE_ID 0xe4 214 215 /* Virtio CCW commands */ 216 #define CCW_CMD_SET_VQ 0x13 217 #define CCW_CMD_VDEV_RESET 0x33 218 #define CCW_CMD_READ_FEAT 0x12 219 #define CCW_CMD_WRITE_FEAT 0x11 220 #define CCW_CMD_READ_CONF 0x22 221 #define CCW_CMD_WRITE_CONF 0x21 222 #define CCW_CMD_WRITE_STATUS 0x31 223 #define CCW_CMD_SET_IND 0x43 224 #define CCW_CMD_SET_CONF_IND 0x53 225 #define CCW_CMD_READ_VQ_CONF 0x32 226 227 /* DASD CCW commands */ 228 #define CCW_CMD_DASD_READ 0x06 229 #define CCW_CMD_DASD_SEEK 0x07 230 #define CCW_CMD_DASD_SEARCH_ID_EQ 0x31 231 #define CCW_CMD_DASD_READ_MT 0x86 232 233 /* 234 * Command-mode operation request block 235 */ 236 typedef struct cmd_orb { 237 __u32 intparm; /* interruption parameter */ 238 __u32 key:4; /* flags, like key, suspend control, etc. */ 239 __u32 spnd:1; /* suspend control */ 240 __u32 res1:1; /* reserved */ 241 __u32 mod:1; /* modification control */ 242 __u32 sync:1; /* synchronize control */ 243 __u32 fmt:1; /* format control */ 244 __u32 pfch:1; /* prefetch control */ 245 __u32 isic:1; /* initial-status-interruption control */ 246 __u32 alcc:1; /* address-limit-checking control */ 247 __u32 ssic:1; /* suppress-suspended-interr. control */ 248 __u32 res2:1; /* reserved */ 249 __u32 c64:1; /* IDAW/QDIO 64 bit control */ 250 __u32 i2k:1; /* IDAW 2/4kB block size control */ 251 __u32 lpm:8; /* logical path mask */ 252 __u32 ils:1; /* incorrect length */ 253 __u32 zero:6; /* reserved zeros */ 254 __u32 orbx:1; /* ORB extension control */ 255 __u32 cpa; /* channel program address */ 256 } __attribute__ ((packed, aligned(4))) CmdOrb; 257 258 struct ciw { 259 __u8 type; 260 __u8 command; 261 __u16 count; 262 }; 263 264 #define CU_TYPE_UNKNOWN 0x0000 265 #define CU_TYPE_DASD_2107 0x2107 266 #define CU_TYPE_VIRTIO 0x3832 267 #define CU_TYPE_DASD_3990 0x3990 268 269 /* 270 * sense-id response buffer layout 271 */ 272 typedef struct senseid { 273 /* common part */ 274 __u8 reserved; /* always 0x'FF' */ 275 __u16 cu_type; /* control unit type */ 276 __u8 cu_model; /* control unit model */ 277 __u16 dev_type; /* device type */ 278 __u8 dev_model; /* device model */ 279 __u8 unused; /* padding byte */ 280 /* extended part */ 281 struct ciw ciw[62]; 282 } __attribute__ ((packed, aligned(4))) SenseId; 283 284 /* 285 * architected values for first sense byte - common_status. Bits 0-5 of this 286 * field are common to all device types. 287 */ 288 #define SNS_STAT0_CMD_REJECT 0x80 289 #define SNS_STAT0_INTERVENTION_REQ 0x40 290 #define SNS_STAT0_BUS_OUT_CHECK 0x20 291 #define SNS_STAT0_EQUIPMENT_CHECK 0x10 292 #define SNS_STAT0_DATA_CHECK 0x08 293 #define SNS_STAT0_OVERRUN 0x04 294 #define SNS_STAT0_INCOMPL_DOMAIN 0x01 295 296 /* ECKD DASD status[0] byte */ 297 #define SNS_STAT1_PERM_ERR 0x80 298 #define SNS_STAT1_INV_TRACK_FORMAT 0x40 299 #define SNS_STAT1_EOC 0x20 300 #define SNS_STAT1_MESSAGE_TO_OPER 0x10 301 #define SNS_STAT1_NO_REC_FOUND 0x08 302 #define SNS_STAT1_FILE_PROTECTED 0x04 303 #define SNS_STAT1_WRITE_INHIBITED 0x02 304 #define SNS_STAT1_IMPRECISE_END 0x01 305 306 /* ECKD DASD status[1] byte */ 307 #define SNS_STAT2_REQ_INH_WRITE 0x80 308 #define SNS_STAT2_CORRECTABLE 0x40 309 #define SNS_STAT2_FIRST_LOG_ERR 0x20 310 #define SNS_STAT2_ENV_DATA_PRESENT 0x10 311 #define SNS_STAT2_IMPRECISE_END 0x04 312 313 /* ECKD DASD 24-byte Sense fmt_msg codes */ 314 #define SENSE24_FMT_PROG_SYS 0x0 315 #define SENSE24_FMT_EQUIPMENT 0x2 316 #define SENSE24_FMT_CONTROLLER 0x3 317 #define SENSE24_FMT_MISC 0xF 318 319 /* basic sense response buffer layout */ 320 typedef struct SenseDataEckdDasd { 321 uint8_t common_status; 322 uint8_t status[2]; 323 uint8_t res_count; 324 uint8_t phys_drive_id; 325 uint8_t low_cyl_addr; 326 uint8_t head_high_cyl_addr; 327 uint8_t fmt_msg; 328 uint64_t fmt_dependent_info[2]; 329 uint8_t reserved; 330 uint8_t program_action_code; 331 uint16_t config_info; 332 uint8_t mcode_hicyl; 333 uint8_t cyl_head_addr[3]; 334 } __attribute__ ((packed, aligned(4))) SenseDataEckdDasd; 335 336 #define ECKD_SENSE24_GET_FMT(sd) (sd->fmt_msg & 0xF0 >> 4) 337 #define ECKD_SENSE24_GET_MSG(sd) (sd->fmt_msg & 0x0F) 338 339 #define unit_check(irb) ((irb)->scsw.dstat & SCSW_DSTAT_UCHK) 340 #define iface_ctrl_check(irb) ((irb)->scsw.cstat & SCSW_CSTAT_ICCHK) 341 342 /* interruption response block */ 343 typedef struct irb { 344 struct scsw scsw; 345 __u32 esw[5]; 346 __u32 ecw[8]; 347 __u32 emw[8]; 348 } __attribute__ ((packed, aligned(4))) Irb; 349 350 /* Used for SEEK ccw commands */ 351 typedef struct CcwSeekData { 352 uint16_t reserved; 353 uint16_t cyl; 354 uint16_t head; 355 } __attribute__((packed)) CcwSeekData; 356 357 /* Used for SEARCH ID ccw commands */ 358 typedef struct CcwSearchIdData { 359 uint16_t cyl; 360 uint16_t head; 361 uint8_t record; 362 } __attribute__((packed)) CcwSearchIdData; 363 364 int enable_mss_facility(void); 365 void enable_subchannel(SubChannelId schid); 366 uint16_t cu_type(SubChannelId schid); 367 int basic_sense(SubChannelId schid, uint16_t cutype, void *sense_data, 368 uint16_t data_size); 369 int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt); 370 371 /* 372 * Some S390 specific IO instructions as inline 373 */ 374 375 static inline int stsch_err(struct subchannel_id schid, struct schib *addr) 376 { 377 register struct subchannel_id reg1 asm ("1") = schid; 378 int ccode = -EIO; 379 380 asm volatile( 381 " stsch 0(%3)\n" 382 "0: ipm %0\n" 383 " srl %0,28\n" 384 "1:\n" 385 : "+d" (ccode), "=m" (*addr) 386 : "d" (reg1), "a" (addr) 387 : "cc"); 388 return ccode; 389 } 390 391 static inline int msch(struct subchannel_id schid, struct schib *addr) 392 { 393 register struct subchannel_id reg1 asm ("1") = schid; 394 int ccode; 395 396 asm volatile( 397 " msch 0(%2)\n" 398 " ipm %0\n" 399 " srl %0,28" 400 : "=d" (ccode) 401 : "d" (reg1), "a" (addr), "m" (*addr) 402 : "cc"); 403 return ccode; 404 } 405 406 static inline int msch_err(struct subchannel_id schid, struct schib *addr) 407 { 408 register struct subchannel_id reg1 asm ("1") = schid; 409 int ccode = -EIO; 410 411 asm volatile( 412 " msch 0(%2)\n" 413 "0: ipm %0\n" 414 " srl %0,28\n" 415 "1:\n" 416 : "+d" (ccode) 417 : "d" (reg1), "a" (addr), "m" (*addr) 418 : "cc"); 419 return ccode; 420 } 421 422 static inline int tsch(struct subchannel_id schid, struct irb *addr) 423 { 424 register struct subchannel_id reg1 asm ("1") = schid; 425 int ccode; 426 427 asm volatile( 428 " tsch 0(%3)\n" 429 " ipm %0\n" 430 " srl %0,28" 431 : "=d" (ccode), "=m" (*addr) 432 : "d" (reg1), "a" (addr) 433 : "cc"); 434 return ccode; 435 } 436 437 static inline int ssch(struct subchannel_id schid, struct cmd_orb *addr) 438 { 439 register struct subchannel_id reg1 asm("1") = schid; 440 int ccode = -EIO; 441 442 asm volatile( 443 " ssch 0(%2)\n" 444 "0: ipm %0\n" 445 " srl %0,28\n" 446 "1:\n" 447 : "+d" (ccode) 448 : "d" (reg1), "a" (addr), "m" (*addr) 449 : "cc", "memory"); 450 return ccode; 451 } 452 453 static inline int csch(struct subchannel_id schid) 454 { 455 register struct subchannel_id reg1 asm("1") = schid; 456 int ccode; 457 458 asm volatile( 459 " csch\n" 460 " ipm %0\n" 461 " srl %0,28" 462 : "=d" (ccode) 463 : "d" (reg1) 464 : "cc"); 465 return ccode; 466 } 467 468 static inline int tpi(struct tpi_info *addr) 469 { 470 int ccode; 471 472 asm volatile( 473 " tpi 0(%2)\n" 474 " ipm %0\n" 475 " srl %0,28" 476 : "=d" (ccode), "=m" (*addr) 477 : "a" (addr) 478 : "cc"); 479 return ccode; 480 } 481 482 static inline int chsc(void *chsc_area) 483 { 484 typedef struct { char _[4096]; } addr_type; 485 int cc; 486 487 asm volatile( 488 " .insn rre,0xb25f0000,%2,0\n" 489 " ipm %0\n" 490 " srl %0,28\n" 491 : "=d" (cc), "=m" (*(addr_type *) chsc_area) 492 : "d" (chsc_area), "m" (*(addr_type *) chsc_area) 493 : "cc"); 494 return cc; 495 } 496 497 #endif /* CIO_H */ 498