aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/usb2/core
diff options
context:
space:
mode:
authorAndrew Thompson <thompsa@FreeBSD.org>2009-01-13 19:02:30 +0000
committerAndrew Thompson <thompsa@FreeBSD.org>2009-01-13 19:02:30 +0000
commitf3396b74be0eaf844e6499d8ffb028721b6a3356 (patch)
tree740ec279f95f973de7e4f03828803329f45ee7c3 /sys/dev/usb2/core
parent63812bb50a21a8147b47cb4aafcc595b15b73d9e (diff)
Notes
Diffstat (limited to 'sys/dev/usb2/core')
-rw-r--r--sys/dev/usb2/core/usb2_generic.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/sys/dev/usb2/core/usb2_generic.c b/sys/dev/usb2/core/usb2_generic.c
index 1b3c316b605b..c486be0231df 100644
--- a/sys/dev/usb2/core/usb2_generic.c
+++ b/sys/dev/usb2/core/usb2_generic.c
@@ -1688,15 +1688,23 @@ ugen_set_power_mode(struct usb2_fifo *f, int mode)
{
struct usb2_device *udev = f->udev;
int err;
+ uint8_t old_mode;
if ((udev == NULL) ||
(udev->parent_hub == NULL)) {
return (EINVAL);
}
err = priv_check(curthread, PRIV_ROOT);
- if (err) {
+ if (err)
return (err);
- }
+
+ /* get old power mode */
+ old_mode = udev->power_mode;
+
+ /* if no change, then just return */
+ if (old_mode == mode)
+ return (0);
+
switch (mode) {
case USB_POWER_MODE_OFF:
/* get the device unconfigured */
@@ -1734,6 +1742,13 @@ ugen_set_power_mode(struct usb2_fifo *f, int mode)
if (err)
return (ENXIO); /* I/O failure */
+ /* if we are powered off we need to re-enumerate first */
+ if (old_mode == USB_POWER_MODE_OFF) {
+ err = ugen_re_enumerate(f);
+ if (err)
+ return (err);
+ }
+
/* set new power mode */
usb2_set_power_mode(udev, mode);