diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-28 14:15:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-06-28 14:15:17 -0400 |
commit | 2e34b429a404675dc4fc4ad2ee339eea028da3ca (patch) | |
tree | 93c9595fa65bf1e676f9b2a2b03bc8c187c25d06 /drivers/usb/core | |
parent | 04b905942b482092a547798a2477f21e32a8f65d (diff) | |
parent | 857aab34f04ff86666aa80e751ee696eff0113dd (diff) |
Merge branch 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* 'usb-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6:
MAINTAINERS: add myself as maintainer of USB/IP
usb: r8a66597-hcd: fix cannot detect low/full speed device
USB: ehci-ath79: fix a NULL pointer dereference
USB: Add new FT232H chip to drivers/usb/serial/ftdi_sio.c
usb/isp1760: Fix bug preventing the unlinking of control urbs
USB: Fix up URB error codes to reflect implementation.
xhci: Always set urb->status to zero for isoc endpoints.
xhci: Add reset on resume quirk for asrock p67 host
xHCI 1.0: Incompatible Device Error
USB: don't let errors prevent system sleep
USB: don't let the hub driver prevent system sleep
USB: change maintainership of ohci-hcd and ehci-hcd
xHCI 1.0: Force Stopped Event(FSE)
xhci: Don't warn about zeroed bMaxBurst descriptor field.
USB: Free bandwidth when usb_disable_device is called.
xhci: Reject double add of active endpoints.
USB: TI 3410/5052 USB Serial Driver: Fix mem leak when firmware is too big.
usb: musb: gadget: clear TXPKTRDY flag when set FLUSHFIFO
usb: musb: host: compare status for negative error values
Diffstat (limited to 'drivers/usb/core')
-rw-r--r-- | drivers/usb/core/driver.c | 11 | ||||
-rw-r--r-- | drivers/usb/core/hub.c | 16 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 15 |
3 files changed, 35 insertions, 7 deletions
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index aa3cc465a601..34e3da5aa72a 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -1187,13 +1187,22 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1187 | for (i = n - 1; i >= 0; --i) { | 1187 | for (i = n - 1; i >= 0; --i) { |
1188 | intf = udev->actconfig->interface[i]; | 1188 | intf = udev->actconfig->interface[i]; |
1189 | status = usb_suspend_interface(udev, intf, msg); | 1189 | status = usb_suspend_interface(udev, intf, msg); |
1190 | |||
1191 | /* Ignore errors during system sleep transitions */ | ||
1192 | if (!(msg.event & PM_EVENT_AUTO)) | ||
1193 | status = 0; | ||
1190 | if (status != 0) | 1194 | if (status != 0) |
1191 | break; | 1195 | break; |
1192 | } | 1196 | } |
1193 | } | 1197 | } |
1194 | if (status == 0) | 1198 | if (status == 0) { |
1195 | status = usb_suspend_device(udev, msg); | 1199 | status = usb_suspend_device(udev, msg); |
1196 | 1200 | ||
1201 | /* Again, ignore errors during system sleep transitions */ | ||
1202 | if (!(msg.event & PM_EVENT_AUTO)) | ||
1203 | status = 0; | ||
1204 | } | ||
1205 | |||
1197 | /* If the suspend failed, resume interfaces that did get suspended */ | 1206 | /* If the suspend failed, resume interfaces that did get suspended */ |
1198 | if (status != 0) { | 1207 | if (status != 0) { |
1199 | msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME); | 1208 | msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 90ae1753dda1..a428aa080a36 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -1634,6 +1634,7 @@ void usb_disconnect(struct usb_device **pdev) | |||
1634 | { | 1634 | { |
1635 | struct usb_device *udev = *pdev; | 1635 | struct usb_device *udev = *pdev; |
1636 | int i; | 1636 | int i; |
1637 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
1637 | 1638 | ||
1638 | if (!udev) { | 1639 | if (!udev) { |
1639 | pr_debug ("%s nodev\n", __func__); | 1640 | pr_debug ("%s nodev\n", __func__); |
@@ -1661,7 +1662,9 @@ void usb_disconnect(struct usb_device **pdev) | |||
1661 | * so that the hardware is now fully quiesced. | 1662 | * so that the hardware is now fully quiesced. |
1662 | */ | 1663 | */ |
1663 | dev_dbg (&udev->dev, "unregistering device\n"); | 1664 | dev_dbg (&udev->dev, "unregistering device\n"); |
1665 | mutex_lock(hcd->bandwidth_mutex); | ||
1664 | usb_disable_device(udev, 0); | 1666 | usb_disable_device(udev, 0); |
1667 | mutex_unlock(hcd->bandwidth_mutex); | ||
1665 | usb_hcd_synchronize_unlinks(udev); | 1668 | usb_hcd_synchronize_unlinks(udev); |
1666 | 1669 | ||
1667 | usb_remove_ep_devs(&udev->ep0); | 1670 | usb_remove_ep_devs(&udev->ep0); |
@@ -2362,6 +2365,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg) | |||
2362 | USB_DEVICE_REMOTE_WAKEUP, 0, | 2365 | USB_DEVICE_REMOTE_WAKEUP, 0, |
2363 | NULL, 0, | 2366 | NULL, 0, |
2364 | USB_CTRL_SET_TIMEOUT); | 2367 | USB_CTRL_SET_TIMEOUT); |
2368 | |||
2369 | /* System sleep transitions should never fail */ | ||
2370 | if (!(msg.event & PM_EVENT_AUTO)) | ||
2371 | status = 0; | ||
2365 | } else { | 2372 | } else { |
2366 | /* device has up to 10 msec to fully suspend */ | 2373 | /* device has up to 10 msec to fully suspend */ |
2367 | dev_dbg(&udev->dev, "usb %ssuspend\n", | 2374 | dev_dbg(&udev->dev, "usb %ssuspend\n", |
@@ -2611,16 +2618,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | |||
2611 | struct usb_device *hdev = hub->hdev; | 2618 | struct usb_device *hdev = hub->hdev; |
2612 | unsigned port1; | 2619 | unsigned port1; |
2613 | 2620 | ||
2614 | /* fail if children aren't already suspended */ | 2621 | /* Warn if children aren't already suspended */ |
2615 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { | 2622 | for (port1 = 1; port1 <= hdev->maxchild; port1++) { |
2616 | struct usb_device *udev; | 2623 | struct usb_device *udev; |
2617 | 2624 | ||
2618 | udev = hdev->children [port1-1]; | 2625 | udev = hdev->children [port1-1]; |
2619 | if (udev && udev->can_submit) { | 2626 | if (udev && udev->can_submit) { |
2620 | if (!(msg.event & PM_EVENT_AUTO)) | 2627 | dev_warn(&intf->dev, "port %d nyet suspended\n", port1); |
2621 | dev_dbg(&intf->dev, "port %d nyet suspended\n", | 2628 | if (msg.event & PM_EVENT_AUTO) |
2622 | port1); | 2629 | return -EBUSY; |
2623 | return -EBUSY; | ||
2624 | } | 2630 | } |
2625 | } | 2631 | } |
2626 | 2632 | ||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 5701e857392b..64c7ab4702df 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1135,10 +1135,13 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, | |||
1135 | * Deallocates hcd/hardware state for the endpoints (nuking all or most | 1135 | * Deallocates hcd/hardware state for the endpoints (nuking all or most |
1136 | * pending urbs) and usbcore state for the interfaces, so that usbcore | 1136 | * pending urbs) and usbcore state for the interfaces, so that usbcore |
1137 | * must usb_set_configuration() before any interfaces could be used. | 1137 | * must usb_set_configuration() before any interfaces could be used. |
1138 | * | ||
1139 | * Must be called with hcd->bandwidth_mutex held. | ||
1138 | */ | 1140 | */ |
1139 | void usb_disable_device(struct usb_device *dev, int skip_ep0) | 1141 | void usb_disable_device(struct usb_device *dev, int skip_ep0) |
1140 | { | 1142 | { |
1141 | int i; | 1143 | int i; |
1144 | struct usb_hcd *hcd = bus_to_hcd(dev->bus); | ||
1142 | 1145 | ||
1143 | /* getting rid of interfaces will disconnect | 1146 | /* getting rid of interfaces will disconnect |
1144 | * any drivers bound to them (a key side effect) | 1147 | * any drivers bound to them (a key side effect) |
@@ -1172,6 +1175,16 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1172 | 1175 | ||
1173 | dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, | 1176 | dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, |
1174 | skip_ep0 ? "non-ep0" : "all"); | 1177 | skip_ep0 ? "non-ep0" : "all"); |
1178 | if (hcd->driver->check_bandwidth) { | ||
1179 | /* First pass: Cancel URBs, leave endpoint pointers intact. */ | ||
1180 | for (i = skip_ep0; i < 16; ++i) { | ||
1181 | usb_disable_endpoint(dev, i, false); | ||
1182 | usb_disable_endpoint(dev, i + USB_DIR_IN, false); | ||
1183 | } | ||
1184 | /* Remove endpoints from the host controller internal state */ | ||
1185 | usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL); | ||
1186 | /* Second pass: remove endpoint pointers */ | ||
1187 | } | ||
1175 | for (i = skip_ep0; i < 16; ++i) { | 1188 | for (i = skip_ep0; i < 16; ++i) { |
1176 | usb_disable_endpoint(dev, i, true); | 1189 | usb_disable_endpoint(dev, i, true); |
1177 | usb_disable_endpoint(dev, i + USB_DIR_IN, true); | 1190 | usb_disable_endpoint(dev, i + USB_DIR_IN, true); |
@@ -1727,6 +1740,7 @@ free_interfaces: | |||
1727 | /* if it's already configured, clear out old state first. | 1740 | /* if it's already configured, clear out old state first. |
1728 | * getting rid of old interfaces means unbinding their drivers. | 1741 | * getting rid of old interfaces means unbinding their drivers. |
1729 | */ | 1742 | */ |
1743 | mutex_lock(hcd->bandwidth_mutex); | ||
1730 | if (dev->state != USB_STATE_ADDRESS) | 1744 | if (dev->state != USB_STATE_ADDRESS) |
1731 | usb_disable_device(dev, 1); /* Skip ep0 */ | 1745 | usb_disable_device(dev, 1); /* Skip ep0 */ |
1732 | 1746 | ||
@@ -1739,7 +1753,6 @@ free_interfaces: | |||
1739 | * host controller will not allow submissions to dropped endpoints. If | 1753 | * host controller will not allow submissions to dropped endpoints. If |
1740 | * this call fails, the device state is unchanged. | 1754 | * this call fails, the device state is unchanged. |
1741 | */ | 1755 | */ |
1742 | mutex_lock(hcd->bandwidth_mutex); | ||
1743 | ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); | 1756 | ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL); |
1744 | if (ret < 0) { | 1757 | if (ret < 0) { |
1745 | mutex_unlock(hcd->bandwidth_mutex); | 1758 | mutex_unlock(hcd->bandwidth_mutex); |