Merge tag 'usb-serial-4.6-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/johan...
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Apr 2016 22:41:58 +0000 (15:41 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 8 Apr 2016 22:41:58 +0000 (15:41 -0700)
Johan writes:

USB-serial fixes for v4.6-rc3

Here are some new device ids.

Signed-off-by: Johan Hovold <johan@kernel.org>
18 files changed:
drivers/usb/core/config.c
drivers/usb/dwc2/gadget.c
drivers/usb/dwc3/core.c
drivers/usb/dwc3/dwc3-keystone.c
drivers/usb/dwc3/dwc3-pci.c
drivers/usb/dwc3/gadget.c
drivers/usb/gadget/composite.c
drivers/usb/gadget/function/f_midi.c
drivers/usb/gadget/udc/atmel_usba_udc.c
drivers/usb/gadget/udc/udc-core.c
drivers/usb/phy/phy-qcom-8x16-usb.c
drivers/usb/renesas_usbhs/fifo.c
drivers/usb/renesas_usbhs/mod_gadget.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/mct_u232.c
drivers/usb/usbip/usbip_common.c
include/uapi/linux/usb/ch9.h

index 5eb1a87228b47afd397fecfd4180413e7043a304..31ccdccd7a04fda36003cdc3ba58b82e25773fa9 100644 (file)
@@ -75,8 +75,6 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
         * be the first thing immediately following the endpoint descriptor.
         */
        desc = (struct usb_ss_ep_comp_descriptor *) buffer;
-       buffer += desc->bLength;
-       size -= desc->bLength;
 
        if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP ||
                        size < USB_DT_SS_EP_COMP_SIZE) {
@@ -100,7 +98,8 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
                                        ep->desc.wMaxPacketSize;
                return;
        }
-
+       buffer += desc->bLength;
+       size -= desc->bLength;
        memcpy(&ep->ss_ep_comp, desc, USB_DT_SS_EP_COMP_SIZE);
 
        /* Check the various values */
@@ -146,12 +145,6 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
                ep->ss_ep_comp.bmAttributes = 2;
        }
 
-       /* Parse a possible SuperSpeedPlus isoc ep companion descriptor */
-       if (usb_endpoint_xfer_isoc(&ep->desc) &&
-           USB_SS_SSP_ISOC_COMP(desc->bmAttributes))
-               usb_parse_ssp_isoc_endpoint_companion(ddev, cfgno, inum, asnum,
-                                                       ep, buffer, size);
-
        if (usb_endpoint_xfer_isoc(&ep->desc))
                max_tx = (desc->bMaxBurst + 1) *
                        (USB_SS_MULT(desc->bmAttributes)) *
@@ -171,6 +164,11 @@ static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno,
                                max_tx);
                ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx);
        }
+       /* Parse a possible SuperSpeedPlus isoc ep companion descriptor */
+       if (usb_endpoint_xfer_isoc(&ep->desc) &&
+           USB_SS_SSP_ISOC_COMP(desc->bmAttributes))
+               usb_parse_ssp_isoc_endpoint_companion(ddev, cfgno, inum, asnum,
+                                                       ep, buffer, size);
 }
 
 static int usb_parse_endpoint(struct device *ddev, int cfgno, int inum,
index e9940dd004e46c11472f776d79aebddc6497a906..818f158232bb6eb84e13e16a85808a25b7b1f668 100644 (file)
@@ -2254,6 +2254,7 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
 {
        u32 intmsk;
        u32 val;
+       u32 usbcfg;
 
        /* Kill any ep0 requests as controller will be reinitialized */
        kill_all_requests(hsotg, hsotg->eps_out[0], -ECONNRESET);
@@ -2267,10 +2268,16 @@ void dwc2_hsotg_core_init_disconnected(struct dwc2_hsotg *hsotg,
         * set configuration.
         */
 
+       /* keep other bits untouched (so e.g. forced modes are not lost) */
+       usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
+       usbcfg &= ~(GUSBCFG_TOUTCAL_MASK | GUSBCFG_PHYIF16 | GUSBCFG_SRPCAP |
+               GUSBCFG_HNPCAP);
+
        /* set the PLL on, remove the HNP/SRP and set the PHY */
        val = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5;
-       dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
-              (val << GUSBCFG_USBTRDTIM_SHIFT), hsotg->regs + GUSBCFG);
+       usbcfg |= hsotg->phyif | GUSBCFG_TOUTCAL(7) |
+               (val << GUSBCFG_USBTRDTIM_SHIFT);
+       dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
        dwc2_hsotg_init_fifo(hsotg);
 
@@ -3031,6 +3038,7 @@ static struct usb_ep_ops dwc2_hsotg_ep_ops = {
 static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg)
 {
        u32 trdtim;
+       u32 usbcfg;
        /* unmask subset of endpoint interrupts */
 
        dwc2_writel(DIEPMSK_TIMEOUTMSK | DIEPMSK_AHBERRMSK |
@@ -3054,11 +3062,16 @@ static void dwc2_hsotg_init(struct dwc2_hsotg *hsotg)
 
        dwc2_hsotg_init_fifo(hsotg);
 
+       /* keep other bits untouched (so e.g. forced modes are not lost) */
+       usbcfg = dwc2_readl(hsotg->regs + GUSBCFG);
+       usbcfg &= ~(GUSBCFG_TOUTCAL_MASK | GUSBCFG_PHYIF16 | GUSBCFG_SRPCAP |
+               GUSBCFG_HNPCAP);
+
        /* set the PLL on, remove the HNP/SRP and set the PHY */
        trdtim = (hsotg->phyif == GUSBCFG_PHYIF8) ? 9 : 5;
-       dwc2_writel(hsotg->phyif | GUSBCFG_TOUTCAL(7) |
-               (trdtim << GUSBCFG_USBTRDTIM_SHIFT),
-               hsotg->regs + GUSBCFG);
+       usbcfg |= hsotg->phyif | GUSBCFG_TOUTCAL(7) |
+               (trdtim << GUSBCFG_USBTRDTIM_SHIFT);
+       dwc2_writel(usbcfg, hsotg->regs + GUSBCFG);
 
        if (using_dma(hsotg))
                __orr32(hsotg->regs + GAHBCFG, GAHBCFG_DMA_EN);
index 17fd81447c9f72b452c83f8567e056e28bb1dd67..fa20f5a99d125aad27d28717683b5447a419fedf 100644 (file)
@@ -67,23 +67,9 @@ void dwc3_set_mode(struct dwc3 *dwc, u32 mode)
 static int dwc3_core_soft_reset(struct dwc3 *dwc)
 {
        u32             reg;
+       int             retries = 1000;
        int             ret;
 
-       /* Before Resetting PHY, put Core in Reset */
-       reg = dwc3_readl(dwc->regs, DWC3_GCTL);
-       reg |= DWC3_GCTL_CORESOFTRESET;
-       dwc3_writel(dwc->regs, DWC3_GCTL, reg);
-
-       /* Assert USB3 PHY reset */
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
-       reg |= DWC3_GUSB3PIPECTL_PHYSOFTRST;
-       dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
-
-       /* Assert USB2 PHY reset */
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-       reg |= DWC3_GUSB2PHYCFG_PHYSOFTRST;
-       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
-
        usb_phy_init(dwc->usb2_phy);
        usb_phy_init(dwc->usb3_phy);
        ret = phy_init(dwc->usb2_generic_phy);
@@ -95,26 +81,28 @@ static int dwc3_core_soft_reset(struct dwc3 *dwc)
                phy_exit(dwc->usb2_generic_phy);
                return ret;
        }
-       mdelay(100);
 
-       /* Clear USB3 PHY reset */
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
-       reg &= ~DWC3_GUSB3PIPECTL_PHYSOFTRST;
-       dwc3_writel(dwc->regs, DWC3_GUSB3PIPECTL(0), reg);
+       /*
+        * We're resetting only the device side because, if we're in host mode,
+        * XHCI driver will reset the host block. If dwc3 was configured for
+        * host-only mode, then we can return early.
+        */
+       if (dwc->dr_mode == USB_DR_MODE_HOST)
+               return 0;
 
-       /* Clear USB2 PHY reset */
-       reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
-       reg &= ~DWC3_GUSB2PHYCFG_PHYSOFTRST;
-       dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+       reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+       reg |= DWC3_DCTL_CSFTRST;
+       dwc3_writel(dwc->regs, DWC3_DCTL, reg);
 
-       mdelay(100);
+       do {
+               reg = dwc3_readl(dwc->regs, DWC3_DCTL);
+               if (!(reg & DWC3_DCTL_CSFTRST))
+                       return 0;
 
-       /* After PHYs are stable we can take Core out of reset state */
-       reg = dwc3_readl(dwc->regs, DWC3_GCTL);
-       reg &= ~DWC3_GCTL_CORESOFTRESET;
-       dwc3_writel(dwc->regs, DWC3_GCTL, reg);
+               udelay(1);
+       } while (--retries);
 
-       return 0;
+       return -ETIMEDOUT;
 }
 
 /**
index 2be268d2423d9339679d38dc0a01982912424b96..72664700b8a25c7d9bcee89c16c68fa6b5792565 100644 (file)
@@ -39,8 +39,6 @@
 #define USBSS_IRQ_COREIRQ_EN   BIT(0)
 #define USBSS_IRQ_COREIRQ_CLR  BIT(0)
 
-static u64 kdwc3_dma_mask;
-
 struct dwc3_keystone {
        struct device                   *dev;
        struct clk                      *clk;
@@ -108,9 +106,6 @@ static int kdwc3_probe(struct platform_device *pdev)
        if (IS_ERR(kdwc->usbss))
                return PTR_ERR(kdwc->usbss);
 
-       kdwc3_dma_mask = dma_get_mask(dev);
-       dev->dma_mask = &kdwc3_dma_mask;
-
        kdwc->clk = devm_clk_get(kdwc->dev, "usb");
 
        error = clk_prepare_enable(kdwc->clk);
index 009d83048c8c9ab51ae01191e3cb2aa30207d928..adc1e8a624cb036d8fdb7ceee8d87d153a472eb4 100644 (file)
@@ -35,6 +35,7 @@
 #define PCI_DEVICE_ID_INTEL_SPTLP              0x9d30
 #define PCI_DEVICE_ID_INTEL_SPTH               0xa130
 #define PCI_DEVICE_ID_INTEL_BXT                        0x0aaa
+#define PCI_DEVICE_ID_INTEL_BXT_M              0x1aaa
 #define PCI_DEVICE_ID_INTEL_APL                        0x5aaa
 
 static const struct acpi_gpio_params reset_gpios = { 0, 0, false };
@@ -213,6 +214,7 @@ static const struct pci_device_id dwc3_pci_id_table[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTLP), },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SPTH), },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT), },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BXT_M), },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_APL), },
        { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_NL_USB), },
        {  }    /* Terminating Entry */
index 3ac170f9d94d46156a172231c61be29c8067af09..d54a028cdfebaf69920f964bd7280427088b5b38 100644 (file)
@@ -568,7 +568,7 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
                dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
 
                if (!usb_endpoint_xfer_isoc(desc))
-                       return 0;
+                       goto out;
 
                /* Link TRB for ISOC. The HWO bit is never reset */
                trb_st_hw = &dep->trb_pool[0];
@@ -582,9 +582,10 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
                trb_link->ctrl |= DWC3_TRB_CTRL_HWO;
        }
 
+out:
        switch (usb_endpoint_type(desc)) {
        case USB_ENDPOINT_XFER_CONTROL:
-               strlcat(dep->name, "-control", sizeof(dep->name));
+               /* don't change name */
                break;
        case USB_ENDPOINT_XFER_ISOC:
                strlcat(dep->name, "-isoc", sizeof(dep->name));
@@ -2487,7 +2488,11 @@ static void dwc3_gadget_wakeup_interrupt(struct dwc3 *dwc)
         * implemented.
         */
 
-       dwc->gadget_driver->resume(&dwc->gadget);
+       if (dwc->gadget_driver && dwc->gadget_driver->resume) {
+               spin_unlock(&dwc->lock);
+               dwc->gadget_driver->resume(&dwc->gadget);
+               spin_lock(&dwc->lock);
+       }
 }
 
 static void dwc3_gadget_linksts_change_interrupt(struct dwc3 *dwc,
index a5c62093c26c67192dc91ca9920817e88928ae02..de9ffd60fcfa84b59291e755edc4ca0fb9945f2f 100644 (file)
@@ -656,7 +656,8 @@ static int bos_desc(struct usb_composite_dev *cdev)
                ssp_cap->bmAttributes = cpu_to_le32(1);
 
                /* Min RX/TX Lane Count = 1 */
-               ssp_cap->wFunctionalitySupport = (1 << 8) | (1 << 12);
+               ssp_cap->wFunctionalitySupport =
+                       cpu_to_le16((1 << 8) | (1 << 12));
 
                /*
                 * bmSublinkSpeedAttr[0]:
@@ -666,7 +667,7 @@ static int bos_desc(struct usb_composite_dev *cdev)
                 *   LSM = 10 (10 Gbps)
                 */
                ssp_cap->bmSublinkSpeedAttr[0] =
-                       (3 << 4) | (1 << 14) | (0xa << 16);
+                       cpu_to_le32((3 << 4) | (1 << 14) | (0xa << 16));
                /*
                 * bmSublinkSpeedAttr[1] =
                 *   ST  = Symmetric, TX
@@ -675,7 +676,8 @@ static int bos_desc(struct usb_composite_dev *cdev)
                 *   LSM = 10 (10 Gbps)
                 */
                ssp_cap->bmSublinkSpeedAttr[1] =
-                       (3 << 4) | (1 << 14) | (0xa << 16) | (1 << 7);
+                       cpu_to_le32((3 << 4) | (1 << 14) |
+                                   (0xa << 16) | (1 << 7));
        }
 
        return le16_to_cpu(bos->wTotalLength);
index 84c0ee5ebd1ea6e97abbfd22f69cdfaaa2627d70..58fc199a18ecd735021796ed4c352f7f728d0e22 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/kfifo.h>
+#include <linux/spinlock.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -89,6 +90,7 @@ struct f_midi {
        unsigned int buflen, qlen;
        /* This fifo is used as a buffer ring for pre-allocated IN usb_requests */
        DECLARE_KFIFO_PTR(in_req_fifo, struct usb_request *);
+       spinlock_t transmit_lock;
        unsigned int in_last_port;
 
        struct gmidi_in_port    in_ports_array[/* in_ports */];
@@ -358,7 +360,9 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
        /* allocate a bunch of read buffers and queue them all at once. */
        for (i = 0; i < midi->qlen && err == 0; i++) {
                struct usb_request *req =
-                       midi_alloc_ep_req(midi->out_ep, midi->buflen);
+                       midi_alloc_ep_req(midi->out_ep,
+                               max_t(unsigned, midi->buflen,
+                                       bulk_out_desc.wMaxPacketSize));
                if (req == NULL)
                        return -ENOMEM;
 
@@ -597,17 +601,24 @@ static void f_midi_transmit(struct f_midi *midi)
 {
        struct usb_ep *ep = midi->in_ep;
        int ret;
+       unsigned long flags;
 
        /* We only care about USB requests if IN endpoint is enabled */
        if (!ep || !ep->enabled)
                goto drop_out;
 
+       spin_lock_irqsave(&midi->transmit_lock, flags);
+
        do {
                ret = f_midi_do_transmit(midi, ep);
-               if (ret < 0)
+               if (ret < 0) {
+                       spin_unlock_irqrestore(&midi->transmit_lock, flags);
                        goto drop_out;
+               }
        } while (ret);
 
+       spin_unlock_irqrestore(&midi->transmit_lock, flags);
+
        return;
 
 drop_out:
@@ -1201,6 +1212,8 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
        if (status)
                goto setup_fail;
 
+       spin_lock_init(&midi->transmit_lock);
+
        ++opts->refcnt;
        mutex_unlock(&opts->lock);
 
index 81d42cce885a4ae3a080c20f08ca20f4db241d16..18569de06b0495762950fcc724f69d05f10047af 100644 (file)
@@ -1045,20 +1045,6 @@ static void reset_all_endpoints(struct usba_udc *udc)
                list_del_init(&req->queue);
                request_complete(ep, req, -ECONNRESET);
        }
-
-       /* NOTE:  normally, the next call to the gadget driver is in
-        * charge of disabling endpoints... usually disconnect().
-        * The exception would be entering a high speed test mode.
-        *
-        * FIXME remove this code ... and retest thoroughly.
-        */
-       list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) {
-               if (ep->ep.desc) {
-                       spin_unlock(&udc->lock);
-                       usba_ep_disable(&ep->ep);
-                       spin_lock(&udc->lock);
-               }
-       }
 }
 
 static struct usba_ep *get_ep_by_addr(struct usba_udc *udc, u16 wIndex)
index 4151597e9d2881ac107012d3cdc895bbcba7dc4f..e4e70e11d0f6ca2c2cc2b7a423353fb652dabf6a 100644 (file)
@@ -371,12 +371,6 @@ int usb_add_gadget_udc_release(struct device *parent, struct usb_gadget *gadget,
        INIT_WORK(&gadget->work, usb_gadget_state_work);
        gadget->dev.parent = parent;
 
-#ifdef CONFIG_HAS_DMA
-       dma_set_coherent_mask(&gadget->dev, parent->coherent_dma_mask);
-       gadget->dev.dma_parms = parent->dma_parms;
-       gadget->dev.dma_mask = parent->dma_mask;
-#endif
-
        if (release)
                gadget->dev.release = release;
        else
index 579587d972177338e97ca7ece02fabbc60fdcf55..3d7af85aecb9564d23946a98e7bb48dea81bf86f 100644 (file)
@@ -65,9 +65,7 @@ struct phy_8x16 {
        void __iomem                    *regs;
        struct clk                      *core_clk;
        struct clk                      *iface_clk;
-       struct regulator                *v3p3;
-       struct regulator                *v1p8;
-       struct regulator                *vdd;
+       struct regulator_bulk_data      regulator[3];
 
        struct reset_control            *phy_reset;
 
@@ -78,51 +76,6 @@ struct phy_8x16 {
        struct notifier_block           reboot_notify;
 };
 
-static int phy_8x16_regulators_enable(struct phy_8x16 *qphy)
-{
-       int ret;
-
-       ret = regulator_set_voltage(qphy->vdd, HSPHY_VDD_MIN, HSPHY_VDD_MAX);
-       if (ret)
-               return ret;
-
-       ret = regulator_enable(qphy->vdd);
-       if (ret)
-               return ret;
-
-       ret = regulator_set_voltage(qphy->v3p3, HSPHY_3P3_MIN, HSPHY_3P3_MAX);
-       if (ret)
-               goto off_vdd;
-
-       ret = regulator_enable(qphy->v3p3);
-       if (ret)
-               goto off_vdd;
-
-       ret = regulator_set_voltage(qphy->v1p8, HSPHY_1P8_MIN, HSPHY_1P8_MAX);
-       if (ret)
-               goto off_3p3;
-
-       ret = regulator_enable(qphy->v1p8);
-       if (ret)
-               goto off_3p3;
-
-       return 0;
-
-off_3p3:
-       regulator_disable(qphy->v3p3);
-off_vdd:
-       regulator_disable(qphy->vdd);
-
-       return ret;
-}
-
-static void phy_8x16_regulators_disable(struct phy_8x16 *qphy)
-{
-       regulator_disable(qphy->v1p8);
-       regulator_disable(qphy->v3p3);
-       regulator_disable(qphy->vdd);
-}
-
 static int phy_8x16_notify_connect(struct usb_phy *phy,
                                   enum usb_device_speed speed)
 {
@@ -261,7 +214,6 @@ static void phy_8x16_shutdown(struct usb_phy *phy)
 
 static int phy_8x16_read_devicetree(struct phy_8x16 *qphy)
 {
-       struct regulator_bulk_data regs[3];
        struct device *dev = qphy->phy.dev;
        int ret;
 
@@ -273,18 +225,15 @@ static int phy_8x16_read_devicetree(struct phy_8x16 *qphy)
        if (IS_ERR(qphy->iface_clk))
                return PTR_ERR(qphy->iface_clk);
 
-       regs[0].supply = "v3p3";
-       regs[1].supply = "v1p8";
-       regs[2].supply = "vddcx";
+       qphy->regulator[0].supply = "v3p3";
+       qphy->regulator[1].supply = "v1p8";
+       qphy->regulator[2].supply = "vddcx";
 
-       ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(regs), regs);
+       ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(qphy->regulator),
+                                     qphy->regulator);
        if (ret)
                return ret;
 
-       qphy->v3p3 = regs[0].consumer;
-       qphy->v1p8 = regs[1].consumer;
-       qphy->vdd  = regs[2].consumer;
-
        qphy->phy_reset = devm_reset_control_get(dev, "phy");
        if (IS_ERR(qphy->phy_reset))
                return PTR_ERR(qphy->phy_reset);
@@ -364,8 +313,9 @@ static int phy_8x16_probe(struct platform_device *pdev)
        if (ret < 0)
                goto off_core;
 
-       ret = phy_8x16_regulators_enable(qphy);
-       if (0 && ret)
+       ret = regulator_bulk_enable(ARRAY_SIZE(qphy->regulator),
+                                   qphy->regulator);
+       if (WARN_ON(ret))
                goto off_clks;
 
        qphy->vbus_notify.notifier_call = phy_8x16_vbus_notify;
@@ -387,7 +337,7 @@ off_extcon:
        extcon_unregister_notifier(qphy->vbus_edev, EXTCON_USB,
                                   &qphy->vbus_notify);
 off_power:
-       phy_8x16_regulators_disable(qphy);
+       regulator_bulk_disable(ARRAY_SIZE(qphy->regulator), qphy->regulator);
 off_clks:
        clk_disable_unprepare(qphy->iface_clk);
 off_core:
@@ -413,7 +363,7 @@ static int phy_8x16_remove(struct platform_device *pdev)
 
        clk_disable_unprepare(qphy->iface_clk);
        clk_disable_unprepare(qphy->core_clk);
-       phy_8x16_regulators_disable(qphy);
+       regulator_bulk_disable(ARRAY_SIZE(qphy->regulator), qphy->regulator);
        return 0;
 }
 
index b4de70ee16d3cfb56f4f3d5eb2047c5feb729a3a..000f9750149f5503b3da33aaf1f36bd9d550ab9d 100644 (file)
@@ -190,7 +190,8 @@ static int usbhsf_pkt_handler(struct usbhs_pipe *pipe, int type)
                goto __usbhs_pkt_handler_end;
        }
 
-       ret = func(pkt, &is_done);
+       if (likely(func))
+               ret = func(pkt, &is_done);
 
        if (is_done)
                __usbhsf_pkt_del(pkt);
@@ -889,6 +890,7 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done)
 
        pkt->trans = len;
 
+       usbhsf_tx_irq_ctrl(pipe, 0);
        INIT_WORK(&pkt->work, xfer_work);
        schedule_work(&pkt->work);
 
index 664b263e4b204cf6ac426d8a1bf179f3b5d68b8f..53d104b56ef17a9d47d29a9d1bcdfac9f8f4e7de 100644 (file)
@@ -158,10 +158,14 @@ static void usbhsg_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt)
        struct usbhs_pipe *pipe = pkt->pipe;
        struct usbhsg_uep *uep = usbhsg_pipe_to_uep(pipe);
        struct usbhsg_request *ureq = usbhsg_pkt_to_ureq(pkt);
+       unsigned long flags;
 
        ureq->req.actual = pkt->actual;
 
-       usbhsg_queue_pop(uep, ureq, 0);
+       usbhs_lock(priv, flags);
+       if (uep)
+               __usbhsg_queue_pop(uep, ureq, 0);
+       usbhs_unlock(priv, flags);
 }
 
 static void usbhsg_queue_push(struct usbhsg_uep *uep,
index b283eb8b86d68f5b53c336ee70bc8a6cd609adce..bbeeb2bd55a83cebf4cfec9b4b8f2876edde1ca0 100644 (file)
@@ -447,6 +447,11 @@ static int cypress_generic_port_probe(struct usb_serial_port *port)
        struct usb_serial *serial = port->serial;
        struct cypress_private *priv;
 
+       if (!port->interrupt_out_urb || !port->interrupt_in_urb) {
+               dev_err(&port->dev, "required endpoint is missing\n");
+               return -ENODEV;
+       }
+
        priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
@@ -606,12 +611,6 @@ static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
                cypress_set_termios(tty, port, &priv->tmp_termios);
 
        /* setup the port and start reading from the device */
-       if (!port->interrupt_in_urb) {
-               dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n",
-                       __func__);
-               return -1;
-       }
-
        usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
                usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
                port->interrupt_in_urb->transfer_buffer,
index 010a42a92688954d7b65a82472d28fad346c80c3..16e8e37b3b36d521749ec48d17b2becfc4ae4f51 100644 (file)
@@ -1251,8 +1251,27 @@ static int digi_port_init(struct usb_serial_port *port, unsigned port_num)
 
 static int digi_startup(struct usb_serial *serial)
 {
+       struct device *dev = &serial->interface->dev;
        struct digi_serial *serial_priv;
        int ret;
+       int i;
+
+       /* check whether the device has the expected number of endpoints */
+       if (serial->num_port_pointers < serial->type->num_ports + 1) {
+               dev_err(dev, "OOB endpoints missing\n");
+               return -ENODEV;
+       }
+
+       for (i = 0; i < serial->type->num_ports + 1 ; i++) {
+               if (!serial->port[i]->read_urb) {
+                       dev_err(dev, "bulk-in endpoint missing\n");
+                       return -ENODEV;
+               }
+               if (!serial->port[i]->write_urb) {
+                       dev_err(dev, "bulk-out endpoint missing\n");
+                       return -ENODEV;
+               }
+       }
 
        serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL);
        if (!serial_priv)
index 4446b8d70ac203cc8b763c38b6b93903cd1a0cb8..885655315de15a4b28db64da22f5d94bea7c8ea9 100644 (file)
@@ -376,14 +376,21 @@ static void mct_u232_msr_to_state(struct usb_serial_port *port,
 
 static int mct_u232_port_probe(struct usb_serial_port *port)
 {
+       struct usb_serial *serial = port->serial;
        struct mct_u232_private *priv;
 
+       /* check first to simplify error handling */
+       if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) {
+               dev_err(&port->dev, "expected endpoint missing\n");
+               return -ENODEV;
+       }
+
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv)
                return -ENOMEM;
 
        /* Use second interrupt-in endpoint for reading. */
-       priv->read_urb = port->serial->port[1]->interrupt_in_urb;
+       priv->read_urb = serial->port[1]->interrupt_in_urb;
        priv->read_urb->context = port;
 
        spin_lock_init(&priv->lock);
index facaaf003f19931b2f15603568bb565f3de40607..e40da7759a0e6cd3a55bccdf90bb10284376ab11 100644 (file)
@@ -741,6 +741,17 @@ int usbip_recv_xbuff(struct usbip_device *ud, struct urb *urb)
        if (!(size > 0))
                return 0;
 
+       if (size > urb->transfer_buffer_length) {
+               /* should not happen, probably malicious packet */
+               if (ud->side == USBIP_STUB) {
+                       usbip_event_add(ud, SDEV_EVENT_ERROR_TCP);
+                       return 0;
+               } else {
+                       usbip_event_add(ud, VDEV_EVENT_ERROR_TCP);
+                       return -EPIPE;
+               }
+       }
+
        ret = usbip_recv(ud->tcp_socket, urb->transfer_buffer, size);
        if (ret != size) {
                dev_err(&urb->dev->dev, "recv xbuf, %d\n", ret);
index 06d6c6228a7a75cfbbd0426d376a441b69597459..d5ce71607972e82f37e7a2aaa83d9fd59c87f919 100644 (file)
@@ -899,7 +899,7 @@ struct usb_ssp_cap_descriptor {
        __le32 bmAttributes;
 #define USB_SSP_SUBLINK_SPEED_ATTRIBS  (0x1f << 0) /* sublink speed entries */
 #define USB_SSP_SUBLINK_SPEED_IDS      (0xf << 5)  /* speed ID entries */
-       __u16  wFunctionalitySupport;
+       __le16  wFunctionalitySupport;
 #define USB_SSP_MIN_SUBLINK_SPEED_ATTRIBUTE_ID (0xf)
 #define USB_SSP_MIN_RX_LANE_COUNT              (0xf << 8)
 #define USB_SSP_MIN_TX_LANE_COUNT              (0xf << 12)