Skip to content

Commit 0f987e6

Browse files
oberparAlexander Gordeev
authored andcommitted
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>
1 parent 5e6bb10 commit 0f987e6

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

drivers/s390/cio/chp.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,35 @@ static ssize_t chp_esc_show(struct device *dev,
392392
}
393393
static DEVICE_ATTR(esc, 0444, chp_esc_show, NULL);
394394

395+
static char apply_max_suffix(unsigned long *value, unsigned long base)
396+
{
397+
static char suffixes[] = { 0, 'K', 'M', 'G', 'T' };
398+
int i;
399+
400+
for (i = 0; i < ARRAY_SIZE(suffixes) - 1; i++) {
401+
if (*value < base || *value % base != 0)
402+
break;
403+
*value /= base;
404+
}
405+
406+
return suffixes[i];
407+
}
408+
409+
static ssize_t speed_bps_show(struct device *dev,
410+
struct device_attribute *attr, char *buf)
411+
{
412+
struct channel_path *chp = to_channelpath(dev);
413+
unsigned long speed = chp->speed;
414+
char suffix;
415+
416+
suffix = apply_max_suffix(&speed, 1000);
417+
418+
return suffix ? sysfs_emit(buf, "%lu%c\n", speed, suffix) :
419+
sysfs_emit(buf, "%lu\n", speed);
420+
}
421+
422+
static DEVICE_ATTR_RO(speed_bps);
423+
395424
static ssize_t util_string_read(struct file *filp, struct kobject *kobj,
396425
struct bin_attribute *attr, char *buf,
397426
loff_t off, size_t count)
@@ -423,6 +452,7 @@ static struct attribute *chp_attrs[] = {
423452
&dev_attr_chid.attr,
424453
&dev_attr_chid_external.attr,
425454
&dev_attr_esc.attr,
455+
&dev_attr_speed_bps.attr,
426456
NULL,
427457
};
428458
static struct attribute_group chp_attr_group = {

drivers/s390/cio/chp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct channel_path {
5252
int cmg;
5353
int shared;
5454
int extended;
55+
unsigned long speed;
5556
struct cmg_chars cmg_chars;
5657
};
5758

drivers/s390/cio/chsc.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,6 +1066,18 @@ chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
10661066
}
10671067
}
10681068

1069+
static unsigned long scmc_get_speed(u32 s, u32 p)
1070+
{
1071+
unsigned long speed = s;
1072+
1073+
if (!p)
1074+
p = 8;
1075+
while (p--)
1076+
speed *= 10;
1077+
1078+
return speed;
1079+
}
1080+
10691081
int chsc_get_channel_measurement_chars(struct channel_path *chp)
10701082
{
10711083
unsigned long flags;
@@ -1086,16 +1098,19 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
10861098
u32 : 21;
10871099
u32 chpid : 8;
10881100
u32 cmcv : 5;
1089-
u32 : 11;
1101+
u32 : 7;
1102+
u32 cmgp : 4;
10901103
u32 cmgq : 8;
10911104
u32 cmg : 8;
1092-
u32 zeroes3;
1105+
u32 : 16;
1106+
u32 cmgs : 16;
10931107
u32 data[NR_MEASUREMENT_CHARS];
10941108
} *scmc_area;
10951109

10961110
chp->shared = -1;
10971111
chp->cmg = -1;
10981112
chp->extended = 0;
1113+
chp->speed = 0;
10991114

11001115
if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm)
11011116
return -EINVAL;
@@ -1126,6 +1141,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
11261141
chp->cmg = scmc_area->cmg;
11271142
chp->shared = scmc_area->shared;
11281143
chp->extended = scmc_area->extended;
1144+
chp->speed = scmc_get_speed(scmc_area->cmgs, scmc_area->cmgp);
11291145
chsc_initialize_cmg_chars(chp, scmc_area->cmcv,
11301146
(struct cmg_chars *) &scmc_area->data);
11311147
out:

0 commit comments

Comments
 (0)