mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
s390/cio: export CHPID operating speed
Add a per-CHPID sysfs attribute named "speed_bps" that provides the operating speed of the associated channel path in bits per second, or 0 if the operating speed is not available. Example: $ cat /sys/devices/css0/chp0.32/speed_bps 32G Reviewed-by: Vineeth Vijayan <vneethv@linux.ibm.com> Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
This commit is contained in:
parent
5e6bb10ee5
commit
0f987e6caa
@ -392,6 +392,35 @@ static ssize_t chp_esc_show(struct device *dev,
|
||||
}
|
||||
static DEVICE_ATTR(esc, 0444, chp_esc_show, NULL);
|
||||
|
||||
static char apply_max_suffix(unsigned long *value, unsigned long base)
|
||||
{
|
||||
static char suffixes[] = { 0, 'K', 'M', 'G', 'T' };
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(suffixes) - 1; i++) {
|
||||
if (*value < base || *value % base != 0)
|
||||
break;
|
||||
*value /= base;
|
||||
}
|
||||
|
||||
return suffixes[i];
|
||||
}
|
||||
|
||||
static ssize_t speed_bps_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct channel_path *chp = to_channelpath(dev);
|
||||
unsigned long speed = chp->speed;
|
||||
char suffix;
|
||||
|
||||
suffix = apply_max_suffix(&speed, 1000);
|
||||
|
||||
return suffix ? sysfs_emit(buf, "%lu%c\n", speed, suffix) :
|
||||
sysfs_emit(buf, "%lu\n", speed);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(speed_bps);
|
||||
|
||||
static ssize_t util_string_read(struct file *filp, struct kobject *kobj,
|
||||
struct bin_attribute *attr, char *buf,
|
||||
loff_t off, size_t count)
|
||||
@ -423,6 +452,7 @@ static struct attribute *chp_attrs[] = {
|
||||
&dev_attr_chid.attr,
|
||||
&dev_attr_chid_external.attr,
|
||||
&dev_attr_esc.attr,
|
||||
&dev_attr_speed_bps.attr,
|
||||
NULL,
|
||||
};
|
||||
static struct attribute_group chp_attr_group = {
|
||||
|
@ -52,6 +52,7 @@ struct channel_path {
|
||||
int cmg;
|
||||
int shared;
|
||||
int extended;
|
||||
unsigned long speed;
|
||||
struct cmg_chars cmg_chars;
|
||||
};
|
||||
|
||||
|
@ -1066,6 +1066,18 @@ chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned long scmc_get_speed(u32 s, u32 p)
|
||||
{
|
||||
unsigned long speed = s;
|
||||
|
||||
if (!p)
|
||||
p = 8;
|
||||
while (p--)
|
||||
speed *= 10;
|
||||
|
||||
return speed;
|
||||
}
|
||||
|
||||
int chsc_get_channel_measurement_chars(struct channel_path *chp)
|
||||
{
|
||||
unsigned long flags;
|
||||
@ -1086,16 +1098,19 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
|
||||
u32 : 21;
|
||||
u32 chpid : 8;
|
||||
u32 cmcv : 5;
|
||||
u32 : 11;
|
||||
u32 : 7;
|
||||
u32 cmgp : 4;
|
||||
u32 cmgq : 8;
|
||||
u32 cmg : 8;
|
||||
u32 zeroes3;
|
||||
u32 : 16;
|
||||
u32 cmgs : 16;
|
||||
u32 data[NR_MEASUREMENT_CHARS];
|
||||
} *scmc_area;
|
||||
|
||||
chp->shared = -1;
|
||||
chp->cmg = -1;
|
||||
chp->extended = 0;
|
||||
chp->speed = 0;
|
||||
|
||||
if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm)
|
||||
return -EINVAL;
|
||||
@ -1126,6 +1141,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
|
||||
chp->cmg = scmc_area->cmg;
|
||||
chp->shared = scmc_area->shared;
|
||||
chp->extended = scmc_area->extended;
|
||||
chp->speed = scmc_get_speed(scmc_area->cmgs, scmc_area->cmgp);
|
||||
chsc_initialize_cmg_chars(chp, scmc_area->cmcv,
|
||||
(struct cmg_chars *) &scmc_area->data);
|
||||
out:
|
||||
|
Loading…
Reference in New Issue
Block a user