aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/qdio.h')
-rw-r--r--drivers/s390/cio/qdio.h837
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
65enum qdio_irq_states { 19enum 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) 87static 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;
237QDIO_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)); \
248QDIO_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
265static inline int 102 return (_ccq >> 32) & 0xff;
266do_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
288static inline int 105static inline int do_eqbs(u64 token, unsigned char *state, int queue,
289do_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
125static inline int do_sqbs(u64 token, unsigned char state, int queue,
126 int *start, int *count) { return 0; }
127static inline int do_eqbs(u64 token, unsigned char *state, int queue,
128 int *start, int *count) { return 0; }
129#endif /* CONFIG_64BIT */
312 130
131struct qdio_irq;
313 132
314static inline int 133struct siga_flag {
315do_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
332static inline int
333do_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
349static inline int
350do_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
371static inline unsigned long
372do_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
409struct qdio_chsc_ssqd { 143struct 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
437struct qdio_perf_stats { 157struct 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; 177struct 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 */ 188struct 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
498struct qdio_q { 202struct 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
598struct qdio_irq { 258struct 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 */
303static 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
309static 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 */
342void qdio_sync_after_thinint(struct qdio_q *q);
343int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state);
344void qdio_check_outbound_after_thinint(struct qdio_q *q);
345int qdio_inbound_q_moved(struct qdio_q *q);
346void qdio_kick_inbound_handler(struct qdio_q *q);
347void qdio_stop_polling(struct qdio_q *q);
348int qdio_siga_sync_q(struct qdio_q *q);
349
350void qdio_setup_thinint(struct qdio_irq *irq_ptr);
351int qdio_establish_thinint(struct qdio_irq *irq_ptr);
352void qdio_shutdown_thinint(struct qdio_irq *irq_ptr);
353void tiqdio_add_input_queues(struct qdio_irq *irq_ptr);
354void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr);
355void tiqdio_inbound_processing(unsigned long q);
356int tiqdio_allocate_memory(void);
357void tiqdio_free_memory(void);
358int tiqdio_register_thinints(void);
359void tiqdio_unregister_thinints(void);
360
361/* prototypes for setup */
362void qdio_inbound_processing(unsigned long data);
363void qdio_outbound_processing(unsigned long data);
364void qdio_outbound_timer(unsigned long data);
365void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
366 struct irb *irb);
367int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs,
368 int nr_output_qs);
369void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr);
370int qdio_setup_irq(struct qdio_initialize *init_data);
371void qdio_print_subchannel_info(struct qdio_irq *irq_ptr,
372 struct ccw_device *cdev);
373void qdio_release_memory(struct qdio_irq *irq_ptr);
374int qdio_setup_init(void);
375void qdio_setup_exit(void);
376
377#endif /* _CIO_QDIO_H */