summaryrefslogtreecommitdiffstats
path: root/drivers/s390/cio/device_fsm.c
diff options
context:
space:
mode:
authorCornelia Huck2006-06-29 15:08:41 +0200
committerMartin Schwidefsky2006-06-29 15:08:41 +0200
commit94bb063312d872d9269deb2e5c0c7c6d5b0318e1 (patch)
treebef899fbe742ee31d93ff0e077898d4562086f9e /drivers/s390/cio/device_fsm.c
parent[S390] appldata enhancements. (diff)
downloadkernel-qcow2-linux-94bb063312d872d9269deb2e5c0c7c6d5b0318e1.tar.gz
kernel-qcow2-linux-94bb063312d872d9269deb2e5c0c7c6d5b0318e1.tar.xz
kernel-qcow2-linux-94bb063312d872d9269deb2e5c0c7c6d5b0318e1.zip
[S390] rework of channel measurement facility.
Fixes for several channel measurement facility bugs: * Blocks copied from the hardware might not be consistent. Solve this by moving the copying into idle state and repeating the copying. * avg_sample_interval changed with every read, even though no new block was available. Solve this by storing a timestamp when the last new block was received. * Several locking issues. * Measurements were not reenabled after a disconnected device became available again. * Remove #defines for ioctls that were never implemented. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/device_fsm.c')
-rw-r--r--drivers/s390/cio/device_fsm.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 5ec8ef1df9fa..7d0dd72635eb 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -336,8 +336,11 @@ ccw_device_oper_notify(void *data)
if (!ret)
/* Driver doesn't want device back. */
ccw_device_do_unreg_rereg((void *)cdev);
- else
+ else {
+ /* Reenable channel measurements, if needed. */
+ cmf_reenable(cdev);
wake_up(&cdev->private->wait_q);
+ }
}
/*
@@ -1095,6 +1098,13 @@ ccw_device_change_cmfstate(struct ccw_device *cdev, enum dev_event dev_event)
dev_fsm_event(cdev, dev_event);
}
+static void ccw_device_update_cmfblock(struct ccw_device *cdev,
+ enum dev_event dev_event)
+{
+ cmf_retry_copy_block(cdev);
+ cdev->private->state = DEV_STATE_ONLINE;
+ dev_fsm_event(cdev, dev_event);
+}
static void
ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event)
@@ -1249,6 +1259,12 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = {
[DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate,
[DEV_EVENT_VERIFY] = ccw_device_change_cmfstate,
},
+ [DEV_STATE_CMFUPDATE] = {
+ [DEV_EVENT_NOTOPER] = ccw_device_update_cmfblock,
+ [DEV_EVENT_INTERRUPT] = ccw_device_update_cmfblock,
+ [DEV_EVENT_TIMEOUT] = ccw_device_update_cmfblock,
+ [DEV_EVENT_VERIFY] = ccw_device_update_cmfblock,
+ },
};
/*