aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2006-12-08 15:53:57 +0100
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-12-08 15:53:57 +0100
commitc16375329c2ab4667df873394c4be7a61d163c62 (patch)
tree9ee9505e4587ce5f472db3fd09935611b0062f83 /drivers/s390/cio
parente45ccc0562e3f391dcba8b2e8a02551e8e42d8db (diff)
downloadkernel_samsung_smdk4412-c16375329c2ab4667df873394c4be7a61d163c62.zip
kernel_samsung_smdk4412-c16375329c2ab4667df873394c4be7a61d163c62.tar.gz
kernel_samsung_smdk4412-c16375329c2ab4667df873394c4be7a61d163c62.tar.bz2
[S390] more workqueue fixes.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio')
-rw-r--r--drivers/s390/cio/css.h2
-rw-r--r--drivers/s390/cio/device.c43
-rw-r--r--drivers/s390/cio/device.h4
-rw-r--r--drivers/s390/cio/device_fsm.c38
-rw-r--r--drivers/s390/cio/qdio.c8
5 files changed, 56 insertions, 39 deletions
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 9ff064e..dfd5462 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -73,6 +73,8 @@ struct senseid {
} __attribute__ ((packed,aligned(4)));
struct ccw_device_private {
+ struct ccw_device *cdev;
+ struct subchannel *sch;
int state; /* device state */
atomic_t onoff;
unsigned long registered;
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index d3d3716..0f60462 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -585,12 +585,13 @@ static struct ccw_device * get_disc_ccwdev_by_dev_id(struct ccw_dev_id *dev_id,
}
static void
-ccw_device_add_changed(void *data)
+ccw_device_add_changed(struct work_struct *work)
{
-
+ struct ccw_device_private *priv;
struct ccw_device *cdev;
- cdev = data;
+ priv = container_of(work, struct ccw_device_private, kick_work);
+ cdev = priv->cdev;
if (device_add(&cdev->dev)) {
put_device(&cdev->dev);
return;
@@ -605,13 +606,15 @@ ccw_device_add_changed(void *data)
extern int css_get_ssd_info(struct subchannel *sch);
void
-ccw_device_do_unreg_rereg(void *data)
+ccw_device_do_unreg_rereg(struct work_struct *work)
{
+ struct ccw_device_private *priv;
struct ccw_device *cdev;
struct subchannel *sch;
int need_rename;
- cdev = data;
+ priv = container_of(work, struct ccw_device_private, kick_work);
+ cdev = priv->cdev;
sch = to_subchannel(cdev->dev.parent);
if (cdev->private->dev_id.devno != sch->schib.pmcw.dev) {
/*
@@ -659,7 +662,7 @@ ccw_device_do_unreg_rereg(void *data)
snprintf (cdev->dev.bus_id, BUS_ID_SIZE, "0.%x.%04x",
sch->schid.ssid, sch->schib.pmcw.dev);
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_add_changed, cdev);
+ ccw_device_add_changed);
queue_work(ccw_device_work, &cdev->private->kick_work);
}
@@ -677,14 +680,16 @@ ccw_device_release(struct device *dev)
* Register recognized device.
*/
static void
-io_subchannel_register(void *data)
+io_subchannel_register(struct work_struct *work)
{
+ struct ccw_device_private *priv;
struct ccw_device *cdev;
struct subchannel *sch;
int ret;
unsigned long flags;
- cdev = data;
+ priv = container_of(work, struct ccw_device_private, kick_work);
+ cdev = priv->cdev;
sch = to_subchannel(cdev->dev.parent);
/*
@@ -734,11 +739,14 @@ out:
}
void
-ccw_device_call_sch_unregister(void *data)
+ccw_device_call_sch_unregister(struct work_struct *work)
{
- struct ccw_device *cdev = data;
+ struct ccw_device_private *priv;
+ struct ccw_device *cdev;
struct subchannel *sch;
+ priv = container_of(work, struct ccw_device_private, kick_work);
+ cdev = priv->cdev;
sch = to_subchannel(cdev->dev.parent);
css_sch_device_unregister(sch);
/* Reset intparm to zeroes. */
@@ -768,7 +776,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
break;
sch = to_subchannel(cdev->dev.parent);
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_call_sch_unregister, cdev);
+ ccw_device_call_sch_unregister);
queue_work(slow_path_wq, &cdev->private->kick_work);
if (atomic_dec_and_test(&ccw_device_init_count))
wake_up(&ccw_device_init_wq);
@@ -783,7 +791,7 @@ io_subchannel_recog_done(struct ccw_device *cdev)
if (!get_device(&cdev->dev))
break;
PREPARE_WORK(&cdev->private->kick_work,
- io_subchannel_register, cdev);
+ io_subchannel_register);
queue_work(slow_path_wq, &cdev->private->kick_work);
break;
}
@@ -865,6 +873,7 @@ io_subchannel_probe (struct subchannel *sch)
kfree(cdev);
return -ENOMEM;
}
+ cdev->private->cdev = cdev;
atomic_set(&cdev->private->onoff, 0);
cdev->dev.parent = &sch->dev;
cdev->dev.release = ccw_device_release;
@@ -890,12 +899,13 @@ io_subchannel_probe (struct subchannel *sch)
return rc;
}
-static void
-ccw_device_unregister(void *data)
+static void ccw_device_unregister(struct work_struct *work)
{
+ struct ccw_device_private *priv;
struct ccw_device *cdev;
- cdev = (struct ccw_device *)data;
+ priv = container_of(work, struct ccw_device_private, kick_work);
+ cdev = priv->cdev;
if (test_and_clear_bit(1, &cdev->private->registered))
device_unregister(&cdev->dev);
put_device(&cdev->dev);
@@ -921,7 +931,7 @@ io_subchannel_remove (struct subchannel *sch)
*/
if (get_device(&cdev->dev)) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_unregister, cdev);
+ ccw_device_unregister);
queue_work(ccw_device_work, &cdev->private->kick_work);
}
return 0;
@@ -1048,6 +1058,7 @@ ccw_device_probe_console(void)
memset(&console_cdev, 0, sizeof(struct ccw_device));
memset(&console_private, 0, sizeof(struct ccw_device_private));
console_cdev.private = &console_private;
+ console_private.cdev = &console_cdev;
ret = ccw_device_console_enable(&console_cdev, sch);
if (ret) {
cio_release_console();
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 9233b5c..d5fe95e 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -78,8 +78,8 @@ void io_subchannel_recog_done(struct ccw_device *cdev);
int ccw_device_cancel_halt_clear(struct ccw_device *);
-void ccw_device_do_unreg_rereg(void *);
-void ccw_device_call_sch_unregister(void *);
+void ccw_device_do_unreg_rereg(struct work_struct *);
+void ccw_device_call_sch_unregister(struct work_struct *);
int ccw_device_recognition(struct ccw_device *);
int ccw_device_online(struct ccw_device *);
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 09c7672..0f0301c 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -194,7 +194,7 @@ ccw_device_handle_oper(struct ccw_device *cdev)
cdev->id.dev_model != cdev->private->senseid.dev_model ||
cdev->private->dev_id.devno != sch->schib.pmcw.dev) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_do_unreg_rereg, cdev);
+ ccw_device_do_unreg_rereg);
queue_work(ccw_device_work, &cdev->private->kick_work);
return 0;
}
@@ -329,19 +329,21 @@ ccw_device_sense_id_done(struct ccw_device *cdev, int err)
}
static void
-ccw_device_oper_notify(void *data)
+ccw_device_oper_notify(struct work_struct *work)
{
+ struct ccw_device_private *priv;
struct ccw_device *cdev;
struct subchannel *sch;
int ret;
- cdev = data;
+ priv = container_of(work, struct ccw_device_private, kick_work);
+ cdev = priv->cdev;
sch = to_subchannel(cdev->dev.parent);
ret = (sch->driver && sch->driver->notify) ?
sch->driver->notify(&sch->dev, CIO_OPER) : 0;
if (!ret)
/* Driver doesn't want device back. */
- ccw_device_do_unreg_rereg(cdev);
+ ccw_device_do_unreg_rereg(work);
else {
/* Reenable channel measurements, if needed. */
cmf_reenable(cdev);
@@ -377,8 +379,7 @@ ccw_device_done(struct ccw_device *cdev, int state)
if (cdev->private->flags.donotify) {
cdev->private->flags.donotify = 0;
- PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify,
- cdev);
+ PREPARE_WORK(&cdev->private->kick_work, ccw_device_oper_notify);
queue_work(ccw_device_notify_work, &cdev->private->kick_work);
}
wake_up(&cdev->private->wait_q);
@@ -528,13 +529,15 @@ ccw_device_recog_timeout(struct ccw_device *cdev, enum dev_event dev_event)
static void
-ccw_device_nopath_notify(void *data)
+ccw_device_nopath_notify(struct work_struct *work)
{
+ struct ccw_device_private *priv;
struct ccw_device *cdev;
struct subchannel *sch;
int ret;
- cdev = data;
+ priv = container_of(work, struct ccw_device_private, kick_work);
+ cdev = priv->cdev;
sch = to_subchannel(cdev->dev.parent);
/* Extra sanity. */
if (sch->lpm)
@@ -547,8 +550,7 @@ ccw_device_nopath_notify(void *data)
cio_disable_subchannel(sch);
if (get_device(&cdev->dev)) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_call_sch_unregister,
- cdev);
+ ccw_device_call_sch_unregister);
queue_work(ccw_device_work,
&cdev->private->kick_work);
} else
@@ -607,7 +609,7 @@ ccw_device_verify_done(struct ccw_device *cdev, int err)
/* Reset oper notify indication after verify error. */
cdev->private->flags.donotify = 0;
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_nopath_notify, cdev);
+ ccw_device_nopath_notify);
queue_work(ccw_device_notify_work, &cdev->private->kick_work);
ccw_device_done(cdev, DEV_STATE_NOT_OPER);
break;
@@ -738,7 +740,7 @@ ccw_device_offline_notoper(struct ccw_device *cdev, enum dev_event dev_event)
sch = to_subchannel(cdev->dev.parent);
if (get_device(&cdev->dev)) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_call_sch_unregister, cdev);
+ ccw_device_call_sch_unregister);
queue_work(ccw_device_work, &cdev->private->kick_work);
}
wake_up(&cdev->private->wait_q);
@@ -769,7 +771,7 @@ ccw_device_online_notoper(struct ccw_device *cdev, enum dev_event dev_event)
}
if (get_device(&cdev->dev)) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_call_sch_unregister, cdev);
+ ccw_device_call_sch_unregister);
queue_work(ccw_device_work, &cdev->private->kick_work);
}
wake_up(&cdev->private->wait_q);
@@ -874,7 +876,7 @@ ccw_device_online_timeout(struct ccw_device *cdev, enum dev_event dev_event)
sch = to_subchannel(cdev->dev.parent);
if (!sch->lpm) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_nopath_notify, cdev);
+ ccw_device_nopath_notify);
queue_work(ccw_device_notify_work,
&cdev->private->kick_work);
} else
@@ -969,7 +971,7 @@ ccw_device_killing_irq(struct ccw_device *cdev, enum dev_event dev_event)
ERR_PTR(-EIO));
if (!sch->lpm) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_nopath_notify, cdev);
+ ccw_device_nopath_notify);
queue_work(ccw_device_notify_work, &cdev->private->kick_work);
} else if (cdev->private->flags.doverify)
/* Start delayed path verification. */
@@ -992,7 +994,7 @@ ccw_device_killing_timeout(struct ccw_device *cdev, enum dev_event dev_event)
sch = to_subchannel(cdev->dev.parent);
if (!sch->lpm) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_nopath_notify, cdev);
+ ccw_device_nopath_notify);
queue_work(ccw_device_notify_work,
&cdev->private->kick_work);
} else
@@ -1021,7 +1023,7 @@ void device_kill_io(struct subchannel *sch)
if (ret == -ENODEV) {
if (!sch->lpm) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_nopath_notify, cdev);
+ ccw_device_nopath_notify);
queue_work(ccw_device_notify_work,
&cdev->private->kick_work);
} else
@@ -1033,7 +1035,7 @@ void device_kill_io(struct subchannel *sch)
ERR_PTR(-EIO));
if (!sch->lpm) {
PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_nopath_notify, cdev);
+ ccw_device_nopath_notify);
queue_work(ccw_device_notify_work, &cdev->private->kick_work);
} else
/* Start delayed path verification. */
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 8d5fa1b..d066dbf 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -2045,11 +2045,13 @@ omit_handler_call:
}
static void
-qdio_call_shutdown(void *data)
+qdio_call_shutdown(struct work_struct *work)
{
+ struct ccw_device_private *priv;
struct ccw_device *cdev;
- cdev = (struct ccw_device *)data;
+ priv = container_of(work, struct ccw_device_private, kick_work);
+ cdev = priv->cdev;
qdio_shutdown(cdev, QDIO_FLAG_CLEANUP_USING_CLEAR);
put_device(&cdev->dev);
}
@@ -2091,7 +2093,7 @@ qdio_timeout_handler(struct ccw_device *cdev)
if (get_device(&cdev->dev)) {
/* Can't call shutdown from interrupt context. */
PREPARE_WORK(&cdev->private->kick_work,
- qdio_call_shutdown, (void *)cdev);
+ qdio_call_shutdown);
queue_work(ccw_device_work, &cdev->private->kick_work);
}
break;