We forgot to add usb_poison_urb() and usb_unpoison_urb()
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Fri, 17 Jul 2009 15:53:52 +0000 (08:53 -0700)
committerLuis R. Rodriguez <lrodriguez@atheros.com>
Fri, 17 Jul 2009 15:53:52 +0000 (08:53 -0700)
Also correct the placement of USB backport files in consideration
for 2.6.28.

Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
compat/compat-2.6.27.c
compat/compat-2.6.28.c
compat/compat-2.6.28.h
compat/compat-2.6.29.c
compat/compat-2.6.29.h

index d072f646a579ff28771b6e95bad3760d5125fc82..a3ef74823fc98b56faf85ecd1543f375ecde9979 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 
-
 /* rfkill notification chain */
 #define RFKILL_STATE_CHANGED            0x0001  /* state of a normal rfkill
                                                        switch has changed */
index 7abd50d7795f2bbfd77940ea7619de764ec8e734..df06cbe089327a17e82d1c816d2c108b7c57ea78 100644 (file)
 
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,28))
 
-/* 2.6.27 compat code goes here */
+#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)
+ */
+
+/**
+ * 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
+
+       usb_hcd_unlink_urb(urb, -ENOENT);
+       wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0);
+}
+EXPORT_SYMBOL_GPL(usb_poison_urb);
+
+void usb_unpoison_urb(struct urb *urb)
+{
+       unsigned long flags;
+
+       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);
+
+
+/**
+ * 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);
+
+/**
+ * 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)
 {
index 6f7760eb2b045aba5abc3d7ede03ac9440e29bae..945e9f2a8da8b7cae0d9e8a80798824f36c343f0 100644 (file)
@@ -9,6 +9,7 @@
 
 #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) */
 })
 #endif /* From include/asm-generic/bug.h */
 
+extern void usb_poison_urb(struct urb *urb);
+extern void usb_unpoison_urb(struct urb *urb);
+
+extern void usb_poison_anchored_urbs(struct usb_anchor *anchor);
+extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor);
+
+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);
 
 /**
index 8c66d5237ea7dc2e2e337b69cb196e9655f17d01..490edac3fc27d73319be417c53a5aac01840187e 100644 (file)
 
 #include <linux/usb.h>
 
-/* 2.6.29 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)
- */
-
-/**
- * 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);
-
 /**
  * usb_unpoison_anchored_urbs - let an anchor be used successfully again
  * @anchor: anchor the requests are bound to
@@ -87,75 +35,6 @@ void usb_unpoison_anchored_urbs(struct usb_anchor *anchor)
 }
 EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs);
 
-/**
- * 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,29) */
 
index ee8db16d735b2e3fa159e801a5d358f1295b3166..f4086e92e6a9d6b6eda2d3c9641b010413745ffa 100644 (file)
@@ -8,17 +8,6 @@
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
 
 #include <linux/skbuff.h>
-#include <linux/usb.h>
-
-extern void usb_poison_urb(struct urb *urb);
-extern void usb_unpoison_urb(struct urb *urb);
-
-extern void usb_poison_anchored_urbs(struct usb_anchor *anchor);
-extern void usb_unpoison_anchored_urbs(struct usb_anchor *anchor);
-
-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);
 
 /**
  *     skb_queue_is_first - check if skb is the first entry in the queue