提交 352d0263 编写于 作者: A Alan Stern 提交者: Greg Kroah-Hartman

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: NAlan Stern <stern@rowland.harvard.edu>
Cc: stable <stable@kernel.org> [2.6.27, 2.6.26, 2.6.25]
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 0047ca0a
...@@ -1091,6 +1091,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) ...@@ -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);
} }
......
...@@ -840,7 +840,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf) ...@@ -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
......
...@@ -108,6 +108,7 @@ enum usb_interface_condition { ...@@ -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 { ...@@ -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 */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册