Commit 2b3eb6e3 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'usb-4.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB driver fixes from Greg KH:
 "Here's some USB driver fixes for 4.2-rc3.

  The ususal number of gadget driver fixes are in here, along with some
  new device ids and a build fix for the mn10300 arch which required
  some symbols to be renamed in the mos7720 driver.

  All have been in linux-next for a while with no reported issues"

* tag 'usb-4.2-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  USB: serial: Destroy serial_minors IDR on module exit
  usb: gadget: f_midi: fix error recovery path
  usb: phy: mxs: suspend to RAM causes NULL pointer dereference
  usb: gadget: udc: fix free_irq() after request_irq() failed
  usb: gadget: composite: Fix NULL pointer dereference
  usb: gadget: f_fs: do not set cancel function on synchronous {read,write}
  usb: f_mass_storage: limit number of reported LUNs
  usb: dwc3: core: avoid NULL pointer dereference
  usb: dwc2: embed storage for reg backup in struct dwc2_hsotg
  usb: dwc2: host: allocate qtd before atomic enqueue
  usb: dwc2: host: allocate qh before atomic enqueue
  usb: musb: host: rely on port_mode to call musb_start()
  USB: cp210x: add ID for Aruba Networks controllers
  USB: mos7720: rename registers
  USB: option: add 2020:4000 ID
parents 1ea2a01c 51f007e1
...@@ -72,17 +72,7 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) ...@@ -72,17 +72,7 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
dev_dbg(hsotg->dev, "%s\n", __func__); dev_dbg(hsotg->dev, "%s\n", __func__);
/* Backup Host regs */ /* Backup Host regs */
hr = hsotg->hr_backup; hr = &hsotg->hr_backup;
if (!hr) {
hr = devm_kzalloc(hsotg->dev, sizeof(*hr), GFP_KERNEL);
if (!hr) {
dev_err(hsotg->dev, "%s: can't allocate host regs\n",
__func__);
return -ENOMEM;
}
hsotg->hr_backup = hr;
}
hr->hcfg = readl(hsotg->regs + HCFG); hr->hcfg = readl(hsotg->regs + HCFG);
hr->haintmsk = readl(hsotg->regs + HAINTMSK); hr->haintmsk = readl(hsotg->regs + HAINTMSK);
for (i = 0; i < hsotg->core_params->host_channels; ++i) for (i = 0; i < hsotg->core_params->host_channels; ++i)
...@@ -90,6 +80,7 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg) ...@@ -90,6 +80,7 @@ static int dwc2_backup_host_registers(struct dwc2_hsotg *hsotg)
hr->hprt0 = readl(hsotg->regs + HPRT0); hr->hprt0 = readl(hsotg->regs + HPRT0);
hr->hfir = readl(hsotg->regs + HFIR); hr->hfir = readl(hsotg->regs + HFIR);
hr->valid = true;
return 0; return 0;
} }
...@@ -109,12 +100,13 @@ static int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg) ...@@ -109,12 +100,13 @@ static int dwc2_restore_host_registers(struct dwc2_hsotg *hsotg)
dev_dbg(hsotg->dev, "%s\n", __func__); dev_dbg(hsotg->dev, "%s\n", __func__);
/* Restore host regs */ /* Restore host regs */
hr = hsotg->hr_backup; hr = &hsotg->hr_backup;
if (!hr) { if (!hr->valid) {
dev_err(hsotg->dev, "%s: no host registers to restore\n", dev_err(hsotg->dev, "%s: no host registers to restore\n",
__func__); __func__);
return -EINVAL; return -EINVAL;
} }
hr->valid = false;
writel(hr->hcfg, hsotg->regs + HCFG); writel(hr->hcfg, hsotg->regs + HCFG);
writel(hr->haintmsk, hsotg->regs + HAINTMSK); writel(hr->haintmsk, hsotg->regs + HAINTMSK);
...@@ -152,17 +144,7 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) ...@@ -152,17 +144,7 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
dev_dbg(hsotg->dev, "%s\n", __func__); dev_dbg(hsotg->dev, "%s\n", __func__);
/* Backup dev regs */ /* Backup dev regs */
dr = hsotg->dr_backup; dr = &hsotg->dr_backup;
if (!dr) {
dr = devm_kzalloc(hsotg->dev, sizeof(*dr), GFP_KERNEL);
if (!dr) {
dev_err(hsotg->dev, "%s: can't allocate device regs\n",
__func__);
return -ENOMEM;
}
hsotg->dr_backup = dr;
}
dr->dcfg = readl(hsotg->regs + DCFG); dr->dcfg = readl(hsotg->regs + DCFG);
dr->dctl = readl(hsotg->regs + DCTL); dr->dctl = readl(hsotg->regs + DCTL);
...@@ -195,7 +177,7 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg) ...@@ -195,7 +177,7 @@ static int dwc2_backup_device_registers(struct dwc2_hsotg *hsotg)
dr->doeptsiz[i] = readl(hsotg->regs + DOEPTSIZ(i)); dr->doeptsiz[i] = readl(hsotg->regs + DOEPTSIZ(i));
dr->doepdma[i] = readl(hsotg->regs + DOEPDMA(i)); dr->doepdma[i] = readl(hsotg->regs + DOEPDMA(i));
} }
dr->valid = true;
return 0; return 0;
} }
...@@ -215,12 +197,13 @@ static int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg) ...@@ -215,12 +197,13 @@ static int dwc2_restore_device_registers(struct dwc2_hsotg *hsotg)
dev_dbg(hsotg->dev, "%s\n", __func__); dev_dbg(hsotg->dev, "%s\n", __func__);
/* Restore dev regs */ /* Restore dev regs */
dr = hsotg->dr_backup; dr = &hsotg->dr_backup;
if (!dr) { if (!dr->valid) {
dev_err(hsotg->dev, "%s: no device registers to restore\n", dev_err(hsotg->dev, "%s: no device registers to restore\n",
__func__); __func__);
return -EINVAL; return -EINVAL;
} }
dr->valid = false;
writel(dr->dcfg, hsotg->regs + DCFG); writel(dr->dcfg, hsotg->regs + DCFG);
writel(dr->dctl, hsotg->regs + DCTL); writel(dr->dctl, hsotg->regs + DCTL);
...@@ -268,17 +251,7 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg) ...@@ -268,17 +251,7 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg)
int i; int i;
/* Backup global regs */ /* Backup global regs */
gr = hsotg->gr_backup; gr = &hsotg->gr_backup;
if (!gr) {
gr = devm_kzalloc(hsotg->dev, sizeof(*gr), GFP_KERNEL);
if (!gr) {
dev_err(hsotg->dev, "%s: can't allocate global regs\n",
__func__);
return -ENOMEM;
}
hsotg->gr_backup = gr;
}
gr->gotgctl = readl(hsotg->regs + GOTGCTL); gr->gotgctl = readl(hsotg->regs + GOTGCTL);
gr->gintmsk = readl(hsotg->regs + GINTMSK); gr->gintmsk = readl(hsotg->regs + GINTMSK);
...@@ -291,6 +264,7 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg) ...@@ -291,6 +264,7 @@ static int dwc2_backup_global_registers(struct dwc2_hsotg *hsotg)
for (i = 0; i < MAX_EPS_CHANNELS; i++) for (i = 0; i < MAX_EPS_CHANNELS; i++)
gr->dtxfsiz[i] = readl(hsotg->regs + DPTXFSIZN(i)); gr->dtxfsiz[i] = readl(hsotg->regs + DPTXFSIZN(i));
gr->valid = true;
return 0; return 0;
} }
...@@ -309,12 +283,13 @@ static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg) ...@@ -309,12 +283,13 @@ static int dwc2_restore_global_registers(struct dwc2_hsotg *hsotg)
dev_dbg(hsotg->dev, "%s\n", __func__); dev_dbg(hsotg->dev, "%s\n", __func__);
/* Restore global regs */ /* Restore global regs */
gr = hsotg->gr_backup; gr = &hsotg->gr_backup;
if (!gr) { if (!gr->valid) {
dev_err(hsotg->dev, "%s: no global registers to restore\n", dev_err(hsotg->dev, "%s: no global registers to restore\n",
__func__); __func__);
return -EINVAL; return -EINVAL;
} }
gr->valid = false;
writel(0xffffffff, hsotg->regs + GINTSTS); writel(0xffffffff, hsotg->regs + GINTSTS);
writel(gr->gotgctl, hsotg->regs + GOTGCTL); writel(gr->gotgctl, hsotg->regs + GOTGCTL);
......
...@@ -492,6 +492,7 @@ struct dwc2_gregs_backup { ...@@ -492,6 +492,7 @@ struct dwc2_gregs_backup {
u32 gdfifocfg; u32 gdfifocfg;
u32 dtxfsiz[MAX_EPS_CHANNELS]; u32 dtxfsiz[MAX_EPS_CHANNELS];
u32 gpwrdn; u32 gpwrdn;
bool valid;
}; };
/** /**
...@@ -521,6 +522,7 @@ struct dwc2_dregs_backup { ...@@ -521,6 +522,7 @@ struct dwc2_dregs_backup {
u32 doepctl[MAX_EPS_CHANNELS]; u32 doepctl[MAX_EPS_CHANNELS];
u32 doeptsiz[MAX_EPS_CHANNELS]; u32 doeptsiz[MAX_EPS_CHANNELS];
u32 doepdma[MAX_EPS_CHANNELS]; u32 doepdma[MAX_EPS_CHANNELS];
bool valid;
}; };
/** /**
...@@ -538,6 +540,7 @@ struct dwc2_hregs_backup { ...@@ -538,6 +540,7 @@ struct dwc2_hregs_backup {
u32 hcintmsk[MAX_EPS_CHANNELS]; u32 hcintmsk[MAX_EPS_CHANNELS];
u32 hprt0; u32 hprt0;
u32 hfir; u32 hfir;
bool valid;
}; };
/** /**
...@@ -705,9 +708,9 @@ struct dwc2_hsotg { ...@@ -705,9 +708,9 @@ struct dwc2_hsotg {
struct work_struct wf_otg; struct work_struct wf_otg;
struct timer_list wkp_timer; struct timer_list wkp_timer;
enum dwc2_lx_state lx_state; enum dwc2_lx_state lx_state;
struct dwc2_gregs_backup *gr_backup; struct dwc2_gregs_backup gr_backup;
struct dwc2_dregs_backup *dr_backup; struct dwc2_dregs_backup dr_backup;
struct dwc2_hregs_backup *hr_backup; struct dwc2_hregs_backup hr_backup;
struct dentry *debug_root; struct dentry *debug_root;
struct debugfs_regset32 *regset; struct debugfs_regset32 *regset;
......
...@@ -359,10 +359,9 @@ void dwc2_hcd_stop(struct dwc2_hsotg *hsotg) ...@@ -359,10 +359,9 @@ void dwc2_hcd_stop(struct dwc2_hsotg *hsotg)
/* Caller must hold driver lock */ /* Caller must hold driver lock */
static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
struct dwc2_hcd_urb *urb, void **ep_handle, struct dwc2_hcd_urb *urb, struct dwc2_qh *qh,
gfp_t mem_flags) struct dwc2_qtd *qtd)
{ {
struct dwc2_qtd *qtd;
u32 intr_mask; u32 intr_mask;
int retval; int retval;
int dev_speed; int dev_speed;
...@@ -386,18 +385,15 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg, ...@@ -386,18 +385,15 @@ static int dwc2_hcd_urb_enqueue(struct dwc2_hsotg *hsotg,
return -ENODEV; return -ENODEV;
} }
qtd = kzalloc(sizeof(*qtd), mem_flags);
if (!qtd) if (!qtd)
return -ENOMEM; return -EINVAL;
dwc2_hcd_qtd_init(qtd, urb); dwc2_hcd_qtd_init(qtd, urb);
retval = dwc2_hcd_qtd_add(hsotg, qtd, (struct dwc2_qh **)ep_handle, retval = dwc2_hcd_qtd_add(hsotg, qtd, qh);
mem_flags);
if (retval) { if (retval) {
dev_err(hsotg->dev, dev_err(hsotg->dev,
"DWC OTG HCD URB Enqueue failed adding QTD. Error status %d\n", "DWC OTG HCD URB Enqueue failed adding QTD. Error status %d\n",
retval); retval);
kfree(qtd);
return retval; return retval;
} }
...@@ -2445,6 +2441,9 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, ...@@ -2445,6 +2441,9 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
u32 tflags = 0; u32 tflags = 0;
void *buf; void *buf;
unsigned long flags; unsigned long flags;
struct dwc2_qh *qh;
bool qh_allocated = false;
struct dwc2_qtd *qtd;
if (dbg_urb(urb)) { if (dbg_urb(urb)) {
dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n"); dev_vdbg(hsotg->dev, "DWC OTG HCD URB Enqueue\n");
...@@ -2523,15 +2522,32 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, ...@@ -2523,15 +2522,32 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
urb->iso_frame_desc[i].length); urb->iso_frame_desc[i].length);
urb->hcpriv = dwc2_urb; urb->hcpriv = dwc2_urb;
qh = (struct dwc2_qh *) ep->hcpriv;
/* Create QH for the endpoint if it doesn't exist */
if (!qh) {
qh = dwc2_hcd_qh_create(hsotg, dwc2_urb, mem_flags);
if (!qh) {
retval = -ENOMEM;
goto fail0;
}
ep->hcpriv = qh;
qh_allocated = true;
}
qtd = kzalloc(sizeof(*qtd), mem_flags);
if (!qtd) {
retval = -ENOMEM;
goto fail1;
}
spin_lock_irqsave(&hsotg->lock, flags); spin_lock_irqsave(&hsotg->lock, flags);
retval = usb_hcd_link_urb_to_ep(hcd, urb); retval = usb_hcd_link_urb_to_ep(hcd, urb);
if (retval) if (retval)
goto fail1; goto fail2;
retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, &ep->hcpriv, mem_flags); retval = dwc2_hcd_urb_enqueue(hsotg, dwc2_urb, qh, qtd);
if (retval) if (retval)
goto fail2; goto fail3;
if (alloc_bandwidth) { if (alloc_bandwidth) {
dwc2_allocate_bus_bandwidth(hcd, dwc2_allocate_bus_bandwidth(hcd,
...@@ -2543,12 +2559,25 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, ...@@ -2543,12 +2559,25 @@ static int _dwc2_hcd_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
return 0; return 0;
fail2: fail3:
dwc2_urb->priv = NULL; dwc2_urb->priv = NULL;
usb_hcd_unlink_urb_from_ep(hcd, urb); usb_hcd_unlink_urb_from_ep(hcd, urb);
fail1: fail2:
spin_unlock_irqrestore(&hsotg->lock, flags); spin_unlock_irqrestore(&hsotg->lock, flags);
urb->hcpriv = NULL; urb->hcpriv = NULL;
kfree(qtd);
fail1:
if (qh_allocated) {
struct dwc2_qtd *qtd2, *qtd2_tmp;
ep->hcpriv = NULL;
dwc2_hcd_qh_unlink(hsotg, qh);
/* Free each QTD in the QH's QTD list */
list_for_each_entry_safe(qtd2, qtd2_tmp, &qh->qtd_list,
qtd_list_entry)
dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh);
dwc2_hcd_qh_free(hsotg, qh);
}
fail0: fail0:
kfree(dwc2_urb); kfree(dwc2_urb);
......
...@@ -463,6 +463,9 @@ extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg, ...@@ -463,6 +463,9 @@ extern void dwc2_hcd_queue_transactions(struct dwc2_hsotg *hsotg,
/* Schedule Queue Functions */ /* Schedule Queue Functions */
/* Implemented in hcd_queue.c */ /* Implemented in hcd_queue.c */
extern void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg); extern void dwc2_hcd_init_usecs(struct dwc2_hsotg *hsotg);
extern struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
struct dwc2_hcd_urb *urb,
gfp_t mem_flags);
extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); extern void dwc2_hcd_qh_free(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); extern int dwc2_hcd_qh_add(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh); extern void dwc2_hcd_qh_unlink(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh);
...@@ -471,7 +474,7 @@ extern void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, ...@@ -471,7 +474,7 @@ extern void dwc2_hcd_qh_deactivate(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb); extern void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb);
extern int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, extern int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
struct dwc2_qh **qh, gfp_t mem_flags); struct dwc2_qh *qh);
/* Unlinks and frees a QTD */ /* Unlinks and frees a QTD */
static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg, static inline void dwc2_hcd_qtd_unlink_and_free(struct dwc2_hsotg *hsotg,
......
...@@ -191,7 +191,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh, ...@@ -191,7 +191,7 @@ static void dwc2_qh_init(struct dwc2_hsotg *hsotg, struct dwc2_qh *qh,
* *
* Return: Pointer to the newly allocated QH, or NULL on error * Return: Pointer to the newly allocated QH, or NULL on error
*/ */
static struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg, struct dwc2_qh *dwc2_hcd_qh_create(struct dwc2_hsotg *hsotg,
struct dwc2_hcd_urb *urb, struct dwc2_hcd_urb *urb,
gfp_t mem_flags) gfp_t mem_flags)
{ {
...@@ -767,57 +767,32 @@ void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb) ...@@ -767,57 +767,32 @@ void dwc2_hcd_qtd_init(struct dwc2_qtd *qtd, struct dwc2_hcd_urb *urb)
* *
* @hsotg: The DWC HCD structure * @hsotg: The DWC HCD structure
* @qtd: The QTD to add * @qtd: The QTD to add
* @qh: Out parameter to return queue head * @qh: Queue head to add qtd to
* @atomic_alloc: Flag to do atomic alloc if needed
* *
* Return: 0 if successful, negative error code otherwise * Return: 0 if successful, negative error code otherwise
* *
* Finds the correct QH to place the QTD into. If it does not find a QH, it * If the QH to which the QTD is added is not currently scheduled, it is placed
* will create a new QH. If the QH to which the QTD is added is not currently * into the proper schedule based on its EP type.
* scheduled, it is placed into the proper schedule based on its EP type.
*/ */
int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd, int dwc2_hcd_qtd_add(struct dwc2_hsotg *hsotg, struct dwc2_qtd *qtd,
struct dwc2_qh **qh, gfp_t mem_flags) struct dwc2_qh *qh)
{ {
struct dwc2_hcd_urb *urb = qtd->urb;
int allocated = 0;
int retval; int retval;
/* if (unlikely(!qh)) {
* Get the QH which holds the QTD-list to insert to. Create QH if it dev_err(hsotg->dev, "%s: Invalid QH\n", __func__);
* doesn't exist. retval = -EINVAL;
*/ goto fail;
if (*qh == NULL) {
*qh = dwc2_hcd_qh_create(hsotg, urb, mem_flags);
if (*qh == NULL)
return -ENOMEM;
allocated = 1;
} }
retval = dwc2_hcd_qh_add(hsotg, *qh); retval = dwc2_hcd_qh_add(hsotg, qh);
if (retval) if (retval)
goto fail; goto fail;
qtd->qh = *qh; qtd->qh = qh;
list_add_tail(&qtd->qtd_list_entry, &(*qh)->qtd_list); list_add_tail(&qtd->qtd_list_entry, &qh->qtd_list);
return 0; return 0;
fail: fail:
if (allocated) {
struct dwc2_qtd *qtd2, *qtd2_tmp;
struct dwc2_qh *qh_tmp = *qh;
*qh = NULL;
dwc2_hcd_qh_unlink(hsotg, qh_tmp);
/* Free each QTD in the QH's QTD list */
list_for_each_entry_safe(qtd2, qtd2_tmp, &qh_tmp->qtd_list,
qtd_list_entry)
dwc2_hcd_qtd_unlink_and_free(hsotg, qtd2, qh_tmp);
dwc2_hcd_qh_free(hsotg, qh_tmp);
}
return retval; return retval;
} }
...@@ -446,10 +446,12 @@ static int dwc3_phy_setup(struct dwc3 *dwc) ...@@ -446,10 +446,12 @@ static int dwc3_phy_setup(struct dwc3 *dwc)
/* Select the HS PHY interface */ /* Select the HS PHY interface */
switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) { switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI: case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
if (!strncmp(dwc->hsphy_interface, "utmi", 4)) { if (dwc->hsphy_interface &&
!strncmp(dwc->hsphy_interface, "utmi", 4)) {
reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI; reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
break; break;
} else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) { } else if (dwc->hsphy_interface &&
!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI; reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg); dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
} else { } else {
......
...@@ -1758,10 +1758,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) ...@@ -1758,10 +1758,13 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
* take such requests too, if that's ever needed: to work * take such requests too, if that's ever needed: to work
* in config 0, etc. * in config 0, etc.
*/ */
if (cdev->config) {
list_for_each_entry(f, &cdev->config->functions, list) list_for_each_entry(f, &cdev->config->functions, list)
if (f->req_match && f->req_match(f, ctrl)) if (f->req_match && f->req_match(f, ctrl))
goto try_fun_setup; goto try_fun_setup;
f = NULL; f = NULL;
}
switch (ctrl->bRequestType & USB_RECIP_MASK) { switch (ctrl->bRequestType & USB_RECIP_MASK) {
case USB_RECIP_INTERFACE: case USB_RECIP_INTERFACE:
if (!cdev->config || intf >= MAX_CONFIG_INTERFACES) if (!cdev->config || intf >= MAX_CONFIG_INTERFACES)
......
...@@ -924,6 +924,7 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from) ...@@ -924,6 +924,7 @@ static ssize_t ffs_epfile_write_iter(struct kiocb *kiocb, struct iov_iter *from)
kiocb->private = p; kiocb->private = p;
if (p->aio)
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
res = ffs_epfile_io(kiocb->ki_filp, p); res = ffs_epfile_io(kiocb->ki_filp, p);
...@@ -968,6 +969,7 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to) ...@@ -968,6 +969,7 @@ static ssize_t ffs_epfile_read_iter(struct kiocb *kiocb, struct iov_iter *to)
kiocb->private = p; kiocb->private = p;
if (p->aio)
kiocb_set_cancel_fn(kiocb, ffs_aio_cancel); kiocb_set_cancel_fn(kiocb, ffs_aio_cancel);
res = ffs_epfile_io(kiocb->ki_filp, p); res = ffs_epfile_io(kiocb->ki_filp, p);
......
...@@ -2786,7 +2786,7 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns) ...@@ -2786,7 +2786,7 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
return -EINVAL; return -EINVAL;
} }
curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL); curlun = kcalloc(FSG_MAX_LUNS, sizeof(*curlun), GFP_KERNEL);
if (unlikely(!curlun)) if (unlikely(!curlun))
return -ENOMEM; return -ENOMEM;
...@@ -2796,8 +2796,6 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns) ...@@ -2796,8 +2796,6 @@ int fsg_common_set_nluns(struct fsg_common *common, int nluns)
common->luns = curlun; common->luns = curlun;
common->nluns = nluns; common->nluns = nluns;
pr_info("Number of LUNs=%d\n", common->nluns);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(fsg_common_set_nluns); EXPORT_SYMBOL_GPL(fsg_common_set_nluns);
...@@ -3563,14 +3561,26 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi) ...@@ -3563,14 +3561,26 @@ static struct usb_function *fsg_alloc(struct usb_function_instance *fi)
struct fsg_opts *opts = fsg_opts_from_func_inst(fi); struct fsg_opts *opts = fsg_opts_from_func_inst(fi);
struct fsg_common *common = opts->common; struct fsg_common *common = opts->common;
struct fsg_dev *fsg; struct fsg_dev *fsg;
unsigned nluns, i;
fsg = kzalloc(sizeof(*fsg), GFP_KERNEL); fsg = kzalloc(sizeof(*fsg), GFP_KERNEL);
if (unlikely(!fsg)) if (unlikely(!fsg))
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
mutex_lock(&opts->lock); mutex_lock(&opts->lock);
if (!opts->refcnt) {
for (nluns = i = 0; i < FSG_MAX_LUNS; ++i)
if (common->luns[i])
nluns = i + 1;
if (!nluns)
pr_warn("No LUNS defined, continuing anyway\n");
else
common->nluns = nluns;
pr_info("Number of LUNs=%u\n", common->nluns);
}
opts->refcnt++; opts->refcnt++;
mutex_unlock(&opts->lock); mutex_unlock(&opts->lock);
fsg->function.name = FSG_DRIVER_DESC; fsg->function.name = FSG_DRIVER_DESC;
fsg->function.bind = fsg_bind; fsg->function.bind = fsg_bind;
fsg->function.unbind = fsg_unbind; fsg->function.unbind = fsg_unbind;
......
...@@ -1145,7 +1145,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) ...@@ -1145,7 +1145,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
if (opts->id && !midi->id) { if (opts->id && !midi->id) {
status = -ENOMEM; status = -ENOMEM;
mutex_unlock(&opts->lock); mutex_unlock(&opts->lock);
goto kstrdup_fail; goto setup_fail;
} }
midi->in_ports = opts->in_ports; midi->in_ports = opts->in_ports;
midi->out_ports = opts->out_ports; midi->out_ports = opts->out_ports;
...@@ -1164,8 +1164,6 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) ...@@ -1164,8 +1164,6 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
return &midi->func; return &midi->func;
kstrdup_fail:
f_midi_unregister_card(midi);
setup_fail: setup_fail:
for (--i; i >= 0; i--) for (--i; i >= 0; i--)
kfree(midi->in_port[i]); kfree(midi->in_port[i]);
......
...@@ -1171,7 +1171,7 @@ static int fotg210_udc_probe(struct platform_device *pdev) ...@@ -1171,7 +1171,7 @@ static int fotg210_udc_probe(struct platform_device *pdev)
udc_name, fotg210); udc_name, fotg210);
if (ret < 0) { if (ret < 0) {
pr_err("request_irq error (%d)\n", ret); pr_err("request_irq error (%d)\n", ret);
goto err_irq; goto err_req;
} }
ret = usb_add_gadget_udc(&pdev->dev, &fotg210->gadget); ret = usb_add_gadget_udc(&pdev->dev, &fotg210->gadget);
...@@ -1183,7 +1183,6 @@ static int fotg210_udc_probe(struct platform_device *pdev) ...@@ -1183,7 +1183,6 @@ static int fotg210_udc_probe(struct platform_device *pdev)
return 0; return 0;
err_add_udc: err_add_udc:
err_irq:
free_irq(ires->start, fotg210); free_irq(ires->start, fotg210);
err_req: err_req:
......
...@@ -275,9 +275,7 @@ static int musb_has_gadget(struct musb *musb) ...@@ -275,9 +275,7 @@ static int musb_has_gadget(struct musb *musb)
#ifdef CONFIG_USB_MUSB_HOST #ifdef CONFIG_USB_MUSB_HOST
return 1; return 1;
#else #else
if (musb->port_mode == MUSB_PORT_MODE_HOST) return musb->port_mode == MUSB_PORT_MODE_HOST;
return 1;
return musb->g.dev.driver != NULL;
#endif #endif
} }
......
...@@ -217,6 +217,9 @@ static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy) ...@@ -217,6 +217,9 @@ static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy)
{ {
unsigned int vbus_value; unsigned int vbus_value;
if (!mxs_phy->regmap_anatop)
return false;
if (mxs_phy->port_id == 0) if (mxs_phy->port_id == 0)
regmap_read(mxs_phy->regmap_anatop, regmap_read(mxs_phy->regmap_anatop,
ANADIG_USB1_VBUS_DET_STAT, ANADIG_USB1_VBUS_DET_STAT,
......
...@@ -187,6 +187,7 @@ static const struct usb_device_id id_table[] = { ...@@ -187,6 +187,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */ { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */
{ USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */ { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */
{ USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */ { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */
{ USB_DEVICE(0x2626, 0xEA60) }, /* Aruba Networks 7xxx USB Serial Console */
{ USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */
{ USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */
{ USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */
......
This diff is collapsed.
...@@ -1765,6 +1765,7 @@ static const struct usb_device_id option_ids[] = { ...@@ -1765,6 +1765,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */
{ USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */
{ USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) }, { USB_DEVICE(INOVIA_VENDOR_ID, INOVIA_SEW858) },
{ USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) }, { USB_DEVICE(VIATELECOM_VENDOR_ID, VIATELECOM_PRODUCT_CDS7) },
{ } /* Terminating entry */ { } /* Terminating entry */
......
...@@ -1306,6 +1306,7 @@ static void __exit usb_serial_exit(void) ...@@ -1306,6 +1306,7 @@ static void __exit usb_serial_exit(void)
tty_unregister_driver(usb_serial_tty_driver); tty_unregister_driver(usb_serial_tty_driver);
put_tty_driver(usb_serial_tty_driver); put_tty_driver(usb_serial_tty_driver);
bus_unregister(&usb_serial_bus_type); bus_unregister(&usb_serial_bus_type);
idr_destroy(&serial_minors);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment