Hi,

this is the second take of the patch to switch off autosuspend
through sysfs to allow battery powered devices to recharge of the
bus. It includes the cleanups Alan suggested.
In addition, likewise at Alan's request, it cleans up coding style in
the rest of sysfs.c

        Regards
                Oliver

Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
--

--- a/include/linux/usb.h       2007-01-18 13:15:25.000000000 +0100
+++ b/include/linux/usb.h       2007-01-17 15:42:11.000000000 +0100
@@ -364,6 +364,7 @@
 
        unsigned discon_suspended:1;    /* Disconnected while suspended */
        unsigned have_langid:1;         /* whether string_langid is valid */
+       unsigned can_autosuspend;       /* whether it should autosuspend */
        int string_langid;              /* language ID for strings */
 
        /* static strings from the device */
--- a/drivers/usb/core/driver.c 2007-01-18 13:13:22.000000000 +0100
+++ b/drivers/usb/core/driver.c 2007-01-18 13:02:46.000000000 +0100
@@ -948,7 +948,8 @@
        int                     i;
        struct usb_interface    *intf;
 
-       /* For autosuspend, fail fast if anything is in use.
+       /* For autosuspend, fail fast if anything is in use or autosuspend
+        * is disabled through sysfs.
         * Also fail if any interfaces require remote wakeup but it
         * isn't available. */
        udev->do_remote_wakeup = device_may_wakeup(&udev->dev);
--- a/drivers/usb/core/usb.c    2007-01-18 13:13:50.000000000 +0100
+++ b/drivers/usb/core/usb.c    2007-01-18 12:56:28.000000000 +0100
@@ -301,6 +301,7 @@
        dev->portnum = port1;
        dev->bus = bus;
        dev->parent = parent;
+       dev->can_autosuspend = 1;
        INIT_LIST_HEAD(&dev->filelist);
 
 #ifdef CONFIG_PM
--- a/drivers/usb/core/sysfs.c  2007-01-18 13:13:35.000000000 +0100
+++ b/drivers/usb/core/sysfs.c  2007-01-19 09:47:30.000000000 +0100
@@ -57,7 +57,7 @@
 usb_actconfig_show(bConfigurationValue, 1, "%u\n");
 
 static ssize_t
-set_bConfigurationValue (struct device *dev, struct device_attribute *attr,
+set_bConfigurationValue(struct device *dev, struct device_attribute *attr,
                const char *buf, size_t count)
 {
        struct usb_device       *udev = to_usb_device (dev);
@@ -91,7 +91,7 @@
 usb_string_attr(serial);
 
 static ssize_t
-show_speed (struct device *dev, struct device_attribute *attr, char *buf)
+show_speed(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct usb_device *udev;
        char *speed;
@@ -117,7 +117,7 @@
 static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL);
 
 static ssize_t
-show_devnum (struct device *dev, struct device_attribute *attr, char *buf)
+show_devnum(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct usb_device *udev;
 
@@ -127,7 +127,7 @@
 static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL);
 
 static ssize_t
-show_version (struct device *dev, struct device_attribute *attr, char *buf)
+show_version(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct usb_device *udev;
        u16 bcdUSB;
@@ -139,7 +139,7 @@
 static DEVICE_ATTR(version, S_IRUGO, show_version, NULL);
 
 static ssize_t
-show_maxchild (struct device *dev, struct device_attribute *attr, char *buf)
+show_maxchild(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct usb_device *udev;
 
@@ -148,6 +148,41 @@
 }
 static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL);
 
+static ssize_t
+show_autosuspend(struct device *dev, struct device_attribute *attr, char *buf)
+{
+       int autosusp;
+       struct usb_device *udev;
+
+       udev = to_usb_device (dev);
+       autosusp = udev->can_autosuspend;
+       return sprintf (buf, "%d\n", autosusp);
+}
+
+static ssize_t
+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, old;
+
+       if (sscanf (buf, "%u", &value) != 1 || value > 1)
+               return -EINVAL;
+
+       /* protected by sysfs's lock */
+       old = udev->can_autosuspend;
+       udev->can_autosuspend = value;
+       if (!value && old)
+               usb_autoresume_device (udev);
+       else if (value && !old)
+               usb_autosuspend_device (udev);
+
+       return count;
+}
+
+static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR, 
+               show_autosuspend, set_autosuspend);
+
 /* Descriptor fields */
 #define usb_descriptor_attr_le16(field, format_string)                 \
 static ssize_t                                                         \
@@ -185,6 +220,8 @@
 usb_descriptor_attr (bMaxPacketSize0, "%d\n")
 
 static struct attribute *dev_attrs[] = {
+       /* power management attributes */
+       &dev_attr_autosuspend.attr,
        /* current configuration's attributes */
        &dev_attr_configuration.attr,
        &dev_attr_bNumInterfaces.attr,
@@ -246,7 +283,7 @@
        return retval;
 }
 
-void usb_remove_sysfs_dev_files (struct usb_device *udev)
+void usb_remove_sysfs_dev_files(struct usb_device *udev)
 {
        struct device *dev = &udev->dev;
 
@@ -384,7 +421,7 @@
        return retval;
 }
 
-void usb_remove_sysfs_intf_files (struct usb_interface *intf)
+void usb_remove_sysfs_intf_files(struct usb_interface *intf)
 {
        usb_remove_intf_ep_files(intf);
        sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp);

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
linux-usb-devel@lists.sourceforge.net
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to