aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/sysfs.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2009-10-27 15:20:13 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-12-11 14:55:18 -0500
commit253e05724f9230910344357b1142ad8642ff9f5a (patch)
treeff29ac01c681b183db2ad4b18b95b6c3dbe0ca0b /drivers/usb/core/sysfs.c
parentd697cdda43939a80432863e2e26df6701ce72b63 (diff)
USB: add a "remove hardware" sysfs attribute
This patch (as1297) adds a "remove" attribute to each USB device's directory in sysfs. Writing to this attribute causes the device to be deconfigured (the same as writing 0 to the "bConfigurationValue" attribute) and then tells the hub driver to disable the device's upstream port. The device remains locked during these activities so there is no possibility of it getting reconfigured in between. The port will remain disabled until after the device is unplugged. The purpose of this is to provide a means for user programs to imitate the "Safely remove hardware" applet in Windows. Some devices do expect their ports to be disabled before they are unplugged, and they provide visual feedback to users indicating when they can safely be unplugged. The security implications are minimal. Writing to the "remove" attribute is no more dangerous than writing to the "bConfigurationValue" attribute. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Cc: David Zeuthen <davidz@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/core/sysfs.c')
-rw-r--r--drivers/usb/core/sysfs.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 7ec3041ae79e..470e2413a9cf 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,
508static DEVICE_ATTR(authorized, 0644, 508static DEVICE_ATTR(authorized, 0644,
509 usb_dev_authorized_show, usb_dev_authorized_store); 509 usb_dev_authorized_show, usb_dev_authorized_store);
510 510
511/* "Safely remove a device" */
512static ssize_t usb_remove_store(struct device *dev,
513 struct device_attribute *attr,
514 const char *buf, size_t count)
515{
516 struct usb_device *udev = to_usb_device(dev);
517 int rc = 0;
518
519 usb_lock_device(udev);
520 if (udev->state != USB_STATE_NOTATTACHED) {
521
522 /* To avoid races, first unconfigure and then remove */
523 usb_set_configuration(udev, -1);
524 rc = usb_remove_device(udev);
525 }
526 if (rc == 0)
527 rc = count;
528 usb_unlock_device(udev);
529 return rc;
530}
531static DEVICE_ATTR(remove, 0200, NULL, usb_remove_store);
532
511 533
512static struct attribute *dev_attrs[] = { 534static struct attribute *dev_attrs[] = {
513 /* current configuration's attributes */ 535 /* current configuration's attributes */
@@ -533,6 +555,7 @@ static struct attribute *dev_attrs[] = {
533 &dev_attr_maxchild.attr, 555 &dev_attr_maxchild.attr,
534 &dev_attr_quirks.attr, 556 &dev_attr_quirks.attr,
535 &dev_attr_authorized.attr, 557 &dev_attr_authorized.attr,
558 &dev_attr_remove.attr,
536 NULL, 559 NULL,
537}; 560};
538static struct attribute_group dev_attr_grp = { 561static struct attribute_group dev_attr_grp = {