Commit eab54042 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge branch 'for-usb-linus' of...

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: xhci - fix interval calculation for FS isoc endpoints
  xhci: Disable MSI for some Fresco Logic hosts.
  xhci: Do not issue device reset when device is not setup
  xhci: Add defines for hardcoded slot states
  xhci: Bigendian fix for xhci_check_bandwidth()
  xhci: Bigendian fix for skip_isoc_td()
parents 59c5f46f cd3c18ba
...@@ -438,13 +438,13 @@ char *xhci_get_slot_state(struct xhci_hcd *xhci, ...@@ -438,13 +438,13 @@ char *xhci_get_slot_state(struct xhci_hcd *xhci,
struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx); struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
switch (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state))) { switch (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state))) {
case 0: case SLOT_STATE_ENABLED:
return "enabled/disabled"; return "enabled/disabled";
case 1: case SLOT_STATE_DEFAULT:
return "default"; return "default";
case 2: case SLOT_STATE_ADDRESSED:
return "addressed"; return "addressed";
case 3: case SLOT_STATE_CONFIGURED:
return "configured"; return "configured";
default: default:
return "reserved"; return "reserved";
......
...@@ -985,9 +985,19 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev, ...@@ -985,9 +985,19 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,
interval = clamp_val(ep->desc.bInterval, 1, 16) - 1; interval = clamp_val(ep->desc.bInterval, 1, 16) - 1;
if (interval != ep->desc.bInterval - 1) if (interval != ep->desc.bInterval - 1)
dev_warn(&udev->dev, dev_warn(&udev->dev,
"ep %#x - rounding interval to %d microframes\n", "ep %#x - rounding interval to %d %sframes\n",
ep->desc.bEndpointAddress, ep->desc.bEndpointAddress,
1 << interval); 1 << interval,
udev->speed == USB_SPEED_FULL ? "" : "micro");
if (udev->speed == USB_SPEED_FULL) {
/*
* Full speed isoc endpoints specify interval in frames,
* not microframes. We are using microframes everywhere,
* so adjust accordingly.
*/
interval += 3; /* 1 frame = 2^3 uframes */
}
return interval; return interval;
} }
......
...@@ -106,12 +106,22 @@ static int xhci_pci_setup(struct usb_hcd *hcd) ...@@ -106,12 +106,22 @@ static int xhci_pci_setup(struct usb_hcd *hcd)
/* Look for vendor-specific quirks */ /* Look for vendor-specific quirks */
if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC && if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK && pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_PDK) {
pdev->revision == 0x0) { if (pdev->revision == 0x0) {
xhci->quirks |= XHCI_RESET_EP_QUIRK; xhci->quirks |= XHCI_RESET_EP_QUIRK;
xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure" xhci_dbg(xhci, "QUIRK: Fresco Logic xHC needs configure"
" endpoint cmd after reset endpoint\n"); " endpoint cmd after reset endpoint\n");
}
/* Fresco Logic confirms: all revisions of this chip do not
* support MSI, even though some of them claim to in their PCI
* capabilities.
*/
xhci->quirks |= XHCI_BROKEN_MSI;
xhci_dbg(xhci, "QUIRK: Fresco Logic revision %u "
"has broken MSI implementation\n",
pdev->revision);
} }
if (pdev->vendor == PCI_VENDOR_ID_NEC) if (pdev->vendor == PCI_VENDOR_ID_NEC)
xhci->quirks |= XHCI_NEC_HOST; xhci->quirks |= XHCI_NEC_HOST;
......
...@@ -1782,7 +1782,7 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td, ...@@ -1782,7 +1782,7 @@ static int skip_isoc_td(struct xhci_hcd *xhci, struct xhci_td *td,
struct usb_iso_packet_descriptor *frame; struct usb_iso_packet_descriptor *frame;
int idx; int idx;
ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer); ep_ring = xhci_dma_to_transfer_ring(ep, le64_to_cpu(event->buffer));
urb_priv = td->urb->hcpriv; urb_priv = td->urb->hcpriv;
idx = urb_priv->td_cnt; idx = urb_priv->td_cnt;
frame = &td->urb->iso_frame_desc[idx]; frame = &td->urb->iso_frame_desc[idx];
......
...@@ -430,12 +430,19 @@ int xhci_run(struct usb_hcd *hcd) ...@@ -430,12 +430,19 @@ int xhci_run(struct usb_hcd *hcd)
free_irq(hcd->irq, hcd); free_irq(hcd->irq, hcd);
hcd->irq = -1; hcd->irq = -1;
/* Some Fresco Logic host controllers advertise MSI, but fail to
* generate interrupts. Don't even try to enable MSI.
*/
if (xhci->quirks & XHCI_BROKEN_MSI)
goto legacy_irq;
ret = xhci_setup_msix(xhci); ret = xhci_setup_msix(xhci);
if (ret) if (ret)
/* fall back to msi*/ /* fall back to msi*/
ret = xhci_setup_msi(xhci); ret = xhci_setup_msi(xhci);
if (ret) { if (ret) {
legacy_irq:
/* fall back to legacy interrupt*/ /* fall back to legacy interrupt*/
ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
hcd->irq_descr, hcd); hcd->irq_descr, hcd);
...@@ -1849,8 +1856,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev) ...@@ -1849,8 +1856,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
/* Free any rings that were dropped, but not changed. */ /* Free any rings that were dropped, but not changed. */
for (i = 1; i < 31; ++i) { for (i = 1; i < 31; ++i) {
if ((ctrl_ctx->drop_flags & (1 << (i + 1))) && if ((le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1))) &&
!(ctrl_ctx->add_flags & (1 << (i + 1)))) !(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1))))
xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i); xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
} }
xhci_zero_in_ctx(xhci, virt_dev); xhci_zero_in_ctx(xhci, virt_dev);
...@@ -2467,6 +2474,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) ...@@ -2467,6 +2474,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
struct xhci_command *reset_device_cmd; struct xhci_command *reset_device_cmd;
int timeleft; int timeleft;
int last_freed_endpoint; int last_freed_endpoint;
struct xhci_slot_ctx *slot_ctx;
ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__); ret = xhci_check_args(hcd, udev, NULL, 0, false, __func__);
if (ret <= 0) if (ret <= 0)
...@@ -2499,6 +2507,12 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev) ...@@ -2499,6 +2507,12 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
return -EINVAL; return -EINVAL;
} }
/* If device is not setup, there is no point in resetting it */
slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
if (GET_SLOT_STATE(le32_to_cpu(slot_ctx->dev_state)) ==
SLOT_STATE_DISABLED)
return 0;
xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id); xhci_dbg(xhci, "Resetting device with slot ID %u\n", slot_id);
/* Allocate the command structure that holds the struct completion. /* Allocate the command structure that holds the struct completion.
* Assume we're in process context, since the normal device reset * Assume we're in process context, since the normal device reset
......
...@@ -560,6 +560,11 @@ struct xhci_slot_ctx { ...@@ -560,6 +560,11 @@ struct xhci_slot_ctx {
#define SLOT_STATE (0x1f << 27) #define SLOT_STATE (0x1f << 27)
#define GET_SLOT_STATE(p) (((p) & (0x1f << 27)) >> 27) #define GET_SLOT_STATE(p) (((p) & (0x1f << 27)) >> 27)
#define SLOT_STATE_DISABLED 0
#define SLOT_STATE_ENABLED SLOT_STATE_DISABLED
#define SLOT_STATE_DEFAULT 1
#define SLOT_STATE_ADDRESSED 2
#define SLOT_STATE_CONFIGURED 3
/** /**
* struct xhci_ep_ctx * struct xhci_ep_ctx
...@@ -1302,6 +1307,7 @@ struct xhci_hcd { ...@@ -1302,6 +1307,7 @@ struct xhci_hcd {
* commands. * commands.
*/ */
#define XHCI_EP_LIMIT_QUIRK (1 << 5) #define XHCI_EP_LIMIT_QUIRK (1 << 5)
#define XHCI_BROKEN_MSI (1 << 6)
unsigned int num_active_eps; unsigned int num_active_eps;
unsigned int limit_active_eps; unsigned int limit_active_eps;
/* There are two roothubs to keep track of bus suspend info for */ /* There are two roothubs to keep track of bus suspend info for */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment