Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19ea9d66 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull USB fixes from Greg KH:
 "Here are some small gadget and xhci USB fixes for 4.12-rc6.

  Nothing major, but one of the gadget patches does fix a reported oops,
  and the xhci ones resolve reported problems. All have been in
  linux-next with no reported issues"

* tag 'usb-4.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb:
  USB: gadgetfs, dummy-hcd, net2280: fix locking for callbacks
  usb: xhci: ASMedia ASM1042A chipset need shorts TX quirk
  usb: xhci: Fix USB 3.1 supported protocol parsing
  USB: gadget: fix GPF in gadgetfs
  usb: gadget: composite: make sure to reactivate function on unbind
parents 1be627df f16443a0
Loading
Loading
Loading
Loading
+5 −6
Original line number Original line Diff line number Diff line
@@ -315,6 +315,9 @@ void usb_remove_function(struct usb_configuration *c, struct usb_function *f)
	list_del(&f->list);
	list_del(&f->list);
	if (f->unbind)
	if (f->unbind)
		f->unbind(c, f);
		f->unbind(c, f);

	if (f->bind_deactivated)
		usb_function_activate(f);
}
}
EXPORT_SYMBOL_GPL(usb_remove_function);
EXPORT_SYMBOL_GPL(usb_remove_function);


@@ -956,12 +959,8 @@ static void remove_config(struct usb_composite_dev *cdev,


		f = list_first_entry(&config->functions,
		f = list_first_entry(&config->functions,
				struct usb_function, list);
				struct usb_function, list);
		list_del(&f->list);

		if (f->unbind) {
		usb_remove_function(config, f);
			DBG(cdev, "unbind function '%s'/%p\n", f->name, f);
			f->unbind(config, f);
			/* may free memory for "f" */
		}
	}
	}
	list_del(&config->list);
	list_del(&config->list);
	if (config->unbind) {
	if (config->unbind) {
+6 −3
Original line number Original line Diff line number Diff line
@@ -1183,8 +1183,10 @@ dev_release (struct inode *inode, struct file *fd)


	/* closing ep0 === shutdown all */
	/* closing ep0 === shutdown all */


	if (dev->gadget_registered)
	if (dev->gadget_registered) {
		usb_gadget_unregister_driver (&gadgetfs_driver);
		usb_gadget_unregister_driver (&gadgetfs_driver);
		dev->gadget_registered = false;
	}


	/* at this point "good" hardware has disconnected the
	/* at this point "good" hardware has disconnected the
	 * device from USB; the host won't see it any more.
	 * device from USB; the host won't see it any more.
@@ -1677,9 +1679,10 @@ static void
gadgetfs_suspend (struct usb_gadget *gadget)
gadgetfs_suspend (struct usb_gadget *gadget)
{
{
	struct dev_data		*dev = get_gadget_data (gadget);
	struct dev_data		*dev = get_gadget_data (gadget);
	unsigned long		flags;


	INFO (dev, "suspended from state %d\n", dev->state);
	INFO (dev, "suspended from state %d\n", dev->state);
	spin_lock (&dev->lock);
	spin_lock_irqsave(&dev->lock, flags);
	switch (dev->state) {
	switch (dev->state) {
	case STATE_DEV_SETUP:		// VERY odd... host died??
	case STATE_DEV_SETUP:		// VERY odd... host died??
	case STATE_DEV_CONNECTED:
	case STATE_DEV_CONNECTED:
@@ -1690,7 +1693,7 @@ gadgetfs_suspend (struct usb_gadget *gadget)
	default:
	default:
		break;
		break;
	}
	}
	spin_unlock (&dev->lock);
	spin_unlock_irqrestore(&dev->lock, flags);
}
}


static struct usb_gadget_driver gadgetfs_driver = {
static struct usb_gadget_driver gadgetfs_driver = {
+4 −9
Original line number Original line Diff line number Diff line
@@ -442,23 +442,16 @@ static void set_link_state(struct dummy_hcd *dum_hcd)
		/* Report reset and disconnect events to the driver */
		/* Report reset and disconnect events to the driver */
		if (dum->driver && (disconnect || reset)) {
		if (dum->driver && (disconnect || reset)) {
			stop_activity(dum);
			stop_activity(dum);
			spin_unlock(&dum->lock);
			if (reset)
			if (reset)
				usb_gadget_udc_reset(&dum->gadget, dum->driver);
				usb_gadget_udc_reset(&dum->gadget, dum->driver);
			else
			else
				dum->driver->disconnect(&dum->gadget);
				dum->driver->disconnect(&dum->gadget);
			spin_lock(&dum->lock);
		}
		}
	} else if (dum_hcd->active != dum_hcd->old_active) {
	} else if (dum_hcd->active != dum_hcd->old_active) {
		if (dum_hcd->old_active && dum->driver->suspend) {
		if (dum_hcd->old_active && dum->driver->suspend)
			spin_unlock(&dum->lock);
			dum->driver->suspend(&dum->gadget);
			dum->driver->suspend(&dum->gadget);
			spin_lock(&dum->lock);
		else if (!dum_hcd->old_active &&  dum->driver->resume)
		} else if (!dum_hcd->old_active &&  dum->driver->resume) {
			spin_unlock(&dum->lock);
			dum->driver->resume(&dum->gadget);
			dum->driver->resume(&dum->gadget);
			spin_lock(&dum->lock);
		}
	}
	}


	dum_hcd->old_status = dum_hcd->port_status;
	dum_hcd->old_status = dum_hcd->port_status;
@@ -983,7 +976,9 @@ static int dummy_udc_stop(struct usb_gadget *g)
	struct dummy_hcd	*dum_hcd = gadget_to_dummy_hcd(g);
	struct dummy_hcd	*dum_hcd = gadget_to_dummy_hcd(g);
	struct dummy		*dum = dum_hcd->dum;
	struct dummy		*dum = dum_hcd->dum;


	spin_lock_irq(&dum->lock);
	dum->driver = NULL;
	dum->driver = NULL;
	spin_unlock_irq(&dum->lock);


	return 0;
	return 0;
}
}
+1 −8
Original line number Original line Diff line number Diff line
@@ -2470,11 +2470,8 @@ static void stop_activity(struct net2280 *dev, struct usb_gadget_driver *driver)
		nuke(&dev->ep[i]);
		nuke(&dev->ep[i]);


	/* report disconnect; the driver is already quiesced */
	/* report disconnect; the driver is already quiesced */
	if (driver) {
	if (driver)
		spin_unlock(&dev->lock);
		driver->disconnect(&dev->gadget);
		driver->disconnect(&dev->gadget);
		spin_lock(&dev->lock);
	}


	usb_reinit(dev);
	usb_reinit(dev);
}
}
@@ -3348,8 +3345,6 @@ static void handle_stat0_irqs(struct net2280 *dev, u32 stat)
		BIT(PCI_RETRY_ABORT_INTERRUPT))
		BIT(PCI_RETRY_ABORT_INTERRUPT))


static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
static void handle_stat1_irqs(struct net2280 *dev, u32 stat)
__releases(dev->lock)
__acquires(dev->lock)
{
{
	struct net2280_ep	*ep;
	struct net2280_ep	*ep;
	u32			tmp, num, mask, scratch;
	u32			tmp, num, mask, scratch;
@@ -3390,14 +3385,12 @@ __acquires(dev->lock)
			if (disconnect || reset) {
			if (disconnect || reset) {
				stop_activity(dev, dev->driver);
				stop_activity(dev, dev->driver);
				ep0_start(dev);
				ep0_start(dev);
				spin_unlock(&dev->lock);
				if (reset)
				if (reset)
					usb_gadget_udc_reset
					usb_gadget_udc_reset
						(&dev->gadget, dev->driver);
						(&dev->gadget, dev->driver);
				else
				else
					(dev->driver->disconnect)
					(dev->driver->disconnect)
						(&dev->gadget);
						(&dev->gadget);
				spin_lock(&dev->lock);
				return;
				return;
			}
			}
		}
		}
+5 −2
Original line number Original line Diff line number Diff line
@@ -2119,11 +2119,12 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
{
{
	u32 temp, port_offset, port_count;
	u32 temp, port_offset, port_count;
	int i;
	int i;
	u8 major_revision;
	u8 major_revision, minor_revision;
	struct xhci_hub *rhub;
	struct xhci_hub *rhub;


	temp = readl(addr);
	temp = readl(addr);
	major_revision = XHCI_EXT_PORT_MAJOR(temp);
	major_revision = XHCI_EXT_PORT_MAJOR(temp);
	minor_revision = XHCI_EXT_PORT_MINOR(temp);


	if (major_revision == 0x03) {
	if (major_revision == 0x03) {
		rhub = &xhci->usb3_rhub;
		rhub = &xhci->usb3_rhub;
@@ -2137,7 +2138,9 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports,
		return;
		return;
	}
	}
	rhub->maj_rev = XHCI_EXT_PORT_MAJOR(temp);
	rhub->maj_rev = XHCI_EXT_PORT_MAJOR(temp);
	rhub->min_rev = XHCI_EXT_PORT_MINOR(temp);

	if (rhub->min_rev < minor_revision)
		rhub->min_rev = minor_revision;


	/* Port offset and count in the third dword, see section 7.2 */
	/* Port offset and count in the third dword, see section 7.2 */
	temp = readl(addr + 2);
	temp = readl(addr + 2);
Loading