linux/drivers/s390/net/ctcm_sysfs.c
<<
>>
Prefs
   1/*
   2 * drivers/s390/net/ctcm_sysfs.c
   3 *
   4 * Copyright IBM Corp. 2007, 2007
   5 * Authors:     Peter Tiedemann (ptiedem@de.ibm.com)
   6 *
   7 */
   8
   9#undef DEBUG
  10#undef DEBUGDATA
  11#undef DEBUGCCW
  12
  13#define KMSG_COMPONENT "ctcm"
  14#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  15
  16#include <linux/sysfs.h>
  17#include "ctcm_main.h"
  18
  19/*
  20 * sysfs attributes
  21 */
  22
  23static ssize_t ctcm_buffer_show(struct device *dev,
  24                                struct device_attribute *attr, char *buf)
  25{
  26        struct ctcm_priv *priv = dev_get_drvdata(dev);
  27
  28        if (!priv)
  29                return -ENODEV;
  30        return sprintf(buf, "%d\n", priv->buffer_size);
  31}
  32
  33static ssize_t ctcm_buffer_write(struct device *dev,
  34                struct device_attribute *attr, const char *buf, size_t count)
  35{
  36        struct net_device *ndev;
  37        int bs1;
  38        struct ctcm_priv *priv = dev_get_drvdata(dev);
  39
  40        if (!(priv && priv->channel[READ] &&
  41                        (ndev = priv->channel[READ]->netdev))) {
  42                CTCM_DBF_TEXT(SETUP, CTC_DBF_ERROR, "bfnondev");
  43                return -ENODEV;
  44        }
  45
  46        sscanf(buf, "%u", &bs1);
  47        if (bs1 > CTCM_BUFSIZE_LIMIT)
  48                                        goto einval;
  49        if (bs1 < (576 + LL_HEADER_LENGTH + 2))
  50                                        goto einval;
  51        priv->buffer_size = bs1;        /* just to overwrite the default */
  52
  53        if ((ndev->flags & IFF_RUNNING) &&
  54            (bs1 < (ndev->mtu + LL_HEADER_LENGTH + 2)))
  55                                        goto einval;
  56
  57        priv->channel[READ]->max_bufsize = bs1;
  58        priv->channel[WRITE]->max_bufsize = bs1;
  59        if (!(ndev->flags & IFF_RUNNING))
  60                ndev->mtu = bs1 - LL_HEADER_LENGTH - 2;
  61        priv->channel[READ]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
  62        priv->channel[WRITE]->flags |= CHANNEL_FLAGS_BUFSIZE_CHANGED;
  63
  64        CTCM_DBF_DEV(SETUP, ndev, buf);
  65        return count;
  66
  67einval:
  68        CTCM_DBF_DEV(SETUP, ndev, "buff_err");
  69        return -EINVAL;
  70}
  71
  72static void ctcm_print_statistics(struct ctcm_priv *priv)
  73{
  74        char *sbuf;
  75        char *p;
  76
  77        if (!priv)
  78                return;
  79        sbuf = kmalloc(2048, GFP_KERNEL);
  80        if (sbuf == NULL)
  81                return;
  82        p = sbuf;
  83
  84        p += sprintf(p, "  Device FSM state: %s\n",
  85                     fsm_getstate_str(priv->fsm));
  86        p += sprintf(p, "  RX channel FSM state: %s\n",
  87                     fsm_getstate_str(priv->channel[READ]->fsm));
  88        p += sprintf(p, "  TX channel FSM state: %s\n",
  89                     fsm_getstate_str(priv->channel[WRITE]->fsm));
  90        p += sprintf(p, "  Max. TX buffer used: %ld\n",
  91                     priv->channel[WRITE]->prof.maxmulti);
  92        p += sprintf(p, "  Max. chained SKBs: %ld\n",
  93                     priv->channel[WRITE]->prof.maxcqueue);
  94        p += sprintf(p, "  TX single write ops: %ld\n",
  95                     priv->channel[WRITE]->prof.doios_single);
  96        p += sprintf(p, "  TX multi write ops: %ld\n",
  97                     priv->channel[WRITE]->prof.doios_multi);
  98        p += sprintf(p, "  Netto bytes written: %ld\n",
  99                     priv->channel[WRITE]->prof.txlen);
 100        p += sprintf(p, "  Max. TX IO-time: %ld\n",
 101                     priv->channel[WRITE]->prof.tx_time);
 102
 103        printk(KERN_INFO "Statistics for %s:\n%s",
 104                                priv->channel[WRITE]->netdev->name, sbuf);
 105        kfree(sbuf);
 106        return;
 107}
 108
 109static ssize_t stats_show(struct device *dev,
 110                                struct device_attribute *attr, char *buf)
 111{
 112        struct ctcm_priv *priv = dev_get_drvdata(dev);
 113        if (!priv)
 114                return -ENODEV;
 115        ctcm_print_statistics(priv);
 116        return sprintf(buf, "0\n");
 117}
 118
 119static ssize_t stats_write(struct device *dev, struct device_attribute *attr,
 120                                const char *buf, size_t count)
 121{
 122        struct ctcm_priv *priv = dev_get_drvdata(dev);
 123        if (!priv)
 124                return -ENODEV;
 125        /* Reset statistics */
 126        memset(&priv->channel[WRITE]->prof, 0,
 127                                sizeof(priv->channel[WRITE]->prof));
 128        return count;
 129}
 130
 131static ssize_t ctcm_proto_show(struct device *dev,
 132                                struct device_attribute *attr, char *buf)
 133{
 134        struct ctcm_priv *priv = dev_get_drvdata(dev);
 135        if (!priv)
 136                return -ENODEV;
 137
 138        return sprintf(buf, "%d\n", priv->protocol);
 139}
 140
 141static ssize_t ctcm_proto_store(struct device *dev,
 142                struct device_attribute *attr, const char *buf, size_t count)
 143{
 144        int value;
 145        struct ctcm_priv *priv = dev_get_drvdata(dev);
 146
 147        if (!priv)
 148                return -ENODEV;
 149        sscanf(buf, "%u", &value);
 150        if (!((value == CTCM_PROTO_S390)  ||
 151              (value == CTCM_PROTO_LINUX) ||
 152              (value == CTCM_PROTO_MPC) ||
 153              (value == CTCM_PROTO_OS390)))
 154                return -EINVAL;
 155        priv->protocol = value;
 156        CTCM_DBF_DEV(SETUP, dev, buf);
 157
 158        return count;
 159}
 160
 161static ssize_t ctcm_type_show(struct device *dev,
 162                                struct device_attribute *attr, char *buf)
 163{
 164        struct ccwgroup_device *cgdev;
 165
 166        cgdev = to_ccwgroupdev(dev);
 167        if (!cgdev)
 168                return -ENODEV;
 169
 170        return sprintf(buf, "%s\n",
 171                        cu3088_type[cgdev->cdev[0]->id.driver_info]);
 172}
 173
 174static DEVICE_ATTR(buffer, 0644, ctcm_buffer_show, ctcm_buffer_write);
 175static DEVICE_ATTR(protocol, 0644, ctcm_proto_show, ctcm_proto_store);
 176static DEVICE_ATTR(type, 0444, ctcm_type_show, NULL);
 177static DEVICE_ATTR(stats, 0644, stats_show, stats_write);
 178
 179static struct attribute *ctcm_attr[] = {
 180        &dev_attr_protocol.attr,
 181        &dev_attr_type.attr,
 182        &dev_attr_buffer.attr,
 183        NULL,
 184};
 185
 186static struct attribute_group ctcm_attr_group = {
 187        .attrs = ctcm_attr,
 188};
 189
 190int ctcm_add_attributes(struct device *dev)
 191{
 192        int rc;
 193
 194        rc = device_create_file(dev, &dev_attr_stats);
 195
 196        return rc;
 197}
 198
 199void ctcm_remove_attributes(struct device *dev)
 200{
 201        device_remove_file(dev, &dev_attr_stats);
 202}
 203
 204int ctcm_add_files(struct device *dev)
 205{
 206        return sysfs_create_group(&dev->kobj, &ctcm_attr_group);
 207}
 208
 209void ctcm_remove_files(struct device *dev)
 210{
 211        sysfs_remove_group(&dev->kobj, &ctcm_attr_group);
 212}
 213
 214