aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2012-05-09 10:27:34 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-05-16 08:42:36 -0400
commit1549d13f4c5f0ca77b66bd725287d0b3f877eb6b (patch)
tree5ba439915cc4cceb8930a18e9adf2aba34adc82f /drivers/s390
parent050276ab8ce9f30c1d2d74c42a349ed54701905f (diff)
s390/qdio: Cleanup error handling to drivers
Various improvements of qdio error reporting to the upper-layer drivers (qeth, zfcp): - Split QDIO_ERROR_ACTIVATE_CHECK_CONDITION into: QDIO_ERROR_ACTIVATE: qdio termination interrupt QDIO_ERROR_GET_BUF_STATE: QIOASSIST eqbs error QDIO_ERROR_SET_BUF_STATE: QIOASSIST sqbs error Add QDIO_ERROR_FATAL / QDIO_ERROR_TEMPORARY masks to ease recovery decision in upper-layer drivers. - Don't (ab-)use qdio handler errors as return codes for do_QDIO but use standard error codes: -ENOBUFS: temporary target CC=2 condition -EBUSY: unresolved SIGA-W CC=2 busy condition -EIO: I/O error (CC=1, CC=3) - Remove unneeded memory clobber from SIGA-R - Remove EX_TABLE entry on SIGA-W, we want to see these errors Reviewed-by: Ursula Braun <ursula.braun@de.ibm.com> Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/qdio_main.c43
-rw-r--r--drivers/s390/net/qeth_core_main.c4
2 files changed, 24 insertions, 23 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 35c685c374e9..19902cdc6fac 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -63,7 +63,7 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask,
63 " ipm %0\n" 63 " ipm %0\n"
64 " srl %0,28\n" 64 " srl %0,28\n"
65 : "=d" (cc) 65 : "=d" (cc)
66 : "d" (__fc), "d" (__schid), "d" (__mask) : "cc", "memory"); 66 : "d" (__fc), "d" (__schid), "d" (__mask) : "cc");
67 return cc; 67 return cc;
68} 68}
69 69
@@ -74,7 +74,7 @@ static inline int do_siga_input(unsigned long schid, unsigned int mask,
74 * @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer 74 * @bb: busy bit indicator, set only if SIGA-w/wt could not access a buffer
75 * @fc: function code to perform 75 * @fc: function code to perform
76 * 76 *
77 * Returns cc or QDIO_ERROR_SIGA_ACCESS_EXCEPTION. 77 * Returns condition code.
78 * Note: For IQDC unicast queues only the highest priority queue is processed. 78 * Note: For IQDC unicast queues only the highest priority queue is processed.
79 */ 79 */
80static inline int do_siga_output(unsigned long schid, unsigned long mask, 80static inline int do_siga_output(unsigned long schid, unsigned long mask,
@@ -85,18 +85,16 @@ static inline int do_siga_output(unsigned long schid, unsigned long mask,
85 register unsigned long __schid asm("1") = schid; 85 register unsigned long __schid asm("1") = schid;
86 register unsigned long __mask asm("2") = mask; 86 register unsigned long __mask asm("2") = mask;
87 register unsigned long __aob asm("3") = aob; 87 register unsigned long __aob asm("3") = aob;
88 int cc = QDIO_ERROR_SIGA_ACCESS_EXCEPTION; 88 int cc;
89 89
90 asm volatile( 90 asm volatile(
91 " siga 0\n" 91 " siga 0\n"
92 "0: ipm %0\n" 92 " ipm %0\n"
93 " srl %0,28\n" 93 " srl %0,28\n"
94 "1:\n" 94 : "=d" (cc), "+d" (__fc), "+d" (__aob)
95 EX_TABLE(0b, 1b) 95 : "d" (__schid), "d" (__mask)
96 : "+d" (cc), "+d" (__fc), "+d" (__schid), "+d" (__mask), 96 : "cc");
97 "+d" (__aob) 97 *bb = __fc >> 31;
98 : : "cc", "memory");
99 *bb = ((unsigned int) __fc) >> 31;
100 return cc; 98 return cc;
101} 99}
102 100
@@ -167,7 +165,7 @@ again:
167 165
168 DBF_ERROR("%4x EQBS ERROR", SCH_NO(q)); 166 DBF_ERROR("%4x EQBS ERROR", SCH_NO(q));
169 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); 167 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
170 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 168 q->handler(q->irq_ptr->cdev, QDIO_ERROR_GET_BUF_STATE,
171 q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); 169 q->nr, q->first_to_kick, count, q->irq_ptr->int_parm);
172 return 0; 170 return 0;
173} 171}
@@ -215,7 +213,7 @@ again:
215 213
216 DBF_ERROR("%4x SQBS ERROR", SCH_NO(q)); 214 DBF_ERROR("%4x SQBS ERROR", SCH_NO(q));
217 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr); 215 DBF_ERROR("%3d%3d%2d", count, tmp_count, nr);
218 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 216 q->handler(q->irq_ptr->cdev, QDIO_ERROR_SET_BUF_STATE,
219 q->nr, q->first_to_kick, count, q->irq_ptr->int_parm); 217 q->nr, q->first_to_kick, count, q->irq_ptr->int_parm);
220 return 0; 218 return 0;
221} 219}
@@ -313,7 +311,7 @@ static inline int qdio_siga_sync(struct qdio_q *q, unsigned int output,
313 cc = do_siga_sync(schid, output, input, fc); 311 cc = do_siga_sync(schid, output, input, fc);
314 if (unlikely(cc)) 312 if (unlikely(cc))
315 DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc); 313 DBF_ERROR("%4x SIGA-S:%2d", SCH_NO(q), cc);
316 return cc; 314 return (cc) ? -EIO : 0;
317} 315}
318 316
319static inline int qdio_siga_sync_q(struct qdio_q *q) 317static inline int qdio_siga_sync_q(struct qdio_q *q)
@@ -384,7 +382,7 @@ static inline int qdio_siga_input(struct qdio_q *q)
384 cc = do_siga_input(schid, q->mask, fc); 382 cc = do_siga_input(schid, q->mask, fc);
385 if (unlikely(cc)) 383 if (unlikely(cc))
386 DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc); 384 DBF_ERROR("%4x SIGA-R:%2d", SCH_NO(q), cc);
387 return cc; 385 return (cc) ? -EIO : 0;
388} 386}
389 387
390#define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0) 388#define qdio_siga_sync_out(q) qdio_siga_sync(q, ~0U, 0)
@@ -443,7 +441,7 @@ static void process_buffer_error(struct qdio_q *q, int count)
443 unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT : 441 unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT :
444 SLSB_P_OUTPUT_NOT_INIT; 442 SLSB_P_OUTPUT_NOT_INIT;
445 443
446 q->qdio_error |= QDIO_ERROR_SLSB_STATE; 444 q->qdio_error = QDIO_ERROR_SLSB_STATE;
447 445
448 /* special handling for no target buffer empty */ 446 /* special handling for no target buffer empty */
449 if ((!q->is_input_q && 447 if ((!q->is_input_q &&
@@ -575,7 +573,7 @@ static int qdio_inbound_q_moved(struct qdio_q *q)
575 573
576 bufnr = get_inbound_buffer_frontier(q); 574 bufnr = get_inbound_buffer_frontier(q);
577 575
578 if ((bufnr != q->last_move) || q->qdio_error) { 576 if (bufnr != q->last_move) {
579 q->last_move = bufnr; 577 q->last_move = bufnr;
580 if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR) 578 if (!is_thinint_irq(q->irq_ptr) && MACHINE_IS_LPAR)
581 q->u.in.timestamp = get_clock(); 579 q->u.in.timestamp = get_clock();
@@ -863,7 +861,7 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q)
863 861
864 bufnr = get_outbound_buffer_frontier(q); 862 bufnr = get_outbound_buffer_frontier(q);
865 863
866 if ((bufnr != q->last_move) || q->qdio_error) { 864 if (bufnr != q->last_move) {
867 q->last_move = bufnr; 865 q->last_move = bufnr;
868 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr); 866 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
869 return 1; 867 return 1;
@@ -894,13 +892,16 @@ retry:
894 goto retry; 892 goto retry;
895 } 893 }
896 DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr); 894 DBF_ERROR("%4x cc2 BBC:%1d", SCH_NO(q), q->nr);
897 cc |= QDIO_ERROR_SIGA_BUSY; 895 cc = -EBUSY;
898 } else 896 } else {
899 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr); 897 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "siga-w cc2:%1d", q->nr);
898 cc = -ENOBUFS;
899 }
900 break; 900 break;
901 case 1: 901 case 1:
902 case 3: 902 case 3:
903 DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc); 903 DBF_ERROR("%4x SIGA-W:%1d", SCH_NO(q), cc);
904 cc = -EIO;
904 break; 905 break;
905 } 906 }
906 if (retries) { 907 if (retries) {
@@ -1090,7 +1091,7 @@ static void qdio_handle_activate_check(struct ccw_device *cdev,
1090 } 1091 }
1091 1092
1092 count = sub_buf(q->first_to_check, q->first_to_kick); 1093 count = sub_buf(q->first_to_check, q->first_to_kick);
1093 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE_CHECK_CONDITION, 1094 q->handler(q->irq_ptr->cdev, QDIO_ERROR_ACTIVATE,
1094 q->nr, q->first_to_kick, count, irq_ptr->int_parm); 1095 q->nr, q->first_to_kick, count, irq_ptr->int_parm);
1095no_handler: 1096no_handler:
1096 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED); 1097 qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
@@ -1691,7 +1692,7 @@ int do_QDIO(struct ccw_device *cdev, unsigned int callflags,
1691 "do%02x b:%02x c:%02x", callflags, bufnr, count); 1692 "do%02x b:%02x c:%02x", callflags, bufnr, count);
1692 1693
1693 if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE) 1694 if (irq_ptr->state != QDIO_IRQ_STATE_ACTIVE)
1694 return -EBUSY; 1695 return -EIO;
1695 if (!count) 1696 if (!count)
1696 return 0; 1697 return 0;
1697 if (callflags & QDIO_FLAG_SYNC_INPUT) 1698 if (callflags & QDIO_FLAG_SYNC_INPUT)
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 8334dadc681d..c146877e8b7b 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3339,7 +3339,7 @@ static void qeth_flush_buffers(struct qeth_qdio_out_q *queue, int index,
3339 if (rc) { 3339 if (rc) {
3340 queue->card->stats.tx_errors += count; 3340 queue->card->stats.tx_errors += count;
3341 /* ignore temporary SIGA errors without busy condition */ 3341 /* ignore temporary SIGA errors without busy condition */
3342 if (rc == QDIO_ERROR_SIGA_TARGET) 3342 if (rc == -ENOBUFS)
3343 return; 3343 return;
3344 QETH_CARD_TEXT(queue->card, 2, "flushbuf"); 3344 QETH_CARD_TEXT(queue->card, 2, "flushbuf");
3345 QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no); 3345 QETH_CARD_TEXT_(queue->card, 2, " q%d", queue->queue_no);
@@ -3533,7 +3533,7 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
3533 int i; 3533 int i;
3534 3534
3535 QETH_CARD_TEXT(card, 6, "qdouhdl"); 3535 QETH_CARD_TEXT(card, 6, "qdouhdl");
3536 if (qdio_error & QDIO_ERROR_ACTIVATE_CHECK_CONDITION) { 3536 if (qdio_error & QDIO_ERROR_FATAL) {
3537 QETH_CARD_TEXT(card, 2, "achkcond"); 3537 QETH_CARD_TEXT(card, 2, "achkcond");
3538 netif_stop_queue(card->dev); 3538 netif_stop_queue(card->dev);
3539 qeth_schedule_recovery(card); 3539 qeth_schedule_recovery(card);