1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: [PATCH] qdio: move adapter interrupt tasklet code
3 References: bnc#532063,LTC#55526
5 From: Jan Glauber <jang@linux.vnet.ibm.com>
7 Move the adapter interrupt tasklet function to the qdio main code
8 since all the functions used by the tasklet are located there.
10 Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
12 Acked-by: John Jolly <jjolly@suse.de>
15 drivers/s390/cio/qdio.h | 11 -----
16 drivers/s390/cio/qdio_debug.c | 3 -
17 drivers/s390/cio/qdio_main.c | 83 ++++++++++++++++++++++++++++++++++------
18 drivers/s390/cio/qdio_thinint.c | 57 ---------------------------
19 4 files changed, 75 insertions(+), 79 deletions(-)
21 Index: linux-sles11/drivers/s390/cio/qdio.h
22 ===================================================================
23 --- linux-sles11.orig/drivers/s390/cio/qdio.h
24 +++ linux-sles11/drivers/s390/cio/qdio.h
25 @@ -348,15 +348,6 @@ static inline unsigned long long get_use
26 ((bufnr - dec) & QDIO_MAX_BUFFERS_MASK)
28 /* prototypes for thin interrupt */
29 -void qdio_sync_after_thinint(struct qdio_q *q);
30 -int get_buf_state(struct qdio_q *q, unsigned int bufnr, unsigned char *state,
32 -void qdio_check_outbound_after_thinint(struct qdio_q *q);
33 -int qdio_inbound_q_moved(struct qdio_q *q);
34 -void qdio_kick_inbound_handler(struct qdio_q *q);
35 -void qdio_stop_polling(struct qdio_q *q);
36 -int qdio_siga_sync_q(struct qdio_q *q);
38 void qdio_setup_thinint(struct qdio_irq *irq_ptr);
39 int qdio_establish_thinint(struct qdio_irq *irq_ptr);
40 void qdio_shutdown_thinint(struct qdio_irq *irq_ptr);
41 @@ -389,4 +380,6 @@ void qdio_setup_destroy_sysfs(struct ccw
42 int qdio_setup_init(void);
43 void qdio_setup_exit(void);
45 +int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
46 + unsigned char *state);
47 #endif /* _CIO_QDIO_H */
48 Index: linux-sles11/drivers/s390/cio/qdio_debug.c
49 ===================================================================
50 --- linux-sles11.orig/drivers/s390/cio/qdio_debug.c
51 +++ linux-sles11/drivers/s390/cio/qdio_debug.c
52 @@ -69,9 +69,8 @@ static int qstat_show(struct seq_file *m
53 seq_printf(m, "slsb buffer states:\n");
54 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
56 - qdio_siga_sync_q(q);
57 for (i = 0; i < QDIO_MAX_BUFFERS_PER_Q; i++) {
58 - get_buf_state(q, i, &state, 0);
59 + debug_get_buf_state(q, i, &state);
61 case SLSB_P_INPUT_NOT_INIT:
62 case SLSB_P_OUTPUT_NOT_INIT:
63 Index: linux-sles11/drivers/s390/cio/qdio_main.c
64 ===================================================================
65 --- linux-sles11.orig/drivers/s390/cio/qdio_main.c
66 +++ linux-sles11/drivers/s390/cio/qdio_main.c
67 @@ -225,8 +225,8 @@ static inline int get_buf_states(struct
71 -inline int get_buf_state(struct qdio_q *q, unsigned int bufnr,
72 - unsigned char *state, int auto_ack)
73 +static inline int get_buf_state(struct qdio_q *q, unsigned int bufnr,
74 + unsigned char *state, int auto_ack)
76 return get_buf_states(q, bufnr, state, 1, auto_ack);
78 @@ -270,7 +270,7 @@ void qdio_init_buf_states(struct qdio_ir
79 QDIO_MAX_BUFFERS_PER_Q);
82 -static int qdio_siga_sync(struct qdio_q *q, unsigned int output,
83 +static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output,
87 @@ -287,7 +287,7 @@ static int qdio_siga_sync(struct qdio_q
91 -inline int qdio_siga_sync_q(struct qdio_q *q)
92 +static inline int qdio_siga_sync_q(struct qdio_q *q)
95 return qdio_siga_sync(q, 0, q->mask);
96 @@ -349,8 +349,7 @@ static inline int qdio_siga_input(struct
100 -/* called from thinint inbound handler */
101 -void qdio_sync_after_thinint(struct qdio_q *q)
102 +static inline void qdio_sync_after_thinint(struct qdio_q *q)
104 if (pci_out_supported(q)) {
105 if (need_siga_sync_thinint(q))
106 @@ -361,7 +360,14 @@ void qdio_sync_after_thinint(struct qdio
110 -inline void qdio_stop_polling(struct qdio_q *q)
111 +int debug_get_buf_state(struct qdio_q *q, unsigned int bufnr,
112 + unsigned char *state)
114 + qdio_siga_sync_q(q);
115 + return get_buf_states(q, bufnr, state, 1, 0);
118 +static inline void qdio_stop_polling(struct qdio_q *q)
120 if (!q->u.in.polling)
122 @@ -507,7 +513,7 @@ out:
123 return q->first_to_check;
126 -int qdio_inbound_q_moved(struct qdio_q *q)
127 +static int qdio_inbound_q_moved(struct qdio_q *q)
131 @@ -587,6 +593,22 @@ void qdio_kick_inbound_handler(struct qd
135 +static inline int tiqdio_inbound_q_done(struct qdio_q *q)
137 + unsigned char state = 0;
139 + if (!atomic_read(&q->nr_buf_used))
142 + qdio_siga_sync_q(q);
143 + get_buf_state(q, q->first_to_check, &state, 0);
145 + if (state == SLSB_P_INPUT_PRIMED)
146 + /* more work coming */
151 static void __qdio_inbound_processing(struct qdio_q *q)
153 qdio_perf_stat_inc(&perf_stats.tasklet_inbound);
154 @@ -609,7 +631,6 @@ again:
158 -/* inbound tasklet */
159 void qdio_inbound_processing(unsigned long data)
161 struct qdio_q *q = (struct qdio_q *)data;
162 @@ -812,8 +833,7 @@ void qdio_outbound_timer(unsigned long d
163 tasklet_schedule(&q->tasklet);
166 -/* called from thinint inbound tasklet */
167 -void qdio_check_outbound_after_thinint(struct qdio_q *q)
168 +static inline void qdio_check_outbound_after_thinint(struct qdio_q *q)
172 @@ -826,6 +846,47 @@ void qdio_check_outbound_after_thinint(s
173 tasklet_schedule(&out->tasklet);
176 +static void __tiqdio_inbound_processing(struct qdio_q *q)
178 + qdio_perf_stat_inc(&perf_stats.thinint_inbound);
179 + qdio_sync_after_thinint(q);
182 + * The interrupt could be caused by a PCI request. Check the
183 + * PCI capable outbound queues.
185 + qdio_check_outbound_after_thinint(q);
187 + if (!qdio_inbound_q_moved(q))
190 + qdio_kick_inbound_handler(q);
192 + if (!tiqdio_inbound_q_done(q)) {
193 + qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
194 + if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
195 + tasklet_schedule(&q->tasklet);
199 + qdio_stop_polling(q);
201 + * We need to check again to not lose initiative after
202 + * resetting the ACK state.
204 + if (!tiqdio_inbound_q_done(q)) {
205 + qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
206 + if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
207 + tasklet_schedule(&q->tasklet);
211 +void tiqdio_inbound_processing(unsigned long data)
213 + struct qdio_q *q = (struct qdio_q *)data;
214 + __tiqdio_inbound_processing(q);
217 static inline void qdio_set_state(struct qdio_irq *irq_ptr,
218 enum qdio_irq_states state)
220 Index: linux-sles11/drivers/s390/cio/qdio_thinint.c
221 ===================================================================
222 --- linux-sles11.orig/drivers/s390/cio/qdio_thinint.c
223 +++ linux-sles11/drivers/s390/cio/qdio_thinint.c
224 @@ -126,68 +126,11 @@ void tiqdio_remove_input_queues(struct q
228 -static inline int tiqdio_inbound_q_done(struct qdio_q *q)
230 - unsigned char state;
232 - if (!atomic_read(&q->nr_buf_used))
235 - qdio_siga_sync_q(q);
236 - get_buf_state(q, q->first_to_check, &state, 0);
238 - if (state == SLSB_P_INPUT_PRIMED)
239 - /* more work coming */
244 static inline int shared_ind(struct qdio_irq *irq_ptr)
246 return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
249 -static void __tiqdio_inbound_processing(struct qdio_q *q)
251 - qdio_perf_stat_inc(&perf_stats.thinint_inbound);
252 - qdio_sync_after_thinint(q);
255 - * Maybe we have work on our outbound queues... at least
256 - * we have to check the PCI capable queues.
258 - qdio_check_outbound_after_thinint(q);
260 - if (!qdio_inbound_q_moved(q))
263 - qdio_kick_inbound_handler(q);
265 - if (!tiqdio_inbound_q_done(q)) {
266 - qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
267 - if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
268 - tasklet_schedule(&q->tasklet);
271 - qdio_stop_polling(q);
273 - * We need to check again to not lose initiative after
274 - * resetting the ACK state.
276 - if (!tiqdio_inbound_q_done(q)) {
277 - qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
278 - if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
279 - tasklet_schedule(&q->tasklet);
283 -void tiqdio_inbound_processing(unsigned long data)
285 - struct qdio_q *q = (struct qdio_q *)data;
287 - __tiqdio_inbound_processing(q);
290 /* check for work on all inbound thinint queues */
291 static void tiqdio_tasklet_fn(unsigned long data)