Commit 61c3dae6 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull USB fixes from Greg KH:
 "Here are some small USB gadget, phy, and xhci fixes for 4.8-rc6.

  All of these resolve minor issues that have been reported, and all
  have been in linux-next with no reported issues"

* tag 'usb-4.8-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: chipidea: udc: fix NULL ptr dereference in isr_setup_status_phase
  xhci: fix null pointer dereference in stop command timeout function
  usb: dwc3: pci: fix build warning on !PM_SLEEP
  usb: gadget: prevent potenial null pointer dereference on skb->len
  usb: renesas_usbhs: fix clearing the {BRDY,BEMP}STS condition
  usb: phy: phy-generic: Check clk_prepare_enable() error
  usb: gadget: udc: renesas-usb3: clear VBOUT bit in DRD_CON
  Revert "usb: dwc3: gadget: always decrement by 1"
parents 98ac9a60 6b98174b
...@@ -949,6 +949,15 @@ static int isr_setup_status_phase(struct ci_hdrc *ci) ...@@ -949,6 +949,15 @@ static int isr_setup_status_phase(struct ci_hdrc *ci)
int retval; int retval;
struct ci_hw_ep *hwep; struct ci_hw_ep *hwep;
/*
* Unexpected USB controller behavior, caused by bad signal integrity
* or ground reference problems, can lead to isr_setup_status_phase
* being called with ci->status equal to NULL.
* If this situation occurs, you should review your USB hardware design.
*/
if (WARN_ON_ONCE(!ci->status))
return -EPIPE;
hwep = (ci->ep0_dir == TX) ? ci->ep0out : ci->ep0in; hwep = (ci->ep0_dir == TX) ? ci->ep0out : ci->ep0in;
ci->status->context = ci; ci->status->context = ci;
ci->status->complete = isr_setup_status_complete; ci->status->complete = isr_setup_status_complete;
......
...@@ -249,7 +249,9 @@ static int dwc3_pci_runtime_resume(struct device *dev) ...@@ -249,7 +249,9 @@ static int dwc3_pci_runtime_resume(struct device *dev)
return pm_runtime_get(&dwc3->dev); return pm_runtime_get(&dwc3->dev);
} }
#endif /* CONFIG_PM */
#ifdef CONFIG_PM_SLEEP
static int dwc3_pci_pm_dummy(struct device *dev) static int dwc3_pci_pm_dummy(struct device *dev)
{ {
/* /*
...@@ -262,7 +264,7 @@ static int dwc3_pci_pm_dummy(struct device *dev) ...@@ -262,7 +264,7 @@ static int dwc3_pci_pm_dummy(struct device *dev)
*/ */
return 0; return 0;
} }
#endif /* CONFIG_PM */ #endif /* CONFIG_PM_SLEEP */
static struct dev_pm_ops dwc3_pci_dev_pm_ops = { static struct dev_pm_ops dwc3_pci_dev_pm_ops = {
SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_pm_dummy, dwc3_pci_pm_dummy) SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_pm_dummy, dwc3_pci_pm_dummy)
......
...@@ -884,9 +884,12 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep) ...@@ -884,9 +884,12 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
return DWC3_TRB_NUM - 1; return DWC3_TRB_NUM - 1;
} }
trbs_left = dep->trb_dequeue - dep->trb_enqueue - 1; trbs_left = dep->trb_dequeue - dep->trb_enqueue;
trbs_left &= (DWC3_TRB_NUM - 1); trbs_left &= (DWC3_TRB_NUM - 1);
if (dep->trb_dequeue < dep->trb_enqueue)
trbs_left--;
return trbs_left; return trbs_left;
} }
......
...@@ -342,7 +342,7 @@ static struct sk_buff *eem_wrap(struct gether *port, struct sk_buff *skb) ...@@ -342,7 +342,7 @@ static struct sk_buff *eem_wrap(struct gether *port, struct sk_buff *skb)
struct sk_buff *skb2 = NULL; struct sk_buff *skb2 = NULL;
struct usb_ep *in = port->in_ep; struct usb_ep *in = port->in_ep;
int headroom, tailroom, padlen = 0; int headroom, tailroom, padlen = 0;
u16 len = skb->len; u16 len;
if (!skb) if (!skb)
return NULL; return NULL;
......
...@@ -106,6 +106,7 @@ ...@@ -106,6 +106,7 @@
/* DRD_CON */ /* DRD_CON */
#define DRD_CON_PERI_CON BIT(24) #define DRD_CON_PERI_CON BIT(24)
#define DRD_CON_VBOUT BIT(0)
/* USB_INT_ENA_1 and USB_INT_STA_1 */ /* USB_INT_ENA_1 and USB_INT_STA_1 */
#define USB_INT_1_B3_PLLWKUP BIT(31) #define USB_INT_1_B3_PLLWKUP BIT(31)
...@@ -363,6 +364,7 @@ static void usb3_init_epc_registers(struct renesas_usb3 *usb3) ...@@ -363,6 +364,7 @@ static void usb3_init_epc_registers(struct renesas_usb3 *usb3)
{ {
/* FIXME: How to change host / peripheral mode as well? */ /* FIXME: How to change host / peripheral mode as well? */
usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON); usb3_set_bit(usb3, DRD_CON_PERI_CON, USB3_DRD_CON);
usb3_clear_bit(usb3, DRD_CON_VBOUT, USB3_DRD_CON);
usb3_write(usb3, ~0, USB3_USB_INT_STA_1); usb3_write(usb3, ~0, USB3_USB_INT_STA_1);
usb3_enable_irq_1(usb3, USB_INT_1_VBUS_CNG); usb3_enable_irq_1(usb3, USB_INT_1_VBUS_CNG);
......
...@@ -850,6 +850,10 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) ...@@ -850,6 +850,10 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
spin_lock_irqsave(&xhci->lock, flags); spin_lock_irqsave(&xhci->lock, flags);
ep->stop_cmds_pending--; ep->stop_cmds_pending--;
if (xhci->xhc_state & XHCI_STATE_REMOVING) {
spin_unlock_irqrestore(&xhci->lock, flags);
return;
}
if (xhci->xhc_state & XHCI_STATE_DYING) { if (xhci->xhc_state & XHCI_STATE_DYING) {
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"Stop EP timer ran, but another timer marked " "Stop EP timer ran, but another timer marked "
...@@ -903,7 +907,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg) ...@@ -903,7 +907,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
spin_unlock_irqrestore(&xhci->lock, flags); spin_unlock_irqrestore(&xhci->lock, flags);
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"Calling usb_hc_died()"); "Calling usb_hc_died()");
usb_hc_died(xhci_to_hcd(xhci)->primary_hcd); usb_hc_died(xhci_to_hcd(xhci));
xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
"xHCI host controller is dead."); "xHCI host controller is dead.");
} }
......
...@@ -144,14 +144,18 @@ static irqreturn_t nop_gpio_vbus_thread(int irq, void *data) ...@@ -144,14 +144,18 @@ static irqreturn_t nop_gpio_vbus_thread(int irq, void *data)
int usb_gen_phy_init(struct usb_phy *phy) int usb_gen_phy_init(struct usb_phy *phy)
{ {
struct usb_phy_generic *nop = dev_get_drvdata(phy->dev); struct usb_phy_generic *nop = dev_get_drvdata(phy->dev);
int ret;
if (!IS_ERR(nop->vcc)) { if (!IS_ERR(nop->vcc)) {
if (regulator_enable(nop->vcc)) if (regulator_enable(nop->vcc))
dev_err(phy->dev, "Failed to enable power\n"); dev_err(phy->dev, "Failed to enable power\n");
} }
if (!IS_ERR(nop->clk)) if (!IS_ERR(nop->clk)) {
clk_prepare_enable(nop->clk); ret = clk_prepare_enable(nop->clk);
if (ret)
return ret;
}
nop_reset(nop); nop_reset(nop);
......
...@@ -282,8 +282,15 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) ...@@ -282,8 +282,15 @@ static irqreturn_t usbhs_interrupt(int irq, void *data)
if (usbhs_mod_is_host(priv)) if (usbhs_mod_is_host(priv))
usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);
/*
* The driver should not clear the xxxSTS after the line of
* "call irq callback functions" because each "if" statement is
* possible to call the callback function for avoiding any side effects.
*/
if (irq_state.intsts0 & BRDY)
usbhs_write(priv, BRDYSTS, ~irq_state.brdysts); usbhs_write(priv, BRDYSTS, ~irq_state.brdysts);
usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts); usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts);
if (irq_state.intsts0 & BEMP)
usbhs_write(priv, BEMPSTS, ~irq_state.bempsts); usbhs_write(priv, BEMPSTS, ~irq_state.bempsts);
/* /*
......
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