[argyllcms] Re: Spyder2 stopped working - device. Linux ehci-hcd driver has a bug.

  • From: Jan-Erik Skata <jeskata@xxxxxxxxx>
  • To: argyllcms@xxxxxxxxxxxxx
  • Date: Tue, 26 Jul 2011 18:05:16 +0300

On Tue, Jul 19, 2011 at 4:44 AM, Graeme Gill <graeme@xxxxxxxxxxxxx> wrote:
> Ok, here's a status report.
>
> Alan has looked into the problem and noticed a subtle bug in
> Linux's ehci-hcd controller, and supplied a patch.
>
> I've tried this out on my (getting old) 2.6.23.1 Linux
> system, and this does indeed fix the problem I've been able
> to reproduce using an external USB 2.0 hub.
>
> I guess it will take a while for this fix to make it into
> Linux releases, so the only short term fix would be for
> people to patch their own Linux kernel and re-compile it.
>
> Attached is Alan's patch for those who feel up to doing this.
>
> cheers,
>
> Graeme Gill.
>
> Index: usb-3.0/drivers/usb/host/ehci-q.c
> ===================================================================
> --- usb-3.0.orig/drivers/usb/host/ehci-q.c
> +++ usb-3.0/drivers/usb/host/ehci-q.c
> @@ -103,7 +103,7 @@ qh_update (struct ehci_hcd *ehci, struct
>        if (!(hw->hw_info1 & cpu_to_hc32(ehci, 1 << 14))) {
>                unsigned        is_out, epnum;
>
> -               is_out = !(qtd->hw_token & cpu_to_hc32(ehci, 1 << 8));
> +               is_out = qh->is_out;
>                epnum = (hc32_to_cpup(ehci, &hw->hw_info1) >> 8) & 0x0f;
>                if (unlikely (!usb_gettoggle (qh->dev, epnum, is_out))) {
>                        hw->hw_token &= ~cpu_to_hc32(ehci, QTD_TOGGLE);
> @@ -946,6 +946,7 @@ done:
>        hw = qh->hw;
>        hw->hw_info1 = cpu_to_hc32(ehci, info1);
>        hw->hw_info2 = cpu_to_hc32(ehci, info2);
> +       qh->is_out = !is_input;
>        usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
>        qh_refresh (ehci, qh);
>        return qh;
> Index: usb-3.0/drivers/usb/host/ehci.h
> ===================================================================
> --- usb-3.0.orig/drivers/usb/host/ehci.h
> +++ usb-3.0/drivers/usb/host/ehci.h
> @@ -377,6 +377,7 @@ struct ehci_qh {
>  #define NO_FRAME ((unsigned short)~0)                  /* pick new start */
>
>        struct usb_device       *dev;           /* access to TT */
> +       unsigned                is_out:1;       /* bulk or intr OUT */
>        unsigned                clearing_tt:1;  /* Clear-TT-Buf in progress */
>  };
>
>
>
>
>

Applied this and it seems to be working, thanks to everybody involved.
Strange though that it worked with an old USB card in the same
machine. Probably all the motherboard ports are behind some sort of a
hub.

Other related posts: