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

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

s390/cmf: simplify set_schib_wait



No need for refcounting - the data can be on stack.

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 adc69b4d
Loading
Loading
Loading
Loading
+23 −47
Original line number Original line Diff line number Diff line
@@ -215,72 +215,52 @@ struct set_schib_struct {
	unsigned long address;
	unsigned long address;
	wait_queue_head_t wait;
	wait_queue_head_t wait;
	int ret;
	int ret;
	struct kref kref;
};
};


static void cmf_set_schib_release(struct kref *kref)
{
	struct set_schib_struct *set_data;

	set_data = container_of(kref, struct set_schib_struct, kref);
	kfree(set_data);
}

#define CMF_PENDING 1
#define CMF_PENDING 1
#define SET_SCHIB_TIMEOUT (10 * HZ)
#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)
{
{
	struct set_schib_struct *set_data;
	struct set_schib_struct set_data;
	int ret;
	int ret = -ENODEV;


	spin_lock_irq(cdev->ccwlock);
	spin_lock_irq(cdev->ccwlock);
	if (!cdev->private->cmb) {
	if (!cdev->private->cmb)
		ret = -ENODEV;
		goto out;
	}
	set_data = kzalloc(sizeof(struct set_schib_struct), GFP_ATOMIC);
	if (!set_data) {
		ret = -ENOMEM;
		goto out;
		goto out;
	}
	init_waitqueue_head(&set_data->wait);
	kref_init(&set_data->kref);
	set_data->mme = mme;
	set_data->mbfc = mbfc;
	set_data->address = address;


	ret = set_schib(cdev, mme, mbfc, address);
	ret = set_schib(cdev, mme, mbfc, address);
	if (ret != -EBUSY)
	if (ret != -EBUSY)
		goto out_put;
		goto out;


	if (cdev->private->state != DEV_STATE_ONLINE) {
	/* if the device is not online, don't even try again */
	/* if the device is not online, don't even try again */
		ret = -EBUSY;
	if (cdev->private->state != DEV_STATE_ONLINE)
		goto out_put;
		goto out;
	}

	init_waitqueue_head(&set_data.wait);
	set_data.mme = mme;
	set_data.mbfc = mbfc;
	set_data.address = address;
	set_data.ret = CMF_PENDING;


	cdev->private->state = DEV_STATE_CMFCHANGE;
	cdev->private->state = DEV_STATE_CMFCHANGE;
	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);


	ret = wait_event_interruptible_timeout(set_data->wait,
	ret = wait_event_interruptible_timeout(set_data.wait,
					       set_data->ret != CMF_PENDING,
					       set_data.ret != CMF_PENDING,
					       SET_SCHIB_TIMEOUT);
					       SET_SCHIB_TIMEOUT);
	spin_lock_irq(cdev->ccwlock);
	spin_lock_irq(cdev->ccwlock);
	if (ret <= 0) {
	if (ret <= 0) {
		if (set_data->ret == CMF_PENDING) {
		if (set_data.ret == CMF_PENDING) {
			set_data->ret = (ret == 0) ? -ETIME : ret;
			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;
		}
		}
	}
	}
	cdev->private->cmb_wait = NULL;
	cdev->private->cmb_wait = NULL;
	ret = set_data->ret;
	ret = set_data.ret;
out_put:
	kref_put(&set_data->kref, cmf_set_schib_release);
out:
out:
	spin_unlock_irq(cdev->ccwlock);
	spin_unlock_irq(cdev->ccwlock);
	return ret;
	return ret;
@@ -288,18 +268,14 @@ static int set_schib_wait(struct ccw_device *cdev, u32 mme,


void retry_set_schib(struct ccw_device *cdev)
void retry_set_schib(struct ccw_device *cdev)
{
{
	struct set_schib_struct *set_data;
	struct set_schib_struct *set_data = cdev->private->cmb_wait;


	set_data = cdev->private->cmb_wait;
	if (!set_data)
	if (!set_data) {
		WARN_ON(1);
		return;
		return;
	}

	kref_get(&set_data->kref);
	set_data->ret = set_schib(cdev, set_data->mme, set_data->mbfc,
	set_data->ret = set_schib(cdev, set_data->mme, set_data->mbfc,
				  set_data->address);
				  set_data->address);
	wake_up(&set_data->wait);
	wake_up(&set_data->wait);
	kref_put(&set_data->kref, cmf_set_schib_release);
}
}


static int cmf_copy_block(struct ccw_device *cdev)
static int cmf_copy_block(struct ccw_device *cdev)