From: Luis R. Rodriguez Date: Thu, 10 Dec 2009 21:38:29 +0000 (-0800) Subject: Rearrange module order for easy placement on external builds X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=ca2d92df5649c3233ccf5bb3f92d621e461728db;p=~aditr%2Fcompat.git Rearrange module order for easy placement on external builds You will typically cp -a compat/ to your own build and then cp include/linux/*.h to your own header space on your build as well. Provided on this Makefile is also a hack to let you use include/linux without having to add or mucking the user's header files or directory. Example compat autoconf is also provided. Signed-off-by: Luis R. Rodriguez --- diff --git a/Makefile b/Makefile index d2c08d1..0433a14 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,8 @@ export KLIB_BUILD ?= $(KLIB)/build export PWD := $(shell pwd) +# This generates a bunch of CONFIG_COMPAT_KERNEL_22 CONFIG_COMPAT_KERNEL_23 .. etc for +# each kernel release you need an object for. ifneq ($(wildcard $(KLIB_BUILD)/Makefile),) COMPAT_LATEST_VERSION = 32 KERNEL_SUBLEVEL := $(shell $(MAKE) -C $(KLIB_BUILD) kernelversion | sed -n 's/^2\.6\.\([0-9]\+\).*/\1/p') @@ -16,27 +18,12 @@ COMPAT_VERSIONS := $(shell I=$(COMPAT_LATEST_VERSION); while [ "$$I" -gt $(KERNE $(foreach ver,$(COMPAT_VERSIONS),$(eval CONFIG_COMPAT_KERNEL_$(ver)=y)) endif -obj-m += compat.o -#compat-objs := +obj-y += compat/ -compat-y += main.o - -# Compat kernel compatibility code -compat-$(CONFIG_COMPAT_KERNEL_14) += compat-2.6.14.o -compat-$(CONFIG_COMPAT_KERNEL_18) += compat-2.6.18.o -compat-$(CONFIG_COMPAT_KERNEL_19) += compat-2.6.19.o -compat-$(CONFIG_COMPAT_KERNEL_21) += compat-2.6.21.o -compat-$(CONFIG_COMPAT_KERNEL_22) += compat-2.6.22.o -compat-$(CONFIG_COMPAT_KERNEL_23) += compat-2.6.23.o -compat-$(CONFIG_COMPAT_KERNEL_24) += compat-2.6.24.o -compat-$(CONFIG_COMPAT_KERNEL_25) += compat-2.6.25.o -compat-$(CONFIG_COMPAT_KERNEL_26) += compat-2.6.26.o -compat-$(CONFIG_COMPAT_KERNEL_27) += compat-2.6.27.o -compat-$(CONFIG_COMPAT_KERNEL_28) += compat-2.6.28.o -compat-$(CONFIG_COMPAT_KERNEL_29) += compat-2.6.29.o -compat-$(CONFIG_COMPAT_KERNEL_30) += compat-2.6.30.o -compat-$(CONFIG_COMPAT_KERNEL_31) += compat-2.6.31.o -compat-$(CONFIG_COMPAT_KERNEL_32) += compat-2.6.32.o +# This hack lets us put our include path first than the kernel's +# when building our compat modules. Your own makefile would look +# the same. +NOSTDINC_FLAGS := -I$(M)/include/ -include $(M)/include/linux/compat.h $(CFLAGS) modules: $(MAKE) -C $(KLIB_BUILD) M=$(PWD) modules diff --git a/compat-2.6.14.c b/compat-2.6.14.c deleted file mode 100644 index e0af181..0000000 --- a/compat-2.6.14.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.14. - */ - -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) - -/* 2.6.14 compat code goes here */ - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) */ - diff --git a/compat-2.6.14.h b/compat-2.6.14.h deleted file mode 100644 index 22e7e31..0000000 --- a/compat-2.6.14.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LINUX_26_14_COMPAT_H -#define LINUX_26_14_COMPAT_H - -#include -#include - -/* Compat work for 2.6.14 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) - -typedef unsigned int gfp_t; - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) */ - -#endif /* LINUX_26_14_COMPAT_H */ diff --git a/compat-2.6.18.c b/compat-2.6.18.c deleted file mode 100644 index c7fb2e4..0000000 --- a/compat-2.6.18.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.18. - */ - -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) - -/* 2.6.18 compat code goes here */ - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */ - diff --git a/compat-2.6.18.h b/compat-2.6.18.h deleted file mode 100644 index 3245c42..0000000 --- a/compat-2.6.18.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LINUX_26_18_COMPAT_H -#define LINUX_26_18_COMPAT_H - -#include -#include - -/* Compat work for 2.6.18 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) - -#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) */ - -#endif /* LINUX_26_18_COMPAT_H */ diff --git a/compat-2.6.19.c b/compat-2.6.19.c deleted file mode 100644 index fc75b64..0000000 --- a/compat-2.6.19.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.19. - */ - -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) - -/* 2.6.19 compat code goes here */ - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */ - diff --git a/compat-2.6.19.h b/compat-2.6.19.h deleted file mode 100644 index 017044c..0000000 --- a/compat-2.6.19.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef LINUX_26_19_COMPAT_H -#define LINUX_26_19_COMPAT_H - -#include -#include - -/* Compat work for 2.6.19 */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) - -#include - -static inline int -compat_kmem_cache_destroy(struct kmem_cache *cachep) -{ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) - return kmem_cache_destroy(cachep); -#else - kmem_cache_destroy(cachep); - return 0; -#endif -} - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) */ - -#endif /* LINUX_26_19_COMPAT_H */ diff --git a/compat-2.6.21.c b/compat-2.6.21.c deleted file mode 100644 index e2737fb..0000000 --- a/compat-2.6.21.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.21. - */ - -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) - -/* 2.6.21 compat code goes here */ - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) */ - diff --git a/compat-2.6.21.h b/compat-2.6.21.h deleted file mode 100644 index 263ebd2..0000000 --- a/compat-2.6.21.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef LINUX_26_21_COMPAT_H -#define LINUX_26_21_COMPAT_H - -#include -#include - -/* Compat work for 2.6.21 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) - -#include - -#define register_sysctl_table(table) \ - ({ \ - register_sysctl_table((table), 0); \ - }) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) */ - -#endif /* LINUX_26_21_COMPAT_H */ diff --git a/compat-2.6.22.c b/compat-2.6.22.c deleted file mode 100644 index b1ff1f3..0000000 --- a/compat-2.6.22.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.22. - */ - -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) - -/* 2.6.22 compat code goes here */ - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) */ - diff --git a/compat-2.6.22.h b/compat-2.6.22.h deleted file mode 100644 index 85cd9d5..0000000 --- a/compat-2.6.22.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef LINUX_26_22_COMPAT_H -#define LINUX_26_22_COMPAT_H - -#include -#include - -/* Compat work for 2.6.21 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) - -#include -#include - -/* reuse ax25_ptr */ -#define ieee80211_ptr ax25_ptr - -#ifdef CONFIG_AX25 -#error Compat reuses the AX.25 pointer so that may not be enabled! -#endif - -static inline unsigned char *skb_mac_header(const struct sk_buff *skb) -{ - return skb->mac.raw; -} - -static inline void skb_set_mac_header(struct sk_buff *skb, int offset) -{ - skb->mac.raw = skb->data + offset; -} - -static inline void skb_reset_mac_header(struct sk_buff *skb) -{ - skb->mac.raw = skb->data; -} - -static inline void skb_reset_network_header(struct sk_buff *skb) -{ - skb->nh.raw = skb->data; -} - -static inline void skb_set_network_header(struct sk_buff *skb, int offset) -{ - skb->nh.raw = skb->data + offset; -} - -static inline void skb_set_transport_header(struct sk_buff *skb, int offset) -{ - skb->h.raw = skb->data + offset; -} - -static inline unsigned char *skb_transport_header(struct sk_buff *skb) -{ - return skb->h.raw; -} - -static inline unsigned char *skb_network_header(const struct sk_buff *skb) -{ - return skb->nh.raw; -} - -static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb) -{ - return skb->tail; -} - -static inline struct iphdr *ip_hdr(const struct sk_buff *skb) -{ - return (struct iphdr *)skb_network_header(skb); -} - -static inline void skb_copy_from_linear_data(const struct sk_buff *skb, - void *to, - const unsigned int len) -{ - memcpy(to, skb->data, len); -} - -static inline void skb_copy_from_linear_data_offset(const struct sk_buff *skb, - const int offset, void *to, - const unsigned int len) -{ - memcpy(to, skb->data + offset, len); -} - -#define __maybe_unused __attribute__((unused)) - -#define uninitialized_var(x) x = x - -/* This will lead to very weird behaviour... */ -#define NLA_BINARY NLA_STRING - -static inline int pci_set_mwi(struct pci_dev *dev) -{ - return -ENOSYS; -} - -static inline void pci_clear_mwi(struct pci_dev *dev) -{ -} - -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) */ - -#endif /* LINUX_26_22_COMPAT_H */ diff --git a/compat-2.6.23.c b/compat-2.6.23.c deleted file mode 100644 index d232b1a..0000000 --- a/compat-2.6.23.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.23. - */ - -#include - -/* All things not in 2.6.22 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) - -/* Part of net/core/dev_mcast.c as of 2.6.23. This is a slightly different version. - * Since da->da_synced is not part of 2.6.22 we need to take longer route when - * syncing */ - -/** - * dev_mc_sync - Synchronize device's multicast list to another device - * @to: destination device - * @from: source device - * - * Add newly added addresses to the destination device and release - * addresses that have no users left. The source device must be - * locked by netif_tx_lock_bh. - * - * This function is intended to be called from the dev->set_multicast_list - * function of layered software devices. - */ -int dev_mc_sync(struct net_device *to, struct net_device *from) -{ - struct dev_addr_list *da, *next, *da_to; - int err = 0; - - netif_tx_lock_bh(to); - da = from->mc_list; - while (da != NULL) { - int synced = 0; - next = da->next; - da_to = to->mc_list; - /* 2.6.22 does not have da->da_synced so lets take the long route */ - while (da_to != NULL) { - if (memcmp(da_to->da_addr, da->da_addr, da_to->da_addrlen) == 0 && - da->da_addrlen == da_to->da_addrlen) - synced = 1; - break; - } - if (!synced) { - err = __dev_addr_add(&to->mc_list, &to->mc_count, - da->da_addr, da->da_addrlen, 0); - if (err < 0) - break; - da->da_users++; - } else if (da->da_users == 1) { - __dev_addr_delete(&to->mc_list, &to->mc_count, - da->da_addr, da->da_addrlen, 0); - __dev_addr_delete(&from->mc_list, &from->mc_count, - da->da_addr, da->da_addrlen, 0); - } - da = next; - } - if (!err) - __dev_set_rx_mode(to); - netif_tx_unlock_bh(to); - - return err; -} -EXPORT_SYMBOL(dev_mc_sync); - - -/* Part of net/core/dev_mcast.c as of 2.6.23. This is a slighty different version. - * Since da->da_synced is not part of 2.6.22 we need to take longer route when - * unsyncing */ - -/** - * dev_mc_unsync - Remove synchronized addresses from the destination - * device - * @to: destination device - * @from: source device - * - * Remove all addresses that were added to the destination device by - * dev_mc_sync(). This function is intended to be called from the - * dev->stop function of layered software devices. - */ -void dev_mc_unsync(struct net_device *to, struct net_device *from) -{ - struct dev_addr_list *da, *next, *da_to; - - netif_tx_lock_bh(from); - netif_tx_lock_bh(to); - - da = from->mc_list; - while (da != NULL) { - bool synced = false; - next = da->next; - da_to = to->mc_list; - /* 2.6.22 does not have da->da_synced so lets take the long route */ - while (da_to != NULL) { - if (memcmp(da_to->da_addr, da->da_addr, da_to->da_addrlen) == 0 && - da->da_addrlen == da_to->da_addrlen) - synced = true; - break; - } - if (!synced) { - da = next; - continue; - } - __dev_addr_delete(&to->mc_list, &to->mc_count, - da->da_addr, da->da_addrlen, 0); - __dev_addr_delete(&from->mc_list, &from->mc_count, - da->da_addr, da->da_addrlen, 0); - da = next; - } - __dev_set_rx_mode(to); - - netif_tx_unlock_bh(to); - netif_tx_unlock_bh(from); -} -EXPORT_SYMBOL(dev_mc_unsync); - -/* Added as of 2.6.23 on net/core/dev.c. Slightly modifed, no dev->set_rx_mode on - * 2.6.22 so ignore that. */ - -/* - * Upload unicast and multicast address lists to device and - * configure RX filtering. When the device doesn't support unicast - * filtering it is put in promiscous mode while unicast addresses - * are present. - */ -void __dev_set_rx_mode(struct net_device *dev) -{ - /* dev_open will call this function so the list will stay sane. */ - if (!(dev->flags&IFF_UP)) - return; - - if (!netif_device_present(dev)) - return; - -/* This needs to be ported to 2.6.22 framework */ -#if 0 - /* Unicast addresses changes may only happen under the rtnl, - * therefore calling __dev_set_promiscuity here is safe. - */ - if (dev->uc_count > 0 && !dev->uc_promisc) { - __dev_set_promiscuity(dev, 1); - dev->uc_promisc = 1; - } else if (dev->uc_count == 0 && dev->uc_promisc) { - __dev_set_promiscuity(dev, -1); - dev->uc_promisc = 0; - } -#endif - - if (dev->set_multicast_list) - dev->set_multicast_list(dev); -} - -#ifndef HAVE_PCI_SET_MWI -int pci_try_set_mwi(struct pci_dev *dev) -{ - return 0; -} -EXPORT_SYMBOL(pci_try_set_mwi); -#else - -/** - * pci_try_set_mwi - enables memory-write-invalidate PCI transaction - * @dev: the PCI device for which MWI is enabled - * - * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND. - * Callers are not required to check the return value. - * - * RETURNS: An appropriate -ERRNO error value on error, or zero for success. - */ -int pci_try_set_mwi(struct pci_dev *dev) -{ - int rc = pci_set_mwi(dev); - return rc; -} -EXPORT_SYMBOL(pci_try_set_mwi); -#endif - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) */ - diff --git a/compat-2.6.23.h b/compat-2.6.23.h deleted file mode 100644 index c36f90d..0000000 --- a/compat-2.6.23.h +++ /dev/null @@ -1,136 +0,0 @@ -#ifndef LINUX_26_23_COMPAT_H -#define LINUX_26_23_COMPAT_H - -#include -#include - -/* Compat work for < 2.6.23 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) - -#include -#include -#include -#include - -/* - * Tell gcc if a function is cold. The compiler will assume any path - * directly leading to the call is unlikely. - */ - -#if !(__GNUC__ == 4 && __GNUC_MINOR__ < 3) -/* Mark functions as cold. gcc will assume any path leading to a call - * to them will be unlikely. This means a lot of manual unlikely()s - * are unnecessary now for any paths leading to the usual suspects - * like BUG(), printk(), panic() etc. [but let's keep them for now for - * older compilers] - * - * Early snapshots of gcc 4.3 don't support this and we can't detect this - * in the preprocessor, but we can live with this because they're unreleased. - * Maketime probing would be overkill here. - * - * gcc also has a __attribute__((__hot__)) to move hot functions into - * a special section, but I don't see any sense in this right now in - * the kernel context */ -#define __cold __attribute__((__cold__)) -#endif /* gcc 4.3 check */ - -#ifndef __cold -#define __cold -#endif - -/* Added as of 2.6.23 in include/linux/netdevice.h */ -#define alloc_netdev_mq(sizeof_priv, name, setup, queue) \ - alloc_netdev(sizeof_priv, name, setup) -#define NETIF_F_MULTI_QUEUE 16384 - -/* Added as of 2.6.23 on include/linux/netdevice.h */ -static inline int netif_is_multiqueue(const struct net_device *dev) -{ - return (!!(NETIF_F_MULTI_QUEUE & dev->features)); -} - -/* 2.6.23 fixed a bug in tcf_destroy_chain and the parameter changed */ -static inline void tcf_destroy_chain_compat(struct tcf_proto **fl) -{ - struct tcf_proto *tp; - - while ((tp = *fl) != NULL) { - *fl = tp->next; - tp->ops->destroy(tp); - module_put(tp->ops->owner); - kfree(tp); - } -} - -/* dev_mc_list was replaced with dev_addr_list as of 2.6.23, - * only new member added is da_synced. */ -#define dev_addr_list dev_mc_list -#define da_addr dmi_addr -#define da_addrlen dmi_addrlen -#define da_users dmi_users -#define da_gusers dmi_gusers - -/* dev_set_promiscuity() was moved to __dev_set_promiscuity() on 2.6.23 and - * dev_set_promiscuity() became a wrapper. */ -#define __dev_set_promiscuity dev_set_promiscuity - -/* Our own 2.6.22 port on compat.c */ -extern void dev_mc_unsync(struct net_device *to, struct net_device *from); -extern int dev_mc_sync(struct net_device *to, struct net_device *from); - -/* Our own 2.6.22 port on compat.c */ -extern void __dev_set_rx_mode(struct net_device *dev); - -/* Simple to add this */ -extern int cancel_delayed_work_sync(struct delayed_work *work); - -#define cancel_delayed_work_sync cancel_rearming_delayed_work - -#define debugfs_rename(a, b, c, d) 1 - -/* nl80211 requires multicast group support which is new and added on - * 2.6.23. We can't add support for it for older kernels to support it - * genl_family structure was changed. Lets just let through the - * genl_register_mc_group call. This means no multicast group suppport */ - -#define genl_register_mc_group(a, b) 0 - -/** - * struct genl_multicast_group - generic netlink multicast group - * @name: name of the multicast group, names are per-family - * @id: multicast group ID, assigned by the core, to use with - * genlmsg_multicast(). - * @list: list entry for linking - * @family: pointer to family, need not be set before registering - */ -struct genl_multicast_group -{ - struct genl_family *family; /* private */ - struct list_head list; /* private */ - char name[GENL_NAMSIZ]; - u32 id; -}; - - -/* Added as of 2.6.23 */ -int pci_try_set_mwi(struct pci_dev *dev); - -/* Added as of 2.6.23 */ -#ifdef CONFIG_PM_SLEEP -/* - * Tell the freezer that the current task should be frozen by it - */ -static inline void set_freezable(void) -{ - current->flags &= ~PF_NOFREEZE; -} - -#else -static inline void set_freezable(void) {} -#endif /* CONFIG_PM_SLEEP */ - -#else -#define tcf_destroy_chain_compat tcf_destroy_chain -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) */ - -#endif /* LINUX_26_23_COMPAT_H */ diff --git a/compat-2.6.24.c b/compat-2.6.24.c deleted file mode 100644 index 977eb45..0000000 --- a/compat-2.6.24.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.24. - */ - -#include - -/* All things not in 2.6.22 and 2.6.23 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) - -/* Part of net/ethernet/eth.c as of 2.6.24 */ -char *print_mac(char *buf, const u8 *addr) -{ - sprintf(buf, MAC_FMT, - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - return buf; -} -EXPORT_SYMBOL(print_mac); - -/* On net/core/dev.c as of 2.6.24 */ -int __dev_addr_delete(struct dev_addr_list **list, int *count, - void *addr, int alen, int glbl) -{ - struct dev_addr_list *da; - - for (; (da = *list) != NULL; list = &da->next) { - if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && - alen == da->da_addrlen) { - if (glbl) { - int old_glbl = da->da_gusers; - da->da_gusers = 0; - if (old_glbl == 0) - break; - } - if (--da->da_users) - return 0; - - *list = da->next; - kfree(da); - (*count)--; - return 0; - } - } - return -ENOENT; -} - -/* On net/core/dev.c as of 2.6.24. This is not yet used by mac80211 but - * might as well add it */ -int __dev_addr_add(struct dev_addr_list **list, int *count, - void *addr, int alen, int glbl) -{ - struct dev_addr_list *da; - - for (da = *list; da != NULL; da = da->next) { - if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && - da->da_addrlen == alen) { - if (glbl) { - int old_glbl = da->da_gusers; - da->da_gusers = 1; - if (old_glbl) - return 0; - } - da->da_users++; - return 0; - } - } - - da = kmalloc(sizeof(*da), GFP_ATOMIC); - if (da == NULL) - return -ENOMEM; - memcpy(da->da_addr, addr, alen); - da->da_addrlen = alen; - da->da_users = 1; - da->da_gusers = glbl ? 1 : 0; - da->next = *list; - *list = da; - (*count)++; - return 0; -} - -/* 2.6.22 and 2.6.23 have eth_header_cache_update defined as extern in include/linux/etherdevice.h - * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */ - -/** - * eth_header_cache_update - update cache entry - * @hh: destination cache entry - * @dev: network device - * @haddr: new hardware address - * - * Called by Address Resolution module to notify changes in address. - */ -void eth_header_cache_update(struct hh_cache *hh, - struct net_device *dev, - unsigned char *haddr) -{ - memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)), - haddr, ETH_ALEN); -} -EXPORT_SYMBOL(eth_header_cache_update); - -/* 2.6.22 and 2.6.23 have eth_header_cache defined as extern in include/linux/etherdevice.h - * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */ - -/** - * eth_header_cache - fill cache entry from neighbour - * @neigh: source neighbour - * @hh: destination cache entry - * Create an Ethernet header template from the neighbour. - */ -int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh) -{ - __be16 type = hh->hh_type; - struct ethhdr *eth; - const struct net_device *dev = neigh->dev; - - eth = (struct ethhdr *) - (((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth)))); - - if (type == htons(ETH_P_802_3)) - return -1; - - eth->h_proto = type; - memcpy(eth->h_source, dev->dev_addr, ETH_ALEN); - memcpy(eth->h_dest, neigh->ha, ETH_ALEN); - hh->hh_len = ETH_HLEN; - return 0; -} -EXPORT_SYMBOL(eth_header_cache); - -/* 2.6.22 and 2.6.23 have eth_header() defined as extern in include/linux/etherdevice.h - * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */ - -/** - * eth_header - create the Ethernet header - * @skb: buffer to alter - * @dev: source device - * @type: Ethernet type field - * @daddr: destination address (NULL leave destination address) - * @saddr: source address (NULL use device source address) - * @len: packet length (<= skb->len) - * - * - * Set the protocol type. For a packet of type ETH_P_802_3 we put the length - * in here instead. It is up to the 802.2 layer to carry protocol information. - */ -int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, - void *daddr, void *saddr, unsigned len) -{ - struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN); - - if (type != ETH_P_802_3) - eth->h_proto = htons(type); - else - eth->h_proto = htons(len); - - /* - * Set the source hardware address. - */ - - if (!saddr) - saddr = dev->dev_addr; - memcpy(eth->h_source, saddr, dev->addr_len); - - if (daddr) { - memcpy(eth->h_dest, daddr, dev->addr_len); - return ETH_HLEN; - } - - /* - * Anyway, the loopback-device should never use this function... - */ - - if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { - memset(eth->h_dest, 0, dev->addr_len); - return ETH_HLEN; - } - - return -ETH_HLEN; -} - -EXPORT_SYMBOL(eth_header); - -/* 2.6.22 and 2.6.23 have eth_rebuild_header defined as extern in include/linux/etherdevice.h - * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */ - -/** - * eth_rebuild_header- rebuild the Ethernet MAC header. - * @skb: socket buffer to update - * - * This is called after an ARP or IPV6 ndisc it's resolution on this - * sk_buff. We now let protocol (ARP) fill in the other fields. - * - * This routine CANNOT use cached dst->neigh! - * Really, it is used only when dst->neigh is wrong. - */ -int eth_rebuild_header(struct sk_buff *skb) -{ - struct ethhdr *eth = (struct ethhdr *)skb->data; - struct net_device *dev = skb->dev; - - switch (eth->h_proto) { -#ifdef CONFIG_INET - case __constant_htons(ETH_P_IP): - return arp_find(eth->h_dest, skb); -#endif - default: - printk(KERN_DEBUG - "%s: unable to resolve type %X addresses.\n", - dev->name, (int)eth->h_proto); - - memcpy(eth->h_source, dev->dev_addr, ETH_ALEN); - break; - } - - return 0; -} -EXPORT_SYMBOL(eth_rebuild_header); - -/* 2.6.24 will introduce struct pci_dev is_pcie bit. To help - * with the compatibility code (compat.diff) being smaller, we provide a helper - * so in cases where that will be used we can simply slap ifdefs with this - * routine. Use compat_ prefex to not pollute namespace. */ -int compat_is_pcie(struct pci_dev *pdev) -{ - int cap; - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - return cap ? 1 : 0; -} -EXPORT_SYMBOL(compat_is_pcie); - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */ - diff --git a/compat-2.6.24.h b/compat-2.6.24.h deleted file mode 100644 index 43e6302..0000000 --- a/compat-2.6.24.h +++ /dev/null @@ -1,202 +0,0 @@ -#ifndef LINUX_26_24_COMPAT_H -#define LINUX_26_24_COMPAT_H - -#include -#include - -/* Compat work for 2.6.21, 2.6.22 and 2.6.23 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) - -/* Added on 2.6.24 in include/linux/types.h by Al viro on commit 142956af */ -typedef unsigned long uintptr_t; - -/* From include/linux/net.h */ -enum sock_shutdown_cmd { - SHUT_RD = 0, - SHUT_WR = 1, - SHUT_RDWR = 2, -}; - -#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,23)) /* Local check */ -/* Added as of 2.6.24 in include/linux/skbuff.h. - * - * Although 2.6.23 does support for CONFIG_NETDEVICES_MULTIQUEUE - * this helper was not added until 2.6.24. This implementation - * is exactly as it is on newer kernels. - * - * For older kernels we use the an internal mac80211 hack. - * For details see changes to include/net/mac80211.h through - * compat.diff and compat/mq_compat.h */ -static inline u16 skb_get_queue_mapping(struct sk_buff *skb) -{ -#ifdef CONFIG_NETDEVICES_MULTIQUEUE - return skb->queue_mapping; -#else - return 0; -#endif -} -#endif /* Local 2.6.23 check */ - -/* On older kernels we handle this a bit differently, so we yield to that - * code for its implementation in mq_compat.h as we want to make - * use of the internal mac80211 __ieee80211_queue_stopped() which itself - * uses internal mac80211 data structure hacks. */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) /* Local check */ -/** - * netif_subqueue_stopped - test status of subqueue - * @dev: network device - * @queue_index: sub queue index - * - * Check individual transmit queue of a device with multiple transmit queues. - */ -static inline int __netif_subqueue_stopped(const struct net_device *dev, - u16 queue_index) -{ -#ifdef CONFIG_NETDEVICES_MULTIQUEUE - return test_bit(__LINK_STATE_XOFF, - &dev->egress_subqueue[queue_index].state); -#else - return 0; -#endif -} - -/* Note: although the backport implementation for netif_subqueue_stopped - * on older kernels is identical to upstream __netif_subqueue_stopped() - * (except for a const qualifier) we implement netif_subqueue_stopped() - * as part of mac80211 as it relies on internal mac80211 structures we - * use for MQ support. We this implement it in mq_compat.h */ - -#endif /* Local 2.6.23 check */ - -/* - * Force link bug if constructor is used, can't be done compatibly - * because constructor arguments were swapped since then! - */ -extern void __incompatible_kmem_cache_create(void); - -/* 2.6.21 and 2.6.22 kmem_cache_create() takes 6 arguments */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) -#define kmem_cache_create(name, objsize, align, flags, ctor) \ - ({ \ - if (ctor) __incompatible_kmem_cache_create(); \ - kmem_cache_create((name), (objsize), (align), \ - (flags), NULL, NULL); \ - }) -#endif - -/* 2.6.23 kmem_cache_create() takes 5 arguments */ -#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,23)) -#define kmem_cache_create(name, objsize, align, flags, ctor) \ - ({ \ - if (ctor) __incompatible_kmem_cache_create(); \ - kmem_cache_create((name), (objsize), (align), \ - (flags), NULL); \ - }) -#endif - -/* From include/linux/mod_devicetable.h */ - -/* SSB core, see drivers/ssb/ */ -#ifndef SSB_DEVICE -struct ssb_device_id { - __u16 vendor; - __u16 coreid; - __u8 revision; -}; -#define SSB_DEVICE(_vendor, _coreid, _revision) \ - { .vendor = _vendor, .coreid = _coreid, .revision = _revision, } -#define SSB_DEVTABLE_END \ - { 0, }, - -#define SSB_ANY_VENDOR 0xFFFF -#define SSB_ANY_ID 0xFFFF -#define SSB_ANY_REV 0xFF -#endif - - -/* Namespace stuff, introduced on 2.6.24 */ -#define dev_get_by_index(a, b) dev_get_by_index(b) -#define __dev_get_by_index(a, b) __dev_get_by_index(b) - -/* - * Display a 6 byte device address (MAC) in a readable format. - */ -#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" -extern char *print_mac(char *buf, const u8 *addr); -#define DECLARE_MAC_BUF(var) char var[18] __maybe_unused - -extern int eth_header(struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, - void *saddr, unsigned len); -extern int eth_rebuild_header(struct sk_buff *skb); -extern void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, - unsigned char * haddr); -extern int eth_header_cache(struct neighbour *neigh, - struct hh_cache *hh); - -/* This structure is simply not present on 2.6.22 and 2.6.23 */ -struct header_ops { - int (*create) (struct sk_buff *skb, struct net_device *dev, - unsigned short type, void *daddr, - void *saddr, unsigned len); - int (*parse)(const struct sk_buff *skb, unsigned char *haddr); - int (*rebuild)(struct sk_buff *skb); - #define HAVE_HEADER_CACHE - int (*cache)(struct neighbour *neigh, struct hh_cache *hh); - void (*cache_update)(struct hh_cache *hh, - struct net_device *dev, - unsigned char *haddr); -}; - -/* net/ieee80211/ieee80211_crypt_tkip uses sg_init_table. This was added on - * 2.6.24. CONFIG_DEBUG_SG was added in 2.6.24 as well, so lets just ignore - * the debug stuff. Note that adding this required changes to the struct - * scatterlist on include/asm/scatterlist*, so the right way to port this - * is to simply ignore the new structure changes and zero the scatterlist - * array. We lave the kdoc intact for reference. - */ - -/** - * sg_mark_end - Mark the end of the scatterlist - * @sg: SG entryScatterlist - * - * Description: - * Marks the passed in sg entry as the termination point for the sg - * table. A call to sg_next() on this entry will return NULL. - * - **/ -static inline void sg_mark_end(struct scatterlist *sg) -{ -} - -/** - * sg_init_table - Initialize SG table - * @sgl: The SG table - * @nents: Number of entries in table - * - * Notes: - * If this is part of a chained sg table, sg_mark_end() should be - * used only on the last table part. - * - **/ -{ - memset(sgl, 0, sizeof(*sgl) * nents); -} - -/** - * usb_endpoint_num - get the endpoint's number - * @epd: endpoint to be checked - * - * Returns @epd's number: 0 to 15. - */ -static inline int usb_endpoint_num(const struct usb_endpoint_descriptor *epd) -{ - return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; -} - -/* Helper to make struct pci_dev is_pcie compatibility code smaller */ -int compat_is_pcie(struct pci_dev *pdev); - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) */ - -#endif /* LINUX_26_24_COMPAT_H */ diff --git a/compat-2.6.25.c b/compat-2.6.25.c deleted file mode 100644 index e872447..0000000 --- a/compat-2.6.25.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.25. - */ - -#include - -/* All things not in 2.6.22, 2.6.23 and 2.6.24 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) - -/* Backport work for QoS dependencies (kernel/pm_qos_params.c) - * ipw2100 now makes use of - * pm_qos_add_requirement(), - * pm_qos_update_requirement() and - * pm_qos_remove_requirement() from it - * - * */ - -/* - * locking rule: all changes to target_value or requirements or notifiers lists - * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock - * held, taken with _irqsave. One lock to rule them all - */ -struct requirement_list { - struct list_head list; - union { - s32 value; - s32 usec; - s32 kbps; - }; - char *name; -}; - -static s32 max_compare(s32 v1, s32 v2); -static s32 min_compare(s32 v1, s32 v2); - -struct pm_qos_object { - struct requirement_list requirements; - struct blocking_notifier_head *notifiers; - struct miscdevice pm_qos_power_miscdev; - char *name; - s32 default_value; - s32 target_value; - s32 (*comparitor)(s32, s32); -}; - -static struct pm_qos_object null_pm_qos; -static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier); -static struct pm_qos_object cpu_dma_pm_qos = { - .requirements = {LIST_HEAD_INIT(cpu_dma_pm_qos.requirements.list)}, - .notifiers = &cpu_dma_lat_notifier, - .name = "cpu_dma_latency", - .default_value = 2000 * USEC_PER_SEC, - .target_value = 2000 * USEC_PER_SEC, - .comparitor = min_compare -}; - -static BLOCKING_NOTIFIER_HEAD(network_lat_notifier); -static struct pm_qos_object network_lat_pm_qos = { - .requirements = {LIST_HEAD_INIT(network_lat_pm_qos.requirements.list)}, - .notifiers = &network_lat_notifier, - .name = "network_latency", - .default_value = 2000 * USEC_PER_SEC, - .target_value = 2000 * USEC_PER_SEC, - .comparitor = min_compare -}; - - -static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier); -static struct pm_qos_object network_throughput_pm_qos = { - .requirements = - {LIST_HEAD_INIT(network_throughput_pm_qos.requirements.list)}, - .notifiers = &network_throughput_notifier, - .name = "network_throughput", - .default_value = 0, - .target_value = 0, - .comparitor = max_compare -}; - - -static struct pm_qos_object *pm_qos_array[] = { - &null_pm_qos, - &cpu_dma_pm_qos, - &network_lat_pm_qos, - &network_throughput_pm_qos -}; - -static DEFINE_SPINLOCK(pm_qos_lock); - -/* static helper functions */ -static s32 max_compare(s32 v1, s32 v2) -{ - return max(v1, v2); -} - -static s32 min_compare(s32 v1, s32 v2) -{ - return min(v1, v2); -} - -static void update_target(int target) -{ - s32 extreme_value; - struct requirement_list *node; - unsigned long flags; - int call_notifier = 0; - - spin_lock_irqsave(&pm_qos_lock, flags); - extreme_value = pm_qos_array[target]->default_value; - list_for_each_entry(node, - &pm_qos_array[target]->requirements.list, list) { - extreme_value = pm_qos_array[target]->comparitor( - extreme_value, node->value); - } - if (pm_qos_array[target]->target_value != extreme_value) { - call_notifier = 1; - pm_qos_array[target]->target_value = extreme_value; - pr_debug(KERN_ERR "new target for qos %d is %d\n", target, - pm_qos_array[target]->target_value); - } - spin_unlock_irqrestore(&pm_qos_lock, flags); - - if (call_notifier) - blocking_notifier_call_chain(pm_qos_array[target]->notifiers, - (unsigned long) extreme_value, NULL); -} - - -/** - * pm_qos_add_requirement - inserts new qos request into the list - * @pm_qos_class: identifies which list of qos request to us - * @name: identifies the request - * @value: defines the qos request - * - * This function inserts a new entry in the pm_qos_class list of requested qos - * performance charactoistics. It recomputes the agregate QoS expectations for - * the pm_qos_class of parrameters. - */ -int pm_qos_add_requirement(int pm_qos_class, char *name, s32 value) -{ - struct requirement_list *dep; - unsigned long flags; - - dep = kzalloc(sizeof(struct requirement_list), GFP_KERNEL); - if (dep) { - if (value == PM_QOS_DEFAULT_VALUE) - dep->value = pm_qos_array[pm_qos_class]->default_value; - else - dep->value = value; - dep->name = kstrdup(name, GFP_KERNEL); - if (!dep->name) - goto cleanup; - - spin_lock_irqsave(&pm_qos_lock, flags); - list_add(&dep->list, - &pm_qos_array[pm_qos_class]->requirements.list); - spin_unlock_irqrestore(&pm_qos_lock, flags); - update_target(pm_qos_class); - - return 0; - } - -cleanup: - kfree(dep); - return -ENOMEM; -} -EXPORT_SYMBOL_GPL(pm_qos_add_requirement); - -/** - * pm_qos_update_requirement - modifies an existing qos request - * @pm_qos_class: identifies which list of qos request to us - * @name: identifies the request - * @value: defines the qos request - * - * Updates an existing qos requierement for the pm_qos_class of parameters along - * with updating the target pm_qos_class value. - * - * If the named request isn't in the lest then no change is made. - */ -int pm_qos_update_requirement(int pm_qos_class, char *name, s32 new_value) -{ - unsigned long flags; - struct requirement_list *node; - int pending_update = 0; - - spin_lock_irqsave(&pm_qos_lock, flags); - list_for_each_entry(node, - &pm_qos_array[pm_qos_class]->requirements.list, list) { - if (strcmp(node->name, name) == 0) { - if (new_value == PM_QOS_DEFAULT_VALUE) - node->value = - pm_qos_array[pm_qos_class]->default_value; - else - node->value = new_value; - pending_update = 1; - break; - } - } - spin_unlock_irqrestore(&pm_qos_lock, flags); - if (pending_update) - update_target(pm_qos_class); - - return 0; -} -EXPORT_SYMBOL_GPL(pm_qos_update_requirement); - -/** - * pm_qos_remove_requirement - modifies an existing qos request - * @pm_qos_class: identifies which list of qos request to us - * @name: identifies the request - * - * Will remove named qos request from pm_qos_class list of parrameters and - * recompute the current target value for the pm_qos_class. - */ -void pm_qos_remove_requirement(int pm_qos_class, char *name) -{ - unsigned long flags; - struct requirement_list *node; - int pending_update = 0; - - spin_lock_irqsave(&pm_qos_lock, flags); - list_for_each_entry(node, - &pm_qos_array[pm_qos_class]->requirements.list, list) { - if (strcmp(node->name, name) == 0) { - kfree(node->name); - list_del(&node->list); - kfree(node); - pending_update = 1; - break; - } - } - spin_unlock_irqrestore(&pm_qos_lock, flags); - if (pending_update) - update_target(pm_qos_class); -} -EXPORT_SYMBOL_GPL(pm_qos_remove_requirement); - - -/** - * The following things are out of ./lib/vsprintf.c - * The new iwlwifi driver is using them. - */ - -/** - * strict_strtoul - convert a string to an unsigned long strictly - * @cp: The string to be converted - * @base: The number base to use - * @res: The converted result value - * - * strict_strtoul converts a string to an unsigned long only if the - * string is really an unsigned long string, any string containing - * any invalid char at the tail will be rejected and -EINVAL is returned, - * only a newline char at the tail is acceptible because people generally - * change a module parameter in the following way: - * - * echo 1024 > /sys/module/e1000/parameters/copybreak - * - * echo will append a newline to the tail. - * - * It returns 0 if conversion is successful and *res is set to the converted - * value, otherwise it returns -EINVAL and *res is set to 0. - * - * simple_strtoul just ignores the successive invalid characters and - * return the converted value of prefix part of the string. - */ -int strict_strtoul(const char *cp, unsigned int base, unsigned long *res); - -/** - * strict_strtol - convert a string to a long strictly - * @cp: The string to be converted - * @base: The number base to use - * @res: The converted result value - * - * strict_strtol is similiar to strict_strtoul, but it allows the first - * character of a string is '-'. - * - * It returns 0 if conversion is successful and *res is set to the converted - * value, otherwise it returns -EINVAL and *res is set to 0. - */ -int strict_strtol(const char *cp, unsigned int base, long *res); - -#define define_strict_strtoux(type, valtype) \ -int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\ -{ \ - char *tail; \ - valtype val; \ - size_t len; \ - \ - *res = 0; \ - len = strlen(cp); \ - if (len == 0) \ - return -EINVAL; \ - \ - val = simple_strtou##type(cp, &tail, base); \ - if ((*tail == '\0') || \ - ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {\ - *res = val; \ - return 0; \ - } \ - \ - return -EINVAL; \ -} \ - -#define define_strict_strtox(type, valtype) \ -int strict_strto##type(const char *cp, unsigned int base, valtype *res) \ -{ \ - int ret; \ - if (*cp == '-') { \ - ret = strict_strtou##type(cp+1, base, res); \ - if (!ret) \ - *res = -(*res); \ - } else \ - ret = strict_strtou##type(cp, base, res); \ - \ - return ret; \ -} \ - -define_strict_strtoux(l, unsigned long) -define_strict_strtox(l, long) - -EXPORT_SYMBOL(strict_strtoul); -EXPORT_SYMBOL(strict_strtol); - -int __dev_addr_sync(struct dev_addr_list **to, int *to_count, - struct dev_addr_list **from, int *from_count) -{ - struct dev_addr_list *da, *next; - int err = 0; - - da = *from; - while (da != NULL) { - next = da->next; - if (!da->da_synced) { - err = __dev_addr_add(to, to_count, - da->da_addr, da->da_addrlen, 0); - if (err < 0) - break; - da->da_synced = 1; - da->da_users++; - } else if (da->da_users == 1) { - __dev_addr_delete(to, to_count, - da->da_addr, da->da_addrlen, 0); - __dev_addr_delete(from, from_count, - da->da_addr, da->da_addrlen, 0); - } - da = next; - } - return err; -} -EXPORT_SYMBOL_GPL(__dev_addr_sync); - -void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, - struct dev_addr_list **from, int *from_count) -{ - struct dev_addr_list *da, *next; - - da = *from; - while (da != NULL) { - next = da->next; - if (da->da_synced) { - __dev_addr_delete(to, to_count, - da->da_addr, da->da_addrlen, 0); - da->da_synced = 0; - __dev_addr_delete(from, from_count, - da->da_addr, da->da_addrlen, 0); - } - da = next; - } -} -EXPORT_SYMBOL_GPL(__dev_addr_unsync); - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) */ - diff --git a/compat-2.6.25.h b/compat-2.6.25.h deleted file mode 100644 index 23cf487..0000000 --- a/compat-2.6.25.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef LINUX_26_25_COMPAT_H -#define LINUX_26_25_COMPAT_H - -#include -#include - -/* Compat work for 2.6.24 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) - -#include -#include -#include -#include -#include -#include -#include - -#define __WARN(foo) dump_stack() - -#define dev_emerg(dev, format, arg...) \ - dev_printk(KERN_EMERG , dev , format , ## arg) -#define dev_alert(dev, format, arg...) \ - dev_printk(KERN_ALERT , dev , format , ## arg) -#define dev_crit(dev, format, arg...) \ - dev_printk(KERN_CRIT , dev , format , ## arg) - -extern int __dev_addr_sync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count); -extern void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count); - -#define seq_file_net &init_net; - -enum nf_inet_hooks { - NF_INET_PRE_ROUTING = 0, - NF_INET_LOCAL_IN = 1, - NF_INET_FORWARD = 2, - NF_INET_LOCAL_OUT = 3, - NF_INET_POST_ROUTING = 4, - NF_INET_NUMHOOKS = 5 -}; - -/* The patch: - * commit 8b5f6883683c91ad7e1af32b7ceeb604d68e2865 - * Author: Marcin Slusarz - * Date: Fri Feb 8 04:20:12 2008 -0800 - * - * byteorder: move le32_add_cpu & friends from OCFS2 to core - * - * moves le*_add_cpu and be*_add_cpu functions from OCFS2 to core - * header (1st) and converted some existing code to it. We port - * it here as later kernels will most likely use it. - */ -static inline void le16_add_cpu(__le16 *var, u16 val) -{ - *var = cpu_to_le16(le16_to_cpu(*var) + val); -} - -static inline void le32_add_cpu(__le32 *var, u32 val) -{ - *var = cpu_to_le32(le32_to_cpu(*var) + val); -} - -static inline void le64_add_cpu(__le64 *var, u64 val) -{ - *var = cpu_to_le64(le64_to_cpu(*var) + val); -} - -static inline void be16_add_cpu(__be16 *var, u16 val) -{ - u16 v = be16_to_cpu(*var); - *var = cpu_to_be16(v + val); -} - -static inline void be32_add_cpu(__be32 *var, u32 val) -{ - u32 v = be32_to_cpu(*var); - *var = cpu_to_be32(v + val); -} - -static inline void be64_add_cpu(__be64 *var, u64 val) -{ - u64 v = be64_to_cpu(*var); - *var = cpu_to_be64(v + val); -} - -/* 2.6.25 changes hwrng_unregister()'s behaviour by supporting - * suspend of its parent device (the misc device, which is itself the - * hardware random number generator). It does this by passing a parameter to - * unregister_miscdev() which is not supported in older kernels. The suspend - * parameter allows us to enable access to the device's hardware - * number generator during suspend. As far as wireless is concerned this means - * if a driver goes to suspend it you won't have the HNR available in - * older kernels. */ -static inline void __hwrng_unregister(struct hwrng *rng, bool suspended) -{ - hwrng_unregister(rng); -} - -static inline void led_classdev_unregister_suspended(struct led_classdev *lcd) -{ - led_classdev_unregister(lcd); -} - -/** - * The following things are out of ./include/linux/kernel.h - * The new iwlwifi driver is using them. - */ -extern int strict_strtoul(const char *, unsigned int, unsigned long *); -extern int strict_strtol(const char *, unsigned int, long *); - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) */ - -#endif /* LINUX_26_25_COMPAT_H */ diff --git a/compat-2.6.26.c b/compat-2.6.26.c deleted file mode 100644 index 960a79a..0000000 --- a/compat-2.6.26.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.26. - * - * Copyright holders from ported work: - * - * Copyright (c) 2002-2003 Patrick Mochel - * Copyright (c) 2006-2007 Greg Kroah-Hartman - * Copyright (c) 2006-2007 Novell Inc. - */ - -#include - -/* All things not in 2.6.25 */ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) - - -/** - * kobject_set_name_vargs - Set the name of an kobject - * @kobj: struct kobject to set the name of - * @fmt: format string used to build the name - * @vargs: vargs to format the string. - */ -static -int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, - va_list vargs) -{ - const char *old_name = kobj->name; - char *s; - - if (kobj->name && !fmt) - return 0; - - kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs); - if (!kobj->name) - return -ENOMEM; - - /* ewww... some of these buggers have '/' in the name ... */ - while ((s = strchr(kobj->name, '/'))) - s[0] = '!'; - - kfree(old_name); - return 0; -} - -/** - * dev_set_name - set a device name - * @dev: device - * @fmt: format string for the device's name - */ -int dev_set_name(struct device *dev, const char *fmt, ...) -{ - va_list vargs; - int err; - - va_start(vargs, fmt); - err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); - va_end(vargs); - return err; -} -EXPORT_SYMBOL_GPL(dev_set_name); - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) */ - diff --git a/compat-2.6.26.h b/compat-2.6.26.h deleted file mode 100644 index b7c3b05..0000000 --- a/compat-2.6.26.h +++ /dev/null @@ -1,377 +0,0 @@ -#ifndef LINUX_26_26_COMPAT_H -#define LINUX_26_26_COMPAT_H - -#include -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) - -#include -#include -#include -#include -#include -#include - -/* These jiffie helpers added as of 2.6.26 */ - -/* - * These four macros compare jiffies and 'a' for convenience. - */ - -/* time_is_before_jiffies(a) return true if a is before jiffies */ -#define time_is_before_jiffies(a) time_after(jiffies, a) - -/* time_is_after_jiffies(a) return true if a is after jiffies */ -#define time_is_after_jiffies(a) time_before(jiffies, a) - -/* time_is_before_eq_jiffies(a) return true if a is before or equal to jiffies*/ -#define time_is_before_eq_jiffies(a) time_after_eq(jiffies, a) - -/* time_is_after_eq_jiffies(a) return true if a is after or equal to jiffies*/ -#define time_is_after_eq_jiffies(a) time_before_eq(jiffies, a) - -/* This comes from include/linux/input.h */ -#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any" - set = radio enabled */ - -/* From kernel.h */ -#define USHORT_MAX ((u16)(~0U)) -#define SHORT_MAX ((s16)(USHORT_MAX>>1)) -#define SHORT_MIN (-SHORT_MAX - 1) - -extern int dev_set_name(struct device *dev, const char *name, ...) - __attribute__((format(printf, 2, 3))); - -/** - * clamp_t - return a value clamped to a given range using a given type - * @type: the type of variable to use - * @val: current value - * @min: minimum allowable value - * @max: maximum allowable value - * - * This macro does no typechecking and uses temporary variables of type - * 'type' to make all the comparisons. - */ -#define clamp_t(type, val, min, max) ({ \ - type __val = (val); \ - type __min = (min); \ - type __max = (max); \ - __val = __val < __min ? __min: __val; \ - __val > __max ? __max: __val; }) - - -/* from include/linux/device.h */ -/* device_create_drvdata() is new */ -extern struct device *device_create_drvdata(struct class *cls, - struct device *parent, - dev_t devt, - void *drvdata, - const char *fmt, ...) -__attribute__((format(printf, 5, 6))); - -/* This is from include/linux/list.h */ - -/** - * list_is_singular - tests whether a list has just one entry. - * @head: the list to test. - */ -static inline int list_is_singular(const struct list_head *head) -{ - return !list_empty(head) && (head->next == head->prev); -} - -/* This is from include/linux/device.h, which was added as of 2.6.26 */ -static inline const char *dev_name(struct device *dev) -{ - /* will be changed into kobject_name(&dev->kobj) in the near future */ - return dev->bus_id; -} - -/* This is from include/linux/kernel.h, which was added as of 2.6.26 */ - -/** - * clamp_val - return a value clamped to a given range using val's type - * @val: current value - * @min: minimum allowable value - * @max: maximum allowable value - * - * This macro does no typechecking and uses temporary variables of whatever - * type the input argument 'val' is. This is useful when val is an unsigned - * type and min and max are literals that will otherwise be assigned a signed - * integer type. - */ - -#define clamp_val(val, min, max) ({ \ - typeof(val) __val = (val); \ - typeof(val) __min = (min); \ - typeof(val) __max = (max); \ - __val = __val < __min ? __min: __val; \ - __val > __max ? __max: __val; }) - -/* This comes from include/net/net_namespace.h */ - -#ifdef CONFIG_NET_NS -static inline -int net_eq(const struct net *net1, const struct net *net2) -{ - return net1 == net2; -} -#else -static inline -int net_eq(const struct net *net1, const struct net *net2) -{ - return 1; -} -#endif - -static inline -void dev_net_set(struct net_device *dev, struct net *net) -{ -#ifdef CONFIG_NET_NS - release_net(dev->nd_net); - dev->nd_net = hold_net(net); -#endif -} - -static inline -struct net *sock_net(const struct sock *sk) -{ -#ifdef CONFIG_NET_NS - return sk->sk_net; -#else - return &init_net; -#endif -} - -/* This comes from include/linux/netdevice.h */ - -/* - * Net namespace inlines - */ -static inline -struct net *dev_net(const struct net_device *dev) -{ -#ifdef CONFIG_NET_NS - /* - * compat-wirelss backport note: - * For older kernels we may just need to always return init_net, - * not sure when we added dev->nd_net. - */ - return dev->nd_net; -#else - return &init_net; -#endif -} - - -/* - * 2.6.26 added its own unaligned API which the - * new drivers can use. Lets port it here by including it in older - * kernels and also deal with the architecture handling here. - */ - -#ifdef CONFIG_ALPHA - -#include -#include -#include - -#endif /* alpha */ -#ifdef CONFIG_ARM - -/* arm */ -#include -#include -#include - -#endif /* arm */ -#ifdef CONFIG_AVR32 - -/* - * AVR32 can handle some unaligned accesses, depending on the - * implementation. The AVR32 AP implementation can handle unaligned - * words, but halfwords must be halfword-aligned, and doublewords must - * be word-aligned. - * - * However, swapped word loads must be word-aligned so we can't - * optimize word loads in general. - */ - -#include -#include -#include - -#endif -#ifdef CONFIG_BLACKFIN - -#include -#include -#include - -#endif /* blackfin */ -#ifdef CONFIG_CRIS - -/* - * CRIS can do unaligned accesses itself. - */ -#include -#include - -#endif /* cris */ -#ifdef CONFIG_FRV - -#include -#include -#include - -#endif /* frv */ -#ifdef CONFIG_H8300 - -#include -#include -#include - -#endif /* h8300 */ -#ifdef CONFIG_IA64 - -#include -#include -#include - -#endif /* ia64 */ -#ifdef CONFIG_M32R - -#if defined(__LITTLE_ENDIAN__) -# include -# include -# include -#else -# include -# include -# include -#endif - -#endif /* m32r */ -#ifdef CONFIG_M68K /* this handles both m68k and m68knommu */ - -#ifdef CONFIG_COLDFIRE -#include -#include -#include -#else - -/* - * The m68k can do unaligned accesses itself. - */ -#include -#include -#endif - -#endif /* m68k and m68knommu */ -#ifdef CONFIG_MIPS - -#if defined(__MIPSEB__) -# include -# include -# include -# define get_unaligned __get_unaligned_be -# define put_unaligned __put_unaligned_be -#elif defined(__MIPSEL__) -# include -# include -# include -#endif - -#endif /* mips */ -#ifdef CONFIG_MN10300 - -#include -#include - -#endif /* mn10300 */ -#ifdef CONFIG_PARISC - -#include -#include -#include - -#endif /* parisc */ -#ifdef CONFIG_PPC -/* - * The PowerPC can do unaligned accesses itself in big endian mode. - */ -#include -#include - -#endif /* ppc */ -#ifdef CONFIG_S390 - -/* - * The S390 can do unaligned accesses itself. - */ -#include -#include - -#endif /* s390 */ -#ifdef CONFIG_SUPERH - -/* SH can't handle unaligned accesses. */ -#ifdef __LITTLE_ENDIAN__ -# include -# include -# include -#else -# include -# include -# include -#endif - -#endif /* sh - SUPERH */ -#ifdef CONFIG_SPARC - -/* sparc and sparc64 */ -#include -#include -#include - -#endif /* sparc */ -#ifdef CONFIG_UML - -#include "asm/arch/unaligned.h" - -#endif /* um - uml */ -#ifdef CONFIG_V850 - -#include -#include -#include - -#endif /* v850 */ -#ifdef CONFIG_X86 -/* - * The x86 can do unaligned accesses itself. - */ -#include -#include - -#endif /* x86 */ -#ifdef CONFIG_XTENSA - -#ifdef __XTENSA_EL__ -# include -# include -# include -#elif defined(__XTENSA_EB__) -# include -# include -# include -#else -# error processor byte order undefined! -#endif - -#endif /* xtensa */ - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) */ - -#endif /* LINUX_26_26_COMPAT_H */ diff --git a/compat-2.6.27.c b/compat-2.6.27.c deleted file mode 100644 index 996aab5..0000000 --- a/compat-2.6.27.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.27 - */ - -#include "compat.h" - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) - -#include -#include -#include -#include -#include - -/* rfkill notification chain */ -#define RFKILL_STATE_CHANGED 0x0001 /* state of a normal rfkill - switch has changed */ - -/* - * e5899e1b7d73e67de758a32174a859cc2586c0b9 made pci_pme_capable() external, - * it was defined internally, some drivers want access to this information. - * - * Unfortunately the old kernels do not have ->pm_cap or ->pme_support so - * we have to call the PCI routines directly. - */ - -/** - * pci_pme_capable - check the capability of PCI device to generate PME# - * @dev: PCI device to handle. - * @state: PCI state from which device will issue PME#. - * - * This is the backport code for older kernels for compat-wireless, we read stuff - * from the initialization stuff from pci_pm_init(). - */ -bool pci_pme_capable(struct pci_dev *dev, pci_power_t state) -{ - int pm; - u16 pmc = 0; - u16 pme_support; /* as from the pci dev */ - /* find PCI PM capability in list */ - pm = pci_find_capability(dev, PCI_CAP_ID_PM); - if (!pm) - return false; - - if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { - dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n", - pmc & PCI_PM_CAP_VER_MASK); - return false; - } - - pmc &= PCI_PM_CAP_PME_MASK; - - if (!pmc) - return false; - - pme_support = pmc >> PCI_PM_CAP_PME_SHIFT; - - /* Check device's ability to generate PME# */ - - return !!(pme_support & (1 << state)); -} -EXPORT_SYMBOL(pci_pme_capable); - -/** - * mmc_align_data_size - pads a transfer size to a more optimal value - * @card: the MMC card associated with the data transfer - * @sz: original transfer size - * - * Pads the original data size with a number of extra bytes in - * order to avoid controller bugs and/or performance hits - * (e.g. some controllers revert to PIO for certain sizes). - * - * Returns the improved size, which might be unmodified. - * - * Note that this function is only relevant when issuing a - * single scatter gather entry. - */ -unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) -{ - /* - * FIXME: We don't have a system for the controller to tell - * the core about its problems yet, so for now we just 32-bit - * align the size. - */ - sz = ((sz + 3) / 4) * 4; - - return sz; -} -EXPORT_SYMBOL(mmc_align_data_size); - -/* - * Calculate the maximum byte mode transfer size - */ -static inline unsigned int sdio_max_byte_size(struct sdio_func *func) -{ - unsigned int mval = (unsigned int) min(func->card->host->max_seg_size, - func->card->host->max_blk_size); - mval = min(mval, func->max_blksize); - return min(mval, 512u); /* maximum size for byte mode */ -} - -/** - * sdio_align_size - pads a transfer size to a more optimal value - * @func: SDIO function - * @sz: original transfer size - * - * Pads the original data size with a number of extra bytes in - * order to avoid controller bugs and/or performance hits - * (e.g. some controllers revert to PIO for certain sizes). - * - * If possible, it will also adjust the size so that it can be - * handled in just a single request. - * - * Returns the improved size, which might be unmodified. - */ -unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz) -{ - unsigned int orig_sz; - unsigned int blk_sz, byte_sz; - unsigned chunk_sz; - - orig_sz = sz; - - /* - * Do a first check with the controller, in case it - * wants to increase the size up to a point where it - * might need more than one block. - */ - sz = mmc_align_data_size(func->card, sz); - - /* - * If we can still do this with just a byte transfer, then - * we're done. - */ - if (sz <= sdio_max_byte_size(func)) - return sz; - - if (func->card->cccr.multi_block) { - /* - * Check if the transfer is already block aligned - */ - if ((sz % func->cur_blksize) == 0) - return sz; - - /* - * Realign it so that it can be done with one request, - * and recheck if the controller still likes it. - */ - blk_sz = ((sz + func->cur_blksize - 1) / - func->cur_blksize) * func->cur_blksize; - blk_sz = mmc_align_data_size(func->card, blk_sz); - - /* - * This value is only good if it is still just - * one request. - */ - if ((blk_sz % func->cur_blksize) == 0) - return blk_sz; - - /* - * We failed to do one request, but at least try to - * pad the remainder properly. - */ - byte_sz = mmc_align_data_size(func->card, - sz % func->cur_blksize); - if (byte_sz <= sdio_max_byte_size(func)) { - blk_sz = sz / func->cur_blksize; - return blk_sz * func->cur_blksize + byte_sz; - } - } else { - /* - * We need multiple requests, so first check that the - * controller can handle the chunk size; - */ - chunk_sz = mmc_align_data_size(func->card, - sdio_max_byte_size(func)); - if (chunk_sz == sdio_max_byte_size(func)) { - /* - * Fix up the size of the remainder (if any) - */ - byte_sz = orig_sz % chunk_sz; - if (byte_sz) { - byte_sz = mmc_align_data_size(func->card, - byte_sz); - } - - return (orig_sz / chunk_sz) * chunk_sz + byte_sz; - } - } - - /* - * The controller is simply incapable of transferring the size - * we want in decent manner, so just return the original size. - */ - return orig_sz; -} -EXPORT_SYMBOL_GPL(sdio_align_size); - - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) */ - diff --git a/compat-2.6.27.h b/compat-2.6.27.h deleted file mode 100644 index ed10a6c..0000000 --- a/compat-2.6.27.h +++ /dev/null @@ -1,183 +0,0 @@ -#ifndef LINUX_26_27_COMPAT_H -#define LINUX_26_27_COMPAT_H - -#include -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PCI_PM_CAP_PME_SHIFT 11 - -/* I can't find a more suitable replacement... */ -#define flush_work(work) cancel_work_sync(work) - -/* - * On older kernels we do not have net_device Multi Queue support, but - * since we no longer use MQ on mac80211 we can simply use the 0 queue. - * Note that if other fullmac drivers make use of this they then need - * to be backported somehow or deal with just 1 queueue from MQ. - */ -static inline void netif_tx_wake_all_queues(struct net_device *dev) -{ - netif_wake_queue(dev); -} -static inline void netif_tx_start_all_queues(struct net_device *dev) -{ - netif_start_queue(dev); -} -static inline void netif_tx_stop_all_queues(struct net_device *dev) -{ - netif_stop_queue(dev); -} - -bool pci_pme_capable(struct pci_dev *dev, pci_power_t state); - -/* - * The net_device has a spin_lock on newer kernels, on older kernels we're out of luck - */ -#define netif_addr_lock_bh -#define netif_addr_unlock_bh - -/* - * To port this properly we'd have to port warn_slowpath_null(), - * which I'm lazy to do so just do a regular print for now. If you - * want to port this read kernel/panic.c - */ -#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0) - -/* This is ported directly as-is on newer kernels */ -#ifndef WARN -#define WARN(condition, format...) ({ \ - int __ret_warn_on = !!(condition); \ - if (unlikely(__ret_warn_on)) \ - __WARN_printf(format); \ - unlikely(__ret_warn_on); \ -}) -#endif - -/* On 2.6.27 a second argument was added, on older kernels we ignore it */ -#define dma_mapping_error(pdev, dma_addr) dma_mapping_error(dma_addr) -#define pci_dma_mapping_error(pdev, dma_addr) dma_mapping_error(pdev, dma_addr) - -/* This is from include/linux/ieee80211.h */ -#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 - -/* New link list changes added as of 2.6.27, needed for ath9k */ - -static inline void __list_cut_position(struct list_head *list, - struct list_head *head, struct list_head *entry) -{ - struct list_head *new_first = entry->next; - list->next = head->next; - list->next->prev = list; - list->prev = entry; - entry->next = list; - head->next = new_first; - new_first->prev = head; -} - -/** - * list_cut_position - cut a list into two - * @list: a new list to add all removed entries - * @head: a list with entries - * @entry: an entry within head, could be the head itself - * and if so we won't cut the list - * - * This helper moves the initial part of @head, up to and - * including @entry, from @head to @list. You should - * pass on @entry an element you know is on @head. @list - * should be an empty list or a list you do not care about - * losing its data. - * - */ -static inline void list_cut_position(struct list_head *list, - struct list_head *head, struct list_head *entry) -{ - if (list_empty(head)) - return; - if (list_is_singular(head) && - (head->next != entry && head != entry)) - return; - if (entry == head) - INIT_LIST_HEAD(list); - else - __list_cut_position(list, head, entry); -} - - -/* __list_splice as re-implemented on 2.6.27, we backport it */ -static inline void __compat_list_splice_new_27(const struct list_head *list, - struct list_head *prev, - struct list_head *next) -{ - struct list_head *first = list->next; - struct list_head *last = list->prev; - - first->prev = prev; - prev->next = first; - - last->next = next; - next->prev = last; -} - -/** - * list_splice_tail - join two lists, each list being a queue - * @list: the new list to add. - * @head: the place to add it in the first list. - */ -static inline void list_splice_tail(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) - __compat_list_splice_new_27(list, head->prev, head); -} - -/** - * list_splice_tail_init - join two lists and reinitialise the emptied list - * @list: the new list to add. - * @head: the place to add it in the first list. - * - * Each of the lists is a queue. - * The list at @list is reinitialised - */ -static inline void list_splice_tail_init(struct list_head *list, - struct list_head *head) -{ - if (!list_empty(list)) { - __compat_list_splice_new_27(list, head->prev, head); - INIT_LIST_HEAD(list); - } -} - -extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); -extern unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz); - -#define iwe_stream_add_value(info, event, value, ends, iwe, event_len) iwe_stream_add_value(event, value, ends, iwe, event_len) -#define iwe_stream_add_point(info, stream, ends, iwe, extra) iwe_stream_add_point(stream, ends, iwe, extra) -#define iwe_stream_add_event(info, stream, ends, iwe, event_len) iwe_stream_add_event(stream, ends, iwe, event_len) - -/* Flags available in struct iw_request_info */ -#define IW_REQUEST_FLAG_COMPAT 0x0001 /* Compat ioctl call */ - -static inline int iwe_stream_lcp_len(struct iw_request_info *info) -{ -#ifdef CONFIG_COMPAT - if (info->flags & IW_REQUEST_FLAG_COMPAT) - return IW_EV_COMPAT_LCP_LEN; -#endif - return IW_EV_LCP_LEN; -} - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) */ - -#endif /* LINUX_26_27_COMPAT_H */ diff --git a/compat-2.6.28.c b/compat-2.6.28.c deleted file mode 100644 index a8dfcbb..0000000 --- a/compat-2.6.28.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.28. - */ - -#include "compat.h" - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) - -#include - -/* 2.6.28 compat code goes here */ - -/* - * Compat-wireless notes for USB backport stuff: - * - * urb->reject exists on 2.6.27, the poison/unpoison helpers - * did not though. The anchor poison does not exist so we cannot use them. - * - * USB anchor poising seems to exist to prevent future driver sumbissions - * of usb_anchor_urb() to an anchor marked as poisoned. For older kernels - * we cannot use that, so new usb_anchor_urb()s will be anchored. The down - * side to this should be submission of URBs will continue being anchored - * on an anchor instead of having them being rejected immediately when the - * driver realized we needed to stop. For ar9170 we poison URBs upon the - * ar9170 mac80211 stop callback(), don't think this should be so bad. - * It mean there is period of time in older kernels for which we continue - * to anchor new URBs to a known stopped anchor. We have two anchors - * (TX, and RX) - */ - -#if 0 -/** - * usb_poison_urb - reliably kill a transfer and prevent further use of an URB - * @urb: pointer to URB describing a previously submitted request, - * may be NULL - * - * This routine cancels an in-progress request. It is guaranteed that - * upon return all completion handlers will have finished and the URB - * will be totally idle and cannot be reused. These features make - * this an ideal way to stop I/O in a disconnect() callback. - * If the request has not already finished or been unlinked - * the completion handler will see urb->status == -ENOENT. - * - * After and while the routine runs, attempts to resubmit the URB will fail - * with error -EPERM. Thus even if the URB's completion handler always - * tries to resubmit, it will not succeed and the URB will become idle. - * - * This routine may not be used in an interrupt context (such as a bottom - * half or a completion handler), or when holding a spinlock, or in other - * situations where the caller can't schedule(). - * - * This routine should not be called by a driver after its disconnect - * method has returned. - */ -void usb_poison_urb(struct urb *urb) -{ - might_sleep(); - if (!(urb && urb->dev && urb->ep)) - return; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) - spin_lock_irq(&usb_reject_lock); -#endif - ++urb->reject; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) - spin_unlock_irq(&usb_reject_lock); -#endif - /* - * XXX: usb_hcd_unlink_urb() needs backporting... this is defined - * on usb hcd.c but urb.c gets access to it. That is, older kernels - * have usb_hcd_unlink_urb() but its not exported, nor can we - * re-implement it exactly. This essentially dequeues the urb from - * hw, we need to figure out a way to backport this. - */ - //usb_hcd_unlink_urb(urb, -ENOENT); - - wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); -} -EXPORT_SYMBOL_GPL(usb_poison_urb); -#endif - -#include -struct pcmcia_cfg_mem { - tuple_t tuple; - cisparse_t parse; - u8 buf[256]; - cistpl_cftable_entry_t dflt; -}; -/** - * pcmcia_loop_config() - loop over configuration options - * @p_dev: the struct pcmcia_device which we need to loop for. - * @conf_check: function to call for each configuration option. - * It gets passed the struct pcmcia_device, the CIS data - * describing the configuration option, and private data - * being passed to pcmcia_loop_config() - * @priv_data: private data to be passed to the conf_check function. - * - * pcmcia_loop_config() loops over all configuration options, and calls - * the driver-specific conf_check() for each one, checking whether - * it is a valid one. Returns 0 on success or errorcode otherwise. - */ -int pcmcia_loop_config(struct pcmcia_device *p_dev, - int (*conf_check) (struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data), - void *priv_data) -{ - struct pcmcia_cfg_mem *cfg_mem; - - tuple_t *tuple; - int ret; - unsigned int vcc; - - cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); - if (cfg_mem == NULL) - return -ENOMEM; - - /* get the current Vcc setting */ - vcc = p_dev->socket->socket.Vcc; - - tuple = &cfg_mem->tuple; - tuple->TupleData = cfg_mem->buf; - tuple->TupleDataMax = 255; - tuple->TupleOffset = 0; - tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; - tuple->Attributes = 0; - - ret = pcmcia_get_first_tuple(p_dev, tuple); - while (!ret) { - cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry; - - if (pcmcia_get_tuple_data(p_dev, tuple)) - goto next_entry; - - if (pcmcia_parse_tuple(tuple, &cfg_mem->parse)) - goto next_entry; - - /* default values */ - p_dev->conf.ConfigIndex = cfg->index; - if (cfg->flags & CISTPL_CFTABLE_DEFAULT) - cfg_mem->dflt = *cfg; - - ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data); - if (!ret) - break; - -next_entry: - ret = pcmcia_get_next_tuple(p_dev, tuple); - } - - return ret; -} -EXPORT_SYMBOL(pcmcia_loop_config); - -void usb_unpoison_urb(struct urb *urb) -{ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) - unsigned long flags; -#endif - - if (!urb) - return; - -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) - spin_lock_irqsave(&usb_reject_lock, flags); -#endif - --urb->reject; -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) - spin_unlock_irqrestore(&usb_reject_lock, flags); -#endif -} -EXPORT_SYMBOL_GPL(usb_unpoison_urb); - - -#if 0 -/** - * usb_poison_anchored_urbs - cease all traffic from an anchor - * @anchor: anchor the requests are bound to - * - * this allows all outstanding URBs to be poisoned starting - * from the back of the queue. Newly added URBs will also be - * poisoned - * - * This routine should not be called by a driver after its disconnect - * method has returned. - */ -void usb_poison_anchored_urbs(struct usb_anchor *anchor) -{ - struct urb *victim; - - spin_lock_irq(&anchor->lock); - // anchor->poisoned = 1; /* XXX: Cannot backport */ - while (!list_empty(&anchor->urb_list)) { - victim = list_entry(anchor->urb_list.prev, struct urb, - anchor_list); - /* we must make sure the URB isn't freed before we kill it*/ - usb_get_urb(victim); - spin_unlock_irq(&anchor->lock); - /* this will unanchor the URB */ - usb_poison_urb(victim); - usb_put_urb(victim); - spin_lock_irq(&anchor->lock); - } - spin_unlock_irq(&anchor->lock); -} -EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs); -#endif - -/** - * usb_get_from_anchor - get an anchor's oldest urb - * @anchor: the anchor whose urb you want - * - * this will take the oldest urb from an anchor, - * unanchor and return it - */ -struct urb *usb_get_from_anchor(struct usb_anchor *anchor) -{ - struct urb *victim; - unsigned long flags; - - spin_lock_irqsave(&anchor->lock, flags); - if (!list_empty(&anchor->urb_list)) { - victim = list_entry(anchor->urb_list.next, struct urb, - anchor_list); - usb_get_urb(victim); - spin_unlock_irqrestore(&anchor->lock, flags); - usb_unanchor_urb(victim); - } else { - spin_unlock_irqrestore(&anchor->lock, flags); - victim = NULL; - } - - return victim; -} - -EXPORT_SYMBOL_GPL(usb_get_from_anchor); - -/** - * usb_scuttle_anchored_urbs - unanchor all an anchor's urbs - * @anchor: the anchor whose urbs you want to unanchor - * - * use this to get rid of all an anchor's urbs - */ -void usb_scuttle_anchored_urbs(struct usb_anchor *anchor) -{ - struct urb *victim; - unsigned long flags; - - spin_lock_irqsave(&anchor->lock, flags); - while (!list_empty(&anchor->urb_list)) { - victim = list_entry(anchor->urb_list.prev, struct urb, - anchor_list); - usb_get_urb(victim); - spin_unlock_irqrestore(&anchor->lock, flags); - /* this may free the URB */ - usb_unanchor_urb(victim); - usb_put_urb(victim); - spin_lock_irqsave(&anchor->lock, flags); - } - spin_unlock_irqrestore(&anchor->lock, flags); -} - -EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs); - -/** - * usb_anchor_empty - is an anchor empty - * @anchor: the anchor you want to query - * - * returns 1 if the anchor has no urbs associated with it - */ -int usb_anchor_empty(struct usb_anchor *anchor) -{ - return list_empty(&anchor->urb_list); -} - -EXPORT_SYMBOL_GPL(usb_anchor_empty); - - -void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) -{ - /* - * Make sure the BAR is actually a memory resource, not an IO resource - */ - if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { - WARN_ON(1); - return NULL; - } - return ioremap_nocache(pci_resource_start(pdev, bar), - pci_resource_len(pdev, bar)); -} -EXPORT_SYMBOL_GPL(pci_ioremap_bar); - -static unsigned long round_jiffies_common(unsigned long j, int cpu, - bool force_up) -{ - int rem; - unsigned long original = j; - - /* - * We don't want all cpus firing their timers at once hitting the - * same lock or cachelines, so we skew each extra cpu with an extra - * 3 jiffies. This 3 jiffies came originally from the mm/ code which - * already did this. - * The skew is done by adding 3*cpunr, then round, then subtract this - * extra offset again. - */ - j += cpu * 3; - - rem = j % HZ; - - /* - * If the target jiffie is just after a whole second (which can happen - * due to delays of the timer irq, long irq off times etc etc) then - * we should round down to the whole second, not up. Use 1/4th second - * as cutoff for this rounding as an extreme upper bound for this. - * But never round down if @force_up is set. - */ - if (rem < HZ/4 && !force_up) /* round down */ - j = j - rem; - else /* round up */ - j = j - rem + HZ; - - /* now that we have rounded, subtract the extra skew again */ - j -= cpu * 3; - - if (j <= jiffies) /* rounding ate our timeout entirely; */ - return original; - return j; -} - -/** - * round_jiffies_up - function to round jiffies up to a full second - * @j: the time in (absolute) jiffies that should be rounded - * - * This is the same as round_jiffies() except that it will never - * round down. This is useful for timeouts for which the exact time - * of firing does not matter too much, as long as they don't fire too - * early. - */ -unsigned long round_jiffies_up(unsigned long j) -{ - return round_jiffies_common(j, raw_smp_processor_id(), true); -} -EXPORT_SYMBOL_GPL(round_jiffies_up); - -void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, - int size) -{ - skb_fill_page_desc(skb, i, page, off, size); - skb->len += size; - skb->data_len += size; - skb->truesize += size; -} -EXPORT_SYMBOL(skb_add_rx_frag); - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) */ diff --git a/compat-2.6.28.h b/compat-2.6.28.h deleted file mode 100644 index 8f90edc..0000000 --- a/compat-2.6.28.h +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef LINUX_26_28_COMPAT_H -#define LINUX_26_28_COMPAT_H - -#include -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) - -#include -#include -#include - -#ifndef ETH_P_PAE -#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -#endif - -#include - -#ifndef WARN_ONCE -#define WARN_ONCE(condition, format...) ({ \ - static int __warned; \ - int __ret_warn_once = !!(condition); \ - \ - if (unlikely(__ret_warn_once)) \ - if (WARN(!__warned, format)) \ - __warned = 1; \ - unlikely(__ret_warn_once); \ -}) -#endif /* From include/asm-generic/bug.h */ - -#include -#include -#include -#ifdef pcmcia_parse_tuple -#undef pcmcia_parse_tuple -#define pcmcia_parse_tuple(tuple, parse) pccard_parse_tuple(tuple, parse) -#endif - -/* From : include/pcmcia/ds.h */ -/* loop CIS entries for valid configuration */ -int pcmcia_loop_config(struct pcmcia_device *p_dev, - int (*conf_check) (struct pcmcia_device *p_dev, - cistpl_cftable_entry_t *cfg, - cistpl_cftable_entry_t *dflt, - unsigned int vcc, - void *priv_data), - void *priv_data); - -#if 0 -extern void usb_poison_urb(struct urb *urb); -#endif -extern void usb_unpoison_urb(struct urb *urb); - -#if 0 -extern void usb_poison_anchored_urbs(struct usb_anchor *anchor); -#endif - -extern struct urb *usb_get_from_anchor(struct usb_anchor *anchor); -extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor); -extern int usb_anchor_empty(struct usb_anchor *anchor); - - -void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar); - -/** - * skb_queue_is_last - check if skb is the last entry in the queue - * @list: queue head - * @skb: buffer - * - * Returns true if @skb is the last buffer on the list. - */ -static inline bool skb_queue_is_last(const struct sk_buff_head *list, - const struct sk_buff *skb) -{ - return (skb->next == (struct sk_buff *) list); -} - -/** - * skb_queue_next - return the next packet in the queue - * @list: queue head - * @skb: current buffer - * - * Return the next packet in @list after @skb. It is only valid to - * call this if skb_queue_is_last() evaluates to false. - */ -static inline struct sk_buff *skb_queue_next(const struct sk_buff_head *list, - const struct sk_buff *skb) -{ - /* This BUG_ON may seem severe, but if we just return then we - * are going to dereference garbage. - */ - BUG_ON(skb_queue_is_last(list, skb)); - return skb->next; -} - -/** - * __skb_queue_head_init - initialize non-spinlock portions of sk_buff_head - * @list: queue to initialize - * - * This initializes only the list and queue length aspects of - * an sk_buff_head object. This allows to initialize the list - * aspects of an sk_buff_head without reinitializing things like - * the spinlock. It can also be used for on-stack sk_buff_head - * objects where the spinlock is known to not be used. - */ -static inline void __skb_queue_head_init(struct sk_buff_head *list) -{ - list->prev = list->next = (struct sk_buff *)list; - list->qlen = 0; -} - -static inline void __skb_queue_splice(const struct sk_buff_head *list, - struct sk_buff *prev, - struct sk_buff *next) -{ - struct sk_buff *first = list->next; - struct sk_buff *last = list->prev; - - first->prev = prev; - prev->next = first; - - last->next = next; - next->prev = last; -} - -/** - * skb_queue_splice - join two skb lists, this is designed for stacks - * @list: the new list to add - * @head: the place to add it in the first list - */ -static inline void skb_queue_splice(const struct sk_buff_head *list, - struct sk_buff_head *head) -{ - if (!skb_queue_empty(list)) { - __skb_queue_splice(list, (struct sk_buff *) head, head->next); - head->qlen += list->qlen; - } -} - -/** - * skb_queue_splice_tail - join two skb lists and reinitialise the emptied list - * @list: the new list to add - * @head: the place to add it in the first list - * - * Each of the lists is a queue. - * The list at @list is reinitialised - */ -static inline void skb_queue_splice_tail_init(struct sk_buff_head *list, - struct sk_buff_head *head) -{ - if (!skb_queue_empty(list)) { - __skb_queue_splice(list, head->prev, (struct sk_buff *) head); - head->qlen += list->qlen; - __skb_queue_head_init(list); - } -} /* From include/linux/skbuff.h */ - -/** - * skb_queue_splice_tail - join two skb lists, each list being a queue - * @list: the new list to add - * @head: the place to add it in the first list - */ -static inline void skb_queue_splice_tail(const struct sk_buff_head *list, - struct sk_buff_head *head) -{ - if (!skb_queue_empty(list)) { - __skb_queue_splice(list, head->prev, (struct sk_buff *) head); - head->qlen += list->qlen; - } -} - -#ifndef DECLARE_TRACE - -#define TP_PROTO(args...) args -#define TP_ARGS(args...) args - -#define DECLARE_TRACE(name, proto, args) \ - static inline void _do_trace_##name(struct tracepoint *tp, proto) \ - { } \ - static inline void trace_##name(proto) \ - { } \ - static inline int register_trace_##name(void (*probe)(proto)) \ - { \ - return -ENOSYS; \ - } \ - static inline int unregister_trace_##name(void (*probe)(proto)) \ - { \ - return -ENOSYS; \ - } - -#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) -#define EXPORT_TRACEPOINT_SYMBOL(name) - - -#endif - -/* openSuse includes round_jiffies_up in it's kernel 2.6.27. - * This is needed to prevent conflicts with the openSuse definition. - */ -#define round_jiffies_up backport_round_jiffies_up - -unsigned long round_jiffies_up(unsigned long j); - -extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, - int off, int size); - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) */ - -#endif /* LINUX_26_28_COMPAT_H */ diff --git a/compat-2.6.29.c b/compat-2.6.29.c deleted file mode 100644 index 664be92..0000000 --- a/compat-2.6.29.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.29. - */ - -#include "compat.h" - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) - -#include - -/** - * usb_unpoison_anchored_urbs - let an anchor be used successfully again - * @anchor: anchor the requests are bound to - * - * Reverses the effect of usb_poison_anchored_urbs - * the anchor can be used normally after it returns - */ -void usb_unpoison_anchored_urbs(struct usb_anchor *anchor) -{ - unsigned long flags; - struct urb *lazarus; - - spin_lock_irqsave(&anchor->lock, flags); - list_for_each_entry(lazarus, &anchor->urb_list, anchor_list) { - usb_unpoison_urb(lazarus); - } - //anchor->poisoned = 0; /* XXX: cannot backport */ - spin_unlock_irqrestore(&anchor->lock, flags); -} -EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs); - - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */ - diff --git a/compat-2.6.29.h b/compat-2.6.29.h deleted file mode 100644 index cad5e6b..0000000 --- a/compat-2.6.29.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef LINUX_26_29_COMPAT_H -#define LINUX_26_29_COMPAT_H - -#include -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) - -#include -#include -#include - -/** - * skb_queue_is_first - check if skb is the first entry in the queue - * @list: queue head - * @skb: buffer - * - * Returns true if @skb is the first buffer on the list. - */ -static inline bool skb_queue_is_first(const struct sk_buff_head *list, - const struct sk_buff *skb) -{ - return (skb->prev == (struct sk_buff *) list); -} - -/** - * skb_queue_prev - return the prev packet in the queue - * @list: queue head - * @skb: current buffer - * - * Return the prev packet in @list before @skb. It is only valid to - * call this if skb_queue_is_first() evaluates to false. - */ -static inline struct sk_buff *skb_queue_prev(const struct sk_buff_head *list, - const struct sk_buff *skb) -{ - /* This BUG_ON may seem severe, but if we just return then we - * are going to dereference garbage. - */ - BUG_ON(skb_queue_is_first(list, skb)); - return skb->prev; -} - - -static inline struct net_device_stats *dev_get_stats(struct net_device *dev) -{ - return dev->get_stats(dev); -} - -extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor); - -#define DIV_ROUND_CLOSEST(x, divisor)( \ -{ \ - typeof(divisor) __divisor = divisor; \ - (((x) + ((__divisor) / 2)) / (__divisor)); \ -} \ -) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) */ - -#endif /* LINUX_26_29_COMPAT_H */ diff --git a/compat-2.6.30.c b/compat-2.6.30.c deleted file mode 100644 index 6e0d69c..0000000 --- a/compat-2.6.30.c +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.30. - */ - -#include "compat.h" - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) - -/* 2.6.30 compat code goes here */ - -#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) */ - diff --git a/compat-2.6.30.h b/compat-2.6.30.h deleted file mode 100644 index 2ff1d69..0000000 --- a/compat-2.6.30.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef LINUX_26_30_COMPAT_H -#define LINUX_26_30_COMPAT_H - -#include -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) - -#ifndef TP_PROTO -#define TP_PROTO(args...) TPPROTO(args) -#endif -#ifndef TP_ARGS -#define TP_ARGS(args...) TPARGS(args) -#endif - -#define IRQ_WAKE_THREAD (2) - -/* From : include/linux/pm.h */ -/* How to reorder dpm_list after device_move() */ -enum dpm_order { - DPM_ORDER_NONE, - DPM_ORDER_DEV_AFTER_PARENT, - DPM_ORDER_PARENT_BEFORE_DEV, - DPM_ORDER_DEV_LAST, -}; - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) */ - -#endif /* LINUX_26_30_COMPAT_H */ diff --git a/compat-2.6.31.c b/compat-2.6.31.c deleted file mode 100644 index 90b6a41..0000000 --- a/compat-2.6.31.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.31. - */ - -#include "compat.h" - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) - -#include - -/** - * genl_register_family_with_ops - register a generic netlink family - * @family: generic netlink family - * @ops: operations to be registered - * @n_ops: number of elements to register - * - * Registers the specified family and operations from the specified table. - * Only one family may be registered with the same family name or identifier. - * - * The family id may equal GENL_ID_GENERATE causing an unique id to - * be automatically generated and assigned. - * - * Either a doit or dumpit callback must be specified for every registered - * operation or the function will fail. Only one operation structure per - * command identifier may be registered. - * - * See include/net/genetlink.h for more documenation on the operations - * structure. - * - * This is equivalent to calling genl_register_family() followed by - * genl_register_ops() for every operation entry in the table taking - * care to unregister the family on error path. - * - * Return 0 on success or a negative error code. - */ -int genl_register_family_with_ops(struct genl_family *family, - struct genl_ops *ops, size_t n_ops) -{ - int err, i; - - err = genl_register_family(family); - if (err) - return err; - - for (i = 0; i < n_ops; ++i, ++ops) { - err = genl_register_ops(family, ops); - if (err) - goto err_out; - } - return 0; -err_out: - genl_unregister_family(family); - return err; -} -EXPORT_SYMBOL(genl_register_family_with_ops); - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) */ - diff --git a/compat-2.6.31.h b/compat-2.6.31.h deleted file mode 100644 index 27dc6a1..0000000 --- a/compat-2.6.31.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef LINUX_26_31_COMPAT_H -#define LINUX_26_31_COMPAT_H - -#include -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) - -#include -#include -#include -#include -#include -#include - -/* - * These macros allow us to backport rfkill without any - * changes on cfg80211 through compat.diff. Note that this - * file will be included by rfkill_backport.h so we must - * not conflict with things there. - */ -#define rfkill_get_led_trigger_name backport_rfkill_get_led_trigger_name -#define rfkill_set_led_trigger_name backport_rfkill_set_led_trigger_name -#define rfkill_set_hw_state backport_rfkill_set_hw_state -#define rfkill_set_sw_state backport_rfkill_set_sw_state -#define rfkill_init_sw_state backport_rfkill_init_sw_state -#define rfkill_set_states backport_rfkill_set_states -#define rfkill_pause_polling backport_rfkill_pause_polling -#define rfkill_resume_polling backport_rfkill_resume_polling -#define rfkill_blocked backport_rfkill_blocked -#define rfkill_alloc backport_rfkill_alloc -#define rfkill_register backport_rfkill_register -#define rfkill_unregister backport_rfkill_unregister -#define rfkill_destroy backport_rfkill_destroy - -#ifndef ERFKILL -#if !defined(CONFIG_ALPHA) && !defined(CONFIG_MIPS) && !defined(CONFIG_PARISC) && !defined(CONFIG_SPARC) -#define ERFKILL 132 /* Operation not possible due to RF-kill */ -#endif -#ifdef CONFIG_ALPHA -#define ERFKILL 138 /* Operation not possible due to RF-kill */ -#endif -#ifdef CONFIG_MIPS -#define ERFKILL 167 /* Operation not possible due to RF-kill */ -#endif -#ifdef CONFIG_PARISC -#define ERFKILL 256 /* Operation not possible due to RF-kill */ -#endif -#ifdef CONFIG_SPARC -#define ERFKILL 134 /* Operation not possible due to RF-kill */ -#endif -#endif - -#ifndef NETDEV_PRE_UP -#define NETDEV_PRE_UP 0x000D -#endif - -#ifndef SDIO_DEVICE_ID_MARVELL_8688WLAN -#define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 -#endif - -struct compat_threaded_irq { - unsigned int irq; - irq_handler_t handler; - irq_handler_t thread_fn; - void *dev_id; - char wq_name[64]; - struct workqueue_struct *wq; - struct work_struct work; -}; - -/* - * kmemleak was introduced on 2.6.31, since older kernels do not have - * we simply ignore its tuning. - */ -static inline void kmemleak_ignore(const void *ptr) -{ - return; -} - -static inline void kmemleak_not_leak(const void *ptr) -{ - return; -} - -static inline void kmemleak_no_scan(const void *ptr) -{ - return; -} - -/* - * Added via adf30907d63893e4208dfe3f5c88ae12bc2f25d5 - * - * There is no _sk_dst on older kernels, so just set the - * old dst to NULL and release it directly. - */ -static inline void skb_dst_drop(struct sk_buff *skb) -{ - dst_release(skb->dst); - skb->dst = NULL; -} - -static inline struct dst_entry *skb_dst(const struct sk_buff *skb) -{ - return (struct dst_entry *)skb->dst; -} - -static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst) -{ - skb->dst = dst; -} - -static inline struct rtable *skb_rtable(const struct sk_buff *skb) -{ - return (struct rtable *)skb_dst(skb); -} - -extern int genl_register_family_with_ops(struct genl_family *family, - struct genl_ops *ops, size_t n_ops); - - -/* Backport threaded IRQ support */ - -static inline -void compat_irq_work(struct work_struct *work) -{ - struct compat_threaded_irq *comp = container_of(work, struct compat_threaded_irq, work); - comp->thread_fn(comp->irq, comp->dev_id); -} - -static inline -irqreturn_t compat_irq_dispatcher(int irq, void *dev_id) -{ - struct compat_threaded_irq *comp = dev_id; - irqreturn_t res; - - res = comp->handler(irq, comp->dev_id); - if (res == IRQ_WAKE_THREAD) { - queue_work(comp->wq, &comp->work); - res = IRQ_HANDLED; - } - - return res; -} - -static inline -int compat_request_threaded_irq(struct compat_threaded_irq *comp, - unsigned int irq, - irq_handler_t handler, - irq_handler_t thread_fn, - unsigned long flags, - const char *name, - void *dev_id) -{ - comp->irq = irq; - comp->handler = handler; - comp->thread_fn = thread_fn; - comp->dev_id = dev_id; - INIT_WORK(&comp->work, compat_irq_work); - - if (!comp->wq) { - snprintf(comp->wq_name, sizeof(comp->wq_name), - "compirq/%u-%s", irq, name); - comp->wq = create_singlethread_workqueue(comp->wq_name); - if (!comp->wq) { - printk(KERN_ERR "Failed to create compat-threaded-IRQ workqueue %s\n", - comp->wq_name); - return -ENOMEM; - } - } - return request_irq(irq, compat_irq_dispatcher, flags, name, comp); -} - -static inline -void compat_free_threaded_irq(struct compat_threaded_irq *comp) -{ - free_irq(comp->irq, comp); -} - -static inline -void compat_destroy_threaded_irq(struct compat_threaded_irq *comp) -{ - if (comp->wq) - destroy_workqueue(comp->wq); - comp->wq = NULL; -} - -static inline -void compat_synchronize_threaded_irq(struct compat_threaded_irq *comp) -{ - synchronize_irq(comp->irq); - cancel_work_sync(&comp->work); -} - - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) */ - -#endif /* LINUX_26_31_COMPAT_H */ diff --git a/compat-2.6.32.c b/compat-2.6.32.c deleted file mode 100644 index 5d085e6..0000000 --- a/compat-2.6.32.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2007 Luis R. Rodriguez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Compatibility file for Linux wireless for kernels 2.6.32. - */ - -#include "compat.h" - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) - -#include - -int __dev_addr_add(struct dev_addr_list **list, int *count, - void *addr, int alen, int glbl) -{ - struct dev_addr_list *da; - - for (da = *list; da != NULL; da = da->next) { - if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && - da->da_addrlen == alen) { - if (glbl) { - int old_glbl = da->da_gusers; - da->da_gusers = 1; - if (old_glbl) - return 0; - } - da->da_users++; - return 0; - } - } - - da = kzalloc(sizeof(*da), GFP_ATOMIC); - if (da == NULL) - return -ENOMEM; - memcpy(da->da_addr, addr, alen); - da->da_addrlen = alen; - da->da_users = 1; - da->da_gusers = glbl ? 1 : 0; - da->next = *list; - *list = da; - (*count)++; - return 0; -} - -int __dev_addr_delete(struct dev_addr_list **list, int *count, - void *addr, int alen, int glbl) -{ - struct dev_addr_list *da; - - for (; (da = *list) != NULL; list = &da->next) { - if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && - alen == da->da_addrlen) { - if (glbl) { - int old_glbl = da->da_gusers; - da->da_gusers = 0; - if (old_glbl == 0) - break; - } - if (--da->da_users) - return 0; - - *list = da->next; - kfree(da); - (*count)--; - return 0; - } - } - return -ENOENT; -} - -int __dev_addr_sync(struct dev_addr_list **to, int *to_count, - struct dev_addr_list **from, int *from_count) -{ - struct dev_addr_list *da, *next; - int err = 0; - - da = *from; - while (da != NULL) { - next = da->next; - if (!da->da_synced) { - err = __dev_addr_add(to, to_count, - da->da_addr, da->da_addrlen, 0); - if (err < 0) - break; - da->da_synced = 1; - da->da_users++; - } else if (da->da_users == 1) { - __dev_addr_delete(to, to_count, - da->da_addr, da->da_addrlen, 0); - __dev_addr_delete(from, from_count, - da->da_addr, da->da_addrlen, 0); - } - da = next; - } - return err; -} -EXPORT_SYMBOL_GPL(__dev_addr_sync); - -void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, - struct dev_addr_list **from, int *from_count) -{ - struct dev_addr_list *da, *next; - - da = *from; - while (da != NULL) { - next = da->next; - if (da->da_synced) { - __dev_addr_delete(to, to_count, - da->da_addr, da->da_addrlen, 0); - da->da_synced = 0; - __dev_addr_delete(from, from_count, - da->da_addr, da->da_addrlen, 0); - } - da = next; - } -} -EXPORT_SYMBOL_GPL(__dev_addr_unsync); - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) */ - diff --git a/compat-2.6.32.h b/compat-2.6.32.h deleted file mode 100644 index 3e8725a..0000000 --- a/compat-2.6.32.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef LINUX_26_32_COMPAT_H -#define LINUX_26_32_COMPAT_H - -#include -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) - -#include -#include - -#define SDIO_VENDOR_ID_INTEL 0x0089 -#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402 -#define SDIO_DEVICE_ID_INTEL_IWMC3200WIFI 0x1403 -#define SDIO_DEVICE_ID_INTEL_IWMC3200TOP 0x1404 -#define SDIO_DEVICE_ID_INTEL_IWMC3200GPS 0x1405 -#define SDIO_DEVICE_ID_INTEL_IWMC3200BT 0x1406 - -/* - * struct genl_multicast_group was made netns aware through - * patch "genetlink: make netns aware" by johannes, we just - * force this to always use the default init_net - */ -#define genl_info_net(x) &init_net -/* Just use init_net for older kernels */ -#define get_net_ns_by_pid(x) &init_net - -/* net namespace is lost */ -#define genlmsg_multicast_netns(a, b, c, d, e) genlmsg_multicast(b, c, d, e) -#define genlmsg_multicast_allns(a, b, c, d) genlmsg_multicast(a, b, c, d) - -#define dev_change_net_namespace(a, b, c) (-EOPNOTSUPP) - -#define SET_NETDEV_DEVTYPE(netdev, type) - -#ifdef __KERNEL__ -/* Driver transmit return codes */ -enum netdev_tx { - BACKPORT_NETDEV_TX_OK = NETDEV_TX_OK, /* driver took care of packet */ - BACKPORT_NETDEV_TX_BUSY = NETDEV_TX_BUSY, /* driver tx path was busy*/ - BACKPORT_NETDEV_TX_LOCKED = NETDEV_TX_LOCKED, /* driver tx lock was already taken */ -}; -typedef enum netdev_tx netdev_tx_t; -#endif /* __KERNEL__ */ - -/* - * dev_pm_ops is only available on kernels >= 2.6.29, for - * older kernels we rely on reverting the work to old - * power management style stuff. - */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) -/* - * Use this if you want to use the same suspend and resume callbacks for suspend - * to RAM and hibernation. - */ -#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ -struct dev_pm_ops name = { \ - .suspend = suspend_fn, \ - .resume = resume_fn, \ - .freeze = suspend_fn, \ - .thaw = resume_fn, \ - .poweroff = suspend_fn, \ - .restore = resume_fn, \ -} -#else -#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) -#endif /* >= 2.6.29 */ - -#define wireless_send_event(a, b, c, d) wireless_send_event(a, b, c, (char * ) d) - -/* The export symbol in changed in compat/patches/15-symbol-export-conflicts.patch */ -#define ieee80211_rx(hw, skb) mac80211_ieee80211_rx(hw, skb) - -#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) */ - -#endif /* LINUX_26_32_COMPAT_H */ diff --git a/compat.h b/compat.h deleted file mode 100644 index ceedc47..0000000 --- a/compat.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef LINUX_26_COMPAT_H -#define LINUX_26_COMPAT_H - -#include -#include - -/* - * Each compat file represents compatibility code for new kernel - * code introduced for *that* kernel revision. - */ - -#include "compat-2.6.14.h" -#include "compat-2.6.18.h" -#include "compat-2.6.19.h" -#include "compat-2.6.21.h" -#include "compat-2.6.22.h" -#include "compat-2.6.23.h" -#include "compat-2.6.24.h" -#include "compat-2.6.25.h" -#include "compat-2.6.26.h" -#include "compat-2.6.27.h" -#include "compat-2.6.28.h" -#include "compat-2.6.29.h" -#include "compat-2.6.30.h" -#include "compat-2.6.31.h" -#include "compat-2.6.32.h" - -#endif /* LINUX_26_COMPAT_H */ diff --git a/compat/Makefile b/compat/Makefile new file mode 100644 index 0000000..20d80e2 --- /dev/null +++ b/compat/Makefile @@ -0,0 +1,21 @@ +obj-m += compat.o +#compat-objs := + +compat-y += main.o + +# Compat kernel compatibility code +compat-$(CONFIG_COMPAT_KERNEL_14) += compat-2.6.14.o +compat-$(CONFIG_COMPAT_KERNEL_18) += compat-2.6.18.o +compat-$(CONFIG_COMPAT_KERNEL_19) += compat-2.6.19.o +compat-$(CONFIG_COMPAT_KERNEL_21) += compat-2.6.21.o +compat-$(CONFIG_COMPAT_KERNEL_22) += compat-2.6.22.o +compat-$(CONFIG_COMPAT_KERNEL_23) += compat-2.6.23.o +compat-$(CONFIG_COMPAT_KERNEL_24) += compat-2.6.24.o +compat-$(CONFIG_COMPAT_KERNEL_25) += compat-2.6.25.o +compat-$(CONFIG_COMPAT_KERNEL_26) += compat-2.6.26.o +compat-$(CONFIG_COMPAT_KERNEL_27) += compat-2.6.27.o +compat-$(CONFIG_COMPAT_KERNEL_28) += compat-2.6.28.o +compat-$(CONFIG_COMPAT_KERNEL_29) += compat-2.6.29.o +compat-$(CONFIG_COMPAT_KERNEL_30) += compat-2.6.30.o +compat-$(CONFIG_COMPAT_KERNEL_31) += compat-2.6.31.o +compat-$(CONFIG_COMPAT_KERNEL_32) += compat-2.6.32.o diff --git a/compat/compat-2.6.14.c b/compat/compat-2.6.14.c new file mode 100644 index 0000000..e0af181 --- /dev/null +++ b/compat/compat-2.6.14.c @@ -0,0 +1,18 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.14. + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) + +/* 2.6.14 compat code goes here */ + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) */ + diff --git a/compat/compat-2.6.18.c b/compat/compat-2.6.18.c new file mode 100644 index 0000000..c7fb2e4 --- /dev/null +++ b/compat/compat-2.6.18.c @@ -0,0 +1,18 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.18. + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) + +/* 2.6.18 compat code goes here */ + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) */ + diff --git a/compat/compat-2.6.19.c b/compat/compat-2.6.19.c new file mode 100644 index 0000000..fc75b64 --- /dev/null +++ b/compat/compat-2.6.19.c @@ -0,0 +1,18 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.19. + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) + +/* 2.6.19 compat code goes here */ + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */ + diff --git a/compat/compat-2.6.21.c b/compat/compat-2.6.21.c new file mode 100644 index 0000000..e2737fb --- /dev/null +++ b/compat/compat-2.6.21.c @@ -0,0 +1,18 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.21. + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + +/* 2.6.21 compat code goes here */ + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21) */ + diff --git a/compat/compat-2.6.22.c b/compat/compat-2.6.22.c new file mode 100644 index 0000000..b1ff1f3 --- /dev/null +++ b/compat/compat-2.6.22.c @@ -0,0 +1,18 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.22. + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) + +/* 2.6.22 compat code goes here */ + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) */ + diff --git a/compat/compat-2.6.23.c b/compat/compat-2.6.23.c new file mode 100644 index 0000000..d232b1a --- /dev/null +++ b/compat/compat-2.6.23.c @@ -0,0 +1,185 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.23. + */ + +#include + +/* All things not in 2.6.22 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + +/* Part of net/core/dev_mcast.c as of 2.6.23. This is a slightly different version. + * Since da->da_synced is not part of 2.6.22 we need to take longer route when + * syncing */ + +/** + * dev_mc_sync - Synchronize device's multicast list to another device + * @to: destination device + * @from: source device + * + * Add newly added addresses to the destination device and release + * addresses that have no users left. The source device must be + * locked by netif_tx_lock_bh. + * + * This function is intended to be called from the dev->set_multicast_list + * function of layered software devices. + */ +int dev_mc_sync(struct net_device *to, struct net_device *from) +{ + struct dev_addr_list *da, *next, *da_to; + int err = 0; + + netif_tx_lock_bh(to); + da = from->mc_list; + while (da != NULL) { + int synced = 0; + next = da->next; + da_to = to->mc_list; + /* 2.6.22 does not have da->da_synced so lets take the long route */ + while (da_to != NULL) { + if (memcmp(da_to->da_addr, da->da_addr, da_to->da_addrlen) == 0 && + da->da_addrlen == da_to->da_addrlen) + synced = 1; + break; + } + if (!synced) { + err = __dev_addr_add(&to->mc_list, &to->mc_count, + da->da_addr, da->da_addrlen, 0); + if (err < 0) + break; + da->da_users++; + } else if (da->da_users == 1) { + __dev_addr_delete(&to->mc_list, &to->mc_count, + da->da_addr, da->da_addrlen, 0); + __dev_addr_delete(&from->mc_list, &from->mc_count, + da->da_addr, da->da_addrlen, 0); + } + da = next; + } + if (!err) + __dev_set_rx_mode(to); + netif_tx_unlock_bh(to); + + return err; +} +EXPORT_SYMBOL(dev_mc_sync); + + +/* Part of net/core/dev_mcast.c as of 2.6.23. This is a slighty different version. + * Since da->da_synced is not part of 2.6.22 we need to take longer route when + * unsyncing */ + +/** + * dev_mc_unsync - Remove synchronized addresses from the destination + * device + * @to: destination device + * @from: source device + * + * Remove all addresses that were added to the destination device by + * dev_mc_sync(). This function is intended to be called from the + * dev->stop function of layered software devices. + */ +void dev_mc_unsync(struct net_device *to, struct net_device *from) +{ + struct dev_addr_list *da, *next, *da_to; + + netif_tx_lock_bh(from); + netif_tx_lock_bh(to); + + da = from->mc_list; + while (da != NULL) { + bool synced = false; + next = da->next; + da_to = to->mc_list; + /* 2.6.22 does not have da->da_synced so lets take the long route */ + while (da_to != NULL) { + if (memcmp(da_to->da_addr, da->da_addr, da_to->da_addrlen) == 0 && + da->da_addrlen == da_to->da_addrlen) + synced = true; + break; + } + if (!synced) { + da = next; + continue; + } + __dev_addr_delete(&to->mc_list, &to->mc_count, + da->da_addr, da->da_addrlen, 0); + __dev_addr_delete(&from->mc_list, &from->mc_count, + da->da_addr, da->da_addrlen, 0); + da = next; + } + __dev_set_rx_mode(to); + + netif_tx_unlock_bh(to); + netif_tx_unlock_bh(from); +} +EXPORT_SYMBOL(dev_mc_unsync); + +/* Added as of 2.6.23 on net/core/dev.c. Slightly modifed, no dev->set_rx_mode on + * 2.6.22 so ignore that. */ + +/* + * Upload unicast and multicast address lists to device and + * configure RX filtering. When the device doesn't support unicast + * filtering it is put in promiscous mode while unicast addresses + * are present. + */ +void __dev_set_rx_mode(struct net_device *dev) +{ + /* dev_open will call this function so the list will stay sane. */ + if (!(dev->flags&IFF_UP)) + return; + + if (!netif_device_present(dev)) + return; + +/* This needs to be ported to 2.6.22 framework */ +#if 0 + /* Unicast addresses changes may only happen under the rtnl, + * therefore calling __dev_set_promiscuity here is safe. + */ + if (dev->uc_count > 0 && !dev->uc_promisc) { + __dev_set_promiscuity(dev, 1); + dev->uc_promisc = 1; + } else if (dev->uc_count == 0 && dev->uc_promisc) { + __dev_set_promiscuity(dev, -1); + dev->uc_promisc = 0; + } +#endif + + if (dev->set_multicast_list) + dev->set_multicast_list(dev); +} + +#ifndef HAVE_PCI_SET_MWI +int pci_try_set_mwi(struct pci_dev *dev) +{ + return 0; +} +EXPORT_SYMBOL(pci_try_set_mwi); +#else + +/** + * pci_try_set_mwi - enables memory-write-invalidate PCI transaction + * @dev: the PCI device for which MWI is enabled + * + * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND. + * Callers are not required to check the return value. + * + * RETURNS: An appropriate -ERRNO error value on error, or zero for success. + */ +int pci_try_set_mwi(struct pci_dev *dev) +{ + int rc = pci_set_mwi(dev); + return rc; +} +EXPORT_SYMBOL(pci_try_set_mwi); +#endif + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) */ + diff --git a/compat/compat-2.6.24.c b/compat/compat-2.6.24.c new file mode 100644 index 0000000..977eb45 --- /dev/null +++ b/compat/compat-2.6.24.c @@ -0,0 +1,237 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.24. + */ + +#include + +/* All things not in 2.6.22 and 2.6.23 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + +/* Part of net/ethernet/eth.c as of 2.6.24 */ +char *print_mac(char *buf, const u8 *addr) +{ + sprintf(buf, MAC_FMT, + addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); + return buf; +} +EXPORT_SYMBOL(print_mac); + +/* On net/core/dev.c as of 2.6.24 */ +int __dev_addr_delete(struct dev_addr_list **list, int *count, + void *addr, int alen, int glbl) +{ + struct dev_addr_list *da; + + for (; (da = *list) != NULL; list = &da->next) { + if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && + alen == da->da_addrlen) { + if (glbl) { + int old_glbl = da->da_gusers; + da->da_gusers = 0; + if (old_glbl == 0) + break; + } + if (--da->da_users) + return 0; + + *list = da->next; + kfree(da); + (*count)--; + return 0; + } + } + return -ENOENT; +} + +/* On net/core/dev.c as of 2.6.24. This is not yet used by mac80211 but + * might as well add it */ +int __dev_addr_add(struct dev_addr_list **list, int *count, + void *addr, int alen, int glbl) +{ + struct dev_addr_list *da; + + for (da = *list; da != NULL; da = da->next) { + if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && + da->da_addrlen == alen) { + if (glbl) { + int old_glbl = da->da_gusers; + da->da_gusers = 1; + if (old_glbl) + return 0; + } + da->da_users++; + return 0; + } + } + + da = kmalloc(sizeof(*da), GFP_ATOMIC); + if (da == NULL) + return -ENOMEM; + memcpy(da->da_addr, addr, alen); + da->da_addrlen = alen; + da->da_users = 1; + da->da_gusers = glbl ? 1 : 0; + da->next = *list; + *list = da; + (*count)++; + return 0; +} + +/* 2.6.22 and 2.6.23 have eth_header_cache_update defined as extern in include/linux/etherdevice.h + * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */ + +/** + * eth_header_cache_update - update cache entry + * @hh: destination cache entry + * @dev: network device + * @haddr: new hardware address + * + * Called by Address Resolution module to notify changes in address. + */ +void eth_header_cache_update(struct hh_cache *hh, + struct net_device *dev, + unsigned char *haddr) +{ + memcpy(((u8 *) hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)), + haddr, ETH_ALEN); +} +EXPORT_SYMBOL(eth_header_cache_update); + +/* 2.6.22 and 2.6.23 have eth_header_cache defined as extern in include/linux/etherdevice.h + * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */ + +/** + * eth_header_cache - fill cache entry from neighbour + * @neigh: source neighbour + * @hh: destination cache entry + * Create an Ethernet header template from the neighbour. + */ +int eth_header_cache(struct neighbour *neigh, struct hh_cache *hh) +{ + __be16 type = hh->hh_type; + struct ethhdr *eth; + const struct net_device *dev = neigh->dev; + + eth = (struct ethhdr *) + (((u8 *) hh->hh_data) + (HH_DATA_OFF(sizeof(*eth)))); + + if (type == htons(ETH_P_802_3)) + return -1; + + eth->h_proto = type; + memcpy(eth->h_source, dev->dev_addr, ETH_ALEN); + memcpy(eth->h_dest, neigh->ha, ETH_ALEN); + hh->hh_len = ETH_HLEN; + return 0; +} +EXPORT_SYMBOL(eth_header_cache); + +/* 2.6.22 and 2.6.23 have eth_header() defined as extern in include/linux/etherdevice.h + * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */ + +/** + * eth_header - create the Ethernet header + * @skb: buffer to alter + * @dev: source device + * @type: Ethernet type field + * @daddr: destination address (NULL leave destination address) + * @saddr: source address (NULL use device source address) + * @len: packet length (<= skb->len) + * + * + * Set the protocol type. For a packet of type ETH_P_802_3 we put the length + * in here instead. It is up to the 802.2 layer to carry protocol information. + */ +int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, + void *daddr, void *saddr, unsigned len) +{ + struct ethhdr *eth = (struct ethhdr *)skb_push(skb, ETH_HLEN); + + if (type != ETH_P_802_3) + eth->h_proto = htons(type); + else + eth->h_proto = htons(len); + + /* + * Set the source hardware address. + */ + + if (!saddr) + saddr = dev->dev_addr; + memcpy(eth->h_source, saddr, dev->addr_len); + + if (daddr) { + memcpy(eth->h_dest, daddr, dev->addr_len); + return ETH_HLEN; + } + + /* + * Anyway, the loopback-device should never use this function... + */ + + if (dev->flags & (IFF_LOOPBACK | IFF_NOARP)) { + memset(eth->h_dest, 0, dev->addr_len); + return ETH_HLEN; + } + + return -ETH_HLEN; +} + +EXPORT_SYMBOL(eth_header); + +/* 2.6.22 and 2.6.23 have eth_rebuild_header defined as extern in include/linux/etherdevice.h + * and actually defined in net/ethernet/eth.c but 2.6.24 exports it. Lets export it here */ + +/** + * eth_rebuild_header- rebuild the Ethernet MAC header. + * @skb: socket buffer to update + * + * This is called after an ARP or IPV6 ndisc it's resolution on this + * sk_buff. We now let protocol (ARP) fill in the other fields. + * + * This routine CANNOT use cached dst->neigh! + * Really, it is used only when dst->neigh is wrong. + */ +int eth_rebuild_header(struct sk_buff *skb) +{ + struct ethhdr *eth = (struct ethhdr *)skb->data; + struct net_device *dev = skb->dev; + + switch (eth->h_proto) { +#ifdef CONFIG_INET + case __constant_htons(ETH_P_IP): + return arp_find(eth->h_dest, skb); +#endif + default: + printk(KERN_DEBUG + "%s: unable to resolve type %X addresses.\n", + dev->name, (int)eth->h_proto); + + memcpy(eth->h_source, dev->dev_addr, ETH_ALEN); + break; + } + + return 0; +} +EXPORT_SYMBOL(eth_rebuild_header); + +/* 2.6.24 will introduce struct pci_dev is_pcie bit. To help + * with the compatibility code (compat.diff) being smaller, we provide a helper + * so in cases where that will be used we can simply slap ifdefs with this + * routine. Use compat_ prefex to not pollute namespace. */ +int compat_is_pcie(struct pci_dev *pdev) +{ + int cap; + cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + return cap ? 1 : 0; +} +EXPORT_SYMBOL(compat_is_pcie); + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) */ + diff --git a/compat/compat-2.6.25.c b/compat/compat-2.6.25.c new file mode 100644 index 0000000..e872447 --- /dev/null +++ b/compat/compat-2.6.25.c @@ -0,0 +1,378 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.25. + */ + +#include + +/* All things not in 2.6.22, 2.6.23 and 2.6.24 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) + +/* Backport work for QoS dependencies (kernel/pm_qos_params.c) + * ipw2100 now makes use of + * pm_qos_add_requirement(), + * pm_qos_update_requirement() and + * pm_qos_remove_requirement() from it + * + * */ + +/* + * locking rule: all changes to target_value or requirements or notifiers lists + * or pm_qos_object list and pm_qos_objects need to happen with pm_qos_lock + * held, taken with _irqsave. One lock to rule them all + */ +struct requirement_list { + struct list_head list; + union { + s32 value; + s32 usec; + s32 kbps; + }; + char *name; +}; + +static s32 max_compare(s32 v1, s32 v2); +static s32 min_compare(s32 v1, s32 v2); + +struct pm_qos_object { + struct requirement_list requirements; + struct blocking_notifier_head *notifiers; + struct miscdevice pm_qos_power_miscdev; + char *name; + s32 default_value; + s32 target_value; + s32 (*comparitor)(s32, s32); +}; + +static struct pm_qos_object null_pm_qos; +static BLOCKING_NOTIFIER_HEAD(cpu_dma_lat_notifier); +static struct pm_qos_object cpu_dma_pm_qos = { + .requirements = {LIST_HEAD_INIT(cpu_dma_pm_qos.requirements.list)}, + .notifiers = &cpu_dma_lat_notifier, + .name = "cpu_dma_latency", + .default_value = 2000 * USEC_PER_SEC, + .target_value = 2000 * USEC_PER_SEC, + .comparitor = min_compare +}; + +static BLOCKING_NOTIFIER_HEAD(network_lat_notifier); +static struct pm_qos_object network_lat_pm_qos = { + .requirements = {LIST_HEAD_INIT(network_lat_pm_qos.requirements.list)}, + .notifiers = &network_lat_notifier, + .name = "network_latency", + .default_value = 2000 * USEC_PER_SEC, + .target_value = 2000 * USEC_PER_SEC, + .comparitor = min_compare +}; + + +static BLOCKING_NOTIFIER_HEAD(network_throughput_notifier); +static struct pm_qos_object network_throughput_pm_qos = { + .requirements = + {LIST_HEAD_INIT(network_throughput_pm_qos.requirements.list)}, + .notifiers = &network_throughput_notifier, + .name = "network_throughput", + .default_value = 0, + .target_value = 0, + .comparitor = max_compare +}; + + +static struct pm_qos_object *pm_qos_array[] = { + &null_pm_qos, + &cpu_dma_pm_qos, + &network_lat_pm_qos, + &network_throughput_pm_qos +}; + +static DEFINE_SPINLOCK(pm_qos_lock); + +/* static helper functions */ +static s32 max_compare(s32 v1, s32 v2) +{ + return max(v1, v2); +} + +static s32 min_compare(s32 v1, s32 v2) +{ + return min(v1, v2); +} + +static void update_target(int target) +{ + s32 extreme_value; + struct requirement_list *node; + unsigned long flags; + int call_notifier = 0; + + spin_lock_irqsave(&pm_qos_lock, flags); + extreme_value = pm_qos_array[target]->default_value; + list_for_each_entry(node, + &pm_qos_array[target]->requirements.list, list) { + extreme_value = pm_qos_array[target]->comparitor( + extreme_value, node->value); + } + if (pm_qos_array[target]->target_value != extreme_value) { + call_notifier = 1; + pm_qos_array[target]->target_value = extreme_value; + pr_debug(KERN_ERR "new target for qos %d is %d\n", target, + pm_qos_array[target]->target_value); + } + spin_unlock_irqrestore(&pm_qos_lock, flags); + + if (call_notifier) + blocking_notifier_call_chain(pm_qos_array[target]->notifiers, + (unsigned long) extreme_value, NULL); +} + + +/** + * pm_qos_add_requirement - inserts new qos request into the list + * @pm_qos_class: identifies which list of qos request to us + * @name: identifies the request + * @value: defines the qos request + * + * This function inserts a new entry in the pm_qos_class list of requested qos + * performance charactoistics. It recomputes the agregate QoS expectations for + * the pm_qos_class of parrameters. + */ +int pm_qos_add_requirement(int pm_qos_class, char *name, s32 value) +{ + struct requirement_list *dep; + unsigned long flags; + + dep = kzalloc(sizeof(struct requirement_list), GFP_KERNEL); + if (dep) { + if (value == PM_QOS_DEFAULT_VALUE) + dep->value = pm_qos_array[pm_qos_class]->default_value; + else + dep->value = value; + dep->name = kstrdup(name, GFP_KERNEL); + if (!dep->name) + goto cleanup; + + spin_lock_irqsave(&pm_qos_lock, flags); + list_add(&dep->list, + &pm_qos_array[pm_qos_class]->requirements.list); + spin_unlock_irqrestore(&pm_qos_lock, flags); + update_target(pm_qos_class); + + return 0; + } + +cleanup: + kfree(dep); + return -ENOMEM; +} +EXPORT_SYMBOL_GPL(pm_qos_add_requirement); + +/** + * pm_qos_update_requirement - modifies an existing qos request + * @pm_qos_class: identifies which list of qos request to us + * @name: identifies the request + * @value: defines the qos request + * + * Updates an existing qos requierement for the pm_qos_class of parameters along + * with updating the target pm_qos_class value. + * + * If the named request isn't in the lest then no change is made. + */ +int pm_qos_update_requirement(int pm_qos_class, char *name, s32 new_value) +{ + unsigned long flags; + struct requirement_list *node; + int pending_update = 0; + + spin_lock_irqsave(&pm_qos_lock, flags); + list_for_each_entry(node, + &pm_qos_array[pm_qos_class]->requirements.list, list) { + if (strcmp(node->name, name) == 0) { + if (new_value == PM_QOS_DEFAULT_VALUE) + node->value = + pm_qos_array[pm_qos_class]->default_value; + else + node->value = new_value; + pending_update = 1; + break; + } + } + spin_unlock_irqrestore(&pm_qos_lock, flags); + if (pending_update) + update_target(pm_qos_class); + + return 0; +} +EXPORT_SYMBOL_GPL(pm_qos_update_requirement); + +/** + * pm_qos_remove_requirement - modifies an existing qos request + * @pm_qos_class: identifies which list of qos request to us + * @name: identifies the request + * + * Will remove named qos request from pm_qos_class list of parrameters and + * recompute the current target value for the pm_qos_class. + */ +void pm_qos_remove_requirement(int pm_qos_class, char *name) +{ + unsigned long flags; + struct requirement_list *node; + int pending_update = 0; + + spin_lock_irqsave(&pm_qos_lock, flags); + list_for_each_entry(node, + &pm_qos_array[pm_qos_class]->requirements.list, list) { + if (strcmp(node->name, name) == 0) { + kfree(node->name); + list_del(&node->list); + kfree(node); + pending_update = 1; + break; + } + } + spin_unlock_irqrestore(&pm_qos_lock, flags); + if (pending_update) + update_target(pm_qos_class); +} +EXPORT_SYMBOL_GPL(pm_qos_remove_requirement); + + +/** + * The following things are out of ./lib/vsprintf.c + * The new iwlwifi driver is using them. + */ + +/** + * strict_strtoul - convert a string to an unsigned long strictly + * @cp: The string to be converted + * @base: The number base to use + * @res: The converted result value + * + * strict_strtoul converts a string to an unsigned long only if the + * string is really an unsigned long string, any string containing + * any invalid char at the tail will be rejected and -EINVAL is returned, + * only a newline char at the tail is acceptible because people generally + * change a module parameter in the following way: + * + * echo 1024 > /sys/module/e1000/parameters/copybreak + * + * echo will append a newline to the tail. + * + * It returns 0 if conversion is successful and *res is set to the converted + * value, otherwise it returns -EINVAL and *res is set to 0. + * + * simple_strtoul just ignores the successive invalid characters and + * return the converted value of prefix part of the string. + */ +int strict_strtoul(const char *cp, unsigned int base, unsigned long *res); + +/** + * strict_strtol - convert a string to a long strictly + * @cp: The string to be converted + * @base: The number base to use + * @res: The converted result value + * + * strict_strtol is similiar to strict_strtoul, but it allows the first + * character of a string is '-'. + * + * It returns 0 if conversion is successful and *res is set to the converted + * value, otherwise it returns -EINVAL and *res is set to 0. + */ +int strict_strtol(const char *cp, unsigned int base, long *res); + +#define define_strict_strtoux(type, valtype) \ +int strict_strtou##type(const char *cp, unsigned int base, valtype *res)\ +{ \ + char *tail; \ + valtype val; \ + size_t len; \ + \ + *res = 0; \ + len = strlen(cp); \ + if (len == 0) \ + return -EINVAL; \ + \ + val = simple_strtou##type(cp, &tail, base); \ + if ((*tail == '\0') || \ + ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {\ + *res = val; \ + return 0; \ + } \ + \ + return -EINVAL; \ +} \ + +#define define_strict_strtox(type, valtype) \ +int strict_strto##type(const char *cp, unsigned int base, valtype *res) \ +{ \ + int ret; \ + if (*cp == '-') { \ + ret = strict_strtou##type(cp+1, base, res); \ + if (!ret) \ + *res = -(*res); \ + } else \ + ret = strict_strtou##type(cp, base, res); \ + \ + return ret; \ +} \ + +define_strict_strtoux(l, unsigned long) +define_strict_strtox(l, long) + +EXPORT_SYMBOL(strict_strtoul); +EXPORT_SYMBOL(strict_strtol); + +int __dev_addr_sync(struct dev_addr_list **to, int *to_count, + struct dev_addr_list **from, int *from_count) +{ + struct dev_addr_list *da, *next; + int err = 0; + + da = *from; + while (da != NULL) { + next = da->next; + if (!da->da_synced) { + err = __dev_addr_add(to, to_count, + da->da_addr, da->da_addrlen, 0); + if (err < 0) + break; + da->da_synced = 1; + da->da_users++; + } else if (da->da_users == 1) { + __dev_addr_delete(to, to_count, + da->da_addr, da->da_addrlen, 0); + __dev_addr_delete(from, from_count, + da->da_addr, da->da_addrlen, 0); + } + da = next; + } + return err; +} +EXPORT_SYMBOL_GPL(__dev_addr_sync); + +void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, + struct dev_addr_list **from, int *from_count) +{ + struct dev_addr_list *da, *next; + + da = *from; + while (da != NULL) { + next = da->next; + if (da->da_synced) { + __dev_addr_delete(to, to_count, + da->da_addr, da->da_addrlen, 0); + da->da_synced = 0; + __dev_addr_delete(from, from_count, + da->da_addr, da->da_addrlen, 0); + } + da = next; + } +} +EXPORT_SYMBOL_GPL(__dev_addr_unsync); + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) */ + diff --git a/compat/compat-2.6.26.c b/compat/compat-2.6.26.c new file mode 100644 index 0000000..960a79a --- /dev/null +++ b/compat/compat-2.6.26.c @@ -0,0 +1,69 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.26. + * + * Copyright holders from ported work: + * + * Copyright (c) 2002-2003 Patrick Mochel + * Copyright (c) 2006-2007 Greg Kroah-Hartman + * Copyright (c) 2006-2007 Novell Inc. + */ + +#include + +/* All things not in 2.6.25 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + + +/** + * kobject_set_name_vargs - Set the name of an kobject + * @kobj: struct kobject to set the name of + * @fmt: format string used to build the name + * @vargs: vargs to format the string. + */ +static +int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, + va_list vargs) +{ + const char *old_name = kobj->name; + char *s; + + if (kobj->name && !fmt) + return 0; + + kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs); + if (!kobj->name) + return -ENOMEM; + + /* ewww... some of these buggers have '/' in the name ... */ + while ((s = strchr(kobj->name, '/'))) + s[0] = '!'; + + kfree(old_name); + return 0; +} + +/** + * dev_set_name - set a device name + * @dev: device + * @fmt: format string for the device's name + */ +int dev_set_name(struct device *dev, const char *fmt, ...) +{ + va_list vargs; + int err; + + va_start(vargs, fmt); + err = kobject_set_name_vargs(&dev->kobj, fmt, vargs); + va_end(vargs); + return err; +} +EXPORT_SYMBOL_GPL(dev_set_name); + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) */ + diff --git a/compat/compat-2.6.27.c b/compat/compat-2.6.27.c new file mode 100644 index 0000000..7fffe8e --- /dev/null +++ b/compat/compat-2.6.27.c @@ -0,0 +1,207 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.27 + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) + +#include +#include +#include +#include +#include + +/* rfkill notification chain */ +#define RFKILL_STATE_CHANGED 0x0001 /* state of a normal rfkill + switch has changed */ + +/* + * e5899e1b7d73e67de758a32174a859cc2586c0b9 made pci_pme_capable() external, + * it was defined internally, some drivers want access to this information. + * + * Unfortunately the old kernels do not have ->pm_cap or ->pme_support so + * we have to call the PCI routines directly. + */ + +/** + * pci_pme_capable - check the capability of PCI device to generate PME# + * @dev: PCI device to handle. + * @state: PCI state from which device will issue PME#. + * + * This is the backport code for older kernels for compat-wireless, we read stuff + * from the initialization stuff from pci_pm_init(). + */ +bool pci_pme_capable(struct pci_dev *dev, pci_power_t state) +{ + int pm; + u16 pmc = 0; + u16 pme_support; /* as from the pci dev */ + /* find PCI PM capability in list */ + pm = pci_find_capability(dev, PCI_CAP_ID_PM); + if (!pm) + return false; + + if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { + dev_err(&dev->dev, "unsupported PM cap regs version (%u)\n", + pmc & PCI_PM_CAP_VER_MASK); + return false; + } + + pmc &= PCI_PM_CAP_PME_MASK; + + if (!pmc) + return false; + + pme_support = pmc >> PCI_PM_CAP_PME_SHIFT; + + /* Check device's ability to generate PME# */ + + return !!(pme_support & (1 << state)); +} +EXPORT_SYMBOL(pci_pme_capable); + +/** + * mmc_align_data_size - pads a transfer size to a more optimal value + * @card: the MMC card associated with the data transfer + * @sz: original transfer size + * + * Pads the original data size with a number of extra bytes in + * order to avoid controller bugs and/or performance hits + * (e.g. some controllers revert to PIO for certain sizes). + * + * Returns the improved size, which might be unmodified. + * + * Note that this function is only relevant when issuing a + * single scatter gather entry. + */ +unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz) +{ + /* + * FIXME: We don't have a system for the controller to tell + * the core about its problems yet, so for now we just 32-bit + * align the size. + */ + sz = ((sz + 3) / 4) * 4; + + return sz; +} +EXPORT_SYMBOL(mmc_align_data_size); + +/* + * Calculate the maximum byte mode transfer size + */ +static inline unsigned int sdio_max_byte_size(struct sdio_func *func) +{ + unsigned int mval = (unsigned int) min(func->card->host->max_seg_size, + func->card->host->max_blk_size); + mval = min(mval, func->max_blksize); + return min(mval, 512u); /* maximum size for byte mode */ +} + +/** + * sdio_align_size - pads a transfer size to a more optimal value + * @func: SDIO function + * @sz: original transfer size + * + * Pads the original data size with a number of extra bytes in + * order to avoid controller bugs and/or performance hits + * (e.g. some controllers revert to PIO for certain sizes). + * + * If possible, it will also adjust the size so that it can be + * handled in just a single request. + * + * Returns the improved size, which might be unmodified. + */ +unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz) +{ + unsigned int orig_sz; + unsigned int blk_sz, byte_sz; + unsigned chunk_sz; + + orig_sz = sz; + + /* + * Do a first check with the controller, in case it + * wants to increase the size up to a point where it + * might need more than one block. + */ + sz = mmc_align_data_size(func->card, sz); + + /* + * If we can still do this with just a byte transfer, then + * we're done. + */ + if (sz <= sdio_max_byte_size(func)) + return sz; + + if (func->card->cccr.multi_block) { + /* + * Check if the transfer is already block aligned + */ + if ((sz % func->cur_blksize) == 0) + return sz; + + /* + * Realign it so that it can be done with one request, + * and recheck if the controller still likes it. + */ + blk_sz = ((sz + func->cur_blksize - 1) / + func->cur_blksize) * func->cur_blksize; + blk_sz = mmc_align_data_size(func->card, blk_sz); + + /* + * This value is only good if it is still just + * one request. + */ + if ((blk_sz % func->cur_blksize) == 0) + return blk_sz; + + /* + * We failed to do one request, but at least try to + * pad the remainder properly. + */ + byte_sz = mmc_align_data_size(func->card, + sz % func->cur_blksize); + if (byte_sz <= sdio_max_byte_size(func)) { + blk_sz = sz / func->cur_blksize; + return blk_sz * func->cur_blksize + byte_sz; + } + } else { + /* + * We need multiple requests, so first check that the + * controller can handle the chunk size; + */ + chunk_sz = mmc_align_data_size(func->card, + sdio_max_byte_size(func)); + if (chunk_sz == sdio_max_byte_size(func)) { + /* + * Fix up the size of the remainder (if any) + */ + byte_sz = orig_sz % chunk_sz; + if (byte_sz) { + byte_sz = mmc_align_data_size(func->card, + byte_sz); + } + + return (orig_sz / chunk_sz) * chunk_sz + byte_sz; + } + } + + /* + * The controller is simply incapable of transferring the size + * we want in decent manner, so just return the original size. + */ + return orig_sz; +} +EXPORT_SYMBOL_GPL(sdio_align_size); + + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) */ + diff --git a/compat/compat-2.6.28.c b/compat/compat-2.6.28.c new file mode 100644 index 0000000..959a429 --- /dev/null +++ b/compat/compat-2.6.28.c @@ -0,0 +1,363 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.28. + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) + +#include + +/* 2.6.28 compat code goes here */ + +/* + * Compat-wireless notes for USB backport stuff: + * + * urb->reject exists on 2.6.27, the poison/unpoison helpers + * did not though. The anchor poison does not exist so we cannot use them. + * + * USB anchor poising seems to exist to prevent future driver sumbissions + * of usb_anchor_urb() to an anchor marked as poisoned. For older kernels + * we cannot use that, so new usb_anchor_urb()s will be anchored. The down + * side to this should be submission of URBs will continue being anchored + * on an anchor instead of having them being rejected immediately when the + * driver realized we needed to stop. For ar9170 we poison URBs upon the + * ar9170 mac80211 stop callback(), don't think this should be so bad. + * It mean there is period of time in older kernels for which we continue + * to anchor new URBs to a known stopped anchor. We have two anchors + * (TX, and RX) + */ + +#if 0 +/** + * usb_poison_urb - reliably kill a transfer and prevent further use of an URB + * @urb: pointer to URB describing a previously submitted request, + * may be NULL + * + * This routine cancels an in-progress request. It is guaranteed that + * upon return all completion handlers will have finished and the URB + * will be totally idle and cannot be reused. These features make + * this an ideal way to stop I/O in a disconnect() callback. + * If the request has not already finished or been unlinked + * the completion handler will see urb->status == -ENOENT. + * + * After and while the routine runs, attempts to resubmit the URB will fail + * with error -EPERM. Thus even if the URB's completion handler always + * tries to resubmit, it will not succeed and the URB will become idle. + * + * This routine may not be used in an interrupt context (such as a bottom + * half or a completion handler), or when holding a spinlock, or in other + * situations where the caller can't schedule(). + * + * This routine should not be called by a driver after its disconnect + * method has returned. + */ +void usb_poison_urb(struct urb *urb) +{ + might_sleep(); + if (!(urb && urb->dev && urb->ep)) + return; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) + spin_lock_irq(&usb_reject_lock); +#endif + ++urb->reject; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) + spin_unlock_irq(&usb_reject_lock); +#endif + /* + * XXX: usb_hcd_unlink_urb() needs backporting... this is defined + * on usb hcd.c but urb.c gets access to it. That is, older kernels + * have usb_hcd_unlink_urb() but its not exported, nor can we + * re-implement it exactly. This essentially dequeues the urb from + * hw, we need to figure out a way to backport this. + */ + //usb_hcd_unlink_urb(urb, -ENOENT); + + wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); +} +EXPORT_SYMBOL_GPL(usb_poison_urb); +#endif + +#include +struct pcmcia_cfg_mem { + tuple_t tuple; + cisparse_t parse; + u8 buf[256]; + cistpl_cftable_entry_t dflt; +}; +/** + * pcmcia_loop_config() - loop over configuration options + * @p_dev: the struct pcmcia_device which we need to loop for. + * @conf_check: function to call for each configuration option. + * It gets passed the struct pcmcia_device, the CIS data + * describing the configuration option, and private data + * being passed to pcmcia_loop_config() + * @priv_data: private data to be passed to the conf_check function. + * + * pcmcia_loop_config() loops over all configuration options, and calls + * the driver-specific conf_check() for each one, checking whether + * it is a valid one. Returns 0 on success or errorcode otherwise. + */ +int pcmcia_loop_config(struct pcmcia_device *p_dev, + int (*conf_check) (struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data), + void *priv_data) +{ + struct pcmcia_cfg_mem *cfg_mem; + + tuple_t *tuple; + int ret; + unsigned int vcc; + + cfg_mem = kzalloc(sizeof(struct pcmcia_cfg_mem), GFP_KERNEL); + if (cfg_mem == NULL) + return -ENOMEM; + + /* get the current Vcc setting */ + vcc = p_dev->socket->socket.Vcc; + + tuple = &cfg_mem->tuple; + tuple->TupleData = cfg_mem->buf; + tuple->TupleDataMax = 255; + tuple->TupleOffset = 0; + tuple->DesiredTuple = CISTPL_CFTABLE_ENTRY; + tuple->Attributes = 0; + + ret = pcmcia_get_first_tuple(p_dev, tuple); + while (!ret) { + cistpl_cftable_entry_t *cfg = &cfg_mem->parse.cftable_entry; + + if (pcmcia_get_tuple_data(p_dev, tuple)) + goto next_entry; + + if (pcmcia_parse_tuple(tuple, &cfg_mem->parse)) + goto next_entry; + + /* default values */ + p_dev->conf.ConfigIndex = cfg->index; + if (cfg->flags & CISTPL_CFTABLE_DEFAULT) + cfg_mem->dflt = *cfg; + + ret = conf_check(p_dev, cfg, &cfg_mem->dflt, vcc, priv_data); + if (!ret) + break; + +next_entry: + ret = pcmcia_get_next_tuple(p_dev, tuple); + } + + return ret; +} +EXPORT_SYMBOL(pcmcia_loop_config); + +void usb_unpoison_urb(struct urb *urb) +{ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) + unsigned long flags; +#endif + + if (!urb) + return; + +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) + spin_lock_irqsave(&usb_reject_lock, flags); +#endif + --urb->reject; +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)) + spin_unlock_irqrestore(&usb_reject_lock, flags); +#endif +} +EXPORT_SYMBOL_GPL(usb_unpoison_urb); + + +#if 0 +/** + * usb_poison_anchored_urbs - cease all traffic from an anchor + * @anchor: anchor the requests are bound to + * + * this allows all outstanding URBs to be poisoned starting + * from the back of the queue. Newly added URBs will also be + * poisoned + * + * This routine should not be called by a driver after its disconnect + * method has returned. + */ +void usb_poison_anchored_urbs(struct usb_anchor *anchor) +{ + struct urb *victim; + + spin_lock_irq(&anchor->lock); + // anchor->poisoned = 1; /* XXX: Cannot backport */ + while (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.prev, struct urb, + anchor_list); + /* we must make sure the URB isn't freed before we kill it*/ + usb_get_urb(victim); + spin_unlock_irq(&anchor->lock); + /* this will unanchor the URB */ + usb_poison_urb(victim); + usb_put_urb(victim); + spin_lock_irq(&anchor->lock); + } + spin_unlock_irq(&anchor->lock); +} +EXPORT_SYMBOL_GPL(usb_poison_anchored_urbs); +#endif + +/** + * usb_get_from_anchor - get an anchor's oldest urb + * @anchor: the anchor whose urb you want + * + * this will take the oldest urb from an anchor, + * unanchor and return it + */ +struct urb *usb_get_from_anchor(struct usb_anchor *anchor) +{ + struct urb *victim; + unsigned long flags; + + spin_lock_irqsave(&anchor->lock, flags); + if (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.next, struct urb, + anchor_list); + usb_get_urb(victim); + spin_unlock_irqrestore(&anchor->lock, flags); + usb_unanchor_urb(victim); + } else { + spin_unlock_irqrestore(&anchor->lock, flags); + victim = NULL; + } + + return victim; +} + +EXPORT_SYMBOL_GPL(usb_get_from_anchor); + +/** + * usb_scuttle_anchored_urbs - unanchor all an anchor's urbs + * @anchor: the anchor whose urbs you want to unanchor + * + * use this to get rid of all an anchor's urbs + */ +void usb_scuttle_anchored_urbs(struct usb_anchor *anchor) +{ + struct urb *victim; + unsigned long flags; + + spin_lock_irqsave(&anchor->lock, flags); + while (!list_empty(&anchor->urb_list)) { + victim = list_entry(anchor->urb_list.prev, struct urb, + anchor_list); + usb_get_urb(victim); + spin_unlock_irqrestore(&anchor->lock, flags); + /* this may free the URB */ + usb_unanchor_urb(victim); + usb_put_urb(victim); + spin_lock_irqsave(&anchor->lock, flags); + } + spin_unlock_irqrestore(&anchor->lock, flags); +} + +EXPORT_SYMBOL_GPL(usb_scuttle_anchored_urbs); + +/** + * usb_anchor_empty - is an anchor empty + * @anchor: the anchor you want to query + * + * returns 1 if the anchor has no urbs associated with it + */ +int usb_anchor_empty(struct usb_anchor *anchor) +{ + return list_empty(&anchor->urb_list); +} + +EXPORT_SYMBOL_GPL(usb_anchor_empty); + + +void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) +{ + /* + * Make sure the BAR is actually a memory resource, not an IO resource + */ + if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) { + WARN_ON(1); + return NULL; + } + return ioremap_nocache(pci_resource_start(pdev, bar), + pci_resource_len(pdev, bar)); +} +EXPORT_SYMBOL_GPL(pci_ioremap_bar); + +static unsigned long round_jiffies_common(unsigned long j, int cpu, + bool force_up) +{ + int rem; + unsigned long original = j; + + /* + * We don't want all cpus firing their timers at once hitting the + * same lock or cachelines, so we skew each extra cpu with an extra + * 3 jiffies. This 3 jiffies came originally from the mm/ code which + * already did this. + * The skew is done by adding 3*cpunr, then round, then subtract this + * extra offset again. + */ + j += cpu * 3; + + rem = j % HZ; + + /* + * If the target jiffie is just after a whole second (which can happen + * due to delays of the timer irq, long irq off times etc etc) then + * we should round down to the whole second, not up. Use 1/4th second + * as cutoff for this rounding as an extreme upper bound for this. + * But never round down if @force_up is set. + */ + if (rem < HZ/4 && !force_up) /* round down */ + j = j - rem; + else /* round up */ + j = j - rem + HZ; + + /* now that we have rounded, subtract the extra skew again */ + j -= cpu * 3; + + if (j <= jiffies) /* rounding ate our timeout entirely; */ + return original; + return j; +} + +/** + * round_jiffies_up - function to round jiffies up to a full second + * @j: the time in (absolute) jiffies that should be rounded + * + * This is the same as round_jiffies() except that it will never + * round down. This is useful for timeouts for which the exact time + * of firing does not matter too much, as long as they don't fire too + * early. + */ +unsigned long round_jiffies_up(unsigned long j) +{ + return round_jiffies_common(j, raw_smp_processor_id(), true); +} +EXPORT_SYMBOL_GPL(round_jiffies_up); + +void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off, + int size) +{ + skb_fill_page_desc(skb, i, page, off, size); + skb->len += size; + skb->data_len += size; + skb->truesize += size; +} +EXPORT_SYMBOL(skb_add_rx_frag); + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) */ diff --git a/compat/compat-2.6.29.c b/compat/compat-2.6.29.c new file mode 100644 index 0000000..669ad35 --- /dev/null +++ b/compat/compat-2.6.29.c @@ -0,0 +1,40 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.29. + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + +#include + +/** + * usb_unpoison_anchored_urbs - let an anchor be used successfully again + * @anchor: anchor the requests are bound to + * + * Reverses the effect of usb_poison_anchored_urbs + * the anchor can be used normally after it returns + */ +void usb_unpoison_anchored_urbs(struct usb_anchor *anchor) +{ + unsigned long flags; + struct urb *lazarus; + + spin_lock_irqsave(&anchor->lock, flags); + list_for_each_entry(lazarus, &anchor->urb_list, anchor_list) { + usb_unpoison_urb(lazarus); + } + //anchor->poisoned = 0; /* XXX: cannot backport */ + spin_unlock_irqrestore(&anchor->lock, flags); +} +EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs); + + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */ + diff --git a/compat/compat-2.6.30.c b/compat/compat-2.6.30.c new file mode 100644 index 0000000..f821918 --- /dev/null +++ b/compat/compat-2.6.30.c @@ -0,0 +1,18 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.30. + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) + +/* 2.6.30 compat code goes here */ + +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) */ + diff --git a/compat/compat-2.6.31.c b/compat/compat-2.6.31.c new file mode 100644 index 0000000..dc8588f --- /dev/null +++ b/compat/compat-2.6.31.c @@ -0,0 +1,64 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.31. + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) + +#include + +/** + * genl_register_family_with_ops - register a generic netlink family + * @family: generic netlink family + * @ops: operations to be registered + * @n_ops: number of elements to register + * + * Registers the specified family and operations from the specified table. + * Only one family may be registered with the same family name or identifier. + * + * The family id may equal GENL_ID_GENERATE causing an unique id to + * be automatically generated and assigned. + * + * Either a doit or dumpit callback must be specified for every registered + * operation or the function will fail. Only one operation structure per + * command identifier may be registered. + * + * See include/net/genetlink.h for more documenation on the operations + * structure. + * + * This is equivalent to calling genl_register_family() followed by + * genl_register_ops() for every operation entry in the table taking + * care to unregister the family on error path. + * + * Return 0 on success or a negative error code. + */ +int genl_register_family_with_ops(struct genl_family *family, + struct genl_ops *ops, size_t n_ops) +{ + int err, i; + + err = genl_register_family(family); + if (err) + return err; + + for (i = 0; i < n_ops; ++i, ++ops) { + err = genl_register_ops(family, ops); + if (err) + goto err_out; + } + return 0; +err_out: + genl_unregister_family(family); + return err; +} +EXPORT_SYMBOL(genl_register_family_with_ops); + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) */ + diff --git a/compat/compat-2.6.32.c b/compat/compat-2.6.32.c new file mode 100644 index 0000000..22c2c19 --- /dev/null +++ b/compat/compat-2.6.32.c @@ -0,0 +1,124 @@ +/* + * Copyright 2007 Luis R. Rodriguez + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Compatibility file for Linux wireless for kernels 2.6.32. + */ + +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) + +#include + +int __dev_addr_add(struct dev_addr_list **list, int *count, + void *addr, int alen, int glbl) +{ + struct dev_addr_list *da; + + for (da = *list; da != NULL; da = da->next) { + if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && + da->da_addrlen == alen) { + if (glbl) { + int old_glbl = da->da_gusers; + da->da_gusers = 1; + if (old_glbl) + return 0; + } + da->da_users++; + return 0; + } + } + + da = kzalloc(sizeof(*da), GFP_ATOMIC); + if (da == NULL) + return -ENOMEM; + memcpy(da->da_addr, addr, alen); + da->da_addrlen = alen; + da->da_users = 1; + da->da_gusers = glbl ? 1 : 0; + da->next = *list; + *list = da; + (*count)++; + return 0; +} + +int __dev_addr_delete(struct dev_addr_list **list, int *count, + void *addr, int alen, int glbl) +{ + struct dev_addr_list *da; + + for (; (da = *list) != NULL; list = &da->next) { + if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 && + alen == da->da_addrlen) { + if (glbl) { + int old_glbl = da->da_gusers; + da->da_gusers = 0; + if (old_glbl == 0) + break; + } + if (--da->da_users) + return 0; + + *list = da->next; + kfree(da); + (*count)--; + return 0; + } + } + return -ENOENT; +} + +int __dev_addr_sync(struct dev_addr_list **to, int *to_count, + struct dev_addr_list **from, int *from_count) +{ + struct dev_addr_list *da, *next; + int err = 0; + + da = *from; + while (da != NULL) { + next = da->next; + if (!da->da_synced) { + err = __dev_addr_add(to, to_count, + da->da_addr, da->da_addrlen, 0); + if (err < 0) + break; + da->da_synced = 1; + da->da_users++; + } else if (da->da_users == 1) { + __dev_addr_delete(to, to_count, + da->da_addr, da->da_addrlen, 0); + __dev_addr_delete(from, from_count, + da->da_addr, da->da_addrlen, 0); + } + da = next; + } + return err; +} +EXPORT_SYMBOL_GPL(__dev_addr_sync); + +void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, + struct dev_addr_list **from, int *from_count) +{ + struct dev_addr_list *da, *next; + + da = *from; + while (da != NULL) { + next = da->next; + if (da->da_synced) { + __dev_addr_delete(to, to_count, + da->da_addr, da->da_addrlen, 0); + da->da_synced = 0; + __dev_addr_delete(from, from_count, + da->da_addr, da->da_addrlen, 0); + } + da = next; + } +} +EXPORT_SYMBOL_GPL(__dev_addr_unsync); + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) */ + diff --git a/compat/main.c b/compat/main.c new file mode 100644 index 0000000..390278d --- /dev/null +++ b/compat/main.c @@ -0,0 +1,18 @@ +#include + +MODULE_AUTHOR("Luis R. Rodriguez"); +MODULE_DESCRIPTION("Kernel compatibility module"); +MODULE_LICENSE("GPL"); + +static int __init compat_init(void) +{ + return 0; +} +module_init(compat_init); + +static void __exit compat_exit(void) +{ + return; +} +module_exit(compat_exit); + diff --git a/include/linux/compat-2.6.14.h b/include/linux/compat-2.6.14.h new file mode 100644 index 0000000..22e7e31 --- /dev/null +++ b/include/linux/compat-2.6.14.h @@ -0,0 +1,14 @@ +#ifndef LINUX_26_14_COMPAT_H +#define LINUX_26_14_COMPAT_H + +#include +#include + +/* Compat work for 2.6.14 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) + +typedef unsigned int gfp_t; + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14)) */ + +#endif /* LINUX_26_14_COMPAT_H */ diff --git a/include/linux/compat-2.6.18.h b/include/linux/compat-2.6.18.h new file mode 100644 index 0000000..3245c42 --- /dev/null +++ b/include/linux/compat-2.6.18.h @@ -0,0 +1,14 @@ +#ifndef LINUX_26_18_COMPAT_H +#define LINUX_26_18_COMPAT_H + +#include +#include + +/* Compat work for 2.6.18 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) + +#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) */ + +#endif /* LINUX_26_18_COMPAT_H */ diff --git a/include/linux/compat-2.6.19.h b/include/linux/compat-2.6.19.h new file mode 100644 index 0000000..017044c --- /dev/null +++ b/include/linux/compat-2.6.19.h @@ -0,0 +1,25 @@ +#ifndef LINUX_26_19_COMPAT_H +#define LINUX_26_19_COMPAT_H + +#include +#include + +/* Compat work for 2.6.19 */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)) + +#include + +static inline int +compat_kmem_cache_destroy(struct kmem_cache *cachep) +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) + return kmem_cache_destroy(cachep); +#else + kmem_cache_destroy(cachep); + return 0; +#endif +} + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) */ + +#endif /* LINUX_26_19_COMPAT_H */ diff --git a/include/linux/compat-2.6.21.h b/include/linux/compat-2.6.21.h new file mode 100644 index 0000000..263ebd2 --- /dev/null +++ b/include/linux/compat-2.6.21.h @@ -0,0 +1,19 @@ +#ifndef LINUX_26_21_COMPAT_H +#define LINUX_26_21_COMPAT_H + +#include +#include + +/* Compat work for 2.6.21 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) + +#include + +#define register_sysctl_table(table) \ + ({ \ + register_sysctl_table((table), 0); \ + }) + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) */ + +#endif /* LINUX_26_21_COMPAT_H */ diff --git a/include/linux/compat-2.6.22.h b/include/linux/compat-2.6.22.h new file mode 100644 index 0000000..85cd9d5 --- /dev/null +++ b/include/linux/compat-2.6.22.h @@ -0,0 +1,105 @@ +#ifndef LINUX_26_22_COMPAT_H +#define LINUX_26_22_COMPAT_H + +#include +#include + +/* Compat work for 2.6.21 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) + +#include +#include + +/* reuse ax25_ptr */ +#define ieee80211_ptr ax25_ptr + +#ifdef CONFIG_AX25 +#error Compat reuses the AX.25 pointer so that may not be enabled! +#endif + +static inline unsigned char *skb_mac_header(const struct sk_buff *skb) +{ + return skb->mac.raw; +} + +static inline void skb_set_mac_header(struct sk_buff *skb, int offset) +{ + skb->mac.raw = skb->data + offset; +} + +static inline void skb_reset_mac_header(struct sk_buff *skb) +{ + skb->mac.raw = skb->data; +} + +static inline void skb_reset_network_header(struct sk_buff *skb) +{ + skb->nh.raw = skb->data; +} + +static inline void skb_set_network_header(struct sk_buff *skb, int offset) +{ + skb->nh.raw = skb->data + offset; +} + +static inline void skb_set_transport_header(struct sk_buff *skb, int offset) +{ + skb->h.raw = skb->data + offset; +} + +static inline unsigned char *skb_transport_header(struct sk_buff *skb) +{ + return skb->h.raw; +} + +static inline unsigned char *skb_network_header(const struct sk_buff *skb) +{ + return skb->nh.raw; +} + +static inline unsigned char *skb_tail_pointer(const struct sk_buff *skb) +{ + return skb->tail; +} + +static inline struct iphdr *ip_hdr(const struct sk_buff *skb) +{ + return (struct iphdr *)skb_network_header(skb); +} + +static inline void skb_copy_from_linear_data(const struct sk_buff *skb, + void *to, + const unsigned int len) +{ + memcpy(to, skb->data, len); +} + +static inline void skb_copy_from_linear_data_offset(const struct sk_buff *skb, + const int offset, void *to, + const unsigned int len) +{ + memcpy(to, skb->data + offset, len); +} + +#define __maybe_unused __attribute__((unused)) + +#define uninitialized_var(x) x = x + +/* This will lead to very weird behaviour... */ +#define NLA_BINARY NLA_STRING + +static inline int pci_set_mwi(struct pci_dev *dev) +{ + return -ENOSYS; +} + +static inline void pci_clear_mwi(struct pci_dev *dev) +{ +} + +#define list_first_entry(ptr, type, member) \ + list_entry((ptr)->next, type, member) + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)) */ + +#endif /* LINUX_26_22_COMPAT_H */ diff --git a/include/linux/compat-2.6.23.h b/include/linux/compat-2.6.23.h new file mode 100644 index 0000000..c36f90d --- /dev/null +++ b/include/linux/compat-2.6.23.h @@ -0,0 +1,136 @@ +#ifndef LINUX_26_23_COMPAT_H +#define LINUX_26_23_COMPAT_H + +#include +#include + +/* Compat work for < 2.6.23 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) + +#include +#include +#include +#include + +/* + * Tell gcc if a function is cold. The compiler will assume any path + * directly leading to the call is unlikely. + */ + +#if !(__GNUC__ == 4 && __GNUC_MINOR__ < 3) +/* Mark functions as cold. gcc will assume any path leading to a call + * to them will be unlikely. This means a lot of manual unlikely()s + * are unnecessary now for any paths leading to the usual suspects + * like BUG(), printk(), panic() etc. [but let's keep them for now for + * older compilers] + * + * Early snapshots of gcc 4.3 don't support this and we can't detect this + * in the preprocessor, but we can live with this because they're unreleased. + * Maketime probing would be overkill here. + * + * gcc also has a __attribute__((__hot__)) to move hot functions into + * a special section, but I don't see any sense in this right now in + * the kernel context */ +#define __cold __attribute__((__cold__)) +#endif /* gcc 4.3 check */ + +#ifndef __cold +#define __cold +#endif + +/* Added as of 2.6.23 in include/linux/netdevice.h */ +#define alloc_netdev_mq(sizeof_priv, name, setup, queue) \ + alloc_netdev(sizeof_priv, name, setup) +#define NETIF_F_MULTI_QUEUE 16384 + +/* Added as of 2.6.23 on include/linux/netdevice.h */ +static inline int netif_is_multiqueue(const struct net_device *dev) +{ + return (!!(NETIF_F_MULTI_QUEUE & dev->features)); +} + +/* 2.6.23 fixed a bug in tcf_destroy_chain and the parameter changed */ +static inline void tcf_destroy_chain_compat(struct tcf_proto **fl) +{ + struct tcf_proto *tp; + + while ((tp = *fl) != NULL) { + *fl = tp->next; + tp->ops->destroy(tp); + module_put(tp->ops->owner); + kfree(tp); + } +} + +/* dev_mc_list was replaced with dev_addr_list as of 2.6.23, + * only new member added is da_synced. */ +#define dev_addr_list dev_mc_list +#define da_addr dmi_addr +#define da_addrlen dmi_addrlen +#define da_users dmi_users +#define da_gusers dmi_gusers + +/* dev_set_promiscuity() was moved to __dev_set_promiscuity() on 2.6.23 and + * dev_set_promiscuity() became a wrapper. */ +#define __dev_set_promiscuity dev_set_promiscuity + +/* Our own 2.6.22 port on compat.c */ +extern void dev_mc_unsync(struct net_device *to, struct net_device *from); +extern int dev_mc_sync(struct net_device *to, struct net_device *from); + +/* Our own 2.6.22 port on compat.c */ +extern void __dev_set_rx_mode(struct net_device *dev); + +/* Simple to add this */ +extern int cancel_delayed_work_sync(struct delayed_work *work); + +#define cancel_delayed_work_sync cancel_rearming_delayed_work + +#define debugfs_rename(a, b, c, d) 1 + +/* nl80211 requires multicast group support which is new and added on + * 2.6.23. We can't add support for it for older kernels to support it + * genl_family structure was changed. Lets just let through the + * genl_register_mc_group call. This means no multicast group suppport */ + +#define genl_register_mc_group(a, b) 0 + +/** + * struct genl_multicast_group - generic netlink multicast group + * @name: name of the multicast group, names are per-family + * @id: multicast group ID, assigned by the core, to use with + * genlmsg_multicast(). + * @list: list entry for linking + * @family: pointer to family, need not be set before registering + */ +struct genl_multicast_group +{ + struct genl_family *family; /* private */ + struct list_head list; /* private */ + char name[GENL_NAMSIZ]; + u32 id; +}; + + +/* Added as of 2.6.23 */ +int pci_try_set_mwi(struct pci_dev *dev); + +/* Added as of 2.6.23 */ +#ifdef CONFIG_PM_SLEEP +/* + * Tell the freezer that the current task should be frozen by it + */ +static inline void set_freezable(void) +{ + current->flags &= ~PF_NOFREEZE; +} + +#else +static inline void set_freezable(void) {} +#endif /* CONFIG_PM_SLEEP */ + +#else +#define tcf_destroy_chain_compat tcf_destroy_chain +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) */ + +#endif /* LINUX_26_23_COMPAT_H */ diff --git a/include/linux/compat-2.6.24.h b/include/linux/compat-2.6.24.h new file mode 100644 index 0000000..43e6302 --- /dev/null +++ b/include/linux/compat-2.6.24.h @@ -0,0 +1,202 @@ +#ifndef LINUX_26_24_COMPAT_H +#define LINUX_26_24_COMPAT_H + +#include +#include + +/* Compat work for 2.6.21, 2.6.22 and 2.6.23 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) + +/* Added on 2.6.24 in include/linux/types.h by Al viro on commit 142956af */ +typedef unsigned long uintptr_t; + +/* From include/linux/net.h */ +enum sock_shutdown_cmd { + SHUT_RD = 0, + SHUT_WR = 1, + SHUT_RDWR = 2, +}; + +#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,23)) /* Local check */ +/* Added as of 2.6.24 in include/linux/skbuff.h. + * + * Although 2.6.23 does support for CONFIG_NETDEVICES_MULTIQUEUE + * this helper was not added until 2.6.24. This implementation + * is exactly as it is on newer kernels. + * + * For older kernels we use the an internal mac80211 hack. + * For details see changes to include/net/mac80211.h through + * compat.diff and compat/mq_compat.h */ +static inline u16 skb_get_queue_mapping(struct sk_buff *skb) +{ +#ifdef CONFIG_NETDEVICES_MULTIQUEUE + return skb->queue_mapping; +#else + return 0; +#endif +} +#endif /* Local 2.6.23 check */ + +/* On older kernels we handle this a bit differently, so we yield to that + * code for its implementation in mq_compat.h as we want to make + * use of the internal mac80211 __ieee80211_queue_stopped() which itself + * uses internal mac80211 data structure hacks. */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23)) /* Local check */ +/** + * netif_subqueue_stopped - test status of subqueue + * @dev: network device + * @queue_index: sub queue index + * + * Check individual transmit queue of a device with multiple transmit queues. + */ +static inline int __netif_subqueue_stopped(const struct net_device *dev, + u16 queue_index) +{ +#ifdef CONFIG_NETDEVICES_MULTIQUEUE + return test_bit(__LINK_STATE_XOFF, + &dev->egress_subqueue[queue_index].state); +#else + return 0; +#endif +} + +/* Note: although the backport implementation for netif_subqueue_stopped + * on older kernels is identical to upstream __netif_subqueue_stopped() + * (except for a const qualifier) we implement netif_subqueue_stopped() + * as part of mac80211 as it relies on internal mac80211 structures we + * use for MQ support. We this implement it in mq_compat.h */ + +#endif /* Local 2.6.23 check */ + +/* + * Force link bug if constructor is used, can't be done compatibly + * because constructor arguments were swapped since then! + */ +extern void __incompatible_kmem_cache_create(void); + +/* 2.6.21 and 2.6.22 kmem_cache_create() takes 6 arguments */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)) +#define kmem_cache_create(name, objsize, align, flags, ctor) \ + ({ \ + if (ctor) __incompatible_kmem_cache_create(); \ + kmem_cache_create((name), (objsize), (align), \ + (flags), NULL, NULL); \ + }) +#endif + +/* 2.6.23 kmem_cache_create() takes 5 arguments */ +#if (LINUX_VERSION_CODE == KERNEL_VERSION(2,6,23)) +#define kmem_cache_create(name, objsize, align, flags, ctor) \ + ({ \ + if (ctor) __incompatible_kmem_cache_create(); \ + kmem_cache_create((name), (objsize), (align), \ + (flags), NULL); \ + }) +#endif + +/* From include/linux/mod_devicetable.h */ + +/* SSB core, see drivers/ssb/ */ +#ifndef SSB_DEVICE +struct ssb_device_id { + __u16 vendor; + __u16 coreid; + __u8 revision; +}; +#define SSB_DEVICE(_vendor, _coreid, _revision) \ + { .vendor = _vendor, .coreid = _coreid, .revision = _revision, } +#define SSB_DEVTABLE_END \ + { 0, }, + +#define SSB_ANY_VENDOR 0xFFFF +#define SSB_ANY_ID 0xFFFF +#define SSB_ANY_REV 0xFF +#endif + + +/* Namespace stuff, introduced on 2.6.24 */ +#define dev_get_by_index(a, b) dev_get_by_index(b) +#define __dev_get_by_index(a, b) __dev_get_by_index(b) + +/* + * Display a 6 byte device address (MAC) in a readable format. + */ +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x" +extern char *print_mac(char *buf, const u8 *addr); +#define DECLARE_MAC_BUF(var) char var[18] __maybe_unused + +extern int eth_header(struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, + void *saddr, unsigned len); +extern int eth_rebuild_header(struct sk_buff *skb); +extern void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, + unsigned char * haddr); +extern int eth_header_cache(struct neighbour *neigh, + struct hh_cache *hh); + +/* This structure is simply not present on 2.6.22 and 2.6.23 */ +struct header_ops { + int (*create) (struct sk_buff *skb, struct net_device *dev, + unsigned short type, void *daddr, + void *saddr, unsigned len); + int (*parse)(const struct sk_buff *skb, unsigned char *haddr); + int (*rebuild)(struct sk_buff *skb); + #define HAVE_HEADER_CACHE + int (*cache)(struct neighbour *neigh, struct hh_cache *hh); + void (*cache_update)(struct hh_cache *hh, + struct net_device *dev, + unsigned char *haddr); +}; + +/* net/ieee80211/ieee80211_crypt_tkip uses sg_init_table. This was added on + * 2.6.24. CONFIG_DEBUG_SG was added in 2.6.24 as well, so lets just ignore + * the debug stuff. Note that adding this required changes to the struct + * scatterlist on include/asm/scatterlist*, so the right way to port this + * is to simply ignore the new structure changes and zero the scatterlist + * array. We lave the kdoc intact for reference. + */ + +/** + * sg_mark_end - Mark the end of the scatterlist + * @sg: SG entryScatterlist + * + * Description: + * Marks the passed in sg entry as the termination point for the sg + * table. A call to sg_next() on this entry will return NULL. + * + **/ +static inline void sg_mark_end(struct scatterlist *sg) +{ +} + +/** + * sg_init_table - Initialize SG table + * @sgl: The SG table + * @nents: Number of entries in table + * + * Notes: + * If this is part of a chained sg table, sg_mark_end() should be + * used only on the last table part. + * + **/ +{ + memset(sgl, 0, sizeof(*sgl) * nents); +} + +/** + * usb_endpoint_num - get the endpoint's number + * @epd: endpoint to be checked + * + * Returns @epd's number: 0 to 15. + */ +static inline int usb_endpoint_num(const struct usb_endpoint_descriptor *epd) +{ + return epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; +} + +/* Helper to make struct pci_dev is_pcie compatibility code smaller */ +int compat_is_pcie(struct pci_dev *pdev); + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)) */ + +#endif /* LINUX_26_24_COMPAT_H */ diff --git a/include/linux/compat-2.6.25.h b/include/linux/compat-2.6.25.h new file mode 100644 index 0000000..23cf487 --- /dev/null +++ b/include/linux/compat-2.6.25.h @@ -0,0 +1,112 @@ +#ifndef LINUX_26_25_COMPAT_H +#define LINUX_26_25_COMPAT_H + +#include +#include + +/* Compat work for 2.6.24 */ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) + +#include +#include +#include +#include +#include +#include +#include + +#define __WARN(foo) dump_stack() + +#define dev_emerg(dev, format, arg...) \ + dev_printk(KERN_EMERG , dev , format , ## arg) +#define dev_alert(dev, format, arg...) \ + dev_printk(KERN_ALERT , dev , format , ## arg) +#define dev_crit(dev, format, arg...) \ + dev_printk(KERN_CRIT , dev , format , ## arg) + +extern int __dev_addr_sync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count); +extern void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, struct dev_addr_list **from, int *from_count); + +#define seq_file_net &init_net; + +enum nf_inet_hooks { + NF_INET_PRE_ROUTING = 0, + NF_INET_LOCAL_IN = 1, + NF_INET_FORWARD = 2, + NF_INET_LOCAL_OUT = 3, + NF_INET_POST_ROUTING = 4, + NF_INET_NUMHOOKS = 5 +}; + +/* The patch: + * commit 8b5f6883683c91ad7e1af32b7ceeb604d68e2865 + * Author: Marcin Slusarz + * Date: Fri Feb 8 04:20:12 2008 -0800 + * + * byteorder: move le32_add_cpu & friends from OCFS2 to core + * + * moves le*_add_cpu and be*_add_cpu functions from OCFS2 to core + * header (1st) and converted some existing code to it. We port + * it here as later kernels will most likely use it. + */ +static inline void le16_add_cpu(__le16 *var, u16 val) +{ + *var = cpu_to_le16(le16_to_cpu(*var) + val); +} + +static inline void le32_add_cpu(__le32 *var, u32 val) +{ + *var = cpu_to_le32(le32_to_cpu(*var) + val); +} + +static inline void le64_add_cpu(__le64 *var, u64 val) +{ + *var = cpu_to_le64(le64_to_cpu(*var) + val); +} + +static inline void be16_add_cpu(__be16 *var, u16 val) +{ + u16 v = be16_to_cpu(*var); + *var = cpu_to_be16(v + val); +} + +static inline void be32_add_cpu(__be32 *var, u32 val) +{ + u32 v = be32_to_cpu(*var); + *var = cpu_to_be32(v + val); +} + +static inline void be64_add_cpu(__be64 *var, u64 val) +{ + u64 v = be64_to_cpu(*var); + *var = cpu_to_be64(v + val); +} + +/* 2.6.25 changes hwrng_unregister()'s behaviour by supporting + * suspend of its parent device (the misc device, which is itself the + * hardware random number generator). It does this by passing a parameter to + * unregister_miscdev() which is not supported in older kernels. The suspend + * parameter allows us to enable access to the device's hardware + * number generator during suspend. As far as wireless is concerned this means + * if a driver goes to suspend it you won't have the HNR available in + * older kernels. */ +static inline void __hwrng_unregister(struct hwrng *rng, bool suspended) +{ + hwrng_unregister(rng); +} + +static inline void led_classdev_unregister_suspended(struct led_classdev *lcd) +{ + led_classdev_unregister(lcd); +} + +/** + * The following things are out of ./include/linux/kernel.h + * The new iwlwifi driver is using them. + */ +extern int strict_strtoul(const char *, unsigned int, unsigned long *); +extern int strict_strtol(const char *, unsigned int, long *); + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25)) */ + +#endif /* LINUX_26_25_COMPAT_H */ diff --git a/include/linux/compat-2.6.26.h b/include/linux/compat-2.6.26.h new file mode 100644 index 0000000..b7c3b05 --- /dev/null +++ b/include/linux/compat-2.6.26.h @@ -0,0 +1,377 @@ +#ifndef LINUX_26_26_COMPAT_H +#define LINUX_26_26_COMPAT_H + +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) + +#include +#include +#include +#include +#include +#include + +/* These jiffie helpers added as of 2.6.26 */ + +/* + * These four macros compare jiffies and 'a' for convenience. + */ + +/* time_is_before_jiffies(a) return true if a is before jiffies */ +#define time_is_before_jiffies(a) time_after(jiffies, a) + +/* time_is_after_jiffies(a) return true if a is after jiffies */ +#define time_is_after_jiffies(a) time_before(jiffies, a) + +/* time_is_before_eq_jiffies(a) return true if a is before or equal to jiffies*/ +#define time_is_before_eq_jiffies(a) time_after_eq(jiffies, a) + +/* time_is_after_eq_jiffies(a) return true if a is after or equal to jiffies*/ +#define time_is_after_eq_jiffies(a) time_before_eq(jiffies, a) + +/* This comes from include/linux/input.h */ +#define SW_RFKILL_ALL 0x03 /* rfkill master switch, type "any" + set = radio enabled */ + +/* From kernel.h */ +#define USHORT_MAX ((u16)(~0U)) +#define SHORT_MAX ((s16)(USHORT_MAX>>1)) +#define SHORT_MIN (-SHORT_MAX - 1) + +extern int dev_set_name(struct device *dev, const char *name, ...) + __attribute__((format(printf, 2, 3))); + +/** + * clamp_t - return a value clamped to a given range using a given type + * @type: the type of variable to use + * @val: current value + * @min: minimum allowable value + * @max: maximum allowable value + * + * This macro does no typechecking and uses temporary variables of type + * 'type' to make all the comparisons. + */ +#define clamp_t(type, val, min, max) ({ \ + type __val = (val); \ + type __min = (min); \ + type __max = (max); \ + __val = __val < __min ? __min: __val; \ + __val > __max ? __max: __val; }) + + +/* from include/linux/device.h */ +/* device_create_drvdata() is new */ +extern struct device *device_create_drvdata(struct class *cls, + struct device *parent, + dev_t devt, + void *drvdata, + const char *fmt, ...) +__attribute__((format(printf, 5, 6))); + +/* This is from include/linux/list.h */ + +/** + * list_is_singular - tests whether a list has just one entry. + * @head: the list to test. + */ +static inline int list_is_singular(const struct list_head *head) +{ + return !list_empty(head) && (head->next == head->prev); +} + +/* This is from include/linux/device.h, which was added as of 2.6.26 */ +static inline const char *dev_name(struct device *dev) +{ + /* will be changed into kobject_name(&dev->kobj) in the near future */ + return dev->bus_id; +} + +/* This is from include/linux/kernel.h, which was added as of 2.6.26 */ + +/** + * clamp_val - return a value clamped to a given range using val's type + * @val: current value + * @min: minimum allowable value + * @max: maximum allowable value + * + * This macro does no typechecking and uses temporary variables of whatever + * type the input argument 'val' is. This is useful when val is an unsigned + * type and min and max are literals that will otherwise be assigned a signed + * integer type. + */ + +#define clamp_val(val, min, max) ({ \ + typeof(val) __val = (val); \ + typeof(val) __min = (min); \ + typeof(val) __max = (max); \ + __val = __val < __min ? __min: __val; \ + __val > __max ? __max: __val; }) + +/* This comes from include/net/net_namespace.h */ + +#ifdef CONFIG_NET_NS +static inline +int net_eq(const struct net *net1, const struct net *net2) +{ + return net1 == net2; +} +#else +static inline +int net_eq(const struct net *net1, const struct net *net2) +{ + return 1; +} +#endif + +static inline +void dev_net_set(struct net_device *dev, struct net *net) +{ +#ifdef CONFIG_NET_NS + release_net(dev->nd_net); + dev->nd_net = hold_net(net); +#endif +} + +static inline +struct net *sock_net(const struct sock *sk) +{ +#ifdef CONFIG_NET_NS + return sk->sk_net; +#else + return &init_net; +#endif +} + +/* This comes from include/linux/netdevice.h */ + +/* + * Net namespace inlines + */ +static inline +struct net *dev_net(const struct net_device *dev) +{ +#ifdef CONFIG_NET_NS + /* + * compat-wirelss backport note: + * For older kernels we may just need to always return init_net, + * not sure when we added dev->nd_net. + */ + return dev->nd_net; +#else + return &init_net; +#endif +} + + +/* + * 2.6.26 added its own unaligned API which the + * new drivers can use. Lets port it here by including it in older + * kernels and also deal with the architecture handling here. + */ + +#ifdef CONFIG_ALPHA + +#include +#include +#include + +#endif /* alpha */ +#ifdef CONFIG_ARM + +/* arm */ +#include +#include +#include + +#endif /* arm */ +#ifdef CONFIG_AVR32 + +/* + * AVR32 can handle some unaligned accesses, depending on the + * implementation. The AVR32 AP implementation can handle unaligned + * words, but halfwords must be halfword-aligned, and doublewords must + * be word-aligned. + * + * However, swapped word loads must be word-aligned so we can't + * optimize word loads in general. + */ + +#include +#include +#include + +#endif +#ifdef CONFIG_BLACKFIN + +#include +#include +#include + +#endif /* blackfin */ +#ifdef CONFIG_CRIS + +/* + * CRIS can do unaligned accesses itself. + */ +#include +#include + +#endif /* cris */ +#ifdef CONFIG_FRV + +#include +#include +#include + +#endif /* frv */ +#ifdef CONFIG_H8300 + +#include +#include +#include + +#endif /* h8300 */ +#ifdef CONFIG_IA64 + +#include +#include +#include + +#endif /* ia64 */ +#ifdef CONFIG_M32R + +#if defined(__LITTLE_ENDIAN__) +# include +# include +# include +#else +# include +# include +# include +#endif + +#endif /* m32r */ +#ifdef CONFIG_M68K /* this handles both m68k and m68knommu */ + +#ifdef CONFIG_COLDFIRE +#include +#include +#include +#else + +/* + * The m68k can do unaligned accesses itself. + */ +#include +#include +#endif + +#endif /* m68k and m68knommu */ +#ifdef CONFIG_MIPS + +#if defined(__MIPSEB__) +# include +# include +# include +# define get_unaligned __get_unaligned_be +# define put_unaligned __put_unaligned_be +#elif defined(__MIPSEL__) +# include +# include +# include +#endif + +#endif /* mips */ +#ifdef CONFIG_MN10300 + +#include +#include + +#endif /* mn10300 */ +#ifdef CONFIG_PARISC + +#include +#include +#include + +#endif /* parisc */ +#ifdef CONFIG_PPC +/* + * The PowerPC can do unaligned accesses itself in big endian mode. + */ +#include +#include + +#endif /* ppc */ +#ifdef CONFIG_S390 + +/* + * The S390 can do unaligned accesses itself. + */ +#include +#include + +#endif /* s390 */ +#ifdef CONFIG_SUPERH + +/* SH can't handle unaligned accesses. */ +#ifdef __LITTLE_ENDIAN__ +# include +# include +# include +#else +# include +# include +# include +#endif + +#endif /* sh - SUPERH */ +#ifdef CONFIG_SPARC + +/* sparc and sparc64 */ +#include +#include +#include + +#endif /* sparc */ +#ifdef CONFIG_UML + +#include "asm/arch/unaligned.h" + +#endif /* um - uml */ +#ifdef CONFIG_V850 + +#include +#include +#include + +#endif /* v850 */ +#ifdef CONFIG_X86 +/* + * The x86 can do unaligned accesses itself. + */ +#include +#include + +#endif /* x86 */ +#ifdef CONFIG_XTENSA + +#ifdef __XTENSA_EL__ +# include +# include +# include +#elif defined(__XTENSA_EB__) +# include +# include +# include +#else +# error processor byte order undefined! +#endif + +#endif /* xtensa */ + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26)) */ + +#endif /* LINUX_26_26_COMPAT_H */ diff --git a/include/linux/compat-2.6.27.h b/include/linux/compat-2.6.27.h new file mode 100644 index 0000000..ed10a6c --- /dev/null +++ b/include/linux/compat-2.6.27.h @@ -0,0 +1,183 @@ +#ifndef LINUX_26_27_COMPAT_H +#define LINUX_26_27_COMPAT_H + +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PCI_PM_CAP_PME_SHIFT 11 + +/* I can't find a more suitable replacement... */ +#define flush_work(work) cancel_work_sync(work) + +/* + * On older kernels we do not have net_device Multi Queue support, but + * since we no longer use MQ on mac80211 we can simply use the 0 queue. + * Note that if other fullmac drivers make use of this they then need + * to be backported somehow or deal with just 1 queueue from MQ. + */ +static inline void netif_tx_wake_all_queues(struct net_device *dev) +{ + netif_wake_queue(dev); +} +static inline void netif_tx_start_all_queues(struct net_device *dev) +{ + netif_start_queue(dev); +} +static inline void netif_tx_stop_all_queues(struct net_device *dev) +{ + netif_stop_queue(dev); +} + +bool pci_pme_capable(struct pci_dev *dev, pci_power_t state); + +/* + * The net_device has a spin_lock on newer kernels, on older kernels we're out of luck + */ +#define netif_addr_lock_bh +#define netif_addr_unlock_bh + +/* + * To port this properly we'd have to port warn_slowpath_null(), + * which I'm lazy to do so just do a regular print for now. If you + * want to port this read kernel/panic.c + */ +#define __WARN_printf(arg...) do { printk(arg); __WARN(); } while (0) + +/* This is ported directly as-is on newer kernels */ +#ifndef WARN +#define WARN(condition, format...) ({ \ + int __ret_warn_on = !!(condition); \ + if (unlikely(__ret_warn_on)) \ + __WARN_printf(format); \ + unlikely(__ret_warn_on); \ +}) +#endif + +/* On 2.6.27 a second argument was added, on older kernels we ignore it */ +#define dma_mapping_error(pdev, dma_addr) dma_mapping_error(dma_addr) +#define pci_dma_mapping_error(pdev, dma_addr) dma_mapping_error(pdev, dma_addr) + +/* This is from include/linux/ieee80211.h */ +#define IEEE80211_HT_CAP_DSSSCCK40 0x1000 + +/* New link list changes added as of 2.6.27, needed for ath9k */ + +static inline void __list_cut_position(struct list_head *list, + struct list_head *head, struct list_head *entry) +{ + struct list_head *new_first = entry->next; + list->next = head->next; + list->next->prev = list; + list->prev = entry; + entry->next = list; + head->next = new_first; + new_first->prev = head; +} + +/** + * list_cut_position - cut a list into two + * @list: a new list to add all removed entries + * @head: a list with entries + * @entry: an entry within head, could be the head itself + * and if so we won't cut the list + * + * This helper moves the initial part of @head, up to and + * including @entry, from @head to @list. You should + * pass on @entry an element you know is on @head. @list + * should be an empty list or a list you do not care about + * losing its data. + * + */ +static inline void list_cut_position(struct list_head *list, + struct list_head *head, struct list_head *entry) +{ + if (list_empty(head)) + return; + if (list_is_singular(head) && + (head->next != entry && head != entry)) + return; + if (entry == head) + INIT_LIST_HEAD(list); + else + __list_cut_position(list, head, entry); +} + + +/* __list_splice as re-implemented on 2.6.27, we backport it */ +static inline void __compat_list_splice_new_27(const struct list_head *list, + struct list_head *prev, + struct list_head *next) +{ + struct list_head *first = list->next; + struct list_head *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +/** + * list_splice_tail - join two lists, each list being a queue + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice_tail(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __compat_list_splice_new_27(list, head->prev, head); +} + +/** + * list_splice_tail_init - join two lists and reinitialise the emptied list + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * Each of the lists is a queue. + * The list at @list is reinitialised + */ +static inline void list_splice_tail_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __compat_list_splice_new_27(list, head->prev, head); + INIT_LIST_HEAD(list); + } +} + +extern unsigned int mmc_align_data_size(struct mmc_card *, unsigned int); +extern unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz); + +#define iwe_stream_add_value(info, event, value, ends, iwe, event_len) iwe_stream_add_value(event, value, ends, iwe, event_len) +#define iwe_stream_add_point(info, stream, ends, iwe, extra) iwe_stream_add_point(stream, ends, iwe, extra) +#define iwe_stream_add_event(info, stream, ends, iwe, event_len) iwe_stream_add_event(stream, ends, iwe, event_len) + +/* Flags available in struct iw_request_info */ +#define IW_REQUEST_FLAG_COMPAT 0x0001 /* Compat ioctl call */ + +static inline int iwe_stream_lcp_len(struct iw_request_info *info) +{ +#ifdef CONFIG_COMPAT + if (info->flags & IW_REQUEST_FLAG_COMPAT) + return IW_EV_COMPAT_LCP_LEN; +#endif + return IW_EV_LCP_LEN; +} + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27)) */ + +#endif /* LINUX_26_27_COMPAT_H */ diff --git a/include/linux/compat-2.6.28.h b/include/linux/compat-2.6.28.h new file mode 100644 index 0000000..8f90edc --- /dev/null +++ b/include/linux/compat-2.6.28.h @@ -0,0 +1,209 @@ +#ifndef LINUX_26_28_COMPAT_H +#define LINUX_26_28_COMPAT_H + +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) + +#include +#include +#include + +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#endif + +#include + +#ifndef WARN_ONCE +#define WARN_ONCE(condition, format...) ({ \ + static int __warned; \ + int __ret_warn_once = !!(condition); \ + \ + if (unlikely(__ret_warn_once)) \ + if (WARN(!__warned, format)) \ + __warned = 1; \ + unlikely(__ret_warn_once); \ +}) +#endif /* From include/asm-generic/bug.h */ + +#include +#include +#include +#ifdef pcmcia_parse_tuple +#undef pcmcia_parse_tuple +#define pcmcia_parse_tuple(tuple, parse) pccard_parse_tuple(tuple, parse) +#endif + +/* From : include/pcmcia/ds.h */ +/* loop CIS entries for valid configuration */ +int pcmcia_loop_config(struct pcmcia_device *p_dev, + int (*conf_check) (struct pcmcia_device *p_dev, + cistpl_cftable_entry_t *cfg, + cistpl_cftable_entry_t *dflt, + unsigned int vcc, + void *priv_data), + void *priv_data); + +#if 0 +extern void usb_poison_urb(struct urb *urb); +#endif +extern void usb_unpoison_urb(struct urb *urb); + +#if 0 +extern void usb_poison_anchored_urbs(struct usb_anchor *anchor); +#endif + +extern struct urb *usb_get_from_anchor(struct usb_anchor *anchor); +extern void usb_scuttle_anchored_urbs(struct usb_anchor *anchor); +extern int usb_anchor_empty(struct usb_anchor *anchor); + + +void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar); + +/** + * skb_queue_is_last - check if skb is the last entry in the queue + * @list: queue head + * @skb: buffer + * + * Returns true if @skb is the last buffer on the list. + */ +static inline bool skb_queue_is_last(const struct sk_buff_head *list, + const struct sk_buff *skb) +{ + return (skb->next == (struct sk_buff *) list); +} + +/** + * skb_queue_next - return the next packet in the queue + * @list: queue head + * @skb: current buffer + * + * Return the next packet in @list after @skb. It is only valid to + * call this if skb_queue_is_last() evaluates to false. + */ +static inline struct sk_buff *skb_queue_next(const struct sk_buff_head *list, + const struct sk_buff *skb) +{ + /* This BUG_ON may seem severe, but if we just return then we + * are going to dereference garbage. + */ + BUG_ON(skb_queue_is_last(list, skb)); + return skb->next; +} + +/** + * __skb_queue_head_init - initialize non-spinlock portions of sk_buff_head + * @list: queue to initialize + * + * This initializes only the list and queue length aspects of + * an sk_buff_head object. This allows to initialize the list + * aspects of an sk_buff_head without reinitializing things like + * the spinlock. It can also be used for on-stack sk_buff_head + * objects where the spinlock is known to not be used. + */ +static inline void __skb_queue_head_init(struct sk_buff_head *list) +{ + list->prev = list->next = (struct sk_buff *)list; + list->qlen = 0; +} + +static inline void __skb_queue_splice(const struct sk_buff_head *list, + struct sk_buff *prev, + struct sk_buff *next) +{ + struct sk_buff *first = list->next; + struct sk_buff *last = list->prev; + + first->prev = prev; + prev->next = first; + + last->next = next; + next->prev = last; +} + +/** + * skb_queue_splice - join two skb lists, this is designed for stacks + * @list: the new list to add + * @head: the place to add it in the first list + */ +static inline void skb_queue_splice(const struct sk_buff_head *list, + struct sk_buff_head *head) +{ + if (!skb_queue_empty(list)) { + __skb_queue_splice(list, (struct sk_buff *) head, head->next); + head->qlen += list->qlen; + } +} + +/** + * skb_queue_splice_tail - join two skb lists and reinitialise the emptied list + * @list: the new list to add + * @head: the place to add it in the first list + * + * Each of the lists is a queue. + * The list at @list is reinitialised + */ +static inline void skb_queue_splice_tail_init(struct sk_buff_head *list, + struct sk_buff_head *head) +{ + if (!skb_queue_empty(list)) { + __skb_queue_splice(list, head->prev, (struct sk_buff *) head); + head->qlen += list->qlen; + __skb_queue_head_init(list); + } +} /* From include/linux/skbuff.h */ + +/** + * skb_queue_splice_tail - join two skb lists, each list being a queue + * @list: the new list to add + * @head: the place to add it in the first list + */ +static inline void skb_queue_splice_tail(const struct sk_buff_head *list, + struct sk_buff_head *head) +{ + if (!skb_queue_empty(list)) { + __skb_queue_splice(list, head->prev, (struct sk_buff *) head); + head->qlen += list->qlen; + } +} + +#ifndef DECLARE_TRACE + +#define TP_PROTO(args...) args +#define TP_ARGS(args...) args + +#define DECLARE_TRACE(name, proto, args) \ + static inline void _do_trace_##name(struct tracepoint *tp, proto) \ + { } \ + static inline void trace_##name(proto) \ + { } \ + static inline int register_trace_##name(void (*probe)(proto)) \ + { \ + return -ENOSYS; \ + } \ + static inline int unregister_trace_##name(void (*probe)(proto)) \ + { \ + return -ENOSYS; \ + } + +#define EXPORT_TRACEPOINT_SYMBOL_GPL(name) +#define EXPORT_TRACEPOINT_SYMBOL(name) + + +#endif + +/* openSuse includes round_jiffies_up in it's kernel 2.6.27. + * This is needed to prevent conflicts with the openSuse definition. + */ +#define round_jiffies_up backport_round_jiffies_up + +unsigned long round_jiffies_up(unsigned long j); + +extern void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, + int off, int size); + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) */ + +#endif /* LINUX_26_28_COMPAT_H */ diff --git a/include/linux/compat-2.6.29.h b/include/linux/compat-2.6.29.h new file mode 100644 index 0000000..cad5e6b --- /dev/null +++ b/include/linux/compat-2.6.29.h @@ -0,0 +1,61 @@ +#ifndef LINUX_26_29_COMPAT_H +#define LINUX_26_29_COMPAT_H + +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + +#include +#include +#include + +/** + * skb_queue_is_first - check if skb is the first entry in the queue + * @list: queue head + * @skb: buffer + * + * Returns true if @skb is the first buffer on the list. + */ +static inline bool skb_queue_is_first(const struct sk_buff_head *list, + const struct sk_buff *skb) +{ + return (skb->prev == (struct sk_buff *) list); +} + +/** + * skb_queue_prev - return the prev packet in the queue + * @list: queue head + * @skb: current buffer + * + * Return the prev packet in @list before @skb. It is only valid to + * call this if skb_queue_is_first() evaluates to false. + */ +static inline struct sk_buff *skb_queue_prev(const struct sk_buff_head *list, + const struct sk_buff *skb) +{ + /* This BUG_ON may seem severe, but if we just return then we + * are going to dereference garbage. + */ + BUG_ON(skb_queue_is_first(list, skb)); + return skb->prev; +} + + +static inline struct net_device_stats *dev_get_stats(struct net_device *dev) +{ + return dev->get_stats(dev); +} + +extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor); + +#define DIV_ROUND_CLOSEST(x, divisor)( \ +{ \ + typeof(divisor) __divisor = divisor; \ + (((x) + ((__divisor) / 2)) / (__divisor)); \ +} \ +) + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) */ + +#endif /* LINUX_26_29_COMPAT_H */ diff --git a/include/linux/compat-2.6.30.h b/include/linux/compat-2.6.30.h new file mode 100644 index 0000000..2ff1d69 --- /dev/null +++ b/include/linux/compat-2.6.30.h @@ -0,0 +1,29 @@ +#ifndef LINUX_26_30_COMPAT_H +#define LINUX_26_30_COMPAT_H + +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) + +#ifndef TP_PROTO +#define TP_PROTO(args...) TPPROTO(args) +#endif +#ifndef TP_ARGS +#define TP_ARGS(args...) TPARGS(args) +#endif + +#define IRQ_WAKE_THREAD (2) + +/* From : include/linux/pm.h */ +/* How to reorder dpm_list after device_move() */ +enum dpm_order { + DPM_ORDER_NONE, + DPM_ORDER_DEV_AFTER_PARENT, + DPM_ORDER_PARENT_BEFORE_DEV, + DPM_ORDER_DEV_LAST, +}; + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30)) */ + +#endif /* LINUX_26_30_COMPAT_H */ diff --git a/include/linux/compat-2.6.31.h b/include/linux/compat-2.6.31.h new file mode 100644 index 0000000..27dc6a1 --- /dev/null +++ b/include/linux/compat-2.6.31.h @@ -0,0 +1,198 @@ +#ifndef LINUX_26_31_COMPAT_H +#define LINUX_26_31_COMPAT_H + +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) + +#include +#include +#include +#include +#include +#include + +/* + * These macros allow us to backport rfkill without any + * changes on cfg80211 through compat.diff. Note that this + * file will be included by rfkill_backport.h so we must + * not conflict with things there. + */ +#define rfkill_get_led_trigger_name backport_rfkill_get_led_trigger_name +#define rfkill_set_led_trigger_name backport_rfkill_set_led_trigger_name +#define rfkill_set_hw_state backport_rfkill_set_hw_state +#define rfkill_set_sw_state backport_rfkill_set_sw_state +#define rfkill_init_sw_state backport_rfkill_init_sw_state +#define rfkill_set_states backport_rfkill_set_states +#define rfkill_pause_polling backport_rfkill_pause_polling +#define rfkill_resume_polling backport_rfkill_resume_polling +#define rfkill_blocked backport_rfkill_blocked +#define rfkill_alloc backport_rfkill_alloc +#define rfkill_register backport_rfkill_register +#define rfkill_unregister backport_rfkill_unregister +#define rfkill_destroy backport_rfkill_destroy + +#ifndef ERFKILL +#if !defined(CONFIG_ALPHA) && !defined(CONFIG_MIPS) && !defined(CONFIG_PARISC) && !defined(CONFIG_SPARC) +#define ERFKILL 132 /* Operation not possible due to RF-kill */ +#endif +#ifdef CONFIG_ALPHA +#define ERFKILL 138 /* Operation not possible due to RF-kill */ +#endif +#ifdef CONFIG_MIPS +#define ERFKILL 167 /* Operation not possible due to RF-kill */ +#endif +#ifdef CONFIG_PARISC +#define ERFKILL 256 /* Operation not possible due to RF-kill */ +#endif +#ifdef CONFIG_SPARC +#define ERFKILL 134 /* Operation not possible due to RF-kill */ +#endif +#endif + +#ifndef NETDEV_PRE_UP +#define NETDEV_PRE_UP 0x000D +#endif + +#ifndef SDIO_DEVICE_ID_MARVELL_8688WLAN +#define SDIO_DEVICE_ID_MARVELL_8688WLAN 0x9104 +#endif + +struct compat_threaded_irq { + unsigned int irq; + irq_handler_t handler; + irq_handler_t thread_fn; + void *dev_id; + char wq_name[64]; + struct workqueue_struct *wq; + struct work_struct work; +}; + +/* + * kmemleak was introduced on 2.6.31, since older kernels do not have + * we simply ignore its tuning. + */ +static inline void kmemleak_ignore(const void *ptr) +{ + return; +} + +static inline void kmemleak_not_leak(const void *ptr) +{ + return; +} + +static inline void kmemleak_no_scan(const void *ptr) +{ + return; +} + +/* + * Added via adf30907d63893e4208dfe3f5c88ae12bc2f25d5 + * + * There is no _sk_dst on older kernels, so just set the + * old dst to NULL and release it directly. + */ +static inline void skb_dst_drop(struct sk_buff *skb) +{ + dst_release(skb->dst); + skb->dst = NULL; +} + +static inline struct dst_entry *skb_dst(const struct sk_buff *skb) +{ + return (struct dst_entry *)skb->dst; +} + +static inline void skb_dst_set(struct sk_buff *skb, struct dst_entry *dst) +{ + skb->dst = dst; +} + +static inline struct rtable *skb_rtable(const struct sk_buff *skb) +{ + return (struct rtable *)skb_dst(skb); +} + +extern int genl_register_family_with_ops(struct genl_family *family, + struct genl_ops *ops, size_t n_ops); + + +/* Backport threaded IRQ support */ + +static inline +void compat_irq_work(struct work_struct *work) +{ + struct compat_threaded_irq *comp = container_of(work, struct compat_threaded_irq, work); + comp->thread_fn(comp->irq, comp->dev_id); +} + +static inline +irqreturn_t compat_irq_dispatcher(int irq, void *dev_id) +{ + struct compat_threaded_irq *comp = dev_id; + irqreturn_t res; + + res = comp->handler(irq, comp->dev_id); + if (res == IRQ_WAKE_THREAD) { + queue_work(comp->wq, &comp->work); + res = IRQ_HANDLED; + } + + return res; +} + +static inline +int compat_request_threaded_irq(struct compat_threaded_irq *comp, + unsigned int irq, + irq_handler_t handler, + irq_handler_t thread_fn, + unsigned long flags, + const char *name, + void *dev_id) +{ + comp->irq = irq; + comp->handler = handler; + comp->thread_fn = thread_fn; + comp->dev_id = dev_id; + INIT_WORK(&comp->work, compat_irq_work); + + if (!comp->wq) { + snprintf(comp->wq_name, sizeof(comp->wq_name), + "compirq/%u-%s", irq, name); + comp->wq = create_singlethread_workqueue(comp->wq_name); + if (!comp->wq) { + printk(KERN_ERR "Failed to create compat-threaded-IRQ workqueue %s\n", + comp->wq_name); + return -ENOMEM; + } + } + return request_irq(irq, compat_irq_dispatcher, flags, name, comp); +} + +static inline +void compat_free_threaded_irq(struct compat_threaded_irq *comp) +{ + free_irq(comp->irq, comp); +} + +static inline +void compat_destroy_threaded_irq(struct compat_threaded_irq *comp) +{ + if (comp->wq) + destroy_workqueue(comp->wq); + comp->wq = NULL; +} + +static inline +void compat_synchronize_threaded_irq(struct compat_threaded_irq *comp) +{ + synchronize_irq(comp->irq); + cancel_work_sync(&comp->work); +} + + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,31)) */ + +#endif /* LINUX_26_31_COMPAT_H */ diff --git a/include/linux/compat-2.6.32.h b/include/linux/compat-2.6.32.h new file mode 100644 index 0000000..3e8725a --- /dev/null +++ b/include/linux/compat-2.6.32.h @@ -0,0 +1,76 @@ +#ifndef LINUX_26_32_COMPAT_H +#define LINUX_26_32_COMPAT_H + +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) + +#include +#include + +#define SDIO_VENDOR_ID_INTEL 0x0089 +#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402 +#define SDIO_DEVICE_ID_INTEL_IWMC3200WIFI 0x1403 +#define SDIO_DEVICE_ID_INTEL_IWMC3200TOP 0x1404 +#define SDIO_DEVICE_ID_INTEL_IWMC3200GPS 0x1405 +#define SDIO_DEVICE_ID_INTEL_IWMC3200BT 0x1406 + +/* + * struct genl_multicast_group was made netns aware through + * patch "genetlink: make netns aware" by johannes, we just + * force this to always use the default init_net + */ +#define genl_info_net(x) &init_net +/* Just use init_net for older kernels */ +#define get_net_ns_by_pid(x) &init_net + +/* net namespace is lost */ +#define genlmsg_multicast_netns(a, b, c, d, e) genlmsg_multicast(b, c, d, e) +#define genlmsg_multicast_allns(a, b, c, d) genlmsg_multicast(a, b, c, d) + +#define dev_change_net_namespace(a, b, c) (-EOPNOTSUPP) + +#define SET_NETDEV_DEVTYPE(netdev, type) + +#ifdef __KERNEL__ +/* Driver transmit return codes */ +enum netdev_tx { + BACKPORT_NETDEV_TX_OK = NETDEV_TX_OK, /* driver took care of packet */ + BACKPORT_NETDEV_TX_BUSY = NETDEV_TX_BUSY, /* driver tx path was busy*/ + BACKPORT_NETDEV_TX_LOCKED = NETDEV_TX_LOCKED, /* driver tx lock was already taken */ +}; +typedef enum netdev_tx netdev_tx_t; +#endif /* __KERNEL__ */ + +/* + * dev_pm_ops is only available on kernels >= 2.6.29, for + * older kernels we rely on reverting the work to old + * power management style stuff. + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)) +/* + * Use this if you want to use the same suspend and resume callbacks for suspend + * to RAM and hibernation. + */ +#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) \ +struct dev_pm_ops name = { \ + .suspend = suspend_fn, \ + .resume = resume_fn, \ + .freeze = suspend_fn, \ + .thaw = resume_fn, \ + .poweroff = suspend_fn, \ + .restore = resume_fn, \ +} +#else +#define SIMPLE_DEV_PM_OPS(name, suspend_fn, resume_fn) +#endif /* >= 2.6.29 */ + +#define wireless_send_event(a, b, c, d) wireless_send_event(a, b, c, (char * ) d) + +/* The export symbol in changed in compat/patches/15-symbol-export-conflicts.patch */ +#define ieee80211_rx(hw, skb) mac80211_ieee80211_rx(hw, skb) + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) */ + +#endif /* LINUX_26_32_COMPAT_H */ diff --git a/include/linux/compat-2.6.33.h b/include/linux/compat-2.6.33.h new file mode 100644 index 0000000..528627e --- /dev/null +++ b/include/linux/compat-2.6.33.h @@ -0,0 +1,15 @@ +#ifndef LINUX_26_33_COMPAT_H +#define LINUX_26_33_COMPAT_H + +#include +#include +#include + +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) + +#define IFF_DONT_BRIDGE 0x800 /* disallow bridging this ether dev */ +/* source: include/linux/if.h */ + +#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,33)) */ + +#endif /* LINUX_26_33_COMPAT_H */ diff --git a/include/linux/compat.h b/include/linux/compat.h new file mode 100644 index 0000000..bea00c9 --- /dev/null +++ b/include/linux/compat.h @@ -0,0 +1,26 @@ +#ifndef LINUX_26_COMPAT_H +#define LINUX_26_COMPAT_H + +#include +#include +#include + +/* + * Each compat file represents compatibility code for new kernel + * code introduced for *that* kernel revision. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* LINUX_26_COMPAT_H */ diff --git a/include/linux/compat_autoconf.h b/include/linux/compat_autoconf.h new file mode 100644 index 0000000..813755c --- /dev/null +++ b/include/linux/compat_autoconf.h @@ -0,0 +1,37 @@ +#ifndef COMPAT_AUTOCONF_INCLUDED +#define COMPAT_AUTOCONF_INCLUDED + +/* + * This is an example of a compat autconf header file that gets + * automatically generated by your projet. You will only need this + * if you are working with a lot of config options. + * + * Your project will likely just override this, or leave this as-is. + */ + +/* + * Example automatically generated C config: don't edit + * Thu Dec 10 10:34:11 PST 2009 + * compat-wireless-2.6: master-2009-11-19-5-gb4fd4dd + * linux-2.6: next-20091208 + */ +//#define COMPAT_PROJECT_FOO_RELEASE "master-2009-11-19-5-gb4fd4dd" +//#define COMPAT_UPSTREAM_FOO_KERNEL_RELEASE "next-20091208" + +/* Example kernel version minimum requirement */ +//#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)) +//#error Compat-wireless requirement: Linux >= 2,6,10 +//#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) */ + +/* Example hard requirement */ +//#error Compat-wireless requirement: CONFIG_WIRELESS_EXT must be enabled in your kernel +//#endif /* CONFIG_WIRELESS_EXT */ + +/* + * Example of how to match your external modules kconfig options into this. + * You'll need something to generate this for you. + */ +//#ifndef CONFIG_FOO_BAR +//#define CONFIG_FOO_BAR 1 + +#endif /* COMPAT_AUTOCONF_INCLUDED */ diff --git a/main.c b/main.c deleted file mode 100644 index 390278d..0000000 --- a/main.c +++ /dev/null @@ -1,18 +0,0 @@ -#include - -MODULE_AUTHOR("Luis R. Rodriguez"); -MODULE_DESCRIPTION("Kernel compatibility module"); -MODULE_LICENSE("GPL"); - -static int __init compat_init(void) -{ - return 0; -} -module_init(compat_init); - -static void __exit compat_exit(void) -{ - return; -} -module_exit(compat_exit); -