Commit 2c01c3d5 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are a handful of small USB driver fixes for 6.10-rc6 to resolve
  some reported issues. Included in here are:

   - typec driver bugfixes

   - usb gadget driver reverts for commits that were reported to have
     problems

   - resource leak bugfix

   - gadget driver bugfixes

   - dwc3 driver bugfixes

   - usb atm driver bugfix for when syzbot got loose on it

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

* tag 'usb-6.10-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  usb: dwc3: core: Workaround for CSR read timeout
  Revert "usb: gadget: u_ether: Replace netif_stop_queue with netif_device_detach"
  Revert "usb: gadget: u_ether: Re-attach netif device to mirror detachment"
  usb: gadget: aspeed_udc: fix device address configuration
  usb: dwc3: core: remove lock of otg mode during gadget suspend/resume to avoid deadlock
  usb: typec: ucsi: glink: fix child node release in probe function
  usb: musb: da8xx: fix a resource leak in probe()
  usb: typec: ucsi_acpi: Add LG Gram quirk
  usb: ucsi: stm32: fix command completion handling
  usb: atm: cxacru: fix endpoint checking in cxacru_bind()
  usb: gadget: printer: fix races against disable
  usb: gadget: printer: SS+ support
parents 3ffea9a7 fc1d1a71
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1131,6 +1131,7 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
	struct cxacru_data *instance;
	struct usb_device *usb_dev = interface_to_usbdev(intf);
	struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD];
	struct usb_endpoint_descriptor *in, *out;
	int ret;

	/* instance init */
@@ -1177,6 +1178,19 @@ static int cxacru_bind(struct usbatm_data *usbatm_instance,
		goto fail;
	}

	if (usb_endpoint_xfer_int(&cmd_ep->desc))
		ret = usb_find_common_endpoints(intf->cur_altsetting,
						NULL, NULL, &in, &out);
	else
		ret = usb_find_common_endpoints(intf->cur_altsetting,
						&in, &out, NULL, NULL);

	if (ret) {
		usb_err(usbatm_instance, "cxacru_bind: interface has incorrect endpoints\n");
		ret = -ENODEV;
		goto fail;
	}

	if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
			== USB_ENDPOINT_XFER_INT) {
		usb_fill_int_urb(instance->rcv_urb,
+19 −7
Original line number Diff line number Diff line
@@ -957,12 +957,16 @@ static bool dwc3_core_is_valid(struct dwc3 *dwc)

static void dwc3_core_setup_global_control(struct dwc3 *dwc)
{
	unsigned int power_opt;
	unsigned int hw_mode;
	u32 reg;

	reg = dwc3_readl(dwc->regs, DWC3_GCTL);
	reg &= ~DWC3_GCTL_SCALEDOWN_MASK;
	hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
	power_opt = DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1);

	switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc->hwparams.hwparams1)) {
	switch (power_opt) {
	case DWC3_GHWPARAMS1_EN_PWROPT_CLK:
		/**
		 * WORKAROUND: DWC3 revisions between 2.10a and 2.50a have an
@@ -995,6 +999,20 @@ static void dwc3_core_setup_global_control(struct dwc3 *dwc)
		break;
	}

	/*
	 * This is a workaround for STAR#4846132, which only affects
	 * DWC_usb31 version2.00a operating in host mode.
	 *
	 * There is a problem in DWC_usb31 version 2.00a operating
	 * in host mode that would cause a CSR read timeout When CSR
	 * read coincides with RAM Clock Gating Entry. By disable
	 * Clock Gating, sacrificing power consumption for normal
	 * operation.
	 */
	if (power_opt != DWC3_GHWPARAMS1_EN_PWROPT_NO &&
	    hw_mode != DWC3_GHWPARAMS0_MODE_GADGET && DWC3_VER_IS(DWC31, 200A))
		reg |= DWC3_GCTL_DSBLCLKGTNG;

	/* check if current dwc3 is on simulation board */
	if (dwc->hwparams.hwparams6 & DWC3_GHWPARAMS6_EN_FPGA) {
		dev_info(dwc->dev, "Running with FPGA optimizations\n");
@@ -2250,7 +2268,6 @@ static int dwc3_core_init_for_resume(struct dwc3 *dwc)

static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
{
	unsigned long	flags;
	u32 reg;
	int i;

@@ -2293,9 +2310,7 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)
			break;

		if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
			spin_lock_irqsave(&dwc->lock, flags);
			dwc3_gadget_suspend(dwc);
			spin_unlock_irqrestore(&dwc->lock, flags);
			synchronize_irq(dwc->irq_gadget);
		}

@@ -2312,7 +2327,6 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg)

static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
{
	unsigned long	flags;
	int		ret;
	u32		reg;
	int		i;
@@ -2366,9 +2380,7 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg)
		if (dwc->current_otg_role == DWC3_OTG_ROLE_HOST) {
			dwc3_otg_host_init(dwc);
		} else if (dwc->current_otg_role == DWC3_OTG_ROLE_DEVICE) {
			spin_lock_irqsave(&dwc->lock, flags);
			dwc3_gadget_resume(dwc);
			spin_unlock_irqrestore(&dwc->lock, flags);
		}

		break;
+30 −10
Original line number Diff line number Diff line
@@ -213,6 +213,7 @@ static inline struct usb_endpoint_descriptor *ep_desc(struct usb_gadget *gadget,
					struct usb_endpoint_descriptor *ss)
{
	switch (gadget->speed) {
	case USB_SPEED_SUPER_PLUS:
	case USB_SPEED_SUPER:
		return ss;
	case USB_SPEED_HIGH:
@@ -449,11 +450,8 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
	mutex_lock(&dev->lock_printer_io);
	spin_lock_irqsave(&dev->lock, flags);

	if (dev->interface < 0) {
		spin_unlock_irqrestore(&dev->lock, flags);
		mutex_unlock(&dev->lock_printer_io);
		return -ENODEV;
	}
	if (dev->interface < 0)
		goto out_disabled;

	/* We will use this flag later to check if a printer reset happened
	 * after we turn interrupts back on.
@@ -461,6 +459,9 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
	dev->reset_printer = 0;

	setup_rx_reqs(dev);
	/* this dropped the lock - need to retest */
	if (dev->interface < 0)
		goto out_disabled;

	bytes_copied = 0;
	current_rx_req = dev->current_rx_req;
@@ -494,6 +495,8 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
		wait_event_interruptible(dev->rx_wait,
				(likely(!list_empty(&dev->rx_buffers))));
		spin_lock_irqsave(&dev->lock, flags);
		if (dev->interface < 0)
			goto out_disabled;
	}

	/* We have data to return then copy it to the caller's buffer.*/
@@ -537,6 +540,9 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
			return -EAGAIN;
		}

		if (dev->interface < 0)
			goto out_disabled;

		/* If we not returning all the data left in this RX request
		 * buffer then adjust the amount of data left in the buffer.
		 * Othewise if we are done with this RX request buffer then
@@ -566,6 +572,11 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
		return bytes_copied;
	else
		return -EAGAIN;

out_disabled:
	spin_unlock_irqrestore(&dev->lock, flags);
	mutex_unlock(&dev->lock_printer_io);
	return -ENODEV;
}

static ssize_t
@@ -586,11 +597,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
	mutex_lock(&dev->lock_printer_io);
	spin_lock_irqsave(&dev->lock, flags);

	if (dev->interface < 0) {
		spin_unlock_irqrestore(&dev->lock, flags);
		mutex_unlock(&dev->lock_printer_io);
		return -ENODEV;
	}
	if (dev->interface < 0)
		goto out_disabled;

	/* Check if a printer reset happens while we have interrupts on */
	dev->reset_printer = 0;
@@ -613,6 +621,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
		wait_event_interruptible(dev->tx_wait,
				(likely(!list_empty(&dev->tx_reqs))));
		spin_lock_irqsave(&dev->lock, flags);
		if (dev->interface < 0)
			goto out_disabled;
	}

	while (likely(!list_empty(&dev->tx_reqs)) && len) {
@@ -662,6 +672,9 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
			return -EAGAIN;
		}

		if (dev->interface < 0)
			goto out_disabled;

		list_add(&req->list, &dev->tx_reqs_active);

		/* here, we unlock, and only unlock, to avoid deadlock. */
@@ -674,6 +687,8 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
			mutex_unlock(&dev->lock_printer_io);
			return -EAGAIN;
		}
		if (dev->interface < 0)
			goto out_disabled;
	}

	spin_unlock_irqrestore(&dev->lock, flags);
@@ -685,6 +700,11 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
		return bytes_copied;
	else
		return -EAGAIN;

out_disabled:
	spin_unlock_irqrestore(&dev->lock, flags);
	mutex_unlock(&dev->lock_printer_io);
	return -ENODEV;
}

static int
+1 −3
Original line number Diff line number Diff line
@@ -1163,8 +1163,6 @@ struct net_device *gether_connect(struct gether *link)
		if (netif_running(dev->net))
			eth_start(dev, GFP_ATOMIC);

		netif_device_attach(dev->net);

	/* on error, disable any endpoints  */
	} else {
		(void) usb_ep_disable(link->out_ep);
@@ -1202,7 +1200,7 @@ void gether_disconnect(struct gether *link)

	DBG(dev, "%s\n", __func__);

	netif_device_detach(dev->net);
	netif_stop_queue(dev->net);
	netif_carrier_off(dev->net);

	/* disable endpoints, forcing (synchronous) completion
+2 −2
Original line number Diff line number Diff line
@@ -66,8 +66,8 @@
#define USB_UPSTREAM_EN			BIT(0)

/* Main config reg */
#define UDC_CFG_SET_ADDR(x)		((x) & 0x3f)
#define UDC_CFG_ADDR_MASK		(0x3f)
#define UDC_CFG_SET_ADDR(x)		((x) & UDC_CFG_ADDR_MASK)
#define UDC_CFG_ADDR_MASK		GENMASK(6, 0)

/* Interrupt ctrl & status reg */
#define UDC_IRQ_EP_POOL_NAK		BIT(17)
Loading