diff options
Diffstat (limited to 'net/atm/atm_sysfs.c')
-rw-r--r-- | net/atm/atm_sysfs.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c new file mode 100644 index 000000000000..5df4b9a068bb --- /dev/null +++ b/net/atm/atm_sysfs.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* ATM driver model support. */ | ||
2 | |||
3 | #include <linux/config.h> | ||
4 | #include <linux/kernel.h> | ||
5 | #include <linux/init.h> | ||
6 | #include <linux/kobject.h> | ||
7 | #include <linux/atmdev.h> | ||
8 | #include "common.h" | ||
9 | #include "resources.h" | ||
10 | |||
11 | #define to_atm_dev(cldev) container_of(cldev, struct atm_dev, class_dev) | ||
12 | |||
13 | static ssize_t show_type(struct class_device *cdev, char *buf) | ||
14 | { | ||
15 | struct atm_dev *adev = to_atm_dev(cdev); | ||
16 | return sprintf(buf, "%s\n", adev->type); | ||
17 | } | ||
18 | |||
19 | static ssize_t show_address(struct class_device *cdev, char *buf) | ||
20 | { | ||
21 | char *pos = buf; | ||
22 | struct atm_dev *adev = to_atm_dev(cdev); | ||
23 | int i; | ||
24 | |||
25 | for (i = 0; i < (ESI_LEN - 1); i++) | ||
26 | pos += sprintf(pos, "%02x:", adev->esi[i]); | ||
27 | pos += sprintf(pos, "%02x\n", adev->esi[i]); | ||
28 | |||
29 | return pos - buf; | ||
30 | } | ||
31 | |||
32 | static ssize_t show_atmaddress(struct class_device *cdev, char *buf) | ||
33 | { | ||
34 | unsigned long flags; | ||
35 | char *pos = buf; | ||
36 | struct atm_dev *adev = to_atm_dev(cdev); | ||
37 | struct atm_dev_addr *aaddr; | ||
38 | int bin[] = { 1, 2, 10, 6, 1 }, *fmt = bin; | ||
39 | int i, j; | ||
40 | |||
41 | spin_lock_irqsave(&adev->lock, flags); | ||
42 | list_for_each_entry(aaddr, &adev->local, entry) { | ||
43 | for(i = 0, j = 0; i < ATM_ESA_LEN; ++i, ++j) { | ||
44 | if (j == *fmt) { | ||
45 | pos += sprintf(pos, "."); | ||
46 | ++fmt; | ||
47 | j = 0; | ||
48 | } | ||
49 | pos += sprintf(pos, "%02x", aaddr->addr.sas_addr.prv[i]); | ||
50 | } | ||
51 | pos += sprintf(pos, "\n"); | ||
52 | } | ||
53 | spin_unlock_irqrestore(&adev->lock, flags); | ||
54 | |||
55 | return pos - buf; | ||
56 | } | ||
57 | |||
58 | static ssize_t show_carrier(struct class_device *cdev, char *buf) | ||
59 | { | ||
60 | char *pos = buf; | ||
61 | struct atm_dev *adev = to_atm_dev(cdev); | ||
62 | |||
63 | pos += sprintf(pos, "%d\n", | ||
64 | adev->signal == ATM_PHY_SIG_LOST ? 0 : 1); | ||
65 | |||
66 | return pos - buf; | ||
67 | } | ||
68 | |||
69 | static ssize_t show_link_rate(struct class_device *cdev, char *buf) | ||
70 | { | ||
71 | char *pos = buf; | ||
72 | struct atm_dev *adev = to_atm_dev(cdev); | ||
73 | int link_rate; | ||
74 | |||
75 | /* show the link rate, not the data rate */ | ||
76 | switch (adev->link_rate) { | ||
77 | case ATM_OC3_PCR: | ||
78 | link_rate = 155520000; | ||
79 | break; | ||
80 | case ATM_OC12_PCR: | ||
81 | link_rate = 622080000; | ||
82 | break; | ||
83 | case ATM_25_PCR: | ||
84 | link_rate = 25600000; | ||
85 | break; | ||
86 | default: | ||
87 | link_rate = adev->link_rate * 8 * 53; | ||
88 | } | ||
89 | pos += sprintf(pos, "%d\n", link_rate); | ||
90 | |||
91 | return pos - buf; | ||
92 | } | ||
93 | |||
94 | static CLASS_DEVICE_ATTR(address, S_IRUGO, show_address, NULL); | ||
95 | static CLASS_DEVICE_ATTR(atmaddress, S_IRUGO, show_atmaddress, NULL); | ||
96 | static CLASS_DEVICE_ATTR(carrier, S_IRUGO, show_carrier, NULL); | ||
97 | static CLASS_DEVICE_ATTR(type, S_IRUGO, show_type, NULL); | ||
98 | static CLASS_DEVICE_ATTR(link_rate, S_IRUGO, show_link_rate, NULL); | ||
99 | |||
100 | static struct class_device_attribute *atm_attrs[] = { | ||
101 | &class_device_attr_atmaddress, | ||
102 | &class_device_attr_address, | ||
103 | &class_device_attr_carrier, | ||
104 | &class_device_attr_type, | ||
105 | &class_device_attr_link_rate, | ||
106 | NULL | ||
107 | }; | ||
108 | |||
109 | static int atm_uevent(struct class_device *cdev, char **envp, int num_envp, char *buf, int size) | ||
110 | { | ||
111 | struct atm_dev *adev; | ||
112 | int i = 0, len = 0; | ||
113 | |||
114 | if (!cdev) | ||
115 | return -ENODEV; | ||
116 | |||
117 | adev = to_atm_dev(cdev); | ||
118 | if (!adev) | ||
119 | return -ENODEV; | ||
120 | |||
121 | if (add_uevent_var(envp, num_envp, &i, buf, size, &len, | ||
122 | "NAME=%s%d", adev->type, adev->number)) | ||
123 | return -ENOMEM; | ||
124 | |||
125 | envp[i] = NULL; | ||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static void atm_release(struct class_device *cdev) | ||
130 | { | ||
131 | struct atm_dev *adev = to_atm_dev(cdev); | ||
132 | |||
133 | kfree(adev); | ||
134 | } | ||
135 | |||
136 | static struct class atm_class = { | ||
137 | .name = "atm", | ||
138 | .release = atm_release, | ||
139 | .uevent = atm_uevent, | ||
140 | }; | ||
141 | |||
142 | int atm_register_sysfs(struct atm_dev *adev) | ||
143 | { | ||
144 | struct class_device *cdev = &adev->class_dev; | ||
145 | int i, err; | ||
146 | |||
147 | cdev->class = &atm_class; | ||
148 | class_set_devdata(cdev, adev); | ||
149 | |||
150 | snprintf(cdev->class_id, BUS_ID_SIZE, "%s%d", adev->type, adev->number); | ||
151 | err = class_device_register(cdev); | ||
152 | if (err < 0) | ||
153 | return err; | ||
154 | |||
155 | for (i = 0; atm_attrs[i]; i++) | ||
156 | class_device_create_file(cdev, atm_attrs[i]); | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | void atm_unregister_sysfs(struct atm_dev *adev) | ||
162 | { | ||
163 | struct class_device *cdev = &adev->class_dev; | ||
164 | |||
165 | class_device_del(cdev); | ||
166 | } | ||
167 | |||
168 | int __init atm_sysfs_init(void) | ||
169 | { | ||
170 | return class_register(&atm_class); | ||
171 | } | ||
172 | |||
173 | void __exit atm_sysfs_exit(void) | ||
174 | { | ||
175 | class_unregister(&atm_class); | ||
176 | } | ||