xref: /openbmc/qemu/pc-bios/s390-ccw/cio.h (revision e17e57e862faf6e1f372385c18dcf6d3fd31158e)
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