From 02760828716da7cccf9095a9247c0e305d39dcd9 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Tue, 1 Sep 2009 14:53:35 +0000 Subject: [PATCH] [mac80211] fix module loading with kernel 2.6.27 SVN-Revision: 17457 --- .../patches/008-disable_usb_backport.patch | 81 ---- .../011-move_ar9170_usb_compat_code.patch | 459 +++++++++++++++++- 2 files changed, 451 insertions(+), 89 deletions(-) delete mode 100644 package/mac80211/patches/008-disable_usb_backport.patch diff --git a/package/mac80211/patches/008-disable_usb_backport.patch b/package/mac80211/patches/008-disable_usb_backport.patch deleted file mode 100644 index c612413e99..0000000000 --- a/package/mac80211/patches/008-disable_usb_backport.patch +++ /dev/null @@ -1,81 +0,0 @@ ---- a/net/wireless/compat-2.6.28.c -+++ b/net/wireless/compat-2.6.28.c -@@ -12,10 +12,11 @@ - - #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) - --#include -- - /* 2.6.28 compat code goes here */ - -+#ifdef CONFIG_AR9170_USB -+#include -+ - /* - * Compat-wireless notes for USB backport stuff: - * -@@ -206,6 +207,7 @@ int usb_anchor_empty(struct usb_anchor * - } - - EXPORT_SYMBOL_GPL(usb_anchor_empty); -+#endif /* CONFIG_AR9170_USB */ - - - void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar) ---- a/include/net/compat-2.6.28.h -+++ b/include/net/compat-2.6.28.h -@@ -9,7 +9,6 @@ - - #include - #include --#include - - #ifndef ETH_P_PAE - #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -@@ -37,6 +36,8 @@ - #define pcmcia_parse_tuple(tuple, parse) pccard_parse_tuple(tuple, parse) - #endif - -+#ifdef CONFIG_AR9170_USB -+#include - #if 0 - extern void usb_poison_urb(struct urb *urb); - #endif -@@ -49,6 +50,7 @@ extern void usb_poison_anchored_urbs(str - 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); -+#endif /* CONFIG_AR9170_USB */ - - - void __iomem *pci_ioremap_bar(struct pci_dev *pdev, int bar); ---- a/net/wireless/compat-2.6.29.c -+++ b/net/wireless/compat-2.6.29.c -@@ -12,6 +12,7 @@ - - #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) - -+#ifdef CONFIG_AR9170_USB - #include - - /** -@@ -34,6 +35,7 @@ void usb_unpoison_anchored_urbs(struct u - spin_unlock_irqrestore(&anchor->lock, flags); - } - EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs); -+#endif /* CONFIG_AR9170_USB */ - - - #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */ ---- a/include/net/compat-2.6.29.h -+++ b/include/net/compat-2.6.29.h -@@ -41,7 +41,9 @@ static inline struct sk_buff *skb_queue_ - return skb->prev; - } - -+#ifdef CONFIG_AR9170_USB - extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor); -+#endif /* CONFIG_AR9170_USB */ - - #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) */ - diff --git a/package/mac80211/patches/011-move_ar9170_usb_compat_code.patch b/package/mac80211/patches/011-move_ar9170_usb_compat_code.patch index 07daada9e9..2a705b5ce0 100644 --- a/package/mac80211/patches/011-move_ar9170_usb_compat_code.patch +++ b/package/mac80211/patches/011-move_ar9170_usb_compat_code.patch @@ -1,14 +1,11 @@ --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c -@@ -96,6 +96,34 @@ static struct usb_device_id ar9170_usb_i +@@ -96,6 +96,225 @@ static struct usb_device_id ar9170_usb_i }; MODULE_DEVICE_TABLE(usb, ar9170_usb_ids); +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + -+#ifdef CONFIG_AR9170_USB -+#include -+ +/** + * usb_unpoison_anchored_urbs - let an anchor be used successfully again + * @anchor: anchor the requests are bound to @@ -29,19 +26,417 @@ + spin_unlock_irqrestore(&anchor->lock, flags); +} +EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs); -+#endif /* CONFIG_AR9170_USB */ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28)) ++ ++/* ++ * 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 ++ ++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); ++ ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28) */ + static void ar9170_usb_submit_urb(struct ar9170_usb *aru) { struct urb *urb; +--- a/net/wireless/compat-2.6.28.c ++++ b/net/wireless/compat-2.6.28.c +@@ -12,202 +12,8 @@ + + #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 +- +-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) + { + /* --- a/net/wireless/compat-2.6.29.c +++ b/net/wireless/compat-2.6.29.c -@@ -12,31 +12,7 @@ +@@ -12,29 +12,7 @@ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) --#ifdef CONFIG_AR9170_USB -#include - -/** @@ -64,9 +459,57 @@ - spin_unlock_irqrestore(&anchor->lock, flags); -} -EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs); --#endif /* CONFIG_AR9170_USB */ - +/* 2.6.29 compat code goes here */ #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) */ +--- a/include/net/compat-2.6.28.h ++++ b/include/net/compat-2.6.28.h +@@ -9,7 +9,6 @@ + + #include + #include +-#include + + #ifndef ETH_P_PAE + #define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +@@ -37,19 +36,6 @@ + #define pcmcia_parse_tuple(tuple, parse) pccard_parse_tuple(tuple, parse) + #endif + +-#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); + +--- a/include/net/compat-2.6.29.h ++++ b/include/net/compat-2.6.29.h +@@ -8,7 +8,6 @@ + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) + + #include +-#include + + /** + * skb_queue_is_first - check if skb is the first entry in the queue +@@ -41,8 +40,6 @@ static inline struct sk_buff *skb_queue_ + return skb->prev; + } + +-extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor); +- + #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)) */ + + #endif /* LINUX_26_29_COMPAT_H */ -- 2.30.2