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

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

s390/cio: move ccw_device_stlck functions



device_ops.c should only contain functions that are called by ccw device
drivers. Move the cio internal functions that handle unconditional
reserve + release to device_pgid.c

Acked-by: default avatarPeter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 8421d212
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -125,9 +125,6 @@ void ccw_device_verify_done(struct ccw_device *, int);
void ccw_device_disband_start(struct ccw_device *);
void ccw_device_disband_done(struct ccw_device *, int);

void ccw_device_stlck_start(struct ccw_device *, void *, void *, void *);
void ccw_device_stlck_done(struct ccw_device *, void *, int);

int ccw_device_stlck(struct ccw_device *);

/* Helper function for machine check handling. */
+0 −61
Original line number Diff line number Diff line
@@ -456,67 +456,6 @@ __u8 ccw_device_get_path_mask(struct ccw_device *cdev)
	return sch->lpm;
}

struct stlck_data {
	struct completion done;
	int rc;
};

void ccw_device_stlck_done(struct ccw_device *cdev, void *data, int rc)
{
	struct stlck_data *sdata = data;

	sdata->rc = rc;
	complete(&sdata->done);
}

/*
 * Perform unconditional reserve + release.
 */
int ccw_device_stlck(struct ccw_device *cdev)
{
	struct subchannel *sch = to_subchannel(cdev->dev.parent);
	struct stlck_data data;
	u8 *buffer;
	int rc;

	/* Check if steal lock operation is valid for this device. */
	if (cdev->drv) {
		if (!cdev->private->options.force)
			return -EINVAL;
	}
	buffer = kzalloc(64, GFP_DMA | GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;
	init_completion(&data.done);
	data.rc = -EIO;
	spin_lock_irq(sch->lock);
	rc = cio_enable_subchannel(sch, (u32) (addr_t) sch);
	if (rc)
		goto out_unlock;
	/* Perform operation. */
	cdev->private->state = DEV_STATE_STEAL_LOCK;
	ccw_device_stlck_start(cdev, &data, &buffer[0], &buffer[32]);
	spin_unlock_irq(sch->lock);
	/* Wait for operation to finish. */
	if (wait_for_completion_interruptible(&data.done)) {
		/* Got a signal. */
		spin_lock_irq(sch->lock);
		ccw_request_cancel(cdev);
		spin_unlock_irq(sch->lock);
		wait_for_completion(&data.done);
	}
	rc = data.rc;
	/* Check results. */
	spin_lock_irq(sch->lock);
	cio_disable_subchannel(sch);
	cdev->private->state = DEV_STATE_BOXED;
out_unlock:
	spin_unlock_irq(sch->lock);
	kfree(buffer);

	return rc;
}

/**
 * chp_get_chp_desc - return newly allocated channel-path descriptor
 * @cdev: device to obtain the descriptor for
+60 −6
Original line number Diff line number Diff line
@@ -9,9 +9,10 @@

#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/bitops.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/bitops.h>
#include <linux/slab.h>
#include <asm/ccwdev.h>
#include <asm/cio.h>

@@ -616,6 +617,11 @@ void ccw_device_disband_start(struct ccw_device *cdev)
	ccw_request_start(cdev);
}

struct stlck_data {
	struct completion done;
	int rc;
};

static void stlck_build_cp(struct ccw_device *cdev, void *buf1, void *buf2)
{
	struct ccw_request *req = &cdev->private->req;
@@ -634,7 +640,10 @@ static void stlck_build_cp(struct ccw_device *cdev, void *buf1, void *buf2)

static void stlck_callback(struct ccw_device *cdev, void *data, int rc)
{
	ccw_device_stlck_done(cdev, data, rc);
	struct stlck_data *sdata = data;

	sdata->rc = rc;
	complete(&sdata->done);
}

/**
@@ -645,11 +654,9 @@ static void stlck_callback(struct ccw_device *cdev, void *data, int rc)
 * @buf2: data pointer used in channel program
 *
 * Execute a channel program on @cdev to release an existing PGID reservation.
 * When finished, call ccw_device_stlck_done with a return code specifying the
 * result.
 */
void ccw_device_stlck_start(struct ccw_device *cdev, void *data, void *buf1,
			    void *buf2)
static void ccw_device_stlck_start(struct ccw_device *cdev, void *data,
				   void *buf1, void *buf2)
{
	struct subchannel *sch = to_subchannel(cdev->dev.parent);
	struct ccw_request *req = &cdev->private->req;
@@ -667,3 +674,50 @@ void ccw_device_stlck_start(struct ccw_device *cdev, void *data, void *buf1,
	ccw_request_start(cdev);
}

/*
 * Perform unconditional reserve + release.
 */
int ccw_device_stlck(struct ccw_device *cdev)
{
	struct subchannel *sch = to_subchannel(cdev->dev.parent);
	struct stlck_data data;
	u8 *buffer;
	int rc;

	/* Check if steal lock operation is valid for this device. */
	if (cdev->drv) {
		if (!cdev->private->options.force)
			return -EINVAL;
	}
	buffer = kzalloc(64, GFP_DMA | GFP_KERNEL);
	if (!buffer)
		return -ENOMEM;
	init_completion(&data.done);
	data.rc = -EIO;
	spin_lock_irq(sch->lock);
	rc = cio_enable_subchannel(sch, (u32) (addr_t) sch);
	if (rc)
		goto out_unlock;
	/* Perform operation. */
	cdev->private->state = DEV_STATE_STEAL_LOCK;
	ccw_device_stlck_start(cdev, &data, &buffer[0], &buffer[32]);
	spin_unlock_irq(sch->lock);
	/* Wait for operation to finish. */
	if (wait_for_completion_interruptible(&data.done)) {
		/* Got a signal. */
		spin_lock_irq(sch->lock);
		ccw_request_cancel(cdev);
		spin_unlock_irq(sch->lock);
		wait_for_completion(&data.done);
	}
	rc = data.rc;
	/* Check results. */
	spin_lock_irq(sch->lock);
	cio_disable_subchannel(sch);
	cdev->private->state = DEV_STATE_BOXED;
out_unlock:
	spin_unlock_irq(sch->lock);
	kfree(buffer);

	return rc;
}