]> rtime.felk.cvut.cz Git - socketcan-devel.git/blob - kernel/2.6/drivers/net/can/sysfs.c
dev: Use minimal set of SYSFS flies for intelligent CAN controllers
[socketcan-devel.git] / kernel / 2.6 / drivers / net / can / sysfs.c
1 /*
2  * $Id: dev.c 542 2007-11-07 13:57:16Z thuermann $
3  *
4  * Copyright (C) 2007-2008 Wolfgang Grandegger <wg@grandegger.com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the version 2 of the GNU General Public License
8  * as published by the Free Software Foundation
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19
20 #include <linux/capability.h>
21 #include <linux/kernel.h>
22 #include <linux/netdevice.h>
23 #include <linux/if_arp.h>
24 #include <net/sock.h>
25 #include <linux/rtnetlink.h>
26
27 #include <linux/can.h>
28 #include <linux/can/dev.h>
29
30 #include "sysfs.h"
31
32 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
33 int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
34 {
35         char *tail;
36         unsigned long val;
37         size_t len;
38
39         *res = 0;
40         len = strlen(cp);
41         if (len == 0)
42                 return -EINVAL;
43
44         val = simple_strtoul(cp, &tail, base);
45         if ((*tail == '\0') ||
46                 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
47                 *res = val;
48                 return 0;
49         }
50
51         return -EINVAL;
52 }
53 #endif
54
55 #ifdef CONFIG_SYSFS
56
57 /*
58  * SYSFS access functions and attributes. Use same locking as
59  * net/core/net-sysfs.c does.
60  */
61 static inline int dev_isalive(const struct net_device *dev)
62 {
63         return dev->reg_state <= NETREG_REGISTERED;
64 }
65
66 /* use same locking rules as GIF* ioctl's */
67 static ssize_t can_dev_show(struct device *d,
68                             struct device_attribute *attr, char *buf,
69                             ssize_t (*fmt)(struct net_device *, char *))
70 {
71         struct net_device *dev = to_net_dev(d);
72         ssize_t ret = -EINVAL;
73
74         read_lock(&dev_base_lock);
75         if (dev_isalive(dev))
76                 ret = (*fmt)(dev, buf);
77         read_unlock(&dev_base_lock);
78
79         return ret;
80 }
81
82 /* generate a show function for simple field */
83 #define CAN_DEV_SHOW(field, fmt_string)                                 \
84 static ssize_t fmt_can_##field(struct net_device *dev, char *buf)       \
85 {                                                                       \
86         struct can_priv *priv = netdev_priv(dev);                       \
87         return sprintf(buf, fmt_string, priv->field);                   \
88 }                                                                       \
89 static ssize_t show_can_##field(struct device *d,                       \
90                                 struct device_attribute *attr,          \
91                                 char *buf)                              \
92 {                                                                       \
93         return can_dev_show(d, attr, buf, fmt_can_##field);             \
94 }
95
96 /* use same locking and permission rules as SIF* ioctl's */
97 static ssize_t can_dev_store(struct device *d, struct device_attribute *attr,
98                              const char *buf, size_t len,
99                              int (*set)(struct net_device *, unsigned long))
100 {
101         struct net_device *dev = to_net_dev(d);
102         unsigned long new;
103         int ret = -EINVAL;
104
105         if (!capable(CAP_NET_ADMIN))
106                 return -EPERM;
107
108         ret = strict_strtoul(buf, 0, &new);
109         if (ret)
110                 goto out;
111
112         rtnl_lock();
113         if (dev_isalive(dev)) {
114                 ret = (*set)(dev, new);
115                 if (!ret)
116                         ret = len;
117         }
118         rtnl_unlock();
119 out:
120         return ret;
121 }
122
123 #define CAN_CREATE_FILE(_dev, _name)                                    \
124         if (device_create_file(&_dev->dev, &dev_attr_##_name))          \
125                 dev_err(ND2D(_dev),                                     \
126                         "Couldn't create device file for ##_name\n")
127
128 #define CAN_REMOVE_FILE(_dev, _name)                                    \
129         device_remove_file(&_dev->dev, &dev_attr_##_name)               \
130
131 CAN_DEV_SHOW(ctrlmode, "0x%x\n");
132
133 static int change_can_ctrlmode(struct net_device *dev, unsigned long ctrlmode)
134 {
135         struct can_priv *priv = netdev_priv(dev);
136         int err = 0;
137
138         if (priv->state != CAN_STATE_STOPPED)
139                 return -EBUSY;
140
141         if (priv->do_set_ctrlmode)
142                 err = priv->do_set_ctrlmode(dev, ctrlmode);
143
144         if (!err)
145                 priv->ctrlmode = ctrlmode;
146
147         return err;
148 }
149
150 static ssize_t store_can_ctrlmode(struct device *dev,
151                                   struct device_attribute *attr,
152                                   const char *buf, size_t len)
153 {
154         return can_dev_store(dev, attr, buf, len, change_can_ctrlmode);
155 }
156
157 static DEVICE_ATTR(can_ctrlmode, S_IRUGO | S_IWUSR,
158                    show_can_ctrlmode, store_can_ctrlmode);
159
160 static const char *can_state_names[] = {
161         "active", "bus-warn", "bus-pass" , "bus-off",
162         "stopped", "sleeping", "unkown"
163 };
164
165 static ssize_t printf_can_state(struct net_device *dev, char *buf)
166 {
167         struct can_priv *priv = netdev_priv(dev);
168         enum can_state state;
169         int err = 0;
170
171         if (priv->do_get_state) {
172                 err = priv->do_get_state(dev, &state);
173                 if (err)
174                         goto out;
175                 priv->state = state;
176         } else
177                 state = priv->state;
178
179         if (state >= ARRAY_SIZE(can_state_names))
180                 state = ARRAY_SIZE(can_state_names) - 1;
181         err = sprintf(buf, "%s\n", can_state_names[state]);
182 out:
183         return err;
184 }
185
186 static ssize_t show_can_state(struct device *d,
187                               struct device_attribute *attr, char *buf)
188 {
189         return can_dev_show(d, attr, buf, printf_can_state);
190 }
191
192 static DEVICE_ATTR(can_state, S_IRUGO, show_can_state, NULL);
193
194 CAN_DEV_SHOW(restart_ms, "%d\n");
195
196 static int change_can_restart_ms(struct net_device *dev, unsigned long ms)
197 {
198         struct can_priv *priv = netdev_priv(dev);
199
200         if (priv->restart_ms < 0)
201                 return -EOPNOTSUPP;
202         priv->restart_ms = ms;
203         return 0;
204 }
205
206 static ssize_t store_can_restart_ms(struct device *dev,
207                                     struct device_attribute *attr,
208                                     const char *buf, size_t len)
209 {
210         return can_dev_store(dev, attr, buf, len, change_can_restart_ms);
211 }
212
213 static DEVICE_ATTR(can_restart_ms, S_IRUGO | S_IWUSR,
214                    show_can_restart_ms, store_can_restart_ms);
215
216 static ssize_t printf_can_echo(struct net_device *dev, char *buf)
217 {
218         return sprintf(buf, "%d\n", dev->flags & IFF_ECHO ? 1 : 0);
219 }
220
221 static ssize_t show_can_echo(struct device *d,
222                           struct device_attribute *attr, char *buf)
223 {
224         return can_dev_show(d, attr, buf, printf_can_echo);
225 }
226
227 static int change_can_echo(struct net_device *dev, unsigned long on)
228 {
229         if (on)
230                 dev->flags |= IFF_ECHO;
231         else
232                 dev->flags &= ~IFF_ECHO;
233         return 0;
234 }
235
236 static ssize_t store_can_echo(struct device *dev,
237                               struct device_attribute *attr,
238                               const char *buf, size_t len)
239 {
240         return can_dev_store(dev, attr, buf, len, change_can_echo);
241 }
242
243 static DEVICE_ATTR(can_echo, S_IRUGO | S_IWUSR, show_can_echo, store_can_echo);
244
245 static int change_can_restart(struct net_device *dev, unsigned long on)
246 {
247         return can_restart_now(dev);
248 }
249
250 static ssize_t store_can_restart(struct device *dev,
251                                  struct device_attribute *attr,
252                                  const char *buf, size_t len)
253 {
254         return can_dev_store(dev, attr, buf, len, change_can_restart);
255 }
256
257 static DEVICE_ATTR(can_restart, S_IWUSR, NULL, store_can_restart);
258
259 /* Show a given attribute if the CAN bittiming group */
260 static ssize_t can_btc_show(const struct device *d,
261                             struct device_attribute *attr, char *buf,
262                             unsigned long offset)
263 {
264         struct net_device *dev = to_net_dev(d);
265         struct can_priv *priv = netdev_priv(dev);
266         struct can_bittiming_const *btc = priv->bittiming_const;
267         ssize_t ret = -EINVAL;
268
269         WARN_ON(offset >= sizeof(struct can_bittiming_const) ||
270                 offset % sizeof(u32) != 0);
271
272         read_lock(&dev_base_lock);
273         if (dev_isalive(dev) && btc)
274                 ret = sprintf(buf, "%d\n",
275                               *(u32 *)(((u8 *)btc) + offset));
276
277         read_unlock(&dev_base_lock);
278         return ret;
279 }
280
281 /* Generate a read-only bittiming const attribute */
282 #define CAN_BT_CONST_ENTRY(name)                                        \
283 static ssize_t show_##name(struct device *d,                            \
284                            struct device_attribute *attr, char *buf)    \
285 {                                                                       \
286         return can_btc_show(d, attr, buf,                               \
287                             offsetof(struct can_bittiming_const, name));\
288 }                                                                       \
289 static DEVICE_ATTR(hw_##name, S_IRUGO, show_##name, NULL)
290
291 CAN_BT_CONST_ENTRY(tseg1_min);
292 CAN_BT_CONST_ENTRY(tseg1_max);
293 CAN_BT_CONST_ENTRY(tseg2_min);
294 CAN_BT_CONST_ENTRY(tseg2_max);
295 CAN_BT_CONST_ENTRY(sjw_max);
296 CAN_BT_CONST_ENTRY(brp_min);
297 CAN_BT_CONST_ENTRY(brp_max);
298 CAN_BT_CONST_ENTRY(brp_inc);
299
300 static ssize_t can_bt_show(const struct device *d,
301                            struct device_attribute *attr, char *buf,
302                            unsigned long offset)
303 {
304         struct net_device *dev = to_net_dev(d);
305         struct can_priv *priv = netdev_priv(dev);
306         struct can_bittiming *bt = &priv->bittiming;
307         ssize_t ret = -EINVAL;
308         u32 *ptr, val;
309
310         WARN_ON(offset >= sizeof(struct can_bittiming) ||
311                 offset % sizeof(u32) != 0);
312
313         read_lock(&dev_base_lock);
314         if (dev_isalive(dev)) {
315                 ptr = (u32 *)(((u8 *)bt) + offset);
316                 if (ptr == &bt->sample_point &&
317                     priv->state != CAN_STATE_STOPPED)
318                         val = can_sample_point(bt);
319                 else
320                         val = *ptr;
321                 ret = sprintf(buf, "%d\n", val);
322         }
323         read_unlock(&dev_base_lock);
324         return ret;
325 }
326
327 static ssize_t can_bt_store(const struct device *d,
328                             struct device_attribute *attr,
329                             const char *buf, size_t count,
330                             unsigned long offset)
331 {
332         struct net_device *dev = to_net_dev(d);
333         struct can_priv *priv = netdev_priv(dev);
334         struct can_bittiming *bt = &priv->bittiming;
335         unsigned long new;
336         ssize_t ret = -EINVAL;
337         u32 *ptr;
338
339         if (priv->state != CAN_STATE_STOPPED)
340                 return -EBUSY;
341
342         WARN_ON(offset >= sizeof(struct can_bittiming) ||
343                 offset % sizeof(u32) != 0);
344
345         ret = strict_strtoul(buf, 0, &new);
346         if (ret)
347                 goto out;
348
349         ptr = (u32 *)(((u8 *)bt) + offset);
350         rtnl_lock();
351         if (dev_isalive(dev)) {
352                 *ptr = (u32)new;
353
354                 if ((ptr == &bt->bitrate) || (ptr == &bt->sample_point)) {
355                         bt->tq = 0;
356                         bt->brp = 0;
357                         bt->sjw = 0;
358                         bt->prop_seg = 0;
359                         bt->phase_seg1 = 0;
360                         bt->phase_seg2 = 0;
361                 } else {
362                         bt->bitrate = 0;
363                         bt->sample_point = 0;
364                 }
365                 ret = count;
366         }
367         rtnl_unlock();
368 out:
369         return ret;
370 }
371
372 #define CAN_BT_ENTRY_RO(name)                                           \
373 static ssize_t show_##name(struct device *d,                            \
374                            struct device_attribute *attr, char *buf)    \
375 {                                                                       \
376         return can_bt_show(d, attr, buf,                                \
377                            offsetof(struct can_bittiming, name));       \
378 }                                                                       \
379 static DEVICE_ATTR(hw_##name, S_IRUGO, show_##name, NULL)
380
381 CAN_BT_ENTRY_RO(clock);
382
383 #define CAN_BT_ENTRY(name)                                              \
384 static ssize_t show_##name(struct device *d,                            \
385                            struct device_attribute *attr, char *buf)    \
386 {                                                                       \
387         return can_bt_show(d, attr, buf,                                \
388                            offsetof(struct can_bittiming, name));       \
389 }                                                                       \
390 static ssize_t store_##name(struct device *d,                           \
391                             struct device_attribute *attr,              \
392                             const char *buf, size_t count)              \
393 {                                                                       \
394         return can_bt_store(d, attr, buf, count,                        \
395                             offsetof(struct can_bittiming, name));      \
396 }                                                                       \
397 static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
398
399 CAN_BT_ENTRY(bitrate);
400 CAN_BT_ENTRY(sample_point);
401 CAN_BT_ENTRY(tq);
402 CAN_BT_ENTRY(prop_seg);
403 CAN_BT_ENTRY(phase_seg1);
404 CAN_BT_ENTRY(phase_seg2);
405 CAN_BT_ENTRY(sjw);
406
407 static struct attribute *can_bittiming_attrs[] = {
408         &dev_attr_hw_tseg1_min.attr,
409         &dev_attr_hw_tseg1_max.attr,
410         &dev_attr_hw_tseg2_max.attr,
411         &dev_attr_hw_tseg2_min.attr,
412         &dev_attr_hw_sjw_max.attr,
413         &dev_attr_hw_brp_min.attr,
414         &dev_attr_hw_brp_max.attr,
415         &dev_attr_hw_brp_inc.attr,
416         &dev_attr_hw_clock.attr,
417         &dev_attr_bitrate.attr,
418         &dev_attr_sample_point.attr,
419         &dev_attr_tq.attr,
420         &dev_attr_prop_seg.attr,
421         &dev_attr_phase_seg1.attr,
422         &dev_attr_phase_seg2.attr,
423         &dev_attr_sjw.attr,
424         NULL
425 };
426
427 /* Minimal number of attributes to support intelligent CAN controllers */
428 static struct attribute *can_bittiming_min_attrs[] = {
429         &dev_attr_bitrate.attr,
430         NULL
431 };
432
433 static struct attribute_group can_bittiming_group = {
434         .name = "can_bittiming",
435         .attrs = can_bittiming_attrs,
436 };
437
438 /* Show a given attribute in the CAN statistics group */
439 static ssize_t can_stat_show(const struct device *d,
440                              struct device_attribute *attr, char *buf,
441                              unsigned long offset)
442 {
443         struct net_device *dev = to_net_dev(d);
444         struct can_priv *priv = netdev_priv(dev);
445         struct can_device_stats *stats = &priv->can_stats;
446         ssize_t ret = -EINVAL;
447
448         WARN_ON(offset >= sizeof(struct can_device_stats) ||
449                 offset % sizeof(unsigned long) != 0);
450
451         read_lock(&dev_base_lock);
452         if (dev_isalive(dev))
453                 ret = sprintf(buf, "%ld\n",
454                               *(unsigned long *)(((u8 *)stats) + offset));
455
456         read_unlock(&dev_base_lock);
457         return ret;
458 }
459
460 /* Generate a read-only CAN statistics attribute */
461 #define CAN_STAT_ENTRY(name)                                            \
462 static ssize_t show_##name(struct device *d,                            \
463                            struct device_attribute *attr, char *buf)    \
464 {                                                                       \
465         return can_stat_show(d, attr, buf,                              \
466                              offsetof(struct can_device_stats, name));  \
467 }                                                                       \
468 static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
469
470 CAN_STAT_ENTRY(error_warning);
471 CAN_STAT_ENTRY(error_passive);
472 CAN_STAT_ENTRY(bus_error);
473 CAN_STAT_ENTRY(arbitration_lost);
474 CAN_STAT_ENTRY(data_overrun);
475 CAN_STAT_ENTRY(wakeup);
476 CAN_STAT_ENTRY(restarts);
477
478 static struct attribute *can_statistics_attrs[] = {
479         &dev_attr_error_warning.attr,
480         &dev_attr_error_passive.attr,
481         &dev_attr_bus_error.attr,
482         &dev_attr_arbitration_lost.attr,
483         &dev_attr_data_overrun.attr,
484         &dev_attr_wakeup.attr,
485         &dev_attr_restarts.attr,
486         NULL
487 };
488
489 static struct attribute_group can_statistics_group = {
490         .name = "can_statistics",
491         .attrs = can_statistics_attrs,
492 };
493
494 void can_create_sysfs(struct net_device *dev)
495 {
496         struct can_priv *priv = netdev_priv(dev);
497         int err;
498
499         CAN_CREATE_FILE(dev, can_ctrlmode);
500         CAN_CREATE_FILE(dev, can_echo);
501         CAN_CREATE_FILE(dev, can_restart);
502         CAN_CREATE_FILE(dev, can_state);
503         CAN_CREATE_FILE(dev, can_restart_ms);
504
505         err = sysfs_create_group(&(dev->dev.kobj),
506                                  &can_statistics_group);
507         if (err) {
508                 printk(KERN_EMERG
509                        "couldn't create sysfs group for CAN statistics\n");
510         }
511
512         if (!priv->bittiming_const)
513                 can_bittiming_group.attrs = can_bittiming_min_attrs;
514         err = sysfs_create_group(&(dev->dev.kobj), &can_bittiming_group);
515         if (err) {
516                 printk(KERN_EMERG "couldn't create sysfs "
517                        "group for CAN bittiming\n");
518         }
519 }
520
521 void can_remove_sysfs(struct net_device *dev)
522 {
523         struct can_priv *priv = netdev_priv(dev);
524
525         CAN_REMOVE_FILE(dev, can_ctrlmode);
526         CAN_REMOVE_FILE(dev, can_echo);
527         CAN_REMOVE_FILE(dev, can_state);
528         CAN_REMOVE_FILE(dev, can_restart);
529         CAN_REMOVE_FILE(dev, can_restart_ms);
530
531         sysfs_remove_group(&(dev->dev.kobj), &can_statistics_group);
532         if (priv->bittiming_const)
533                 sysfs_remove_group(&(dev->dev.kobj), &can_bittiming_group);
534 }
535
536 #endif /* CONFIG_SYSFS */
537
538
539