aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/core/sysfs.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/usb/core/sysfs.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/usb/core/sysfs.c')
-rw-r--r--drivers/usb/core/sysfs.c156
1 files changed, 110 insertions, 46 deletions
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 7ec3041ae79e..43c002e3a9aa 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -82,9 +82,13 @@ static ssize_t show_##name(struct device *dev, \
82 struct device_attribute *attr, char *buf) \ 82 struct device_attribute *attr, char *buf) \
83{ \ 83{ \
84 struct usb_device *udev; \ 84 struct usb_device *udev; \
85 int retval; \
85 \ 86 \
86 udev = to_usb_device(dev); \ 87 udev = to_usb_device(dev); \
87 return sprintf(buf, "%s\n", udev->name); \ 88 usb_lock_device(udev); \
89 retval = sprintf(buf, "%s\n", udev->name); \
90 usb_unlock_device(udev); \
91 return retval; \
88} \ 92} \
89static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); 93static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL);
90 94
@@ -111,6 +115,12 @@ show_speed(struct device *dev, struct device_attribute *attr, char *buf)
111 case USB_SPEED_HIGH: 115 case USB_SPEED_HIGH:
112 speed = "480"; 116 speed = "480";
113 break; 117 break;
118 case USB_SPEED_WIRELESS:
119 speed = "480";
120 break;
121 case USB_SPEED_SUPER:
122 speed = "5000";
123 break;
114 default: 124 default:
115 speed = "unknown"; 125 speed = "unknown";
116 } 126 }
@@ -139,6 +149,16 @@ show_devnum(struct device *dev, struct device_attribute *attr, char *buf)
139static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); 149static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL);
140 150
141static ssize_t 151static ssize_t
152show_devpath(struct device *dev, struct device_attribute *attr, char *buf)
153{
154 struct usb_device *udev;
155
156 udev = to_usb_device(dev);
157 return sprintf(buf, "%s\n", udev->devpath);
158}
159static DEVICE_ATTR(devpath, S_IRUGO, show_devpath, NULL);
160
161static ssize_t
142show_version(struct device *dev, struct device_attribute *attr, char *buf) 162show_version(struct device *dev, struct device_attribute *attr, char *buf)
143{ 163{
144 struct usb_device *udev; 164 struct usb_device *udev;
@@ -171,6 +191,36 @@ show_quirks(struct device *dev, struct device_attribute *attr, char *buf)
171static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); 191static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL);
172 192
173static ssize_t 193static ssize_t
194show_avoid_reset_quirk(struct device *dev, struct device_attribute *attr, char *buf)
195{
196 struct usb_device *udev;
197
198 udev = to_usb_device(dev);
199 return sprintf(buf, "%d\n", !!(udev->quirks & USB_QUIRK_RESET_MORPHS));
200}
201
202static ssize_t
203set_avoid_reset_quirk(struct device *dev, struct device_attribute *attr,
204 const char *buf, size_t count)
205{
206 struct usb_device *udev = to_usb_device(dev);
207 int config;
208
209 if (sscanf(buf, "%d", &config) != 1 || config < 0 || config > 1)
210 return -EINVAL;
211 usb_lock_device(udev);
212 if (config)
213 udev->quirks |= USB_QUIRK_RESET_MORPHS;
214 else
215 udev->quirks &= ~USB_QUIRK_RESET_MORPHS;
216 usb_unlock_device(udev);
217 return count;
218}
219
220static DEVICE_ATTR(avoid_reset_quirk, S_IRUGO | S_IWUSR,
221 show_avoid_reset_quirk, set_avoid_reset_quirk);
222
223static ssize_t
174show_urbnum(struct device *dev, struct device_attribute *attr, char *buf) 224show_urbnum(struct device *dev, struct device_attribute *attr, char *buf)
175{ 225{
176 struct usb_device *udev; 226 struct usb_device *udev;
@@ -206,9 +256,10 @@ set_persist(struct device *dev, struct device_attribute *attr,
206 256
207 if (sscanf(buf, "%d", &value) != 1) 257 if (sscanf(buf, "%d", &value) != 1)
208 return -EINVAL; 258 return -EINVAL;
209 usb_pm_lock(udev); 259
260 usb_lock_device(udev);
210 udev->persist_enabled = !!value; 261 udev->persist_enabled = !!value;
211 usb_pm_unlock(udev); 262 usb_unlock_device(udev);
212 return count; 263 return count;
213} 264}
214 265
@@ -295,20 +346,34 @@ set_autosuspend(struct device *dev, struct device_attribute *attr,
295 const char *buf, size_t count) 346 const char *buf, size_t count)
296{ 347{
297 struct usb_device *udev = to_usb_device(dev); 348 struct usb_device *udev = to_usb_device(dev);
298 int value; 349 int value, old_delay;
350 int rc;
299 351
300 if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ || 352 if (sscanf(buf, "%d", &value) != 1 || value >= INT_MAX/HZ ||
301 value <= - INT_MAX/HZ) 353 value <= - INT_MAX/HZ)
302 return -EINVAL; 354 return -EINVAL;
303 value *= HZ; 355 value *= HZ;
304 356
357 usb_lock_device(udev);
358 old_delay = udev->autosuspend_delay;
305 udev->autosuspend_delay = value; 359 udev->autosuspend_delay = value;
306 if (value >= 0) 360
307 usb_try_autosuspend_device(udev); 361 if (old_delay < 0) { /* Autosuspend wasn't allowed */
308 else { 362 if (value >= 0)
309 if (usb_autoresume_device(udev) == 0)
310 usb_autosuspend_device(udev); 363 usb_autosuspend_device(udev);
364 } else { /* Autosuspend was allowed */
365 if (value < 0) {
366 rc = usb_autoresume_device(udev);
367 if (rc < 0) {
368 count = rc;
369 udev->autosuspend_delay = old_delay;
370 }
371 } else {
372 usb_try_autosuspend_device(udev);
373 }
311 } 374 }
375
376 usb_unlock_device(udev);
312 return count; 377 return count;
313} 378}
314 379
@@ -317,7 +382,6 @@ static DEVICE_ATTR(autosuspend, S_IRUGO | S_IWUSR,
317 382
318static const char on_string[] = "on"; 383static const char on_string[] = "on";
319static const char auto_string[] = "auto"; 384static const char auto_string[] = "auto";
320static const char suspend_string[] = "suspend";
321 385
322static ssize_t 386static ssize_t
323show_level(struct device *dev, struct device_attribute *attr, char *buf) 387show_level(struct device *dev, struct device_attribute *attr, char *buf)
@@ -325,13 +389,8 @@ show_level(struct device *dev, struct device_attribute *attr, char *buf)
325 struct usb_device *udev = to_usb_device(dev); 389 struct usb_device *udev = to_usb_device(dev);
326 const char *p = auto_string; 390 const char *p = auto_string;
327 391
328 if (udev->state == USB_STATE_SUSPENDED) { 392 if (udev->state != USB_STATE_SUSPENDED && udev->autosuspend_disabled)
329 if (udev->autoresume_disabled) 393 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); 394 return sprintf(buf, "%s\n", p);
336} 395}
337 396
@@ -342,45 +401,25 @@ set_level(struct device *dev, struct device_attribute *attr,
342 struct usb_device *udev = to_usb_device(dev); 401 struct usb_device *udev = to_usb_device(dev);
343 int len = count; 402 int len = count;
344 char *cp; 403 char *cp;
345 int rc = 0; 404 int rc;
346 int old_autosuspend_disabled, old_autoresume_disabled;
347 405
348 cp = memchr(buf, '\n', count); 406 cp = memchr(buf, '\n', count);
349 if (cp) 407 if (cp)
350 len = cp - buf; 408 len = cp - buf;
351 409
352 usb_lock_device(udev); 410 usb_lock_device(udev);
353 old_autosuspend_disabled = udev->autosuspend_disabled;
354 old_autoresume_disabled = udev->autoresume_disabled;
355 411
356 /* Setting the flags without calling usb_pm_lock is a subject to
357 * races, but who cares...
358 */
359 if (len == sizeof on_string - 1 && 412 if (len == sizeof on_string - 1 &&
360 strncmp(buf, on_string, len) == 0) { 413 strncmp(buf, on_string, len) == 0)
361 udev->autosuspend_disabled = 1; 414 rc = usb_disable_autosuspend(udev);
362 udev->autoresume_disabled = 0; 415
363 rc = usb_external_resume_device(udev, PMSG_USER_RESUME); 416 else if (len == sizeof auto_string - 1 &&
364 417 strncmp(buf, auto_string, len) == 0)
365 } else if (len == sizeof auto_string - 1 && 418 rc = usb_enable_autosuspend(udev);
366 strncmp(buf, auto_string, len) == 0) { 419
367 udev->autosuspend_disabled = 0; 420 else
368 udev->autoresume_disabled = 0;
369 rc = usb_external_resume_device(udev, PMSG_USER_RESUME);
370
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
378 rc = -EINVAL; 421 rc = -EINVAL;
379 422
380 if (rc) {
381 udev->autosuspend_disabled = old_autosuspend_disabled;
382 udev->autoresume_disabled = old_autoresume_disabled;
383 }
384 usb_unlock_device(udev); 423 usb_unlock_device(udev);
385 return (rc < 0 ? rc : count); 424 return (rc < 0 ? rc : count);
386} 425}
@@ -508,6 +547,28 @@ static ssize_t usb_dev_authorized_store(struct device *dev,
508static DEVICE_ATTR(authorized, 0644, 547static DEVICE_ATTR(authorized, 0644,
509 usb_dev_authorized_show, usb_dev_authorized_store); 548 usb_dev_authorized_show, usb_dev_authorized_store);
510 549
550/* "Safely remove a device" */
551static ssize_t usb_remove_store(struct device *dev,
552 struct device_attribute *attr,
553 const char *buf, size_t count)
554{
555 struct usb_device *udev = to_usb_device(dev);
556 int rc = 0;
557
558 usb_lock_device(udev);
559 if (udev->state != USB_STATE_NOTATTACHED) {
560
561 /* To avoid races, first unconfigure and then remove */
562 usb_set_configuration(udev, -1);
563 rc = usb_remove_device(udev);
564 }
565 if (rc == 0)
566 rc = count;
567 usb_unlock_device(udev);
568 return rc;
569}
570static DEVICE_ATTR(remove, 0200, NULL, usb_remove_store);
571
511 572
512static struct attribute *dev_attrs[] = { 573static struct attribute *dev_attrs[] = {
513 /* current configuration's attributes */ 574 /* current configuration's attributes */
@@ -516,8 +577,8 @@ static struct attribute *dev_attrs[] = {
516 &dev_attr_bConfigurationValue.attr, 577 &dev_attr_bConfigurationValue.attr,
517 &dev_attr_bmAttributes.attr, 578 &dev_attr_bmAttributes.attr,
518 &dev_attr_bMaxPower.attr, 579 &dev_attr_bMaxPower.attr,
519 &dev_attr_urbnum.attr,
520 /* device attributes */ 580 /* device attributes */
581 &dev_attr_urbnum.attr,
521 &dev_attr_idVendor.attr, 582 &dev_attr_idVendor.attr,
522 &dev_attr_idProduct.attr, 583 &dev_attr_idProduct.attr,
523 &dev_attr_bcdDevice.attr, 584 &dev_attr_bcdDevice.attr,
@@ -529,10 +590,13 @@ static struct attribute *dev_attrs[] = {
529 &dev_attr_speed.attr, 590 &dev_attr_speed.attr,
530 &dev_attr_busnum.attr, 591 &dev_attr_busnum.attr,
531 &dev_attr_devnum.attr, 592 &dev_attr_devnum.attr,
593 &dev_attr_devpath.attr,
532 &dev_attr_version.attr, 594 &dev_attr_version.attr,
533 &dev_attr_maxchild.attr, 595 &dev_attr_maxchild.attr,
534 &dev_attr_quirks.attr, 596 &dev_attr_quirks.attr,
597 &dev_attr_avoid_reset_quirk.attr,
535 &dev_attr_authorized.attr, 598 &dev_attr_authorized.attr,
599 &dev_attr_remove.attr,
536 NULL, 600 NULL,
537}; 601};
538static struct attribute_group dev_attr_grp = { 602static struct attribute_group dev_attr_grp = {