Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* ATM driver model support. */
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     /* show the link rate, not the data rate */
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 }