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: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
这个提交包含在:
Sebastian Ott
2015-10-26 12:38:13 +01:00
提交者 Martin Schwidefsky
父节点 8421d212e8
当前提交 ef12cb904e
修改 3 个文件,包含 60 行新增70 行删除

查看文件

@@ -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;
}