summaryrefslogtreecommitdiff
path: root/drivers/usb/core/sysfs.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-03 19:48:58 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-03 19:48:58 +0300
commit7f5b09c15ab989ed5ce4adda0be42c1302df70b7 (patch)
tree9695b00983d1bd077ff91c463abcb136330cf344 /drivers/usb/core/sysfs.c
parent94468080220162f74dc6ce5c3e95e5fec8022902 (diff)
parentcedf8a78421943441b9011ce7bcdab55f07d2ea6 (diff)
downloadlinux-7f5b09c15ab989ed5ce4adda0be42c1302df70b7.tar.xz
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (220 commits) USB: backlight, appledisplay: fix incomplete registration failure handling USB: pl2303: remove unnecessary reset of usb_device in urbs USB: ftdi_sio: remove obsolete check in unthrottle USB: ftdi_sio: remove unused tx_bytes counter USB: qcaux: driver for auxiliary serial ports on Qualcomm devices USB: pl2303: initial TIOCGSERIAL support USB: option: add Longcheer/Longsung vendor ID USB: fix I2C API usage in ohci-pnx4008. USB: usbmon: mask seconds properly in text API USB: sisusbvga: no unnecessary GFP_ATOMIC USB: storage: onetouch: unnecessary GFP_ATOMIC USB: serial: ftdi: add CONTEC vendor and product id USB: remove references to port->port.count from the serial drivers USB: tty: Prune uses of tty_request_room in the USB layer USB: tty: Add a function to insert a string of characters with the same flag USB: don't read past config->interface[] if usb_control_msg() fails in usb_reset_configuration() USB: tty: kill request_room for USB ACM class USB: tty: sort out the request_room handling for whiteheat USB: storage: fix misplaced parenthesis USB: vstusb.c: removal of driver for Vernier Software & Technology, Inc., devices and spectrometers ...
Diffstat (limited to 'drivers/usb/core/sysfs.c')
-rw-r--r--drivers/usb/core/sysfs.c85
1 files changed, 61 insertions, 24 deletions
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 5f3908f6e2dc..43c002e3a9aa 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -115,7 +115,7 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf)
case USB_SPEED_HIGH:
speed = "480";
break;
- case USB_SPEED_VARIABLE:
+ case USB_SPEED_WIRELESS:
speed = "480";
break;
case USB_SPEED_SUPER:
@@ -191,6 +191,36 @@ show_quirks(struct device *dev, struct device_attribute *attr, char *buf)
static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL);
static ssize_t
+show_avoid_reset_quirk(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct usb_device *udev;
+
+ udev = to_usb_device(dev);
+ return sprintf(buf, "%d\n", !!(udev->quirks & USB_QUIRK_RESET_MORPHS));
+}
+
+static ssize_t
+set_avoid_reset_quirk(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_device *udev = to_usb_device(dev);
+ int config;
+
+ if (sscanf(buf, "%d", &config) != 1 || config < 0 || config > 1)
+ return -EINVAL;
+ usb_lock_device(udev);
+ if (config)
+ udev->quirks |= USB_QUIRK_RESET_MORPHS;
+ else
+ udev->quirks &= ~USB_QUIRK_RESET_MORPHS;
+ usb_unlock_device(udev);
+ return count;
+}
+
+static DEVICE_ATTR(avoid_reset_quirk, S_IRUGO | S_IWUSR,
+ show_avoid_reset_quirk, set_avoid_reset_quirk);
+
+static ssize_t
show_urbnum(struct device *dev, struct device_attribute *attr, char *buf)
{
struct usb_device *udev;
@@ -226,9 +256,10 @@ set_persist(struct device *dev, struct device_attribute *attr,
if (sscanf(buf, "%d", &value) != 1)
return -EINVAL;
- usb_pm_lock(udev);
+
+ usb_lock_device(udev);
udev->persist_enabled = !!value;
- usb_pm_unlock(udev);
+ usb_unlock_device(udev);
return count;
}
@@ -315,20 +346,34 @@ 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)
return -EINVAL;
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;
}
@@ -356,34 +401,25 @@ set_level(struct device *dev, struct device_attribute *attr,
struct usb_device *udev = to_usb_device(dev);
int len = count;
char *cp;
- int rc = 0;
- int old_autosuspend_disabled;
+ int rc;
cp = memchr(buf, '\n', count);
if (cp)
len = cp - buf;
usb_lock_device(udev);
- old_autosuspend_disabled = udev->autosuspend_disabled;
- /* Setting the flags without calling usb_pm_lock is a subject to
- * races, but who cares...
- */
if (len == sizeof on_string - 1 &&
- strncmp(buf, on_string, len) == 0) {
- udev->autosuspend_disabled = 1;
- rc = usb_external_resume_device(udev, PMSG_USER_RESUME);
+ strncmp(buf, on_string, len) == 0)
+ rc = usb_disable_autosuspend(udev);
- } else if (len == sizeof auto_string - 1 &&
- strncmp(buf, auto_string, len) == 0) {
- udev->autosuspend_disabled = 0;
- rc = usb_external_resume_device(udev, PMSG_USER_RESUME);
+ else if (len == sizeof auto_string - 1 &&
+ strncmp(buf, auto_string, len) == 0)
+ rc = usb_enable_autosuspend(udev);
- } else
+ else
rc = -EINVAL;
- if (rc)
- udev->autosuspend_disabled = old_autosuspend_disabled;
usb_unlock_device(udev);
return (rc < 0 ? rc : count);
}
@@ -558,6 +594,7 @@ static struct attribute *dev_attrs[] = {
&dev_attr_version.attr,
&dev_attr_maxchild.attr,
&dev_attr_quirks.attr,
+ &dev_attr_avoid_reset_quirk.attr,
&dev_attr_authorized.attr,
&dev_attr_remove.attr,
NULL,