Merge branch 'topic/hda-gateway' into topic/hda
[linux-2.6] / arch / s390 / include / asm / fcx.h
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 */