aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/cio/qdio_main.c')
-rw-r--r--drivers/s390/cio/qdio_main.c102
1 files changed, 50 insertions, 52 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 6547ff469410..3ef8d071c64a 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -15,7 +15,6 @@
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/gfp.h> 16#include <linux/gfp.h>
17#include <linux/io.h> 17#include <linux/io.h>
18#include <linux/kernel_stat.h>
19#include <linux/atomic.h> 18#include <linux/atomic.h>
20#include <asm/debug.h> 19#include <asm/debug.h>
21#include <asm/qdio.h> 20#include <asm/qdio.h>
@@ -105,9 +104,12 @@ static inline int qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
105 /* all done or next buffer state different */ 104 /* all done or next buffer state different */
106 if (ccq == 0 || ccq == 32) 105 if (ccq == 0 || ccq == 32)
107 return 0; 106 return 0;
108 /* not all buffers processed */ 107 /* no buffer processed */
109 if (ccq == 96 || ccq == 97) 108 if (ccq == 97)
110 return 1; 109 return 1;
110 /* not all buffers processed */
111 if (ccq == 96)
112 return 2;
111 /* notify devices immediately */ 113 /* notify devices immediately */
112 DBF_ERROR("%4x ccq:%3d", SCH_NO(q), ccq); 114 DBF_ERROR("%4x ccq:%3d", SCH_NO(q), ccq);
113 return -EIO; 115 return -EIO;
@@ -127,10 +129,8 @@ static inline int qdio_check_ccq(struct qdio_q *q, unsigned int ccq)
127static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state, 129static int qdio_do_eqbs(struct qdio_q *q, unsigned char *state,
128 int start, int count, int auto_ack) 130 int start, int count, int auto_ack)
129{ 131{
132 int rc, tmp_count = count, tmp_start = start, nr = q->nr, retried = 0;
130 unsigned int ccq = 0; 133 unsigned int ccq = 0;
131 int tmp_count = count, tmp_start = start;
132 int nr = q->nr;
133 int rc;
134 134
135 BUG_ON(!q->irq_ptr->sch_token); 135 BUG_ON(!q->irq_ptr->sch_token);
136 qperf_inc(q, eqbs); 136 qperf_inc(q, eqbs);
@@ -141,30 +141,34 @@ again:
141 ccq = do_eqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count, 141 ccq = do_eqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count,
142 auto_ack); 142 auto_ack);
143 rc = qdio_check_ccq(q, ccq); 143 rc = qdio_check_ccq(q, ccq);
144 144 if (!rc)
145 /* At least one buffer was processed, return and extract the remaining 145 return count - tmp_count;
146 * buffers later.
147 */
148 if ((ccq == 96) && (count != tmp_count)) {
149 qperf_inc(q, eqbs_partial);
150 return (count - tmp_count);
151 }
152 146
153 if (rc == 1) { 147 if (rc == 1) {
154 DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS again:%2d", ccq); 148 DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS again:%2d", ccq);
155 goto again; 149 goto again;
156 } 150 }
157 151
158 if (rc < 0) { 152 if (rc == 2) {
159 DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); 153 BUG_ON(tmp_count == count);
160 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); 154 qperf_inc(q, eqbs_partial);
161 q->handler(q->irq_ptr->cdev, 155 DBF_DEV_EVENT(DBF_WARN, q->irq_ptr, "EQBS part:%02x",
162 QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 156 tmp_count);
163 q->nr, q->first_to_kick, count, 157 /*
164 q->irq_ptr->int_parm); 158 * Retry once, if that fails bail out and process the
165 return 0; 159 * extracted buffers before trying again.
160 */
161 if (!retried++)
162 goto again;
163 else
164 return count - tmp_count;
166 } 165 }
167 return count - tmp_count; 166
167 DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
168 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
169 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION,
170 0, -1, -1, q->irq_ptr->int_parm);
171 return 0;
168} 172}
169 173
170/** 174/**
@@ -197,22 +201,22 @@ static int qdio_do_sqbs(struct qdio_q *q, unsigned char state, int start,
197again: 201again:
198 ccq = do_sqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count); 202 ccq = do_sqbs(q->irq_ptr->sch_token, state, nr, &tmp_start, &tmp_count);
199 rc = qdio_check_ccq(q, ccq); 203 rc = qdio_check_ccq(q, ccq);
200 if (rc == 1) { 204 if (!rc) {
205 WARN_ON(tmp_count);
206 return count - tmp_count;
207 }
208
209 if (rc == 1 || rc == 2) {
201 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq); 210 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "SQBS again:%2d", ccq);
202 qperf_inc(q, sqbs_partial); 211 qperf_inc(q, sqbs_partial);
203 goto again; 212 goto again;
204 } 213 }
205 if (rc < 0) { 214
206 DBF_ERROR("%4x SQBS ERROR", SCH_NO(q)); 215 DBF_ERROR("%4x SQBS ERROR", SCH_NO(q));
207 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); 216 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
208 q->handler(q->irq_ptr->cdev, 217 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION,
209 QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 218 0, -1, -1, q->irq_ptr->int_parm);
210 q->nr, q->first_to_kick, count, 219 return 0;
211 q->irq_ptr->int_parm);
212 return 0;
213 }
214 WARN_ON(tmp_count);
215 return count - tmp_count;
216} 220}
217 221
218/* returns number of examined buffers and their common state in *state */ 222/* returns number of examined buffers and their common state in *state */
@@ -277,7 +281,7 @@ static inline int set_buf_state(struct qdio_q *q, int bufnr,
277} 281}
278 282
279/* set slsb states to initial state */ 283/* set slsb states to initial state */
280void qdio_init_buf_states(struct qdio_irq *irq_ptr) 284static void qdio_init_buf_states(struct qdio_irq *irq_ptr)
281{ 285{
282 struct qdio_q *q; 286 struct qdio_q *q;
283 int i; 287 int i;
@@ -446,7 +450,7 @@ static void process_buffer_error(struct qdio_q *q, int count)
446 qperf_inc(q, target_full); 450 qperf_inc(q, target_full);
447 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x", 451 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "OUTFULL FTC:%02x",
448 q->first_to_check); 452 q->first_to_check);
449 return; 453 goto set;
450 } 454 }
451 455
452 DBF_ERROR("%4x BUF ERROR", SCH_NO(q)); 456 DBF_ERROR("%4x BUF ERROR", SCH_NO(q));
@@ -456,6 +460,7 @@ static void process_buffer_error(struct qdio_q *q, int count)
456 q->sbal[q->first_to_check]->element[14].sflags, 460 q->sbal[q->first_to_check]->element[14].sflags,
457 q->sbal[q->first_to_check]->element[15].sflags); 461 q->sbal[q->first_to_check]->element[15].sflags);
458 462
463set:
459 /* 464 /*
460 * Interrupts may be avoided as long as the error is present 465 * Interrupts may be avoided as long as the error is present
461 * so change the buffer state immediately to avoid starvation. 466 * so change the buffer state immediately to avoid starvation.
@@ -513,6 +518,8 @@ static int get_inbound_buffer_frontier(struct qdio_q *q)
513 int count, stop; 518 int count, stop;
514 unsigned char state = 0; 519 unsigned char state = 0;
515 520
521 q->timestamp = get_clock_fast();
522
516 /* 523 /*
517 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved 524 * Don't check 128 buffers, as otherwise qdio_inbound_q_moved
518 * would return 0. 525 * would return 0.
@@ -782,6 +789,8 @@ static int get_outbound_buffer_frontier(struct qdio_q *q)
782 int count, stop; 789 int count, stop;
783 unsigned char state = 0; 790 unsigned char state = 0;
784 791
792 q->timestamp = get_clock_fast();
793
785 if (need_siga_sync(q)) 794 if (need_siga_sync(q))
786 if (((queue_type(q) != QDIO_IQDIO_QFMT) && 795 if (((queue_type(q) != QDIO_IQDIO_QFMT) &&
787 !pci_out_supported(q)) || 796 !pci_out_supported(q)) ||
@@ -912,21 +921,13 @@ static void __qdio_outbound_processing(struct qdio_q *q)
912 if (!pci_out_supported(q) && !qdio_outbound_q_done(q)) 921 if (!pci_out_supported(q) && !qdio_outbound_q_done(q))
913 goto sched; 922 goto sched;
914 923
915 /* bail out for HiperSockets unicast queues */
916 if (queue_type(q) == QDIO_IQDIO_QFMT && !multicast_outbound(q))
917 return;
918
919 if ((queue_type(q) == QDIO_IQDIO_QFMT) &&
920 (atomic_read(&q->nr_buf_used)) > QDIO_IQDIO_POLL_LVL)
921 goto sched;
922
923 if (q->u.out.pci_out_enabled) 924 if (q->u.out.pci_out_enabled)
924 return; 925 return;
925 926
926 /* 927 /*
927 * Now we know that queue type is either qeth without pci enabled 928 * Now we know that queue type is either qeth without pci enabled
928 * or HiperSockets multicast. Make sure buffer switch from PRIMED to 929 * or HiperSockets. Make sure buffer switch from PRIMED to EMPTY
929 * EMPTY is noticed and outbound_handler is called after some time. 930 * is noticed and outbound_handler is called after some time.
930 */ 931 */
931 if (qdio_outbound_q_done(q)) 932 if (qdio_outbound_q_done(q))
932 del_timer(&q->u.out.timer); 933 del_timer(&q->u.out.timer);
@@ -1128,7 +1129,6 @@ void qdio_int_handler(struct ccw_device *cdev, unsigned long intparm,
1128 return; 1129 return;
1129 } 1130 }
1130 1131
1131 kstat_cpu(smp_processor_id()).irqs[IOINT_QDI]++;
1132 if (irq_ptr->perf_stat_enabled) 1132 if (irq_ptr->perf_stat_enabled)
1133 irq_ptr->perf_stat.qdio_int++; 1133 irq_ptr->perf_stat.qdio_int++;
1134 1134
@@ -1719,9 +1719,7 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
1719 1719
1720 WARN_ON(queue_irqs_enabled(q)); 1720 WARN_ON(queue_irqs_enabled(q));
1721 1721
1722 if (!shared_ind(q)) 1722 clear_nonshared_ind(irq_ptr);
1723 xchg(q->irq_ptr->dsci, 0);
1724
1725 qdio_stop_polling(q); 1723 qdio_stop_polling(q);
1726 clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state); 1724 clear_bit(QDIO_QUEUE_IRQS_DISABLED, &q->u.in.queue_irq_state);
1727 1725
@@ -1729,7 +1727,7 @@ int qdio_start_irq(struct ccw_device *cdev, int nr)
1729 * We need to check again to not lose initiative after 1727 * We need to check again to not lose initiative after
1730 * resetting the ACK state. 1728 * resetting the ACK state.
1731 */ 1729 */
1732 if (!shared_ind(q) && *q->irq_ptr->dsci) 1730 if (test_nonshared_ind(irq_ptr))
1733 goto rescan; 1731 goto rescan;
1734 if (!qdio_inbound_q_done(q)) 1732 if (!qdio_inbound_q_done(q))
1735 goto rescan; 1733 goto rescan;