]>
Commit | Line | Data |
---|---|---|
83262d63 PO |
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 | |
99ec1112 | 9 | #define _ASM_S390_FCX_H |
83262d63 PO |
10 | |
11 | #include <linux/types.h> | |
12 | ||
13 | #define TCW_FORMAT_DEFAULT 0 | |
14 | #define TCW_TIDAW_FORMAT_DEFAULT 0 | |
8a80b108 PO |
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)) | |
83262d63 PO |
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 | ||
8a80b108 PO |
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)) | |
83262d63 PO |
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 | ||
8a80b108 PO |
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)) | |
83262d63 PO |
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 | ||
8a80b108 PO |
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)) | |
83262d63 PO |
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 | ||
8a80b108 PO |
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)) | |
83262d63 PO |
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 | ||
8a80b108 | 219 | #define DCW_FLAGS_CC (1 << (7 - 1)) |
83262d63 PO |
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)) | |
d7b60489 PO |
251 | #define TCCB_SAC_DEFAULT 0x1ffe |
252 | #define TCCB_SAC_INTRG 0x1fff | |
83262d63 PO |
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 */ |