[S390] qdio: seperate last move index and polling index
authorJan Glauber <jang@linux.vnet.ibm.com>
Thu, 26 Mar 2009 14:24:29 +0000 (15:24 +0100)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Thu, 26 Mar 2009 14:24:21 +0000 (15:24 +0100)
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>
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_debug.c
drivers/s390/cio/qdio_main.c

index 42f2b09..57807f5 100644 (file)
@@ -186,6 +186,9 @@ struct qdio_input_q {
        /* input buffer acknowledgement flag */
        int polling;
 
+       /* first ACK'ed buffer */
+       int ack_start;
+
        /* how much sbals are acknowledged with qebsm */
        int ack_count;
 
@@ -234,7 +237,7 @@ struct qdio_q {
        int first_to_check;
 
        /* first_to_check of the last time */
-       int last_move_ftc;
+       int last_move;
 
        /* beginning position for calling the program */
        int first_to_kick;
index da7afb0..e3434b3 100644 (file)
@@ -63,8 +63,9 @@ static int qstat_show(struct seq_file *m, void *v)
        seq_printf(m, "device state indicator: %d\n", *(u32 *)q->irq_ptr->dsci);
        seq_printf(m, "nr_used: %d\n", atomic_read(&q->nr_buf_used));
        seq_printf(m, "ftc: %d\n", q->first_to_check);
-       seq_printf(m, "last_move_ftc: %d\n", q->last_move_ftc);
+       seq_printf(m, "last_move: %d\n", q->last_move);
        seq_printf(m, "polling: %d\n", q->u.in.polling);
+       seq_printf(m, "ack start: %d\n", q->u.in.ack_start);
        seq_printf(m, "ack count: %d\n", q->u.in.ack_count);
        seq_printf(m, "slsb buffer states:\n");
        seq_printf(m, "|0      |8      |16     |24     |32     |40     |48     |56  63|\n");
index 61ba765..31b9318 100644 (file)
@@ -380,11 +380,11 @@ inline void qdio_stop_polling(struct qdio_q *q)
 
        /* show the card that we are not polling anymore */
        if (is_qebsm(q)) {
-               set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
+               set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
                               q->u.in.ack_count);
                q->u.in.ack_count = 0;
        } else
-               set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
+               set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
 }
 
 static 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)
                if (!q->u.in.polling) {
                        q->u.in.polling = 1;
                        q->u.in.ack_count = count;
-                       q->last_move_ftc = q->first_to_check;
+                       q->u.in.ack_start = q->first_to_check;
                        return;
                }
 
                /* delete the previous ACK's */
-               set_buf_states(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT,
+               set_buf_states(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT,
                               q->u.in.ack_count);
                q->u.in.ack_count = count;
-               q->last_move_ftc = q->first_to_check;
+               q->u.in.ack_start = q->first_to_check;
                return;
        }
 
@@ -439,18 +439,13 @@ static inline void inbound_primed(struct qdio_q *q, int count)
        if (q->u.in.polling) {
                /* reset the previous ACK but first set the new one */
                set_buf_state(q, new, SLSB_P_INPUT_ACK);
-               set_buf_state(q, q->last_move_ftc, SLSB_P_INPUT_NOT_INIT);
+               set_buf_state(q, q->u.in.ack_start, SLSB_P_INPUT_NOT_INIT);
        } else {
                q->u.in.polling = 1;
                set_buf_state(q, new, SLSB_P_INPUT_ACK);
        }
 
-       /*
-        * last_move_ftc points to the ACK'ed buffer and not to the last turns
-        * first_to_check like for qebsm. Since it is only used to check if
-        * the queue front moved in qdio_inbound_q_done this is not a problem.
-        */
-       q->last_move_ftc = new;
+       q->u.in.ack_start = new;
        count--;
        if (!count)
                return;
@@ -527,7 +522,8 @@ int qdio_inbound_q_moved(struct qdio_q *q)
 
        bufnr = get_inbound_buffer_frontier(q);
 
-       if ((bufnr != q->last_move_ftc) || q->qdio_error) {
+       if ((bufnr != q->last_move) || q->qdio_error) {
+               q->last_move = bufnr;
                if (!need_siga_sync(q) && !pci_out_supported(q))
                        q->u.in.timestamp = get_usecs();
 
@@ -702,8 +698,8 @@ static inline int qdio_outbound_q_moved(struct qdio_q *q)
 
        bufnr = get_outbound_buffer_frontier(q);
 
-       if ((bufnr != q->last_move_ftc) || q->qdio_error) {
-               q->last_move_ftc = bufnr;
+       if ((bufnr != q->last_move) || q->qdio_error) {
+               q->last_move = bufnr;
                DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
                return 1;
        } else
@@ -748,7 +744,7 @@ static void qdio_kick_outbound_handler(struct qdio_q *q)
        int start, end, count;
 
        start = q->first_to_kick;
-       end = q->last_move_ftc;
+       end = q->last_move;
        if (end >= start)
                count = end - start;
        else
@@ -764,7 +760,7 @@ static void qdio_kick_outbound_handler(struct qdio_q *q)
                   q->irq_ptr->int_parm);
 
        /* for the next time: */
-       q->first_to_kick = q->last_move_ftc;
+       q->first_to_kick = q->last_move;
        q->qdio_error = 0;
 }
 
@@ -1475,18 +1471,18 @@ static void handle_inbound(struct qdio_q *q, unsigned int callflags,
                q->u.in.polling = 0;
                q->u.in.ack_count = 0;
                goto set;
-       } else if (buf_in_between(q->last_move_ftc, bufnr, count)) {
+       } else if (buf_in_between(q->u.in.ack_start, bufnr, count)) {
                if (is_qebsm(q)) {
-                       /* partial overwrite, just update last_move_ftc */
+                       /* partial overwrite, just update ack_start */
                        diff = add_buf(bufnr, count);
-                       diff = sub_buf(diff, q->last_move_ftc);
+                       diff = sub_buf(diff, q->u.in.ack_start);
                        q->u.in.ack_count -= diff;
                        if (q->u.in.ack_count <= 0) {
                                q->u.in.polling = 0;
                                q->u.in.ack_count = 0;
                                goto set;
                        }
-                       q->last_move_ftc = add_buf(q->last_move_ftc, diff);
+                       q->u.in.ack_start = add_buf(q->u.in.ack_start, diff);
                }
                else
                        /* the only ACK will be deleted, so stop polling */