linux/net/atm/atm_sysfs.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* ATM driver model support. */
   3
   4#include <linux/kernel.h>
   5#include <linux/slab.h>
   6#include <linux/init.h>
   7#include <linux/kobject.h>
   8#include <linux/atmdev.h>
   9#include "common.h"
  10#include "resources.h"
  11
  12#define to_atm_dev(cldev) container_of(cldev, struct atm_dev, class_dev)
  13
  14static ssize_t type_show(struct device *cdev,
  15                         struct device_attribute *attr, char *buf)
  16{
  17        struct atm_dev *adev = to_atm_dev(cdev);
  18
  19        return scnprintf(buf, PAGE_SIZE, "%s\n", adev->type);
  20}
  21
  22static ssize_t address_show(struct device *cdev,
  23                            struct device_attribute *attr, char *buf)
  24{
  25        struct atm_dev *adev = to_atm_dev(cdev);
  26
  27        return scnprintf(buf, PAGE_SIZE, "%pM\n", adev->esi);
  28}
  29
  30static ssize_t atmaddress_show(struct device *cdev,
  31                               struct device_attribute *attr, char *buf)
  32{
  33        unsigned long flags;
  34        struct atm_dev *adev = to_atm_dev(cdev);
  35        struct atm_dev_addr *aaddr;
  36        int count = 0;
  37
  38        spin_lock_irqsave(&adev->lock, flags);
  39        list_for_each_entry(aaddr, &adev->local, entry) {
  40                count += scnprintf(buf + count, PAGE_SIZE - count,
  41                                   "%1phN.%2phN.%10phN.%6phN.%1phN\n",
  42                                   &aaddr->addr.sas_addr.prv[0],
  43                                   &aaddr->addr.sas_addr.prv[1],
  44                                   &aaddr->addr.sas_addr.prv[3],
  45                                   &aaddr->addr.sas_addr.prv[13],
  46                                   &aaddr->addr.sas_addr.prv[19]);
  47        }
  48        spin_unlock_irqrestore(&adev->lock, flags);
  49
  50        return count;
  51}
  52
  53static ssize_t atmindex_show(struct device *cdev,
  54                             struct device_attribute *attr, char *buf)
  55{
  56        struct atm_dev *adev = to_atm_dev(cdev);
  57
  58        return scnprintf(buf, PAGE_SIZE, "%d\n", adev->number);
  59}
  60
  61static ssize_t carrier_show(struct device *cdev,
  62                            struct device_attribute *attr, char *buf)
  63{
  64        struct atm_dev *adev = to_atm_dev(cdev);
  65
  66        return scnprintf(buf, PAGE_SIZE, "%d\n",
  67                         adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);
  68}
  69
  70static ssize_t link_rate_show(struct device *cdev,
  71                              struct device_attribute *attr, char *buf)
  72{
  73        struct atm_dev *adev = to_atm_dev(cdev);
  74        int link_rate;
  75
  76        /* show the link rate, not the data rate */
  77        switch (adev->link_rate) {
  78        case ATM_OC3_PCR:
  79                link_rate = 155520000;
  80                break;
  81        case ATM_OC12_PCR:
  82                link_rate = 622080000;
  83                break;
  84        case ATM_25_PCR:
  85                link_rate = 25600000;
  86                break;
  87        default:
  88                link_rate = adev->link_rate * 8 * 53;
  89        }
  90        return scnprintf(buf, PAGE_SIZE, "%d\n", link_rate);
  91}
  92
  93static DEVICE_ATTR_RO(address);
  94static DEVICE_ATTR_RO(atmaddress);
  95static DEVICE_ATTR_RO(atmindex);
  96static DEVICE_ATTR_RO(carrier);
  97static DEVICE_ATTR_RO(type);
  98static DEVICE_ATTR_RO(link_rate);
  99
 100static struct device_attribute *atm_attrs[] = {
 101        &dev_attr_atmaddress,
 102        &dev_attr_address,
 103        &dev_attr_atmindex,
 104        &dev_attr_carrier,
 105        &dev_attr_type,
 106        &dev_attr_link_rate,
 107        NULL
 108};
 109
 110
 111static int atm_uevent(struct device *cdev, struct kobj_uevent_env *env)
 112{
 113        struct atm_dev *adev;
 114
 115        if (!cdev)
 116                return -ENODEV;
 117
 118        adev = to_atm_dev(cdev);
 119        if (!adev)
 120                return -ENODEV;
 121
 122        if (add_uevent_var(env, "NAME=%s%d", adev->type, adev->number))
 123                return -ENOMEM;
 124
 125        return 0;
 126}
 127
 128static void atm_release(struct device *cdev)
 129{
 130        struct atm_dev *adev = to_atm_dev(cdev);
 131
 132        kfree(adev);
 133}
 134
 135static struct class atm_class = {
 136        .name           = "atm",
 137        .dev_release    = atm_release,
 138        .dev_uevent             = atm_uevent,
 139};
 140
 141int atm_register_sysfs(struct atm_dev *adev, struct device *parent)
 142{
 143        struct device *cdev = &adev->class_dev;
 144        int i, j, err;
 145
 146        cdev->class = &atm_class;
 147        cdev->parent = parent;
 148        dev_set_drvdata(cdev, adev);
 149
 150        dev_set_name(cdev, "%s%d", adev->type, adev->number);
 151        err = device_register(cdev);
 152        if (err < 0)
 153                return err;
 154
 155        for (i = 0; atm_attrs[i]; i++) {
 156                err = device_create_file(cdev, atm_attrs[i]);
 157                if (err)
 158                        goto err_out;
 159        }
 160
 161        return 0;
 162
 163err_out:
 164        for (j = 0; j < i; j++)
 165                device_remove_file(cdev, atm_attrs[j]);
 166        device_del(cdev);
 167        return err;
 168}
 169
 170void atm_unregister_sysfs(struct atm_dev *adev)
 171{
 172        struct device *cdev = &adev->class_dev;
 173
 174        device_del(cdev);
 175}
 176
 177int __init atm_sysfs_init(void)
 178{
 179        return class_register(&atm_class);
 180}
 181
 182void __exit atm_sysfs_exit(void)
 183{
 184        class_unregister(&atm_class);
 185}
 186