[mac80211] fix module loading with kernel 2.6.27
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 011-move_ar9170_usb_compat_code.patch
index 07daada9e95b3df1345ff179f755c46772106c69..2a705b5ce0b5a10f30b49f9bdf5a7ecb5c6a44d3 100644 (file)
@@ -1,14 +1,11 @@
 --- a/drivers/net/wireless/ath/ar9170/usb.c
 +++ b/drivers/net/wireless/ath/ar9170/usb.c
 --- 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))
 +
  };
  MODULE_DEVICE_TABLE(usb, ar9170_usb_ids);
  
 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
 +
-+#ifdef CONFIG_AR9170_USB
-+#include <linux/usb.h>
-+
 +/**
 + * usb_unpoison_anchored_urbs - let an anchor be used successfully again
 + * @anchor: anchor the requests are bound to
 +/**
 + * usb_unpoison_anchored_urbs - let an anchor be used successfully again
 + * @anchor: anchor the requests are bound to
 +      spin_unlock_irqrestore(&anchor->lock, flags);
 +}
 +EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs);
 +      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;
 +
  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 <linux/usb.h>
+-
+ /* 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
 --- 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))
  
  
  #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
  
--#ifdef CONFIG_AR9170_USB
 -#include <linux/usb.h>
 -
 -/**
 -#include <linux/usb.h>
 -
 -/**
 -      spin_unlock_irqrestore(&anchor->lock, flags);
 -}
 -EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs);
 -      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) */
  
 -
 +/* 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 <linux/skbuff.h>
+ #include <linux/if_ether.h>
+-#include <linux/usb.h>
+ #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 <linux/skbuff.h>
+-#include <linux/usb.h>
+ /**
+  *    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 */