Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | #ifndef _CIO_QDIO_H |
2 | #define _CIO_QDIO_H | |
3 | ||
0b642ede PO |
4 | #include <asm/page.h> |
5 | ||
a8237fc4 CH |
6 | #include "schid.h" |
7 | ||
1da177e4 LT |
8 | #ifdef CONFIG_QDIO_DEBUG |
9 | #define QDIO_VERBOSE_LEVEL 9 | |
10 | #else /* CONFIG_QDIO_DEBUG */ | |
11 | #define QDIO_VERBOSE_LEVEL 5 | |
12 | #endif /* CONFIG_QDIO_DEBUG */ | |
1da177e4 LT |
13 | #define QDIO_USE_PROCESSING_STATE |
14 | ||
1da177e4 LT |
15 | #define QDIO_MINIMAL_BH_RELIEF_TIME 16 |
16 | #define QDIO_TIMER_POLL_VALUE 1 | |
17 | #define IQDIO_TIMER_POLL_VALUE 1 | |
18 | ||
19 | /* | |
20 | * unfortunately this can't be (QDIO_MAX_BUFFERS_PER_Q*4/3) or so -- as | |
21 | * we never know, whether we'll get initiative again, e.g. to give the | |
22 | * transmit skb's back to the stack, however the stack may be waiting for | |
23 | * them... therefore we define 4 as threshold to start polling (which | |
24 | * will stop as soon as the asynchronous queue catches up) | |
25 | * btw, this only applies to the asynchronous HiperSockets queue | |
26 | */ | |
27 | #define IQDIO_FILL_LEVEL_TO_POLL 4 | |
28 | ||
29 | #define TIQDIO_THININT_ISC 3 | |
30 | #define TIQDIO_DELAY_TARGET 0 | |
31 | #define QDIO_BUSY_BIT_PATIENCE 100 /* in microsecs */ | |
32 | #define QDIO_BUSY_BIT_GIVE_UP 10000000 /* 10 seconds */ | |
33 | #define IQDIO_GLOBAL_LAPS 2 /* GLOBAL_LAPS are not used as we */ | |
34 | #define IQDIO_GLOBAL_LAPS_INT 1 /* don't global summary */ | |
35 | #define IQDIO_LOCAL_LAPS 4 | |
36 | #define IQDIO_LOCAL_LAPS_INT 1 | |
37 | #define IQDIO_GLOBAL_SUMMARY_CC_MASK 2 | |
38 | /*#define IQDIO_IQDC_INT_PARM 0x1234*/ | |
39 | ||
40 | #define QDIO_Q_LAPS 5 | |
41 | ||
0b642ede | 42 | #define QDIO_STORAGE_KEY PAGE_DEFAULT_KEY |
1da177e4 LT |
43 | |
44 | #define L2_CACHELINE_SIZE 256 | |
45 | #define INDICATORS_PER_CACHELINE (L2_CACHELINE_SIZE/sizeof(__u32)) | |
46 | ||
47 | #define QDIO_PERF "qdio_perf" | |
48 | ||
49 | /* must be a power of 2 */ | |
50 | /*#define QDIO_STATS_NUMBER 4 | |
51 | ||
52 | #define QDIO_STATS_CLASSES 2 | |
53 | #define QDIO_STATS_COUNT_NEEDED 2*/ | |
54 | ||
55 | #define QDIO_NO_USE_COUNT_TIMEOUT (1*HZ) /* wait for 1 sec on each q before | |
56 | exiting without having use_count | |
57 | of the queue to 0 */ | |
58 | ||
59 | #define QDIO_ESTABLISH_TIMEOUT (1*HZ) | |
60 | #define QDIO_ACTIVATE_TIMEOUT ((5*HZ)>>10) | |
61 | #define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ) | |
62 | #define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ) | |
1f8bdae9 | 63 | #define QDIO_FORCE_CHECK_TIMEOUT (10*HZ) |
1da177e4 LT |
64 | |
65 | enum qdio_irq_states { | |
66 | QDIO_IRQ_STATE_INACTIVE, | |
67 | QDIO_IRQ_STATE_ESTABLISHED, | |
68 | QDIO_IRQ_STATE_ACTIVE, | |
69 | QDIO_IRQ_STATE_STOPPED, | |
70 | QDIO_IRQ_STATE_CLEANUP, | |
71 | QDIO_IRQ_STATE_ERR, | |
72 | NR_QDIO_IRQ_STATES, | |
73 | }; | |
74 | ||
75 | /* used as intparm in do_IO: */ | |
76 | #define QDIO_DOING_SENSEID 0 | |
77 | #define QDIO_DOING_ESTABLISH 1 | |
78 | #define QDIO_DOING_ACTIVATE 2 | |
79 | #define QDIO_DOING_CLEANUP 3 | |
80 | ||
81 | /************************* DEBUG FACILITY STUFF *********************/ | |
82 | ||
83 | #define QDIO_DBF_HEX(ex,name,level,addr,len) \ | |
84 | do { \ | |
85 | if (ex) \ | |
86 | debug_exception(qdio_dbf_##name,level,(void*)(addr),len); \ | |
87 | else \ | |
88 | debug_event(qdio_dbf_##name,level,(void*)(addr),len); \ | |
89 | } while (0) | |
90 | #define QDIO_DBF_TEXT(ex,name,level,text) \ | |
91 | do { \ | |
92 | if (ex) \ | |
93 | debug_text_exception(qdio_dbf_##name,level,text); \ | |
94 | else \ | |
95 | debug_text_event(qdio_dbf_##name,level,text); \ | |
96 | } while (0) | |
97 | ||
98 | ||
99 | #define QDIO_DBF_HEX0(ex,name,addr,len) QDIO_DBF_HEX(ex,name,0,addr,len) | |
100 | #define QDIO_DBF_HEX1(ex,name,addr,len) QDIO_DBF_HEX(ex,name,1,addr,len) | |
101 | #define QDIO_DBF_HEX2(ex,name,addr,len) QDIO_DBF_HEX(ex,name,2,addr,len) | |
102 | #ifdef CONFIG_QDIO_DEBUG | |
103 | #define QDIO_DBF_HEX3(ex,name,addr,len) QDIO_DBF_HEX(ex,name,3,addr,len) | |
104 | #define QDIO_DBF_HEX4(ex,name,addr,len) QDIO_DBF_HEX(ex,name,4,addr,len) | |
105 | #define QDIO_DBF_HEX5(ex,name,addr,len) QDIO_DBF_HEX(ex,name,5,addr,len) | |
106 | #define QDIO_DBF_HEX6(ex,name,addr,len) QDIO_DBF_HEX(ex,name,6,addr,len) | |
107 | #else /* CONFIG_QDIO_DEBUG */ | |
108 | #define QDIO_DBF_HEX3(ex,name,addr,len) do {} while (0) | |
109 | #define QDIO_DBF_HEX4(ex,name,addr,len) do {} while (0) | |
110 | #define QDIO_DBF_HEX5(ex,name,addr,len) do {} while (0) | |
111 | #define QDIO_DBF_HEX6(ex,name,addr,len) do {} while (0) | |
112 | #endif /* CONFIG_QDIO_DEBUG */ | |
113 | ||
114 | #define QDIO_DBF_TEXT0(ex,name,text) QDIO_DBF_TEXT(ex,name,0,text) | |
115 | #define QDIO_DBF_TEXT1(ex,name,text) QDIO_DBF_TEXT(ex,name,1,text) | |
116 | #define QDIO_DBF_TEXT2(ex,name,text) QDIO_DBF_TEXT(ex,name,2,text) | |
117 | #ifdef CONFIG_QDIO_DEBUG | |
118 | #define QDIO_DBF_TEXT3(ex,name,text) QDIO_DBF_TEXT(ex,name,3,text) | |
119 | #define QDIO_DBF_TEXT4(ex,name,text) QDIO_DBF_TEXT(ex,name,4,text) | |
120 | #define QDIO_DBF_TEXT5(ex,name,text) QDIO_DBF_TEXT(ex,name,5,text) | |
121 | #define QDIO_DBF_TEXT6(ex,name,text) QDIO_DBF_TEXT(ex,name,6,text) | |
122 | #else /* CONFIG_QDIO_DEBUG */ | |
123 | #define QDIO_DBF_TEXT3(ex,name,text) do {} while (0) | |
124 | #define QDIO_DBF_TEXT4(ex,name,text) do {} while (0) | |
125 | #define QDIO_DBF_TEXT5(ex,name,text) do {} while (0) | |
126 | #define QDIO_DBF_TEXT6(ex,name,text) do {} while (0) | |
127 | #endif /* CONFIG_QDIO_DEBUG */ | |
128 | ||
129 | #define QDIO_DBF_SETUP_NAME "qdio_setup" | |
130 | #define QDIO_DBF_SETUP_LEN 8 | |
66a464db | 131 | #define QDIO_DBF_SETUP_PAGES 4 |
1da177e4 LT |
132 | #define QDIO_DBF_SETUP_NR_AREAS 1 |
133 | #ifdef CONFIG_QDIO_DEBUG | |
134 | #define QDIO_DBF_SETUP_LEVEL 6 | |
135 | #else /* CONFIG_QDIO_DEBUG */ | |
136 | #define QDIO_DBF_SETUP_LEVEL 2 | |
137 | #endif /* CONFIG_QDIO_DEBUG */ | |
138 | ||
139 | #define QDIO_DBF_SBAL_NAME "qdio_labs" /* sbal */ | |
140 | #define QDIO_DBF_SBAL_LEN 256 | |
66a464db | 141 | #define QDIO_DBF_SBAL_PAGES 4 |
1da177e4 LT |
142 | #define QDIO_DBF_SBAL_NR_AREAS 2 |
143 | #ifdef CONFIG_QDIO_DEBUG | |
144 | #define QDIO_DBF_SBAL_LEVEL 6 | |
145 | #else /* CONFIG_QDIO_DEBUG */ | |
146 | #define QDIO_DBF_SBAL_LEVEL 2 | |
147 | #endif /* CONFIG_QDIO_DEBUG */ | |
148 | ||
149 | #define QDIO_DBF_TRACE_NAME "qdio_trace" | |
150 | #define QDIO_DBF_TRACE_LEN 8 | |
151 | #define QDIO_DBF_TRACE_NR_AREAS 2 | |
152 | #ifdef CONFIG_QDIO_DEBUG | |
66a464db | 153 | #define QDIO_DBF_TRACE_PAGES 16 |
1da177e4 LT |
154 | #define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */ |
155 | #else /* CONFIG_QDIO_DEBUG */ | |
66a464db | 156 | #define QDIO_DBF_TRACE_PAGES 4 |
1da177e4 LT |
157 | #define QDIO_DBF_TRACE_LEVEL 2 |
158 | #endif /* CONFIG_QDIO_DEBUG */ | |
159 | ||
160 | #define QDIO_DBF_SENSE_NAME "qdio_sense" | |
161 | #define QDIO_DBF_SENSE_LEN 64 | |
66a464db | 162 | #define QDIO_DBF_SENSE_PAGES 2 |
1da177e4 LT |
163 | #define QDIO_DBF_SENSE_NR_AREAS 1 |
164 | #ifdef CONFIG_QDIO_DEBUG | |
165 | #define QDIO_DBF_SENSE_LEVEL 6 | |
166 | #else /* CONFIG_QDIO_DEBUG */ | |
167 | #define QDIO_DBF_SENSE_LEVEL 2 | |
168 | #endif /* CONFIG_QDIO_DEBUG */ | |
169 | ||
170 | #ifdef CONFIG_QDIO_DEBUG | |
171 | #define QDIO_TRACE_QTYPE QDIO_ZFCP_QFMT | |
172 | ||
173 | #define QDIO_DBF_SLSB_OUT_NAME "qdio_slsb_out" | |
174 | #define QDIO_DBF_SLSB_OUT_LEN QDIO_MAX_BUFFERS_PER_Q | |
66a464db | 175 | #define QDIO_DBF_SLSB_OUT_PAGES 256 |
1da177e4 LT |
176 | #define QDIO_DBF_SLSB_OUT_NR_AREAS 1 |
177 | #define QDIO_DBF_SLSB_OUT_LEVEL 6 | |
178 | ||
179 | #define QDIO_DBF_SLSB_IN_NAME "qdio_slsb_in" | |
180 | #define QDIO_DBF_SLSB_IN_LEN QDIO_MAX_BUFFERS_PER_Q | |
66a464db | 181 | #define QDIO_DBF_SLSB_IN_PAGES 256 |
1da177e4 LT |
182 | #define QDIO_DBF_SLSB_IN_NR_AREAS 1 |
183 | #define QDIO_DBF_SLSB_IN_LEVEL 6 | |
184 | #endif /* CONFIG_QDIO_DEBUG */ | |
185 | ||
186 | #define QDIO_PRINTK_HEADER QDIO_NAME ": " | |
187 | ||
188 | #if QDIO_VERBOSE_LEVEL>8 | |
189 | #define QDIO_PRINT_STUPID(x...) printk( KERN_DEBUG QDIO_PRINTK_HEADER x) | |
190 | #else | |
39b083fe | 191 | #define QDIO_PRINT_STUPID(x...) do { } while (0) |
1da177e4 LT |
192 | #endif |
193 | ||
194 | #if QDIO_VERBOSE_LEVEL>7 | |
195 | #define QDIO_PRINT_ALL(x...) printk( QDIO_PRINTK_HEADER x) | |
196 | #else | |
39b083fe | 197 | #define QDIO_PRINT_ALL(x...) do { } while (0) |
1da177e4 LT |
198 | #endif |
199 | ||
200 | #if QDIO_VERBOSE_LEVEL>6 | |
201 | #define QDIO_PRINT_INFO(x...) printk( QDIO_PRINTK_HEADER x) | |
202 | #else | |
39b083fe | 203 | #define QDIO_PRINT_INFO(x...) do { } while (0) |
1da177e4 LT |
204 | #endif |
205 | ||
206 | #if QDIO_VERBOSE_LEVEL>5 | |
207 | #define QDIO_PRINT_WARN(x...) printk( QDIO_PRINTK_HEADER x) | |
208 | #else | |
39b083fe | 209 | #define QDIO_PRINT_WARN(x...) do { } while (0) |
1da177e4 LT |
210 | #endif |
211 | ||
212 | #if QDIO_VERBOSE_LEVEL>4 | |
213 | #define QDIO_PRINT_ERR(x...) printk( QDIO_PRINTK_HEADER x) | |
214 | #else | |
39b083fe | 215 | #define QDIO_PRINT_ERR(x...) do { } while (0) |
1da177e4 LT |
216 | #endif |
217 | ||
218 | #if QDIO_VERBOSE_LEVEL>3 | |
219 | #define QDIO_PRINT_CRIT(x...) printk( QDIO_PRINTK_HEADER x) | |
220 | #else | |
39b083fe | 221 | #define QDIO_PRINT_CRIT(x...) do { } while (0) |
1da177e4 LT |
222 | #endif |
223 | ||
224 | #if QDIO_VERBOSE_LEVEL>2 | |
225 | #define QDIO_PRINT_ALERT(x...) printk( QDIO_PRINTK_HEADER x) | |
226 | #else | |
39b083fe | 227 | #define QDIO_PRINT_ALERT(x...) do { } while (0) |
1da177e4 LT |
228 | #endif |
229 | ||
230 | #if QDIO_VERBOSE_LEVEL>1 | |
231 | #define QDIO_PRINT_EMERG(x...) printk( QDIO_PRINTK_HEADER x) | |
232 | #else | |
39b083fe | 233 | #define QDIO_PRINT_EMERG(x...) do { } while (0) |
1da177e4 LT |
234 | #endif |
235 | ||
9163bb2e | 236 | #define QDIO_HEXDUMP16(importance,header,ptr) \ |
1da177e4 LT |
237 | QDIO_PRINT_##importance(header "%02x %02x %02x %02x " \ |
238 | "%02x %02x %02x %02x %02x %02x %02x %02x " \ | |
239 | "%02x %02x %02x %02x\n",*(((char*)ptr)), \ | |
240 | *(((char*)ptr)+1),*(((char*)ptr)+2), \ | |
241 | *(((char*)ptr)+3),*(((char*)ptr)+4), \ | |
242 | *(((char*)ptr)+5),*(((char*)ptr)+6), \ | |
243 | *(((char*)ptr)+7),*(((char*)ptr)+8), \ | |
244 | *(((char*)ptr)+9),*(((char*)ptr)+10), \ | |
245 | *(((char*)ptr)+11),*(((char*)ptr)+12), \ | |
246 | *(((char*)ptr)+13),*(((char*)ptr)+14), \ | |
247 | *(((char*)ptr)+15)); \ | |
248 | QDIO_PRINT_##importance(header "%02x %02x %02x %02x %02x %02x %02x %02x " \ | |
249 | "%02x %02x %02x %02x %02x %02x %02x %02x\n", \ | |
250 | *(((char*)ptr)+16),*(((char*)ptr)+17), \ | |
251 | *(((char*)ptr)+18),*(((char*)ptr)+19), \ | |
252 | *(((char*)ptr)+20),*(((char*)ptr)+21), \ | |
253 | *(((char*)ptr)+22),*(((char*)ptr)+23), \ | |
254 | *(((char*)ptr)+24),*(((char*)ptr)+25), \ | |
255 | *(((char*)ptr)+26),*(((char*)ptr)+27), \ | |
256 | *(((char*)ptr)+28),*(((char*)ptr)+29), \ | |
257 | *(((char*)ptr)+30),*(((char*)ptr)+31)); | |
258 | ||
259 | /****************** END OF DEBUG FACILITY STUFF *********************/ | |
260 | ||
261 | /* | |
262 | * Some instructions as assembly | |
263 | */ | |
8129ee16 FP |
264 | |
265 | static inline int | |
266 | do_sqbs(unsigned long sch, unsigned char state, int queue, | |
267 | unsigned int *start, unsigned int *count) | |
268 | { | |
347a8dc3 | 269 | #ifdef CONFIG_64BIT |
8129ee16 FP |
270 | register unsigned long _ccq asm ("0") = *count; |
271 | register unsigned long _sch asm ("1") = sch; | |
272 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; | |
273 | ||
94c12cc7 MS |
274 | asm volatile( |
275 | " .insn rsy,0xeb000000008A,%1,0,0(%2)" | |
276 | : "+d" (_ccq), "+d" (_queuestart) | |
277 | : "d" ((unsigned long)state), "d" (_sch) | |
278 | : "memory", "cc"); | |
8129ee16 FP |
279 | *count = _ccq & 0xff; |
280 | *start = _queuestart & 0xff; | |
281 | ||
282 | return (_ccq >> 32) & 0xff; | |
283 | #else | |
284 | return 0; | |
285 | #endif | |
286 | } | |
287 | ||
288 | static inline int | |
289 | do_eqbs(unsigned long sch, unsigned char *state, int queue, | |
290 | unsigned int *start, unsigned int *count) | |
291 | { | |
347a8dc3 | 292 | #ifdef CONFIG_64BIT |
8129ee16 FP |
293 | register unsigned long _ccq asm ("0") = *count; |
294 | register unsigned long _sch asm ("1") = sch; | |
295 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; | |
296 | unsigned long _state = 0; | |
297 | ||
94c12cc7 MS |
298 | asm volatile( |
299 | " .insn rrf,0xB99c0000,%1,%2,0,0" | |
300 | : "+d" (_ccq), "+d" (_queuestart), "+d" (_state) | |
301 | : "d" (_sch) | |
302 | : "memory", "cc" ); | |
8129ee16 FP |
303 | *count = _ccq & 0xff; |
304 | *start = _queuestart & 0xff; | |
305 | *state = _state & 0xff; | |
306 | ||
307 | return (_ccq >> 32) & 0xff; | |
308 | #else | |
309 | return 0; | |
310 | #endif | |
311 | } | |
312 | ||
313 | ||
4448aaf0 | 314 | static inline int |
a8237fc4 | 315 | do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2) |
1da177e4 | 316 | { |
94c12cc7 MS |
317 | register unsigned long reg0 asm ("0") = 2; |
318 | register struct subchannel_id reg1 asm ("1") = schid; | |
319 | register unsigned long reg2 asm ("2") = mask1; | |
320 | register unsigned long reg3 asm ("3") = mask2; | |
1da177e4 LT |
321 | int cc; |
322 | ||
94c12cc7 MS |
323 | asm volatile( |
324 | " siga 0\n" | |
325 | " ipm %0\n" | |
326 | " srl %0,28\n" | |
1da177e4 | 327 | : "=d" (cc) |
94c12cc7 | 328 | : "d" (reg0), "d" (reg1), "d" (reg2), "d" (reg3) : "cc"); |
1da177e4 LT |
329 | return cc; |
330 | } | |
331 | ||
4448aaf0 | 332 | static inline int |
a8237fc4 | 333 | do_siga_input(struct subchannel_id schid, unsigned int mask) |
1da177e4 | 334 | { |
94c12cc7 MS |
335 | register unsigned long reg0 asm ("0") = 1; |
336 | register struct subchannel_id reg1 asm ("1") = schid; | |
337 | register unsigned long reg2 asm ("2") = mask; | |
1da177e4 LT |
338 | int cc; |
339 | ||
94c12cc7 MS |
340 | asm volatile( |
341 | " siga 0\n" | |
342 | " ipm %0\n" | |
343 | " srl %0,28\n" | |
1da177e4 | 344 | : "=d" (cc) |
94c12cc7 | 345 | : "d" (reg0), "d" (reg1), "d" (reg2) : "cc", "memory"); |
1da177e4 LT |
346 | return cc; |
347 | } | |
348 | ||
4448aaf0 | 349 | static inline int |
a8237fc4 | 350 | do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb, |
8129ee16 | 351 | unsigned int fc) |
1da177e4 | 352 | { |
94c12cc7 MS |
353 | register unsigned long __fc asm("0") = fc; |
354 | register unsigned long __schid asm("1") = schid; | |
355 | register unsigned long __mask asm("2") = mask; | |
1da177e4 | 356 | int cc; |
94c12cc7 MS |
357 | |
358 | asm volatile( | |
359 | " siga 0\n" | |
360 | "0: ipm %0\n" | |
361 | " srl %0,28\n" | |
362 | "1:\n" | |
363 | EX_TABLE(0b,1b) | |
364 | : "=d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask) | |
365 | : "0" (QDIO_SIGA_ERROR_ACCESS_EXCEPTION) | |
366 | : "cc", "memory"); | |
367 | (*bb) = ((unsigned int) __fc) >> 31; | |
1da177e4 LT |
368 | return cc; |
369 | } | |
370 | ||
4448aaf0 | 371 | static inline unsigned long |
1da177e4 LT |
372 | do_clear_global_summary(void) |
373 | { | |
94c12cc7 MS |
374 | register unsigned long __fn asm("1") = 3; |
375 | register unsigned long __tmp asm("2"); | |
376 | register unsigned long __time asm("3"); | |
377 | ||
378 | asm volatile( | |
379 | " .insn rre,0xb2650000,2,0" | |
380 | : "+d" (__fn), "=d" (__tmp), "=d" (__time)); | |
381 | return __time; | |
1da177e4 LT |
382 | } |
383 | ||
384 | /* | |
385 | * QDIO device commands returned by extended Sense-ID | |
386 | */ | |
387 | #define DEFAULT_ESTABLISH_QS_CMD 0x1b | |
388 | #define DEFAULT_ESTABLISH_QS_COUNT 0x1000 | |
389 | #define DEFAULT_ACTIVATE_QS_CMD 0x1f | |
390 | #define DEFAULT_ACTIVATE_QS_COUNT 0 | |
391 | ||
392 | /* | |
393 | * additional CIWs returned by extended Sense-ID | |
394 | */ | |
395 | #define CIW_TYPE_EQUEUE 0x3 /* establish QDIO queues */ | |
396 | #define CIW_TYPE_AQUEUE 0x4 /* activate QDIO queues */ | |
397 | ||
398 | #define QDIO_CHSC_RESPONSE_CODE_OK 1 | |
399 | /* flags for st qdio sch data */ | |
400 | #define CHSC_FLAG_QDIO_CAPABILITY 0x80 | |
401 | #define CHSC_FLAG_VALIDITY 0x40 | |
402 | ||
403 | #define CHSC_FLAG_SIGA_INPUT_NECESSARY 0x40 | |
404 | #define CHSC_FLAG_SIGA_OUTPUT_NECESSARY 0x20 | |
405 | #define CHSC_FLAG_SIGA_SYNC_NECESSARY 0x10 | |
406 | #define CHSC_FLAG_SIGA_SYNC_DONE_ON_THININTS 0x08 | |
407 | #define CHSC_FLAG_SIGA_SYNC_DONE_ON_OUTB_PCIS 0x04 | |
408 | ||
1da177e4 | 409 | struct qdio_perf_stats { |
00c0c646 UB |
410 | #ifdef CONFIG_64BIT |
411 | atomic64_t tl_runs; | |
412 | atomic64_t outbound_tl_runs; | |
413 | atomic64_t outbound_tl_runs_resched; | |
414 | atomic64_t inbound_tl_runs; | |
415 | atomic64_t inbound_tl_runs_resched; | |
416 | atomic64_t inbound_thin_tl_runs; | |
417 | atomic64_t inbound_thin_tl_runs_resched; | |
418 | ||
419 | atomic64_t siga_outs; | |
420 | atomic64_t siga_ins; | |
421 | atomic64_t siga_syncs; | |
422 | atomic64_t pcis; | |
423 | atomic64_t thinints; | |
424 | atomic64_t fast_reqs; | |
425 | ||
426 | atomic64_t outbound_cnt; | |
427 | atomic64_t inbound_cnt; | |
428 | #else /* CONFIG_64BIT */ | |
429 | atomic_t tl_runs; | |
430 | atomic_t outbound_tl_runs; | |
431 | atomic_t outbound_tl_runs_resched; | |
432 | atomic_t inbound_tl_runs; | |
433 | atomic_t inbound_tl_runs_resched; | |
434 | atomic_t inbound_thin_tl_runs; | |
435 | atomic_t inbound_thin_tl_runs_resched; | |
436 | ||
437 | atomic_t siga_outs; | |
438 | atomic_t siga_ins; | |
439 | atomic_t siga_syncs; | |
440 | atomic_t pcis; | |
441 | atomic_t thinints; | |
442 | atomic_t fast_reqs; | |
443 | ||
444 | atomic_t outbound_cnt; | |
445 | atomic_t inbound_cnt; | |
446 | #endif /* CONFIG_64BIT */ | |
1da177e4 | 447 | }; |
1da177e4 | 448 | |
1da177e4 LT |
449 | /* unlikely as the later the better */ |
450 | #define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q) | |
451 | #define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \ | |
452 | qdio_siga_sync(q,~0U,~0U) | |
453 | #define SYNC_MEMORY_ALL_OUTB if (unlikely(q->siga_sync)) \ | |
454 | qdio_siga_sync(q,~0U,0) | |
455 | ||
456 | #define NOW qdio_get_micros() | |
457 | #define SAVE_TIMESTAMP(q) q->timing.last_transfer_time=NOW | |
458 | #define GET_SAVED_TIMESTAMP(q) (q->timing.last_transfer_time) | |
459 | #define SAVE_FRONTIER(q,val) q->last_move_ftc=val | |
460 | #define GET_SAVED_FRONTIER(q) (q->last_move_ftc) | |
461 | ||
462 | #define MY_MODULE_STRING(x) #x | |
463 | ||
347a8dc3 | 464 | #ifdef CONFIG_64BIT |
1da177e4 | 465 | #define QDIO_GET_ADDR(x) ((__u32)(unsigned long)x) |
347a8dc3 | 466 | #else /* CONFIG_64BIT */ |
1da177e4 | 467 | #define QDIO_GET_ADDR(x) ((__u32)(long)x) |
347a8dc3 | 468 | #endif /* CONFIG_64BIT */ |
1da177e4 | 469 | |
1da177e4 LT |
470 | struct qdio_q { |
471 | volatile struct slsb slsb; | |
472 | ||
473 | char unused[QDIO_MAX_BUFFERS_PER_Q]; | |
474 | ||
8129ee16 | 475 | __u32 * dev_st_chg_ind; |
1da177e4 LT |
476 | |
477 | int is_input_q; | |
a8237fc4 | 478 | struct subchannel_id schid; |
1da177e4 LT |
479 | struct ccw_device *cdev; |
480 | ||
481 | unsigned int is_iqdio_q; | |
482 | unsigned int is_thinint_q; | |
483 | ||
484 | /* bit 0 means queue 0, bit 1 means queue 1, ... */ | |
485 | unsigned int mask; | |
486 | unsigned int q_no; | |
487 | ||
488 | qdio_handler_t (*handler); | |
489 | ||
490 | /* points to the next buffer to be checked for having | |
491 | * been processed by the card (outbound) | |
492 | * or to the next buffer the program should check for (inbound) */ | |
493 | volatile int first_to_check; | |
494 | /* and the last time it was: */ | |
495 | volatile int last_move_ftc; | |
496 | ||
497 | atomic_t number_of_buffers_used; | |
498 | atomic_t polling; | |
499 | ||
500 | unsigned int siga_in; | |
501 | unsigned int siga_out; | |
502 | unsigned int siga_sync; | |
503 | unsigned int siga_sync_done_on_thinints; | |
504 | unsigned int siga_sync_done_on_outb_tis; | |
505 | unsigned int hydra_gives_outbound_pcis; | |
506 | ||
507 | /* used to save beginning position when calling dd_handlers */ | |
508 | int first_element_to_kick; | |
509 | ||
510 | atomic_t use_count; | |
511 | atomic_t is_in_shutdown; | |
512 | ||
513 | void *irq_ptr; | |
514 | ||
1da177e4 | 515 | struct timer_list timer; |
1f8bdae9 | 516 | #ifdef QDIO_USE_TIMERS_FOR_POLLING |
1da177e4 LT |
517 | atomic_t timer_already_set; |
518 | spinlock_t timer_lock; | |
519 | #else /* QDIO_USE_TIMERS_FOR_POLLING */ | |
520 | struct tasklet_struct tasklet; | |
521 | #endif /* QDIO_USE_TIMERS_FOR_POLLING */ | |
522 | ||
8129ee16 | 523 | |
1da177e4 LT |
524 | enum qdio_irq_states state; |
525 | ||
526 | /* used to store the error condition during a data transfer */ | |
527 | unsigned int qdio_error; | |
528 | unsigned int siga_error; | |
529 | unsigned int error_status_flags; | |
530 | ||
531 | /* list of interesting queues */ | |
532 | volatile struct qdio_q *list_next; | |
533 | volatile struct qdio_q *list_prev; | |
534 | ||
535 | struct sl *sl; | |
536 | volatile struct sbal *sbal[QDIO_MAX_BUFFERS_PER_Q]; | |
537 | ||
538 | struct qdio_buffer *qdio_buffers[QDIO_MAX_BUFFERS_PER_Q]; | |
539 | ||
540 | unsigned long int_parm; | |
541 | ||
542 | /*struct { | |
543 | int in_bh_check_limit; | |
544 | int threshold; | |
545 | } threshold_classes[QDIO_STATS_CLASSES];*/ | |
546 | ||
547 | struct { | |
548 | /* inbound: the time to stop polling | |
549 | outbound: the time to kick peer */ | |
550 | int threshold; /* the real value */ | |
551 | ||
552 | /* outbound: last time of do_QDIO | |
553 | inbound: last time of noticing incoming data */ | |
554 | /*__u64 last_transfer_times[QDIO_STATS_NUMBER]; | |
555 | int last_transfer_index; */ | |
556 | ||
557 | __u64 last_transfer_time; | |
558 | __u64 busy_start; | |
559 | } timing; | |
560 | atomic_t busy_siga_counter; | |
561 | unsigned int queue_type; | |
1f8bdae9 | 562 | unsigned int is_pci_out; |
1da177e4 LT |
563 | |
564 | /* leave this member at the end. won't be cleared in qdio_fill_qs */ | |
565 | struct slib *slib; /* a page is allocated under this pointer, | |
566 | sl points into this page, offset PAGE_SIZE/2 | |
567 | (after slib) */ | |
568 | } __attribute__ ((aligned(256))); | |
569 | ||
570 | struct qdio_irq { | |
571 | __u32 * volatile dev_st_chg_ind; | |
572 | ||
573 | unsigned long int_parm; | |
a8237fc4 | 574 | struct subchannel_id schid; |
1da177e4 LT |
575 | |
576 | unsigned int is_iqdio_irq; | |
577 | unsigned int is_thinint_irq; | |
578 | unsigned int hydra_gives_outbound_pcis; | |
579 | unsigned int sync_done_on_outb_pcis; | |
580 | ||
8129ee16 FP |
581 | /* QEBSM facility */ |
582 | unsigned int is_qebsm; | |
583 | unsigned long sch_token; | |
584 | ||
1da177e4 LT |
585 | enum qdio_irq_states state; |
586 | ||
587 | unsigned int no_input_qs; | |
588 | unsigned int no_output_qs; | |
589 | ||
590 | unsigned char qdioac; | |
591 | ||
592 | struct ccw1 ccw; | |
593 | ||
594 | struct ciw equeue; | |
595 | struct ciw aqueue; | |
596 | ||
597 | struct qib qib; | |
598 | ||
599 | void (*original_int_handler) (struct ccw_device *, | |
600 | unsigned long, struct irb *); | |
601 | ||
602 | /* leave these four members together at the end. won't be cleared in qdio_fill_irq */ | |
603 | struct qdr *qdr; | |
604 | struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ]; | |
605 | struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ]; | |
606 | struct semaphore setting_up_sema; | |
607 | }; | |
608 | #endif |