summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2017-09-05 14:22:48 +0200
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-09-28 07:29:41 +0200
commitadc69b4d76ee8a7065c7c637584b39ace265ffab (patch)
treea100bac8bd2063c347148beab68365c804e09def /drivers
parentb08e19defc10befc50af09771ff0b086f2a72138 (diff)
downloadlinux-adc69b4d76ee8a7065c7c637584b39ace265ffab.tar.gz
linux-adc69b4d76ee8a7065c7c637584b39ace265ffab.tar.bz2
linux-adc69b4d76ee8a7065c7c637584b39ace265ffab.zip
s390/cmf: set_schib_wait add timeout
When enabling channel measurement fails with a busy condition we wait for the next interrupt to arrive before we retry the operation. For devices which usually don't create interrupts we wait forever. Although the waiting is done interruptible that behavior is not expected and confused some users. Abort the operation after a 10s timeout. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/s390/cio/cmf.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 220491d27ef4..be0b010ff136 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -227,6 +227,7 @@ static void cmf_set_schib_release(struct kref *kref)
}
#define CMF_PENDING 1
+#define SET_SCHIB_TIMEOUT (10 * HZ)
static int set_schib_wait(struct ccw_device *cdev, u32 mme,
int mbfc, unsigned long address)
@@ -263,19 +264,19 @@ static int set_schib_wait(struct ccw_device *cdev, u32 mme,
cdev->private->state = DEV_STATE_CMFCHANGE;
set_data->ret = CMF_PENDING;
cdev->private->cmb_wait = set_data;
-
spin_unlock_irq(cdev->ccwlock);
- if (wait_event_interruptible(set_data->wait,
- set_data->ret != CMF_PENDING)) {
- spin_lock_irq(cdev->ccwlock);
+
+ ret = wait_event_interruptible_timeout(set_data->wait,
+ set_data->ret != CMF_PENDING,
+ SET_SCHIB_TIMEOUT);
+ spin_lock_irq(cdev->ccwlock);
+ if (ret <= 0) {
if (set_data->ret == CMF_PENDING) {
- set_data->ret = -ERESTARTSYS;
+ set_data->ret = (ret == 0) ? -ETIME : ret;
if (cdev->private->state == DEV_STATE_CMFCHANGE)
cdev->private->state = DEV_STATE_ONLINE;
}
- spin_unlock_irq(cdev->ccwlock);
}
- spin_lock_irq(cdev->ccwlock);
cdev->private->cmb_wait = NULL;
ret = set_data->ret;
out_put: