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