Blob Blame History Raw
From: Julian Wiedmann <jwi@linux.ibm.com>
Date: Mon, 15 Nov 2021 08:28:08 +0100
Subject: s390/qdio: clarify handler logic for qdio_handle_activate_check()
Git-commit: 513251fe25d304d1ca628c581bd0cc0422de150a
Patch-mainline: v5.17-rc1
References: jsc#PED-588 bsc#1203836 LTC#198623

qdio_handle_activate_check() tries to re-use one of the queue-specific
handlers to report that the ACTIVATE ccw has been terminated. But the
logic to select that handler is overly complex - in practice both
qdio drivers have at least one Input Queue, so we never take the other
paths.

Make things more obvious by removing this unused code, and clearly
spelling out that we re-use the Input Handler for generic error
reporting. This also paves the way for a world without queue-specific
error handlers.

Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Acked-by: Petr Tesarik <ptesarik@suse.com>
---
 arch/s390/include/asm/qdio.h  |    2 +-
 drivers/s390/cio/qdio.h       |    1 +
 drivers/s390/cio/qdio_main.c  |   25 +++++++++++--------------
 drivers/s390/cio/qdio_setup.c |    1 +
 4 files changed, 14 insertions(+), 15 deletions(-)

--- a/arch/s390/include/asm/qdio.h
+++ b/arch/s390/include/asm/qdio.h
@@ -312,7 +312,7 @@ typedef void qdio_handler_t(struct ccw_d
  * @qib_rflags: rflags to set
  * @no_input_qs: number of input queues
  * @no_output_qs: number of output queues
- * @input_handler: handler to be called for input queues
+ * @input_handler: handler to be called for input queues, and device-wide errors
  * @output_handler: handler to be called for output queues
  * @irq_poll: Data IRQ polling handler
  * @scan_threshold: # of in-use buffers that triggers scan on output queue
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -240,6 +240,7 @@ struct qdio_irq {
 
 	struct qdio_ssqd_desc ssqd_desc;
 	void (*orig_handler) (struct ccw_device *, unsigned long, struct irb *);
+	qdio_handler_t (*error_handler);
 
 	int perf_stat_enabled;
 
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -654,24 +654,18 @@ static void qdio_handle_activate_check(s
 				       unsigned long intparm, int cstat,
 				       int dstat)
 {
-	struct qdio_q *q;
+	unsigned int first_to_check = 0;
 
 	DBF_ERROR("%4x ACT CHECK", irq_ptr->schid.sch_no);
 	DBF_ERROR("intp :%lx", intparm);
 	DBF_ERROR("ds: %2x cs:%2x", dstat, cstat);
 
-	if (irq_ptr->nr_input_qs) {
-		q = irq_ptr->input_qs[0];
-	} else if (irq_ptr->nr_output_qs) {
-		q = irq_ptr->output_qs[0];
-	} else {
-		dump_stack();
-		goto no_handler;
-	}
+	/* zfcp wants this: */
+	if (irq_ptr->nr_input_qs)
+		first_to_check = irq_ptr->input_qs[0]->first_to_check;
 
-	q->handler(irq_ptr->cdev, QDIO_ERROR_ACTIVATE, 0, q->first_to_check,
-		   0, irq_ptr->int_parm);
-no_handler:
+	irq_ptr->error_handler(irq_ptr->cdev, QDIO_ERROR_ACTIVATE, 0,
+			       first_to_check, 0, irq_ptr->int_parm);
 	qdio_set_state(irq_ptr, QDIO_IRQ_STATE_STOPPED);
 	/*
 	 * In case of z/VM LGR (Live Guest Migration) QDIO recovery will happen.
@@ -996,8 +990,11 @@ int qdio_establish(struct ccw_device *cd
 	    init_data->no_output_qs > irq_ptr->max_output_qs)
 		return -EINVAL;
 
-	if ((init_data->no_input_qs && !init_data->input_handler) ||
-	    (init_data->no_output_qs && !init_data->output_handler))
+	/* Needed as error_handler: */
+	if (!init_data->input_handler)
+		return -EINVAL;
+
+	if (init_data->no_output_qs && !init_data->output_handler)
 		return -EINVAL;
 
 	if (!init_data->input_sbal_addr_array ||
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -375,6 +375,7 @@ void qdio_setup_irq(struct qdio_irq *irq
 	irq_ptr->debugfs_dev = NULL;
 	irq_ptr->sch_token = irq_ptr->perf_stat_enabled = 0;
 	irq_ptr->state = QDIO_IRQ_STATE_INACTIVE;
+	irq_ptr->error_handler = init_data->input_handler;
 
 	irq_ptr->int_parm = init_data->int_parm;
 	irq_ptr->nr_input_qs = init_data->no_input_qs;