aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/s390/cio/qdio.h5
-rw-r--r--drivers/s390/cio/qdio_debug.c3
-rw-r--r--drivers/s390/cio/qdio_main.c38
3 files changed, 23 insertions, 23 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 42f2b09631b6..57807f5ffe84 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -186,6 +186,9 @@ struct qdio_input_q {
186 /* input buffer acknowledgement flag */ 186 /* input buffer acknowledgement flag */
187 int polling; 187 int polling;
188 188
189 /* first ACK'ed buffer */
190 int ack_start;
191
189 /* how much sbals are acknowledged with qebsm */ 192 /* how much sbals are acknowledged with qebsm */
190 int ack_count; 193 int ack_count;
191 194
@@ -234,7 +237,7 @@ struct qdio_q {
234 int first_to_check; 237 int first_to_check;
235 238
236 /* first_to_check of the last time */ 239 /* first_to_check of the last time */
237 int last_move_ftc; 240 int last_move;
238 241
239 /* beginning position for calling the program */ 242 /* beginning position for calling the program */
240 int first_to_kick; 243 int first_to_kick;
diff --git a/drivers/s390/cio/qdio_debug.c b/drivers/s390/cio/qdio_debug.c
index da7afb04e71f..e3434b34f86c 100644
--- a/drivers/s390/cio/qdio_debug.c
+++ b/drivers/s390/cio/qdio_debug.c
@@ -63,8 +63,9 @@ static int qstat_show(struct seq_file *m, void *v)
63 seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci); 63 seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci);
64 seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used)); 64 seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used));
65 seq_printf(m, "ftc: %d\n", q->first_to_check); 65 seq_printf(m, "ftc: %d\n", q->first_to_check);
66 seq_printf(m, "last_move_ftc: %d\n", q->last_move_ftc); 66 seq_printf(m, "last_move: %d\n", q->last_move);
67 seq_printf(m, "polling: %d\n", q->u.in.polling); 67 seq_printf(m, "polling: %d\n", q->u.in.polling);
68 seq_printf(m, "ack start: %d\n", q->u.in.ack_start);
68 seq_printf(m, "ack count: %d\n", q->u.in.ack_count); 69 seq_printf(m, "ack count: %d\n", q->u.in.ack_count);
69 seq_printf(m, "slsb buffer states:\n"); 70 seq_printf(m, "slsb buffer states:\n");
70 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n"); 71 seq_printf(m, "|0 |8 |16 |24 |32 |40 |48 |56 63|\n");
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 */