Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit adc69b4d authored by Sebastian Ott's avatar Sebastian Ott Committed by Martin Schwidefsky
Browse files

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: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Reviewed-by: default avatarPeter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent b08e19de
Loading
Loading
Loading
Loading
+8 −7
Original line number Original line Diff line number Diff line
@@ -227,6 +227,7 @@ static void cmf_set_schib_release(struct kref *kref)
}
}


#define CMF_PENDING 1
#define CMF_PENDING 1
#define SET_SCHIB_TIMEOUT (10 * HZ)


static int set_schib_wait(struct ccw_device *cdev, u32 mme,
static int set_schib_wait(struct ccw_device *cdev, u32 mme,
				int mbfc, unsigned long address)
				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;
	cdev->private->state = DEV_STATE_CMFCHANGE;
	set_data->ret = CMF_PENDING;
	set_data->ret = CMF_PENDING;
	cdev->private->cmb_wait = set_data;
	cdev->private->cmb_wait = set_data;

	spin_unlock_irq(cdev->ccwlock);
	spin_unlock_irq(cdev->ccwlock);
	if (wait_event_interruptible(set_data->wait,

				     set_data->ret != CMF_PENDING)) {
	ret = wait_event_interruptible_timeout(set_data->wait,
					       set_data->ret != CMF_PENDING,
					       SET_SCHIB_TIMEOUT);
	spin_lock_irq(cdev->ccwlock);
	spin_lock_irq(cdev->ccwlock);
	if (ret <= 0) {
		if (set_data->ret == CMF_PENDING) {
		if (set_data->ret == CMF_PENDING) {
			set_data->ret = -ERESTARTSYS;
			set_data->ret = (ret == 0) ? -ETIME : ret;
			if (cdev->private->state == DEV_STATE_CMFCHANGE)
			if (cdev->private->state == DEV_STATE_CMFCHANGE)
				cdev->private->state = DEV_STATE_ONLINE;
				cdev->private->state = DEV_STATE_ONLINE;
		}
		}
		spin_unlock_irq(cdev->ccwlock);
	}
	}
	spin_lock_irq(cdev->ccwlock);
	cdev->private->cmb_wait = NULL;
	cdev->private->cmb_wait = NULL;
	ret = set_data->ret;
	ret = set_data->ret;
out_put:
out_put: