usb: sysfs: make locking interruptible
[cascardo/linux.git] / drivers / usb / core / sysfs.c
index f195320..7a62093 100644 (file)
@@ -23,10 +23,12 @@ static ssize_t field##_show(struct device *dev,                             \
 {                                                                      \
        struct usb_device *udev;                                        \
        struct usb_host_config *actconfig;                              \
-       ssize_t rc = 0;                                                 \
+       ssize_t rc;                                                     \
                                                                        \
        udev = to_usb_device(dev);                                      \
-       usb_lock_device(udev);                                          \
+       rc = usb_lock_device_interruptible(udev);                       \
+       if (rc < 0)                                                     \
+               return -EINTR;                                          \
        actconfig = udev->actconfig;                                    \
        if (actconfig)                                                  \
                rc = sprintf(buf, format_string,                        \
@@ -47,10 +49,12 @@ static ssize_t bMaxPower_show(struct device *dev,
 {
        struct usb_device *udev;
        struct usb_host_config *actconfig;
-       ssize_t rc = 0;
+       ssize_t rc;
 
        udev = to_usb_device(dev);
-       usb_lock_device(udev);
+       rc = usb_lock_device_interruptible(udev);
+       if (rc < 0)
+               return -EINTR;
        actconfig = udev->actconfig;
        if (actconfig)
                rc = sprintf(buf, "%dmA\n", usb_get_max_power(udev, actconfig));
@@ -64,10 +68,12 @@ static ssize_t configuration_show(struct device *dev,
 {
        struct usb_device *udev;
        struct usb_host_config *actconfig;
-       ssize_t rc = 0;
+       ssize_t rc;
 
        udev = to_usb_device(dev);
-       usb_lock_device(udev);
+       rc = usb_lock_device_interruptible(udev);
+       if (rc < 0)
+               return -EINTR;
        actconfig = udev->actconfig;
        if (actconfig && actconfig->string)
                rc = sprintf(buf, "%s\n", actconfig->string);
@@ -84,11 +90,13 @@ static ssize_t bConfigurationValue_store(struct device *dev,
                                         const char *buf, size_t count)
 {
        struct usb_device       *udev = to_usb_device(dev);
-       int                     config, value;
+       int                     config, value, rc;
 
        if (sscanf(buf, "%d", &config) != 1 || config < -1 || config > 255)
                return -EINVAL;
-       usb_lock_device(udev);
+       rc = usb_lock_device_interruptible(udev);
+       if (rc < 0)
+               return -EINTR;
        value = usb_set_configuration(udev, config);
        usb_unlock_device(udev);
        return (value < 0) ? value : count;
@@ -105,7 +113,9 @@ static ssize_t  name##_show(struct device *dev,                             \
        int retval;                                                     \
                                                                        \
        udev = to_usb_device(dev);                                      \
-       usb_lock_device(udev);                                          \
+       retval = usb_lock_device_interruptible(udev);                   \
+       if (retval < 0)                                                 \
+               return -EINTR;                                          \
        retval = sprintf(buf, "%s\n", udev->name);                      \
        usb_unlock_device(udev);                                        \
        return retval;                                                  \
@@ -227,11 +237,13 @@ static ssize_t avoid_reset_quirk_store(struct device *dev,
                                      const char *buf, size_t count)
 {
        struct usb_device       *udev = to_usb_device(dev);
-       int                     val;
+       int                     val, rc;
 
        if (sscanf(buf, "%d", &val) != 1 || val < 0 || val > 1)
                return -EINVAL;
-       usb_lock_device(udev);
+       rc = usb_lock_device_interruptible(udev);
+       if (rc < 0)
+               return -EINTR;
        if (val)
                udev->quirks |= USB_QUIRK_RESET;
        else
@@ -297,7 +309,7 @@ static ssize_t persist_store(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, rc;
 
        /* Hubs are always enabled for USB_PERSIST */
        if (udev->descriptor.bDeviceClass == USB_CLASS_HUB)
@@ -306,7 +318,9 @@ static ssize_t persist_store(struct device *dev, struct device_attribute *attr,
        if (sscanf(buf, "%d", &value) != 1)
                return -EINVAL;
 
-       usb_lock_device(udev);
+       rc = usb_lock_device_interruptible(udev);
+       if (rc < 0)
+               return -EINTR;
        udev->persist_enabled = !!value;
        usb_unlock_device(udev);
        return count;
@@ -423,13 +437,16 @@ static ssize_t level_store(struct device *dev, struct device_attribute *attr,
        int len = count;
        char *cp;
        int rc = count;
+       int rv;
 
        warn_level();
        cp = memchr(buf, '\n', count);
        if (cp)
                len = cp - buf;
 
-       usb_lock_device(udev);
+       rv = usb_lock_device_interruptible(udev);
+       if (rv < 0)
+               return -EINTR;
 
        if (len == sizeof on_string - 1 &&
                        strncmp(buf, on_string, len) == 0)
@@ -469,7 +486,9 @@ static ssize_t usb2_hardware_lpm_store(struct device *dev,
        bool value;
        int ret;
 
-       usb_lock_device(udev);
+       ret = usb_lock_device_interruptible(udev);
+       if (ret < 0)
+               return -EINTR;
 
        ret = strtobool(buf, &value);
 
@@ -539,8 +558,11 @@ static ssize_t usb3_hardware_lpm_u1_show(struct device *dev,
 {
        struct usb_device *udev = to_usb_device(dev);
        const char *p;
+       int rc;
 
-       usb_lock_device(udev);
+       rc = usb_lock_device_interruptible(udev);
+       if (rc < 0)
+               return -EINTR;
 
        if (udev->usb3_lpm_u1_enabled)
                p = "enabled";
@@ -558,8 +580,11 @@ static ssize_t usb3_hardware_lpm_u2_show(struct device *dev,
 {
        struct usb_device *udev = to_usb_device(dev);
        const char *p;
+       int rc;
 
-       usb_lock_device(udev);
+       rc = usb_lock_device_interruptible(udev);
+       if (rc < 0)
+               return -EINTR;
 
        if (udev->usb3_lpm_u2_enabled)
                p = "enabled";
@@ -818,14 +843,16 @@ read_descriptors(struct file *filp, struct kobject *kobj,
        struct usb_device *udev = to_usb_device(dev);
        size_t nleft = count;
        size_t srclen, n;
-       int cfgno;
+       int cfgno, rc;
        void *src;
 
        /* The binary attribute begins with the device descriptor.
         * Following that are the raw descriptor entries for all the
         * configurations (config plus subsidiary descriptors).
         */
-       usb_lock_device(udev);
+       rc = usb_lock_device_interruptible(udev);
+       if (rc < 0)
+               return -EINTR;
        for (cfgno = -1; cfgno < udev->descriptor.bNumConfigurations &&
                        nleft > 0; ++cfgno) {
                if (cfgno < 0) {
@@ -972,7 +999,9 @@ static ssize_t supports_autosuspend_show(struct device *dev,
 {
        int s;
 
-       device_lock(dev);
+       s = device_lock_interruptible(dev);
+       if (s < 0)
+               return -EINTR;
        /* Devices will be autosuspended even when an interface isn't claimed */
        s = (!dev->driver || to_usb_driver(dev->driver)->supports_autosuspend);
        device_unlock(dev);