[S390] qdio: reset error states immediately

The qdio hardware may surpress further interrupts as long as a SBAL is in
the error state. That can lead to unnotified data in the SBALs following
the error state. To prevent this behaviour change the SBAL[s] in error
state immediately to another program owned state so interrupts are again
received for further traffic on the device.

Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by Jan Glauber and committed by Martin Schwidefsky bffbbd2d e4c031b4

+12 -5
+12 -5
drivers/s390/cio/qdio_main.c
··· 407 407 q->q_stats.nr_sbals[pos]++; 408 408 } 409 409 410 - static void announce_buffer_error(struct qdio_q *q, int count) 410 + static void process_buffer_error(struct qdio_q *q, int count) 411 411 { 412 + unsigned char state = (q->is_input_q) ? SLSB_P_INPUT_NOT_INIT : 413 + SLSB_P_OUTPUT_NOT_INIT; 414 + 412 415 q->qdio_error |= QDIO_ERROR_SLSB_STATE; 413 416 414 417 /* special handling for no target buffer empty */ ··· 429 426 DBF_ERROR("F14:%2x F15:%2x", 430 427 q->sbal[q->first_to_check]->element[14].flags & 0xff, 431 428 q->sbal[q->first_to_check]->element[15].flags & 0xff); 429 + 430 + /* 431 + * Interrupts may be avoided as long as the error is present 432 + * so change the buffer state immediately to avoid starvation. 433 + */ 434 + set_buf_states(q, q->first_to_check, state, count); 432 435 } 433 436 434 437 static inline void inbound_primed(struct qdio_q *q, int count) ··· 515 506 account_sbals(q, count); 516 507 break; 517 508 case SLSB_P_INPUT_ERROR: 518 - announce_buffer_error(q, count); 519 - /* process the buffer, the upper layer will take care of it */ 509 + process_buffer_error(q, count); 520 510 q->first_to_check = add_buf(q->first_to_check, count); 521 511 atomic_sub(count, &q->nr_buf_used); 522 512 if (q->irq_ptr->perf_stat_enabled) ··· 685 677 account_sbals(q, count); 686 678 break; 687 679 case SLSB_P_OUTPUT_ERROR: 688 - announce_buffer_error(q, count); 689 - /* process the buffer, the upper layer will take care of it */ 680 + process_buffer_error(q, count); 690 681 q->first_to_check = add_buf(q->first_to_check, count); 691 682 atomic_sub(count, &q->nr_buf_used); 692 683 if (q->irq_ptr->perf_stat_enabled)