mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-22 15:02:32 +00:00
e4489675b5
SVN-Revision: 18465
516 lines
15 KiB
Diff
516 lines
15 KiB
Diff
--- a/drivers/net/wireless/ath/ar9170/usb.c
|
|
+++ b/drivers/net/wireless/ath/ar9170/usb.c
|
|
@@ -100,6 +100,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))
|
|
+
|
|
+/**
|
|
+ * 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) */
|
|
+
|
|
+#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 <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
|
|
@@ -12,29 +12,7 @@
|
|
|
|
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
|
|
|
|
-#include <linux/usb.h>
|
|
-
|
|
-/**
|
|
- * 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);
|
|
-
|
|
+/* 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);
|
|
-
|
|
#define DIV_ROUND_CLOSEST(x, divisor)( \
|
|
{ \
|
|
typeof(divisor) __divisor = divisor; \
|