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