s390/qeth: tolerate pre-filled RX buffer
[linux-2.6-microblaze.git] / drivers / s390 / net / qeth_core_main.c
index 8a76022..b356ee5 100644 (file)
@@ -204,12 +204,17 @@ EXPORT_SYMBOL_GPL(qeth_threads_running);
 void qeth_clear_working_pool_list(struct qeth_card *card)
 {
        struct qeth_buffer_pool_entry *pool_entry, *tmp;
+       struct qeth_qdio_q *queue = card->qdio.in_q;
+       unsigned int i;
 
        QETH_CARD_TEXT(card, 5, "clwrklst");
        list_for_each_entry_safe(pool_entry, tmp,
                            &card->qdio.in_buf_pool.entry_list, list){
                        list_del(&pool_entry->list);
        }
+
+       for (i = 0; i < ARRAY_SIZE(queue->bufs); i++)
+               queue->bufs[i].pool_entry = NULL;
 }
 EXPORT_SYMBOL_GPL(qeth_clear_working_pool_list);
 
@@ -2965,7 +2970,7 @@ static struct qeth_buffer_pool_entry *qeth_find_free_buffer_pool_entry(
 static int qeth_init_input_buffer(struct qeth_card *card,
                struct qeth_qdio_buffer *buf)
 {
-       struct qeth_buffer_pool_entry *pool_entry;
+       struct qeth_buffer_pool_entry *pool_entry = buf->pool_entry;
        int i;
 
        if ((card->options.cq == QETH_CQ_ENABLED) && (!buf->rx_skb)) {
@@ -2976,9 +2981,13 @@ static int qeth_init_input_buffer(struct qeth_card *card,
                        return -ENOMEM;
        }
 
-       pool_entry = qeth_find_free_buffer_pool_entry(card);
-       if (!pool_entry)
-               return -ENOBUFS;
+       if (!pool_entry) {
+               pool_entry = qeth_find_free_buffer_pool_entry(card);
+               if (!pool_entry)
+                       return -ENOBUFS;
+
+               buf->pool_entry = pool_entry;
+       }
 
        /*
         * since the buffer is accessed only from the input_tasklet
@@ -2986,8 +2995,6 @@ static int qeth_init_input_buffer(struct qeth_card *card,
         * the QETH_IN_BUF_REQUEUE_THRESHOLD we should never run  out off
         * buffers
         */
-
-       buf->pool_entry = pool_entry;
        for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
                buf->buffer->element[i].length = PAGE_SIZE;
                buf->buffer->element[i].addr =
@@ -5771,6 +5778,7 @@ static unsigned int qeth_rx_poll(struct qeth_card *card, int budget)
                if (done) {
                        QETH_CARD_STAT_INC(card, rx_bufs);
                        qeth_put_buffer_pool_entry(card, buffer->pool_entry);
+                       buffer->pool_entry = NULL;
                        qeth_queue_input_buffer(card, card->rx.b_index);
                        card->rx.b_count--;