Made sysfs attribute code compatible with earlier kernels.
authorIan Abbott <abbotti@mev.co.uk>
Tue, 2 Jun 2009 18:57:14 +0000 (18:57 +0000)
committerIan Abbott <abbotti@mev.co.uk>
Tue, 2 Jun 2009 18:57:14 +0000 (18:57 +0000)
comedi/comedi_fops.c
include/linux/comedidev.h
include/linux/device.h

index bc0549a42d7884f677ee277759ca1601aa1d1ce1..19295728370fe692aaaf792a6453317f78051cae 100644 (file)
@@ -95,11 +95,55 @@ static int is_device_busy(comedi_device * dev);
 static int resize_async_buffer(comedi_device *dev,
        comedi_subdevice *s, comedi_async *async, unsigned new_size);
 
-//declarations for sysfs attribute files
-struct device_attribute dev_attr_max_read_buffer_kb;
-struct device_attribute dev_attr_read_buffer_kb;
-struct device_attribute dev_attr_max_write_buffer_kb;
-struct device_attribute dev_attr_write_buffer_kb;
+// sysfs attribute files
+
+static COMEDI_DECLARE_ATTR_SHOW(show_max_read_buffer_kb, dev, buf);
+static COMEDI_DECLARE_ATTR_STORE(store_max_read_buffer_kb, dev, buf, count);
+static comedi_device_attribute_t dev_attr_max_read_buffer_kb =
+{
+       .attr = {
+                       .name = "max_read_buffer_kb",
+                       .mode = S_IRUGO | S_IWUSR
+               },
+       .show = &show_max_read_buffer_kb,
+       .store = &store_max_read_buffer_kb
+};
+
+static COMEDI_DECLARE_ATTR_SHOW(show_read_buffer_kb, dev, buf);
+static COMEDI_DECLARE_ATTR_STORE(store_read_buffer_kb, dev, buf, count);
+static comedi_device_attribute_t dev_attr_read_buffer_kb =
+{
+       .attr = {
+                       .name = "read_buffer_kb",
+                       .mode = S_IRUGO | S_IWUSR | S_IWGRP
+               },
+       .show = &show_read_buffer_kb,
+       .store = &store_read_buffer_kb
+};
+
+static COMEDI_DECLARE_ATTR_SHOW(show_max_write_buffer_kb, dev, buf);
+static COMEDI_DECLARE_ATTR_STORE(store_max_write_buffer_kb, dev, buf, count);
+static comedi_device_attribute_t dev_attr_max_write_buffer_kb =
+{
+       .attr = {
+                       .name = "max_write_buffer_kb",
+                       .mode = S_IRUGO | S_IWUSR
+               },
+       .show = &show_max_write_buffer_kb,
+       .store = &store_max_write_buffer_kb
+};
+
+static COMEDI_DECLARE_ATTR_SHOW(show_write_buffer_kb, dev, buf);
+static COMEDI_DECLARE_ATTR_STORE(store_write_buffer_kb, dev, buf, count);
+static comedi_device_attribute_t dev_attr_write_buffer_kb =
+{
+       .attr = {
+                       .name = "write_buffer_kb",
+                       .mode = S_IRUGO | S_IWUSR | S_IWGRP
+               },
+       .show = &show_write_buffer_kb,
+       .store = &store_write_buffer_kb
+};
 
 #ifdef HAVE_UNLOCKED_IOCTL
 static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
@@ -2105,7 +2149,7 @@ int comedi_alloc_board_minor(struct device *hardware_device)
 {
        unsigned long flags;
        struct comedi_device_file_info *info;
-       device_create_result_type *csdev;
+       comedi_device_create_t *csdev;
        unsigned i;
        int retval;
 
@@ -2142,29 +2186,29 @@ int comedi_alloc_board_minor(struct device *hardware_device)
        if(!IS_ERR(csdev)) {
                info->device->class_dev = csdev;
        }
-       dev_set_drvdata(csdev, info);
-       retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb);
+       COMEDI_DEV_SET_DRVDATA(csdev, info);
+       retval = COMEDI_DEVICE_CREATE_FILE(csdev, &dev_attr_max_read_buffer_kb);
        if(retval)
        {
                printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n", dev_attr_max_read_buffer_kb.attr.name);
                comedi_free_board_minor(i);
                return retval;
        }
-       retval = device_create_file(csdev, &dev_attr_read_buffer_kb);
+       retval = COMEDI_DEVICE_CREATE_FILE(csdev, &dev_attr_read_buffer_kb);
        if(retval)
        {
                printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n", dev_attr_read_buffer_kb.attr.name);
                comedi_free_board_minor(i);
                return retval;
        }
-       retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb);
+       retval = COMEDI_DEVICE_CREATE_FILE(csdev, &dev_attr_max_write_buffer_kb);
        if(retval)
        {
                printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n", dev_attr_max_write_buffer_kb.attr.name);
                comedi_free_board_minor(i);
                return retval;
        }
-       retval = device_create_file(csdev, &dev_attr_write_buffer_kb);
+       retval = COMEDI_DEVICE_CREATE_FILE(csdev, &dev_attr_write_buffer_kb);
        if(retval)
        {
                printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n", dev_attr_write_buffer_kb.attr.name);
@@ -2192,7 +2236,8 @@ void comedi_free_board_minor(unsigned minor)
                {
                        if(dev->class_dev)
                        {
-                               device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, dev->minor));
+                               COMEDI_DEVICE_DESTROY(comedi_class,
+                                       MKDEV(COMEDI_MAJOR, dev->minor));
                        }
                        comedi_device_cleanup(dev);
                        kfree(dev);
@@ -2205,7 +2250,7 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
 {
        unsigned long flags;
        struct comedi_device_file_info *info;
-       device_create_result_type *csdev;
+       comedi_device_create_t *csdev;
        unsigned i;
        int retval;
 
@@ -2237,29 +2282,29 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
        {
                s->class_dev = csdev;
        }
-       dev_set_drvdata(csdev, info);
-       retval = device_create_file(csdev, &dev_attr_max_read_buffer_kb);
+       COMEDI_DEV_SET_DRVDATA(csdev, info);
+       retval = COMEDI_DEVICE_CREATE_FILE(csdev, &dev_attr_max_read_buffer_kb);
        if(retval)
        {
                printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n", dev_attr_max_read_buffer_kb.attr.name);
                comedi_free_subdevice_minor(s);
                return retval;
        }
-       retval = device_create_file(csdev, &dev_attr_read_buffer_kb);
+       retval = COMEDI_DEVICE_CREATE_FILE(csdev, &dev_attr_read_buffer_kb);
        if(retval)
        {
                printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n", dev_attr_read_buffer_kb.attr.name);
                comedi_free_subdevice_minor(s);
                return retval;
        }
-       retval = device_create_file(csdev, &dev_attr_max_write_buffer_kb);
+       retval = COMEDI_DEVICE_CREATE_FILE(csdev, &dev_attr_max_write_buffer_kb);
        if(retval)
        {
                printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n", dev_attr_max_write_buffer_kb.attr.name);
                comedi_free_subdevice_minor(s);
                return retval;
        }
-       retval = device_create_file(csdev, &dev_attr_write_buffer_kb);
+       retval = COMEDI_DEVICE_CREATE_FILE(csdev, &dev_attr_write_buffer_kb);
        if(retval)
        {
                printk(KERN_ERR "comedi: failed to create sysfs attribute file \"%s\".\n", dev_attr_write_buffer_kb.attr.name);
@@ -2287,7 +2332,8 @@ void comedi_free_subdevice_minor(comedi_subdevice *s)
 
        if(s->class_dev)
        {
-               device_destroy(comedi_class, MKDEV(COMEDI_MAJOR, s->minor));
+               COMEDI_DEVICE_DESTROY(comedi_class,
+                       MKDEV(COMEDI_MAJOR, s->minor));
                s->class_dev = NULL;
        }
        kfree(info);
@@ -2344,15 +2390,14 @@ static int resize_async_buffer(comedi_device *dev,
        return 0;
 }
 
-// sysfs attribute files
+// sysfs attribute file functions
 
 static const unsigned bytes_per_kibi = 1024;
 
-ssize_t show_max_read_buffer_kb(struct device *dev,
-       struct device_attribute *attr, char *buf)
+static COMEDI_DECLARE_ATTR_SHOW(show_max_read_buffer_kb, dev, buf)
 {
        ssize_t retval;
-       struct comedi_device_file_info *info = dev_get_drvdata(dev);
+       struct comedi_device_file_info *info = COMEDI_DEV_GET_DRVDATA(dev);
        unsigned max_buffer_size_kb = 0;
        comedi_subdevice * const read_subdevice = comedi_get_read_subdevice(info);
 
@@ -2369,10 +2414,9 @@ ssize_t show_max_read_buffer_kb(struct device *dev,
        return retval;
 }
 
-ssize_t store_max_read_buffer_kb(struct device *dev, struct device_attribute *attr,
-       const char *buf, size_t count)
+static COMEDI_DECLARE_ATTR_STORE(store_max_read_buffer_kb, dev, buf, count)
 {
-       struct comedi_device_file_info *info = dev_get_drvdata(dev);
+       struct comedi_device_file_info *info = COMEDI_DEV_GET_DRVDATA(dev);
        unsigned long new_max_size_kb;
        uint64_t new_max_size;
        comedi_subdevice * const read_subdevice = comedi_get_read_subdevice(info);
@@ -2399,21 +2443,10 @@ ssize_t store_max_read_buffer_kb(struct device *dev, struct device_attribute *at
        return count;
 }
 
-struct device_attribute dev_attr_max_read_buffer_kb =
-{
-       .attr = {
-                       .name = "max_read_buffer_kb",
-                       .mode = S_IRUGO | S_IWUSR
-               },
-       .show = &show_max_read_buffer_kb,
-       .store = &store_max_read_buffer_kb
-};
-
-ssize_t show_read_buffer_kb(struct device *dev,
-       struct device_attribute *attr, char *buf)
+static COMEDI_DECLARE_ATTR_SHOW(show_read_buffer_kb, dev, buf)
 {
        ssize_t retval;
-       struct comedi_device_file_info *info = dev_get_drvdata(dev);
+       struct comedi_device_file_info *info = COMEDI_DEV_GET_DRVDATA(dev);
        unsigned buffer_size_kb = 0;
        comedi_subdevice * const read_subdevice = comedi_get_read_subdevice(info);
 
@@ -2430,10 +2463,9 @@ ssize_t show_read_buffer_kb(struct device *dev,
        return retval;
 }
 
-ssize_t store_read_buffer_kb(struct device *dev, struct device_attribute *attr,
-       const char *buf, size_t count)
+static COMEDI_DECLARE_ATTR_STORE(store_read_buffer_kb, dev, buf, count)
 {
-       struct comedi_device_file_info *info = dev_get_drvdata(dev);
+       struct comedi_device_file_info *info = COMEDI_DEV_GET_DRVDATA(dev);
        unsigned long new_size_kb;
        uint64_t new_size;
        int retval;
@@ -2463,21 +2495,10 @@ ssize_t store_read_buffer_kb(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-struct device_attribute dev_attr_read_buffer_kb =
-{
-       .attr = {
-                       .name = "read_buffer_kb",
-                       .mode = S_IRUGO | S_IWUSR | S_IWGRP
-               },
-       .show = &show_read_buffer_kb,
-       .store = &store_read_buffer_kb
-};
-
-ssize_t show_max_write_buffer_kb(struct device *dev,
-       struct device_attribute *attr, char *buf)
+static COMEDI_DECLARE_ATTR_SHOW(show_max_write_buffer_kb, dev, buf)
 {
        ssize_t retval;
-       struct comedi_device_file_info *info = dev_get_drvdata(dev);
+       struct comedi_device_file_info *info = COMEDI_DEV_GET_DRVDATA(dev);
        unsigned max_buffer_size_kb = 0;
        comedi_subdevice * const write_subdevice = comedi_get_write_subdevice(info);
 
@@ -2494,10 +2515,9 @@ ssize_t show_max_write_buffer_kb(struct device *dev,
        return retval;
 }
 
-ssize_t store_max_write_buffer_kb(struct device *dev, struct device_attribute *attr,
-       const char *buf, size_t count)
+static COMEDI_DECLARE_ATTR_STORE(store_max_write_buffer_kb, dev, buf, count)
 {
-       struct comedi_device_file_info *info = dev_get_drvdata(dev);
+       struct comedi_device_file_info *info = COMEDI_DEV_GET_DRVDATA(dev);
        unsigned long new_max_size_kb;
        uint64_t new_max_size;
        comedi_subdevice * const write_subdevice = comedi_get_write_subdevice(info);
@@ -2524,21 +2544,10 @@ ssize_t store_max_write_buffer_kb(struct device *dev, struct device_attribute *a
        return count;
 }
 
-struct device_attribute dev_attr_max_write_buffer_kb =
-{
-       .attr = {
-                       .name = "max_write_buffer_kb",
-                       .mode = S_IRUGO | S_IWUSR
-               },
-       .show = &show_max_write_buffer_kb,
-       .store = &store_max_write_buffer_kb
-};
-
-ssize_t show_write_buffer_kb(struct device *dev,
-       struct device_attribute *attr, char *buf)
+static COMEDI_DECLARE_ATTR_SHOW(show_write_buffer_kb, dev, buf)
 {
        ssize_t retval;
-       struct comedi_device_file_info *info = dev_get_drvdata(dev);
+       struct comedi_device_file_info *info = COMEDI_DEV_GET_DRVDATA(dev);
        unsigned buffer_size_kb = 0;
        comedi_subdevice * const write_subdevice = comedi_get_write_subdevice(info);
 
@@ -2555,10 +2564,9 @@ ssize_t show_write_buffer_kb(struct device *dev,
        return retval;
 }
 
-ssize_t store_write_buffer_kb(struct device *dev, struct device_attribute *attr,
-       const char *buf, size_t count)
+static COMEDI_DECLARE_ATTR_STORE(store_write_buffer_kb, dev, buf, count)
 {
-       struct comedi_device_file_info *info = dev_get_drvdata(dev);
+       struct comedi_device_file_info *info = COMEDI_DEV_GET_DRVDATA(dev);
        unsigned long new_size_kb;
        uint64_t new_size;
        int retval;
@@ -2587,13 +2595,3 @@ ssize_t store_write_buffer_kb(struct device *dev, struct device_attribute *attr,
        if(retval < 0) return retval;
        return count;
 }
-
-struct device_attribute dev_attr_write_buffer_kb =
-{
-       .attr = {
-                       .name = "write_buffer_kb",
-                       .mode = S_IRUGO | S_IWUSR | S_IWGRP
-               },
-       .show = &show_write_buffer_kb,
-       .store = &store_write_buffer_kb
-};
index 74d6cb4e4a1616baf972a3ede585a469edab5826..b8db13805c9dabd48fc2b14df2e74571bf831519 100644 (file)
@@ -187,7 +187,7 @@ struct comedi_subdevice_struct {
 
        unsigned int state;
 
-       device_create_result_type *class_dev;
+       comedi_device_create_t *class_dev;
        int minor;
 };
 
@@ -260,7 +260,7 @@ struct comedi_device_struct {
        comedi_driver *driver;
        void *private;
 
-       device_create_result_type *class_dev;
+       comedi_device_create_t *class_dev;
        int minor;
        /* hw_dev is passed to dma_alloc_coherent when allocating async buffers for subdevices
           that have async_dma_dir set to something other than DMA_NONE */
index cf71c80f33f42c6035ef5aa662b27a18352476e8..327dc633a8b04d38b5a74932910ccd07f5e5a4e6 100644 (file)
 /*
  * Notes:
  *
- * The 'struct device *' returned by the device_create() compatibility
- * functions (assuming the return value is not an error pointer for which
- * 'IS_ERR(ptr)' is true) is not really a 'struct device *' and should not
- * be treated as such.  For kernel versions 2.5.0 to 2.6.17, the return
- * value is actually a 'struct class_device *' in disguise and we assume
- * the 'parent' parameter of device_create() is also a 'struct class_device *'
- * in disguise from a previous call to device_create().
+ * Call COMEDI_DEVICE_CREATE() instead of device_create() for compatibility
+ * with kernel versions prior to 2.6.27.  This returns a PTR_ERR() value or a
+ * 'comedi_device_create_t *' which will be a 'struct class_device *' for
+ * kernel versions prior to 2.6.19, and a 'struct device *' for kernel version
+ * 2.6.19 onwards.  Call COMEDI_DEVICE_DESTROY() to destroy it.
  *
- * The main limitation is that we cannot use a *real* 'struct device *' as
- * the parent parameter of device_create(), only a pointer from a previous
- * call to device_create().
+ * The result of COMEDI_DEVICE_CREATE() can be used to set or get a private
+ * data pointer, using COMEDI_DEV_SET_DRVDATA() and COMEDI_DEV_GET_DRVDATA().
  *
- * Call COMEDI_DEVICE_CREATE() instead of device_create() for compatibility
- * with kernel versions prior to 2.6.27.
+ * The result of COMEDI_DEVICE_CREATE() can be used to create or remove
+ * sysfs attributes, using COMEDI_DECLARE_ATTR_SHOW() to declare the "show
+ * attribute" function, COMEDI_DECLARE_ATTR_STORE() macro to declare the
+ * "store attribute" function, COMEDI_DEVICE_CREATE_FILE() to create the
+ * attribute, and COMEDI_DEVICE_REMOVE_FILE() to remove it.
+ *
+ * The 'drvdata' parameter of COMEDI_DEVICE_CREATE() doesn't work for kernel
+ * versions prior to 2.6.26, so please don't use it!
  *
- * We do not currently support 'dev_get_drvdata()' and 'dev_set_drvdata()'
- * for kernel versions prior to 2.6.26, so the 'drvdata' parameter of
- * COMEDI_DEVICE_CREATE() is pretty useless.
+ *
+ * None of the above is currently supported for 2.4 kernels!
  */
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
@@ -81,6 +83,21 @@ static inline void device_destroy(struct class *cs, dev_t devt)
 
 #include_next <linux/device.h>
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+
+/* Use 'struct class_device' before kernel 2.6.19. */
+
+typedef struct class_device comedi_device_create_t;
+typedef struct class_device_attribute comedi_device_attribute_t;
+#define COMEDI_DEV_SET_DRVDATA(csdev, data)    class_set_devdata(csdev, data)
+#define COMEDI_DEV_GET_DRVDATA(csdev)          class_get_devdata(csdev)
+#define COMEDI_DEVICE_CREATE_FILE(csdev, attr) class_device_create_file(csdev, attr)
+#define COMEDI_DEVICE_REMOVE_FILE(csdev, attr) class_device_remove_file(csdev, attr)
+#define COMEDI_DECLARE_ATTR_SHOW(func, dev, buf) \
+ssize_t func(struct class_device *dev, char *buf)
+#define COMEDI_DECLARE_ATTR_STORE(func, dev, buf, count) \
+ssize_t func(struct class_device *dev, const char *buf, size_t count)
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
 
 #define class_create(owner, name) \
@@ -88,65 +105,76 @@ static inline void device_destroy(struct class *cs, dev_t devt)
 #define class_destroy(cs) \
        class_simple_destroy((struct class_simple *)(cs))
 
-typedef struct class_device device_create_result_type;
 #define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
        class_simple_device_add((struct class_simple *)(cs), \
                devt, device, fmt)
-#define device_destroy(cs, devt) \
+#define COMEDI_DEVICE_DESTROY(cs, devt) \
        class_simple_device_remove(devt)
 
 #else
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
 
-typedef struct class_device device_create_result_type;
 #define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
        class_device_create(cs, devt, device, fmt)
-#define device_destroy(cs, devt) \
+#define COMEDI_DEVICE_DESTROY(cs, devt) \
        class_device_destroy(cs, devt)
 
 #else
-/* device_create does not work for NULL parent with 2.6.18, not sure
-exactly which kernel version it was fixed in. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
 
-typedef struct class_device device_create_result_type;
 #define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
-       class_device_create( \
-                       cs, parent, devt, device, fmt)
-#define device_destroy(cs, devt) \
+       class_device_create(cs, parent, devt, device, fmt)
+#define COMEDI_DEVICE_DESTROY(cs, devt) \
        class_device_destroy(cs, devt)
 
+#endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+
+#endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
+
 #else
 
+/* Use 'struct device' from kernel 2.6.19 onwards. */
+
+typedef struct device comedi_device_create_t;
+typedef struct device_attribute comedi_device_attribute_t;
+#define COMEDI_DEV_SET_DRVDATA(csdev, data)    dev_set_drvdata(csdev, data)
+#define COMEDI_DEV_GET_DRVDATA(csdev)          dev_get_drvdata(csdev)
+#define COMEDI_DEVICE_CREATE_FILE(csdev, attr) device_create_file(csdev, attr)
+#define COMEDI_DEVICE_REMOVE_FILE(csdev, attr) device_remove_file(csdev, attr)
+#define COMEDI_DECLARE_ATTR_SHOW(func, dev, buf) \
+ssize_t func(struct device *dev, struct device_attribute *_attr, char *buf)
+#define COMEDI_DECLARE_ATTR_STORE(func, dev, buf, count) \
+ssize_t func(struct device *dev, struct device_attribute *_attr, \
+       const char *buf, size_t count)
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
 
-typedef struct device device_create_result_type;
 #define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
        device_create(cs, ((parent) ? (parent) : (device)), devt, fmt)
+#define COMEDI_DEVICE_DESTROY(cs, devt) \
+       device_destroy(cs, devt)
 
 #else
 
-typedef struct device device_create_result_type;
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
 
 #define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
        device_create_drvdata(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt)
+#define COMEDI_DEVICE_DESTROY(cs, devt) \
+       device_destroy(cs, devt)
 
 #else
 
 #define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
        device_create(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt)
+#define COMEDI_DEVICE_DESTROY(cs, devt) \
+       device_destroy(cs, devt)
 
 #endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)
 
 #endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)
 
-#endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
-
-#endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
-
-#endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,6,13)
+#endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
 
 #endif // LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)