diff options
author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2017-09-07 13:18:40 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2017-09-28 07:29:42 +0200 |
commit | d4d287e81ff1924f0791fad0638551daec7742b5 (patch) | |
tree | 65826a2781927fd697f1fd09df723fd70ec44b63 /drivers/s390/cio/cmf.c | |
parent | 81b050b564b814585e1515b218783c8ad56913f1 (diff) | |
download | linux-d4d287e81ff1924f0791fad0638551daec7742b5.tar.bz2 |
s390/cmf: read from hw buffer
To ensure data consistency when reading from the channel measurement
block we wait for the subchannel to become idle and copy the whole
block. This is unnecessary when all we do is export the individual
values via sysfs. Read the values for sysfs export directly from
the measurement block.
Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/cio/cmf.c')
-rw-r--r-- | drivers/s390/cio/cmf.c | 45 |
1 files changed, 14 insertions, 31 deletions
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 531861d005fd..78fb492d9881 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -589,22 +589,18 @@ static int set_cmb(struct ccw_device *cdev, u32 mme) static u64 read_cmb(struct ccw_device *cdev, int index) { + struct cmb_data *cmb_data; + unsigned long flags; struct cmb *cmb; + int ret = 0; u32 val; - int ret; - unsigned long flags; - - ret = cmf_cmb_copy_wait(cdev); - if (ret < 0) - return 0; spin_lock_irqsave(cdev->ccwlock, flags); - if (!cdev->private->cmb) { - ret = 0; + cmb_data = cdev->private->cmb; + if (!cmb_data) goto out; - } - cmb = ((struct cmb_data *)cdev->private->cmb)->last_block; + cmb = cmb_data->hw_block; switch (index) { case cmb_ssch_rsch_count: ret = cmb->ssch_rsch_count; @@ -628,7 +624,6 @@ static u64 read_cmb(struct ccw_device *cdev, int index) val = cmb->device_active_only_time; break; default: - ret = 0; goto out; } ret = time_to_avg_nsec(val, cmb->sample_count); @@ -841,27 +836,20 @@ static int set_cmbe(struct ccw_device *cdev, u32 mme) return set_schib_wait(cdev, mme, 1, mba); } - static u64 read_cmbe(struct ccw_device *cdev, int index) { - struct cmbe *cmb; struct cmb_data *cmb_data; - u32 val; - int ret; unsigned long flags; - - ret = cmf_cmb_copy_wait(cdev); - if (ret < 0) - return 0; + struct cmbe *cmb; + int ret = 0; + u32 val; spin_lock_irqsave(cdev->ccwlock, flags); cmb_data = cdev->private->cmb; - if (!cmb_data) { - ret = 0; + if (!cmb_data) goto out; - } - cmb = cmb_data->last_block; + cmb = cmb_data->hw_block; switch (index) { case cmb_ssch_rsch_count: ret = cmb->ssch_rsch_count; @@ -891,7 +879,6 @@ static u64 read_cmbe(struct ccw_device *cdev, int index) val = cmb->initial_command_response_time; break; default: - ret = 0; goto out; } ret = time_to_avg_nsec(val, cmb->sample_count); @@ -982,18 +969,14 @@ static ssize_t cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, char *buf) { - struct ccw_device *cdev; - long interval; + struct ccw_device *cdev = to_ccwdev(dev); unsigned long count; - struct cmb_data *cmb_data; + long interval; - cdev = to_ccwdev(dev); count = cmf_read(cdev, cmb_sample_count); spin_lock_irq(cdev->ccwlock); - cmb_data = cdev->private->cmb; if (count) { - interval = cmb_data->last_update - - cdev->private->cmb_start_time; + interval = get_tod_clock() - cdev->private->cmb_start_time; interval = (interval * 1000) >> 12; interval /= count; } else |