diff options
Diffstat (limited to 'drivers/s390/cio/qdio.h')
-rw-r--r-- | drivers/s390/cio/qdio.h | 837 |
1 files changed, 289 insertions, 548 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h index c3df6b2c38b7..c1a70985abfa 100644 --- a/drivers/s390/cio/qdio.h +++ b/drivers/s390/cio/qdio.h | |||
@@ -1,66 +1,20 @@ | |||
1 | /* | ||
2 | * linux/drivers/s390/cio/qdio.h | ||
3 | * | ||
4 | * Copyright 2000,2008 IBM Corp. | ||
5 | * Author(s): Utz Bacher <utz.bacher@de.ibm.com> | ||
6 | * Jan Glauber <jang@linux.vnet.ibm.com> | ||
7 | */ | ||
1 | #ifndef _CIO_QDIO_H | 8 | #ifndef _CIO_QDIO_H |
2 | #define _CIO_QDIO_H | 9 | #define _CIO_QDIO_H |
3 | 10 | ||
4 | #include <asm/page.h> | 11 | #include <asm/page.h> |
12 | #include <asm/schid.h> | ||
13 | #include "chsc.h" | ||
5 | 14 | ||
6 | #include "schid.h" | 15 | #define QDIO_BUSY_BIT_PATIENCE 100 /* 100 microseconds */ |
7 | 16 | #define QDIO_BUSY_BIT_GIVE_UP 2000000 /* 2 seconds = eternity */ | |
8 | #ifdef CONFIG_QDIO_DEBUG | 17 | #define QDIO_INPUT_THRESHOLD 500 /* 500 microseconds */ |
9 | #define QDIO_VERBOSE_LEVEL 9 | ||
10 | #else /* CONFIG_QDIO_DEBUG */ | ||
11 | #define QDIO_VERBOSE_LEVEL 5 | ||
12 | #endif /* CONFIG_QDIO_DEBUG */ | ||
13 | #define QDIO_USE_PROCESSING_STATE | ||
14 | |||
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 | |||
42 | #define QDIO_STORAGE_KEY PAGE_DEFAULT_KEY | ||
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_CLEANUP_CLEAR_TIMEOUT (20*HZ) | ||
61 | #define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ) | ||
62 | #define QDIO_FORCE_CHECK_TIMEOUT (10*HZ) | ||
63 | #define QDIO_ACTIVATE_TIMEOUT (5) /* 5 ms */ | ||
64 | 18 | ||
65 | enum qdio_irq_states { | 19 | enum qdio_irq_states { |
66 | QDIO_IRQ_STATE_INACTIVE, | 20 | QDIO_IRQ_STATE_INACTIVE, |
@@ -72,565 +26,352 @@ enum qdio_irq_states { | |||
72 | NR_QDIO_IRQ_STATES, | 26 | NR_QDIO_IRQ_STATES, |
73 | }; | 27 | }; |
74 | 28 | ||
75 | /* used as intparm in do_IO: */ | 29 | /* used as intparm in do_IO */ |
76 | #define QDIO_DOING_SENSEID 0 | 30 | #define QDIO_DOING_ESTABLISH 1 |
77 | #define QDIO_DOING_ESTABLISH 1 | 31 | #define QDIO_DOING_ACTIVATE 2 |
78 | #define QDIO_DOING_ACTIVATE 2 | 32 | #define QDIO_DOING_CLEANUP 3 |
79 | #define QDIO_DOING_CLEANUP 3 | 33 | |
80 | 34 | #define SLSB_STATE_NOT_INIT 0x0 | |
81 | /************************* DEBUG FACILITY STUFF *********************/ | 35 | #define SLSB_STATE_EMPTY 0x1 |
82 | 36 | #define SLSB_STATE_PRIMED 0x2 | |
83 | #define QDIO_DBF_HEX(ex,name,level,addr,len) \ | 37 | #define SLSB_STATE_HALTED 0xe |
84 | do { \ | 38 | #define SLSB_STATE_ERROR 0xf |
85 | if (ex) \ | 39 | #define SLSB_TYPE_INPUT 0x0 |
86 | debug_exception(qdio_dbf_##name,level,(void*)(addr),len); \ | 40 | #define SLSB_TYPE_OUTPUT 0x20 |
87 | else \ | 41 | #define SLSB_OWNER_PROG 0x80 |
88 | debug_event(qdio_dbf_##name,level,(void*)(addr),len); \ | 42 | #define SLSB_OWNER_CU 0x40 |
89 | } while (0) | 43 | |
90 | #define QDIO_DBF_TEXT(ex,name,level,text) \ | 44 | #define SLSB_P_INPUT_NOT_INIT \ |
91 | do { \ | 45 | (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_NOT_INIT) /* 0x80 */ |
92 | if (ex) \ | 46 | #define SLSB_P_INPUT_ACK \ |
93 | debug_text_exception(qdio_dbf_##name,level,text); \ | 47 | (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_EMPTY) /* 0x81 */ |
94 | else \ | 48 | #define SLSB_CU_INPUT_EMPTY \ |
95 | debug_text_event(qdio_dbf_##name,level,text); \ | 49 | (SLSB_OWNER_CU | SLSB_TYPE_INPUT | SLSB_STATE_EMPTY) /* 0x41 */ |
96 | } while (0) | 50 | #define SLSB_P_INPUT_PRIMED \ |
97 | 51 | (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_PRIMED) /* 0x82 */ | |
98 | 52 | #define SLSB_P_INPUT_HALTED \ | |
99 | #define QDIO_DBF_HEX0(ex,name,addr,len) QDIO_DBF_HEX(ex,name,0,addr,len) | 53 | (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_HALTED) /* 0x8e */ |
100 | #define QDIO_DBF_HEX1(ex,name,addr,len) QDIO_DBF_HEX(ex,name,1,addr,len) | 54 | #define SLSB_P_INPUT_ERROR \ |
101 | #define QDIO_DBF_HEX2(ex,name,addr,len) QDIO_DBF_HEX(ex,name,2,addr,len) | 55 | (SLSB_OWNER_PROG | SLSB_TYPE_INPUT | SLSB_STATE_ERROR) /* 0x8f */ |
102 | #ifdef CONFIG_QDIO_DEBUG | 56 | #define SLSB_P_OUTPUT_NOT_INIT \ |
103 | #define QDIO_DBF_HEX3(ex,name,addr,len) QDIO_DBF_HEX(ex,name,3,addr,len) | 57 | (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_NOT_INIT) /* 0xa0 */ |
104 | #define QDIO_DBF_HEX4(ex,name,addr,len) QDIO_DBF_HEX(ex,name,4,addr,len) | 58 | #define SLSB_P_OUTPUT_EMPTY \ |
105 | #define QDIO_DBF_HEX5(ex,name,addr,len) QDIO_DBF_HEX(ex,name,5,addr,len) | 59 | (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_EMPTY) /* 0xa1 */ |
106 | #define QDIO_DBF_HEX6(ex,name,addr,len) QDIO_DBF_HEX(ex,name,6,addr,len) | 60 | #define SLSB_CU_OUTPUT_PRIMED \ |
107 | #else /* CONFIG_QDIO_DEBUG */ | 61 | (SLSB_OWNER_CU | SLSB_TYPE_OUTPUT | SLSB_STATE_PRIMED) /* 0x62 */ |
108 | #define QDIO_DBF_HEX3(ex,name,addr,len) do {} while (0) | 62 | #define SLSB_P_OUTPUT_HALTED \ |
109 | #define QDIO_DBF_HEX4(ex,name,addr,len) do {} while (0) | 63 | (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_HALTED) /* 0xae */ |
110 | #define QDIO_DBF_HEX5(ex,name,addr,len) do {} while (0) | 64 | #define SLSB_P_OUTPUT_ERROR \ |
111 | #define QDIO_DBF_HEX6(ex,name,addr,len) do {} while (0) | 65 | (SLSB_OWNER_PROG | SLSB_TYPE_OUTPUT | SLSB_STATE_ERROR) /* 0xaf */ |
112 | #endif /* CONFIG_QDIO_DEBUG */ | 66 | |
113 | 67 | #define SLSB_ERROR_DURING_LOOKUP 0xff | |
114 | #define QDIO_DBF_TEXT0(ex,name,text) QDIO_DBF_TEXT(ex,name,0,text) | 68 | |
115 | #define QDIO_DBF_TEXT1(ex,name,text) QDIO_DBF_TEXT(ex,name,1,text) | 69 | /* additional CIWs returned by extended Sense-ID */ |
116 | #define QDIO_DBF_TEXT2(ex,name,text) QDIO_DBF_TEXT(ex,name,2,text) | 70 | #define CIW_TYPE_EQUEUE 0x3 /* establish QDIO queues */ |
117 | #ifdef CONFIG_QDIO_DEBUG | 71 | #define CIW_TYPE_AQUEUE 0x4 /* activate QDIO queues */ |
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 | ||
131 | #define QDIO_DBF_SETUP_PAGES 4 | ||
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 | ||
141 | #define QDIO_DBF_SBAL_PAGES 4 | ||
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 | ||
153 | #define QDIO_DBF_TRACE_PAGES 16 | ||
154 | #define QDIO_DBF_TRACE_LEVEL 4 /* -------- could be even more verbose here */ | ||
155 | #else /* CONFIG_QDIO_DEBUG */ | ||
156 | #define QDIO_DBF_TRACE_PAGES 4 | ||
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 | ||
162 | #define QDIO_DBF_SENSE_PAGES 2 | ||
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 | ||
175 | #define QDIO_DBF_SLSB_OUT_PAGES 256 | ||
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 | ||
181 | #define QDIO_DBF_SLSB_IN_PAGES 256 | ||
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 | ||
191 | #define QDIO_PRINT_STUPID(x...) do { } while (0) | ||
192 | #endif | ||
193 | |||
194 | #if QDIO_VERBOSE_LEVEL>7 | ||
195 | #define QDIO_PRINT_ALL(x...) printk( QDIO_PRINTK_HEADER x) | ||
196 | #else | ||
197 | #define QDIO_PRINT_ALL(x...) do { } while (0) | ||
198 | #endif | ||
199 | |||
200 | #if QDIO_VERBOSE_LEVEL>6 | ||
201 | #define QDIO_PRINT_INFO(x...) printk( QDIO_PRINTK_HEADER x) | ||
202 | #else | ||
203 | #define QDIO_PRINT_INFO(x...) do { } while (0) | ||
204 | #endif | ||
205 | |||
206 | #if QDIO_VERBOSE_LEVEL>5 | ||
207 | #define QDIO_PRINT_WARN(x...) printk( QDIO_PRINTK_HEADER x) | ||
208 | #else | ||
209 | #define QDIO_PRINT_WARN(x...) do { } while (0) | ||
210 | #endif | ||
211 | |||
212 | #if QDIO_VERBOSE_LEVEL>4 | ||
213 | #define QDIO_PRINT_ERR(x...) printk( QDIO_PRINTK_HEADER x) | ||
214 | #else | ||
215 | #define QDIO_PRINT_ERR(x...) do { } while (0) | ||
216 | #endif | ||
217 | |||
218 | #if QDIO_VERBOSE_LEVEL>3 | ||
219 | #define QDIO_PRINT_CRIT(x...) printk( QDIO_PRINTK_HEADER x) | ||
220 | #else | ||
221 | #define QDIO_PRINT_CRIT(x...) do { } while (0) | ||
222 | #endif | ||
223 | 72 | ||
224 | #if QDIO_VERBOSE_LEVEL>2 | 73 | /* flags for st qdio sch data */ |
225 | #define QDIO_PRINT_ALERT(x...) printk( QDIO_PRINTK_HEADER x) | 74 | #define CHSC_FLAG_QDIO_CAPABILITY 0x80 |
226 | #else | 75 | #define CHSC_FLAG_VALIDITY 0x40 |
227 | #define QDIO_PRINT_ALERT(x...) do { } while (0) | 76 | |
228 | #endif | 77 | /* qdio adapter-characteristics-1 flag */ |
78 | #define AC1_SIGA_INPUT_NEEDED 0x40 /* process input queues */ | ||
79 | #define AC1_SIGA_OUTPUT_NEEDED 0x20 /* process output queues */ | ||
80 | #define AC1_SIGA_SYNC_NEEDED 0x10 /* ask hypervisor to sync */ | ||
81 | #define AC1_AUTOMATIC_SYNC_ON_THININT 0x08 /* set by hypervisor */ | ||
82 | #define AC1_AUTOMATIC_SYNC_ON_OUT_PCI 0x04 /* set by hypervisor */ | ||
83 | #define AC1_SC_QEBSM_AVAILABLE 0x02 /* available for subchannel */ | ||
84 | #define AC1_SC_QEBSM_ENABLED 0x01 /* enabled for subchannel */ | ||
229 | 85 | ||
230 | #if QDIO_VERBOSE_LEVEL>1 | 86 | #ifdef CONFIG_64BIT |
231 | #define QDIO_PRINT_EMERG(x...) printk( QDIO_PRINTK_HEADER x) | 87 | static inline int do_sqbs(u64 token, unsigned char state, int queue, |
232 | #else | 88 | int *start, int *count) |
233 | #define QDIO_PRINT_EMERG(x...) do { } while (0) | 89 | { |
234 | #endif | 90 | register unsigned long _ccq asm ("0") = *count; |
235 | 91 | register unsigned long _token asm ("1") = token; | |
236 | #define QDIO_HEXDUMP16(importance,header,ptr) \ | 92 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; |
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 | 93 | ||
261 | /* | 94 | asm volatile( |
262 | * Some instructions as assembly | 95 | " .insn rsy,0xeb000000008A,%1,0,0(%2)" |
263 | */ | 96 | : "+d" (_ccq), "+d" (_queuestart) |
97 | : "d" ((unsigned long)state), "d" (_token) | ||
98 | : "memory", "cc"); | ||
99 | *count = _ccq & 0xff; | ||
100 | *start = _queuestart & 0xff; | ||
264 | 101 | ||
265 | static inline int | 102 | return (_ccq >> 32) & 0xff; |
266 | do_sqbs(unsigned long sch, unsigned char state, int queue, | ||
267 | unsigned int *start, unsigned int *count) | ||
268 | { | ||
269 | #ifdef CONFIG_64BIT | ||
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 | |||
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"); | ||
279 | *count = _ccq & 0xff; | ||
280 | *start = _queuestart & 0xff; | ||
281 | |||
282 | return (_ccq >> 32) & 0xff; | ||
283 | #else | ||
284 | return 0; | ||
285 | #endif | ||
286 | } | 103 | } |
287 | 104 | ||
288 | static inline int | 105 | static inline int do_eqbs(u64 token, unsigned char *state, int queue, |
289 | do_eqbs(unsigned long sch, unsigned char *state, int queue, | 106 | int *start, int *count) |
290 | unsigned int *start, unsigned int *count) | ||
291 | { | 107 | { |
292 | #ifdef CONFIG_64BIT | ||
293 | register unsigned long _ccq asm ("0") = *count; | 108 | register unsigned long _ccq asm ("0") = *count; |
294 | register unsigned long _sch asm ("1") = sch; | 109 | register unsigned long _token asm ("1") = token; |
295 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; | 110 | unsigned long _queuestart = ((unsigned long)queue << 32) | *start; |
296 | unsigned long _state = 0; | 111 | unsigned long _state = 0; |
297 | 112 | ||
298 | asm volatile( | 113 | asm volatile( |
299 | " .insn rrf,0xB99c0000,%1,%2,0,0" | 114 | " .insn rrf,0xB99c0000,%1,%2,0,0" |
300 | : "+d" (_ccq), "+d" (_queuestart), "+d" (_state) | 115 | : "+d" (_ccq), "+d" (_queuestart), "+d" (_state) |
301 | : "d" (_sch) | 116 | : "d" (_token) |
302 | : "memory", "cc" ); | 117 | : "memory", "cc"); |
303 | *count = _ccq & 0xff; | 118 | *count = _ccq & 0xff; |
304 | *start = _queuestart & 0xff; | 119 | *start = _queuestart & 0xff; |
305 | *state = _state & 0xff; | 120 | *state = _state & 0xff; |
306 | 121 | ||
307 | return (_ccq >> 32) & 0xff; | 122 | return (_ccq >> 32) & 0xff; |
308 | #else | ||
309 | return 0; | ||
310 | #endif | ||
311 | } | 123 | } |
124 | #else | ||
125 | static inline int do_sqbs(u64 token, unsigned char state, int queue, | ||
126 | int *start, int *count) { return 0; } | ||
127 | static inline int do_eqbs(u64 token, unsigned char *state, int queue, | ||
128 | int *start, int *count) { return 0; } | ||
129 | #endif /* CONFIG_64BIT */ | ||
312 | 130 | ||
131 | struct qdio_irq; | ||
313 | 132 | ||
314 | static inline int | 133 | struct siga_flag { |
315 | do_siga_sync(struct subchannel_id schid, unsigned int mask1, unsigned int mask2) | 134 | u8 input:1; |
316 | { | 135 | u8 output:1; |
317 | register unsigned long reg0 asm ("0") = 2; | 136 | u8 sync:1; |
318 | register struct subchannel_id reg1 asm ("1") = schid; | 137 | u8 no_sync_ti:1; |
319 | register unsigned long reg2 asm ("2") = mask1; | 138 | u8 no_sync_out_ti:1; |
320 | register unsigned long reg3 asm ("3") = mask2; | 139 | u8 no_sync_out_pci:1; |
321 | int cc; | 140 | u8:2; |
322 | 141 | } __attribute__ ((packed)); | |
323 | asm volatile( | ||
324 | " siga 0\n" | ||
325 | " ipm %0\n" | ||
326 | " srl %0,28\n" | ||
327 | : "=d" (cc) | ||
328 | : "d" (reg0), "d" (reg1), "d" (reg2), "d" (reg3) : "cc"); | ||
329 | return cc; | ||
330 | } | ||
331 | |||
332 | static inline int | ||
333 | do_siga_input(struct subchannel_id schid, unsigned int mask) | ||
334 | { | ||
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; | ||
338 | int cc; | ||
339 | |||
340 | asm volatile( | ||
341 | " siga 0\n" | ||
342 | " ipm %0\n" | ||
343 | " srl %0,28\n" | ||
344 | : "=d" (cc) | ||
345 | : "d" (reg0), "d" (reg1), "d" (reg2) : "cc", "memory"); | ||
346 | return cc; | ||
347 | } | ||
348 | |||
349 | static inline int | ||
350 | do_siga_output(unsigned long schid, unsigned long mask, __u32 *bb, | ||
351 | unsigned int fc) | ||
352 | { | ||
353 | register unsigned long __fc asm("0") = fc; | ||
354 | register unsigned long __schid asm("1") = schid; | ||
355 | register unsigned long __mask asm("2") = mask; | ||
356 | int cc; | ||
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; | ||
368 | return cc; | ||
369 | } | ||
370 | |||
371 | static inline unsigned long | ||
372 | do_clear_global_summary(void) | ||
373 | { | ||
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; | ||
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 | 142 | ||
409 | struct qdio_chsc_ssqd { | 143 | struct chsc_ssqd_area { |
410 | struct chsc_header request; | 144 | struct chsc_header request; |
411 | u16 reserved1:10; | 145 | u16:10; |
412 | u16 ssid:2; | 146 | u8 ssid:2; |
413 | u16 fmt:4; | 147 | u8 fmt:4; |
414 | u16 first_sch; | 148 | u16 first_sch; |
415 | u16 reserved2; | 149 | u16:16; |
416 | u16 last_sch; | 150 | u16 last_sch; |
417 | u32 reserved3; | 151 | u32:32; |
418 | struct chsc_header response; | 152 | struct chsc_header response; |
419 | u32 reserved4; | 153 | u32:32; |
420 | u8 flags; | 154 | struct qdio_ssqd_desc qdio_ssqd; |
421 | u8 reserved5; | 155 | } __attribute__ ((packed)); |
422 | u16 sch; | ||
423 | u8 qfmt; | ||
424 | u8 parm; | ||
425 | u8 qdioac1; | ||
426 | u8 sch_class; | ||
427 | u8 pct; | ||
428 | u8 icnt; | ||
429 | u8 reserved7; | ||
430 | u8 ocnt; | ||
431 | u8 reserved8; | ||
432 | u8 mbccnt; | ||
433 | u16 qdioac2; | ||
434 | u64 sch_token; | ||
435 | }; | ||
436 | 156 | ||
437 | struct qdio_perf_stats { | 157 | struct scssc_area { |
438 | #ifdef CONFIG_64BIT | 158 | struct chsc_header request; |
439 | atomic64_t tl_runs; | 159 | u16 operation_code; |
440 | atomic64_t outbound_tl_runs; | 160 | u16:16; |
441 | atomic64_t outbound_tl_runs_resched; | 161 | u32:32; |
442 | atomic64_t inbound_tl_runs; | 162 | u32:32; |
443 | atomic64_t inbound_tl_runs_resched; | 163 | u64 summary_indicator_addr; |
444 | atomic64_t inbound_thin_tl_runs; | 164 | u64 subchannel_indicator_addr; |
445 | atomic64_t inbound_thin_tl_runs_resched; | 165 | u32 ks:4; |
446 | 166 | u32 kc:4; | |
447 | atomic64_t siga_outs; | 167 | u32:21; |
448 | atomic64_t siga_ins; | 168 | u32 isc:3; |
449 | atomic64_t siga_syncs; | 169 | u32 word_with_d_bit; |
450 | atomic64_t pcis; | 170 | u32:32; |
451 | atomic64_t thinints; | 171 | struct subchannel_id schid; |
452 | atomic64_t fast_reqs; | 172 | u32 reserved[1004]; |
453 | 173 | struct chsc_header response; | |
454 | atomic64_t outbound_cnt; | 174 | u32:32; |
455 | atomic64_t inbound_cnt; | 175 | } __attribute__ ((packed)); |
456 | #else /* CONFIG_64BIT */ | 176 | |
457 | atomic_t tl_runs; | 177 | struct qdio_input_q { |
458 | atomic_t outbound_tl_runs; | 178 | /* input buffer acknowledgement flag */ |
459 | atomic_t outbound_tl_runs_resched; | 179 | int polling; |
460 | atomic_t inbound_tl_runs; | 180 | |
461 | atomic_t inbound_tl_runs_resched; | 181 | /* last time of noticing incoming data */ |
462 | atomic_t inbound_thin_tl_runs; | 182 | u64 timestamp; |
463 | atomic_t inbound_thin_tl_runs_resched; | 183 | |
464 | 184 | /* lock for clearing the acknowledgement */ | |
465 | atomic_t siga_outs; | 185 | spinlock_t lock; |
466 | atomic_t siga_ins; | ||
467 | atomic_t siga_syncs; | ||
468 | atomic_t pcis; | ||
469 | atomic_t thinints; | ||
470 | atomic_t fast_reqs; | ||
471 | |||
472 | atomic_t outbound_cnt; | ||
473 | atomic_t inbound_cnt; | ||
474 | #endif /* CONFIG_64BIT */ | ||
475 | }; | 186 | }; |
476 | 187 | ||
477 | /* unlikely as the later the better */ | 188 | struct qdio_output_q { |
478 | #define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q) | 189 | /* failed siga-w attempts*/ |
479 | #define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \ | 190 | atomic_t busy_siga_counter; |
480 | qdio_siga_sync(q,~0U,~0U) | ||
481 | #define SYNC_MEMORY_ALL_OUTB if (unlikely(q->siga_sync)) \ | ||
482 | qdio_siga_sync(q,~0U,0) | ||
483 | 191 | ||
484 | #define NOW qdio_get_micros() | 192 | /* start time of busy condition */ |
485 | #define SAVE_TIMESTAMP(q) q->timing.last_transfer_time=NOW | 193 | u64 timestamp; |
486 | #define GET_SAVED_TIMESTAMP(q) (q->timing.last_transfer_time) | ||
487 | #define SAVE_FRONTIER(q,val) q->last_move_ftc=val | ||
488 | #define GET_SAVED_FRONTIER(q) (q->last_move_ftc) | ||
489 | 194 | ||
490 | #define MY_MODULE_STRING(x) #x | 195 | /* PCIs are enabled for the queue */ |
196 | int pci_out_enabled; | ||
491 | 197 | ||
492 | #ifdef CONFIG_64BIT | 198 | /* timer to check for more outbound work */ |
493 | #define QDIO_GET_ADDR(x) ((__u32)(unsigned long)x) | 199 | struct timer_list timer; |
494 | #else /* CONFIG_64BIT */ | 200 | }; |
495 | #define QDIO_GET_ADDR(x) ((__u32)(long)x) | ||
496 | #endif /* CONFIG_64BIT */ | ||
497 | 201 | ||
498 | struct qdio_q { | 202 | struct qdio_q { |
499 | volatile struct slsb slsb; | 203 | struct slsb slsb; |
204 | union { | ||
205 | struct qdio_input_q in; | ||
206 | struct qdio_output_q out; | ||
207 | } u; | ||
500 | 208 | ||
501 | char unused[QDIO_MAX_BUFFERS_PER_Q]; | 209 | /* queue number */ |
210 | int nr; | ||
502 | 211 | ||
503 | __u32 * dev_st_chg_ind; | 212 | /* bitmask of queue number */ |
213 | int mask; | ||
504 | 214 | ||
215 | /* input or output queue */ | ||
505 | int is_input_q; | 216 | int is_input_q; |
506 | struct subchannel_id schid; | ||
507 | struct ccw_device *cdev; | ||
508 | |||
509 | unsigned int is_iqdio_q; | ||
510 | unsigned int is_thinint_q; | ||
511 | 217 | ||
512 | /* bit 0 means queue 0, bit 1 means queue 1, ... */ | 218 | /* list of thinint input queues */ |
513 | unsigned int mask; | 219 | struct list_head entry; |
514 | unsigned int q_no; | ||
515 | 220 | ||
221 | /* upper-layer program handler */ | ||
516 | qdio_handler_t (*handler); | 222 | qdio_handler_t (*handler); |
517 | 223 | ||
518 | /* points to the next buffer to be checked for having | 224 | /* |
519 | * been processed by the card (outbound) | 225 | * inbound: next buffer the program should check for |
520 | * or to the next buffer the program should check for (inbound) */ | 226 | * outbound: next buffer to check for having been processed |
521 | volatile int first_to_check; | 227 | * by the card |
522 | /* and the last time it was: */ | 228 | */ |
523 | volatile int last_move_ftc; | 229 | int first_to_check; |
524 | 230 | ||
525 | atomic_t number_of_buffers_used; | 231 | /* first_to_check of the last time */ |
526 | atomic_t polling; | 232 | int last_move_ftc; |
527 | 233 | ||
528 | unsigned int siga_in; | 234 | /* beginning position for calling the program */ |
529 | unsigned int siga_out; | 235 | int first_to_kick; |
530 | unsigned int siga_sync; | ||
531 | unsigned int siga_sync_done_on_thinints; | ||
532 | unsigned int siga_sync_done_on_outb_tis; | ||
533 | unsigned int hydra_gives_outbound_pcis; | ||
534 | 236 | ||
535 | /* used to save beginning position when calling dd_handlers */ | 237 | /* number of buffers in use by the adapter */ |
536 | int first_element_to_kick; | 238 | atomic_t nr_buf_used; |
537 | 239 | ||
538 | atomic_t use_count; | 240 | struct qdio_irq *irq_ptr; |
539 | atomic_t is_in_shutdown; | ||
540 | |||
541 | void *irq_ptr; | ||
542 | |||
543 | struct timer_list timer; | ||
544 | #ifdef QDIO_USE_TIMERS_FOR_POLLING | ||
545 | atomic_t timer_already_set; | ||
546 | spinlock_t timer_lock; | ||
547 | #else /* QDIO_USE_TIMERS_FOR_POLLING */ | ||
548 | struct tasklet_struct tasklet; | 241 | struct tasklet_struct tasklet; |
549 | #endif /* QDIO_USE_TIMERS_FOR_POLLING */ | ||
550 | 242 | ||
551 | 243 | /* error condition during a data transfer */ | |
552 | enum qdio_irq_states state; | ||
553 | |||
554 | /* used to store the error condition during a data transfer */ | ||
555 | unsigned int qdio_error; | 244 | unsigned int qdio_error; |
556 | unsigned int siga_error; | ||
557 | unsigned int error_status_flags; | ||
558 | |||
559 | /* list of interesting queues */ | ||
560 | volatile struct qdio_q *list_next; | ||
561 | volatile struct qdio_q *list_prev; | ||
562 | 245 | ||
563 | struct sl *sl; | 246 | struct sl *sl; |
564 | volatile struct sbal *sbal[QDIO_MAX_BUFFERS_PER_Q]; | 247 | struct qdio_buffer *sbal[QDIO_MAX_BUFFERS_PER_Q]; |
565 | 248 | ||
566 | struct qdio_buffer *qdio_buffers[QDIO_MAX_BUFFERS_PER_Q]; | 249 | /* |
567 | 250 | * Warning: Leave this member at the end so it won't be cleared in | |
568 | unsigned long int_parm; | 251 | * qdio_fill_qs. A page is allocated under this pointer and used for |
569 | 252 | * slib and sl. slib is 2048 bytes big and sl points to offset | |
570 | /*struct { | 253 | * PAGE_SIZE / 2. |
571 | int in_bh_check_limit; | 254 | */ |
572 | int threshold; | 255 | struct slib *slib; |
573 | } threshold_classes[QDIO_STATS_CLASSES];*/ | ||
574 | |||
575 | struct { | ||
576 | /* inbound: the time to stop polling | ||
577 | outbound: the time to kick peer */ | ||
578 | int threshold; /* the real value */ | ||
579 | |||
580 | /* outbound: last time of do_QDIO | ||
581 | inbound: last time of noticing incoming data */ | ||
582 | /*__u64 last_transfer_times[QDIO_STATS_NUMBER]; | ||
583 | int last_transfer_index; */ | ||
584 | |||
585 | __u64 last_transfer_time; | ||
586 | __u64 busy_start; | ||
587 | } timing; | ||
588 | atomic_t busy_siga_counter; | ||
589 | unsigned int queue_type; | ||
590 | unsigned int is_pci_out; | ||
591 | |||
592 | /* leave this member at the end. won't be cleared in qdio_fill_qs */ | ||
593 | struct slib *slib; /* a page is allocated under this pointer, | ||
594 | sl points into this page, offset PAGE_SIZE/2 | ||
595 | (after slib) */ | ||
596 | } __attribute__ ((aligned(256))); | 256 | } __attribute__ ((aligned(256))); |
597 | 257 | ||
598 | struct qdio_irq { | 258 | struct qdio_irq { |
599 | __u32 * volatile dev_st_chg_ind; | 259 | struct qib qib; |
260 | u32 *dsci; /* address of device state change indicator */ | ||
261 | struct ccw_device *cdev; | ||
600 | 262 | ||
601 | unsigned long int_parm; | 263 | unsigned long int_parm; |
602 | struct subchannel_id schid; | 264 | struct subchannel_id schid; |
603 | 265 | unsigned long sch_token; /* QEBSM facility */ | |
604 | unsigned int is_iqdio_irq; | ||
605 | unsigned int is_thinint_irq; | ||
606 | unsigned int hydra_gives_outbound_pcis; | ||
607 | unsigned int sync_done_on_outb_pcis; | ||
608 | |||
609 | /* QEBSM facility */ | ||
610 | unsigned int is_qebsm; | ||
611 | unsigned long sch_token; | ||
612 | 266 | ||
613 | enum qdio_irq_states state; | 267 | enum qdio_irq_states state; |
614 | 268 | ||
615 | unsigned int no_input_qs; | 269 | struct siga_flag siga_flag; /* siga sync information from qdioac */ |
616 | unsigned int no_output_qs; | ||
617 | 270 | ||
618 | unsigned char qdioac; | 271 | int nr_input_qs; |
272 | int nr_output_qs; | ||
619 | 273 | ||
620 | struct ccw1 ccw; | 274 | struct ccw1 ccw; |
621 | |||
622 | struct ciw equeue; | 275 | struct ciw equeue; |
623 | struct ciw aqueue; | 276 | struct ciw aqueue; |
624 | 277 | ||
625 | struct qib qib; | 278 | struct qdio_ssqd_desc ssqd_desc; |
626 | 279 | ||
627 | void (*original_int_handler) (struct ccw_device *, | 280 | void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *); |
628 | unsigned long, struct irb *); | ||
629 | 281 | ||
630 | /* leave these four members together at the end. won't be cleared in qdio_fill_irq */ | 282 | /* |
283 | * Warning: Leave these members together at the end so they won't be | ||
284 | * cleared in qdio_setup_irq. | ||
285 | */ | ||
631 | struct qdr *qdr; | 286 | struct qdr *qdr; |
287 | unsigned long chsc_page; | ||
288 | |||
632 | struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ]; | 289 | struct qdio_q *input_qs[QDIO_MAX_QUEUES_PER_IRQ]; |
633 | struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ]; | 290 | struct qdio_q *output_qs[QDIO_MAX_QUEUES_PER_IRQ]; |
634 | struct semaphore setting_up_sema; | 291 | |
292 | struct mutex setup_mutex; | ||
635 | }; | 293 | }; |
636 | #endif | 294 | |
295 | /* helper functions */ | ||
296 | #define queue_type(q) q->irq_ptr->qib.qfmt | ||
297 | |||
298 | #define is_thinint_irq(irq) \ | ||
299 | (irq->qib.qfmt == QDIO_IQDIO_QFMT || \ | ||
300 | css_general_characteristics.aif_osa) | ||
301 | |||
302 | /* the highest iqdio queue is used for multicast */ | ||
303 | static inline int multicast_outbound(struct qdio_q *q) | ||
304 | { | ||
305 | return (q->irq_ptr->nr_output_qs > 1) && | ||
306 | (q->nr == q->irq_ptr->nr_output_qs - 1); | ||
307 | } | ||
308 | |||
309 | static inline unsigned long long get_usecs(void) | ||
310 | { | ||
311 | return monotonic_clock() >> 12; | ||
312 | } | ||
313 | |||
314 | #define pci_out_supported(q) \ | ||
315 | (q->irq_ptr->qib.ac & QIB_AC_OUTBOUND_PCI_SUPPORTED) | ||
316 | #define is_qebsm(q) (q->irq_ptr->sch_token != 0) | ||
317 | |||
318 | #define need_siga_sync_thinint(q) (!q->irq_ptr->siga_flag.no_sync_ti) | ||
319 | #define need_siga_sync_out_thinint(q) (!q->irq_ptr->siga_flag.no_sync_out_ti) | ||
320 | #define need_siga_in(q) (q->irq_ptr->siga_flag.input) | ||
321 | #define need_siga_out(q) (q->irq_ptr->siga_flag.output) | ||
322 | #define need_siga_sync(q) (q->irq_ptr->siga_flag.sync) | ||
323 | #define siga_syncs_out_pci(q) (q->irq_ptr->siga_flag.no_sync_out_pci) | ||
324 | |||
325 | #define for_each_input_queue(irq_ptr, q, i) \ | ||
326 | for (i = 0, q = irq_ptr->input_qs[0]; \ | ||
327 | i < irq_ptr->nr_input_qs; \ | ||
328 | q = irq_ptr->input_qs[++i]) | ||
329 | #define for_each_output_queue(irq_ptr, q, i) \ | ||
330 | for (i = 0, q = irq_ptr->output_qs[0]; \ | ||
331 | i < irq_ptr->nr_output_qs; \ | ||
332 | q = irq_ptr->output_qs[++i]) | ||
333 | |||
334 | #define prev_buf(bufnr) \ | ||
335 | ((bufnr + QDIO_MAX_BUFFERS_MASK) & QDIO_MAX_BUFFERS_MASK) | ||
336 | #define next_buf(bufnr) \ | ||
337 | ((bufnr + 1) & QDIO_MAX_BUFFERS_MASK) | ||
338 | #define add_buf(bufnr, inc) \ | ||
339 | ((bufnr + inc) & QDIO_MAX_BUFFERS_MASK) | ||
340 | |||
341 | /* prototypes for thin interrupt */ | ||
342 | void qdio_sync_after_thinint(struct qdio_q *q); | ||
343 | int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state); | ||
344 | void qdio_check_outbound_after_thinint(struct qdio_q *q); | ||
345 | int qdio_inbound_q_moved(struct qdio_q *q); | ||
346 | void qdio_kick_inbound_handler(struct qdio_q *q); | ||
347 | void qdio_stop_polling(struct qdio_q *q); | ||
348 | int qdio_siga_sync_q(struct qdio_q *q); | ||
349 | |||
350 | void qdio_setup_thinint(struct qdio_irq *irq_ptr); | ||
351 | int qdio_establish_thinint(struct qdio_irq *irq_ptr); | ||
352 | void qdio_shutdown_thinint(struct qdio_irq *irq_ptr); | ||
353 | void tiqdio_add_input_queues(struct qdio_irq *irq_ptr); | ||
354 | void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr); | ||
355 | void tiqdio_inbound_processing(unsigned long q); | ||
356 | int tiqdio_allocate_memory(void); | ||
357 | void tiqdio_free_memory(void); | ||
358 | int tiqdio_register_thinints(void); | ||
359 | void tiqdio_unregister_thinints(void); | ||
360 | |||
361 | /* prototypes for setup */ | ||
362 | void qdio_inbound_processing(unsigned long data); | ||
363 | void qdio_outbound_processing(unsigned long data); | ||
364 | void qdio_outbound_timer(unsigned long data); | ||
365 | void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm, | ||
366 | struct irb *irb); | ||
367 | int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, | ||
368 | int nr_output_qs); | ||
369 | void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr); | ||
370 | int qdio_setup_irq(struct qdio_initialize *init_data); | ||
371 | void qdio_print_subchannel_info(struct qdio_irq *irq_ptr, | ||
372 | struct ccw_device *cdev); | ||
373 | void qdio_release_memory(struct qdio_irq *irq_ptr); | ||
374 | int qdio_setup_init(void); | ||
375 | void qdio_setup_exit(void); | ||
376 | |||
377 | #endif /* _CIO_QDIO_H */ | ||