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

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
...@@ -215,72 +215,52 @@ struct set_schib_struct { ...@@ -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 */ if (cdev->private->state != DEV_STATE_ONLINE)
ret = -EBUSY; goto out;
goto out_put;
} 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, ...@@ -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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment