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:
@@ -123,10 +123,11 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (usb_endpoint_xfer_isoc(&ep->desc))
|
if (usb_endpoint_xfer_isoc(&ep->desc))
|
||||||
max_tx = ep->desc.wMaxPacketSize * (desc->bMaxBurst + 1) *
|
max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) *
|
||||||
(desc->bmAttributes + 1);
|
le16_to_cpu(ep->desc.wMaxPacketSize);
|
||||||
else if (usb_endpoint_xfer_int(&ep->desc))
|
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
|
else
|
||||||
max_tx = 999999;
|
max_tx = 999999;
|
||||||
if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) {
|
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: "
|
"config %d interface %d altsetting %d ep %d: "
|
||||||
"setting to %d\n",
|
"setting to %d\n",
|
||||||
usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int",
|
usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int",
|
||||||
desc->wBytesPerInterval,
|
le16_to_cpu(desc->wBytesPerInterval),
|
||||||
cfgno, inum, asnum, ep->desc.bEndpointAddress,
|
cfgno, inum, asnum, ep->desc.bEndpointAddress,
|
||||||
max_tx);
|
max_tx);
|
||||||
ep->ss_ep_comp.wBytesPerInterval = max_tx;
|
ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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 the BIOS owns the HC, signal that the OS wants it, and wait */
|
||||||
if (val & XHCI_HC_BIOS_OWNED) {
|
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 */
|
/* Wait for 5 seconds with 10 microsecond polling interval */
|
||||||
timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED,
|
timeout = handshake(base + ext_cap_offset, XHCI_HC_BIOS_OWNED,
|
||||||
|
@@ -345,7 +345,8 @@ static void xhci_event_ring_work(unsigned long arg)
|
|||||||
spin_lock_irqsave(&xhci->lock, flags);
|
spin_lock_irqsave(&xhci->lock, flags);
|
||||||
temp = xhci_readl(xhci, &xhci->op_regs->status);
|
temp = xhci_readl(xhci, &xhci->op_regs->status);
|
||||||
xhci_dbg(xhci, "op reg status = 0x%x\n", temp);
|
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");
|
xhci_dbg(xhci, "HW died, polling stopped.\n");
|
||||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||||
return;
|
return;
|
||||||
@@ -939,8 +940,11 @@ static int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xhci = hcd_to_xhci(hcd);
|
||||||
|
if (xhci->xhc_state & XHCI_STATE_HALTED)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
if (check_virt_dev) {
|
if (check_virt_dev) {
|
||||||
xhci = hcd_to_xhci(hcd);
|
|
||||||
if (!udev->slot_id || !xhci->devs
|
if (!udev->slot_id || !xhci->devs
|
||||||
|| !xhci->devs[udev->slot_id]) {
|
|| !xhci->devs[udev->slot_id]) {
|
||||||
printk(KERN_DEBUG "xHCI %s called with unaddressed "
|
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);
|
xhci_urb_free_priv(xhci, urb_priv);
|
||||||
return ret;
|
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 "
|
xhci_dbg(xhci, "Ep 0x%x: URB %p to be canceled on "
|
||||||
"non-responsive xHCI host.\n",
|
"non-responsive xHCI host.\n",
|
||||||
urb->ep->desc.bEndpointAddress, urb);
|
urb->ep->desc.bEndpointAddress, urb);
|
||||||
@@ -2665,7 +2670,10 @@ void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev)
|
|||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
ret = xhci_check_args(hcd, udev, NULL, 0, true, __func__);
|
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;
|
return;
|
||||||
|
|
||||||
virt_dev = xhci->devs[udev->slot_id];
|
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);
|
spin_lock_irqsave(&xhci->lock, flags);
|
||||||
/* Don't disable the slot if the host controller is dead. */
|
/* Don't disable the slot if the host controller is dead. */
|
||||||
state = xhci_readl(xhci, &xhci->op_regs->status);
|
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);
|
xhci_free_virt_device(xhci, udev->slot_id);
|
||||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||||
return;
|
return;
|
||||||
|
Reference in New Issue
Block a user