]> git.hungrycats.org Git - linux/commitdiff
[PATCH] USB: ehci-hcd, misc bugfixes
authorDavid Brownell <david-b@pacbell.net>
Mon, 13 Oct 2003 09:21:20 +0000 (02:21 -0700)
committerGreg Kroah-Hartman <greg@kroah.com>
Mon, 13 Oct 2003 09:21:20 +0000 (02:21 -0700)
This fixes some bugs observed in the EHCI code:

  - Byte-order confusion caused the wrong address to be set
    on big-endian hardware (reported last week on PPC and
    SPARC).   That bug's been there for about a year, with
    no problem reports ... hmm.

  - Used the wrong bitmask to determine max packet size
    for interrupt transfers, so they were limited to 1023
    bytes (not 1024 bytes) at high speed.

  - Because those two problems related to the masking,
    I sanity checked it and moved more of byteswapping
    to compile time.

  - Removes some oopsing in the (debug) periodic schedule
    dump, seen with patches that add more interesting
    behaviors (which folk are finally trying...).

  - Removed some now-pointless <linux/version.h> usage

drivers/usb/host/ehci-dbg.c
drivers/usb/host/ehci-q.c
drivers/usb/host/ehci.h

index ab7b4a53568aaa1975457a2135f62e0725f7bbf3..ea90ffc0f16d9941f735018f36718fae54ebb929 100644 (file)
@@ -465,7 +465,7 @@ show_periodic (struct class_device *class_dev, char *buf)
        spin_lock_irqsave (&ehci->lock, flags);
        for (i = 0; i < ehci->periodic_size; i++) {
                p = ehci->pshadow [i];
-               if (!p.ptr)
+               if (likely (!p.ptr))
                        continue;
                tag = Q_NEXT_TYPE (ehci->periodic [i]);
 
@@ -495,7 +495,7 @@ show_periodic (struct class_device *class_dev, char *buf)
                                        break;
                                }
                                /* show more info the first time around */
-                               if (temp == seen_count) {
+                               if (temp == seen_count && p.ptr) {
                                        u32     scratch = cpu_to_le32p (
                                                        &p.qh->hw_info1);
                                        struct ehci_qtd *qtd;
@@ -528,8 +528,10 @@ show_periodic (struct class_device *class_dev, char *buf)
                                                seen [seen_count++].qh = p.qh;
                                } else
                                        temp = 0;
-                               tag = Q_NEXT_TYPE (p.qh->hw_next);
-                               p = p.qh->qh_next;
+                               if (p.qh) {
+                                       tag = Q_NEXT_TYPE (p.qh->hw_next);
+                                       p = p.qh->qh_next;
+                               }
                                break;
                        case Q_TYPE_FSTN:
                                temp = snprintf (next, size,
index 93fedc024028028feb0c8119426b55d7a52f5206..bafc981be5ebde3b7711ea96c3009f594c8a3495 100644 (file)
@@ -184,7 +184,7 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
                struct ehci_qh  *qh = (struct ehci_qh *) urb->hcpriv;
 
                /* S-mask in a QH means it's an interrupt urb */
-               if ((qh->hw_info2 & cpu_to_le32 (0x00ff)) != 0) {
+               if ((qh->hw_info2 & __constant_cpu_to_le32 (0x00ff)) != 0) {
 
                        /* ... update hc-wide periodic stats (for usbfs) */
                        hcd_to_bus (&ehci->hcd)->bandwidth_int_reqs--;
@@ -224,7 +224,7 @@ ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb, struct pt_regs *regs)
  * Chases up to qh->hw_current.  Returns number of completions called,
  * indicating how much "real" work we did.
  */
-#define HALT_BIT cpu_to_le32(QTD_STS_HALT)
+#define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT)
 static unsigned
 qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh, struct pt_regs *regs)
 {
@@ -377,10 +377,14 @@ halt:
 
        return count;
 }
-#undef HALT_BIT
 
 /*-------------------------------------------------------------------------*/
 
+// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
+#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
+// ... and packet size, for any kind of endpoint descriptor
+#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x07ff)
+
 /*
  * reverse of qh_urb_transaction:  free a list of TDs.
  * used for cleanup after errors, before HC sees an URB's TDs.
@@ -461,7 +465,7 @@ qh_urb_transaction (
                token |= (1 /* "in" */ << 8);
        /* else it's already initted to "out" pid (0 << 8) */
 
-       maxpacket = usb_maxpacket (urb->dev, urb->pipe, !is_input) & 0x03ff;
+       maxpacket = max_packet(usb_maxpacket(urb->dev, urb->pipe, !is_input));
 
        /*
         * buffer gets wrapped in one or more qtds;
@@ -564,11 +568,6 @@ clear_toggle (struct usb_device *udev, int ep, int is_out, struct ehci_qh *qh)
 // That'd mean updating how usbcore talks to HCDs. (2.5?)
 
 
-// high bandwidth multiplier, as encoded in highspeed endpoint descriptors
-#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03))
-// ... and packet size, for any kind of endpoint descriptor
-#define max_packet(wMaxPacketSize) ((wMaxPacketSize) & 0x03ff)
-
 /*
  * Each QH holds a qtd list; a QH is used for everything except iso.
  *
@@ -728,7 +727,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
                }
        }
 
-       qh->hw_token &= ~__constant_cpu_to_le32 (QTD_STS_HALT);
+       qh->hw_token &= ~HALT_BIT;
 
        /* splice right after start */
        qh->qh_next = head->qh_next;
@@ -744,6 +743,8 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh)
 
 /*-------------------------------------------------------------------------*/
 
+#define        QH_ADDR_MASK    __constant_le32_to_cpu(0x7f)
+
 /*
  * For control/bulk/interrupt, return QH with these TDs appended.
  * Allocates and initializes the QH if necessary.
@@ -778,12 +779,13 @@ static struct ehci_qh *qh_append_tds (
                /* control qh may need patching after enumeration */
                if (unlikely (epnum == 0)) {
                        /* set_address changes the address */
-                       if (le32_to_cpu (qh->hw_info1 & 0x7f) == 0)
+                       if ((qh->hw_info1 & QH_ADDR_MASK) == 0)
                                qh->hw_info1 |= cpu_to_le32 (
                                                usb_pipedevice (urb->pipe));
 
                        /* for full speed, ep0 maxpacket can grow */
-                       else if (!(qh->hw_info1 & cpu_to_le32 (0x3 << 12))) {
+                       else if (!(qh->hw_info1
+                                       & __constant_cpu_to_le32 (0x3 << 12))) {
                                u32     info, max;
 
                                info = le32_to_cpu (qh->hw_info1);
@@ -797,7 +799,7 @@ static struct ehci_qh *qh_append_tds (
 
                         /* usb_reset_device() briefly reverts to address 0 */
                         if (usb_pipedevice (urb->pipe) == 0)
-                                qh->hw_info1 &= cpu_to_le32(~0x7f);
+                                qh->hw_info1 &= ~QH_ADDR_MASK;
                }
 
                /* usb_clear_halt() means qh data toggle gets reset */
@@ -833,7 +835,7 @@ static struct ehci_qh *qh_append_tds (
                         * HC is allowed to fetch the old dummy (4.10.2).
                         */
                        token = qtd->hw_token;
-                       qtd->hw_token = cpu_to_le32 (QTD_STS_HALT);
+                       qtd->hw_token = HALT_BIT;
                        wmb ();
                        dummy = qh->dummy;
 
index ed23010d21a27c76e83499000e774c60913714e6..43415d2b054caf1c156c7cea5c76e908c575e68c 100644 (file)
@@ -325,6 +325,7 @@ union ehci_shadow {
        struct ehci_itd         *itd;           /* Q_TYPE_ITD */
        struct ehci_sitd        *sitd;          /* Q_TYPE_SITD */
        struct ehci_fstn        *fstn;          /* Q_TYPE_FSTN */
+       u32                     *hw_next;       /* (all types) */
        void                    *ptr;
 };
 
@@ -469,27 +470,12 @@ struct ehci_fstn {
 
 /*-------------------------------------------------------------------------*/
 
-#include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
-
-#define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb)
-#define STUB_DEBUG_FILES
-
-static inline int hcd_register_root (struct usb_hcd *hcd)
-{
-       return usb_new_device (hcd_to_bus (hcd)->root_hub);
-}
-
-#else  /* LINUX_VERSION_CODE */
-
 #define SUBMIT_URB(urb,mem_flags) usb_submit_urb(urb,mem_flags)
 
 #ifndef DEBUG
 #define STUB_DEBUG_FILES
 #endif /* DEBUG */
 
-#endif /* LINUX_VERSION_CODE */
-
 /*-------------------------------------------------------------------------*/
 
 #endif /* __LINUX_EHCI_HCD_H */