Commit | Line | Data |
---|---|---|
23d805b6 PO |
1 | /* |
2 | * Helper functions for scsw access. | |
3 | * | |
d2fc439b | 4 | * Copyright IBM Corp. 2008, 2012 |
23d805b6 PO |
5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> |
6 | */ | |
7 | ||
62733e5a HC |
8 | #ifndef _ASM_S390_SCSW_H_ |
9 | #define _ASM_S390_SCSW_H_ | |
10 | ||
23d805b6 | 11 | #include <linux/types.h> |
382b7366 | 12 | #include <asm/css_chars.h> |
23d805b6 | 13 | #include <asm/cio.h> |
62733e5a HC |
14 | |
15 | /** | |
16 | * struct cmd_scsw - command-mode subchannel status word | |
17 | * @key: subchannel key | |
18 | * @sctl: suspend control | |
19 | * @eswf: esw format | |
20 | * @cc: deferred condition code | |
21 | * @fmt: format | |
22 | * @pfch: prefetch | |
23 | * @isic: initial-status interruption control | |
24 | * @alcc: address-limit checking control | |
25 | * @ssi: suppress-suspended interruption | |
26 | * @zcc: zero condition code | |
27 | * @ectl: extended control | |
28 | * @pno: path not operational | |
29 | * @res: reserved | |
30 | * @fctl: function control | |
31 | * @actl: activity control | |
32 | * @stctl: status control | |
33 | * @cpa: channel program address | |
34 | * @dstat: device status | |
35 | * @cstat: subchannel status | |
36 | * @count: residual count | |
37 | */ | |
38 | struct cmd_scsw { | |
39 | __u32 key : 4; | |
40 | __u32 sctl : 1; | |
41 | __u32 eswf : 1; | |
42 | __u32 cc : 2; | |
43 | __u32 fmt : 1; | |
44 | __u32 pfch : 1; | |
45 | __u32 isic : 1; | |
46 | __u32 alcc : 1; | |
47 | __u32 ssi : 1; | |
48 | __u32 zcc : 1; | |
49 | __u32 ectl : 1; | |
50 | __u32 pno : 1; | |
51 | __u32 res : 1; | |
52 | __u32 fctl : 3; | |
53 | __u32 actl : 7; | |
54 | __u32 stctl : 5; | |
55 | __u32 cpa; | |
56 | __u32 dstat : 8; | |
57 | __u32 cstat : 8; | |
58 | __u32 count : 16; | |
59 | } __attribute__ ((packed)); | |
60 | ||
61 | /** | |
62 | * struct tm_scsw - transport-mode subchannel status word | |
63 | * @key: subchannel key | |
64 | * @eswf: esw format | |
65 | * @cc: deferred condition code | |
66 | * @fmt: format | |
67 | * @x: IRB-format control | |
68 | * @q: interrogate-complete | |
69 | * @ectl: extended control | |
70 | * @pno: path not operational | |
71 | * @fctl: function control | |
72 | * @actl: activity control | |
73 | * @stctl: status control | |
74 | * @tcw: TCW address | |
75 | * @dstat: device status | |
76 | * @cstat: subchannel status | |
77 | * @fcxs: FCX status | |
78 | * @schxs: subchannel-extended status | |
79 | */ | |
80 | struct tm_scsw { | |
81 | u32 key:4; | |
82 | u32 :1; | |
83 | u32 eswf:1; | |
84 | u32 cc:2; | |
85 | u32 fmt:3; | |
86 | u32 x:1; | |
87 | u32 q:1; | |
88 | u32 :1; | |
89 | u32 ectl:1; | |
90 | u32 pno:1; | |
91 | u32 :1; | |
92 | u32 fctl:3; | |
93 | u32 actl:7; | |
94 | u32 stctl:5; | |
95 | u32 tcw; | |
96 | u32 dstat:8; | |
97 | u32 cstat:8; | |
98 | u32 fcxs:8; | |
99 | u32 schxs:8; | |
100 | } __attribute__ ((packed)); | |
101 | ||
d2fc439b SO |
102 | /** |
103 | * struct eadm_scsw - subchannel status word for eadm subchannels | |
104 | * @key: subchannel key | |
105 | * @eswf: esw format | |
106 | * @cc: deferred condition code | |
107 | * @ectl: extended control | |
108 | * @fctl: function control | |
109 | * @actl: activity control | |
110 | * @stctl: status control | |
111 | * @aob: AOB address | |
112 | * @dstat: device status | |
113 | * @cstat: subchannel status | |
114 | */ | |
115 | struct eadm_scsw { | |
116 | u32 key:4; | |
117 | u32:1; | |
118 | u32 eswf:1; | |
119 | u32 cc:2; | |
120 | u32:6; | |
121 | u32 ectl:1; | |
122 | u32:2; | |
123 | u32 fctl:3; | |
124 | u32 actl:7; | |
125 | u32 stctl:5; | |
126 | u32 aob; | |
127 | u32 dstat:8; | |
128 | u32 cstat:8; | |
129 | u32:16; | |
130 | } __packed; | |
131 | ||
62733e5a HC |
132 | /** |
133 | * union scsw - subchannel status word | |
134 | * @cmd: command-mode SCSW | |
135 | * @tm: transport-mode SCSW | |
d2fc439b | 136 | * @eadm: eadm SCSW |
62733e5a HC |
137 | */ |
138 | union scsw { | |
139 | struct cmd_scsw cmd; | |
140 | struct tm_scsw tm; | |
d2fc439b SO |
141 | struct eadm_scsw eadm; |
142 | } __packed; | |
62733e5a HC |
143 | |
144 | #define SCSW_FCTL_CLEAR_FUNC 0x1 | |
145 | #define SCSW_FCTL_HALT_FUNC 0x2 | |
146 | #define SCSW_FCTL_START_FUNC 0x4 | |
147 | ||
148 | #define SCSW_ACTL_SUSPENDED 0x1 | |
149 | #define SCSW_ACTL_DEVACT 0x2 | |
150 | #define SCSW_ACTL_SCHACT 0x4 | |
151 | #define SCSW_ACTL_CLEAR_PEND 0x8 | |
152 | #define SCSW_ACTL_HALT_PEND 0x10 | |
153 | #define SCSW_ACTL_START_PEND 0x20 | |
154 | #define SCSW_ACTL_RESUME_PEND 0x40 | |
155 | ||
156 | #define SCSW_STCTL_STATUS_PEND 0x1 | |
157 | #define SCSW_STCTL_SEC_STATUS 0x2 | |
158 | #define SCSW_STCTL_PRIM_STATUS 0x4 | |
159 | #define SCSW_STCTL_INTER_STATUS 0x8 | |
160 | #define SCSW_STCTL_ALERT_STATUS 0x10 | |
161 | ||
162 | #define DEV_STAT_ATTENTION 0x80 | |
163 | #define DEV_STAT_STAT_MOD 0x40 | |
164 | #define DEV_STAT_CU_END 0x20 | |
165 | #define DEV_STAT_BUSY 0x10 | |
166 | #define DEV_STAT_CHN_END 0x08 | |
167 | #define DEV_STAT_DEV_END 0x04 | |
168 | #define DEV_STAT_UNIT_CHECK 0x02 | |
169 | #define DEV_STAT_UNIT_EXCEP 0x01 | |
170 | ||
171 | #define SCHN_STAT_PCI 0x80 | |
172 | #define SCHN_STAT_INCORR_LEN 0x40 | |
173 | #define SCHN_STAT_PROG_CHECK 0x20 | |
174 | #define SCHN_STAT_PROT_CHECK 0x10 | |
175 | #define SCHN_STAT_CHN_DATA_CHK 0x08 | |
176 | #define SCHN_STAT_CHN_CTRL_CHK 0x04 | |
177 | #define SCHN_STAT_INTF_CTRL_CHK 0x02 | |
178 | #define SCHN_STAT_CHAIN_CHECK 0x01 | |
179 | ||
180 | /* | |
181 | * architectured values for first sense byte | |
182 | */ | |
183 | #define SNS0_CMD_REJECT 0x80 | |
184 | #define SNS_CMD_REJECT SNS0_CMD_REJEC | |
185 | #define SNS0_INTERVENTION_REQ 0x40 | |
186 | #define SNS0_BUS_OUT_CHECK 0x20 | |
187 | #define SNS0_EQUIPMENT_CHECK 0x10 | |
188 | #define SNS0_DATA_CHECK 0x08 | |
189 | #define SNS0_OVERRUN 0x04 | |
190 | #define SNS0_INCOMPL_DOMAIN 0x01 | |
191 | ||
192 | /* | |
193 | * architectured values for second sense byte | |
194 | */ | |
195 | #define SNS1_PERM_ERR 0x80 | |
196 | #define SNS1_INV_TRACK_FORMAT 0x40 | |
197 | #define SNS1_EOC 0x20 | |
198 | #define SNS1_MESSAGE_TO_OPER 0x10 | |
199 | #define SNS1_NO_REC_FOUND 0x08 | |
200 | #define SNS1_FILE_PROTECTED 0x04 | |
201 | #define SNS1_WRITE_INHIBITED 0x02 | |
202 | #define SNS1_INPRECISE_END 0x01 | |
203 | ||
204 | /* | |
205 | * architectured values for third sense byte | |
206 | */ | |
207 | #define SNS2_REQ_INH_WRITE 0x80 | |
208 | #define SNS2_CORRECTABLE 0x40 | |
209 | #define SNS2_FIRST_LOG_ERR 0x20 | |
210 | #define SNS2_ENV_DATA_PRESENT 0x10 | |
211 | #define SNS2_INPRECISE_END 0x04 | |
23d805b6 PO |
212 | |
213 | /** | |
214 | * scsw_is_tm - check for transport mode scsw | |
215 | * @scsw: pointer to scsw | |
216 | * | |
217 | * Return non-zero if the specified scsw is a transport mode scsw, zero | |
218 | * otherwise. | |
219 | */ | |
62733e5a | 220 | static inline int scsw_is_tm(union scsw *scsw) |
23d805b6 PO |
221 | { |
222 | return css_general_characteristics.fcx && (scsw->tm.x == 1); | |
223 | } | |
23d805b6 PO |
224 | |
225 | /** | |
226 | * scsw_key - return scsw key field | |
227 | * @scsw: pointer to scsw | |
228 | * | |
229 | * Return the value of the key field of the specified scsw, regardless of | |
230 | * whether it is a transport mode or command mode scsw. | |
231 | */ | |
62733e5a | 232 | static inline u32 scsw_key(union scsw *scsw) |
23d805b6 PO |
233 | { |
234 | if (scsw_is_tm(scsw)) | |
235 | return scsw->tm.key; | |
236 | else | |
237 | return scsw->cmd.key; | |
238 | } | |
23d805b6 PO |
239 | |
240 | /** | |
241 | * scsw_eswf - return scsw eswf field | |
242 | * @scsw: pointer to scsw | |
243 | * | |
244 | * Return the value of the eswf field of the specified scsw, regardless of | |
245 | * whether it is a transport mode or command mode scsw. | |
246 | */ | |
62733e5a | 247 | static inline u32 scsw_eswf(union scsw *scsw) |
23d805b6 PO |
248 | { |
249 | if (scsw_is_tm(scsw)) | |
250 | return scsw->tm.eswf; | |
251 | else | |
252 | return scsw->cmd.eswf; | |
253 | } | |
23d805b6 PO |
254 | |
255 | /** | |
256 | * scsw_cc - return scsw cc field | |
257 | * @scsw: pointer to scsw | |
258 | * | |
259 | * Return the value of the cc field of the specified scsw, regardless of | |
260 | * whether it is a transport mode or command mode scsw. | |
261 | */ | |
62733e5a | 262 | static inline u32 scsw_cc(union scsw *scsw) |
23d805b6 PO |
263 | { |
264 | if (scsw_is_tm(scsw)) | |
265 | return scsw->tm.cc; | |
266 | else | |
267 | return scsw->cmd.cc; | |
268 | } | |
23d805b6 PO |
269 | |
270 | /** | |
271 | * scsw_ectl - return scsw ectl field | |
272 | * @scsw: pointer to scsw | |
273 | * | |
274 | * Return the value of the ectl field of the specified scsw, regardless of | |
275 | * whether it is a transport mode or command mode scsw. | |
276 | */ | |
62733e5a | 277 | static inline u32 scsw_ectl(union scsw *scsw) |
23d805b6 PO |
278 | { |
279 | if (scsw_is_tm(scsw)) | |
280 | return scsw->tm.ectl; | |
281 | else | |
282 | return scsw->cmd.ectl; | |
283 | } | |
23d805b6 PO |
284 | |
285 | /** | |
286 | * scsw_pno - return scsw pno field | |
287 | * @scsw: pointer to scsw | |
288 | * | |
289 | * Return the value of the pno field of the specified scsw, regardless of | |
290 | * whether it is a transport mode or command mode scsw. | |
291 | */ | |
62733e5a | 292 | static inline u32 scsw_pno(union scsw *scsw) |
23d805b6 PO |
293 | { |
294 | if (scsw_is_tm(scsw)) | |
295 | return scsw->tm.pno; | |
296 | else | |
297 | return scsw->cmd.pno; | |
298 | } | |
23d805b6 PO |
299 | |
300 | /** | |
301 | * scsw_fctl - return scsw fctl field | |
302 | * @scsw: pointer to scsw | |
303 | * | |
304 | * Return the value of the fctl field of the specified scsw, regardless of | |
305 | * whether it is a transport mode or command mode scsw. | |
306 | */ | |
62733e5a | 307 | static inline u32 scsw_fctl(union scsw *scsw) |
23d805b6 PO |
308 | { |
309 | if (scsw_is_tm(scsw)) | |
310 | return scsw->tm.fctl; | |
311 | else | |
312 | return scsw->cmd.fctl; | |
313 | } | |
23d805b6 PO |
314 | |
315 | /** | |
316 | * scsw_actl - return scsw actl field | |
317 | * @scsw: pointer to scsw | |
318 | * | |
319 | * Return the value of the actl field of the specified scsw, regardless of | |
320 | * whether it is a transport mode or command mode scsw. | |
321 | */ | |
62733e5a | 322 | static inline u32 scsw_actl(union scsw *scsw) |
23d805b6 PO |
323 | { |
324 | if (scsw_is_tm(scsw)) | |
325 | return scsw->tm.actl; | |
326 | else | |
327 | return scsw->cmd.actl; | |
328 | } | |
23d805b6 PO |
329 | |
330 | /** | |
331 | * scsw_stctl - return scsw stctl field | |
332 | * @scsw: pointer to scsw | |
333 | * | |
334 | * Return the value of the stctl field of the specified scsw, regardless of | |
335 | * whether it is a transport mode or command mode scsw. | |
336 | */ | |
62733e5a | 337 | static inline u32 scsw_stctl(union scsw *scsw) |
23d805b6 PO |
338 | { |
339 | if (scsw_is_tm(scsw)) | |
340 | return scsw->tm.stctl; | |
341 | else | |
342 | return scsw->cmd.stctl; | |
343 | } | |
23d805b6 PO |
344 | |
345 | /** | |
346 | * scsw_dstat - return scsw dstat field | |
347 | * @scsw: pointer to scsw | |
348 | * | |
349 | * Return the value of the dstat field of the specified scsw, regardless of | |
350 | * whether it is a transport mode or command mode scsw. | |
351 | */ | |
62733e5a | 352 | static inline u32 scsw_dstat(union scsw *scsw) |
23d805b6 PO |
353 | { |
354 | if (scsw_is_tm(scsw)) | |
355 | return scsw->tm.dstat; | |
356 | else | |
357 | return scsw->cmd.dstat; | |
358 | } | |
23d805b6 PO |
359 | |
360 | /** | |
361 | * scsw_cstat - return scsw cstat field | |
362 | * @scsw: pointer to scsw | |
363 | * | |
364 | * Return the value of the cstat field of the specified scsw, regardless of | |
365 | * whether it is a transport mode or command mode scsw. | |
366 | */ | |
62733e5a | 367 | static inline u32 scsw_cstat(union scsw *scsw) |
23d805b6 PO |
368 | { |
369 | if (scsw_is_tm(scsw)) | |
370 | return scsw->tm.cstat; | |
371 | else | |
372 | return scsw->cmd.cstat; | |
373 | } | |
23d805b6 PO |
374 | |
375 | /** | |
376 | * scsw_cmd_is_valid_key - check key field validity | |
377 | * @scsw: pointer to scsw | |
378 | * | |
379 | * Return non-zero if the key field of the specified command mode scsw is | |
380 | * valid, zero otherwise. | |
381 | */ | |
62733e5a | 382 | static inline int scsw_cmd_is_valid_key(union scsw *scsw) |
23d805b6 PO |
383 | { |
384 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | |
385 | } | |
23d805b6 PO |
386 | |
387 | /** | |
388 | * scsw_cmd_is_valid_sctl - check fctl field validity | |
389 | * @scsw: pointer to scsw | |
390 | * | |
391 | * Return non-zero if the fctl field of the specified command mode scsw is | |
392 | * valid, zero otherwise. | |
393 | */ | |
62733e5a | 394 | static inline int scsw_cmd_is_valid_sctl(union scsw *scsw) |
23d805b6 PO |
395 | { |
396 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | |
397 | } | |
23d805b6 PO |
398 | |
399 | /** | |
400 | * scsw_cmd_is_valid_eswf - check eswf field validity | |
401 | * @scsw: pointer to scsw | |
402 | * | |
403 | * Return non-zero if the eswf field of the specified command mode scsw is | |
404 | * valid, zero otherwise. | |
405 | */ | |
62733e5a | 406 | static inline int scsw_cmd_is_valid_eswf(union scsw *scsw) |
23d805b6 PO |
407 | { |
408 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); | |
409 | } | |
23d805b6 PO |
410 | |
411 | /** | |
412 | * scsw_cmd_is_valid_cc - check cc field validity | |
413 | * @scsw: pointer to scsw | |
414 | * | |
415 | * Return non-zero if the cc field of the specified command mode scsw is | |
416 | * valid, zero otherwise. | |
417 | */ | |
62733e5a | 418 | static inline int scsw_cmd_is_valid_cc(union scsw *scsw) |
23d805b6 PO |
419 | { |
420 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && | |
421 | (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND); | |
422 | } | |
23d805b6 PO |
423 | |
424 | /** | |
425 | * scsw_cmd_is_valid_fmt - check fmt field validity | |
426 | * @scsw: pointer to scsw | |
427 | * | |
428 | * Return non-zero if the fmt field of the specified command mode scsw is | |
429 | * valid, zero otherwise. | |
430 | */ | |
62733e5a | 431 | static inline int scsw_cmd_is_valid_fmt(union scsw *scsw) |
23d805b6 PO |
432 | { |
433 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | |
434 | } | |
23d805b6 PO |
435 | |
436 | /** | |
437 | * scsw_cmd_is_valid_pfch - check pfch field validity | |
438 | * @scsw: pointer to scsw | |
439 | * | |
440 | * Return non-zero if the pfch field of the specified command mode scsw is | |
441 | * valid, zero otherwise. | |
442 | */ | |
62733e5a | 443 | static inline int scsw_cmd_is_valid_pfch(union scsw *scsw) |
23d805b6 PO |
444 | { |
445 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | |
446 | } | |
23d805b6 PO |
447 | |
448 | /** | |
449 | * scsw_cmd_is_valid_isic - check isic field validity | |
450 | * @scsw: pointer to scsw | |
451 | * | |
452 | * Return non-zero if the isic field of the specified command mode scsw is | |
453 | * valid, zero otherwise. | |
454 | */ | |
62733e5a | 455 | static inline int scsw_cmd_is_valid_isic(union scsw *scsw) |
23d805b6 PO |
456 | { |
457 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | |
458 | } | |
23d805b6 PO |
459 | |
460 | /** | |
461 | * scsw_cmd_is_valid_alcc - check alcc field validity | |
462 | * @scsw: pointer to scsw | |
463 | * | |
464 | * Return non-zero if the alcc field of the specified command mode scsw is | |
465 | * valid, zero otherwise. | |
466 | */ | |
62733e5a | 467 | static inline int scsw_cmd_is_valid_alcc(union scsw *scsw) |
23d805b6 PO |
468 | { |
469 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | |
470 | } | |
23d805b6 PO |
471 | |
472 | /** | |
473 | * scsw_cmd_is_valid_ssi - check ssi field validity | |
474 | * @scsw: pointer to scsw | |
475 | * | |
476 | * Return non-zero if the ssi field of the specified command mode scsw is | |
477 | * valid, zero otherwise. | |
478 | */ | |
62733e5a | 479 | static inline int scsw_cmd_is_valid_ssi(union scsw *scsw) |
23d805b6 PO |
480 | { |
481 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC); | |
482 | } | |
23d805b6 PO |
483 | |
484 | /** | |
485 | * scsw_cmd_is_valid_zcc - check zcc field validity | |
486 | * @scsw: pointer to scsw | |
487 | * | |
488 | * Return non-zero if the zcc field of the specified command mode scsw is | |
489 | * valid, zero otherwise. | |
490 | */ | |
62733e5a | 491 | static inline int scsw_cmd_is_valid_zcc(union scsw *scsw) |
23d805b6 PO |
492 | { |
493 | return (scsw->cmd.fctl & SCSW_FCTL_START_FUNC) && | |
494 | (scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS); | |
495 | } | |
23d805b6 PO |
496 | |
497 | /** | |
498 | * scsw_cmd_is_valid_ectl - check ectl field validity | |
499 | * @scsw: pointer to scsw | |
500 | * | |
501 | * Return non-zero if the ectl field of the specified command mode scsw is | |
502 | * valid, zero otherwise. | |
503 | */ | |
62733e5a | 504 | static inline int scsw_cmd_is_valid_ectl(union scsw *scsw) |
23d805b6 PO |
505 | { |
506 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | |
507 | !(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && | |
508 | (scsw->cmd.stctl & SCSW_STCTL_ALERT_STATUS); | |
509 | } | |
23d805b6 PO |
510 | |
511 | /** | |
512 | * scsw_cmd_is_valid_pno - check pno field validity | |
513 | * @scsw: pointer to scsw | |
514 | * | |
515 | * Return non-zero if the pno field of the specified command mode scsw is | |
516 | * valid, zero otherwise. | |
517 | */ | |
62733e5a | 518 | static inline int scsw_cmd_is_valid_pno(union scsw *scsw) |
23d805b6 PO |
519 | { |
520 | return (scsw->cmd.fctl != 0) && | |
521 | (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | |
522 | (!(scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) || | |
523 | ((scsw->cmd.stctl & SCSW_STCTL_INTER_STATUS) && | |
524 | (scsw->cmd.actl & SCSW_ACTL_SUSPENDED))); | |
525 | } | |
23d805b6 PO |
526 | |
527 | /** | |
528 | * scsw_cmd_is_valid_fctl - check fctl field validity | |
529 | * @scsw: pointer to scsw | |
530 | * | |
531 | * Return non-zero if the fctl field of the specified command mode scsw is | |
532 | * valid, zero otherwise. | |
533 | */ | |
62733e5a | 534 | static inline int scsw_cmd_is_valid_fctl(union scsw *scsw) |
23d805b6 PO |
535 | { |
536 | /* Only valid if pmcw.dnv == 1*/ | |
537 | return 1; | |
538 | } | |
23d805b6 PO |
539 | |
540 | /** | |
541 | * scsw_cmd_is_valid_actl - check actl field validity | |
542 | * @scsw: pointer to scsw | |
543 | * | |
544 | * Return non-zero if the actl field of the specified command mode scsw is | |
545 | * valid, zero otherwise. | |
546 | */ | |
62733e5a | 547 | static inline int scsw_cmd_is_valid_actl(union scsw *scsw) |
23d805b6 PO |
548 | { |
549 | /* Only valid if pmcw.dnv == 1*/ | |
550 | return 1; | |
551 | } | |
23d805b6 PO |
552 | |
553 | /** | |
554 | * scsw_cmd_is_valid_stctl - check stctl field validity | |
555 | * @scsw: pointer to scsw | |
556 | * | |
557 | * Return non-zero if the stctl field of the specified command mode scsw is | |
558 | * valid, zero otherwise. | |
559 | */ | |
62733e5a | 560 | static inline int scsw_cmd_is_valid_stctl(union scsw *scsw) |
23d805b6 PO |
561 | { |
562 | /* Only valid if pmcw.dnv == 1*/ | |
563 | return 1; | |
564 | } | |
23d805b6 PO |
565 | |
566 | /** | |
567 | * scsw_cmd_is_valid_dstat - check dstat field validity | |
568 | * @scsw: pointer to scsw | |
569 | * | |
570 | * Return non-zero if the dstat field of the specified command mode scsw is | |
571 | * valid, zero otherwise. | |
572 | */ | |
62733e5a | 573 | static inline int scsw_cmd_is_valid_dstat(union scsw *scsw) |
23d805b6 PO |
574 | { |
575 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | |
576 | (scsw->cmd.cc != 3); | |
577 | } | |
23d805b6 PO |
578 | |
579 | /** | |
580 | * scsw_cmd_is_valid_cstat - check cstat field validity | |
581 | * @scsw: pointer to scsw | |
582 | * | |
583 | * Return non-zero if the cstat field of the specified command mode scsw is | |
584 | * valid, zero otherwise. | |
585 | */ | |
62733e5a | 586 | static inline int scsw_cmd_is_valid_cstat(union scsw *scsw) |
23d805b6 PO |
587 | { |
588 | return (scsw->cmd.stctl & SCSW_STCTL_STATUS_PEND) && | |
589 | (scsw->cmd.cc != 3); | |
590 | } | |
23d805b6 PO |
591 | |
592 | /** | |
593 | * scsw_tm_is_valid_key - check key field validity | |
594 | * @scsw: pointer to scsw | |
595 | * | |
596 | * Return non-zero if the key field of the specified transport mode scsw is | |
597 | * valid, zero otherwise. | |
598 | */ | |
62733e5a | 599 | static inline int scsw_tm_is_valid_key(union scsw *scsw) |
23d805b6 PO |
600 | { |
601 | return (scsw->tm.fctl & SCSW_FCTL_START_FUNC); | |
602 | } | |
23d805b6 PO |
603 | |
604 | /** | |
605 | * scsw_tm_is_valid_eswf - check eswf field validity | |
606 | * @scsw: pointer to scsw | |
607 | * | |
608 | * Return non-zero if the eswf field of the specified transport mode scsw is | |
609 | * valid, zero otherwise. | |
610 | */ | |
62733e5a | 611 | static inline int scsw_tm_is_valid_eswf(union scsw *scsw) |
23d805b6 PO |
612 | { |
613 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); | |
614 | } | |
23d805b6 PO |
615 | |
616 | /** | |
617 | * scsw_tm_is_valid_cc - check cc field validity | |
618 | * @scsw: pointer to scsw | |
619 | * | |
620 | * Return non-zero if the cc field of the specified transport mode scsw is | |
621 | * valid, zero otherwise. | |
622 | */ | |
62733e5a | 623 | static inline int scsw_tm_is_valid_cc(union scsw *scsw) |
23d805b6 PO |
624 | { |
625 | return (scsw->tm.fctl & SCSW_FCTL_START_FUNC) && | |
626 | (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND); | |
627 | } | |
23d805b6 PO |
628 | |
629 | /** | |
630 | * scsw_tm_is_valid_fmt - check fmt field validity | |
631 | * @scsw: pointer to scsw | |
632 | * | |
633 | * Return non-zero if the fmt field of the specified transport mode scsw is | |
634 | * valid, zero otherwise. | |
635 | */ | |
62733e5a | 636 | static inline int scsw_tm_is_valid_fmt(union scsw *scsw) |
23d805b6 PO |
637 | { |
638 | return 1; | |
639 | } | |
23d805b6 PO |
640 | |
641 | /** | |
642 | * scsw_tm_is_valid_x - check x field validity | |
643 | * @scsw: pointer to scsw | |
644 | * | |
645 | * Return non-zero if the x field of the specified transport mode scsw is | |
646 | * valid, zero otherwise. | |
647 | */ | |
62733e5a | 648 | static inline int scsw_tm_is_valid_x(union scsw *scsw) |
23d805b6 PO |
649 | { |
650 | return 1; | |
651 | } | |
23d805b6 PO |
652 | |
653 | /** | |
654 | * scsw_tm_is_valid_q - check q field validity | |
655 | * @scsw: pointer to scsw | |
656 | * | |
657 | * Return non-zero if the q field of the specified transport mode scsw is | |
658 | * valid, zero otherwise. | |
659 | */ | |
62733e5a | 660 | static inline int scsw_tm_is_valid_q(union scsw *scsw) |
23d805b6 PO |
661 | { |
662 | return 1; | |
663 | } | |
23d805b6 PO |
664 | |
665 | /** | |
666 | * scsw_tm_is_valid_ectl - check ectl field validity | |
667 | * @scsw: pointer to scsw | |
668 | * | |
669 | * Return non-zero if the ectl field of the specified transport mode scsw is | |
670 | * valid, zero otherwise. | |
671 | */ | |
62733e5a | 672 | static inline int scsw_tm_is_valid_ectl(union scsw *scsw) |
23d805b6 PO |
673 | { |
674 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | |
675 | !(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && | |
676 | (scsw->tm.stctl & SCSW_STCTL_ALERT_STATUS); | |
677 | } | |
23d805b6 PO |
678 | |
679 | /** | |
680 | * scsw_tm_is_valid_pno - check pno field validity | |
681 | * @scsw: pointer to scsw | |
682 | * | |
683 | * Return non-zero if the pno field of the specified transport mode scsw is | |
684 | * valid, zero otherwise. | |
685 | */ | |
62733e5a | 686 | static inline int scsw_tm_is_valid_pno(union scsw *scsw) |
23d805b6 PO |
687 | { |
688 | return (scsw->tm.fctl != 0) && | |
689 | (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | |
690 | (!(scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) || | |
691 | ((scsw->tm.stctl & SCSW_STCTL_INTER_STATUS) && | |
692 | (scsw->tm.actl & SCSW_ACTL_SUSPENDED))); | |
693 | } | |
23d805b6 PO |
694 | |
695 | /** | |
696 | * scsw_tm_is_valid_fctl - check fctl field validity | |
697 | * @scsw: pointer to scsw | |
698 | * | |
699 | * Return non-zero if the fctl field of the specified transport mode scsw is | |
700 | * valid, zero otherwise. | |
701 | */ | |
62733e5a | 702 | static inline int scsw_tm_is_valid_fctl(union scsw *scsw) |
23d805b6 PO |
703 | { |
704 | /* Only valid if pmcw.dnv == 1*/ | |
705 | return 1; | |
706 | } | |
23d805b6 PO |
707 | |
708 | /** | |
709 | * scsw_tm_is_valid_actl - check actl field validity | |
710 | * @scsw: pointer to scsw | |
711 | * | |
712 | * Return non-zero if the actl field of the specified transport mode scsw is | |
713 | * valid, zero otherwise. | |
714 | */ | |
62733e5a | 715 | static inline int scsw_tm_is_valid_actl(union scsw *scsw) |
23d805b6 PO |
716 | { |
717 | /* Only valid if pmcw.dnv == 1*/ | |
718 | return 1; | |
719 | } | |
23d805b6 PO |
720 | |
721 | /** | |
722 | * scsw_tm_is_valid_stctl - check stctl field validity | |
723 | * @scsw: pointer to scsw | |
724 | * | |
725 | * Return non-zero if the stctl field of the specified transport mode scsw is | |
726 | * valid, zero otherwise. | |
727 | */ | |
62733e5a | 728 | static inline int scsw_tm_is_valid_stctl(union scsw *scsw) |
23d805b6 PO |
729 | { |
730 | /* Only valid if pmcw.dnv == 1*/ | |
731 | return 1; | |
732 | } | |
23d805b6 PO |
733 | |
734 | /** | |
735 | * scsw_tm_is_valid_dstat - check dstat field validity | |
736 | * @scsw: pointer to scsw | |
737 | * | |
738 | * Return non-zero if the dstat field of the specified transport mode scsw is | |
739 | * valid, zero otherwise. | |
740 | */ | |
62733e5a | 741 | static inline int scsw_tm_is_valid_dstat(union scsw *scsw) |
23d805b6 PO |
742 | { |
743 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | |
744 | (scsw->tm.cc != 3); | |
745 | } | |
23d805b6 PO |
746 | |
747 | /** | |
748 | * scsw_tm_is_valid_cstat - check cstat field validity | |
749 | * @scsw: pointer to scsw | |
750 | * | |
751 | * Return non-zero if the cstat field of the specified transport mode scsw is | |
752 | * valid, zero otherwise. | |
753 | */ | |
62733e5a | 754 | static inline int scsw_tm_is_valid_cstat(union scsw *scsw) |
23d805b6 PO |
755 | { |
756 | return (scsw->tm.stctl & SCSW_STCTL_STATUS_PEND) && | |
757 | (scsw->tm.cc != 3); | |
758 | } | |
23d805b6 PO |
759 | |
760 | /** | |
761 | * scsw_tm_is_valid_fcxs - check fcxs field validity | |
762 | * @scsw: pointer to scsw | |
763 | * | |
764 | * Return non-zero if the fcxs field of the specified transport mode scsw is | |
765 | * valid, zero otherwise. | |
766 | */ | |
62733e5a | 767 | static inline int scsw_tm_is_valid_fcxs(union scsw *scsw) |
23d805b6 PO |
768 | { |
769 | return 1; | |
770 | } | |
23d805b6 PO |
771 | |
772 | /** | |
773 | * scsw_tm_is_valid_schxs - check schxs field validity | |
774 | * @scsw: pointer to scsw | |
775 | * | |
776 | * Return non-zero if the schxs field of the specified transport mode scsw is | |
777 | * valid, zero otherwise. | |
778 | */ | |
62733e5a | 779 | static inline int scsw_tm_is_valid_schxs(union scsw *scsw) |
23d805b6 PO |
780 | { |
781 | return (scsw->tm.cstat & (SCHN_STAT_PROG_CHECK | | |
782 | SCHN_STAT_INTF_CTRL_CHK | | |
783 | SCHN_STAT_PROT_CHECK | | |
784 | SCHN_STAT_CHN_DATA_CHK)); | |
785 | } | |
23d805b6 PO |
786 | |
787 | /** | |
788 | * scsw_is_valid_actl - check actl field validity | |
789 | * @scsw: pointer to scsw | |
790 | * | |
791 | * Return non-zero if the actl field of the specified scsw is valid, | |
792 | * regardless of whether it is a transport mode or command mode scsw. | |
793 | * Return zero if the field does not contain a valid value. | |
794 | */ | |
62733e5a | 795 | static inline int scsw_is_valid_actl(union scsw *scsw) |
23d805b6 PO |
796 | { |
797 | if (scsw_is_tm(scsw)) | |
798 | return scsw_tm_is_valid_actl(scsw); | |
799 | else | |
800 | return scsw_cmd_is_valid_actl(scsw); | |
801 | } | |
23d805b6 PO |
802 | |
803 | /** | |
804 | * scsw_is_valid_cc - check cc field validity | |
805 | * @scsw: pointer to scsw | |
806 | * | |
807 | * Return non-zero if the cc field of the specified scsw is valid, | |
808 | * regardless of whether it is a transport mode or command mode scsw. | |
809 | * Return zero if the field does not contain a valid value. | |
810 | */ | |
62733e5a | 811 | static inline int scsw_is_valid_cc(union scsw *scsw) |
23d805b6 PO |
812 | { |
813 | if (scsw_is_tm(scsw)) | |
814 | return scsw_tm_is_valid_cc(scsw); | |
815 | else | |
816 | return scsw_cmd_is_valid_cc(scsw); | |
817 | } | |
23d805b6 PO |
818 | |
819 | /** | |
820 | * scsw_is_valid_cstat - check cstat field validity | |
821 | * @scsw: pointer to scsw | |
822 | * | |
823 | * Return non-zero if the cstat field of the specified scsw is valid, | |
824 | * regardless of whether it is a transport mode or command mode scsw. | |
825 | * Return zero if the field does not contain a valid value. | |
826 | */ | |
62733e5a | 827 | static inline int scsw_is_valid_cstat(union scsw *scsw) |
23d805b6 PO |
828 | { |
829 | if (scsw_is_tm(scsw)) | |
830 | return scsw_tm_is_valid_cstat(scsw); | |
831 | else | |
832 | return scsw_cmd_is_valid_cstat(scsw); | |
833 | } | |
23d805b6 PO |
834 | |
835 | /** | |
836 | * scsw_is_valid_dstat - check dstat field validity | |
837 | * @scsw: pointer to scsw | |
838 | * | |
839 | * Return non-zero if the dstat field of the specified scsw is valid, | |
840 | * regardless of whether it is a transport mode or command mode scsw. | |
841 | * Return zero if the field does not contain a valid value. | |
842 | */ | |
62733e5a | 843 | static inline int scsw_is_valid_dstat(union scsw *scsw) |
23d805b6 PO |
844 | { |
845 | if (scsw_is_tm(scsw)) | |
846 | return scsw_tm_is_valid_dstat(scsw); | |
847 | else | |
848 | return scsw_cmd_is_valid_dstat(scsw); | |
849 | } | |
23d805b6 PO |
850 | |
851 | /** | |
852 | * scsw_is_valid_ectl - check ectl field validity | |
853 | * @scsw: pointer to scsw | |
854 | * | |
855 | * Return non-zero if the ectl field of the specified scsw is valid, | |
856 | * regardless of whether it is a transport mode or command mode scsw. | |
857 | * Return zero if the field does not contain a valid value. | |
858 | */ | |
62733e5a | 859 | static inline int scsw_is_valid_ectl(union scsw *scsw) |
23d805b6 PO |
860 | { |
861 | if (scsw_is_tm(scsw)) | |
862 | return scsw_tm_is_valid_ectl(scsw); | |
863 | else | |
864 | return scsw_cmd_is_valid_ectl(scsw); | |
865 | } | |
23d805b6 PO |
866 | |
867 | /** | |
868 | * scsw_is_valid_eswf - check eswf field validity | |
869 | * @scsw: pointer to scsw | |
870 | * | |
871 | * Return non-zero if the eswf field of the specified scsw is valid, | |
872 | * regardless of whether it is a transport mode or command mode scsw. | |
873 | * Return zero if the field does not contain a valid value. | |
874 | */ | |
62733e5a | 875 | static inline int scsw_is_valid_eswf(union scsw *scsw) |
23d805b6 PO |
876 | { |
877 | if (scsw_is_tm(scsw)) | |
878 | return scsw_tm_is_valid_eswf(scsw); | |
879 | else | |
880 | return scsw_cmd_is_valid_eswf(scsw); | |
881 | } | |
23d805b6 PO |
882 | |
883 | /** | |
884 | * scsw_is_valid_fctl - check fctl field validity | |
885 | * @scsw: pointer to scsw | |
886 | * | |
887 | * Return non-zero if the fctl field of the specified scsw is valid, | |
888 | * regardless of whether it is a transport mode or command mode scsw. | |
889 | * Return zero if the field does not contain a valid value. | |
890 | */ | |
62733e5a | 891 | static inline int scsw_is_valid_fctl(union scsw *scsw) |
23d805b6 PO |
892 | { |
893 | if (scsw_is_tm(scsw)) | |
894 | return scsw_tm_is_valid_fctl(scsw); | |
895 | else | |
896 | return scsw_cmd_is_valid_fctl(scsw); | |
897 | } | |
23d805b6 PO |
898 | |
899 | /** | |
900 | * scsw_is_valid_key - check key field validity | |
901 | * @scsw: pointer to scsw | |
902 | * | |
903 | * Return non-zero if the key field of the specified scsw is valid, | |
904 | * regardless of whether it is a transport mode or command mode scsw. | |
905 | * Return zero if the field does not contain a valid value. | |
906 | */ | |
62733e5a | 907 | static inline int scsw_is_valid_key(union scsw *scsw) |
23d805b6 PO |
908 | { |
909 | if (scsw_is_tm(scsw)) | |
910 | return scsw_tm_is_valid_key(scsw); | |
911 | else | |
912 | return scsw_cmd_is_valid_key(scsw); | |
913 | } | |
23d805b6 PO |
914 | |
915 | /** | |
916 | * scsw_is_valid_pno - check pno field validity | |
917 | * @scsw: pointer to scsw | |
918 | * | |
919 | * Return non-zero if the pno field of the specified scsw is valid, | |
920 | * regardless of whether it is a transport mode or command mode scsw. | |
921 | * Return zero if the field does not contain a valid value. | |
922 | */ | |
62733e5a | 923 | static inline int scsw_is_valid_pno(union scsw *scsw) |
23d805b6 PO |
924 | { |
925 | if (scsw_is_tm(scsw)) | |
926 | return scsw_tm_is_valid_pno(scsw); | |
927 | else | |
928 | return scsw_cmd_is_valid_pno(scsw); | |
929 | } | |
23d805b6 PO |
930 | |
931 | /** | |
932 | * scsw_is_valid_stctl - check stctl field validity | |
933 | * @scsw: pointer to scsw | |
934 | * | |
935 | * Return non-zero if the stctl field of the specified scsw is valid, | |
936 | * regardless of whether it is a transport mode or command mode scsw. | |
937 | * Return zero if the field does not contain a valid value. | |
938 | */ | |
62733e5a | 939 | static inline int scsw_is_valid_stctl(union scsw *scsw) |
23d805b6 PO |
940 | { |
941 | if (scsw_is_tm(scsw)) | |
942 | return scsw_tm_is_valid_stctl(scsw); | |
943 | else | |
944 | return scsw_cmd_is_valid_stctl(scsw); | |
945 | } | |
23d805b6 PO |
946 | |
947 | /** | |
948 | * scsw_cmd_is_solicited - check for solicited scsw | |
949 | * @scsw: pointer to scsw | |
950 | * | |
951 | * Return non-zero if the command mode scsw indicates that the associated | |
952 | * status condition is solicited, zero if it is unsolicited. | |
953 | */ | |
62733e5a | 954 | static inline int scsw_cmd_is_solicited(union scsw *scsw) |
23d805b6 PO |
955 | { |
956 | return (scsw->cmd.cc != 0) || (scsw->cmd.stctl != | |
957 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); | |
958 | } | |
23d805b6 PO |
959 | |
960 | /** | |
961 | * scsw_tm_is_solicited - check for solicited scsw | |
962 | * @scsw: pointer to scsw | |
963 | * | |
964 | * Return non-zero if the transport mode scsw indicates that the associated | |
965 | * status condition is solicited, zero if it is unsolicited. | |
966 | */ | |
62733e5a | 967 | static inline int scsw_tm_is_solicited(union scsw *scsw) |
23d805b6 PO |
968 | { |
969 | return (scsw->tm.cc != 0) || (scsw->tm.stctl != | |
970 | (SCSW_STCTL_STATUS_PEND | SCSW_STCTL_ALERT_STATUS)); | |
971 | } | |
23d805b6 PO |
972 | |
973 | /** | |
974 | * scsw_is_solicited - check for solicited scsw | |
975 | * @scsw: pointer to scsw | |
976 | * | |
977 | * Return non-zero if the transport or command mode scsw indicates that the | |
978 | * associated status condition is solicited, zero if it is unsolicited. | |
979 | */ | |
62733e5a | 980 | static inline int scsw_is_solicited(union scsw *scsw) |
23d805b6 PO |
981 | { |
982 | if (scsw_is_tm(scsw)) | |
983 | return scsw_tm_is_solicited(scsw); | |
984 | else | |
985 | return scsw_cmd_is_solicited(scsw); | |
986 | } | |
62733e5a HC |
987 | |
988 | #endif /* _ASM_S390_SCSW_H_ */ |