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

Commit 352d0263 authored by Alan Stern's avatar Alan Stern Committed by Greg Kroah-Hartman
Browse files

USB: don't register endpoints for interfaces that are going away



This patch (as1155) fixes a bug in usbcore.  When interfaces are
deleted, either because the device was disconnected or because of a
configuration change, the extra attribute files and child endpoint
devices may get left behind.  This is because the core removes them
before calling device_del().  But during device_del(), after the
driver is unbound the core will reinstall altsetting 0 and recreate
those extra attributes and children.

The patch prevents this by adding a flag to record when the interface
is in the midst of being unregistered.  When the flag is set, the
attribute files and child devices will not be created.

Signed-off-by: default avatarAlan Stern <stern@rowland.harvard.edu>
Cc: stable <stable@kernel.org> [2.6.27, 2.6.26, 2.6.25]
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 0047ca0a
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -1091,6 +1091,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
				continue;
				continue;
			dev_dbg(&dev->dev, "unregistering interface %s\n",
			dev_dbg(&dev->dev, "unregistering interface %s\n",
				dev_name(&interface->dev));
				dev_name(&interface->dev));
			interface->unregistering = 1;
			usb_remove_sysfs_intf_files(interface);
			usb_remove_sysfs_intf_files(interface);
			device_del(&interface->dev);
			device_del(&interface->dev);
		}
		}
+1 −1
Original line number Original line Diff line number Diff line
@@ -840,7 +840,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
	struct usb_host_interface *alt = intf->cur_altsetting;
	struct usb_host_interface *alt = intf->cur_altsetting;
	int retval;
	int retval;


	if (intf->sysfs_files_created)
	if (intf->sysfs_files_created || intf->unregistering)
		return 0;
		return 0;


	/* The interface string may be present in some altsettings
	/* The interface string may be present in some altsettings
+2 −0
Original line number Original line Diff line number Diff line
@@ -108,6 +108,7 @@ enum usb_interface_condition {
 *	(in probe()), bound to a driver, or unbinding (in disconnect())
 *	(in probe()), bound to a driver, or unbinding (in disconnect())
 * @is_active: flag set when the interface is bound and not suspended.
 * @is_active: flag set when the interface is bound and not suspended.
 * @sysfs_files_created: sysfs attributes exist
 * @sysfs_files_created: sysfs attributes exist
 * @unregistering: flag set when the interface is being unregistered
 * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
 * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
 *	capability during autosuspend.
 *	capability during autosuspend.
 * @needs_altsetting0: flag set when a set-interface request for altsetting 0
 * @needs_altsetting0: flag set when a set-interface request for altsetting 0
@@ -163,6 +164,7 @@ struct usb_interface {
	enum usb_interface_condition condition;		/* state of binding */
	enum usb_interface_condition condition;		/* state of binding */
	unsigned is_active:1;		/* the interface is not suspended */
	unsigned is_active:1;		/* the interface is not suspended */
	unsigned sysfs_files_created:1;	/* the sysfs attributes exist */
	unsigned sysfs_files_created:1;	/* the sysfs attributes exist */
	unsigned unregistering:1;	/* unregistration is in progress */
	unsigned needs_remote_wakeup:1;	/* driver requires remote wakeup */
	unsigned needs_remote_wakeup:1;	/* driver requires remote wakeup */
	unsigned needs_altsetting0:1;	/* switch to altsetting 0 is pending */
	unsigned needs_altsetting0:1;	/* switch to altsetting 0 is pending */
	unsigned needs_binding:1;	/* needs delayed unbind/rebind */
	unsigned needs_binding:1;	/* needs delayed unbind/rebind */