Skip to content

Commit

Permalink
USB: keep track of whether interface sysfs files exist
Browse files Browse the repository at this point in the history
This patch (as1009) solves the problem of multiple registrations for
USB sysfs files in a more satisfying way than the existing code.  It
simply adds a flag to keep track of whether or not the files have been
created; that way the files can be created or removed as needed.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
  • Loading branch information
Alan Stern authored and Greg Kroah-Hartman committed Nov 28, 2007
1 parent 5fdcd03 commit 7e61559
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 10 deletions.
12 changes: 2 additions & 10 deletions drivers/usb/core/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,6 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
struct usb_host_interface *alt;
int ret;
int manual = 0;
int changed;

if (dev->state == USB_STATE_SUSPENDED)
return -EHOSTUNREACH;
Expand Down Expand Up @@ -1212,8 +1211,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
*/

/* prevent submissions using previous endpoint settings */
changed = (iface->cur_altsetting != alt);
if (changed && device_is_registered(&iface->dev))
if (iface->cur_altsetting != alt && device_is_registered(&iface->dev))
usb_remove_sysfs_intf_files(iface);
usb_disable_interface(dev, iface);

Expand Down Expand Up @@ -1250,7 +1248,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
* (Likewise, EP0 never "halts" on well designed devices.)
*/
usb_enable_interface(dev, iface);
if (changed && device_is_registered(&iface->dev))
if (device_is_registered(&iface->dev))
usb_create_sysfs_intf_files(iface);

return 0;
Expand Down Expand Up @@ -1641,12 +1639,6 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
intf->dev.bus_id, ret);
continue;
}

/* The driver's probe method can call usb_set_interface(),
* which would mean the interface's sysfs files are already
* created. Just in case, we'll remove them first.
*/
usb_remove_sysfs_intf_files(intf);
usb_create_sysfs_intf_files(intf);
}

Expand Down
6 changes: 6 additions & 0 deletions drivers/usb/core/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
struct usb_host_interface *alt = intf->cur_altsetting;
int retval;

if (intf->sysfs_files_created)
return 0;
retval = sysfs_create_group(&dev->kobj, &intf_attr_grp);
if (retval)
return retval;
Expand All @@ -746,15 +748,19 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
if (intf->intf_assoc)
retval = sysfs_create_group(&dev->kobj, &intf_assoc_attr_grp);
usb_create_intf_ep_files(intf, udev);
intf->sysfs_files_created = 1;
return 0;
}

void usb_remove_sysfs_intf_files(struct usb_interface *intf)
{
struct device *dev = &intf->dev;

if (!intf->sysfs_files_created)
return;
usb_remove_intf_ep_files(intf);
device_remove_file(dev, &dev_attr_interface);
sysfs_remove_group(&dev->kobj, &intf_attr_grp);
sysfs_remove_group(&intf->dev.kobj, &intf_assoc_attr_grp);
intf->sysfs_files_created = 0;
}
1 change: 1 addition & 0 deletions include/linux/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ struct usb_interface {
* bound to */
enum usb_interface_condition condition; /* state of binding */
unsigned is_active:1; /* the interface is not suspended */
unsigned sysfs_files_created:1; /* the sysfs attributes exist */
unsigned needs_remote_wakeup:1; /* driver requires remote wakeup */

struct device dev; /* interface specific device info */
Expand Down

0 comments on commit 7e61559

Please sign in to comment.