Sorry, this got accidentally filed in "trash" not "review". Happened from cleaning out a thousand or so emails. :(
I suspect I'll be going with a slightly different fix; you can get a preview of it (depending textually on another patch which will now be deferred) at http://marc.info/?l=linux-usb&m=119913406214488&w=2 I'll CC you on the updated patch, and ask you to verify that it behaves on your system. - Dave On Sunday 16 December 2007, Geoff Levand wrote: > > From: Masashi Kimoto <[EMAIL PROTECTED]> > > The EHCI host controller in the Cell Processor's Super Companion > Chip has a hardware errata in its handling of ISO TDs. The > controller will continue to access the TD after the transaction > active bit has been cleared. The condition can be avoided by > delaying the reuse of the TD until the frame number changes. > This change adds a static helper routine itd_in_use() to the EHCI > host controller driver which is conditionaly compiled to include > the check. > > The following errors are typical of those seen with the PS3's > built-in USB Bluetooth controller: > > ps3-ehci-driver sb_04: port 1 resume error -19 > hub 2-0:1.0: hub_port_status failed (err = -32) > > From: Masashi Kimoto <[EMAIL PROTECTED]> > Signed-off-by: Geoff Levand <[EMAIL PROTECTED]> > --- > drivers/usb/host/ehci-sched.c | 42 > ++++++++++++++++++++++++++++++++++++++---- > 1 file changed, 38 insertions(+), 4 deletions(-) > > --- a/drivers/usb/host/ehci-sched.c > +++ b/drivers/usb/host/ehci-sched.c > @@ -1069,6 +1069,32 @@ iso_stream_find (struct ehci_hcd *ehci, > return stream; > } > > +/** > + * itd_in_use - Fix for Cell Super Companion Chip ISO transfers > + * > + * The EHCI host controller in the Cell Processor's Super Companion > + * Chip has a hardware errata in its handling of ISO TDs. The > + * controller will continue to access the TD after the transaction > + * active bit has been cleared. The condition can be avoided by > + * delaying the reuse of the TD until the frame number changes. > + */ > + > +#if defined(CONFIG_PPC_PS3) > +#include <asm/firmware.h> > + > +static int itd_in_use(struct ehci_hcd *ehci, unsigned int itd_frame) > +{ > + return (firmware_has_feature(FW_FEATURE_PS3_LV1) > + && (itd_frame == (ehci_readl(ehci, > + &ehci->regs->frame_index) >> 3) % ehci->periodic_size)); > +} > +#else > +static int itd_in_use(struct ehci_hcd *ehci, unsigned int itd_frame) > +{ > + return 0; > +} > +#endif /* defined(CONFIG_PPC_PS3) */ > + > /*-------------------------------------------------------------------------*/ > > /* ehci_iso_sched ops can be ITD-only or SITD-only */ > @@ -1180,8 +1206,12 @@ itd_urb_transaction ( > if (likely (!list_empty(&stream->free_list))) { > itd = list_entry (stream->free_list.prev, > struct ehci_itd, itd_list); > - list_del (&itd->itd_list); > - itd_dma = itd->itd_dma; > + if (itd_in_use(ehci, itd->frame)) > + itd = NULL; > + else { > + list_del (&itd->itd_list); > + itd_dma = itd->itd_dma; > + } > } else > itd = NULL; > > @@ -1807,8 +1837,12 @@ sitd_urb_transaction ( > if (!list_empty(&stream->free_list)) { > sitd = list_entry (stream->free_list.prev, > struct ehci_sitd, sitd_list); > - list_del (&sitd->sitd_list); > - sitd_dma = sitd->sitd_dma; > + if (itd_in_use(ehci, sitd->frame)) > + sitd = NULL; > + else { > + list_del (&sitd->sitd_list); > + sitd_dma = sitd->sitd_dma; > + } > } else > sitd = NULL; > > > - To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html