diff options
Diffstat (limited to 'drivers/usb/host')
| -rw-r--r-- | drivers/usb/host/ehci-sched.c | 14 | ||||
| -rw-r--r-- | drivers/usb/host/ehci-tegra.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/pci-quirks.c | 18 | ||||
| -rw-r--r-- | drivers/usb/host/xhci-pci.c | 2 | ||||
| -rw-r--r-- | drivers/usb/host/xhci.c | 9 |
5 files changed, 34 insertions, 11 deletions
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index e113fd73aeae..f9a332775c47 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
| @@ -1581,6 +1581,10 @@ iso_stream_schedule ( | |||
| 1581 | else | 1581 | else |
| 1582 | next = (now + 2 + 7) & ~0x07; /* full frame cache */ | 1582 | next = (now + 2 + 7) & ~0x07; /* full frame cache */ |
| 1583 | 1583 | ||
| 1584 | /* If needed, initialize last_iso_frame so that this URB will be seen */ | ||
| 1585 | if (ehci->isoc_count == 0) | ||
| 1586 | ehci->last_iso_frame = now >> 3; | ||
| 1587 | |||
| 1584 | /* | 1588 | /* |
| 1585 | * Use ehci->last_iso_frame as the base. There can't be any | 1589 | * Use ehci->last_iso_frame as the base. There can't be any |
| 1586 | * TDs scheduled for earlier than that. | 1590 | * TDs scheduled for earlier than that. |
| @@ -1600,11 +1604,11 @@ iso_stream_schedule ( | |||
| 1600 | */ | 1604 | */ |
| 1601 | now2 = (now - base) & (mod - 1); | 1605 | now2 = (now - base) & (mod - 1); |
| 1602 | 1606 | ||
| 1603 | /* Is the schedule already full? */ | 1607 | /* Is the schedule about to wrap around? */ |
| 1604 | if (unlikely(!empty && start < period)) { | 1608 | if (unlikely(!empty && start < period)) { |
| 1605 | ehci_dbg(ehci, "iso sched full %p (%u-%u < %u mod %u)\n", | 1609 | ehci_dbg(ehci, "request %p would overflow (%u-%u < %u mod %u)\n", |
| 1606 | urb, stream->next_uframe, base, period, mod); | 1610 | urb, stream->next_uframe, base, period, mod); |
| 1607 | status = -ENOSPC; | 1611 | status = -EFBIG; |
| 1608 | goto fail; | 1612 | goto fail; |
| 1609 | } | 1613 | } |
| 1610 | 1614 | ||
| @@ -1671,10 +1675,6 @@ iso_stream_schedule ( | |||
| 1671 | urb->start_frame = start & (mod - 1); | 1675 | urb->start_frame = start & (mod - 1); |
| 1672 | if (!stream->highspeed) | 1676 | if (!stream->highspeed) |
| 1673 | urb->start_frame >>= 3; | 1677 | urb->start_frame >>= 3; |
| 1674 | |||
| 1675 | /* Make sure scan_isoc() sees these */ | ||
| 1676 | if (ehci->isoc_count == 0) | ||
| 1677 | ehci->last_iso_frame = now >> 3; | ||
| 1678 | return status; | 1678 | return status; |
| 1679 | 1679 | ||
| 1680 | fail: | 1680 | fail: |
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 19a9af1b4d74..ff9af29b4e9f 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c | |||
| @@ -451,7 +451,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) | |||
| 451 | 451 | ||
| 452 | u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); | 452 | u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); |
| 453 | if (IS_ERR(u_phy)) { | 453 | if (IS_ERR(u_phy)) { |
| 454 | err = PTR_ERR(u_phy); | 454 | err = -EPROBE_DEFER; |
| 455 | goto cleanup_clk_en; | 455 | goto cleanup_clk_en; |
| 456 | } | 456 | } |
| 457 | hcd->usb_phy = u_phy; | 457 | hcd->usb_phy = u_phy; |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index dd483c13565b..ce636466edb7 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
| @@ -567,7 +567,8 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
| 567 | { | 567 | { |
| 568 | void __iomem *base; | 568 | void __iomem *base; |
| 569 | u32 control; | 569 | u32 control; |
| 570 | u32 fminterval; | 570 | u32 fminterval = 0; |
| 571 | bool no_fminterval = false; | ||
| 571 | int cnt; | 572 | int cnt; |
| 572 | 573 | ||
| 573 | if (!mmio_resource_enabled(pdev, 0)) | 574 | if (!mmio_resource_enabled(pdev, 0)) |
| @@ -577,6 +578,13 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
| 577 | if (base == NULL) | 578 | if (base == NULL) |
| 578 | return; | 579 | return; |
| 579 | 580 | ||
| 581 | /* | ||
| 582 | * ULi M5237 OHCI controller locks the whole system when accessing | ||
| 583 | * the OHCI_FMINTERVAL offset. | ||
| 584 | */ | ||
| 585 | if (pdev->vendor == PCI_VENDOR_ID_AL && pdev->device == 0x5237) | ||
| 586 | no_fminterval = true; | ||
| 587 | |||
| 580 | control = readl(base + OHCI_CONTROL); | 588 | control = readl(base + OHCI_CONTROL); |
| 581 | 589 | ||
| 582 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ | 590 | /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */ |
| @@ -615,7 +623,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
| 615 | } | 623 | } |
| 616 | 624 | ||
| 617 | /* software reset of the controller, preserving HcFmInterval */ | 625 | /* software reset of the controller, preserving HcFmInterval */ |
| 618 | fminterval = readl(base + OHCI_FMINTERVAL); | 626 | if (!no_fminterval) |
| 627 | fminterval = readl(base + OHCI_FMINTERVAL); | ||
| 628 | |||
| 619 | writel(OHCI_HCR, base + OHCI_CMDSTATUS); | 629 | writel(OHCI_HCR, base + OHCI_CMDSTATUS); |
| 620 | 630 | ||
| 621 | /* reset requires max 10 us delay */ | 631 | /* reset requires max 10 us delay */ |
| @@ -624,7 +634,9 @@ static void quirk_usb_handoff_ohci(struct pci_dev *pdev) | |||
| 624 | break; | 634 | break; |
| 625 | udelay(1); | 635 | udelay(1); |
| 626 | } | 636 | } |
| 627 | writel(fminterval, base + OHCI_FMINTERVAL); | 637 | |
| 638 | if (!no_fminterval) | ||
| 639 | writel(fminterval, base + OHCI_FMINTERVAL); | ||
| 628 | 640 | ||
| 629 | /* Now the controller is safely in SUSPEND and nothing can wake it up */ | 641 | /* Now the controller is safely in SUSPEND and nothing can wake it up */ |
| 630 | iounmap(base); | 642 | iounmap(base); |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 142b601f9563..7f76c8a12f89 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
| @@ -82,6 +82,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
| 82 | "must be suspended extra slowly", | 82 | "must be suspended extra slowly", |
| 83 | pdev->revision); | 83 | pdev->revision); |
| 84 | } | 84 | } |
| 85 | if (pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) | ||
| 86 | xhci->quirks |= XHCI_BROKEN_STREAMS; | ||
| 85 | /* Fresco Logic confirms: all revisions of this chip do not | 87 | /* Fresco Logic confirms: all revisions of this chip do not |
| 86 | * support MSI, even though some of them claim to in their PCI | 88 | * support MSI, even though some of them claim to in their PCI |
| 87 | * capabilities. | 89 | * capabilities. |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 01fcbb5eb06e..c50d8d202618 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
| @@ -3803,6 +3803,15 @@ static int xhci_setup_device(struct usb_hcd *hcd, struct usb_device *udev, | |||
| 3803 | return -EINVAL; | 3803 | return -EINVAL; |
| 3804 | } | 3804 | } |
| 3805 | 3805 | ||
| 3806 | if (setup == SETUP_CONTEXT_ONLY) { | ||
| 3807 | slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx); | ||
| 3808 | if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) == | ||
| 3809 | SLOT_STATE_DEFAULT) { | ||
| 3810 | xhci_dbg(xhci, "Slot already in default state\n"); | ||
| 3811 | return 0; | ||
| 3812 | } | ||
| 3813 | } | ||
| 3814 | |||
| 3806 | command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); | 3815 | command = xhci_alloc_command(xhci, false, false, GFP_KERNEL); |
| 3807 | if (!command) | 3816 | if (!command) |
| 3808 | return -ENOMEM; | 3817 | return -ENOMEM; |
