X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fs390%2Fcio%2Fqdio_main.c;h=e8f267eb88873b2a65e8d0cb05bcce3dc5c2c33c;hb=8043f4eb85bf772e3af82678657019937388b6e1;hp=479c665e9e7c25f91996eeb287770384009c9b7a;hpb=90f1e7481eebfd47e7dbf7c8c0cbfe31e025e031;p=pandora-kernel.git diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c index 479c665e9e7c..e8f267eb8887 100644 --- a/drivers/s390/cio/qdio_main.c +++ b/drivers/s390/cio/qdio_main.c @@ -407,8 +407,11 @@ static inline void account_sbals(struct qdio_q *q, int count) q->q_stats.nr_sbals[pos]++; } -static void announce_buffer_error(struct qdio_q *q, int count) +static void process_buffer_error(struct qdio_q *q, int count) { + unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT : + SLSB_P_OUTPUT_NOT_INIT; + q->qdio_error |= QDIO_ERROR_SLSB_STATE; /* special handling for no target buffer empty */ @@ -426,6 +429,12 @@ static void announce_buffer_error(struct qdio_q *q, int count) DBF_ERROR("F14:%2x F15:%2x", q->sbal[q->first_to_check]->element[14].flags & 0xff, q->sbal[q->first_to_check]->element[15].flags & 0xff); + + /* + * Interrupts may be avoided as long as the error is present + * so change the buffer state immediately to avoid starvation. + */ + set_buf_states(q, q->first_to_check, state, count); } static inline void inbound_primed(struct qdio_q *q, int count) @@ -506,8 +515,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q) account_sbals(q, count); break; case SLSB_P_INPUT_ERROR: - announce_buffer_error(q, count); - /* process the buffer, the upper layer will take care of it */ + process_buffer_error(q, count); q->first_to_check = add_buf(q->first_to_check, count); atomic_sub(count, &q->nr_buf_used); if (q->irq_ptr->perf_stat_enabled) @@ -677,8 +685,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q) account_sbals(q, count); break; case SLSB_P_OUTPUT_ERROR: - announce_buffer_error(q, count); - /* process the buffer, the upper layer will take care of it */ + process_buffer_error(q, count); q->first_to_check = add_buf(q->first_to_check, count); atomic_sub(count, &q->nr_buf_used); if (q->irq_ptr->perf_stat_enabled) @@ -1649,26 +1656,26 @@ static int __init init_QDIO(void) { int rc; - rc = qdio_setup_init(); + rc = qdio_debug_init(); if (rc) return rc; + rc = qdio_setup_init(); + if (rc) + goto out_debug; rc = tiqdio_allocate_memory(); if (rc) goto out_cache; - rc = qdio_debug_init(); - if (rc) - goto out_ti; rc = tiqdio_register_thinints(); if (rc) - goto out_debug; + goto out_ti; return 0; -out_debug: - qdio_debug_exit(); out_ti: tiqdio_free_memory(); out_cache: qdio_setup_exit(); +out_debug: + qdio_debug_exit(); return rc; } @@ -1676,8 +1683,8 @@ static void __exit exit_QDIO(void) { tiqdio_unregister_thinints(); tiqdio_free_memory(); - qdio_debug_exit(); qdio_setup_exit(); + qdio_debug_exit(); } module_init(init_QDIO);