Commit 540936df authored by Julian Wiedmann's avatar Julian Wiedmann Committed by Vasily Gorbik
Browse files

s390/qdio: rework q->qdio_error indication



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: default avatarJulian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: default avatarBenjamin Block <bblock@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 3bf526e0
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -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;

+16 −16
Original line number Diff line number Diff line
@@ -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;
}