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 14 static 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 22 static 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 30 static ssize_t atmindex_show(struct device *cdev, 31 struct device_attribute *attr, char *buf) 32 { 33 struct atm_dev *adev = to_atm_dev(cdev); 34 35 return scnprintf(buf, PAGE_SIZE, "%d\n", adev->number); 36 } 37 38 static ssize_t carrier_show(struct device *cdev, 39 struct device_attribute *attr, char *buf) 40 { 41 struct atm_dev *adev = to_atm_dev(cdev); 42 43 return scnprintf(buf, PAGE_SIZE, "%d\n", 44 adev->signal == ATM_PHY_SIG_LOST ? 0 : 1); 45 } 46 47 static ssize_t link_rate_show(struct device *cdev, 48 struct device_attribute *attr, char *buf) 49 { 50 struct atm_dev *adev = to_atm_dev(cdev); 51 int link_rate; 52 53 /* show the link rate, not the data rate */ 54 switch (adev->link_rate) { 55 case ATM_OC3_PCR: 56 link_rate = 155520000; 57 break; 58 case ATM_OC12_PCR: 59 link_rate = 622080000; 60 break; 61 case ATM_25_PCR: 62 link_rate = 25600000; 63 break; 64 default: 65 link_rate = adev->link_rate * 8 * 53; 66 } 67 return scnprintf(buf, PAGE_SIZE, "%d\n", link_rate); 68 } 69 70 static DEVICE_ATTR_RO(address); 71 static DEVICE_ATTR_RO(atmindex); 72 static DEVICE_ATTR_RO(carrier); 73 static DEVICE_ATTR_RO(type); 74 static DEVICE_ATTR_RO(link_rate); 75 76 static struct device_attribute *atm_attrs[] = { 77 &dev_attr_address, 78 &dev_attr_atmindex, 79 &dev_attr_carrier, 80 &dev_attr_type, 81 &dev_attr_link_rate, 82 NULL 83 }; 84 85 86 static int atm_uevent(const struct device *cdev, struct kobj_uevent_env *env) 87 { 88 const struct atm_dev *adev; 89 90 if (!cdev) 91 return -ENODEV; 92 93 adev = to_atm_dev(cdev); 94 95 if (add_uevent_var(env, "NAME=%s%d", adev->type, adev->number)) 96 return -ENOMEM; 97 98 return 0; 99 } 100 101 static void atm_release(struct device *cdev) 102 { 103 struct atm_dev *adev = to_atm_dev(cdev); 104 105 kfree(adev); 106 } 107 108 static struct class atm_class = { 109 .name = "atm", 110 .dev_release = atm_release, 111 .dev_uevent = atm_uevent, 112 }; 113 114 int atm_register_sysfs(struct atm_dev *adev, struct device *parent) 115 { 116 struct device *cdev = &adev->class_dev; 117 int i, j, err; 118 119 cdev->class = &atm_class; 120 cdev->parent = parent; 121 dev_set_drvdata(cdev, adev); 122 123 dev_set_name(cdev, "%s%d", adev->type, adev->number); 124 err = device_register(cdev); 125 if (err < 0) 126 return err; 127 128 for (i = 0; atm_attrs[i]; i++) { 129 err = device_create_file(cdev, atm_attrs[i]); 130 if (err) 131 goto err_out; 132 } 133 134 return 0; 135 136 err_out: 137 for (j = 0; j < i; j++) 138 device_remove_file(cdev, atm_attrs[j]); 139 device_del(cdev); 140 return err; 141 } 142 143 void atm_unregister_sysfs(struct atm_dev *adev) 144 { 145 struct device *cdev = &adev->class_dev; 146 147 device_del(cdev); 148 } 149 150 int __init atm_sysfs_init(void) 151 { 152 return class_register(&atm_class); 153 } 154 155 void __exit atm_sysfs_exit(void) 156 { 157 class_unregister(&atm_class); 158 } 159