11e17c2c1SAlexander Graf /*
21e17c2c1SAlexander Graf * Channel IO definitions
31e17c2c1SAlexander Graf *
41e17c2c1SAlexander Graf * Copyright (c) 2013 Alexander Graf <agraf@suse.de>
51e17c2c1SAlexander Graf *
61e17c2c1SAlexander Graf * Inspired by various s390 headers in Linux 3.9.
71e17c2c1SAlexander Graf *
81e17c2c1SAlexander Graf * This work is licensed under the terms of the GNU GPL, version 2 or (at
91e17c2c1SAlexander Graf * your option) any later version. See the COPYING file in the top-level
101e17c2c1SAlexander Graf * directory.
111e17c2c1SAlexander Graf */
121e17c2c1SAlexander Graf
131e17c2c1SAlexander Graf #ifndef CIO_H
141e17c2c1SAlexander Graf #define CIO_H
151e17c2c1SAlexander Graf
161e17c2c1SAlexander Graf /*
171e17c2c1SAlexander Graf * path management control word
181e17c2c1SAlexander Graf */
191e17c2c1SAlexander Graf struct pmcw {
200c2a6e12SThomas Huth u32 intparm; /* interruption parameter */
210c2a6e12SThomas Huth u32 qf:1; /* qdio facility */
220c2a6e12SThomas Huth u32 w:1;
230c2a6e12SThomas Huth u32 isc:3; /* interruption subclass */
240c2a6e12SThomas Huth u32 res5:3; /* reserved zeros */
250c2a6e12SThomas Huth u32 ena:1; /* enabled */
260c2a6e12SThomas Huth u32 lm:2; /* limit mode */
270c2a6e12SThomas Huth u32 mme:2; /* measurement-mode enable */
280c2a6e12SThomas Huth u32 mp:1; /* multipath mode */
290c2a6e12SThomas Huth u32 tf:1; /* timing facility */
300c2a6e12SThomas Huth u32 dnv:1; /* device number valid */
310c2a6e12SThomas Huth u32 dev:16; /* device number */
320c2a6e12SThomas Huth u8 lpm; /* logical path mask */
330c2a6e12SThomas Huth u8 pnom; /* path not operational mask */
340c2a6e12SThomas Huth u8 lpum; /* last path used mask */
350c2a6e12SThomas Huth u8 pim; /* path installed mask */
360c2a6e12SThomas Huth u16 mbi; /* measurement-block index */
370c2a6e12SThomas Huth u8 pom; /* path operational mask */
380c2a6e12SThomas Huth u8 pam; /* path available mask */
390c2a6e12SThomas Huth u8 chpid[8]; /* CHPID 0-7 (if available) */
400c2a6e12SThomas Huth u32 unused1:8; /* reserved zeros */
410c2a6e12SThomas Huth u32 st:3; /* subchannel type */
420c2a6e12SThomas Huth u32 unused2:18; /* reserved zeros */
430c2a6e12SThomas Huth u32 mbfc:1; /* measurement block format control */
440c2a6e12SThomas Huth u32 xmwme:1; /* extended measurement word mode enable */
450c2a6e12SThomas Huth u32 csense:1; /* concurrent sense; can be enabled ...*/
461e17c2c1SAlexander Graf /* ... per MSCH, however, if facility */
471e17c2c1SAlexander Graf /* ... is not installed, this results */
481e17c2c1SAlexander Graf /* ... in an operand exception. */
491e17c2c1SAlexander Graf } __attribute__ ((packed));
501e17c2c1SAlexander Graf
511e17c2c1SAlexander Graf /* Target SCHIB configuration. */
521e17c2c1SAlexander Graf struct schib_config {
530c2a6e12SThomas Huth u64 mba;
540c2a6e12SThomas Huth u32 intparm;
550c2a6e12SThomas Huth u16 mbi;
560c2a6e12SThomas Huth u32 isc:3;
570c2a6e12SThomas Huth u32 ena:1;
580c2a6e12SThomas Huth u32 mme:2;
590c2a6e12SThomas Huth u32 mp:1;
600c2a6e12SThomas Huth u32 csense:1;
610c2a6e12SThomas Huth u32 mbfc:1;
621e17c2c1SAlexander Graf } __attribute__ ((packed));
631e17c2c1SAlexander Graf
641e17c2c1SAlexander Graf struct scsw {
650c2a6e12SThomas Huth u16 flags;
660c2a6e12SThomas Huth u16 ctrl;
670c2a6e12SThomas Huth u32 cpa;
680c2a6e12SThomas Huth u8 dstat;
690c2a6e12SThomas Huth u8 cstat;
700c2a6e12SThomas Huth u16 count;
711e17c2c1SAlexander Graf } __attribute__ ((packed));
721e17c2c1SAlexander Graf
733083a1bbSJason J. Herne /* Function Control */
741e17c2c1SAlexander Graf #define SCSW_FCTL_START_FUNC 0x4000
753083a1bbSJason J. Herne #define SCSW_FCTL_HALT_FUNC 0x2000
763083a1bbSJason J. Herne #define SCSW_FCTL_CLEAR_FUNC 0x1000
773083a1bbSJason J. Herne
783083a1bbSJason J. Herne /* Activity Control */
793083a1bbSJason J. Herne #define SCSW_ACTL_RESUME_PEND 0x0800
803083a1bbSJason J. Herne #define SCSW_ACTL_START_PEND 0x0400
813083a1bbSJason J. Herne #define SCSW_ACTL_HALT_PEND 0x0200
823083a1bbSJason J. Herne #define SCSW_ACTL_CLEAR_PEND 0x0100
833083a1bbSJason J. Herne #define SCSW_ACTL_CH_ACTIVE 0x0080
843083a1bbSJason J. Herne #define SCSW_ACTL_DEV_ACTIVE 0x0040
853083a1bbSJason J. Herne #define SCSW_ACTL_SUSPENDED 0x0020
863083a1bbSJason J. Herne
873083a1bbSJason J. Herne /* Status Control */
883083a1bbSJason J. Herne #define SCSW_SCTL_ALERT 0x0010
893083a1bbSJason J. Herne #define SCSW_SCTL_INTERMED 0x0008
903083a1bbSJason J. Herne #define SCSW_SCTL_PRIMARY 0x0004
913083a1bbSJason J. Herne #define SCSW_SCTL_SECONDARY 0x0002
923083a1bbSJason J. Herne #define SCSW_SCTL_STATUS_PEND 0x0001
933083a1bbSJason J. Herne
943083a1bbSJason J. Herne /* SCSW Device Status Flags */
953083a1bbSJason J. Herne #define SCSW_DSTAT_ATTN 0x80
963083a1bbSJason J. Herne #define SCSW_DSTAT_STATMOD 0x40
973083a1bbSJason J. Herne #define SCSW_DSTAT_CUEND 0x20
983083a1bbSJason J. Herne #define SCSW_DSTAT_BUSY 0x10
993083a1bbSJason J. Herne #define SCSW_DSTAT_CHEND 0x08
1003083a1bbSJason J. Herne #define SCSW_DSTAT_DEVEND 0x04
1013083a1bbSJason J. Herne #define SCSW_DSTAT_UCHK 0x02
1023083a1bbSJason J. Herne #define SCSW_DSTAT_UEXCP 0x01
1033083a1bbSJason J. Herne
1043083a1bbSJason J. Herne /* SCSW Subchannel Status Flags */
1053083a1bbSJason J. Herne #define SCSW_CSTAT_PCINT 0x80
1063083a1bbSJason J. Herne #define SCSW_CSTAT_BADLEN 0x40
1073083a1bbSJason J. Herne #define SCSW_CSTAT_PROGCHK 0x20
1083083a1bbSJason J. Herne #define SCSW_CSTAT_PROTCHK 0x10
1093083a1bbSJason J. Herne #define SCSW_CSTAT_CHDCHK 0x08
1103083a1bbSJason J. Herne #define SCSW_CSTAT_CHCCHK 0x04
1113083a1bbSJason J. Herne #define SCSW_CSTAT_ICCHK 0x02
1123083a1bbSJason J. Herne #define SCSW_CSTAT_CHAINCHK 0x01
1131e17c2c1SAlexander Graf
1141e17c2c1SAlexander Graf /*
1151e17c2c1SAlexander Graf * subchannel information block
1161e17c2c1SAlexander Graf */
117d96c5db7SJason J. Herne typedef struct schib {
1181e17c2c1SAlexander Graf struct pmcw pmcw; /* path management control word */
1191e17c2c1SAlexander Graf struct scsw scsw; /* subchannel status word */
1200c2a6e12SThomas Huth u64 mba; /* measurement block address */
1210c2a6e12SThomas Huth u8 mda[4]; /* model dependent area */
122d96c5db7SJason J. Herne } __attribute__ ((packed, aligned(4))) Schib;
1231e17c2c1SAlexander Graf
124d96c5db7SJason J. Herne typedef struct subchannel_id {
125e6d393d0SJanosch Frank union {
126e6d393d0SJanosch Frank struct {
1270c2a6e12SThomas Huth u16 cssid:8;
1280c2a6e12SThomas Huth u16 reserved:4;
1290c2a6e12SThomas Huth u16 m:1;
1300c2a6e12SThomas Huth u16 ssid:2;
1310c2a6e12SThomas Huth u16 one:1;
132e6d393d0SJanosch Frank };
1330c2a6e12SThomas Huth u16 sch_id;
134e6d393d0SJanosch Frank };
1350c2a6e12SThomas Huth u16 sch_no;
136d96c5db7SJason J. Herne } __attribute__ ((packed, aligned(4))) SubChannelId;
1371e17c2c1SAlexander Graf
138c8cda874SDominik Dingel struct chsc_header {
1390c2a6e12SThomas Huth u16 length;
1400c2a6e12SThomas Huth u16 code;
141c8cda874SDominik Dingel } __attribute__((packed));
142c8cda874SDominik Dingel
143d96c5db7SJason J. Herne typedef struct chsc_area_sda {
144c8cda874SDominik Dingel struct chsc_header request;
1450c2a6e12SThomas Huth u8 reserved1:4;
1460c2a6e12SThomas Huth u8 format:4;
1470c2a6e12SThomas Huth u8 reserved2;
1480c2a6e12SThomas Huth u16 operation_code;
1490c2a6e12SThomas Huth u32 reserved3;
1500c2a6e12SThomas Huth u32 reserved4;
1510c2a6e12SThomas Huth u32 operation_data_area[252];
152c8cda874SDominik Dingel struct chsc_header response;
1530c2a6e12SThomas Huth u32 reserved5:4;
1540c2a6e12SThomas Huth u32 format2:4;
1550c2a6e12SThomas Huth u32 reserved6:24;
156d96c5db7SJason J. Herne } __attribute__((packed)) ChscAreaSda;
157c8cda874SDominik Dingel
1581e17c2c1SAlexander Graf /*
1591e17c2c1SAlexander Graf * TPI info structure
1601e17c2c1SAlexander Graf */
1611e17c2c1SAlexander Graf struct tpi_info {
1621e17c2c1SAlexander Graf struct subchannel_id schid;
1630c2a6e12SThomas Huth u32 intparm; /* interruption parameter */
1640c2a6e12SThomas Huth u32 adapter_IO:1;
1650c2a6e12SThomas Huth u32 reserved2:1;
1660c2a6e12SThomas Huth u32 isc:3;
1670c2a6e12SThomas Huth u32 reserved3:12;
1680c2a6e12SThomas Huth u32 int_type:3;
1690c2a6e12SThomas Huth u32 reserved4:12;
170a6e4385dSThomas Huth } __attribute__ ((packed, aligned(4)));
1711e17c2c1SAlexander Graf
1723083a1bbSJason J. Herne /* channel command word (format 0) */
1733083a1bbSJason J. Herne typedef struct ccw0 {
1740c2a6e12SThomas Huth u8 cmd_code;
1750c2a6e12SThomas Huth u32 cda:24;
1760c2a6e12SThomas Huth u32 chainData:1;
1770c2a6e12SThomas Huth u32 chain:1;
1780c2a6e12SThomas Huth u32 sli:1;
1790c2a6e12SThomas Huth u32 skip:1;
1800c2a6e12SThomas Huth u32 pci:1;
1810c2a6e12SThomas Huth u32 ida:1;
1820c2a6e12SThomas Huth u32 suspend:1;
1830c2a6e12SThomas Huth u32 mida:1;
1840c2a6e12SThomas Huth u8 reserved;
1850c2a6e12SThomas Huth u16 count;
1863083a1bbSJason J. Herne } __attribute__ ((packed, aligned(8))) Ccw0;
1873083a1bbSJason J. Herne
1883083a1bbSJason J. Herne /* channel command word (format 1) */
189d96c5db7SJason J. Herne typedef struct ccw1 {
1900c2a6e12SThomas Huth u8 cmd_code;
1910c2a6e12SThomas Huth u8 flags;
1920c2a6e12SThomas Huth u16 count;
1930c2a6e12SThomas Huth u32 cda;
194d96c5db7SJason J. Herne } __attribute__ ((packed, aligned(8))) Ccw1;
1951e17c2c1SAlexander Graf
1963083a1bbSJason J. Herne /* do_cio() CCW formats */
1973083a1bbSJason J. Herne #define CCW_FMT0 0x00
1983083a1bbSJason J. Herne #define CCW_FMT1 0x01
1993083a1bbSJason J. Herne
2001e17c2c1SAlexander Graf #define CCW_FLAG_DC 0x80
2011e17c2c1SAlexander Graf #define CCW_FLAG_CC 0x40
2021e17c2c1SAlexander Graf #define CCW_FLAG_SLI 0x20
2031e17c2c1SAlexander Graf #define CCW_FLAG_SKIP 0x10
2041e17c2c1SAlexander Graf #define CCW_FLAG_PCI 0x08
2051e17c2c1SAlexander Graf #define CCW_FLAG_IDA 0x04
2061e17c2c1SAlexander Graf #define CCW_FLAG_SUSPEND 0x02
2071e17c2c1SAlexander Graf
20869333c36SJason J. Herne /* Common CCW commands */
20969333c36SJason J. Herne #define CCW_CMD_READ_IPL 0x02
2101e17c2c1SAlexander Graf #define CCW_CMD_NOOP 0x03
2111e17c2c1SAlexander Graf #define CCW_CMD_BASIC_SENSE 0x04
2121e17c2c1SAlexander Graf #define CCW_CMD_TIC 0x08
2131e17c2c1SAlexander Graf #define CCW_CMD_SENSE_ID 0xe4
2141e17c2c1SAlexander Graf
21569333c36SJason J. Herne /* Virtio CCW commands */
2161e17c2c1SAlexander Graf #define CCW_CMD_SET_VQ 0x13
2171e17c2c1SAlexander Graf #define CCW_CMD_VDEV_RESET 0x33
2181e17c2c1SAlexander Graf #define CCW_CMD_READ_FEAT 0x12
2191e17c2c1SAlexander Graf #define CCW_CMD_WRITE_FEAT 0x11
2201e17c2c1SAlexander Graf #define CCW_CMD_READ_CONF 0x22
2211e17c2c1SAlexander Graf #define CCW_CMD_WRITE_CONF 0x21
2221e17c2c1SAlexander Graf #define CCW_CMD_WRITE_STATUS 0x31
2231e17c2c1SAlexander Graf #define CCW_CMD_SET_IND 0x43
2241e17c2c1SAlexander Graf #define CCW_CMD_SET_CONF_IND 0x53
2251e17c2c1SAlexander Graf #define CCW_CMD_READ_VQ_CONF 0x32
2261e17c2c1SAlexander Graf
22769333c36SJason J. Herne /* DASD CCW commands */
22869333c36SJason J. Herne #define CCW_CMD_DASD_READ 0x06
22969333c36SJason J. Herne #define CCW_CMD_DASD_SEEK 0x07
23069333c36SJason J. Herne #define CCW_CMD_DASD_SEARCH_ID_EQ 0x31
23169333c36SJason J. Herne #define CCW_CMD_DASD_READ_MT 0x86
23269333c36SJason J. Herne
2331e17c2c1SAlexander Graf /*
2341e17c2c1SAlexander Graf * Command-mode operation request block
2351e17c2c1SAlexander Graf */
236d96c5db7SJason J. Herne typedef struct cmd_orb {
2370c2a6e12SThomas Huth u32 intparm; /* interruption parameter */
2380c2a6e12SThomas Huth u32 key:4; /* flags, like key, suspend control, etc. */
2390c2a6e12SThomas Huth u32 spnd:1; /* suspend control */
2400c2a6e12SThomas Huth u32 res1:1; /* reserved */
2410c2a6e12SThomas Huth u32 mod:1; /* modification control */
2420c2a6e12SThomas Huth u32 sync:1; /* synchronize control */
2430c2a6e12SThomas Huth u32 fmt:1; /* format control */
2440c2a6e12SThomas Huth u32 pfch:1; /* prefetch control */
2450c2a6e12SThomas Huth u32 isic:1; /* initial-status-interruption control */
2460c2a6e12SThomas Huth u32 alcc:1; /* address-limit-checking control */
2470c2a6e12SThomas Huth u32 ssic:1; /* suppress-suspended-interr. control */
2480c2a6e12SThomas Huth u32 res2:1; /* reserved */
2490c2a6e12SThomas Huth u32 c64:1; /* IDAW/QDIO 64 bit control */
2500c2a6e12SThomas Huth u32 i2k:1; /* IDAW 2/4kB block size control */
2510c2a6e12SThomas Huth u32 lpm:8; /* logical path mask */
2520c2a6e12SThomas Huth u32 ils:1; /* incorrect length */
2530c2a6e12SThomas Huth u32 zero:6; /* reserved zeros */
2540c2a6e12SThomas Huth u32 orbx:1; /* ORB extension control */
2550c2a6e12SThomas Huth u32 cpa; /* channel program address */
256d96c5db7SJason J. Herne } __attribute__ ((packed, aligned(4))) CmdOrb;
2571e17c2c1SAlexander Graf
2581e17c2c1SAlexander Graf struct ciw {
2590c2a6e12SThomas Huth u8 type;
2600c2a6e12SThomas Huth u8 command;
2610c2a6e12SThomas Huth u16 count;
2621e17c2c1SAlexander Graf };
2631e17c2c1SAlexander Graf
2643083a1bbSJason J. Herne #define CU_TYPE_UNKNOWN 0x0000
2653083a1bbSJason J. Herne #define CU_TYPE_DASD_2107 0x2107
2663083a1bbSJason J. Herne #define CU_TYPE_VIRTIO 0x3832
2673083a1bbSJason J. Herne #define CU_TYPE_DASD_3990 0x3990
2683083a1bbSJason J. Herne
2691e17c2c1SAlexander Graf /*
2701e17c2c1SAlexander Graf * sense-id response buffer layout
2711e17c2c1SAlexander Graf */
272d96c5db7SJason J. Herne typedef struct senseid {
2731e17c2c1SAlexander Graf /* common part */
2740c2a6e12SThomas Huth u8 reserved; /* always 0x'FF' */
2750c2a6e12SThomas Huth u16 cu_type; /* control unit type */
2760c2a6e12SThomas Huth u8 cu_model; /* control unit model */
2770c2a6e12SThomas Huth u16 dev_type; /* device type */
2780c2a6e12SThomas Huth u8 dev_model; /* device model */
2790c2a6e12SThomas Huth u8 unused; /* padding byte */
2801e17c2c1SAlexander Graf /* extended part */
2811e17c2c1SAlexander Graf struct ciw ciw[62];
282d96c5db7SJason J. Herne } __attribute__ ((packed, aligned(4))) SenseId;
2831e17c2c1SAlexander Graf
2843083a1bbSJason J. Herne /*
2853083a1bbSJason J. Herne * architected values for first sense byte - common_status. Bits 0-5 of this
2863083a1bbSJason J. Herne * field are common to all device types.
2873083a1bbSJason J. Herne */
2883083a1bbSJason J. Herne #define SNS_STAT0_CMD_REJECT 0x80
2893083a1bbSJason J. Herne #define SNS_STAT0_INTERVENTION_REQ 0x40
2903083a1bbSJason J. Herne #define SNS_STAT0_BUS_OUT_CHECK 0x20
2913083a1bbSJason J. Herne #define SNS_STAT0_EQUIPMENT_CHECK 0x10
2923083a1bbSJason J. Herne #define SNS_STAT0_DATA_CHECK 0x08
2933083a1bbSJason J. Herne #define SNS_STAT0_OVERRUN 0x04
2943083a1bbSJason J. Herne #define SNS_STAT0_INCOMPL_DOMAIN 0x01
2953083a1bbSJason J. Herne
2963083a1bbSJason J. Herne /* ECKD DASD status[0] byte */
2973083a1bbSJason J. Herne #define SNS_STAT1_PERM_ERR 0x80
2983083a1bbSJason J. Herne #define SNS_STAT1_INV_TRACK_FORMAT 0x40
2993083a1bbSJason J. Herne #define SNS_STAT1_EOC 0x20
3003083a1bbSJason J. Herne #define SNS_STAT1_MESSAGE_TO_OPER 0x10
3013083a1bbSJason J. Herne #define SNS_STAT1_NO_REC_FOUND 0x08
3023083a1bbSJason J. Herne #define SNS_STAT1_FILE_PROTECTED 0x04
3033083a1bbSJason J. Herne #define SNS_STAT1_WRITE_INHIBITED 0x02
3043083a1bbSJason J. Herne #define SNS_STAT1_IMPRECISE_END 0x01
3053083a1bbSJason J. Herne
3063083a1bbSJason J. Herne /* ECKD DASD status[1] byte */
3073083a1bbSJason J. Herne #define SNS_STAT2_REQ_INH_WRITE 0x80
3083083a1bbSJason J. Herne #define SNS_STAT2_CORRECTABLE 0x40
3093083a1bbSJason J. Herne #define SNS_STAT2_FIRST_LOG_ERR 0x20
3103083a1bbSJason J. Herne #define SNS_STAT2_ENV_DATA_PRESENT 0x10
3113083a1bbSJason J. Herne #define SNS_STAT2_IMPRECISE_END 0x04
3123083a1bbSJason J. Herne
3133083a1bbSJason J. Herne /* ECKD DASD 24-byte Sense fmt_msg codes */
3143083a1bbSJason J. Herne #define SENSE24_FMT_PROG_SYS 0x0
3153083a1bbSJason J. Herne #define SENSE24_FMT_EQUIPMENT 0x2
3163083a1bbSJason J. Herne #define SENSE24_FMT_CONTROLLER 0x3
3173083a1bbSJason J. Herne #define SENSE24_FMT_MISC 0xF
3183083a1bbSJason J. Herne
3193083a1bbSJason J. Herne /* basic sense response buffer layout */
3203083a1bbSJason J. Herne typedef struct SenseDataEckdDasd {
3213083a1bbSJason J. Herne uint8_t common_status;
3223083a1bbSJason J. Herne uint8_t status[2];
3233083a1bbSJason J. Herne uint8_t res_count;
3243083a1bbSJason J. Herne uint8_t phys_drive_id;
3253083a1bbSJason J. Herne uint8_t low_cyl_addr;
3263083a1bbSJason J. Herne uint8_t head_high_cyl_addr;
3273083a1bbSJason J. Herne uint8_t fmt_msg;
3283083a1bbSJason J. Herne uint64_t fmt_dependent_info[2];
3293083a1bbSJason J. Herne uint8_t reserved;
3303083a1bbSJason J. Herne uint8_t program_action_code;
3313083a1bbSJason J. Herne uint16_t config_info;
3323083a1bbSJason J. Herne uint8_t mcode_hicyl;
3333083a1bbSJason J. Herne uint8_t cyl_head_addr[3];
3343083a1bbSJason J. Herne } __attribute__ ((packed, aligned(4))) SenseDataEckdDasd;
3353083a1bbSJason J. Herne
3363083a1bbSJason J. Herne #define ECKD_SENSE24_GET_FMT(sd) (sd->fmt_msg & 0xF0 >> 4)
3373083a1bbSJason J. Herne #define ECKD_SENSE24_GET_MSG(sd) (sd->fmt_msg & 0x0F)
3383083a1bbSJason J. Herne
3393083a1bbSJason J. Herne #define unit_check(irb) ((irb)->scsw.dstat & SCSW_DSTAT_UCHK)
3403083a1bbSJason J. Herne #define iface_ctrl_check(irb) ((irb)->scsw.cstat & SCSW_CSTAT_ICCHK)
3413083a1bbSJason J. Herne
3421e17c2c1SAlexander Graf /* interruption response block */
343d96c5db7SJason J. Herne typedef struct irb {
3441e17c2c1SAlexander Graf struct scsw scsw;
3450c2a6e12SThomas Huth u32 esw[5];
3460c2a6e12SThomas Huth u32 ecw[8];
3470c2a6e12SThomas Huth u32 emw[8];
348d96c5db7SJason J. Herne } __attribute__ ((packed, aligned(4))) Irb;
3491e17c2c1SAlexander Graf
35069333c36SJason J. Herne /* Used for SEEK ccw commands */
35169333c36SJason J. Herne typedef struct CcwSeekData {
35269333c36SJason J. Herne uint16_t reserved;
35369333c36SJason J. Herne uint16_t cyl;
35469333c36SJason J. Herne uint16_t head;
35569333c36SJason J. Herne } __attribute__((packed)) CcwSeekData;
35669333c36SJason J. Herne
35769333c36SJason J. Herne /* Used for SEARCH ID ccw commands */
35869333c36SJason J. Herne typedef struct CcwSearchIdData {
35969333c36SJason J. Herne uint16_t cyl;
36069333c36SJason J. Herne uint16_t head;
36169333c36SJason J. Herne uint8_t record;
36269333c36SJason J. Herne } __attribute__((packed)) CcwSearchIdData;
36369333c36SJason J. Herne
364*8e5739ceSJared Rossi extern SubChannelId net_schid;
365*8e5739ceSJared Rossi
366120d0410SJason J. Herne int enable_mss_facility(void);
367120d0410SJason J. Herne void enable_subchannel(SubChannelId schid);
3683083a1bbSJason J. Herne uint16_t cu_type(SubChannelId schid);
3693083a1bbSJason J. Herne int basic_sense(SubChannelId schid, uint16_t cutype, void *sense_data,
3703083a1bbSJason J. Herne uint16_t data_size);
3713083a1bbSJason J. Herne int do_cio(SubChannelId schid, uint16_t cutype, uint32_t ccw_addr, int fmt);
372120d0410SJason J. Herne
3731e17c2c1SAlexander Graf /*
3741e17c2c1SAlexander Graf * Some S390 specific IO instructions as inline
3751e17c2c1SAlexander Graf */
3761e17c2c1SAlexander Graf
stsch_err(struct subchannel_id schid,struct schib * addr)3771e17c2c1SAlexander Graf static inline int stsch_err(struct subchannel_id schid, struct schib *addr)
3781e17c2c1SAlexander Graf {
3791e17c2c1SAlexander Graf register struct subchannel_id reg1 asm ("1") = schid;
3801e17c2c1SAlexander Graf int ccode = -EIO;
3811e17c2c1SAlexander Graf
3821e17c2c1SAlexander Graf asm volatile(
3831e17c2c1SAlexander Graf " stsch 0(%3)\n"
3841e17c2c1SAlexander Graf "0: ipm %0\n"
3851e17c2c1SAlexander Graf " srl %0,28\n"
3861e17c2c1SAlexander Graf "1:\n"
3871e17c2c1SAlexander Graf : "+d" (ccode), "=m" (*addr)
3881e17c2c1SAlexander Graf : "d" (reg1), "a" (addr)
3891e17c2c1SAlexander Graf : "cc");
3901e17c2c1SAlexander Graf return ccode;
3911e17c2c1SAlexander Graf }
3921e17c2c1SAlexander Graf
msch(struct subchannel_id schid,struct schib * addr)3931e17c2c1SAlexander Graf static inline int msch(struct subchannel_id schid, struct schib *addr)
3941e17c2c1SAlexander Graf {
3951e17c2c1SAlexander Graf register struct subchannel_id reg1 asm ("1") = schid;
3961e17c2c1SAlexander Graf int ccode;
3971e17c2c1SAlexander Graf
3981e17c2c1SAlexander Graf asm volatile(
3991e17c2c1SAlexander Graf " msch 0(%2)\n"
4001e17c2c1SAlexander Graf " ipm %0\n"
4011e17c2c1SAlexander Graf " srl %0,28"
4021e17c2c1SAlexander Graf : "=d" (ccode)
4031e17c2c1SAlexander Graf : "d" (reg1), "a" (addr), "m" (*addr)
4041e17c2c1SAlexander Graf : "cc");
4051e17c2c1SAlexander Graf return ccode;
4061e17c2c1SAlexander Graf }
4071e17c2c1SAlexander Graf
msch_err(struct subchannel_id schid,struct schib * addr)4081e17c2c1SAlexander Graf static inline int msch_err(struct subchannel_id schid, struct schib *addr)
4091e17c2c1SAlexander Graf {
4101e17c2c1SAlexander Graf register struct subchannel_id reg1 asm ("1") = schid;
4111e17c2c1SAlexander Graf int ccode = -EIO;
4121e17c2c1SAlexander Graf
4131e17c2c1SAlexander Graf asm volatile(
4141e17c2c1SAlexander Graf " msch 0(%2)\n"
4151e17c2c1SAlexander Graf "0: ipm %0\n"
4161e17c2c1SAlexander Graf " srl %0,28\n"
4171e17c2c1SAlexander Graf "1:\n"
4181e17c2c1SAlexander Graf : "+d" (ccode)
4191e17c2c1SAlexander Graf : "d" (reg1), "a" (addr), "m" (*addr)
4201e17c2c1SAlexander Graf : "cc");
4211e17c2c1SAlexander Graf return ccode;
4221e17c2c1SAlexander Graf }
4231e17c2c1SAlexander Graf
tsch(struct subchannel_id schid,struct irb * addr)4241e17c2c1SAlexander Graf static inline int tsch(struct subchannel_id schid, struct irb *addr)
4251e17c2c1SAlexander Graf {
4261e17c2c1SAlexander Graf register struct subchannel_id reg1 asm ("1") = schid;
4271e17c2c1SAlexander Graf int ccode;
4281e17c2c1SAlexander Graf
4291e17c2c1SAlexander Graf asm volatile(
4301e17c2c1SAlexander Graf " tsch 0(%3)\n"
4311e17c2c1SAlexander Graf " ipm %0\n"
4321e17c2c1SAlexander Graf " srl %0,28"
4331e17c2c1SAlexander Graf : "=d" (ccode), "=m" (*addr)
4341e17c2c1SAlexander Graf : "d" (reg1), "a" (addr)
4351e17c2c1SAlexander Graf : "cc");
4361e17c2c1SAlexander Graf return ccode;
4371e17c2c1SAlexander Graf }
4381e17c2c1SAlexander Graf
ssch(struct subchannel_id schid,struct cmd_orb * addr)4391e17c2c1SAlexander Graf static inline int ssch(struct subchannel_id schid, struct cmd_orb *addr)
4401e17c2c1SAlexander Graf {
4411e17c2c1SAlexander Graf register struct subchannel_id reg1 asm("1") = schid;
4421e17c2c1SAlexander Graf int ccode = -EIO;
4431e17c2c1SAlexander Graf
4441e17c2c1SAlexander Graf asm volatile(
4451e17c2c1SAlexander Graf " ssch 0(%2)\n"
4461e17c2c1SAlexander Graf "0: ipm %0\n"
4471e17c2c1SAlexander Graf " srl %0,28\n"
4481e17c2c1SAlexander Graf "1:\n"
4491e17c2c1SAlexander Graf : "+d" (ccode)
4501e17c2c1SAlexander Graf : "d" (reg1), "a" (addr), "m" (*addr)
4511e17c2c1SAlexander Graf : "cc", "memory");
4521e17c2c1SAlexander Graf return ccode;
4531e17c2c1SAlexander Graf }
4541e17c2c1SAlexander Graf
csch(struct subchannel_id schid)4551e17c2c1SAlexander Graf static inline int csch(struct subchannel_id schid)
4561e17c2c1SAlexander Graf {
4571e17c2c1SAlexander Graf register struct subchannel_id reg1 asm("1") = schid;
4581e17c2c1SAlexander Graf int ccode;
4591e17c2c1SAlexander Graf
4601e17c2c1SAlexander Graf asm volatile(
4611e17c2c1SAlexander Graf " csch\n"
4621e17c2c1SAlexander Graf " ipm %0\n"
4631e17c2c1SAlexander Graf " srl %0,28"
4641e17c2c1SAlexander Graf : "=d" (ccode)
4651e17c2c1SAlexander Graf : "d" (reg1)
4661e17c2c1SAlexander Graf : "cc");
4671e17c2c1SAlexander Graf return ccode;
4681e17c2c1SAlexander Graf }
4691e17c2c1SAlexander Graf
tpi(struct tpi_info * addr)4701e17c2c1SAlexander Graf static inline int tpi(struct tpi_info *addr)
4711e17c2c1SAlexander Graf {
4721e17c2c1SAlexander Graf int ccode;
4731e17c2c1SAlexander Graf
4741e17c2c1SAlexander Graf asm volatile(
4751e17c2c1SAlexander Graf " tpi 0(%2)\n"
4761e17c2c1SAlexander Graf " ipm %0\n"
4771e17c2c1SAlexander Graf " srl %0,28"
4781e17c2c1SAlexander Graf : "=d" (ccode), "=m" (*addr)
4791e17c2c1SAlexander Graf : "a" (addr)
4801e17c2c1SAlexander Graf : "cc");
4811e17c2c1SAlexander Graf return ccode;
4821e17c2c1SAlexander Graf }
4831e17c2c1SAlexander Graf
chsc(void * chsc_area)4841e17c2c1SAlexander Graf static inline int chsc(void *chsc_area)
4851e17c2c1SAlexander Graf {
4861e17c2c1SAlexander Graf typedef struct { char _[4096]; } addr_type;
4871e17c2c1SAlexander Graf int cc;
4881e17c2c1SAlexander Graf
4891e17c2c1SAlexander Graf asm volatile(
4901e17c2c1SAlexander Graf " .insn rre,0xb25f0000,%2,0\n"
4911e17c2c1SAlexander Graf " ipm %0\n"
4921e17c2c1SAlexander Graf " srl %0,28\n"
4931e17c2c1SAlexander Graf : "=d" (cc), "=m" (*(addr_type *) chsc_area)
4941e17c2c1SAlexander Graf : "d" (chsc_area), "m" (*(addr_type *) chsc_area)
4951e17c2c1SAlexander Graf : "cc");
4961e17c2c1SAlexander Graf return cc;
4971e17c2c1SAlexander Graf }
4981e17c2c1SAlexander Graf
4991e17c2c1SAlexander Graf #endif /* CIO_H */
500