0001
0002
0003
0004 #include <linux/kernel.h>
0005 #include <linux/slab.h>
0006 #include <linux/init.h>
0007 #include <linux/kobject.h>
0008 #include <linux/atmdev.h>
0009 #include "common.h"
0010 #include "resources.h"
0011
0012 #define to_atm_dev(cldev) container_of(cldev, struct atm_dev, class_dev)
0013
0014 static ssize_t type_show(struct device *cdev,
0015 struct device_attribute *attr, char *buf)
0016 {
0017 struct atm_dev *adev = to_atm_dev(cdev);
0018
0019 return scnprintf(buf, PAGE_SIZE, "%s\n", adev->type);
0020 }
0021
0022 static ssize_t address_show(struct device *cdev,
0023 struct device_attribute *attr, char *buf)
0024 {
0025 struct atm_dev *adev = to_atm_dev(cdev);
0026
0027 return scnprintf(buf, PAGE_SIZE, "%pM\n", adev->esi);
0028 }
0029
0030 static ssize_t atmaddress_show(struct device *cdev,
0031 struct device_attribute *attr, char *buf)
0032 {
0033 unsigned long flags;
0034 struct atm_dev *adev = to_atm_dev(cdev);
0035 struct atm_dev_addr *aaddr;
0036 int count = 0;
0037
0038 spin_lock_irqsave(&adev->lock, flags);
0039 list_for_each_entry(aaddr, &adev->local, entry) {
0040 count += scnprintf(buf + count, PAGE_SIZE - count,
0041 "%1phN.%2phN.%10phN.%6phN.%1phN\n",
0042 &aaddr->addr.sas_addr.prv[0],
0043 &aaddr->addr.sas_addr.prv[1],
0044 &aaddr->addr.sas_addr.prv[3],
0045 &aaddr->addr.sas_addr.prv[13],
0046 &aaddr->addr.sas_addr.prv[19]);
0047 }
0048 spin_unlock_irqrestore(&adev->lock, flags);
0049
0050 return count;
0051 }
0052
0053 static ssize_t atmindex_show(struct device *cdev,
0054 struct device_attribute *attr, char *buf)
0055 {
0056 struct atm_dev *adev = to_atm_dev(cdev);
0057
0058 return scnprintf(buf, PAGE_SIZE, "%d\n", adev->number);
0059 }
0060
0061 static ssize_t carrier_show(struct device *cdev,
0062 struct device_attribute *attr, char *buf)
0063 {
0064 struct atm_dev *adev = to_atm_dev(cdev);
0065
0066 return scnprintf(buf, PAGE_SIZE, "%d\n",
0067 adev->signal == ATM_PHY_SIG_LOST ? 0 : 1);
0068 }
0069
0070 static ssize_t link_rate_show(struct device *cdev,
0071 struct device_attribute *attr, char *buf)
0072 {
0073 struct atm_dev *adev = to_atm_dev(cdev);
0074 int link_rate;
0075
0076
0077 switch (adev->link_rate) {
0078 case ATM_OC3_PCR:
0079 link_rate = 155520000;
0080 break;
0081 case ATM_OC12_PCR:
0082 link_rate = 622080000;
0083 break;
0084 case ATM_25_PCR:
0085 link_rate = 25600000;
0086 break;
0087 default:
0088 link_rate = adev->link_rate * 8 * 53;
0089 }
0090 return scnprintf(buf, PAGE_SIZE, "%d\n", link_rate);
0091 }
0092
0093 static DEVICE_ATTR_RO(address);
0094 static DEVICE_ATTR_RO(atmaddress);
0095 static DEVICE_ATTR_RO(atmindex);
0096 static DEVICE_ATTR_RO(carrier);
0097 static DEVICE_ATTR_RO(type);
0098 static DEVICE_ATTR_RO(link_rate);
0099
0100 static struct device_attribute *atm_attrs[] = {
0101 &dev_attr_atmaddress,
0102 &dev_attr_address,
0103 &dev_attr_atmindex,
0104 &dev_attr_carrier,
0105 &dev_attr_type,
0106 &dev_attr_link_rate,
0107 NULL
0108 };
0109
0110
0111 static int atm_uevent(struct device *cdev, struct kobj_uevent_env *env)
0112 {
0113 struct atm_dev *adev;
0114
0115 if (!cdev)
0116 return -ENODEV;
0117
0118 adev = to_atm_dev(cdev);
0119 if (!adev)
0120 return -ENODEV;
0121
0122 if (add_uevent_var(env, "NAME=%s%d", adev->type, adev->number))
0123 return -ENOMEM;
0124
0125 return 0;
0126 }
0127
0128 static void atm_release(struct device *cdev)
0129 {
0130 struct atm_dev *adev = to_atm_dev(cdev);
0131
0132 kfree(adev);
0133 }
0134
0135 static struct class atm_class = {
0136 .name = "atm",
0137 .dev_release = atm_release,
0138 .dev_uevent = atm_uevent,
0139 };
0140
0141 int atm_register_sysfs(struct atm_dev *adev, struct device *parent)
0142 {
0143 struct device *cdev = &adev->class_dev;
0144 int i, j, err;
0145
0146 cdev->class = &atm_class;
0147 cdev->parent = parent;
0148 dev_set_drvdata(cdev, adev);
0149
0150 dev_set_name(cdev, "%s%d", adev->type, adev->number);
0151 err = device_register(cdev);
0152 if (err < 0)
0153 return err;
0154
0155 for (i = 0; atm_attrs[i]; i++) {
0156 err = device_create_file(cdev, atm_attrs[i]);
0157 if (err)
0158 goto err_out;
0159 }
0160
0161 return 0;
0162
0163 err_out:
0164 for (j = 0; j < i; j++)
0165 device_remove_file(cdev, atm_attrs[j]);
0166 device_del(cdev);
0167 return err;
0168 }
0169
0170 void atm_unregister_sysfs(struct atm_dev *adev)
0171 {
0172 struct device *cdev = &adev->class_dev;
0173
0174 device_del(cdev);
0175 }
0176
0177 int __init atm_sysfs_init(void)
0178 {
0179 return class_register(&atm_class);
0180 }
0181
0182 void __exit atm_sysfs_exit(void)
0183 {
0184 class_unregister(&atm_class);
0185 }