aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/qdio_main.c
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2009-03-26 10:24:29 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-03-26 10:24:21 -0400
commite85dea0e415617b5c5627f38c71b33fbc7f94a85 (patch)
tree59400d25cb978f66e3b2906dbed01813b617e0ba /drivers/s390/cio/qdio_main.c
parent3fdf1e18cbc7c58f2d5604315ddae3596725bc6a (diff)
[S390] qdio: seperate last move index and polling index
The index value that indicated that the input queue moved was also used to store the index of the first acknowledged buffer. For non-qebsm only the newest buffer is acknowledged which may be different from the last move index so two seperate values are needed to track the input queue. Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/qdio_main.c')
-rw-r--r--drivers/s390/cio/qdio_main.c38
1 files changed, 17 insertions, 21 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 61ba765936a6..31b9318149ba 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -380,11 +380,11 @@ inline void qdio_stop_polling(struct qdio_q *q)
380 380
381 /* show the card that we are not polling anymore */ 381 /* show the card that we are not polling anymore */
382 if (is_qebsm(q)) { 382 if (is_qebsm(q)) {
383 set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT, 383 set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
384 q->u.in.ack_count); 384 q->u.in.ack_count);
385 q->u.in.ack_count = 0; 385 q->u.in.ack_count = 0;
386 } else 386 } else
387 set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT); 387 set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
388} 388}
389 389
390static void announce_buffer_error(struct qdio_q *q, int count) 390static void announce_buffer_error(struct qdio_q *q, int count)
@@ -419,15 +419,15 @@ static inline void inbound_primed(struct qdio_q *q, int count)
419 if (!q->u.in.polling) { 419 if (!q->u.in.polling) {
420 q->u.in.polling = 1; 420 q->u.in.polling = 1;
421 q->u.in.ack_count = count; 421 q->u.in.ack_count = count;
422 q->last_move_ftc = q->first_to_check; 422 q->u.in.ack_start = q->first_to_check;
423 return; 423 return;
424 } 424 }
425 425
426 /* delete the previous ACK's */ 426 /* delete the previous ACK's */
427 set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT, 427 set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
428 q->u.in.ack_count); 428 q->u.in.ack_count);
429 q->u.in.ack_count = count; 429 q->u.in.ack_count = count;
430 q->last_move_ftc = q->first_to_check; 430 q->u.in.ack_start = q->first_to_check;
431 return; 431 return;
432 } 432 }
433 433
@@ -439,18 +439,13 @@ static inline void inbound_primed(struct qdio_q *q, int count)
439 if (q->u.in.polling) { 439 if (q->u.in.polling) {
440 /* reset the previous ACK but first set the new one */ 440 /* reset the previous ACK but first set the new one */
441 set_buf_state(q, new, SLSB_P_INPUT_ACK); 441 set_buf_state(q, new, SLSB_P_INPUT_ACK);
442 set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT); 442 set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
443 } else { 443 } else {
444 q->u.in.polling = 1; 444 q->u.in.polling = 1;
445 set_buf_state(q, new, SLSB_P_INPUT_ACK); 445 set_buf_state(q, new, SLSB_P_INPUT_ACK);
446 } 446 }
447 447
448 /* 448 q->u.in.ack_start = new;
449 * last_move_ftc points to the ACK'ed buffer and not to the last turns
450 * first_to_check like for qebsm. Since it is only used to check if
451 * the queue front moved in qdio_inbound_q_done this is not a problem.
452 */
453 q->last_move_ftc = new;
454 count--; 449 count--;
455 if (!count) 450 if (!count)
456 return; 451 return;
@@ -527,7 +522,8 @@ int qdio_inbound_q_moved(struct qdio_q *q)
527 522
528 bufnr = get_inbound_buffer_frontier(q); 523 bufnr = get_inbound_buffer_frontier(q);
529 524
530 if ((bufnr != q->last_move_ftc) || q->qdio_error) { 525 if ((bufnr != q->last_move) || q->qdio_error) {
526 q->last_move = bufnr;
531 if (!need_siga_sync(q) && !pci_out_supported(q)) 527 if (!need_siga_sync(q) && !pci_out_supported(q))
532 q->u.in.timestamp = get_usecs(); 528 q->u.in.timestamp = get_usecs();
533 529
@@ -702,8 +698,8 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q)
702 698
703 bufnr = get_outbound_buffer_frontier(q); 699 bufnr = get_outbound_buffer_frontier(q);
704 700
705 if ((bufnr != q->last_move_ftc) || q->qdio_error) { 701 if ((bufnr != q->last_move) || q->qdio_error) {
706 q->last_move_ftc = bufnr; 702 q->last_move = bufnr;
707 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr); 703 DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
708 return 1; 704 return 1;
709 } else 705 } else
@@ -748,7 +744,7 @@ static void qdio_kick_outbound_handler(struct qdio_q *q)
748 int start, end, count; 744 int start, end, count;
749 745
750 start = q->first_to_kick; 746 start = q->first_to_kick;
751 end = q->last_move_ftc; 747 end = q->last_move;
752 if (end >= start) 748 if (end >= start)
753 count = end - start; 749 count = end - start;
754 else 750 else
@@ -764,7 +760,7 @@ static void qdio_kick_outbound_handler(struct qdio_q *q)
764 q->irq_ptr->int_parm); 760 q->irq_ptr->int_parm);
765 761
766 /* for the next time: */ 762 /* for the next time: */
767 q->first_to_kick = q->last_move_ftc; 763 q->first_to_kick = q->last_move;
768 q->qdio_error = 0; 764 q->qdio_error = 0;
769} 765}
770 766
@@ -1475,18 +1471,18 @@ static void handle_inbound(struct qdio_q *q, unsigned int callflags,
1475 q->u.in.polling = 0; 1471 q->u.in.polling = 0;
1476 q->u.in.ack_count = 0; 1472 q->u.in.ack_count = 0;
1477 goto set; 1473 goto set;
1478 } else if (buf_in_between(q->last_move_ftc, bufnr, count)) { 1474 } else if (buf_in_between(q->u.in.ack_start, bufnr, count)) {
1479 if (is_qebsm(q)) { 1475 if (is_qebsm(q)) {
1480 /* partial overwrite, just update last_move_ftc */ 1476 /* partial overwrite, just update ack_start */
1481 diff = add_buf(bufnr, count); 1477 diff = add_buf(bufnr, count);
1482 diff = sub_buf(diff, q->last_move_ftc); 1478 diff = sub_buf(diff, q->u.in.ack_start);
1483 q->u.in.ack_count -= diff; 1479 q->u.in.ack_count -= diff;
1484 if (q->u.in.ack_count <= 0) { 1480 if (q->u.in.ack_count <= 0) {
1485 q->u.in.polling = 0; 1481 q->u.in.polling = 0;
1486 q->u.in.ack_count = 0; 1482 q->u.in.ack_count = 0;
1487 goto set; 1483 goto set;
1488 } 1484 }
1489 q->last_move_ftc = add_buf(q->last_move_ftc, diff); 1485 q->u.in.ack_start = add_buf(q->u.in.ack_start, diff);
1490 } 1486 }
1491 else 1487 else
1492 /* the only ACK will be deleted, so stop polling */ 1488 /* the only ACK will be deleted, so stop polling */