USB: deprecate the power/level sysfs attribute
[safe/jmp/linux-2.6] / drivers / usb / core / sysfs.c
index 313e241..06863be 100644 (file)
@@ -346,7 +346,8 @@ set_autosuspend(struct device *dev, struct device_attribute *attr,
                const char *buf, size_t count)
 {
        struct usb_device *udev = to_usb_device(dev);
-       int value;
+       int value, old_delay;
+       int rc;
 
        if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ ||
                        value <= - INT_MAX/HZ)
@@ -354,13 +355,24 @@ set_autosuspend(struct device *dev, struct device_attribute *attr,
        value *= HZ;
 
        usb_lock_device(udev);
+       old_delay = udev->autosuspend_delay;
        udev->autosuspend_delay = value;
-       if (value >= 0)
-               usb_try_autosuspend_device(udev);
-       else {
-               if (usb_autoresume_device(udev) == 0)
+
+       if (old_delay < 0) {    /* Autosuspend wasn't allowed */
+               if (value >= 0)
                        usb_autosuspend_device(udev);
+       } else {                /* Autosuspend was allowed */
+               if (value < 0) {
+                       rc = usb_autoresume_device(udev);
+                       if (rc < 0) {
+                               count = rc;
+                               udev->autosuspend_delay = old_delay;
+                       }
+               } else {
+                       usb_try_autosuspend_device(udev);
+               }
        }
+
        usb_unlock_device(udev);
        return count;
 }
@@ -371,13 +383,24 @@ static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR,
 static const char on_string[] = "on";
 static const char auto_string[] = "auto";
 
+static void warn_level(void) {
+       static int level_warned;
+
+       if (!level_warned) {
+               level_warned = 1;
+               printk(KERN_WARNING "WARNING! power/level is deprecated; "
+                               "use power/control instead\n");
+       }
+}
+
 static ssize_t
 show_level(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct usb_device *udev = to_usb_device(dev);
        const char *p = auto_string;
 
-       if (udev->state != USB_STATE_SUSPENDED && udev->autosuspend_disabled)
+       warn_level();
+       if (udev->state != USB_STATE_SUSPENDED && !udev->dev.power.runtime_auto)
                p = on_string;
        return sprintf(buf, "%s\n", p);
 }
@@ -389,8 +412,9 @@ set_level(struct device *dev, struct device_attribute *attr,
        struct usb_device *udev = to_usb_device(dev);
        int len = count;
        char *cp;
-       int rc;
+       int rc = count;
 
+       warn_level();
        cp = memchr(buf, '\n', count);
        if (cp)
                len = cp - buf;
@@ -399,17 +423,17 @@ set_level(struct device *dev, struct device_attribute *attr,
 
        if (len == sizeof on_string - 1 &&
                        strncmp(buf, on_string, len) == 0)
-               rc = usb_disable_autosuspend(udev);
+               usb_disable_autosuspend(udev);
 
        else if (len == sizeof auto_string - 1 &&
                        strncmp(buf, auto_string, len) == 0)
-               rc = usb_enable_autosuspend(udev);
+               usb_enable_autosuspend(udev);
 
        else
                rc = -EINVAL;
 
        usb_unlock_device(udev);
-       return (rc < 0 ? rc : count);
+       return rc;
 }
 
 static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level);