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.
This commit is contained in:
Greg Kroah-Hartman 2011-08-01 16:38:38 -07:00
commit 8e36f79ecf
3 changed files with 21 additions and 11 deletions

View File

@ -123,10 +123,11 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
}
if (usb_endpoint_xfer_isoc(&ep->desc))
max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1) *
(desc->bmAttributes + 1);
max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) *
le16_to_cpu(ep->desc.wMaxPacketSize);
else if (usb_endpoint_xfer_int(&ep->desc))
max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1);
max_tx = le16_to_cpu(ep->desc.wMaxPacketSize) *
(desc->bMaxBurst + 1);
else
max_tx = 999999;
if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) {
@ -134,10 +135,10 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
"config %d interface %d altsetting %d ep %d: "
"setting to %d\n",
usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int",
desc->wBytesPerInterval,
le16_to_cpu(desc->wBytesPerInterval),
cfgno, inum, asnum, ep->desc.bEndpointAddress,
max_tx);
ep->ss_ep_comp.wBytesPerInterval = max_tx;
ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
}
}

View File

@ -817,7 +817,7 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
/* If the BIOS owns the HC, signal that the OS wants it, and wait */
if (val & XHCI_HC_BIOS_OWNED) {
writel(val & XHCI_HC_OS_OWNED, base + ext_cap_offset);
writel(val | XHCI_HC_OS_OWNED, base + ext_cap_offset);
/* Wait for 5 seconds with 10 microsecond polling interval */
timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED,

View File

@ -345,7 +345,8 @@ static void xhci_event_ring_work(unsigned long arg)
spin_lock_irqsave(&xhci->lock, flags);
temp = xhci_readl(xhci, &xhci->op_regs->status);
xhci_dbg(xhci, "op reg status = 0x%x\n", temp);
if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) ||
(xhci->xhc_state & XHCI_STATE_HALTED)) {
xhci_dbg(xhci, "HW died, polling stopped.\n");
spin_unlock_irqrestore(&xhci->lock, flags);
return;
@ -939,8 +940,11 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
return 0;
}
xhci = hcd_to_xhci(hcd);
if (xhci->xhc_state & XHCI_STATE_HALTED)
return -ENODEV;
if (check_virt_dev) {
xhci = hcd_to_xhci(hcd);
if (!udev->slot_id || !xhci->devs
|| !xhci->devs[udev->slot_id]) {
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)
xhci_urb_free_priv(xhci, urb_priv);
return ret;
}
if (xhci->xhc_state & XHCI_STATE_DYING) {
if ((xhci->xhc_state & XHCI_STATE_DYING) ||
(xhci->xhc_state & XHCI_STATE_HALTED)) {
xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on "
"non-responsive xHCI host.\n",
urb->ep->desc.bEndpointAddress, urb);
@ -2665,7 +2670,10 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
int i, ret;
ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
if (ret <= 0)
/* If the host is halted due to driver unload, we still need to free the
* device.
*/
if (ret <= 0 && ret != -ENODEV)
return;
virt_dev = xhci->devs[udev->slot_id];
@ -2679,7 +2687,8 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
spin_lock_irqsave(&xhci->lock, flags);
/* Don't disable the slot if the host controller is dead. */
state = xhci_readl(xhci, &xhci->op_regs->status);
if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING)) {
if (state == 0xffffffff || (xhci->xhc_state & XHCI_STATE_DYING) ||
(xhci->xhc_state & XHCI_STATE_HALTED)) {
xhci_free_virt_device(xhci, udev->slot_id);
spin_unlock_irqrestore(&xhci->lock, flags);
return;