diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-12-21 05:21:15 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-12-21 05:21:15 -0500 |
commit | de8853bc38ceab1fa7e7f723b21430d4aad60fea (patch) | |
tree | 5084ef51866fd1767324f8dc8eb36e97c55350f5 /drivers/usb/core/sysfs.c | |
parent | f5de24b06aa46427500d0fdbe8616b73a71d8c28 (diff) | |
parent | 440b004cf953bec2bc8cd91c64ae707fd7e25327 (diff) |
Merge remote branch 'alsa/fixes' into fix/hda
Diffstat (limited to 'drivers/usb/core/sysfs.c')
-rw-r--r-- | drivers/usb/core/sysfs.c | 61 |
1 files changed, 39 insertions, 22 deletions
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 7ec3041ae79e..15477008b631 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -139,6 +139,16 @@ show_devnum(struct device *dev, struct device_attribute *attr, char *buf) | |||
139 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); | 139 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); |
140 | 140 | ||
141 | static ssize_t | 141 | static ssize_t |
142 | show_devpath(struct device *dev, struct device_attribute *attr, char *buf) | ||
143 | { | ||
144 | struct usb_device *udev; | ||
145 | |||
146 | udev = to_usb_device(dev); | ||
147 | return sprintf(buf, "%s\n", udev->devpath); | ||
148 | } | ||
149 | static DEVICE_ATTR(devpath, S_IRUGO, show_devpath, NULL); | ||
150 | |||
151 | static ssize_t | ||
142 | show_version(struct device *dev, struct device_attribute *attr, char *buf) | 152 | show_version(struct device *dev, struct device_attribute *attr, char *buf) |
143 | { | 153 | { |
144 | struct usb_device *udev; | 154 | struct usb_device *udev; |
@@ -317,7 +327,6 @@ static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR, | |||
317 | 327 | ||
318 | static const char on_string[] = "on"; | 328 | static const char on_string[] = "on"; |
319 | static const char auto_string[] = "auto"; | 329 | static const char auto_string[] = "auto"; |
320 | static const char suspend_string[] = "suspend"; | ||
321 | 330 | ||
322 | static ssize_t | 331 | static ssize_t |
323 | show_level(struct device *dev, struct device_attribute *attr, char *buf) | 332 | show_level(struct device *dev, struct device_attribute *attr, char *buf) |
@@ -325,13 +334,8 @@ show_level(struct device *dev, struct device_attribute *attr, char *buf) | |||
325 | struct usb_device *udev = to_usb_device(dev); | 334 | struct usb_device *udev = to_usb_device(dev); |
326 | const char *p = auto_string; | 335 | const char *p = auto_string; |
327 | 336 | ||
328 | if (udev->state == USB_STATE_SUSPENDED) { | 337 | if (udev->state != USB_STATE_SUSPENDED && udev->autosuspend_disabled) |
329 | if (udev->autoresume_disabled) | 338 | p = on_string; |
330 | p = suspend_string; | ||
331 | } else { | ||
332 | if (udev->autosuspend_disabled) | ||
333 | p = on_string; | ||
334 | } | ||
335 | return sprintf(buf, "%s\n", p); | 339 | return sprintf(buf, "%s\n", p); |
336 | } | 340 | } |
337 | 341 | ||
@@ -343,7 +347,7 @@ set_level(struct device *dev, struct device_attribute *attr, | |||
343 | int len = count; | 347 | int len = count; |
344 | char *cp; | 348 | char *cp; |
345 | int rc = 0; | 349 | int rc = 0; |
346 | int old_autosuspend_disabled, old_autoresume_disabled; | 350 | int old_autosuspend_disabled; |
347 | 351 | ||
348 | cp = memchr(buf, '\n', count); | 352 | cp = memchr(buf, '\n', count); |
349 | if (cp) | 353 | if (cp) |
@@ -351,7 +355,6 @@ set_level(struct device *dev, struct device_attribute *attr, | |||
351 | 355 | ||
352 | usb_lock_device(udev); | 356 | usb_lock_device(udev); |
353 | old_autosuspend_disabled = udev->autosuspend_disabled; | 357 | old_autosuspend_disabled = udev->autosuspend_disabled; |
354 | old_autoresume_disabled = udev->autoresume_disabled; | ||
355 | 358 | ||
356 | /* Setting the flags without calling usb_pm_lock is a subject to | 359 | /* Setting the flags without calling usb_pm_lock is a subject to |
357 | * races, but who cares... | 360 | * races, but who cares... |
@@ -359,28 +362,18 @@ set_level(struct device *dev, struct device_attribute *attr, | |||
359 | if (len == sizeof on_string - 1 && | 362 | if (len == sizeof on_string - 1 && |
360 | strncmp(buf, on_string, len) == 0) { | 363 | strncmp(buf, on_string, len) == 0) { |
361 | udev->autosuspend_disabled = 1; | 364 | udev->autosuspend_disabled = 1; |
362 | udev->autoresume_disabled = 0; | ||
363 | rc = usb_external_resume_device(udev, PMSG_USER_RESUME); | 365 | rc = usb_external_resume_device(udev, PMSG_USER_RESUME); |
364 | 366 | ||
365 | } else if (len == sizeof auto_string - 1 && | 367 | } else if (len == sizeof auto_string - 1 && |
366 | strncmp(buf, auto_string, len) == 0) { | 368 | strncmp(buf, auto_string, len) == 0) { |
367 | udev->autosuspend_disabled = 0; | 369 | udev->autosuspend_disabled = 0; |
368 | udev->autoresume_disabled = 0; | ||
369 | rc = usb_external_resume_device(udev, PMSG_USER_RESUME); | 370 | rc = usb_external_resume_device(udev, PMSG_USER_RESUME); |
370 | 371 | ||
371 | } else if (len == sizeof suspend_string - 1 && | ||
372 | strncmp(buf, suspend_string, len) == 0) { | ||
373 | udev->autosuspend_disabled = 0; | ||
374 | udev->autoresume_disabled = 1; | ||
375 | rc = usb_external_suspend_device(udev, PMSG_USER_SUSPEND); | ||
376 | |||
377 | } else | 372 | } else |
378 | rc = -EINVAL; | 373 | rc = -EINVAL; |
379 | 374 | ||
380 | if (rc) { | 375 | if (rc) |
381 | udev->autosuspend_disabled = old_autosuspend_disabled; | 376 | udev->autosuspend_disabled = old_autosuspend_disabled; |
382 | udev->autoresume_disabled = old_autoresume_disabled; | ||
383 | } | ||
384 | usb_unlock_device(udev); | 377 | usb_unlock_device(udev); |
385 | return (rc < 0 ? rc : count); | 378 | return (rc < 0 ? rc : count); |
386 | } | 379 | } |
@@ -508,6 +501,28 @@ static ssize_t usb_dev_authorized_store(struct device *dev, | |||
508 | static DEVICE_ATTR(authorized, 0644, | 501 | static DEVICE_ATTR(authorized, 0644, |
509 | usb_dev_authorized_show, usb_dev_authorized_store); | 502 | usb_dev_authorized_show, usb_dev_authorized_store); |
510 | 503 | ||
504 | /* "Safely remove a device" */ | ||
505 | static ssize_t usb_remove_store(struct device *dev, | ||
506 | struct device_attribute *attr, | ||
507 | const char *buf, size_t count) | ||
508 | { | ||
509 | struct usb_device *udev = to_usb_device(dev); | ||
510 | int rc = 0; | ||
511 | |||
512 | usb_lock_device(udev); | ||
513 | if (udev->state != USB_STATE_NOTATTACHED) { | ||
514 | |||
515 | /* To avoid races, first unconfigure and then remove */ | ||
516 | usb_set_configuration(udev, -1); | ||
517 | rc = usb_remove_device(udev); | ||
518 | } | ||
519 | if (rc == 0) | ||
520 | rc = count; | ||
521 | usb_unlock_device(udev); | ||
522 | return rc; | ||
523 | } | ||
524 | static DEVICE_ATTR(remove, 0200, NULL, usb_remove_store); | ||
525 | |||
511 | 526 | ||
512 | static struct attribute *dev_attrs[] = { | 527 | static struct attribute *dev_attrs[] = { |
513 | /* current configuration's attributes */ | 528 | /* current configuration's attributes */ |
@@ -516,8 +531,8 @@ static struct attribute *dev_attrs[] = { | |||
516 | &dev_attr_bConfigurationValue.attr, | 531 | &dev_attr_bConfigurationValue.attr, |
517 | &dev_attr_bmAttributes.attr, | 532 | &dev_attr_bmAttributes.attr, |
518 | &dev_attr_bMaxPower.attr, | 533 | &dev_attr_bMaxPower.attr, |
519 | &dev_attr_urbnum.attr, | ||
520 | /* device attributes */ | 534 | /* device attributes */ |
535 | &dev_attr_urbnum.attr, | ||
521 | &dev_attr_idVendor.attr, | 536 | &dev_attr_idVendor.attr, |
522 | &dev_attr_idProduct.attr, | 537 | &dev_attr_idProduct.attr, |
523 | &dev_attr_bcdDevice.attr, | 538 | &dev_attr_bcdDevice.attr, |
@@ -529,10 +544,12 @@ static struct attribute *dev_attrs[] = { | |||
529 | &dev_attr_speed.attr, | 544 | &dev_attr_speed.attr, |
530 | &dev_attr_busnum.attr, | 545 | &dev_attr_busnum.attr, |
531 | &dev_attr_devnum.attr, | 546 | &dev_attr_devnum.attr, |
547 | &dev_attr_devpath.attr, | ||
532 | &dev_attr_version.attr, | 548 | &dev_attr_version.attr, |
533 | &dev_attr_maxchild.attr, | 549 | &dev_attr_maxchild.attr, |
534 | &dev_attr_quirks.attr, | 550 | &dev_attr_quirks.attr, |
535 | &dev_attr_authorized.attr, | 551 | &dev_attr_authorized.attr, |
552 | &dev_attr_remove.attr, | ||
536 | NULL, | 553 | NULL, |
537 | }; | 554 | }; |
538 | static struct attribute_group dev_attr_grp = { | 555 | static struct attribute_group dev_attr_grp = { |