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