Merge 3.10-rc5 into usb-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Jun 2013 04:27:51 +0000 (21:27 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 9 Jun 2013 04:27:51 +0000 (21:27 -0700)
We need the changes in this branch.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1  2 
drivers/usb/core/devio.c
drivers/usb/host/xhci-mem.c
drivers/usb/host/xhci.c
drivers/usb/host/xhci.h
drivers/usb/musb/musb_host.c
drivers/usb/serial/keyspan.c

diff --combined drivers/usb/core/devio.c
index 47ff9b1c8a371dea50e2952f047c12f407c357fa,c88c4fb9459dfbc94119e8a0590a924fa5868f0c..05986507b585897c763ac58e067e8a25f7e75374
  #include <linux/security.h>
  #include <linux/user_namespace.h>
  #include <linux/scatterlist.h>
 -#include <asm/uaccess.h>
 +#include <linux/uaccess.h>
  #include <asm/byteorder.h>
  #include <linux/moduleparam.h>
  
  #include "usb.h"
  
  #define USB_MAXBUS                    64
 -#define USB_DEVICE_MAX                        USB_MAXBUS * 128
 +#define USB_DEVICE_MAX                        (USB_MAXBUS * 128)
  #define USB_SG_SIZE                   16384 /* split-size for large txs */
  
  /* Mutual exclusion for removal, open, and release */
@@@ -1287,9 -1287,13 +1287,13 @@@ static int proc_do_submiturb(struct dev
                        goto error;
                }
                for (totlen = u = 0; u < uurb->number_of_packets; u++) {
-                       /* arbitrary limit,
-                        * sufficient for USB 2.0 high-bandwidth iso */
-                       if (isopkt[u].length > 8192) {
+                       /*
+                        * arbitrary limit need for USB 3.0
+                        * bMaxBurst (0~15 allowed, 1~16 packets)
+                        * bmAttributes (bit 1:0, mult 0~2, 1~3 packets)
+                        * sizemax: 1024 * 16 * 3 = 49152
+                        */
+                       if (isopkt[u].length > 49152) {
                                ret = -EINVAL;
                                goto error;
                        }
@@@ -1800,8 -1804,7 +1804,8 @@@ static int proc_ioctl(struct dev_state 
  
        /* alloc buffer */
        if ((size = _IOC_SIZE(ctl->ioctl_code)) > 0) {
 -              if ((buf = kmalloc(size, GFP_KERNEL)) == NULL)
 +              buf = kmalloc(size, GFP_KERNEL);
 +              if (buf == NULL)
                        return -ENOMEM;
                if ((_IOC_DIR(ctl->ioctl_code) & _IOC_WRITE)) {
                        if (copy_from_user(buf, ctl->data, size)) {
index 832f05ede42757d3dd85b7eb09aae9bee7ebbe26,fbf75e57628b72e0b7a74237d8a9610826b2ab93..8c0e119efa4e9384a7e58736674b402f46a16b5f
@@@ -1827,6 -1827,9 +1827,9 @@@ void xhci_mem_cleanup(struct xhci_hcd *
        }
        spin_unlock_irqrestore(&xhci->lock, flags);
  
+       if (!xhci->rh_bw)
+               goto no_bw;
        num_ports = HCS_MAX_PORTS(xhci->hcs_params1);
        for (i = 0; i < num_ports; i++) {
                struct xhci_interval_bw_table *bwt = &xhci->rh_bw[i].bw_table;
                }
        }
  
+ no_bw:
        xhci->num_usb2_ports = 0;
        xhci->num_usb3_ports = 0;
        xhci->num_active_eps = 0;
        kfree(xhci->usb3_ports);
        kfree(xhci->port_array);
        kfree(xhci->rh_bw);
 +      kfree(xhci->ext_caps);
  
        xhci->page_size = 0;
        xhci->page_shift = 0;
@@@ -2040,7 -2043,7 +2044,7 @@@ static void xhci_set_hc_event_deq(struc
  }
  
  static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
 -              __le32 __iomem *addr, u8 major_revision)
 +              __le32 __iomem *addr, u8 major_revision, int max_caps)
  {
        u32 temp, port_offset, port_count;
        int i;
                /* WTF? "Valid values are ‘1’ to MaxPorts" */
                return;
  
 +      /* cache usb2 port capabilities */
 +      if (major_revision < 0x03 && xhci->num_ext_caps < max_caps)
 +              xhci->ext_caps[xhci->num_ext_caps++] = temp;
 +
        /* Check the host's USB2 LPM capability */
        if ((xhci->hci_version == 0x96) && (major_revision != 0x03) &&
                        (temp & XHCI_L1C)) {
   */
  static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags)
  {
 -      __le32 __iomem *addr;
 -      u32 offset;
 +      __le32 __iomem *addr, *tmp_addr;
 +      u32 offset, tmp_offset;
        unsigned int num_ports;
        int i, j, port_index;
 +      int cap_count = 0;
  
        addr = &xhci->cap_regs->hcc_params;
        offset = XHCI_HCC_EXT_CAPS(xhci_readl(xhci, addr));
         * See section 5.3.6 for offset calculation.
         */
        addr = &xhci->cap_regs->hc_capbase + offset;
 +
 +      tmp_addr = addr;
 +      tmp_offset = offset;
 +
 +      /* count extended protocol capability entries for later caching */
 +      do {
 +              u32 cap_id;
 +              cap_id = xhci_readl(xhci, tmp_addr);
 +              if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)
 +                      cap_count++;
 +              tmp_offset = XHCI_EXT_CAPS_NEXT(cap_id);
 +              tmp_addr += tmp_offset;
 +      } while (tmp_offset);
 +
 +      xhci->ext_caps = kzalloc(sizeof(*xhci->ext_caps) * cap_count, flags);
 +      if (!xhci->ext_caps)
 +              return -ENOMEM;
 +
        while (1) {
                u32 cap_id;
  
                cap_id = xhci_readl(xhci, addr);
                if (XHCI_EXT_CAPS_ID(cap_id) == XHCI_EXT_CAPS_PROTOCOL)
                        xhci_add_in_port(xhci, num_ports, addr,
 -                                      (u8) XHCI_EXT_PORT_MAJOR(cap_id));
 +                                      (u8) XHCI_EXT_PORT_MAJOR(cap_id),
 +                                      cap_count);
                offset = XHCI_EXT_CAPS_NEXT(cap_id);
                if (!offset || (xhci->num_usb2_ports + xhci->num_usb3_ports)
                                == num_ports)
@@@ -2281,6 -2260,9 +2285,9 @@@ int xhci_mem_init(struct xhci_hcd *xhci
        u32 page_size, temp;
        int i;
  
+       INIT_LIST_HEAD(&xhci->lpm_failed_devs);
+       INIT_LIST_HEAD(&xhci->cancel_cmd_list);
        page_size = xhci_readl(xhci, &xhci->op_regs->page_size);
        xhci_dbg(xhci, "Supported page size register = 0x%x\n", page_size);
        for (i = 0; i < 16; i++) {
        xhci->cmd_ring = xhci_ring_alloc(xhci, 1, 1, TYPE_COMMAND, flags);
        if (!xhci->cmd_ring)
                goto fail;
-       INIT_LIST_HEAD(&xhci->cancel_cmd_list);
        xhci_dbg(xhci, "Allocated command ring at %p\n", xhci->cmd_ring);
        xhci_dbg(xhci, "First segment DMA is 0x%llx\n",
                        (unsigned long long)xhci->cmd_ring->first_seg->dma);
        if (xhci_setup_port_arrays(xhci, flags))
                goto fail;
  
-       INIT_LIST_HEAD(&xhci->lpm_failed_devs);
        /* Enable USB 3.0 device notifications for function remote wake, which
         * is necessary for allowing USB 3.0 devices to do remote wakeup from
         * U3 (device suspend).
diff --combined drivers/usb/host/xhci.c
index 8be34f838bd45e6a854c73d4e94923bf73bb928e,d8f640b12dd9d950e842892858a617b7fa97247e..77113c1fcb9630fd99907f507f2f177e4fd0e894
@@@ -218,7 -218,7 +218,7 @@@ static int xhci_setup_msi(struct xhci_h
                return ret;
        }
  
 -      ret = request_irq(pdev->irq, (irq_handler_t)xhci_msi_irq,
 +      ret = request_irq(pdev->irq, xhci_msi_irq,
                                0, "xhci_hcd", xhci_to_hcd(xhci));
        if (ret) {
                xhci_dbg(xhci, "disable MSI interrupt\n");
@@@ -290,7 -290,7 +290,7 @@@ static int xhci_setup_msix(struct xhci_
  
        for (i = 0; i < xhci->msix_count; i++) {
                ret = request_irq(xhci->msix_entries[i].vector,
 -                              (irq_handler_t)xhci_msi_irq,
 +                              xhci_msi_irq,
                                0, "xhci_hcd", xhci_to_hcd(xhci));
                if (ret)
                        goto disable_msix;
@@@ -466,7 -466,7 +466,7 @@@ static void compliance_mode_recovery_ti
   * Systems:
   * Vendor: Hewlett-Packard -> System Models: Z420, Z620 and Z820
   */
static bool compliance_mode_recovery_timer_quirk_check(void)
bool xhci_compliance_mode_recovery_timer_quirk_check(void)
  {
        const char *dmi_product_name, *dmi_sys_vendor;
  
@@@ -517,7 -517,7 +517,7 @@@ int xhci_init(struct usb_hcd *hcd
        xhci_dbg(xhci, "Finished xhci_init\n");
  
        /* Initializing Compliance Mode Recovery Data If Needed */
-       if (compliance_mode_recovery_timer_quirk_check()) {
+       if (xhci_compliance_mode_recovery_timer_quirk_check()) {
                xhci->quirks |= XHCI_COMP_MODE_QUIRK;
                compliance_mode_recovery_timer_init(xhci);
        }
@@@ -956,6 -956,7 +956,7 @@@ int xhci_resume(struct xhci_hcd *xhci, 
        struct usb_hcd          *hcd = xhci_to_hcd(xhci);
        struct usb_hcd          *secondary_hcd;
        int                     retval = 0;
+       bool                    comp_timer_running = false;
  
        /* Wait a bit if either of the roothubs need to settle from the
         * transition into bus suspend.
  
        /* If restore operation fails, re-initialize the HC during resume */
        if ((temp & STS_SRE) || hibernated) {
+               if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) &&
+                               !(xhci_all_ports_seen_u0(xhci))) {
+                       del_timer_sync(&xhci->comp_mode_recovery_timer);
+                       xhci_dbg(xhci, "Compliance Mode Recovery Timer deleted!\n");
+               }
                /* Let the USB core know _both_ roothubs lost power. */
                usb_root_hub_lost_power(xhci->main_hcd->self.root_hub);
                usb_root_hub_lost_power(xhci->shared_hcd->self.root_hub);
                retval = xhci_init(hcd->primary_hcd);
                if (retval)
                        return retval;
+               comp_timer_running = true;
                xhci_dbg(xhci, "Start the primary HCD\n");
                retval = xhci_run(hcd->primary_hcd);
                if (!retval) {
         * to suffer the Compliance Mode issue again. It doesn't matter if
         * ports have entered previously to U0 before system's suspension.
         */
-       if (xhci->quirks & XHCI_COMP_MODE_QUIRK)
+       if ((xhci->quirks & XHCI_COMP_MODE_QUIRK) && !comp_timer_running)
                compliance_mode_recovery_timer_init(xhci);
  
        /* Re-enable port polling. */
@@@ -1111,16 -1121,6 +1121,16 @@@ unsigned int xhci_get_endpoint_index(st
        return index;
  }
  
 +/* The reverse operation to xhci_get_endpoint_index. Calculate the USB endpoint
 + * address from the XHCI endpoint index.
 + */
 +unsigned int xhci_get_endpoint_address(unsigned int ep_index)
 +{
 +      unsigned int number = DIV_ROUND_UP(ep_index, 2);
 +      unsigned int direction = ep_index % 2 ? USB_DIR_OUT : USB_DIR_IN;
 +      return direction | number;
 +}
 +
  /* Find the flag for this endpoint (for use in the control context).  Use the
   * endpoint index to create a bitmask.  The slot context is bit 0, endpoint 0 is
   * bit 1, etc.
@@@ -3815,56 -3815,6 +3825,56 @@@ int xhci_find_raw_port_number(struct us
        return raw_port;
  }
  
 +/*
 + * Issue an Evaluate Context command to change the Maximum Exit Latency in the
 + * slot context.  If that succeeds, store the new MEL in the xhci_virt_device.
 + */
 +static int xhci_change_max_exit_latency(struct xhci_hcd *xhci,
 +                      struct usb_device *udev, u16 max_exit_latency)
 +{
 +      struct xhci_virt_device *virt_dev;
 +      struct xhci_command *command;
 +      struct xhci_input_control_ctx *ctrl_ctx;
 +      struct xhci_slot_ctx *slot_ctx;
 +      unsigned long flags;
 +      int ret;
 +
 +      spin_lock_irqsave(&xhci->lock, flags);
 +      if (max_exit_latency == xhci->devs[udev->slot_id]->current_mel) {
 +              spin_unlock_irqrestore(&xhci->lock, flags);
 +              return 0;
 +      }
 +
 +      /* Attempt to issue an Evaluate Context command to change the MEL. */
 +      virt_dev = xhci->devs[udev->slot_id];
 +      command = xhci->lpm_command;
 +      xhci_slot_copy(xhci, command->in_ctx, virt_dev->out_ctx);
 +      spin_unlock_irqrestore(&xhci->lock, flags);
 +
 +      ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx);
 +      ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
 +      slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx);
 +      slot_ctx->dev_info2 &= cpu_to_le32(~((u32) MAX_EXIT));
 +      slot_ctx->dev_info2 |= cpu_to_le32(max_exit_latency);
 +
 +      xhci_dbg(xhci, "Set up evaluate context for LPM MEL change.\n");
 +      xhci_dbg(xhci, "Slot %u Input Context:\n", udev->slot_id);
 +      xhci_dbg_ctx(xhci, command->in_ctx, 0);
 +
 +      /* Issue and wait for the evaluate context command. */
 +      ret = xhci_configure_endpoint(xhci, udev, command,
 +                      true, true);
 +      xhci_dbg(xhci, "Slot %u Output Context:\n", udev->slot_id);
 +      xhci_dbg_ctx(xhci, virt_dev->out_ctx, 0);
 +
 +      if (!ret) {
 +              spin_lock_irqsave(&xhci->lock, flags);
 +              virt_dev->current_mel = max_exit_latency;
 +              spin_unlock_irqrestore(&xhci->lock, flags);
 +      }
 +      return ret;
 +}
 +
  #ifdef CONFIG_PM_RUNTIME
  
  /* BESL to HIRD Encoding array for USB2 LPM */
@@@ -3906,28 -3856,6 +3916,28 @@@ static int xhci_calculate_hird_besl(str
        return besl;
  }
  
 +/* Calculate BESLD, L1 timeout and HIRDM for USB2 PORTHLPMC */
 +static int xhci_calculate_usb2_hw_lpm_params(struct usb_device *udev)
 +{
 +      u32 field;
 +      int l1;
 +      int besld = 0;
 +      int hirdm = 0;
 +
 +      field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
 +
 +      /* xHCI l1 is set in steps of 256us, xHCI 1.0 section 5.4.11.2 */
 +      l1 = udev->l1_params.timeout / 256;
 +
 +      /* device has preferred BESLD */
 +      if (field & USB_BESL_DEEP_VALID) {
 +              besld = USB_GET_BESL_DEEP(field);
 +              hirdm = 1;
 +      }
 +
 +      return PORT_BESLD(besld) | PORT_L1_TIMEOUT(l1) | PORT_HIRDM(hirdm);
 +}
 +
  static int xhci_usb2_software_lpm_test(struct usb_hcd *hcd,
                                        struct usb_device *udev)
  {
         * Check device's USB 2.0 extension descriptor to determine whether
         * HIRD or BESL shoule be used. See USB2.0 LPM errata.
         */
 -      pm_addr = port_array[port_num] + 1;
 +      pm_addr = port_array[port_num] + PORTPMSC;
        hird = xhci_calculate_hird_besl(xhci, udev);
        temp = PORT_L1DS(udev->slot_id) | PORT_HIRD(hird);
        xhci_writel(xhci, temp, pm_addr);
@@@ -4060,12 -3988,11 +4070,12 @@@ int xhci_set_usb2_hardware_lpm(struct u
  {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
        __le32 __iomem  **port_array;
 -      __le32 __iomem  *pm_addr;
 -      u32             temp;
 +      __le32 __iomem  *pm_addr, *hlpm_addr;
 +      u32             pm_val, hlpm_val, field;
        unsigned int    port_num;
        unsigned long   flags;
 -      int             hird;
 +      int             hird, exit_latency;
 +      int             ret;
  
        if (hcd->speed == HCD_USB3 || !xhci->hw_lpm_support ||
                        !udev->lpm_capable)
  
        port_array = xhci->usb2_ports;
        port_num = udev->portnum - 1;
 -      pm_addr = port_array[port_num] + 1;
 -      temp = xhci_readl(xhci, pm_addr);
 +      pm_addr = port_array[port_num] + PORTPMSC;
 +      pm_val = xhci_readl(xhci, pm_addr);
 +      hlpm_addr = port_array[port_num] + PORTHLPMC;
 +      field = le32_to_cpu(udev->bos->ext_cap->bmAttributes);
  
        xhci_dbg(xhci, "%s port %d USB2 hardware LPM\n",
                        enable ? "enable" : "disable", port_num);
  
 -      hird = xhci_calculate_hird_besl(xhci, udev);
 -
        if (enable) {
 -              temp &= ~PORT_HIRD_MASK;
 -              temp |= PORT_HIRD(hird) | PORT_RWE;
 -              xhci_writel(xhci, temp, pm_addr);
 -              temp = xhci_readl(xhci, pm_addr);
 -              temp |= PORT_HLE;
 -              xhci_writel(xhci, temp, pm_addr);
 +              /* Host supports BESL timeout instead of HIRD */
 +              if (udev->usb2_hw_lpm_besl_capable) {
 +                      /* if device doesn't have a preferred BESL value use a
 +                       * default one which works with mixed HIRD and BESL
 +                       * systems. See XHCI_DEFAULT_BESL definition in xhci.h
 +                       */
 +                      if ((field & USB_BESL_SUPPORT) &&
 +                          (field & USB_BESL_BASELINE_VALID))
 +                              hird = USB_GET_BESL_BASELINE(field);
 +                      else
 +                              hird = udev->l1_params.besl;
 +
 +                      exit_latency = xhci_besl_encoding[hird];
 +                      spin_unlock_irqrestore(&xhci->lock, flags);
 +
 +                      /* USB 3.0 code dedicate one xhci->lpm_command->in_ctx
 +                       * input context for link powermanagement evaluate
 +                       * context commands. It is protected by hcd->bandwidth
 +                       * mutex and is shared by all devices. We need to set
 +                       * the max ext latency in USB 2 BESL LPM as well, so
 +                       * use the same mutex and xhci_change_max_exit_latency()
 +                       */
 +                      mutex_lock(hcd->bandwidth_mutex);
 +                      ret = xhci_change_max_exit_latency(xhci, udev,
 +                                                         exit_latency);
 +                      mutex_unlock(hcd->bandwidth_mutex);
 +
 +                      if (ret < 0)
 +                              return ret;
 +                      spin_lock_irqsave(&xhci->lock, flags);
 +
 +                      hlpm_val = xhci_calculate_usb2_hw_lpm_params(udev);
 +                      xhci_writel(xhci, hlpm_val, hlpm_addr);
 +                      /* flush write */
 +                      xhci_readl(xhci, hlpm_addr);
 +              } else {
 +                      hird = xhci_calculate_hird_besl(xhci, udev);
 +              }
 +
 +              pm_val &= ~PORT_HIRD_MASK;
 +              pm_val |= PORT_HIRD(hird) | PORT_RWE;
 +              xhci_writel(xhci, pm_val, pm_addr);
 +              pm_val = xhci_readl(xhci, pm_addr);
 +              pm_val |= PORT_HLE;
 +              xhci_writel(xhci, pm_val, pm_addr);
 +              /* flush write */
 +              xhci_readl(xhci, pm_addr);
        } else {
 -              temp &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK);
 -              xhci_writel(xhci, temp, pm_addr);
 +              pm_val &= ~(PORT_HLE | PORT_RWE | PORT_HIRD_MASK);
 +              xhci_writel(xhci, pm_val, pm_addr);
 +              /* flush write */
 +              xhci_readl(xhci, pm_addr);
 +              if (udev->usb2_hw_lpm_besl_capable) {
 +                      spin_unlock_irqrestore(&xhci->lock, flags);
 +                      mutex_lock(hcd->bandwidth_mutex);
 +                      xhci_change_max_exit_latency(xhci, udev, 0);
 +                      mutex_unlock(hcd->bandwidth_mutex);
 +                      return 0;
 +              }
        }
  
        spin_unlock_irqrestore(&xhci->lock, flags);
        return 0;
  }
  
 +/* check if a usb2 port supports a given extened capability protocol
 + * only USB2 ports extended protocol capability values are cached.
 + * Return 1 if capability is supported
 + */
 +static int xhci_check_usb2_port_capability(struct xhci_hcd *xhci, int port,
 +                                         unsigned capability)
 +{
 +      u32 port_offset, port_count;
 +      int i;
 +
 +      for (i = 0; i < xhci->num_ext_caps; i++) {
 +              if (xhci->ext_caps[i] & capability) {
 +                      /* port offsets starts at 1 */
 +                      port_offset = XHCI_EXT_PORT_OFF(xhci->ext_caps[i]) - 1;
 +                      port_count = XHCI_EXT_PORT_COUNT(xhci->ext_caps[i]);
 +                      if (port >= port_offset &&
 +                          port < port_offset + port_count)
 +                              return 1;
 +              }
 +      }
 +      return 0;
 +}
 +
  int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
  {
        struct xhci_hcd *xhci = hcd_to_xhci(hcd);
        int             ret;
 +      int             portnum = udev->portnum - 1;
  
        ret = xhci_usb2_software_lpm_test(hcd, udev);
        if (!ret) {
                xhci_dbg(xhci, "software LPM test succeed\n");
 -              if (xhci->hw_lpm_support == 1) {
 +              if (xhci->hw_lpm_support == 1 &&
 +                  xhci_check_usb2_port_capability(xhci, portnum, XHCI_HLC)) {
                        udev->usb2_hw_lpm_capable = 1;
 +                      udev->l1_params.timeout = XHCI_L1_TIMEOUT;
 +                      udev->l1_params.besl = XHCI_DEFAULT_BESL;
 +                      if (xhci_check_usb2_port_capability(xhci, portnum,
 +                                                          XHCI_BLC))
 +                              udev->usb2_hw_lpm_besl_capable = 1;
                        ret = xhci_set_usb2_hardware_lpm(hcd, udev, 1);
                        if (!ret)
                                udev->usb2_hw_lpm_enabled = 1;
@@@ -4526,6 -4373,56 +4536,6 @@@ static u16 xhci_calculate_lpm_timeout(s
        return timeout;
  }
  
 -/*
 - * Issue an Evaluate Context command to change the Maximum Exit Latency in the
 - * slot context.  If that succeeds, store the new MEL in the xhci_virt_device.
 - */
 -static int xhci_change_max_exit_latency(struct xhci_hcd *xhci,
 -                      struct usb_device *udev, u16 max_exit_latency)
 -{
 -      struct xhci_virt_device *virt_dev;
 -      struct xhci_command *command;
 -      struct xhci_input_control_ctx *ctrl_ctx;
 -      struct xhci_slot_ctx *slot_ctx;
 -      unsigned long flags;
 -      int ret;
 -
 -      spin_lock_irqsave(&xhci->lock, flags);
 -      if (max_exit_latency == xhci->devs[udev->slot_id]->current_mel) {
 -              spin_unlock_irqrestore(&xhci->lock, flags);
 -              return 0;
 -      }
 -
 -      /* Attempt to issue an Evaluate Context command to change the MEL. */
 -      virt_dev = xhci->devs[udev->slot_id];
 -      command = xhci->lpm_command;
 -      xhci_slot_copy(xhci, command->in_ctx, virt_dev->out_ctx);
 -      spin_unlock_irqrestore(&xhci->lock, flags);
 -
 -      ctrl_ctx = xhci_get_input_control_ctx(xhci, command->in_ctx);
 -      ctrl_ctx->add_flags |= cpu_to_le32(SLOT_FLAG);
 -      slot_ctx = xhci_get_slot_ctx(xhci, command->in_ctx);
 -      slot_ctx->dev_info2 &= cpu_to_le32(~((u32) MAX_EXIT));
 -      slot_ctx->dev_info2 |= cpu_to_le32(max_exit_latency);
 -
 -      xhci_dbg(xhci, "Set up evaluate context for LPM MEL change.\n");
 -      xhci_dbg(xhci, "Slot %u Input Context:\n", udev->slot_id);
 -      xhci_dbg_ctx(xhci, command->in_ctx, 0);
 -
 -      /* Issue and wait for the evaluate context command. */
 -      ret = xhci_configure_endpoint(xhci, udev, command,
 -                      true, true);
 -      xhci_dbg(xhci, "Slot %u Output Context:\n", udev->slot_id);
 -      xhci_dbg_ctx(xhci, virt_dev->out_ctx, 0);
 -
 -      if (!ret) {
 -              spin_lock_irqsave(&xhci->lock, flags);
 -              virt_dev->current_mel = max_exit_latency;
 -              spin_unlock_irqrestore(&xhci->lock, flags);
 -      }
 -      return ret;
 -}
 -
  static int calculate_max_exit_latency(struct usb_device *udev,
                enum usb3_link_state state_changed,
                u16 hub_encoded_timeout)
diff --combined drivers/usb/host/xhci.h
index c306849eb299027ca2cb75faacb8d795362ae7fd,77600cefcaf1df6ed3209a41c2a00dcdbb31b4dc..c338741a675d1e254b590e81810f9b48db943f15
@@@ -132,11 -132,6 +132,11 @@@ struct xhci_cap_regs 
  /* Number of registers per port */
  #define       NUM_PORT_REGS   4
  
 +#define PORTSC                0
 +#define PORTPMSC      1
 +#define PORTLI                2
 +#define PORTHLPMC     3
 +
  /**
   * struct xhci_op_regs - xHCI Host Controller Operational Registers.
   * @command:          USBCMD - xHC command register
@@@ -386,27 -381,6 +386,27 @@@ struct xhci_op_regs 
  #define       PORT_L1DS(p)            (((p) & 0xff) << 8)
  #define       PORT_HLE                (1 << 16)
  
 +
 +/* USB2 Protocol PORTHLPMC */
 +#define PORT_HIRDM(p)((p) & 3)
 +#define PORT_L1_TIMEOUT(p)(((p) & 0xff) << 2)
 +#define PORT_BESLD(p)(((p) & 0xf) << 10)
 +
 +/* use 512 microseconds as USB2 LPM L1 default timeout. */
 +#define XHCI_L1_TIMEOUT               512
 +
 +/* Set default HIRD/BESL value to 4 (350/400us) for USB2 L1 LPM resume latency.
 + * Safe to use with mixed HIRD and BESL systems (host and device) and is used
 + * by other operating systems.
 + *
 + * XHCI 1.0 errata 8/14/12 Table 13 notes:
 + * "Software should choose xHC BESL/BESLD field values that do not violate a
 + * device's resume latency requirements,
 + * e.g. not program values > '4' if BLC = '1' and a HIRD device is attached,
 + * or not program values < '4' if BLC = '0' and a BESL device is attached.
 + */
 +#define XHCI_DEFAULT_BESL     4
 +
  /**
   * struct xhci_intr_reg - Interrupt Register Set
   * @irq_pending:      IMAN - Interrupt Management Register.  Used to enable
@@@ -1558,9 -1532,6 +1558,9 @@@ struct xhci_hcd 
        unsigned                sw_lpm_support:1;
        /* support xHCI 1.0 spec USB2 hardware LPM */
        unsigned                hw_lpm_support:1;
 +      /* cached usb2 extened protocol capabilites */
 +      u32                     *ext_caps;
 +      unsigned int            num_ext_caps;
        /* Compliance Mode Recovery Data */
        struct timer_list       comp_mode_recovery_timer;
        u32                     port_status_u0;
@@@ -1670,7 -1641,6 +1670,7 @@@ int xhci_setup_addressable_virt_dev(str
  void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
                struct usb_device *udev);
  unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc);
 +unsigned int xhci_get_endpoint_address(unsigned int ep_index);
  unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc);
  unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index);
  unsigned int xhci_last_valid_endpoint(u32 added_ctxs);
@@@ -1775,7 -1745,7 +1775,7 @@@ int xhci_resume(struct xhci_hcd *xhci, 
  
  int xhci_get_frame(struct usb_hcd *hcd);
  irqreturn_t xhci_irq(struct usb_hcd *hcd);
 -irqreturn_t xhci_msi_irq(int irq, struct usb_hcd *hcd);
 +irqreturn_t xhci_msi_irq(int irq, void *hcd);
  int xhci_alloc_dev(struct usb_hcd *hcd, struct usb_device *udev);
  void xhci_free_dev(struct usb_hcd *hcd, struct usb_device *udev);
  int xhci_alloc_tt_info(struct xhci_hcd *xhci,
@@@ -1883,4 -1853,7 +1883,7 @@@ struct xhci_input_control_ctx *xhci_get
  struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
  struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
  
+ /* xHCI quirks */
+ bool xhci_compliance_mode_recovery_timer_quirk_check(void);
  #endif /* __LINUX_XHCI_HCD_H */
index 85ed11e04f35cb45434ea063a071f5f5eddbecd2,9d3044bdebe54c68ac7d506a2fa593f59287c4c0..4211e55409456b077b15889f02a60b8b2a328f56
@@@ -269,7 -269,8 +269,7 @@@ musb_start_urb(struct musb *musb, int i
                /* FIXME this doesn't implement that scheduling policy ...
                 * or handle framecounter wrapping
                 */
 -              if ((urb->transfer_flags & URB_ISO_ASAP)
 -                              || (frame >= urb->start_frame)) {
 +              if (1) {        /* Always assume URB_ISO_ASAP */
                        /* REVISIT the SOF irq handler shouldn't duplicate
                         * this code; and we don't init urb->start_frame...
                         */
@@@ -1231,7 -1232,6 +1231,6 @@@ void musb_host_tx(struct musb *musb, u
        void __iomem            *mbase = musb->mregs;
        struct dma_channel      *dma;
        bool                    transfer_pending = false;
-       static bool use_sg;
  
        musb_ep_select(mbase, epnum);
        tx_csr = musb_readw(epio, MUSB_TXCSR);
@@@ -1462,9 -1462,9 +1461,9 @@@ done
         * NULL.
         */
        if (!urb->transfer_buffer)
-               use_sg = true;
+               qh->use_sg = true;
  
-       if (use_sg) {
+       if (qh->use_sg) {
                /* sg_miter_start is already done in musb_ep_program */
                if (!sg_miter_next(&qh->sg_miter)) {
                        dev_err(musb->controller, "error: sg list empty\n");
  
        qh->segsize = length;
  
-       if (use_sg) {
+       if (qh->use_sg) {
                if (offset + length >= urb->transfer_buffer_length)
-                       use_sg = false;
+                       qh->use_sg = false;
        }
  
        musb_ep_select(mbase, epnum);
@@@ -1551,7 -1551,6 +1550,6 @@@ void musb_host_rx(struct musb *musb, u
        bool                    done = false;
        u32                     status;
        struct dma_channel      *dma;
-       static bool use_sg;
        unsigned int sg_flags = SG_MITER_ATOMIC | SG_MITER_TO_SG;
  
        musb_ep_select(mbase, epnum);
                         * NULL.
                         */
                        if (!urb->transfer_buffer) {
-                               use_sg = true;
+                               qh->use_sg = true;
                                sg_miter_start(&qh->sg_miter, urb->sg, 1,
                                                sg_flags);
                        }
  
-                       if (use_sg) {
+                       if (qh->use_sg) {
                                if (!sg_miter_next(&qh->sg_miter)) {
                                        dev_err(musb->controller, "error: sg list empty\n");
                                        sg_miter_stop(&qh->sg_miter);
@@@ -1912,8 -1911,8 +1910,8 @@@ finish
        urb->actual_length += xfer_len;
        qh->offset += xfer_len;
        if (done) {
-               if (use_sg)
-                       use_sg = false;
+               if (qh->use_sg)
+                       qh->use_sg = false;
  
                if (urb->status == -EINPROGRESS)
                        urb->status = status;
index 546fa904e141c6bbeeb8ea13cf94fb038cddd5f0,3549d073df229617690f90d29b6c2e1f77648b64..28365e647168e73372175ec338be281ca9f3accb
@@@ -520,7 -520,12 +520,7 @@@ static void       usa28_instat_callback(struc
                goto exit;
        }
  
 -      /*
 -      dev_dbg(&urb->dev->dev,
 -              "%s %x %x %x %x %x %x %x %x %x %x %x %x", __func__,
 -              data[0], data[1], data[2], data[3], data[4], data[5],
 -              data[6], data[7], data[8], data[9], data[10], data[11]);
 -      */
 +      /*dev_dbg(&urb->dev->dev, "%s %12ph", __func__, data);*/
  
        /* Now do something useful with the data */
        msg = (struct keyspan_usa28_portStatusMessage *)data;
@@@ -602,7 -607,11 +602,7 @@@ static void       usa49_instat_callback(struc
                goto exit;
        }
  
 -      /*
 -      dev_dbg(&urb->dev->dev, "%s: %x %x %x %x %x %x %x %x %x %x %x",
 -              __func__, data[0], data[1], data[2], data[3], data[4],
 -              data[5], data[6], data[7], data[8], data[9], data[10]);
 -      */
 +      /*dev_dbg(&urb->dev->dev, "%s: %11ph", __func__, data);*/
  
        /* Now do something useful with the data */
        msg = (struct keyspan_usa49_portStatusMessage *)data;
@@@ -1539,7 -1548,6 +1539,6 @@@ static int keyspan_usa26_send_setup(str
        struct keyspan_serial_private           *s_priv;
        struct keyspan_port_private             *p_priv;
        const struct keyspan_device_details     *d_details;
-       int                                     outcont_urb;
        struct urb                              *this_urb;
        int                                     device_port, err;
  
        d_details = s_priv->device_details;
        device_port = port->number - port->serial->minor;
  
-       outcont_urb = d_details->outcont_endpoints[port->number];
        this_urb = p_priv->outcont_urb;
  
        dev_dbg(&port->dev, "%s - endpoint %d\n", __func__, usb_pipeendpoint(this_urb->pipe));
        err = usb_submit_urb(this_urb, GFP_ATOMIC);
        if (err != 0)
                dev_dbg(&port->dev, "%s - usb_submit_urb(setup) failed (%d)\n", __func__, err);
- #if 0
-       else {
-               dev_dbg(&port->dev, "%s - usb_submit_urb(%d) OK %d bytes (end %d)\n", __func__
-                       outcont_urb, this_urb->transfer_buffer_length,
-                       usb_pipeendpoint(this_urb->pipe));
-       }
- #endif
        return 0;
  }
  
This page took 0.041122 seconds and 5 git commands to generate.