]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/usb/musb/musb_host.c
Merge branch 'core-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-omap-h63xx.git] / drivers / usb / musb / musb_host.c
index 8b4be012669a683b6e4d9ee7764d38defb1aaed8..3133990f04ec868fcb0809cd233535f3fc562ff2 100644 (file)
@@ -108,7 +108,7 @@ static void musb_ep_program(struct musb *musb, u8 epnum,
 /*
  * Clear TX fifo. Needed to avoid BABBLE errors.
  */
-static inline void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
+static void musb_h_tx_flush_fifo(struct musb_hw_ep *ep)
 {
        void __iomem    *epio = ep->regs;
        u16             csr;
@@ -291,6 +291,7 @@ __acquires(musb->lock)
                        urb->actual_length, urb->transfer_buffer_length
                        );
 
+       usb_hcd_unlink_urb_from_ep(musb_to_hcd(musb), urb);
        spin_unlock(&musb->lock);
        usb_hcd_giveback_urb(musb_to_hcd(musb), urb, status);
        spin_lock(&musb->lock);
@@ -353,8 +354,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status)
                break;
        }
 
-       usb_hcd_unlink_urb_from_ep(musb_to_hcd(musb), urb);
-
        qh->is_ready = 0;
        __musb_giveback(musb, urb, status);
        qh->is_ready = ready;
@@ -436,7 +435,7 @@ musb_advance_schedule(struct musb *musb, struct urb *urb,
        }
 }
 
-static inline u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr)
+static u16 musb_h_flush_rxfifo(struct musb_hw_ep *hw_ep, u16 csr)
 {
        /* we don't want fifo to fill itself again;
         * ignore dma (various models),
@@ -1005,7 +1004,7 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb)
 
 /*
  * Handle default endpoint interrupt as host. Only called in IRQ time
- * from the LinuxIsr() interrupt service routine.
+ * from musb_interrupt().
  *
  * called with controller irqlocked
  */
@@ -1791,7 +1790,9 @@ static int musb_urb_enqueue(
         */
        qh = kzalloc(sizeof *qh, mem_flags);
        if (!qh) {
+               spin_lock_irqsave(&musb->lock, flags);
                usb_hcd_unlink_urb_from_ep(hcd, urb);
+               spin_unlock_irqrestore(&musb->lock, flags);
                return -ENOMEM;
        }
 
@@ -1873,7 +1874,11 @@ static int musb_urb_enqueue(
                        /* set up tt info if needed */
                        if (urb->dev->tt) {
                                qh->h_port_reg = (u8) urb->dev->ttport;
-                               qh->h_addr_reg |= 0x80;
+                               if (urb->dev->tt->hub)
+                                       qh->h_addr_reg =
+                                               (u8) urb->dev->tt->hub->devnum;
+                               if (urb->dev->tt->multi)
+                                       qh->h_addr_reg |= 0x80;
                        }
                }
        }
@@ -1903,7 +1908,9 @@ static int musb_urb_enqueue(
 
 done:
        if (ret != 0) {
+               spin_lock_irqsave(&musb->lock, flags);
                usb_hcd_unlink_urb_from_ep(hcd, urb);
+               spin_unlock_irqrestore(&musb->lock, flags);
                kfree(qh);
        }
        return ret;