Re: [PATCH] xhci: Make handover code more robust

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 <mjg@xxxxxxxxxx>
> ---
>  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 majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux