Merge tag 'usb-5.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 10 Jan 2021 20:33:19 +0000 (12:33 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 10 Jan 2021 20:33:19 +0000 (12:33 -0800)
Pull USB fixes from Greg KH:
 "Here are a number of small USB driver fixes for 5.11-rc3.

  Include in here are:

   - USB gadget driver fixes for reported issues

   - new usb-serial driver ids

   - dma from stack bugfixes

   - typec bugfixes

   - dwc3 bugfixes

   - xhci driver bugfixes

   - other small misc usb driver bugfixes

  All of these have been in linux-next with no reported issues"

* tag 'usb-5.11-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (35 commits)
  usb: dwc3: gadget: Clear wait flag on dequeue
  usb: typec: Send uevent for num_altmodes update
  usb: typec: Fix copy paste error for NVIDIA alt-mode description
  usb: gadget: enable super speed plus
  kcov, usb: hide in_serving_softirq checks in __usb_hcd_giveback_urb
  usb: uas: Add PNY USB Portable SSD to unusual_uas
  usb: gadget: configfs: Preserve function ordering after bind failure
  usb: gadget: select CONFIG_CRC32
  usb: gadget: core: change the comment for usb_gadget_connect
  usb: gadget: configfs: Fix use-after-free issue with udc_name
  usb: dwc3: gadget: Restart DWC3 gadget when enabling pullup
  usb: usbip: vhci_hcd: protect shift size
  USB: usblp: fix DMA to stack
  USB: serial: iuu_phoenix: fix DMA from stack
  USB: serial: option: add LongSung M5710 module support
  USB: serial: option: add Quectel EM160R-GL
  USB: Gadget: dummy-hcd: Fix shift-out-of-bounds bug
  usb: gadget: f_uac2: reset wMaxPacketSize
  usb: dwc3: ulpi: Fix USB2.0 HS/FS/LS PHY suspend regression
  usb: dwc3: ulpi: Replace CPU-based busyloop with Protocol-based one
  ...

33 files changed:
Documentation/devicetree/bindings/usb/ti,j721e-usb.yaml
MAINTAINERS
drivers/usb/chipidea/ci_hdrc_imx.c
drivers/usb/class/cdc-acm.c
drivers/usb/class/cdc-wdm.c
drivers/usb/class/usblp.c
drivers/usb/core/hcd.c
drivers/usb/dwc3/core.h
drivers/usb/dwc3/dwc3-meson-g12a.c
drivers/usb/dwc3/gadget.c
drivers/usb/dwc3/ulpi.c
drivers/usb/gadget/Kconfig
drivers/usb/gadget/composite.c
drivers/usb/gadget/configfs.c
drivers/usb/gadget/function/f_printer.c
drivers/usb/gadget/function/f_uac2.c
drivers/usb/gadget/function/u_ether.c
drivers/usb/gadget/legacy/acm_ms.c
drivers/usb/gadget/udc/Kconfig
drivers/usb/gadget/udc/Makefile
drivers/usb/gadget/udc/core.c
drivers/usb/gadget/udc/dummy_hcd.c
drivers/usb/gadget/udc/fsl_mxc_udc.c [deleted file]
drivers/usb/host/xhci.c
drivers/usb/misc/yurex.c
drivers/usb/serial/iuu_phoenix.c
drivers/usb/serial/option.c
drivers/usb/storage/unusual_uas.h
drivers/usb/typec/altmodes/Kconfig
drivers/usb/typec/class.c
drivers/usb/typec/mux/intel_pmc_mux.c
drivers/usb/usbip/vhci_hcd.c
include/linux/kcov.h

index 388245b..148b3fb 100644 (file)
@@ -11,8 +11,12 @@ maintainers:
 
 properties:
   compatible:
-    items:
+    oneOf:
       - const: ti,j721e-usb
+      - const: ti,am64-usb
+      - items:
+          - const: ti,j721e-usb
+          - const: ti,am64-usb
 
   reg:
     description: module registers
index 9758b33..04f0bb8 100644 (file)
@@ -3883,7 +3883,7 @@ F:        drivers/mtd/nand/raw/cadence-nand-controller.c
 CADENCE USB3 DRD IP DRIVER
 M:     Peter Chen <peter.chen@nxp.com>
 M:     Pawel Laszczak <pawell@cadence.com>
-M:     Roger Quadros <rogerq@ti.com>
+R:     Roger Quadros <rogerq@kernel.org>
 R:     Aswath Govindraju <a-govindraju@ti.com>
 L:     linux-usb@vger.kernel.org
 S:     Maintained
index 9e12152..8b7bc10 100644 (file)
@@ -139,9 +139,13 @@ static struct imx_usbmisc_data *usbmisc_get_init_data(struct device *dev)
        misc_pdev = of_find_device_by_node(args.np);
        of_node_put(args.np);
 
-       if (!misc_pdev || !platform_get_drvdata(misc_pdev))
+       if (!misc_pdev)
                return ERR_PTR(-EPROBE_DEFER);
 
+       if (!platform_get_drvdata(misc_pdev)) {
+               put_device(&misc_pdev->dev);
+               return ERR_PTR(-EPROBE_DEFER);
+       }
        data->dev = &misc_pdev->dev;
 
        /*
index f52f1bc..7819057 100644 (file)
@@ -1895,6 +1895,10 @@ static const struct usb_device_id acm_ids[] = {
        { USB_DEVICE(0x04d8, 0xfd08),
        .driver_info = IGNORE_DEVICE,
        },
+
+       { USB_DEVICE(0x04d8, 0xf58b),
+       .driver_info = IGNORE_DEVICE,
+       },
 #endif
 
        /*Samsung phone in firmware update mode */
index 02d0cfd..508b1c3 100644 (file)
@@ -465,13 +465,23 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
        if (!desc->resp_count || !--desc->resp_count)
                goto out;
 
+       if (test_bit(WDM_DISCONNECTING, &desc->flags)) {
+               rv = -ENODEV;
+               goto out;
+       }
+       if (test_bit(WDM_RESETTING, &desc->flags)) {
+               rv = -EIO;
+               goto out;
+       }
+
        set_bit(WDM_RESPONDING, &desc->flags);
        spin_unlock_irq(&desc->iuspin);
        rv = usb_submit_urb(desc->response, GFP_KERNEL);
        spin_lock_irq(&desc->iuspin);
        if (rv) {
-               dev_err(&desc->intf->dev,
-                       "usb_submit_urb failed with result %d\n", rv);
+               if (!test_bit(WDM_DISCONNECTING, &desc->flags))
+                       dev_err(&desc->intf->dev,
+                               "usb_submit_urb failed with result %d\n", rv);
 
                /* make sure the next notification trigger a submit */
                clear_bit(WDM_RESPONDING, &desc->flags);
@@ -1027,9 +1037,9 @@ static void wdm_disconnect(struct usb_interface *intf)
        wake_up_all(&desc->wait);
        mutex_lock(&desc->rlock);
        mutex_lock(&desc->wlock);
-       kill_urbs(desc);
        cancel_work_sync(&desc->rxwork);
        cancel_work_sync(&desc->service_outs_intr);
+       kill_urbs(desc);
        mutex_unlock(&desc->wlock);
        mutex_unlock(&desc->rlock);
 
index 67cbd42..134dc20 100644 (file)
@@ -274,8 +274,25 @@ static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, i
 #define usblp_reset(usblp)\
        usblp_ctrl_msg(usblp, USBLP_REQ_RESET, USB_TYPE_CLASS, USB_DIR_OUT, USB_RECIP_OTHER, 0, NULL, 0)
 
-#define usblp_hp_channel_change_request(usblp, channel, buffer) \
-       usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST, USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE, channel, buffer, 1)
+static int usblp_hp_channel_change_request(struct usblp *usblp, int channel, u8 *new_channel)
+{
+       u8 *buf;
+       int ret;
+
+       buf = kzalloc(1, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       ret = usblp_ctrl_msg(usblp, USBLP_REQ_HP_CHANNEL_CHANGE_REQUEST,
+                       USB_TYPE_VENDOR, USB_DIR_IN, USB_RECIP_INTERFACE,
+                       channel, buf, 1);
+       if (ret == 0)
+               *new_channel = buf[0];
+
+       kfree(buf);
+
+       return ret;
+}
 
 /*
  * See the description for usblp_select_alts() below for the usage
index 60886a7..ad5a0f4 100644 (file)
@@ -1649,14 +1649,12 @@ static void __usb_hcd_giveback_urb(struct urb *urb)
        urb->status = status;
        /*
         * This function can be called in task context inside another remote
-        * coverage collection section, but KCOV doesn't support that kind of
+        * coverage collection section, but kcov doesn't support that kind of
         * recursion yet. Only collect coverage in softirq context for now.
         */
-       if (in_serving_softirq())
-               kcov_remote_start_usb((u64)urb->dev->bus->busnum);
+       kcov_remote_start_usb_softirq((u64)urb->dev->bus->busnum);
        urb->complete(urb);
-       if (in_serving_softirq())
-               kcov_remote_stop();
+       kcov_remote_stop_softirq();
 
        usb_anchor_resume_wakeups(anchor);
        atomic_dec(&urb->use_count);
index 2f95f08..1b241f9 100644 (file)
 
 /* Global USB2 PHY Vendor Control Register */
 #define DWC3_GUSB2PHYACC_NEWREGREQ     BIT(25)
+#define DWC3_GUSB2PHYACC_DONE          BIT(24)
 #define DWC3_GUSB2PHYACC_BUSY          BIT(23)
 #define DWC3_GUSB2PHYACC_WRITE         BIT(22)
 #define DWC3_GUSB2PHYACC_ADDR(n)       (n << 16)
index 417e053..bdf1f98 100644 (file)
@@ -754,7 +754,7 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev)
 
        ret = priv->drvdata->setup_regmaps(priv, base);
        if (ret)
-               return ret;
+               goto err_disable_clks;
 
        if (priv->vbus) {
                ret = regulator_enable(priv->vbus);
index 78cb4db..ee44321 100644 (file)
@@ -1763,6 +1763,8 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
                        list_for_each_entry_safe(r, t, &dep->started_list, list)
                                dwc3_gadget_move_cancelled_request(r);
 
+                       dep->flags &= ~DWC3_EP_WAIT_TRANSFER_COMPLETE;
+
                        goto out;
                }
        }
@@ -2083,6 +2085,7 @@ static int dwc3_gadget_run_stop(struct dwc3 *dwc, int is_on, int suspend)
 
 static void dwc3_gadget_disable_irq(struct dwc3 *dwc);
 static void __dwc3_gadget_stop(struct dwc3 *dwc);
+static int __dwc3_gadget_start(struct dwc3 *dwc);
 
 static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
 {
@@ -2145,6 +2148,8 @@ static int dwc3_gadget_pullup(struct usb_gadget *g, int is_on)
                        dwc->ev_buf->lpos = (dwc->ev_buf->lpos + count) %
                                                dwc->ev_buf->length;
                }
+       } else {
+               __dwc3_gadget_start(dwc);
        }
 
        ret = dwc3_gadget_run_stop(dwc, is_on, false);
@@ -2319,10 +2324,6 @@ static int dwc3_gadget_start(struct usb_gadget *g,
        }
 
        dwc->gadget_driver      = driver;
-
-       if (pm_runtime_active(dwc->dev))
-               __dwc3_gadget_start(dwc);
-
        spin_unlock_irqrestore(&dwc->lock, flags);
 
        return 0;
@@ -2348,13 +2349,6 @@ static int dwc3_gadget_stop(struct usb_gadget *g)
        unsigned long           flags;
 
        spin_lock_irqsave(&dwc->lock, flags);
-
-       if (pm_runtime_suspended(dwc->dev))
-               goto out;
-
-       __dwc3_gadget_stop(dwc);
-
-out:
        dwc->gadget_driver      = NULL;
        spin_unlock_irqrestore(&dwc->lock, flags);
 
index aa213c9..f23f4c9 100644 (file)
@@ -7,6 +7,8 @@
  * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
  */
 
+#include <linux/delay.h>
+#include <linux/time64.h>
 #include <linux/ulpi/regs.h>
 
 #include "core.h"
                DWC3_GUSB2PHYACC_ADDR(ULPI_ACCESS_EXTENDED) | \
                DWC3_GUSB2PHYACC_EXTEND_ADDR(a) : DWC3_GUSB2PHYACC_ADDR(a))
 
-static int dwc3_ulpi_busyloop(struct dwc3 *dwc)
+#define DWC3_ULPI_BASE_DELAY   DIV_ROUND_UP(NSEC_PER_SEC, 60000000L)
+
+static int dwc3_ulpi_busyloop(struct dwc3 *dwc, u8 addr, bool read)
 {
-       unsigned int count = 1000;
+       unsigned long ns = 5L * DWC3_ULPI_BASE_DELAY;
+       unsigned int count = 10000;
        u32 reg;
 
+       if (addr >= ULPI_EXT_VENDOR_SPECIFIC)
+               ns += DWC3_ULPI_BASE_DELAY;
+
+       if (read)
+               ns += DWC3_ULPI_BASE_DELAY;
+
+       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
+       if (reg & DWC3_GUSB2PHYCFG_SUSPHY)
+               usleep_range(1000, 1200);
+
        while (count--) {
+               ndelay(ns);
                reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYACC(0));
-               if (!(reg & DWC3_GUSB2PHYACC_BUSY))
+               if (reg & DWC3_GUSB2PHYACC_DONE)
                        return 0;
                cpu_relax();
        }
@@ -38,16 +54,10 @@ static int dwc3_ulpi_read(struct device *dev, u8 addr)
        u32 reg;
        int ret;
 
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-       if (reg & DWC3_GUSB2PHYCFG_SUSPHY) {
-               reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
-               dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-       }
-
        reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
 
-       ret = dwc3_ulpi_busyloop(dwc);
+       ret = dwc3_ulpi_busyloop(dwc, addr, true);
        if (ret)
                return ret;
 
@@ -61,17 +71,11 @@ static int dwc3_ulpi_write(struct device *dev, u8 addr, u8 val)
        struct dwc3 *dwc = dev_get_drvdata(dev);
        u32 reg;
 
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-       if (reg & DWC3_GUSB2PHYCFG_SUSPHY) {
-               reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
-               dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-       }
-
        reg = DWC3_GUSB2PHYACC_NEWREGREQ | DWC3_ULPI_ADDR(addr);
        reg |= DWC3_GUSB2PHYACC_WRITE | val;
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYACC(0), reg);
 
-       return dwc3_ulpi_busyloop(dwc);
+       return dwc3_ulpi_busyloop(dwc, addr, false);
 }
 
 static const struct ulpi_ops dwc3_ulpi_ops = {
index 7e47e62..2d15257 100644 (file)
@@ -265,6 +265,7 @@ config USB_CONFIGFS_NCM
        depends on NET
        select USB_U_ETHER
        select USB_F_NCM
+       select CRC32
        help
          NCM is an advanced protocol for Ethernet encapsulation, allows
          grouping of several ethernet frames into one USB transfer and
@@ -314,6 +315,7 @@ config USB_CONFIGFS_EEM
        depends on NET
        select USB_U_ETHER
        select USB_F_EEM
+       select CRC32
        help
          CDC EEM is a newer USB standard that is somewhat simpler than CDC ECM
          and therefore can be supported by more hardware.  Technically ECM and
index c6d455f..1a556a6 100644 (file)
@@ -392,8 +392,11 @@ int usb_function_deactivate(struct usb_function *function)
 
        spin_lock_irqsave(&cdev->lock, flags);
 
-       if (cdev->deactivations == 0)
+       if (cdev->deactivations == 0) {
+               spin_unlock_irqrestore(&cdev->lock, flags);
                status = usb_gadget_deactivate(cdev->gadget);
+               spin_lock_irqsave(&cdev->lock, flags);
+       }
        if (status == 0)
                cdev->deactivations++;
 
@@ -424,8 +427,11 @@ int usb_function_activate(struct usb_function *function)
                status = -EINVAL;
        else {
                cdev->deactivations--;
-               if (cdev->deactivations == 0)
+               if (cdev->deactivations == 0) {
+                       spin_unlock_irqrestore(&cdev->lock, flags);
                        status = usb_gadget_activate(cdev->gadget);
+                       spin_lock_irqsave(&cdev->lock, flags);
+               }
        }
 
        spin_unlock_irqrestore(&cdev->lock, flags);
index 56051bb..36ffb43 100644 (file)
@@ -221,9 +221,16 @@ static ssize_t gadget_dev_desc_bcdUSB_store(struct config_item *item,
 
 static ssize_t gadget_dev_desc_UDC_show(struct config_item *item, char *page)
 {
-       char *udc_name = to_gadget_info(item)->composite.gadget_driver.udc_name;
+       struct gadget_info *gi = to_gadget_info(item);
+       char *udc_name;
+       int ret;
+
+       mutex_lock(&gi->lock);
+       udc_name = gi->composite.gadget_driver.udc_name;
+       ret = sprintf(page, "%s\n", udc_name ?: "");
+       mutex_unlock(&gi->lock);
 
-       return sprintf(page, "%s\n", udc_name ?: "");
+       return ret;
 }
 
 static int unregister_gadget(struct gadget_info *gi)
@@ -1248,9 +1255,9 @@ static void purge_configs_funcs(struct gadget_info *gi)
 
                cfg = container_of(c, struct config_usb_cfg, c);
 
-               list_for_each_entry_safe(f, tmp, &c->functions, list) {
+               list_for_each_entry_safe_reverse(f, tmp, &c->functions, list) {
 
-                       list_move_tail(&f->list, &cfg->func_list);
+                       list_move(&f->list, &cfg->func_list);
                        if (f->unbind) {
                                dev_dbg(&gi->cdev.gadget->dev,
                                        "unbind function '%s'/%p\n",
@@ -1536,7 +1543,7 @@ static const struct usb_gadget_driver configfs_driver_template = {
        .suspend        = configfs_composite_suspend,
        .resume         = configfs_composite_resume,
 
-       .max_speed      = USB_SPEED_SUPER,
+       .max_speed      = USB_SPEED_SUPER_PLUS,
        .driver = {
                .owner          = THIS_MODULE,
                .name           = "configfs-gadget",
@@ -1576,7 +1583,7 @@ static struct config_group *gadgets_make(
        gi->composite.unbind = configfs_do_nothing;
        gi->composite.suspend = NULL;
        gi->composite.resume = NULL;
-       gi->composite.max_speed = USB_SPEED_SUPER;
+       gi->composite.max_speed = USB_SPEED_SUPER_PLUS;
 
        spin_lock_init(&gi->spinlock);
        mutex_init(&gi->lock);
index 64a4112..2f1eb2e 100644 (file)
@@ -1162,6 +1162,7 @@ fail_tx_reqs:
                printer_req_free(dev->in_ep, req);
        }
 
+       usb_free_all_descriptors(f);
        return ret;
 
 }
index 3633df6..5d960b6 100644 (file)
@@ -271,7 +271,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = {
 
        .bEndpointAddress = USB_DIR_OUT,
        .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
-       .wMaxPacketSize = cpu_to_le16(1023),
+       /* .wMaxPacketSize = DYNAMIC */
        .bInterval = 1,
 };
 
@@ -280,7 +280,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = {
        .bDescriptorType = USB_DT_ENDPOINT,
 
        .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
-       .wMaxPacketSize = cpu_to_le16(1024),
+       /* .wMaxPacketSize = DYNAMIC */
        .bInterval = 4,
 };
 
@@ -348,7 +348,7 @@ static struct usb_endpoint_descriptor fs_epin_desc = {
 
        .bEndpointAddress = USB_DIR_IN,
        .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
-       .wMaxPacketSize = cpu_to_le16(1023),
+       /* .wMaxPacketSize = DYNAMIC */
        .bInterval = 1,
 };
 
@@ -357,7 +357,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = {
        .bDescriptorType = USB_DT_ENDPOINT,
 
        .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC,
-       .wMaxPacketSize = cpu_to_le16(1024),
+       /* .wMaxPacketSize = DYNAMIC */
        .bInterval = 4,
 };
 
@@ -444,12 +444,28 @@ struct cntrl_range_lay3 {
        __le32  dRES;
 } __packed;
 
-static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
+static int set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
        struct usb_endpoint_descriptor *ep_desc,
-       unsigned int factor, bool is_playback)
+       enum usb_device_speed speed, bool is_playback)
 {
        int chmask, srate, ssize;
-       u16 max_packet_size;
+       u16 max_size_bw, max_size_ep;
+       unsigned int factor;
+
+       switch (speed) {
+       case USB_SPEED_FULL:
+               max_size_ep = 1023;
+               factor = 1000;
+               break;
+
+       case USB_SPEED_HIGH:
+               max_size_ep = 1024;
+               factor = 8000;
+               break;
+
+       default:
+               return -EINVAL;
+       }
 
        if (is_playback) {
                chmask = uac2_opts->p_chmask;
@@ -461,10 +477,12 @@ static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
                ssize = uac2_opts->c_ssize;
        }
 
-       max_packet_size = num_channels(chmask) * ssize *
+       max_size_bw = num_channels(chmask) * ssize *
                DIV_ROUND_UP(srate, factor / (1 << (ep_desc->bInterval - 1)));
-       ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_packet_size,
-                               le16_to_cpu(ep_desc->wMaxPacketSize)));
+       ep_desc->wMaxPacketSize = cpu_to_le16(min_t(u16, max_size_bw,
+                                                   max_size_ep));
+
+       return 0;
 }
 
 /* Use macro to overcome line length limitation */
@@ -670,10 +688,33 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
        }
 
        /* Calculate wMaxPacketSize according to audio bandwidth */
-       set_ep_max_packet_size(uac2_opts, &fs_epin_desc, 1000, true);
-       set_ep_max_packet_size(uac2_opts, &fs_epout_desc, 1000, false);
-       set_ep_max_packet_size(uac2_opts, &hs_epin_desc, 8000, true);
-       set_ep_max_packet_size(uac2_opts, &hs_epout_desc, 8000, false);
+       ret = set_ep_max_packet_size(uac2_opts, &fs_epin_desc, USB_SPEED_FULL,
+                                    true);
+       if (ret < 0) {
+               dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
+               return ret;
+       }
+
+       ret = set_ep_max_packet_size(uac2_opts, &fs_epout_desc, USB_SPEED_FULL,
+                                    false);
+       if (ret < 0) {
+               dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
+               return ret;
+       }
+
+       ret = set_ep_max_packet_size(uac2_opts, &hs_epin_desc, USB_SPEED_HIGH,
+                                    true);
+       if (ret < 0) {
+               dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
+               return ret;
+       }
+
+       ret = set_ep_max_packet_size(uac2_opts, &hs_epout_desc, USB_SPEED_HIGH,
+                                    false);
+       if (ret < 0) {
+               dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
+               return ret;
+       }
 
        if (EPOUT_EN(uac2_opts)) {
                agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);
index 31ea76a..c019f2b 100644 (file)
 #define UETH__VERSION  "29-May-2008"
 
 /* Experiments show that both Linux and Windows hosts allow up to 16k
- * frame sizes. Set the max size to 15k+52 to prevent allocating 32k
+ * frame sizes. Set the max MTU size to 15k+52 to prevent allocating 32k
  * blocks and still have efficient handling. */
-#define GETHER_MAX_ETH_FRAME_LEN 15412
+#define GETHER_MAX_MTU_SIZE 15412
+#define GETHER_MAX_ETH_FRAME_LEN (GETHER_MAX_MTU_SIZE + ETH_HLEN)
 
 struct eth_dev {
        /* lock is held while accessing port_usb
@@ -786,7 +787,7 @@ struct eth_dev *gether_setup_name(struct usb_gadget *g,
 
        /* MTU range: 14 - 15412 */
        net->min_mtu = ETH_HLEN;
-       net->max_mtu = GETHER_MAX_ETH_FRAME_LEN;
+       net->max_mtu = GETHER_MAX_MTU_SIZE;
 
        dev->gadget = g;
        SET_NETDEV_DEV(net, &g->dev);
@@ -848,7 +849,7 @@ struct net_device *gether_setup_name_default(const char *netname)
 
        /* MTU range: 14 - 15412 */
        net->min_mtu = ETH_HLEN;
-       net->max_mtu = GETHER_MAX_ETH_FRAME_LEN;
+       net->max_mtu = GETHER_MAX_MTU_SIZE;
 
        return net;
 }
index 59be2d8..e8033e5 100644 (file)
@@ -200,8 +200,10 @@ static int acm_ms_bind(struct usb_composite_dev *cdev)
                struct usb_descriptor_header *usb_desc;
 
                usb_desc = usb_otg_descriptor_alloc(gadget);
-               if (!usb_desc)
+               if (!usb_desc) {
+                       status = -ENOMEM;
                        goto fail_string_ids;
+               }
                usb_otg_descriptor_init(gadget, usb_desc);
                otg_desc[0] = usb_desc;
                otg_desc[1] = NULL;
index 1a12aab..8c614bb 100644 (file)
@@ -90,7 +90,7 @@ config USB_BCM63XX_UDC
 
 config USB_FSL_USB2
        tristate "Freescale Highspeed USB DR Peripheral Controller"
-       depends on FSL_SOC || ARCH_MXC
+       depends on FSL_SOC
        help
           Some of Freescale PowerPC and i.MX processors have a High Speed
           Dual-Role(DR) USB controller, which supports device mode.
index f5a7ce2..a21f222 100644 (file)
@@ -23,7 +23,6 @@ obj-$(CONFIG_USB_ATMEL_USBA)  += atmel_usba_udc.o
 obj-$(CONFIG_USB_BCM63XX_UDC)  += bcm63xx_udc.o
 obj-$(CONFIG_USB_FSL_USB2)     += fsl_usb2_udc.o
 fsl_usb2_udc-y                 := fsl_udc_core.o
-fsl_usb2_udc-$(CONFIG_ARCH_MXC)        += fsl_mxc_udc.o
 obj-$(CONFIG_USB_TEGRA_XUDC)   += tegra-xudc.o
 obj-$(CONFIG_USB_M66592)       += m66592-udc.o
 obj-$(CONFIG_USB_R8A66597)     += r8a66597-udc.o
index 5b5cfeb..6a62bbd 100644 (file)
@@ -659,8 +659,7 @@ EXPORT_SYMBOL_GPL(usb_gadget_vbus_disconnect);
  *
  * Enables the D+ (or potentially D-) pullup.  The host will start
  * enumerating this gadget when the pullup is active and a VBUS session
- * is active (the link is powered).  This pullup is always enabled unless
- * usb_gadget_disconnect() has been used to disable it.
+ * is active (the link is powered).
  *
  * Returns zero on success, else negative errno.
  */
index ab5e978..1a953f4 100644 (file)
@@ -2118,9 +2118,21 @@ static int dummy_hub_control(
                                dum_hcd->port_status &= ~USB_PORT_STAT_POWER;
                        set_link_state(dum_hcd);
                        break;
-               default:
+               case USB_PORT_FEAT_ENABLE:
+               case USB_PORT_FEAT_C_ENABLE:
+               case USB_PORT_FEAT_C_SUSPEND:
+                       /* Not allowed for USB-3 */
+                       if (hcd->speed == HCD_USB3)
+                               goto error;
+                       fallthrough;
+               case USB_PORT_FEAT_C_CONNECTION:
+               case USB_PORT_FEAT_C_RESET:
                        dum_hcd->port_status &= ~(1 << wValue);
                        set_link_state(dum_hcd);
+                       break;
+               default:
+               /* Disallow INDICATOR and C_OVER_CURRENT */
+                       goto error;
                }
                break;
        case GetHubDescriptor:
@@ -2281,18 +2293,17 @@ static int dummy_hub_control(
                         */
                        dum_hcd->re_timeout = jiffies + msecs_to_jiffies(50);
                        fallthrough;
+               case USB_PORT_FEAT_C_CONNECTION:
+               case USB_PORT_FEAT_C_RESET:
+               case USB_PORT_FEAT_C_ENABLE:
+               case USB_PORT_FEAT_C_SUSPEND:
+                       /* Not allowed for USB-3, and ignored for USB-2 */
+                       if (hcd->speed == HCD_USB3)
+                               goto error;
+                       break;
                default:
-                       if (hcd->speed == HCD_USB3) {
-                               if ((dum_hcd->port_status &
-                                    USB_SS_PORT_STAT_POWER) != 0) {
-                                       dum_hcd->port_status |= (1 << wValue);
-                               }
-                       } else
-                               if ((dum_hcd->port_status &
-                                    USB_PORT_STAT_POWER) != 0) {
-                                       dum_hcd->port_status |= (1 << wValue);
-                               }
-                       set_link_state(dum_hcd);
+               /* Disallow TEST, INDICATOR, and C_OVER_CURRENT */
+                       goto error;
                }
                break;
        case GetPortErrorCount:
diff --git a/drivers/usb/gadget/udc/fsl_mxc_udc.c b/drivers/usb/gadget/udc/fsl_mxc_udc.c
deleted file mode 100644 (file)
index 5a32199..0000000
+++ /dev/null
@@ -1,122 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2009
- * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
- *
- * Description:
- * Helper routines for i.MX3x SoCs from Freescale, needed by the fsl_usb2_udc.c
- * driver to function correctly on these systems.
- */
-#include <linux/clk.h>
-#include <linux/delay.h>
-#include <linux/err.h>
-#include <linux/fsl_devices.h>
-#include <linux/mod_devicetable.h>
-#include <linux/platform_device.h>
-#include <linux/io.h>
-
-#include "fsl_usb2_udc.h"
-
-static struct clk *mxc_ahb_clk;
-static struct clk *mxc_per_clk;
-static struct clk *mxc_ipg_clk;
-
-/* workaround ENGcm09152 for i.MX35 */
-#define MX35_USBPHYCTRL_OFFSET         0x600
-#define USBPHYCTRL_OTGBASE_OFFSET      0x8
-#define USBPHYCTRL_EVDO                        (1 << 23)
-
-int fsl_udc_clk_init(struct platform_device *pdev)
-{
-       struct fsl_usb2_platform_data *pdata;
-       unsigned long freq;
-       int ret;
-
-       pdata = dev_get_platdata(&pdev->dev);
-
-       mxc_ipg_clk = devm_clk_get(&pdev->dev, "ipg");
-       if (IS_ERR(mxc_ipg_clk)) {
-               dev_err(&pdev->dev, "clk_get(\"ipg\") failed\n");
-               return PTR_ERR(mxc_ipg_clk);
-       }
-
-       mxc_ahb_clk = devm_clk_get(&pdev->dev, "ahb");
-       if (IS_ERR(mxc_ahb_clk)) {
-               dev_err(&pdev->dev, "clk_get(\"ahb\") failed\n");
-               return PTR_ERR(mxc_ahb_clk);
-       }
-
-       mxc_per_clk = devm_clk_get(&pdev->dev, "per");
-       if (IS_ERR(mxc_per_clk)) {
-               dev_err(&pdev->dev, "clk_get(\"per\") failed\n");
-               return PTR_ERR(mxc_per_clk);
-       }
-
-       clk_prepare_enable(mxc_ipg_clk);
-       clk_prepare_enable(mxc_ahb_clk);
-       clk_prepare_enable(mxc_per_clk);
-
-       /* make sure USB_CLK is running at 60 MHz +/- 1000 Hz */
-       if (!strcmp(pdev->id_entry->name, "imx-udc-mx27")) {
-               freq = clk_get_rate(mxc_per_clk);
-               if (pdata->phy_mode != FSL_USB2_PHY_ULPI &&
-                   (freq < 59999000 || freq > 60001000)) {
-                       dev_err(&pdev->dev, "USB_CLK=%lu, should be 60MHz\n", freq);
-                       ret = -EINVAL;
-                       goto eclkrate;
-               }
-       }
-
-       return 0;
-
-eclkrate:
-       clk_disable_unprepare(mxc_ipg_clk);
-       clk_disable_unprepare(mxc_ahb_clk);
-       clk_disable_unprepare(mxc_per_clk);
-       mxc_per_clk = NULL;
-       return ret;
-}
-
-int fsl_udc_clk_finalize(struct platform_device *pdev)
-{
-       struct fsl_usb2_platform_data *pdata = dev_get_platdata(&pdev->dev);
-       int ret = 0;
-
-       /* workaround ENGcm09152 for i.MX35 */
-       if (pdata->workaround & FLS_USB2_WORKAROUND_ENGCM09152) {
-               unsigned int v;
-               struct resource *res = platform_get_resource
-                       (pdev, IORESOURCE_MEM, 0);
-               void __iomem *phy_regs = ioremap(res->start +
-                                               MX35_USBPHYCTRL_OFFSET, 512);
-               if (!phy_regs) {
-                       dev_err(&pdev->dev, "ioremap for phy address fails\n");
-                       ret = -EINVAL;
-                       goto ioremap_err;
-               }
-
-               v = readl(phy_regs + USBPHYCTRL_OTGBASE_OFFSET);
-               writel(v | USBPHYCTRL_EVDO,
-                       phy_regs + USBPHYCTRL_OTGBASE_OFFSET);
-
-               iounmap(phy_regs);
-       }
-
-
-ioremap_err:
-       /* ULPI transceivers don't need usbpll */
-       if (pdata->phy_mode == FSL_USB2_PHY_ULPI) {
-               clk_disable_unprepare(mxc_per_clk);
-               mxc_per_clk = NULL;
-       }
-
-       return ret;
-}
-
-void fsl_udc_clk_release(void)
-{
-       if (mxc_per_clk)
-               clk_disable_unprepare(mxc_per_clk);
-       clk_disable_unprepare(mxc_ahb_clk);
-       clk_disable_unprepare(mxc_ipg_clk);
-}
index 91ab81c..e869405 100644 (file)
@@ -4770,19 +4770,19 @@ static u16 xhci_calculate_u1_timeout(struct xhci_hcd *xhci,
 {
        unsigned long long timeout_ns;
 
+       if (xhci->quirks & XHCI_INTEL_HOST)
+               timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc);
+       else
+               timeout_ns = udev->u1_params.sel;
+
        /* Prevent U1 if service interval is shorter than U1 exit latency */
        if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
-               if (xhci_service_interval_to_ns(desc) <= udev->u1_params.mel) {
+               if (xhci_service_interval_to_ns(desc) <= timeout_ns) {
                        dev_dbg(&udev->dev, "Disable U1, ESIT shorter than exit latency\n");
                        return USB3_LPM_DISABLED;
                }
        }
 
-       if (xhci->quirks & XHCI_INTEL_HOST)
-               timeout_ns = xhci_calculate_intel_u1_timeout(udev, desc);
-       else
-               timeout_ns = udev->u1_params.sel;
-
        /* The U1 timeout is encoded in 1us intervals.
         * Don't return a timeout of zero, because that's USB3_LPM_DISABLED.
         */
@@ -4834,19 +4834,19 @@ static u16 xhci_calculate_u2_timeout(struct xhci_hcd *xhci,
 {
        unsigned long long timeout_ns;
 
+       if (xhci->quirks & XHCI_INTEL_HOST)
+               timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc);
+       else
+               timeout_ns = udev->u2_params.sel;
+
        /* Prevent U2 if service interval is shorter than U2 exit latency */
        if (usb_endpoint_xfer_int(desc) || usb_endpoint_xfer_isoc(desc)) {
-               if (xhci_service_interval_to_ns(desc) <= udev->u2_params.mel) {
+               if (xhci_service_interval_to_ns(desc) <= timeout_ns) {
                        dev_dbg(&udev->dev, "Disable U2, ESIT shorter than exit latency\n");
                        return USB3_LPM_DISABLED;
                }
        }
 
-       if (xhci->quirks & XHCI_INTEL_HOST)
-               timeout_ns = xhci_calculate_intel_u2_timeout(udev, desc);
-       else
-               timeout_ns = udev->u2_params.sel;
-
        /* The U2 timeout is encoded in 256us intervals */
        timeout_ns = DIV_ROUND_UP_ULL(timeout_ns, 256 * 1000);
        /* If the necessary timeout value is bigger than what we can set in the
index 73ebfa6..c640f98 100644 (file)
@@ -496,6 +496,9 @@ static ssize_t yurex_write(struct file *file, const char __user *user_buffer,
                timeout = schedule_timeout(YUREX_WRITE_TIMEOUT);
        finish_wait(&dev->waitq, &wait);
 
+       /* make sure URB is idle after timeout or (spurious) CMD_ACK */
+       usb_kill_urb(dev->cntl_urb);
+
        mutex_unlock(&dev->io_mutex);
 
        if (retval < 0) {
index f1201d4..e8f06b4 100644 (file)
@@ -532,23 +532,29 @@ static int iuu_uart_flush(struct usb_serial_port *port)
        struct device *dev = &port->dev;
        int i;
        int status;
-       u8 rxcmd = IUU_UART_RX;
+       u8 *rxcmd;
        struct iuu_private *priv = usb_get_serial_port_data(port);
 
        if (iuu_led(port, 0xF000, 0, 0, 0xFF) < 0)
                return -EIO;
 
+       rxcmd = kmalloc(1, GFP_KERNEL);
+       if (!rxcmd)
+               return -ENOMEM;
+
+       rxcmd[0] = IUU_UART_RX;
+
        for (i = 0; i < 2; i++) {
-               status = bulk_immediate(port, &rxcmd, 1);
+               status = bulk_immediate(port, rxcmd, 1);
                if (status != IUU_OPERATION_OK) {
                        dev_dbg(dev, "%s - uart_flush_write error\n", __func__);
-                       return status;
+                       goto out_free;
                }
 
                status = read_immediate(port, &priv->len, 1);
                if (status != IUU_OPERATION_OK) {
                        dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
-                       return status;
+                       goto out_free;
                }
 
                if (priv->len > 0) {
@@ -556,12 +562,16 @@ static int iuu_uart_flush(struct usb_serial_port *port)
                        status = read_immediate(port, priv->buf, priv->len);
                        if (status != IUU_OPERATION_OK) {
                                dev_dbg(dev, "%s - uart_flush_read error\n", __func__);
-                               return status;
+                               goto out_free;
                        }
                }
        }
        dev_dbg(dev, "%s - uart_flush_read OK!\n", __func__);
        iuu_led(port, 0, 0xF000, 0, 0xFF);
+
+out_free:
+       kfree(rxcmd);
+
        return status;
 }
 
index 2c21e34..3fe9591 100644 (file)
@@ -1117,6 +1117,8 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0xff, 0xff),
          .driver_info = RSVD(1) | RSVD(2) | RSVD(3) | RSVD(4) | NUMEP2 },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_EM12, 0xff, 0, 0) },
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0xff, 0x30) }, /* EM160R-GL */
+       { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, 0x0620, 0xff, 0, 0) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x30) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0, 0) },
        { USB_DEVICE_AND_INTERFACE_INFO(QUECTEL_VENDOR_ID, QUECTEL_PRODUCT_RM500Q, 0xff, 0xff, 0x10),
@@ -2057,6 +2059,7 @@ static const struct usb_device_id option_ids[] = {
        { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x0105, 0xff),                     /* Fibocom NL678 series */
          .driver_info = RSVD(6) },
        { USB_DEVICE_INTERFACE_CLASS(0x2cb7, 0x01a0, 0xff) },                   /* Fibocom NL668-AM/NL652-EU (laptop MBIM) */
+       { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) },                   /* LongSung M5710 */
        { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) },                   /* GosunCn GM500 RNDIS */
        { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) },                   /* GosunCn GM500 MBIM */
        { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1406, 0xff) },                   /* GosunCn GM500 ECM/NCM */
index 870e9cf..f9677a5 100644 (file)
@@ -90,6 +90,13 @@ UNUSUAL_DEV(0x152d, 0x0578, 0x0000, 0x9999,
                USB_SC_DEVICE, USB_PR_DEVICE, NULL,
                US_FL_BROKEN_FUA),
 
+/* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
+UNUSUAL_DEV(0x154b, 0xf00b, 0x0000, 0x9999,
+               "PNY",
+               "Pro Elite SSD",
+               USB_SC_DEVICE, USB_PR_DEVICE, NULL,
+               US_FL_NO_ATA_1X),
+
 /* Reported-by: Thinh Nguyen <thinhn@synopsys.com> */
 UNUSUAL_DEV(0x154b, 0xf00d, 0x0000, 0x9999,
                "PNY",
index 187690f..60d375e 100644 (file)
@@ -20,6 +20,6 @@ config TYPEC_NVIDIA_ALTMODE
          to enable support for VirtualLink devices with NVIDIA GPUs.
 
          To compile this driver as a module, choose M here: the
-         module will be called typec_displayport.
+         module will be called typec_nvidia.
 
 endmenu
index ebfd311..8f77669 100644 (file)
@@ -766,6 +766,7 @@ int typec_partner_set_num_altmodes(struct typec_partner *partner, int num_altmod
                return ret;
 
        sysfs_notify(&partner->dev.kobj, NULL, "number_of_alternate_modes");
+       kobject_uevent(&partner->dev.kobj, KOBJ_CHANGE);
 
        return 0;
 }
@@ -923,6 +924,7 @@ int typec_plug_set_num_altmodes(struct typec_plug *plug, int num_altmodes)
                return ret;
 
        sysfs_notify(&plug->dev.kobj, NULL, "number_of_alternate_modes");
+       kobject_uevent(&plug->dev.kobj, KOBJ_CHANGE);
 
        return 0;
 }
index cf37a59..46a25b8 100644 (file)
@@ -207,10 +207,21 @@ static int
 pmc_usb_mux_dp_hpd(struct pmc_usb_port *port, struct typec_displayport_data *dp)
 {
        u8 msg[2] = { };
+       int ret;
 
        msg[0] = PMC_USB_DP_HPD;
        msg[0] |= port->usb3_port << PMC_USB_MSG_USB3_PORT_SHIFT;
 
+       /* Configure HPD first if HPD,IRQ comes together */
+       if (!IOM_PORT_HPD_ASSERTED(port->iom_status) &&
+           dp->status & DP_STATUS_IRQ_HPD &&
+           dp->status & DP_STATUS_HPD_STATE) {
+               msg[1] = PMC_USB_DP_HPD_LVL;
+               ret = pmc_usb_command(port, msg, sizeof(msg));
+               if (ret)
+                       return ret;
+       }
+
        if (dp->status & DP_STATUS_IRQ_HPD)
                msg[1] = PMC_USB_DP_HPD_IRQ;
 
index 66cde5e..3209b5d 100644 (file)
@@ -396,6 +396,8 @@ static int vhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
                default:
                        usbip_dbg_vhci_rh(" ClearPortFeature: default %x\n",
                                          wValue);
+                       if (wValue >= 32)
+                               goto error;
                        vhci_hcd->port_status[rhport] &= ~(1 << wValue);
                        break;
                }
index a10e847..4e3037d 100644 (file)
@@ -52,6 +52,25 @@ static inline void kcov_remote_start_usb(u64 id)
        kcov_remote_start(kcov_remote_handle(KCOV_SUBSYSTEM_USB, id));
 }
 
+/*
+ * The softirq flavor of kcov_remote_*() functions is introduced as a temporary
+ * work around for kcov's lack of nested remote coverage sections support in
+ * task context. Adding suport for nested sections is tracked in:
+ * https://bugzilla.kernel.org/show_bug.cgi?id=210337
+ */
+
+static inline void kcov_remote_start_usb_softirq(u64 id)
+{
+       if (in_serving_softirq())
+               kcov_remote_start_usb(id);
+}
+
+static inline void kcov_remote_stop_softirq(void)
+{
+       if (in_serving_softirq())
+               kcov_remote_stop();
+}
+
 #else
 
 static inline void kcov_task_init(struct task_struct *t) {}
@@ -66,6 +85,8 @@ static inline u64 kcov_common_handle(void)
 }
 static inline void kcov_remote_start_common(u64 id) {}
 static inline void kcov_remote_start_usb(u64 id) {}
+static inline void kcov_remote_start_usb_softirq(u64 id) {}
+static inline void kcov_remote_stop_softirq(void) {}
 
 #endif /* CONFIG_KCOV */
 #endif /* _LINUX_KCOV_H */