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