Matthias Fuchs wrote:
> Hi Wolfgang,
>
> On Thursday 10 December 2009 13:37, Wolfgang Grandegger wrote:
>> Matthias Fuchs wrote:
>>> Hi,
>>>
>>> does anybody succeed in setting up SC on a 2.6.18 kernel?
>>> I need to get it up on a RHEL/CentOs 5.3 system.
>>>
>>> On the first glance there have been incompatibel changes in
>>> sysfs support. I don't dare to talk about netlink support.
>> Netlink support requires kernel version > 2.6.24.
> I know. We stepped backwards to sysfs.
>
>> What are the issues with 2.6.18.
>
> Here is my build output with only the ESD_PCI driver enabled. Also ISOTP and
> BCM are
> disabled because 2.6.18 lacks hrtimers support. But these are also not needed.
>
> matth...@debby:~/svn/socketcan/trunk/kernel/2.6$ make
> KERNELDIR=/usr/src/linux-2.6-2.6.18.dfsg.1 -k
> make -C /usr/src/linux-2.6-2.6.18.dfsg.1
> M=/data/home/matthias/svn/socketcan/trunk/kernel/2.6 modules
> TOPDIR=/data/home/matthias/svn/socketcan/trunk/kernel/2.6
> make[1]: Entering directory `/usr/src/linux-2.6-2.6.18.dfsg.1'
> CC [M]
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/vcan.o
> CC [M]
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/dev.o
> CC [M]
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.o
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:
> In function ‘can_dev_show’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:72:
> warning: implicit declaration of function ‘to_net_dev’
> => I fixed this like this:
> Replace
> struct net_device *dev = to_net_dev(d);
> by
> struct net_device *dev = d->driver_data;
>
> But I don't believe it's correct ;-)
See
http://lxr.linux.no/#linux+v2.6.32/include/linux/netdevice.h#L920
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:72:
> warning: initialization makes pointer from integer without a cast
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:
> In function ‘can_dev_store’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:102:
> warning: initialization makes pointer from integer without a cast
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:
> In function ‘can_btc_show’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:262:
> warning: initialization makes pointer from integer without a cast
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:
> In function ‘can_bt_show’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:302:
> warning: initialization makes pointer from integer without a cast
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:
> In function ‘can_bt_store’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:330:
> warning: initialization makes pointer from integer without a cast
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:
> In function ‘can_stat_show’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:445:
> warning: initialization makes pointer from integer without a cast
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:
> In function ‘can_create_sysfs’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:499:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:500:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:501:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:502:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:503:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:505:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:514:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:
> In function ‘can_remove_sysfs’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:525:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:526:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:527:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:528:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:529:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:531:
> error: ‘struct net_device’ has no member named ‘dev’
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.c:533:
> error: ‘struct net_device’ has no member named ‘dev’
> => I fixed this like this:
>
> #define CAN_CREATE_FILE(_dev, _name) \
> // if (device_create_file(&_dev->dev, &dev_attr_##_name)) \
> if (device_create_file(_dev->class_dev.dev, &dev_attr_##_name))
> \
> dev_err(ND2D(_dev), \
> "Couldn't create device file for ##_name\n")
>
> #define CAN_REMOVE_FILE(_dev, _name) \
> device_remove_file(_dev->class_dev.dev, &dev_attr_##_name)
> // device_remove_file(&_dev->dev->dev, &dev_attr_##_name)
>
>
> make[3]: ***
> [/data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sysfs.o]
> Error 1
> CC [M]
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/sja1000.o
> CC [M]
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/sja1000_platform.o
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/sja1000_platform.c:38:2:
> error: #error This driver does not support Kernel versions < 2.6.27
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/sja1000_platform.c:
> In function ‘sp_probe’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/sja1000_platform.c:78:
> warning: implicit declaration of function ‘resource_size’
> => easy to fix
>
> make[4]: ***
> [/data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/sja1000_platform.o]
> Error 1
> CC [M]
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/esd_pci.o
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/esd_pci.c:41:2:
> error: #error This driver does not support Kernel versions < 2.6.21
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/esd_pci.c:102:
> error: ‘PCI_VENDOR_ID_ESDGMBH’ undeclared here (not in a function)
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/esd_pci.c:107:
> error: ‘PCI_DEVICE_ID_PLX_9030’ undeclared here (not in a function)
> => easy to fix
>
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/esd_pci.c:
> In function ‘esd_pci_init_one’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/esd_pci.c:253:
> warning: comparison between pointer and integer
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/esd_pci.c:
> In function ‘esd_pci_remove_one’:
> /data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/esd_pci.c:291:
> warning: comparison between pointer and integer
> make[4]: ***
> [/data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000/esd_pci.o]
> Error 1
> make[4]: Target `__build' not remade because of errors.
> make[3]: ***
> [/data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can/sja1000]
> Error 2
> make[3]: Target `__build' not remade because of errors.
> make[2]: ***
> [/data/home/matthias/svn/socketcan/trunk/kernel/2.6/drivers/net/can] Error 2
> CC [M] /data/home/matthias/svn/socketcan/trunk/kernel/2.6/net/can/raw.o
> CC [M] /data/home/matthias/svn/socketcan/trunk/kernel/2.6/net/can/af_can.o
> CC [M] /data/home/matthias/svn/socketcan/trunk/kernel/2.6/net/can/proc.o
> LD [M] /data/home/matthias/svn/socketcan/trunk/kernel/2.6/net/can/can.o
> LD [M] /data/home/matthias/svn/socketcan/trunk/kernel/2.6/net/can/can-raw.o
> make[2]: Target `__build' not remade because of errors.
> make[1]: *** [_module_/data/home/matthias/svn/socketcan/trunk/kernel/2.6]
> Error 2
> make[1]: Target `modules' not remade because of errors.
> make[1]: Leaving directory `/usr/src/linux-2.6-2.6.18.dfsg.1'
> make: *** [modules] Error 2
> matth...@debby:~/svn/socketcan/trunk/kernel/2.6$
>
> So the main issues are some changes in the struct device, struct net_device
> structures.
>
>>> Are there some inofficial patches for that old kernels?
>> There might be support in the SVN trunk, depending on the drivers you
>> intend to use.
> Getting esd_pci driver running is our first goal. Later we need
> a USB driver running. This driver is currently under development
> an will be posted to the socketcan list in the next days.
>
> Do you think the above changes are correct?
Well, no, I now remember that I have done some porting for 2.6.18. Dig,
dig, dig... see attachment. It was for the old "netlink" branch, though.
Good luck.
Wolfgang.
---
kernel/2.6/drivers/net/can/dev.c | 2
kernel/2.6/drivers/net/can/sysfs.c | 249 ++++++++++++++++++++++++++++---------
2 files changed, 193 insertions(+), 58 deletions(-)
Index: netlink/kernel/2.6/drivers/net/can/dev.c
===================================================================
--- netlink.orig/kernel/2.6/drivers/net/can/dev.c
+++ netlink/kernel/2.6/drivers/net/can/dev.c
@@ -34,7 +34,7 @@
#include <socketcan/can/netlink.h>
#include <net/rtnetlink.h>
#else
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
#error "CAN sysfs interface not support by this kernel version"
#endif
#include "sysfs.h"
Index: netlink/kernel/2.6/drivers/net/can/sysfs.c
===================================================================
--- netlink.orig/kernel/2.6/drivers/net/can/sysfs.c
+++ netlink/kernel/2.6/drivers/net/can/sysfs.c
@@ -30,6 +30,18 @@
#include "sysfs.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+#define compat_device class_device
+#define COMPAT_DEVICE_ATTR CLASS_DEVICE_ATTR
+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
+#else
+#define COMPAT_DEVICE_ATTR DEVICE_ATTR
+#define compat_device device
+#ifndef to_net_dev
+#define to_net_dev(class) container_of(class, struct net_device, class_dev)
+#endif
+#endif
+
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)
int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
{
@@ -53,8 +65,6 @@ int strict_strtoul(const char *cp, unsig
}
#endif
-#ifdef CONFIG_SYSFS
-
/*
* SYSFS access functions and attributes. Use same locking as
* net/core/net-sysfs.c does.
@@ -65,10 +75,9 @@ static inline int dev_isalive(const stru
}
/* use same locking rules as GIF* ioctl's */
-static ssize_t can_dev_show(struct device *d, char *buf,
+static ssize_t can_dev_show(struct net_device *dev, char *buf,
ssize_t (*fmt)(struct net_device *, char *))
{
- struct net_device *dev = to_net_dev(d);
ssize_t ret = -EINVAL;
read_lock(&dev_base_lock);
@@ -80,24 +89,38 @@ static ssize_t can_dev_show(struct devic
}
/* generate a show function for simple field */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
#define CAN_DEV_SHOW(field, fmt_string) \
static ssize_t fmt_can_##field(struct net_device *dev, char *buf) \
{ \
struct can_priv *priv = netdev_priv(dev); \
return sprintf(buf, fmt_string, priv->field); \
} \
-static ssize_t show_can_##field(struct device *d, \
+static ssize_t show_can_##field(struct compat_device *d, \
+ char *buf) \
+{ \
+ return can_dev_show(to_net_dev(d), buf, fmt_can_##field); \
+}
+#else
+#define CAN_DEV_SHOW(field, fmt_string) \
+static ssize_t fmt_can_##field(struct net_device *dev, char *buf) \
+{ \
+ struct can_priv *priv = netdev_priv(dev); \
+ return sprintf(buf, fmt_string, priv->field); \
+} \
+static ssize_t show_can_##field(struct compat_device *d, \
struct device_attribute *attr, \
char *buf) \
{ \
- return can_dev_show(d, buf, fmt_can_##field); \
+ return can_dev_show(to_net_dev(d), buf, fmt_can_##field); \
}
+#endif
/* use same locking and permission rules as SIF* ioctl's */
-static ssize_t can_dev_store(struct device *d, const char *buf, size_t len,
- int (*set)(struct net_device *, unsigned long))
+static ssize_t can_dev_store(struct net_device *dev, const char *buf,
+ size_t len, int (*set)(struct net_device *,
+ unsigned long))
{
- struct net_device *dev = to_net_dev(d);
unsigned long new;
int ret = -EINVAL;
@@ -119,13 +142,24 @@ out:
return ret;
}
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+#define CAN_CREATE_FILE(_dev, _name) \
+ if (class_device_create_file(&_dev->class_dev, \
+ &class_device_attr_##_name)) \
+ dev_err(ND2D(_dev), \
+ "Couldn't create device file for ##_name\n")
+
+#define CAN_REMOVE_FILE(_dev, _name) \
+ class_device_remove_file(&_dev->class_dev, &class_device_attr_##_name)
+#else
#define CAN_CREATE_FILE(_dev, _name) \
if (device_create_file(&_dev->dev, &dev_attr_##_name)) \
dev_err(ND2D(_dev), \
"Couldn't create device file for ##_name\n")
#define CAN_REMOVE_FILE(_dev, _name) \
- device_remove_file(&_dev->dev, &dev_attr_##_name) \
+ device_remove_file(&_dev->dev, &dev_attr_##_name)
+#endif
CAN_DEV_SHOW(ctrlmode, "0x%x\n");
@@ -139,15 +173,17 @@ static int change_can_ctrlmode(struct ne
return 0;
}
-static ssize_t store_can_ctrlmode(struct device *dev,
+static ssize_t store_can_ctrlmode(struct compat_device *d,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
struct device_attribute *attr,
+#endif
const char *buf, size_t len)
{
- return can_dev_store(dev, buf, len, change_can_ctrlmode);
+ return can_dev_store(to_net_dev(d), buf, len, change_can_ctrlmode);
}
-static DEVICE_ATTR(can_ctrlmode, S_IRUGO | S_IWUSR,
- show_can_ctrlmode, store_can_ctrlmode);
+static COMPAT_DEVICE_ATTR(can_ctrlmode, S_IRUGO | S_IWUSR,
+ show_can_ctrlmode, store_can_ctrlmode);
static const char *can_state_names[] = {
"active", "bus-warn", "bus-pass" , "bus-off",
@@ -175,13 +211,16 @@ out:
return err;
}
-static ssize_t show_can_state(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t show_can_state(struct compat_device *d,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+ struct device_attribute *attr,
+#endif
+ char *buf)
{
- return can_dev_show(d, buf, printf_can_state);
+ return can_dev_show(to_net_dev(d), buf, printf_can_state);
}
-static DEVICE_ATTR(can_state, S_IRUGO, show_can_state, NULL);
+static COMPAT_DEVICE_ATTR(can_state, S_IRUGO, show_can_state, NULL);
CAN_DEV_SHOW(restart_ms, "%d\n");
@@ -197,14 +236,16 @@ static int change_can_restart_ms(struct
return 0;
}
-static ssize_t store_can_restart_ms(struct device *dev,
+static ssize_t store_can_restart_ms(struct compat_device *d,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
struct device_attribute *attr,
+#endif
const char *buf, size_t len)
{
- return can_dev_store(dev, buf, len, change_can_restart_ms);
+ return can_dev_store(to_net_dev(d), buf, len, change_can_restart_ms);
}
-static DEVICE_ATTR(can_restart_ms, S_IRUGO | S_IWUSR,
+static COMPAT_DEVICE_ATTR(can_restart_ms, S_IRUGO | S_IWUSR,
show_can_restart_ms, store_can_restart_ms);
static ssize_t printf_can_echo(struct net_device *dev, char *buf)
@@ -212,10 +253,13 @@ static ssize_t printf_can_echo(struct ne
return sprintf(buf, "%d\n", dev->flags & IFF_ECHO ? 1 : 0);
}
-static ssize_t show_can_echo(struct device *d,
- struct device_attribute *attr, char *buf)
+static ssize_t show_can_echo(struct compat_device *d,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
+ struct device_attribute *attr,
+#endif
+ char *buf)
{
- return can_dev_show(d, buf, printf_can_echo);
+ return can_dev_show(to_net_dev(d), buf, printf_can_echo);
}
static int change_can_echo(struct net_device *dev, unsigned long on)
@@ -227,34 +271,37 @@ static int change_can_echo(struct net_de
return 0;
}
-static ssize_t store_can_echo(struct device *dev,
+static ssize_t store_can_echo(struct compat_device *d,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
struct device_attribute *attr,
+#endif
const char *buf, size_t len)
{
- return can_dev_store(dev, buf, len, change_can_echo);
+ return can_dev_store(to_net_dev(d), buf, len, change_can_echo);
}
-static DEVICE_ATTR(can_echo, S_IRUGO | S_IWUSR, show_can_echo, store_can_echo);
+static COMPAT_DEVICE_ATTR(can_echo, S_IRUGO | S_IWUSR, show_can_echo, store_can_echo);
static int change_can_restart(struct net_device *dev, unsigned long on)
{
return can_restart_now(dev);
}
-static ssize_t store_can_restart(struct device *dev,
+static ssize_t store_can_restart(struct compat_device *d,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
struct device_attribute *attr,
+#endif
const char *buf, size_t len)
{
- return can_dev_store(dev, buf, len, change_can_restart);
+ return can_dev_store(to_net_dev(d), buf, len, change_can_restart);
}
-static DEVICE_ATTR(can_restart, S_IWUSR, NULL, store_can_restart);
+static COMPAT_DEVICE_ATTR(can_restart, S_IWUSR, NULL, store_can_restart);
/* Show a given attribute if the CAN bittiming group */
-static ssize_t can_btc_show(const struct device *d, char *buf,
+static ssize_t can_btc_show(struct net_device *dev, char *buf,
unsigned long offset)
{
- struct net_device *dev = to_net_dev(d);
struct can_priv *priv = netdev_priv(dev);
struct can_bittiming_const *btc = priv->bittiming_const;
ssize_t ret = -EINVAL;
@@ -272,14 +319,24 @@ static ssize_t can_btc_show(const struct
}
/* Generate a read-only bittiming const attribute */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+#define CAN_BT_CONST_ENTRY(name) \
+static ssize_t show_##name(struct compat_device *d, char *buf) \
+{ \
+ return can_btc_show(to_net_dev(d), buf, \
+ offsetof(struct can_bittiming_const, name));\
+} \
+static COMPAT_DEVICE_ATTR(hw_##name, S_IRUGO, show_##name, NULL)
+#else
#define CAN_BT_CONST_ENTRY(name) \
-static ssize_t show_##name(struct device *d, \
+static ssize_t show_##name(struct compat_device *d, \
struct device_attribute *attr, char *buf) \
{ \
- return can_btc_show(d, buf, \
+ return can_btc_show(to_net_dev(d), buf, \
offsetof(struct can_bittiming_const, name));\
} \
-static DEVICE_ATTR(hw_##name, S_IRUGO, show_##name, NULL)
+static COMPAT_DEVICE_ATTR(hw_##name, S_IRUGO, show_##name, NULL)
+#endif
CAN_BT_CONST_ENTRY(tseg1_min);
CAN_BT_CONST_ENTRY(tseg1_max);
@@ -290,10 +347,9 @@ CAN_BT_CONST_ENTRY(brp_min);
CAN_BT_CONST_ENTRY(brp_max);
CAN_BT_CONST_ENTRY(brp_inc);
-static ssize_t can_bt_show(const struct device *d, char *buf,
+static ssize_t can_bt_show(struct net_device *dev, char *buf,
unsigned long offset)
{
- struct net_device *dev = to_net_dev(d);
struct can_priv *priv = netdev_priv(dev);
struct can_bittiming *bt = &priv->bittiming;
ssize_t ret = -EINVAL;
@@ -316,10 +372,9 @@ static ssize_t can_bt_show(const struct
return ret;
}
-static ssize_t can_bt_store(const struct device *d, const char *buf,
+static ssize_t can_bt_store(struct net_device *dev, const char *buf,
size_t count, unsigned long offset)
{
- struct net_device *dev = to_net_dev(d);
struct can_priv *priv = netdev_priv(dev);
struct can_bittiming *bt = &priv->bittiming;
unsigned long new;
@@ -366,29 +421,47 @@ static ssize_t fmt_can_clock(struct net_
return sprintf(buf, "%d\n", priv->clock.freq);
}
-static ssize_t show_can_clock(struct device *d,
+static ssize_t show_can_clock(struct compat_device *d,
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)
struct device_attribute *attr,
+#endif
char *buf)
{
- return can_dev_show(d, buf, fmt_can_clock);
+ return can_dev_show(to_net_dev(d), buf, fmt_can_clock);
}
-static DEVICE_ATTR(hw_clock, S_IRUGO, show_can_clock, NULL);
+static COMPAT_DEVICE_ATTR(hw_clock, S_IRUGO, show_can_clock, NULL);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
#define CAN_BT_ENTRY(name) \
-static ssize_t show_##name(struct device *d, \
+static ssize_t show_##name(struct compat_device *d, char *buf) \
+{ \
+ return can_bt_show(to_net_dev(d), buf, \
+ offsetof(struct can_bittiming, name)); \
+} \
+static ssize_t store_##name(struct compat_device *d, \
+ const char *buf, size_t count) \
+{ \
+ return can_bt_store(to_net_dev(d), buf, count, \
+ offsetof(struct can_bittiming, name)); \
+} \
+static COMPAT_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
+#else
+#define CAN_BT_ENTRY(name) \
+static ssize_t show_##name(struct compat_device *d, \
struct device_attribute *attr, char *buf) \
{ \
- return can_bt_show(d, buf, \
+ return can_bt_show(to_net_dev(d), buf, \
offsetof(struct can_bittiming, name)); \
} \
-static ssize_t store_##name(struct device *d, \
+static ssize_t store_##name(struct compat_device *d, \
struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
- return can_bt_store(d, buf, count, \
+ return can_bt_store(to_net_dev(d), buf, count, \
offsetof(struct can_bittiming, name)); \
} \
-static DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
+static COMPAT_DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show_##name, store_##name)
+#endif
CAN_BT_ENTRY(bitrate);
CAN_BT_ENTRY(sample_point);
@@ -398,6 +471,34 @@ CAN_BT_ENTRY(phase_seg1);
CAN_BT_ENTRY(phase_seg2);
CAN_BT_ENTRY(sjw);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+static struct attribute *can_bittiming_attrs[] = {
+ &class_device_attr_hw_tseg1_min.attr,
+ &class_device_attr_hw_tseg1_max.attr,
+ &class_device_attr_hw_tseg2_max.attr,
+ &class_device_attr_hw_tseg2_min.attr,
+ &class_device_attr_hw_sjw_max.attr,
+ &class_device_attr_hw_brp_min.attr,
+ &class_device_attr_hw_brp_max.attr,
+ &class_device_attr_hw_brp_inc.attr,
+ &class_device_attr_hw_clock.attr,
+ &class_device_attr_bitrate.attr,
+ &class_device_attr_sample_point.attr,
+ &class_device_attr_tq.attr,
+ &class_device_attr_prop_seg.attr,
+ &class_device_attr_phase_seg1.attr,
+ &class_device_attr_phase_seg2.attr,
+ &class_device_attr_sjw.attr,
+ NULL
+};
+
+/* Minimal number of attributes to support intelligent CAN controllers */
+static struct attribute *can_bittiming_min_attrs[] = {
+ &class_device_attr_bitrate.attr,
+ NULL
+};
+
+#else
static struct attribute *can_bittiming_attrs[] = {
&dev_attr_hw_tseg1_min.attr,
&dev_attr_hw_tseg1_max.attr,
@@ -423,6 +524,7 @@ static struct attribute *can_bittiming_m
&dev_attr_bitrate.attr,
NULL
};
+#endif
static struct attribute_group can_bittiming_group = {
.name = "can_bittiming",
@@ -430,11 +532,9 @@ static struct attribute_group can_bittim
};
/* Show a given attribute in the CAN statistics group */
-static ssize_t can_stat_show(const struct device *d,
- struct device_attribute *attr, char *buf,
+static ssize_t can_stat_show(struct net_device *dev, char *buf,
unsigned long offset)
{
- struct net_device *dev = to_net_dev(d);
struct can_priv *priv = netdev_priv(dev);
struct can_device_stats *stats = &priv->can_stats;
ssize_t ret = -EINVAL;
@@ -452,14 +552,24 @@ static ssize_t can_stat_show(const struc
}
/* Generate a read-only CAN statistics attribute */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+#define CAN_STAT_ENTRY(name) \
+ static ssize_t show_##name(struct compat_device *d, char *buf) \
+{ \
+ return can_stat_show(to_net_dev(d), buf, \
+ offsetof(struct can_device_stats, name)); \
+} \
+static COMPAT_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+#else
#define CAN_STAT_ENTRY(name) \
-static ssize_t show_##name(struct device *d, \
+ static ssize_t show_##name(struct compat_device *d, \
struct device_attribute *attr, char *buf) \
{ \
- return can_stat_show(d, attr, buf, \
+ return can_stat_show(to_net_dev(d), attr, buf, \
offsetof(struct can_device_stats, name)); \
} \
-static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+static COMPAT_DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
+#endif
CAN_STAT_ENTRY(error_warning);
CAN_STAT_ENTRY(error_passive);
@@ -468,6 +578,17 @@ CAN_STAT_ENTRY(bus_error);
CAN_STAT_ENTRY(arbitration_lost);
CAN_STAT_ENTRY(restarts);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+static struct attribute *can_statistics_attrs[] = {
+ &class_device_attr_error_warning.attr,
+ &class_device_attr_error_passive.attr,
+ &class_device_attr_bus_off.attr,
+ &class_device_attr_bus_error.attr,
+ &class_device_attr_arbitration_lost.attr,
+ &class_device_attr_restarts.attr,
+ NULL
+};
+#else
static struct attribute *can_statistics_attrs[] = {
&dev_attr_error_warning.attr,
&dev_attr_error_passive.attr,
@@ -477,6 +598,7 @@ static struct attribute *can_statistics_
&dev_attr_restarts.attr,
NULL
};
+#endif
static struct attribute_group can_statistics_group = {
.name = "can_statistics",
@@ -494,8 +616,11 @@ void can_create_sysfs(struct net_device
CAN_CREATE_FILE(dev, can_state);
CAN_CREATE_FILE(dev, can_restart_ms);
- err = sysfs_create_group(&(dev->dev.kobj),
- &can_statistics_group);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+ err = sysfs_create_group(&dev->class_dev.kobj, &can_statistics_group);
+#else
+ err = sysfs_create_group(&(dev->dev.kobj), &can_statistics_group);
+#endif
if (err) {
printk(KERN_EMERG
"couldn't create sysfs group for CAN statistics\n");
@@ -503,7 +628,11 @@ void can_create_sysfs(struct net_device
if (!priv->bittiming_const)
can_bittiming_group.attrs = can_bittiming_min_attrs;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+ err = sysfs_create_group(&dev->class_dev.kobj, &can_bittiming_group);
+#else
err = sysfs_create_group(&(dev->dev.kobj), &can_bittiming_group);
+#endif
if (err) {
printk(KERN_EMERG "couldn't create sysfs "
"group for CAN bittiming\n");
@@ -520,12 +649,18 @@ void can_remove_sysfs(struct net_device
CAN_REMOVE_FILE(dev, can_restart);
CAN_REMOVE_FILE(dev, can_restart_ms);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+ sysfs_remove_group(&dev->class_dev.kobj, &can_statistics_group);
+#else
sysfs_remove_group(&(dev->dev.kobj), &can_statistics_group);
+#endif
if (priv->bittiming_const)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)
+ sysfs_remove_group(&dev->class_dev.kobj, &can_bittiming_group);
+#else
sysfs_remove_group(&(dev->dev.kobj), &can_bittiming_group);
+#endif
}
-#endif /* CONFIG_SYSFS */
-
_______________________________________________
Socketcan-core mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/socketcan-core