On Tue, Aug 14, 2012 at 04:44:49PM -0400, Matthew Garrett wrote:
> My test platform (Intel DX79SI) boots reliably under BIOS, but frequently
> crashes when booting via UEFI. I finally tracked this down to the xhci
> handoff code. It seems that reads from the device occasionally just return
> 0xff, resulting in xhci_find_next_cap_offset generating a value that's
> larger than the resource region. We then oops when attempting to read the
> value. Sanity checking that value lets us avoid the crash.
>
> I've no idea what's causing the underlying problem, and xhci still doesn't
> actually *work* even with this, but the machine at least boots which will
> probably make further debugging easier.

Is this an Ivy Bridge system?  xHCI may not work because you're skipping
the port switchover code just before the hc_init label.  Of course, if
the host controller continues to report all f's for register values,
there's no point in trying to initialize the host at all...

Sarah Sharp

> 
> Signed-off-by: Matthew Garrett <m...@redhat.com>
> ---
>  drivers/usb/host/pci-quirks.c | 12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
> index df0828c..7cda232 100644
> --- a/drivers/usb/host/pci-quirks.c
> +++ b/drivers/usb/host/pci-quirks.c
> @@ -815,12 +815,12 @@ static void __devinit quirk_usb_handoff_xhci(struct 
> pci_dev *pdev)
>       void __iomem *op_reg_base;
>       u32 val;
>       int timeout;
> +     int len = pci_resource_len(pdev, 0);
>  
>       if (!mmio_resource_enabled(pdev, 0))
>               return;
>  
> -     base = ioremap_nocache(pci_resource_start(pdev, 0),
> -                             pci_resource_len(pdev, 0));
> +     base = ioremap_nocache(pci_resource_start(pdev, 0), len);
>       if (base == NULL)
>               return;
>  
> @@ -830,9 +830,17 @@ static void __devinit quirk_usb_handoff_xhci(struct 
> pci_dev *pdev)
>        */
>       ext_cap_offset = xhci_find_next_cap_offset(base, 
> XHCI_HCC_PARAMS_OFFSET);
>       do {
> +             if ((ext_cap_offset + sizeof(val)) > len) {
> +                     /* We're reading garbage from the controller */
> +                     dev_warn(&pdev->dev,
> +                              "xHCI controller failing to respond");
> +                     return;
> +             }
> +
>               if (!ext_cap_offset)
>                       /* We've reached the end of the extended capabilities */
>                       goto hc_init;
> +
>               val = readl(base + ext_cap_offset);
>               if (XHCI_EXT_CAPS_ID(val) == XHCI_EXT_CAPS_LEGACY)
>                       break;
> -- 
> 1.7.11.2
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to