diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-19 13:39:21 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-19 13:39:21 -0700 |
commit | 8fdb7e9f612b7c6ba6c3ba460c14263b5ce90f79 (patch) | |
tree | 09f007a62475c22546ba693e5171024cc67fb38c /drivers/usb/host/ehci-sched.c | |
parent | fc7f99cf36ebae853639dabb43bc2f0098c59aef (diff) | |
parent | 4cb80cda51ff950614701fb30c9d4e583fe5a31f (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (45 commits)
USB: gadget/multi: cdc_do_config: remove redundant check
usb: r8a66597-hcd: fix removed from an attached hub
USB: xhci: Make endpoint interval debugging clearer.
USB: Fix usb_fill_int_urb for SuperSpeed devices
USB: cp210x: Remove double usb_control_msg from cp210x_set_config
USB: Remove last bit of CONFIG_USB_BERRY_CHARGE
USB: gadget: add gadget controller number for s3c-hsotg driver
USB: ftdi_sio: Fix locking for change_speed() function
USB: g_mass_storage: fixed module name in Kconfig
USB: gadget: f_mass_storage::fsg_bind(): fix error handling
USB: g_mass_storage: fix section mismatch warnings
USB: gadget: fix Blackfin builds after gadget cleansing
USB: goku_udc: remove potential null dereference
USB: option.c: Add Pirelli VID/PID and indicate Pirelli's modem interface is 0xff
USB: serial: Fix module name typo for qcaux Kconfig entry.
usb: cdc-wdm: Fix deadlock between write and resume
usb: cdc-wdm: Fix order in disconnect and fix locking
usb: cdc-wdm:Fix loss of data due to autosuspend
usb: cdc-wdm: Fix submission of URB after suspension
usb: cdc-wdm: Fix race between disconnect and debug messages
...
Diffstat (limited to 'drivers/usb/host/ehci-sched.c')
-rw-r--r-- | drivers/usb/host/ehci-sched.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 39340ae00ac..a0aaaaff256 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1123,8 +1123,8 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) urb->interval); } - /* if dev->ep [epnum] is a QH, info1.maxpacket is nonzero */ - } else if (unlikely (stream->hw_info1 != 0)) { + /* if dev->ep [epnum] is a QH, hw is set */ + } else if (unlikely (stream->hw != NULL)) { ehci_dbg (ehci, "dev %s ep%d%s, not iso??\n", urb->dev->devpath, epnum, usb_pipein(urb->pipe) ? "in" : "out"); @@ -1565,13 +1565,27 @@ itd_patch( static inline void itd_link (struct ehci_hcd *ehci, unsigned frame, struct ehci_itd *itd) { - /* always prepend ITD/SITD ... only QH tree is order-sensitive */ - itd->itd_next = ehci->pshadow [frame]; - itd->hw_next = ehci->periodic [frame]; - ehci->pshadow [frame].itd = itd; + union ehci_shadow *prev = &ehci->pshadow[frame]; + __hc32 *hw_p = &ehci->periodic[frame]; + union ehci_shadow here = *prev; + __hc32 type = 0; + + /* skip any iso nodes which might belong to previous microframes */ + while (here.ptr) { + type = Q_NEXT_TYPE(ehci, *hw_p); + if (type == cpu_to_hc32(ehci, Q_TYPE_QH)) + break; + prev = periodic_next_shadow(ehci, prev, type); + hw_p = shadow_next_periodic(ehci, &here, type); + here = *prev; + } + + itd->itd_next = here; + itd->hw_next = *hw_p; + prev->itd = itd; itd->frame = frame; wmb (); - ehci->periodic[frame] = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); + *hw_p = cpu_to_hc32(ehci, itd->itd_dma | Q_TYPE_ITD); } /* fit urb's itds into the selected schedule slot; activate as needed */ |