Commit 1abc088a authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are a number of small USB driver fixes for -rc4.

  The usual suspects of gadget, xhci, and dwc2/3 are in here, along with
  some reverts of reported problem changes, and a number of build
  documentation warning fixes. Full details are in the shortlog.

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

* tag 'usb-4.19-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (28 commits)
  Revert "cdc-acm: implement put_char() and flush_chars()"
  usb: Change usb_of_get_companion_dev() place to usb/common
  usb: xhci: fix interrupt transfer error happened on MTK platforms
  usb: cdc-wdm: Fix a sleep-in-atomic-context bug in service_outstanding_interrupt()
  usb: misc: uss720: Fix two sleep-in-atomic-context bugs
  usb: host: u132-hcd: Fix a sleep-in-atomic-context bug in u132_get_frame()
  usb: Avoid use-after-free by flushing endpoints early in usb_set_interface()
  linux/mod_devicetable.h: fix kernel-doc missing notation for typec_device_id
  usb/typec: fix kernel-doc notation warning for typec_match_altmode
  usb: Don't die twice if PCI xhci host is not responding in resume
  usb: mtu3: fix error of xhci port id when enable U3 dual role
  usb: uas: add support for more quirk flags
  USB: Add quirk to support DJI CineSSD
  usb: typec: fix kernel-doc parameter warning
  usb/dwc3/gadget: fix kernel-doc parameter warning
  USB: yurex: Check for truncation in yurex_read()
  USB: yurex: Fix buffer over-read in yurex_write()
  usb: host: xhci-plat: Iterate over parent nodes for finding quirks
  xhci: Fix use after free for URB cancellation on a reallocated endpoint
  USB: add quirk for WORLDE Controller KS49 or Prodipe MIDI 49C USB controller
  ...
parents c284cf06 df3aa13c
Loading
Loading
Loading
Loading
+0 −73
Original line number Diff line number Diff line
@@ -780,20 +780,9 @@ static int acm_tty_write(struct tty_struct *tty,
	}

	if (acm->susp_count) {
		if (acm->putbuffer) {
			/* now to preserve order */
			usb_anchor_urb(acm->putbuffer->urb, &acm->delayed);
			acm->putbuffer = NULL;
		}
		usb_anchor_urb(wb->urb, &acm->delayed);
		spin_unlock_irqrestore(&acm->write_lock, flags);
		return count;
	} else {
		if (acm->putbuffer) {
			/* at this point there is no good way to handle errors */
			acm_start_wb(acm, acm->putbuffer);
			acm->putbuffer = NULL;
		}
	}

	stat = acm_start_wb(acm, wb);
@@ -804,66 +793,6 @@ static int acm_tty_write(struct tty_struct *tty,
	return count;
}

static void acm_tty_flush_chars(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
	struct acm_wb *cur;
	int err;
	unsigned long flags;

	spin_lock_irqsave(&acm->write_lock, flags);

	cur = acm->putbuffer;
	if (!cur) /* nothing to do */
		goto out;

	acm->putbuffer = NULL;
	err = usb_autopm_get_interface_async(acm->control);
	if (err < 0) {
		cur->use = 0;
		acm->putbuffer = cur;
		goto out;
	}

	if (acm->susp_count)
		usb_anchor_urb(cur->urb, &acm->delayed);
	else
		acm_start_wb(acm, cur);
out:
	spin_unlock_irqrestore(&acm->write_lock, flags);
	return;
}

static int acm_tty_put_char(struct tty_struct *tty, unsigned char ch)
{
	struct acm *acm = tty->driver_data;
	struct acm_wb *cur;
	int wbn;
	unsigned long flags;

overflow:
	cur = acm->putbuffer;
	if (!cur) {
		spin_lock_irqsave(&acm->write_lock, flags);
		wbn = acm_wb_alloc(acm);
		if (wbn >= 0) {
			cur = &acm->wb[wbn];
			acm->putbuffer = cur;
		}
		spin_unlock_irqrestore(&acm->write_lock, flags);
		if (!cur)
			return 0;
	}

	if (cur->len == acm->writesize) {
		acm_tty_flush_chars(tty);
		goto overflow;
	}

	cur->buf[cur->len++] = ch;
	return 1;
}

static int acm_tty_write_room(struct tty_struct *tty)
{
	struct acm *acm = tty->driver_data;
@@ -1987,8 +1916,6 @@ static const struct tty_operations acm_ops = {
	.cleanup =		acm_tty_cleanup,
	.hangup =		acm_tty_hangup,
	.write =		acm_tty_write,
	.put_char =		acm_tty_put_char,
	.flush_chars =		acm_tty_flush_chars,
	.write_room =		acm_tty_write_room,
	.ioctl =		acm_tty_ioctl,
	.throttle =		acm_tty_throttle,
+0 −1
Original line number Diff line number Diff line
@@ -96,7 +96,6 @@ struct acm {
	unsigned long read_urbs_free;
	struct urb *read_urbs[ACM_NR];
	struct acm_rb read_buffers[ACM_NR];
	struct acm_wb *putbuffer;			/* for acm_tty_put_char() */
	int rx_buflimit;
	spinlock_t read_lock;
	u8 *notification_buffer;			/* to reassemble fragmented notifications */
+1 −1
Original line number Diff line number Diff line
@@ -460,7 +460,7 @@ static int service_outstanding_interrupt(struct wdm_device *desc)

	set_bit(WDM_RESPONDING, &desc->flags);
	spin_unlock_irq(&desc->iuspin);
	rv = usb_submit_urb(desc->response, GFP_KERNEL);
	rv = usb_submit_urb(desc->response, GFP_ATOMIC);
	spin_lock_irq(&desc->iuspin);
	if (rv) {
		dev_err(&desc->intf->dev,
+25 −0
Original line number Diff line number Diff line
@@ -246,6 +246,31 @@ int of_usb_update_otg_caps(struct device_node *np,
}
EXPORT_SYMBOL_GPL(of_usb_update_otg_caps);

/**
 * usb_of_get_companion_dev - Find the companion device
 * @dev: the device pointer to find a companion
 *
 * Find the companion device from platform bus.
 *
 * Takes a reference to the returned struct device which needs to be dropped
 * after use.
 *
 * Return: On success, a pointer to the companion device, %NULL on failure.
 */
struct device *usb_of_get_companion_dev(struct device *dev)
{
	struct device_node *node;
	struct platform_device *pdev = NULL;

	node = of_parse_phandle(dev->of_node, "companion", 0);
	if (node)
		pdev = of_find_device_by_node(node);

	of_node_put(node);

	return pdev ? &pdev->dev : NULL;
}
EXPORT_SYMBOL_GPL(usb_of_get_companion_dev);
#endif

MODULE_LICENSE("GPL");
+0 −2
Original line number Diff line number Diff line
@@ -515,8 +515,6 @@ static int resume_common(struct device *dev, int event)
				event == PM_EVENT_RESTORE);
		if (retval) {
			dev_err(dev, "PCI post-resume error %d!\n", retval);
			if (hcd->shared_hcd)
				usb_hc_died(hcd->shared_hcd);
			usb_hc_died(hcd);
		}
	}
Loading