s390/qdio: rework q->qdio_error indication
authorJulian Wiedmann <jwi@linux.ibm.com>
Sat, 30 Jan 2021 11:44:17 +0000 (12:44 +0100)
committerVasily Gorbik <gor@linux.ibm.com>
Sat, 13 Feb 2021 16:17:55 +0000 (17:17 +0100)
When inspecting a queue, any error is currently returned back through
the queue's qdio_error field. Turn this into a proper variable that gets
passed through the call chain, so that the lifetime is clear and the
error state can be accessed along the way.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
drivers/s390/cio/qdio.h
drivers/s390/cio/qdio_main.c

index 84425e294e36b9fe6cdc5fc18c4ab803c4f38a16..34bf2f197c7144b13b271400da799abc69452fe5 100644 (file)
@@ -214,9 +214,6 @@ struct qdio_q {
        /* number of buffers in use by the adapter */
        atomic_t nr_buf_used;
 
-       /* error condition during a data transfer */
-       unsigned int qdio_error;
-
        /* last scan of the queue */
        u64 timestamp;
 
index a83101d9ec4aab00057a0a5a2635a61895edf342..4252f43ef214561046fed922140a0456bfe1e10a 100644 (file)
@@ -420,8 +420,6 @@ static inline void account_sbals(struct qdio_q *q, unsigned int count)
 static void process_buffer_error(struct qdio_q *q, unsigned int start,
                                 int count)
 {
-       q->qdio_error = QDIO_ERROR_SLSB_STATE;
-
        /* special handling for no target buffer empty */
        if (queue_type(q) == QDIO_IQDIO_QFMT && !q->is_input_q &&
            q->sbal[start]->element[15].sflags == 0x10) {
@@ -450,7 +448,8 @@ static inline void inbound_handle_work(struct qdio_q *q, unsigned int start,
        q->u.in.batch_count += count;
 }
 
-static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start)
+static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start,
+                                      unsigned int *error)
 {
        unsigned char state = 0;
        int count;
@@ -484,6 +483,7 @@ static int get_inbound_buffer_frontier(struct qdio_q *q, unsigned int start)
                DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "in err:%1d %02x", q->nr,
                              count);
 
+               *error = QDIO_ERROR_SLSB_STATE;
                process_buffer_error(q, start, count);
                inbound_handle_work(q, start, count, false);
                if (atomic_sub_return(count, &q->nr_buf_used) == 0)
@@ -567,7 +567,8 @@ static void qdio_check_pending(struct qdio_q *q, unsigned int index)
        }
 }
 
-static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start)
+static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start,
+                                       unsigned int *error)
 {
        unsigned char state = 0;
        int count;
@@ -601,6 +602,7 @@ static int get_outbound_buffer_frontier(struct qdio_q *q, unsigned int start)
                        account_sbals(q, count);
                return count;
        case SLSB_P_OUTPUT_ERROR:
+               *error = QDIO_ERROR_SLSB_STATE;
                process_buffer_error(q, start, count);
                atomic_sub(count, &q->nr_buf_used);
                if (q->irq_ptr->perf_stat_enabled)
@@ -631,11 +633,12 @@ static inline int qdio_outbound_q_done(struct qdio_q *q)
        return atomic_read(&q->nr_buf_used) == 0;
 }
 
-static inline int qdio_outbound_q_moved(struct qdio_q *q, unsigned int start)
+static inline int qdio_outbound_q_moved(struct qdio_q *q, unsigned int start,
+                                       unsigned int *error)
 {
        int count;
 
-       count = get_outbound_buffer_frontier(q, start);
+       count = get_outbound_buffer_frontier(q, start, error);
 
        if (count) {
                DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "out moved:%1d", q->nr);
@@ -699,12 +702,13 @@ void qdio_outbound_tasklet(struct tasklet_struct *t)
        struct qdio_output_q *out_q = from_tasklet(out_q, t, tasklet);
        struct qdio_q *q = container_of(out_q, struct qdio_q, u.out);
        unsigned int start = q->first_to_check;
+       unsigned int error = 0;
        int count;
 
        qperf_inc(q, tasklet_outbound);
        WARN_ON_ONCE(atomic_read(&q->nr_buf_used) < 0);
 
-       count = qdio_outbound_q_moved(q, start);
+       count = qdio_outbound_q_moved(q, start, &error);
        if (count) {
                q->first_to_check = add_buf(start, count);
 
@@ -713,11 +717,8 @@ void qdio_outbound_tasklet(struct tasklet_struct *t)
                        DBF_DEV_EVENT(DBF_INFO, q->irq_ptr, "koh: s:%02x c:%02x",
                                      start, count);
 
-                       q->handler(q->irq_ptr->cdev, q->qdio_error, q->nr,
-                                  start, count, q->irq_ptr->int_parm);
-
-                       /* for the next time */
-                       q->qdio_error = 0;
+                       q->handler(q->irq_ptr->cdev, error, q->nr, start,
+                                  count, q->irq_ptr->int_parm);
                }
        }
 
@@ -1472,17 +1473,16 @@ static int __qdio_inspect_queue(struct qdio_q *q, unsigned int *bufnr,
        unsigned int start = q->first_to_check;
        int count;
 
-       count = q->is_input_q ? get_inbound_buffer_frontier(q, start) :
-                               qdio_outbound_q_moved(q, start);
+       *error = 0;
+       count = q->is_input_q ? get_inbound_buffer_frontier(q, start, error) :
+                               qdio_outbound_q_moved(q, start, error);
        if (count == 0)
                return 0;
 
        *bufnr = start;
-       *error = q->qdio_error;
 
        /* for the next time */
        q->first_to_check = add_buf(start, count);
-       q->qdio_error = 0;
 
        return count;
 }