Blob Blame History Raw
From: Julian Wiedmann <jwi@linux.ibm.com>
Date: Tue, 1 Jun 2021 08:20:09 +0200
Subject: s390/qdio: propagate error when cancelling a ccw fails
Git-commit: d1ea9b58c8fbdc280f06b48469b4d056bd69f142
Patch-mainline: v5.15-rc1
References: jsc#SLE-18329 jsc#SLE-18330 jsc#SLE-18516 bsc#1191738 LTC#193282

If qdio_cancel_ccw() times out (or is interrupted) before the interrupt
for the {halt,clear} action arrives, report this back to the caller as
an error.

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>
---
 drivers/s390/cio/qdio_main.c |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -893,6 +893,7 @@ static void qdio_shutdown_queues(struct
 static int qdio_cancel_ccw(struct qdio_irq *irq, int how)
 {
 	struct ccw_device *cdev = irq->cdev;
+	long timeout;
 	int rc;
 
 	spin_lock_irq(get_ccwdev_lock(cdev));
@@ -909,12 +910,14 @@ static int qdio_cancel_ccw(struct qdio_i
 		return rc;
 	}
 
-	wait_event_interruptible_timeout(cdev->private->wait_q,
-					 irq->state == QDIO_IRQ_STATE_INACTIVE ||
-					 irq->state == QDIO_IRQ_STATE_ERR,
-					 10 * HZ);
+	timeout = wait_event_interruptible_timeout(cdev->private->wait_q,
+						   irq->state == QDIO_IRQ_STATE_INACTIVE ||
+						   irq->state == QDIO_IRQ_STATE_ERR,
+						   10 * HZ);
+	if (timeout <= 0)
+		rc = (timeout == -ERESTARTSYS) ? -EINTR : -ETIME;
 
-	return 0;
+	return rc;
 }
 
 /**