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

Reply via email to