diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-01 19:38:38 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-01 19:39:14 -0400 |
commit | 8e36f79ecf4f8b09c5ee5041cf97f180e847838e (patch) | |
tree | f6a9602444b0b2c6eb751824be7357f52bacae4a /drivers | |
parent | 5f66d2b58ca879e70740c82422354144845d6dd3 (diff) | |
parent | 7de7c7d2cb49900e0b967be871bf695c7d6135c9 (diff) |
Merge branch 'for-usb-linus' of git+ssh://master.kernel.org/pub/scm/linux/kernel/git/sarah/xhci into usb-linus
* 'for-usb-linus' of git+ssh://master.kernel.org/pub/scm/linux/kernel/git/sarah/xhci:
usb/config: use proper endian access for wMaxPacketSize
USB: xhci: fix OS want to own HC
xhci: Don't submit commands or URBs to halted hosts.
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/core/config.c | 11 | ||||
-rw-r--r-- | drivers/usb/host/pci-quirks.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/xhci.c | 19 |
3 files changed, 21 insertions, 11 deletions
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index c962608b4b9a..26678cadfb21 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -123,10 +123,11 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, | |||
123 | } | 123 | } |
124 | 124 | ||
125 | if (usb_endpoint_xfer_isoc(&ep->desc)) | 125 | if (usb_endpoint_xfer_isoc(&ep->desc)) |
126 | max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1) * | 126 | max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * |
127 | (desc->bmAttributes + 1); | 127 | le16_to_cpu(ep->desc.wMaxPacketSize); |
128 | else if (usb_endpoint_xfer_int(&ep->desc)) | 128 | else if (usb_endpoint_xfer_int(&ep->desc)) |
129 | max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1); | 129 | max_tx = le16_to_cpu(ep->desc.wMaxPacketSize) * |
130 | (desc->bMaxBurst + 1); | ||
130 | else | 131 | else |
131 | max_tx = 999999; | 132 | max_tx = 999999; |
132 | if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { | 133 | if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { |
@@ -134,10 +135,10 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, | |||
134 | "config %d interface %d altsetting %d ep %d: " | 135 | "config %d interface %d altsetting %d ep %d: " |
135 | "setting to %d\n", | 136 | "setting to %d\n", |
136 | usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int", | 137 | usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int", |
137 | desc->wBytesPerInterval, | 138 | le16_to_cpu(desc->wBytesPerInterval), |
138 | cfgno, inum, asnum, ep->desc.bEndpointAddress, | 139 | cfgno, inum, asnum, ep->desc.bEndpointAddress, |
139 | max_tx); | 140 | max_tx); |
140 | ep->ss_ep_comp.wBytesPerInterval = max_tx; | 141 | ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx); |
141 | } | 142 | } |
142 | } | 143 | } |
143 | 144 | ||
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index a9d315906e3d..f4d1b691e6ec 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -817,7 +817,7 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev) | |||
817 | 817 | ||
818 | /* If the BIOS owns the HC, signal that the OS wants it, and wait */ | 818 | /* If the BIOS owns the HC, signal that the OS wants it, and wait */ |
819 | if (val & XHCI_HC_BIOS_OWNED) { | 819 | if (val & XHCI_HC_BIOS_OWNED) { |
820 | writel(val & XHCI_HC_OS_OWNED, base + ext_cap_offset); | 820 | writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset); |
821 | 821 | ||
822 | /* Wait for 5 seconds with 10 microsecond polling interval */ | 822 | /* Wait for 5 seconds with 10 microsecond polling interval */ |
823 | timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED, | 823 | timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED, |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 763f484bc092..1c4432d8fc10 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -345,7 +345,8 @@ static void xhci_event_ring_work(unsigned long arg) | |||
345 | spin_lock_irqsave(&xhci->lock, flags); | 345 | spin_lock_irqsave(&xhci->lock, flags); |
346 | temp = xhci_readl(xhci, &xhci->op_regs->status); | 346 | temp = xhci_readl(xhci, &xhci->op_regs->status); |
347 | xhci_dbg(xhci, "op reg status = 0x%x\n", temp); | 347 | xhci_dbg(xhci, "op reg status = 0x%x\n", temp); |
348 | if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { | 348 | if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) || |
349 | (xhci->xhc_state & XHCI_STATE_HALTED)) { | ||
349 | xhci_dbg(xhci, "HW died, polling stopped.\n"); | 350 | xhci_dbg(xhci, "HW died, polling stopped.\n"); |
350 | spin_unlock_irqrestore(&xhci->lock, flags); | 351 | spin_unlock_irqrestore(&xhci->lock, flags); |
351 | return; | 352 | return; |
@@ -939,8 +940,11 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev, | |||
939 | return 0; | 940 | return 0; |
940 | } | 941 | } |
941 | 942 | ||
943 | xhci = hcd_to_xhci(hcd); | ||
944 | if (xhci->xhc_state & XHCI_STATE_HALTED) | ||
945 | return -ENODEV; | ||
946 | |||
942 | if (check_virt_dev) { | 947 | if (check_virt_dev) { |
943 | xhci = hcd_to_xhci(hcd); | ||
944 | if (!udev->slot_id || !xhci->devs | 948 | if (!udev->slot_id || !xhci->devs |
945 | || !xhci->devs[udev->slot_id]) { | 949 | || !xhci->devs[udev->slot_id]) { |
946 | printk(KERN_DEBUG "xHCI %s called with unaddressed " | 950 | printk(KERN_DEBUG "xHCI %s called with unaddressed " |
@@ -1242,7 +1246,8 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
1242 | xhci_urb_free_priv(xhci, urb_priv); | 1246 | xhci_urb_free_priv(xhci, urb_priv); |
1243 | return ret; | 1247 | return ret; |
1244 | } | 1248 | } |
1245 | if (xhci->xhc_state & XHCI_STATE_DYING) { | 1249 | if ((xhci->xhc_state & XHCI_STATE_DYING) || |
1250 | (xhci->xhc_state & XHCI_STATE_HALTED)) { | ||
1246 | xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " | 1251 | xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on " |
1247 | "non-responsive xHCI host.\n", | 1252 | "non-responsive xHCI host.\n", |
1248 | urb->ep->desc.bEndpointAddress, urb); | 1253 | urb->ep->desc.bEndpointAddress, urb); |
@@ -2665,7 +2670,10 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
2665 | int i, ret; | 2670 | int i, ret; |
2666 | 2671 | ||
2667 | ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); | 2672 | ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__); |
2668 | if (ret <= 0) | 2673 | /* If the host is halted due to driver unload, we still need to free the |
2674 | * device. | ||
2675 | */ | ||
2676 | if (ret <= 0 && ret != -ENODEV) | ||
2669 | return; | 2677 | return; |
2670 | 2678 | ||
2671 | virt_dev = xhci->devs[udev->slot_id]; | 2679 | virt_dev = xhci->devs[udev->slot_id]; |
@@ -2679,7 +2687,8 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev) | |||
2679 | spin_lock_irqsave(&xhci->lock, flags); | 2687 | spin_lock_irqsave(&xhci->lock, flags); |
2680 | /* Don't disable the slot if the host controller is dead. */ | 2688 | /* Don't disable the slot if the host controller is dead. */ |
2681 | state = xhci_readl(xhci, &xhci->op_regs->status); | 2689 | state = xhci_readl(xhci, &xhci->op_regs->status); |
2682 | if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) { | 2690 | if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) || |
2691 | (xhci->xhc_state & XHCI_STATE_HALTED)) { | ||
2683 | xhci_free_virt_device(xhci, udev->slot_id); | 2692 | xhci_free_virt_device(xhci, udev->slot_id); |
2684 | spin_unlock_irqrestore(&xhci->lock, flags); | 2693 | spin_unlock_irqrestore(&xhci->lock, flags); |
2685 | return; | 2694 | return; |