| #ifndef LINUX_3_0_COMPAT_H |
| #define LINUX_3_0_COMPAT_H |
| |
| #include <linux/version.h> |
| |
| #if (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) |
| |
| #include <linux/rcupdate.h> |
| |
| /* |
| * since commit 1c5cae815d19ffe02bdfda1260949ef2b1806171 |
| * "net: call dev_alloc_name from register_netdevice" dev_alloc_name is |
| * called automatically. This is not implemented in older kernel |
| * versions so it will result in device wrong names. |
| */ |
| static inline int register_netdevice_name(struct net_device *dev) |
| { |
| int err; |
| |
| if (strchr(dev->name, '%')) { |
| err = dev_alloc_name(dev, dev->name); |
| if (err < 0) |
| return err; |
| } |
| |
| return register_netdevice(dev); |
| } |
| |
| #define register_netdevice(dev) register_netdevice_name(dev) |
| |
| /* BCMA core, see drivers/bcma/ */ |
| #ifndef BCMA_CORE |
| /* Broadcom's specific AMBA core, see drivers/bcma/ */ |
| struct bcma_device_id { |
| __u16 manuf; |
| __u16 id; |
| __u8 rev; |
| __u8 class; |
| }; |
| #define BCMA_CORE(_manuf, _id, _rev, _class) \ |
| { .manuf = _manuf, .id = _id, .rev = _rev, .class = _class, } |
| #define BCMA_CORETABLE_END \ |
| { 0, }, |
| |
| #define BCMA_ANY_MANUF 0xFFFF |
| #define BCMA_ANY_ID 0xFFFF |
| #define BCMA_ANY_REV 0xFF |
| #define BCMA_ANY_CLASS 0xFF |
| #endif /* BCMA_CORE */ |
| |
| int mac_pton(const char *s, u8 *mac); |
| |
| int __must_check kstrtoull_from_user(const char __user *s, size_t count, unsigned int base, unsigned long long *res); |
| int __must_check kstrtoll_from_user(const char __user *s, size_t count, unsigned int base, long long *res); |
| int __must_check kstrtoul_from_user(const char __user *s, size_t count, unsigned int base, unsigned long *res); |
| int __must_check kstrtol_from_user(const char __user *s, size_t count, unsigned int base, long *res); |
| int __must_check kstrtouint_from_user(const char __user *s, size_t count, unsigned int base, unsigned int *res); |
| int __must_check kstrtoint_from_user(const char __user *s, size_t count, unsigned int base, int *res); |
| int __must_check kstrtou16_from_user(const char __user *s, size_t count, unsigned int base, u16 *res); |
| int __must_check kstrtos16_from_user(const char __user *s, size_t count, unsigned int base, s16 *res); |
| int __must_check kstrtou8_from_user(const char __user *s, size_t count, unsigned int base, u8 *res); |
| int __must_check kstrtos8_from_user(const char __user *s, size_t count, unsigned int base, s8 *res); |
| |
| static inline int __must_check kstrtou64_from_user(const char __user *s, size_t count, unsigned int base, u64 *res) |
| { |
| return kstrtoull_from_user(s, count, base, res); |
| } |
| |
| static inline int __must_check kstrtos64_from_user(const char __user *s, size_t count, unsigned int base, s64 *res) |
| { |
| return kstrtoll_from_user(s, count, base, res); |
| } |
| |
| static inline int __must_check kstrtou32_from_user(const char __user *s, size_t count, unsigned int base, u32 *res) |
| { |
| return kstrtouint_from_user(s, count, base, res); |
| } |
| |
| static inline int __must_check kstrtos32_from_user(const char __user *s, size_t count, unsigned int base, s32 *res) |
| { |
| return kstrtoint_from_user(s, count, base, res); |
| } |
| |
| /* |
| * This adds a nested function everywhere kfree_rcu() was called. This |
| * function frees the memory and is given as a function to call_rcu(). |
| * The rcu callback could happen every time also after the module was |
| * unloaded and this will cause problems. |
| */ |
| #define kfree_rcu(data, rcuhead) do { \ |
| void __kfree_rcu_fn(struct rcu_head *rcu_head) \ |
| { \ |
| void *___ptr; \ |
| ___ptr = container_of(rcu_head, typeof(*(data)), rcuhead);\ |
| kfree(___ptr); \ |
| } \ |
| call_rcu(&(data)->rcuhead, __kfree_rcu_fn); \ |
| } while (0) |
| |
| #ifdef MODULE |
| |
| /* |
| * The define overwriting module_exit is based on the original module_exit |
| * which looks like this: |
| * #define module_exit(exitfn) \ |
| * static inline exitcall_t __exittest(void) \ |
| * { return exitfn; } \ |
| * void cleanup_module(void) __attribute__((alias(#exitfn))); |
| * |
| * We replaced the call to the actual function exitfn() with a call to our |
| * function which calls the original exitfn() and then rcu_barrier() |
| * |
| * As a module will not be unloaded that ofter it should not have a big |
| * performance impact when rcu_barrier() is called on every module exit, |
| * also when no kfree_rcu() backport is used in that module. |
| */ |
| #undef module_exit |
| #define module_exit(exitfn) \ |
| static void __exit __exit_compat(void) \ |
| { \ |
| exitfn(); \ |
| rcu_barrier(); \ |
| } \ |
| void cleanup_module(void) __attribute__((alias("__exit_compat"))); |
| |
| #endif |
| |
| #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)) */ |
| |
| #endif /* LINUX_3_0_COMPAT_H */ |