1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: qeth: adept SIGA error handling to qdio changes
3 References: bnc#484767,LTC#52300
5 Symptom: A qeth recovery may be triggered on hipersocket devices
6 in case no buffers are available on the target.
7 Problem: Recovery is triggered for all non-zero return values of
9 Solution: Check for SIGA errors after do_QDIO and don't recover in case
10 of temporary problems.
12 Acked-by: John Jolly <jjolly@suse.de>
14 drivers/s390/net/qeth_core_main.c | 55 +++++++++++---------------------------
15 1 file changed, 17 insertions(+), 38 deletions(-)
17 Index: linux-sles11/drivers/s390/net/qeth_core_main.c
18 ===================================================================
19 --- linux-sles11.orig/drivers/s390/net/qeth_core_main.c
20 +++ linux-sles11/drivers/s390/net/qeth_core_main.c
21 @@ -2659,40 +2659,21 @@ static int qeth_handle_send_error(struct
22 struct qeth_qdio_out_buffer *buffer, unsigned int qdio_err)
24 int sbalf15 = buffer->buffer->element[15].flags & 0xff;
25 - int cc = qdio_err & 3;
27 QETH_DBF_TEXT(TRACE, 6, "hdsnderr");
28 qeth_check_qdio_errors(buffer->buffer, qdio_err, "qouterr");
32 - QETH_DBF_TEXT(TRACE, 1, "lnkfail");
33 - QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
34 - QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
35 - (u16)qdio_err, (u8)sbalf15);
36 - return QETH_SEND_ERROR_LINK_FAILURE;
40 return QETH_SEND_ERROR_NONE;
42 - if (qdio_err & QDIO_ERROR_SIGA_BUSY) {
43 - QETH_DBF_TEXT(TRACE, 1, "SIGAcc2B");
44 - QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
45 - return QETH_SEND_ERROR_KICK_IT;
47 - if ((sbalf15 >= 15) && (sbalf15 <= 31))
48 - return QETH_SEND_ERROR_RETRY;
49 - return QETH_SEND_ERROR_LINK_FAILURE;
50 - /* look at qdio_error and sbalf 15 */
52 - QETH_DBF_TEXT(TRACE, 1, "SIGAcc1");
53 - QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
54 - return QETH_SEND_ERROR_LINK_FAILURE;
57 - QETH_DBF_TEXT(TRACE, 1, "SIGAcc3");
58 - QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
59 - return QETH_SEND_ERROR_KICK_IT;
62 + if ((sbalf15 >= 15) && (sbalf15 <= 31))
63 + return QETH_SEND_ERROR_RETRY;
65 + QETH_DBF_TEXT(TRACE, 1, "lnkfail");
66 + QETH_DBF_TEXT_(TRACE, 1, "%s", CARD_BUS_ID(card));
67 + QETH_DBF_TEXT_(TRACE, 1, "%04x %02x",
68 + (u16)qdio_err, (u8)sbalf15);
69 + return QETH_SEND_ERROR_LINK_FAILURE;
73 @@ -2828,10 +2809,14 @@ static void qeth_flush_buffers(struct qe
75 queue->card->perf_stats.outbound_do_qdio_start_time;
77 + queue->card->stats.tx_errors += count;
78 + /* ignore temporary SIGA errors without busy condition */
81 QETH_DBF_TEXT(TRACE, 2, "flushbuf");
82 QETH_DBF_TEXT_(TRACE, 2, " err%d", rc);
83 QETH_DBF_TEXT_(TRACE, 2, "%s", CARD_DDEV_ID(queue->card));
84 - queue->card->stats.tx_errors += count;
86 /* this must not happen under normal circumstances. if it
87 * happens something is really wrong -> recover */
88 qeth_schedule_recovery(queue->card);
89 @@ -2906,13 +2891,7 @@ void qeth_qdio_output_handler(struct ccw
91 for (i = first_element; i < (first_element + count); ++i) {
92 buffer = &queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q];
93 - /*we only handle the KICK_IT error by doing a recovery */
94 - if (qeth_handle_send_error(card, buffer, qdio_error)
95 - == QETH_SEND_ERROR_KICK_IT){
96 - netif_stop_queue(card->dev);
97 - qeth_schedule_recovery(card);
100 + qeth_handle_send_error(card, buffer, qdio_error);
101 qeth_clear_output_buffer(queue, buffer);
103 atomic_sub(count, &queue->used_buffers);