소스 검색

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"
Linus Torvalds 9 년 전
부모
커밋
61c3dae670

+ 9 - 0
drivers/usb/chipidea/udc.c

@@ -949,6 +949,15 @@ static int isr_setup_status_phase(struct ci_hdrc *ci)
 	int retval;
 	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;
 	ci->status->context = ci;
 	ci->status->complete = isr_setup_status_complete;

+ 3 - 1
drivers/usb/dwc3/dwc3-pci.c

@@ -249,7 +249,9 @@ static int dwc3_pci_runtime_resume(struct device *dev)
 
 	return pm_runtime_get(&dwc3->dev);
 }
+#endif /* CONFIG_PM */
 
+#ifdef CONFIG_PM_SLEEP
 static int dwc3_pci_pm_dummy(struct device *dev)
 {
 	/*
@@ -262,7 +264,7 @@ static int dwc3_pci_pm_dummy(struct device *dev)
 	 */
 	return 0;
 }
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
 
 static struct dev_pm_ops dwc3_pci_dev_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(dwc3_pci_pm_dummy, dwc3_pci_pm_dummy)

+ 4 - 1
drivers/usb/dwc3/gadget.c

@@ -884,9 +884,12 @@ static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
 		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);
 
+	if (dep->trb_dequeue < dep->trb_enqueue)
+		trbs_left--;
+
 	return trbs_left;
 }
 

+ 1 - 1
drivers/usb/gadget/function/f_eem.c

@@ -342,7 +342,7 @@ static struct sk_buff *eem_wrap(struct gether *port, struct sk_buff *skb)
 	struct sk_buff	*skb2 = NULL;
 	struct usb_ep	*in = port->in_ep;
 	int		headroom, tailroom, padlen = 0;
-	u16		len = skb->len;
+	u16		len;
 
 	if (!skb)
 		return NULL;

+ 2 - 0
drivers/usb/gadget/udc/renesas_usb3.c

@@ -106,6 +106,7 @@
 
 /* DRD_CON */
 #define DRD_CON_PERI_CON	BIT(24)
+#define DRD_CON_VBOUT		BIT(0)
 
 /* USB_INT_ENA_1 and USB_INT_STA_1 */
 #define USB_INT_1_B3_PLLWKUP	BIT(31)
@@ -363,6 +364,7 @@ static void usb3_init_epc_registers(struct renesas_usb3 *usb3)
 {
 	/* FIXME: How to change host / peripheral mode as well? */
 	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_enable_irq_1(usb3, USB_INT_1_VBUS_CNG);

+ 5 - 1
drivers/usb/host/xhci-ring.c

@@ -850,6 +850,10 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
 	spin_lock_irqsave(&xhci->lock, flags);
 
 	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) {
 		xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
 				"Stop EP timer ran, but another timer marked "
@@ -903,7 +907,7 @@ void xhci_stop_endpoint_command_watchdog(unsigned long arg)
 	spin_unlock_irqrestore(&xhci->lock, flags);
 	xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb,
 			"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 host controller is dead.");
 }

+ 6 - 2
drivers/usb/phy/phy-generic.c

@@ -144,14 +144,18 @@ static irqreturn_t nop_gpio_vbus_thread(int irq, void *data)
 int usb_gen_phy_init(struct usb_phy *phy)
 {
 	struct usb_phy_generic *nop = dev_get_drvdata(phy->dev);
+	int ret;
 
 	if (!IS_ERR(nop->vcc)) {
 		if (regulator_enable(nop->vcc))
 			dev_err(phy->dev, "Failed to enable power\n");
 	}
 
-	if (!IS_ERR(nop->clk))
-		clk_prepare_enable(nop->clk);
+	if (!IS_ERR(nop->clk)) {
+		ret = clk_prepare_enable(nop->clk);
+		if (ret)
+			return ret;
+	}
 
 	nop_reset(nop);
 

+ 9 - 2
drivers/usb/renesas_usbhs/mod.c

@@ -282,9 +282,16 @@ static irqreturn_t usbhs_interrupt(int irq, void *data)
 	if (usbhs_mod_is_host(priv))
 		usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);
 
-	usbhs_write(priv, BRDYSTS, ~irq_state.brdysts);
+	/*
+	 * 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, NRDYSTS, ~irq_state.nrdysts);
-	usbhs_write(priv, BEMPSTS, ~irq_state.bempsts);
+	if (irq_state.intsts0 & BEMP)
+		usbhs_write(priv, BEMPSTS, ~irq_state.bempsts);
 
 	/*
 	 * call irq callback functions