1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Functions for assembling fcx enabled I/O control blocks. 4 * 5 * Copyright IBM Corp. 2008 6 * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> 7 */ 8 9 #ifndef _ASM_S390_FCX_H 10 #define _ASM_S390_FCX_H 11 12 #include <linux/types.h> 13 14 #define TCW_FORMAT_DEFAULT 0 15 #define TCW_TIDAW_FORMAT_DEFAULT 0 16 #define TCW_FLAGS_INPUT_TIDA (1 << (23 - 5)) 17 #define TCW_FLAGS_TCCB_TIDA (1 << (23 - 6)) 18 #define TCW_FLAGS_OUTPUT_TIDA (1 << (23 - 7)) 19 #define TCW_FLAGS_TIDAW_FORMAT(x) ((x) & 3) << (23 - 9) 20 #define TCW_FLAGS_GET_TIDAW_FORMAT(x) (((x) >> (23 - 9)) & 3) 21 22 /** 23 * struct tcw - Transport Control Word (TCW) 24 * @format: TCW format 25 * @flags: TCW flags 26 * @tccbl: Transport-Command-Control-Block Length 27 * @r: Read Operations 28 * @w: Write Operations 29 * @output: Output-Data Address 30 * @input: Input-Data Address 31 * @tsb: Transport-Status-Block Address 32 * @tccb: Transport-Command-Control-Block Address 33 * @output_count: Output Count 34 * @input_count: Input Count 35 * @intrg: Interrogate TCW Address 36 */ 37 struct tcw { 38 u32 format:2; 39 u32 :6; 40 u32 flags:24; 41 u32 :8; 42 u32 tccbl:6; 43 u32 r:1; 44 u32 w:1; 45 u32 :16; 46 u64 output; 47 u64 input; 48 u64 tsb; 49 u64 tccb; 50 u32 output_count; 51 u32 input_count; 52 u32 :32; 53 u32 :32; 54 u32 :32; 55 u32 intrg; 56 } __attribute__ ((packed, aligned(64))); 57 58 #define TIDAW_FLAGS_LAST (1 << (7 - 0)) 59 #define TIDAW_FLAGS_SKIP (1 << (7 - 1)) 60 #define TIDAW_FLAGS_DATA_INT (1 << (7 - 2)) 61 #define TIDAW_FLAGS_TTIC (1 << (7 - 3)) 62 #define TIDAW_FLAGS_INSERT_CBC (1 << (7 - 4)) 63 64 /** 65 * struct tidaw - Transport-Indirect-Addressing Word (TIDAW) 66 * @flags: TIDAW flags. Can be an arithmetic OR of the following constants: 67 * %TIDAW_FLAGS_LAST, %TIDAW_FLAGS_SKIP, %TIDAW_FLAGS_DATA_INT, 68 * %TIDAW_FLAGS_TTIC, %TIDAW_FLAGS_INSERT_CBC 69 * @count: Count 70 * @addr: Address 71 */ 72 struct tidaw { 73 u32 flags:8; 74 u32 :24; 75 u32 count; 76 u64 addr; 77 } __attribute__ ((packed, aligned(16))); 78 79 /** 80 * struct tsa_iostat - I/O-Status Transport-Status Area (IO-Stat TSA) 81 * @dev_time: Device Time 82 * @def_time: Defer Time 83 * @queue_time: Queue Time 84 * @dev_busy_time: Device-Busy Time 85 * @dev_act_time: Device-Active-Only Time 86 * @sense: Sense Data (if present) 87 */ 88 struct tsa_iostat { 89 u32 dev_time; 90 u32 def_time; 91 u32 queue_time; 92 u32 dev_busy_time; 93 u32 dev_act_time; 94 u8 sense[32]; 95 } __attribute__ ((packed)); 96 97 /** 98 * struct tsa_ddpcs - Device-Detected-Program-Check Transport-Status Area (DDPC TSA) 99 * @rc: Reason Code 100 * @rcq: Reason Code Qualifier 101 * @sense: Sense Data (if present) 102 */ 103 struct tsa_ddpc { 104 u32 :24; 105 u32 rc:8; 106 u8 rcq[16]; 107 u8 sense[32]; 108 } __attribute__ ((packed)); 109 110 #define TSA_INTRG_FLAGS_CU_STATE_VALID (1 << (7 - 0)) 111 #define TSA_INTRG_FLAGS_DEV_STATE_VALID (1 << (7 - 1)) 112 #define TSA_INTRG_FLAGS_OP_STATE_VALID (1 << (7 - 2)) 113 114 /** 115 * struct tsa_intrg - Interrogate Transport-Status Area (Intrg. TSA) 116 * @format: Format 117 * @flags: Flags. Can be an arithmetic OR of the following constants: 118 * %TSA_INTRG_FLAGS_CU_STATE_VALID, %TSA_INTRG_FLAGS_DEV_STATE_VALID, 119 * %TSA_INTRG_FLAGS_OP_STATE_VALID 120 * @cu_state: Controle-Unit State 121 * @dev_state: Device State 122 * @op_state: Operation State 123 * @sd_info: State-Dependent Information 124 * @dl_id: Device-Level Identifier 125 * @dd_data: Device-Dependent Data 126 */ 127 struct tsa_intrg { 128 u32 format:8; 129 u32 flags:8; 130 u32 cu_state:8; 131 u32 dev_state:8; 132 u32 op_state:8; 133 u32 :24; 134 u8 sd_info[12]; 135 u32 dl_id; 136 u8 dd_data[28]; 137 } __attribute__ ((packed)); 138 139 #define TSB_FORMAT_NONE 0 140 #define TSB_FORMAT_IOSTAT 1 141 #define TSB_FORMAT_DDPC 2 142 #define TSB_FORMAT_INTRG 3 143 144 #define TSB_FLAGS_DCW_OFFSET_VALID (1 << (7 - 0)) 145 #define TSB_FLAGS_COUNT_VALID (1 << (7 - 1)) 146 #define TSB_FLAGS_CACHE_MISS (1 << (7 - 2)) 147 #define TSB_FLAGS_TIME_VALID (1 << (7 - 3)) 148 #define TSB_FLAGS_FORMAT(x) ((x) & 7) 149 #define TSB_FORMAT(t) ((t)->flags & 7) 150 151 /** 152 * struct tsb - Transport-Status Block (TSB) 153 * @length: Length 154 * @flags: Flags. Can be an arithmetic OR of the following constants: 155 * %TSB_FLAGS_DCW_OFFSET_VALID, %TSB_FLAGS_COUNT_VALID, %TSB_FLAGS_CACHE_MISS, 156 * %TSB_FLAGS_TIME_VALID 157 * @dcw_offset: DCW Offset 158 * @count: Count 159 * @tsa: Transport-Status-Area 160 */ 161 struct tsb { 162 u32 length:8; 163 u32 flags:8; 164 u32 dcw_offset:16; 165 u32 count; 166 u32 :32; 167 union { 168 struct tsa_iostat iostat; 169 struct tsa_ddpc ddpc; 170 struct tsa_intrg intrg; 171 } __attribute__ ((packed)) tsa; 172 } __attribute__ ((packed, aligned(8))); 173 174 #define DCW_INTRG_FORMAT_DEFAULT 0 175 176 #define DCW_INTRG_RC_UNSPECIFIED 0 177 #define DCW_INTRG_RC_TIMEOUT 1 178 179 #define DCW_INTRG_RCQ_UNSPECIFIED 0 180 #define DCW_INTRG_RCQ_PRIMARY 1 181 #define DCW_INTRG_RCQ_SECONDARY 2 182 183 #define DCW_INTRG_FLAGS_MPM (1 << (7 - 0)) 184 #define DCW_INTRG_FLAGS_PPR (1 << (7 - 1)) 185 #define DCW_INTRG_FLAGS_CRIT (1 << (7 - 2)) 186 187 /** 188 * struct dcw_intrg_data - Interrogate DCW data 189 * @format: Format. Should be %DCW_INTRG_FORMAT_DEFAULT 190 * @rc: Reason Code. Can be one of %DCW_INTRG_RC_UNSPECIFIED, 191 * %DCW_INTRG_RC_TIMEOUT 192 * @rcq: Reason Code Qualifier: Can be one of %DCW_INTRG_RCQ_UNSPECIFIED, 193 * %DCW_INTRG_RCQ_PRIMARY, %DCW_INTRG_RCQ_SECONDARY 194 * @lpm: Logical-Path Mask 195 * @pam: Path-Available Mask 196 * @pim: Path-Installed Mask 197 * @timeout: Timeout 198 * @flags: Flags. Can be an arithmetic OR of %DCW_INTRG_FLAGS_MPM, 199 * %DCW_INTRG_FLAGS_PPR, %DCW_INTRG_FLAGS_CRIT 200 * @time: Time 201 * @prog_id: Program Identifier 202 * @prog_data: Program-Dependent Data 203 */ 204 struct dcw_intrg_data { 205 u32 format:8; 206 u32 rc:8; 207 u32 rcq:8; 208 u32 lpm:8; 209 u32 pam:8; 210 u32 pim:8; 211 u32 timeout:16; 212 u32 flags:8; 213 u32 :24; 214 u32 :32; 215 u64 time; 216 u64 prog_id; 217 u8 prog_data[]; 218 } __attribute__ ((packed)); 219 220 #define DCW_FLAGS_CC (1 << (7 - 1)) 221 222 #define DCW_CMD_WRITE 0x01 223 #define DCW_CMD_READ 0x02 224 #define DCW_CMD_CONTROL 0x03 225 #define DCW_CMD_SENSE 0x04 226 #define DCW_CMD_SENSE_ID 0xe4 227 #define DCW_CMD_INTRG 0x40 228 229 /** 230 * struct dcw - Device-Command Word (DCW) 231 * @cmd: Command Code. Can be one of %DCW_CMD_WRITE, %DCW_CMD_READ, 232 * %DCW_CMD_CONTROL, %DCW_CMD_SENSE, %DCW_CMD_SENSE_ID, %DCW_CMD_INTRG 233 * @flags: Flags. Can be an arithmetic OR of %DCW_FLAGS_CC 234 * @cd_count: Control-Data Count 235 * @count: Count 236 * @cd: Control Data 237 */ 238 struct dcw { 239 u32 cmd:8; 240 u32 flags:8; 241 u32 :8; 242 u32 cd_count:8; 243 u32 count; 244 u8 cd[]; 245 } __attribute__ ((packed)); 246 247 #define TCCB_FORMAT_DEFAULT 0x7f 248 #define TCCB_MAX_DCW 30 249 #define TCCB_MAX_SIZE (sizeof(struct tccb_tcah) + \ 250 TCCB_MAX_DCW * sizeof(struct dcw) + \ 251 sizeof(struct tccb_tcat)) 252 #define TCCB_SAC_DEFAULT 0x1ffe 253 #define TCCB_SAC_INTRG 0x1fff 254 255 /** 256 * struct tccb_tcah - Transport-Command-Area Header (TCAH) 257 * @format: Format. Should be %TCCB_FORMAT_DEFAULT 258 * @tcal: Transport-Command-Area Length 259 * @sac: Service-Action Code. Can be one of %TCCB_SAC_DEFAULT, %TCCB_SAC_INTRG 260 * @prio: Priority 261 */ 262 struct tccb_tcah { 263 u32 format:8; 264 u32 :24; 265 u32 :24; 266 u32 tcal:8; 267 u32 sac:16; 268 u32 :8; 269 u32 prio:8; 270 u32 :32; 271 } __attribute__ ((packed)); 272 273 /** 274 * struct tccb_tcat - Transport-Command-Area Trailer (TCAT) 275 * @count: Transport Count 276 */ 277 struct tccb_tcat { 278 u32 :32; 279 u32 count; 280 } __attribute__ ((packed)); 281 282 /** 283 * struct tccb - (partial) Transport-Command-Control Block (TCCB) 284 * @tcah: TCAH 285 * @tca: Transport-Command Area 286 */ 287 struct tccb { 288 struct tccb_tcah tcah; 289 u8 tca[0]; 290 } __attribute__ ((packed, aligned(8))); 291 292 struct tcw *tcw_get_intrg(struct tcw *tcw); 293 void *tcw_get_data(struct tcw *tcw); 294 struct tccb *tcw_get_tccb(struct tcw *tcw); 295 struct tsb *tcw_get_tsb(struct tcw *tcw); 296 297 void tcw_init(struct tcw *tcw, int r, int w); 298 void tcw_finalize(struct tcw *tcw, int num_tidaws); 299 300 void tcw_set_intrg(struct tcw *tcw, struct tcw *intrg_tcw); 301 void tcw_set_data(struct tcw *tcw, void *data, int use_tidal); 302 void tcw_set_tccb(struct tcw *tcw, struct tccb *tccb); 303 void tcw_set_tsb(struct tcw *tcw, struct tsb *tsb); 304 305 void tccb_init(struct tccb *tccb, size_t tccb_size, u32 sac); 306 void tsb_init(struct tsb *tsb); 307 struct dcw *tccb_add_dcw(struct tccb *tccb, size_t tccb_size, u8 cmd, u8 flags, 308 void *cd, u8 cd_count, u32 count); 309 struct tidaw *tcw_add_tidaw(struct tcw *tcw, int num_tidaws, u8 flags, 310 void *addr, u32 count); 311 312 #endif /* _ASM_S390_FCX_H */ 313