diff options
Diffstat (limited to 'drivers/usb/core/sysfs.c')
| -rw-r--r-- | drivers/usb/core/sysfs.c | 23 | 
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 7ec3041ae79..470e2413a9c 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -508,6 +508,28 @@ static ssize_t usb_dev_authorized_store(struct device *dev,  static DEVICE_ATTR(authorized, 0644,  	    usb_dev_authorized_show, usb_dev_authorized_store); +/* "Safely remove a device" */ +static ssize_t usb_remove_store(struct device *dev, +		struct device_attribute *attr, +		const char *buf, size_t count) +{ +	struct usb_device *udev = to_usb_device(dev); +	int rc = 0; + +	usb_lock_device(udev); +	if (udev->state != USB_STATE_NOTATTACHED) { + +		/* To avoid races, first unconfigure and then remove */ +		usb_set_configuration(udev, -1); +		rc = usb_remove_device(udev); +	} +	if (rc == 0) +		rc = count; +	usb_unlock_device(udev); +	return rc; +} +static DEVICE_ATTR(remove, 0200, NULL, usb_remove_store); +  static struct attribute *dev_attrs[] = {  	/* current configuration's attributes */ @@ -533,6 +555,7 @@ static struct attribute *dev_attrs[] = {  	&dev_attr_maxchild.attr,  	&dev_attr_quirks.attr,  	&dev_attr_authorized.attr, +	&dev_attr_remove.attr,  	NULL,  };  static struct attribute_group dev_attr_grp = {  | 
