Commit 6f0306d1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Let's try this again...  Here are some USB fixes for 5.9-rc3.

  This differs from the previous pull request for this release in that
  the usb gadget patch now does not break some systems, and actually
  does what it was intended to do. Many thanks to Marek Szyprowski for
  quickly noticing and testing the patch from Andy Shevchenko to resolve
  this issue.

  Additionally, some more new USB quirks have been added to get some new
  devices to work properly based on user reports.

  Other than that, the patches are all here, and they contain:

   - usb gadget driver fixes

   - xhci driver fixes

   - typec fixes

   - new quirks and ids

   - fixes for USB patches that went into 5.9-rc1.

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

* tag 'usb-5.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (33 commits)
  usb: storage: Add unusual_uas entry for Sony PSZ drives
  USB: Ignore UAS for JMicron JMS567 ATA/ATAPI Bridge
  usb: host: ohci-exynos: Fix error handling in exynos_ohci_probe()
  USB: gadget: u_f: Unbreak offset calculation in VLAs
  USB: quirks: Ignore duplicate endpoint on Sound Devices MixPre-D
  usb: typec: tcpm: Fix Fix source hard reset response for TDA 2.3.1.1 and TDA 2.3.1.2 failures
  USB: PHY: JZ4770: Fix static checker warning.
  USB: gadget: f_ncm: add bounds checks to ncm_unwrap_ntb()
  USB: gadget: u_f: add overflow checks to VLA macros
  xhci: Always restore EP_SOFT_CLEAR_TOGGLE even if ep reset failed
  xhci: Do warm-reset when both CAS and XDEV_RESUME are set
  usb: host: xhci: fix ep context print mismatch in debugfs
  usb: uas: Add quirk for PNY Pro Elite
  tools: usb: move to tools buildsystem
  USB: Fix device driver race
  USB: Also match device drivers using the ->match vfunc
  usb: host: xhci-tegra: fix tegra_xusb_get_phy()
  usb: host: xhci-tegra: otg usb2/usb3 port init
  usb: hcd: Fix use after free in usb_hcd_pci_remove()
  usb: typec: ucsi: Hold con->lock for the entire duration of ucsi_register_port()
  ...
parents 42df60fc 20934c0d
Loading
Loading
Loading
Loading
+10 −12
Original line number Diff line number Diff line
@@ -378,21 +378,19 @@ static void acm_ctrl_irq(struct urb *urb)
	if (current_size < expected_size) {
		/* notification is transmitted fragmented, reassemble */
		if (acm->nb_size < expected_size) {
			if (acm->nb_size) {
				kfree(acm->notification_buffer);
				acm->nb_size = 0;
			}
			u8 *new_buffer;
			alloc_size = roundup_pow_of_two(expected_size);
			/*
			 * kmalloc ensures a valid notification_buffer after a
			 * use of kfree in case the previous allocation was too
			 * small. Final freeing is done on disconnect.
			 */
			acm->notification_buffer =
				kmalloc(alloc_size, GFP_ATOMIC);
			if (!acm->notification_buffer)
			/* Final freeing is done on disconnect. */
			new_buffer = krealloc(acm->notification_buffer,
					      alloc_size, GFP_ATOMIC);
			if (!new_buffer) {
				acm->nb_index = 0;
				goto exit;
			}

			acm->notification_buffer = new_buffer;
			acm->nb_size = alloc_size;
			dr = (struct usb_cdc_notification *)acm->notification_buffer;
		}

		copy_size = min(current_size,
+38 −2
Original line number Diff line number Diff line
@@ -905,6 +905,35 @@ static int usb_uevent(struct device *dev, struct kobj_uevent_env *env)
	return 0;
}

static bool is_dev_usb_generic_driver(struct device *dev)
{
	struct usb_device_driver *udd = dev->driver ?
		to_usb_device_driver(dev->driver) : NULL;

	return udd == &usb_generic_driver;
}

static int __usb_bus_reprobe_drivers(struct device *dev, void *data)
{
	struct usb_device_driver *new_udriver = data;
	struct usb_device *udev;
	int ret;

	if (!is_dev_usb_generic_driver(dev))
		return 0;

	udev = to_usb_device(dev);
	if (usb_device_match_id(udev, new_udriver->id_table) == NULL &&
	    (!new_udriver->match || new_udriver->match(udev) != 0))
		return 0;

	ret = device_reprobe(dev);
	if (ret && ret != -EPROBE_DEFER)
		dev_err(dev, "Failed to reprobe device (error %d)\n", ret);

	return 0;
}

/**
 * usb_register_device_driver - register a USB device (not interface) driver
 * @new_udriver: USB operations for the device driver
@@ -934,13 +963,20 @@ int usb_register_device_driver(struct usb_device_driver *new_udriver,

	retval = driver_register(&new_udriver->drvwrap.driver);

	if (!retval)
	if (!retval) {
		pr_info("%s: registered new device driver %s\n",
			usbcore_name, new_udriver->name);
	else
		/*
		 * Check whether any device could be better served with
		 * this new driver
		 */
		bus_for_each_dev(&usb_bus_type, NULL, new_udriver,
				 __usb_bus_reprobe_drivers);
	} else {
		printk(KERN_ERR "%s: error %d registering device "
			"	driver %s\n",
			usbcore_name, retval, new_udriver->name);
	}

	return retval;
}
+3 −2
Original line number Diff line number Diff line
@@ -205,8 +205,9 @@ static int __check_usb_generic(struct device_driver *drv, void *data)
	udrv = to_usb_device_driver(drv);
	if (udrv == &usb_generic_driver)
		return 0;

	return usb_device_match_id(udev, udrv->id_table) != NULL;
	if (usb_device_match_id(udev, udrv->id_table) != NULL)
		return 1;
	return (udrv->match && udrv->match(udev));
}

static bool usb_generic_driver_match(struct usb_device *udev)
+4 −1
Original line number Diff line number Diff line
@@ -315,11 +315,14 @@ EXPORT_SYMBOL_GPL(usb_hcd_pci_probe);
void usb_hcd_pci_remove(struct pci_dev *dev)
{
	struct usb_hcd		*hcd;
	int			hcd_driver_flags;

	hcd = pci_get_drvdata(dev);
	if (!hcd)
		return;

	hcd_driver_flags = hcd->driver->flags;

	if (pci_dev_run_wake(dev))
		pm_runtime_get_noresume(&dev->dev);

@@ -347,7 +350,7 @@ void usb_hcd_pci_remove(struct pci_dev *dev)
		up_read(&companions_rwsem);
	}
	usb_put_hcd(hcd);
	if ((hcd->driver->flags & HCD_MASK) < HCD_USB3)
	if ((hcd_driver_flags & HCD_MASK) < HCD_USB3)
		pci_free_irq_vectors(dev);
	pci_disable_device(dev);
}
+7 −0
Original line number Diff line number Diff line
@@ -370,6 +370,10 @@ static const struct usb_device_id usb_quirk_list[] = {
	{ USB_DEVICE(0x0926, 0x0202), .driver_info =
			USB_QUIRK_ENDPOINT_IGNORE },

	/* Sound Devices MixPre-D */
	{ USB_DEVICE(0x0926, 0x0208), .driver_info =
			USB_QUIRK_ENDPOINT_IGNORE },

	/* Keytouch QWERTY Panel keyboard */
	{ USB_DEVICE(0x0926, 0x3333), .driver_info =
			USB_QUIRK_CONFIG_INTF_STRINGS },
@@ -465,6 +469,8 @@ static const struct usb_device_id usb_quirk_list[] = {

	{ USB_DEVICE(0x2386, 0x3119), .driver_info = USB_QUIRK_NO_LPM },

	{ USB_DEVICE(0x2386, 0x350e), .driver_info = USB_QUIRK_NO_LPM },

	/* DJI CineSSD */
	{ USB_DEVICE(0x2ca3, 0x0031), .driver_info = USB_QUIRK_NO_LPM },

@@ -509,6 +515,7 @@ static const struct usb_device_id usb_amd_resume_quirk_list[] = {
 */
static const struct usb_device_id usb_endpoint_ignore[] = {
	{ USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0202, 1), .driver_info = 0x85 },
	{ USB_DEVICE_INTERFACE_NUMBER(0x0926, 0x0208, 1), .driver_info = 0x85 },
	{ }
};

Loading