usb: Add support for indicating whether a port is removable
authorMatthew Garrett <mjg@redhat.com>
Fri, 3 Feb 2012 22:11:54 +0000 (17:11 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Feb 2012 16:40:11 +0000 (08:40 -0800)
Userspace may want to make policy decisions based on whether or not a
given USB device is removable. Add a per-device member and support
for exposing it in sysfs. Information sources to populate it will be
added later.

Signed-off-by: Matthew Garrett <mjg@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/ABI/testing/sysfs-bus-usb
drivers/usb/core/sysfs.c
include/linux/usb.h

index b4f5487..7c22a53 100644 (file)
@@ -182,3 +182,14 @@ Description:
                USB2 hardware LPM is enabled for the device. Developer can
                write y/Y/1 or n/N/0 to the file to enable/disable the
                feature.
+
+What:          /sys/bus/usb/devices/.../removable
+Date:          February 2012
+Contact:       Matthew Garrett <mjg@redhat.com>
+Description:
+               Some information about whether a given USB device is
+               physically fixed to the platform can be inferred from a
+               combination of hub decriptor bits and platform-specific data
+               such as ACPI. This file will read either "removable" or
+               "fixed" if the information is available, and "unknown"
+               otherwise.
\ No newline at end of file
index 9e491ca..566d9f9 100644 (file)
@@ -230,6 +230,28 @@ show_urbnum(struct device *dev, struct device_attribute *attr, char *buf)
 }
 static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL);
 
+static ssize_t
+show_removable(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       struct usb_device *udev;
+       char *state;
+
+       udev = to_usb_device(dev);
+
+       switch (udev->removable) {
+       case USB_DEVICE_REMOVABLE:
+               state = "removable";
+               break;
+       case USB_DEVICE_FIXED:
+               state = "fixed";
+               break;
+       default:
+               state = "unknown";
+       }
+
+       return sprintf(buf, "%s\n", state);
+}
+static DEVICE_ATTR(removable, S_IRUGO, show_removable, NULL);
 
 #ifdef CONFIG_PM
 
@@ -626,6 +648,7 @@ static struct attribute *dev_attrs[] = {
        &dev_attr_avoid_reset_quirk.attr,
        &dev_attr_authorized.attr,
        &dev_attr_remove.attr,
+       &dev_attr_removable.attr,
        NULL,
 };
 static struct attribute_group dev_attr_grp = {
index 27a4e16..b2eb3a4 100644 (file)
@@ -376,6 +376,12 @@ struct usb_bus {
 
 struct usb_tt;
 
+enum usb_device_removable {
+       USB_DEVICE_REMOVABLE_UNKNOWN = 0,
+       USB_DEVICE_REMOVABLE,
+       USB_DEVICE_FIXED,
+};
+
 /**
  * struct usb_device - kernel's representation of a USB device
  * @devnum: device number; address on a USB bus
@@ -432,6 +438,7 @@ struct usb_tt;
  * @wusb_dev: if this is a Wireless USB device, link to the WUSB
  *     specific data for the device.
  * @slot_id: Slot ID assigned by xHCI
+ * @removable: Device can be physically removed from this port
  *
  * Notes:
  * Usbcore drivers should not set usbdev->state directly.  Instead use
@@ -509,6 +516,7 @@ struct usb_device {
 #endif
        struct wusb_dev *wusb_dev;
        int slot_id;
+       enum usb_device_removable removable;
 };
 #define        to_usb_device(d) container_of(d, struct usb_device, dev)