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
This commit is contained in:
@@ -1187,13 +1187,22 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
|
||||
for (i = n - 1; i >= 0; --i) {
|
||||
intf = udev->actconfig->interface[i];
|
||||
status = usb_suspend_interface(udev, intf, msg);
|
||||
|
||||
/* Ignore errors during system sleep transitions */
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
status = 0;
|
||||
if (status != 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status == 0)
|
||||
if (status == 0) {
|
||||
status = usb_suspend_device(udev, msg);
|
||||
|
||||
/* Again, ignore errors during system sleep transitions */
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
status = 0;
|
||||
}
|
||||
|
||||
/* If the suspend failed, resume interfaces that did get suspended */
|
||||
if (status != 0) {
|
||||
msg.event ^= (PM_EVENT_SUSPEND | PM_EVENT_RESUME);
|
||||
|
@@ -1634,6 +1634,7 @@ void usb_disconnect(struct usb_device **pdev)
|
||||
{
|
||||
struct usb_device *udev = *pdev;
|
||||
int i;
|
||||
struct usb_hcd *hcd = bus_to_hcd(udev->bus);
|
||||
|
||||
if (!udev) {
|
||||
pr_debug ("%s nodev\n", __func__);
|
||||
@@ -1661,7 +1662,9 @@ void usb_disconnect(struct usb_device **pdev)
|
||||
* so that the hardware is now fully quiesced.
|
||||
*/
|
||||
dev_dbg (&udev->dev, "unregistering device\n");
|
||||
mutex_lock(hcd->bandwidth_mutex);
|
||||
usb_disable_device(udev, 0);
|
||||
mutex_unlock(hcd->bandwidth_mutex);
|
||||
usb_hcd_synchronize_unlinks(udev);
|
||||
|
||||
usb_remove_ep_devs(&udev->ep0);
|
||||
@@ -2362,6 +2365,10 @@ int usb_port_suspend(struct usb_device *udev, pm_message_t msg)
|
||||
USB_DEVICE_REMOTE_WAKEUP, 0,
|
||||
NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
|
||||
/* System sleep transitions should never fail */
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
status = 0;
|
||||
} else {
|
||||
/* device has up to 10 msec to fully suspend */
|
||||
dev_dbg(&udev->dev, "usb %ssuspend\n",
|
||||
@@ -2611,16 +2618,15 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
unsigned port1;
|
||||
|
||||
/* fail if children aren't already suspended */
|
||||
/* Warn if children aren't already suspended */
|
||||
for (port1 = 1; port1 <= hdev->maxchild; port1++) {
|
||||
struct usb_device *udev;
|
||||
|
||||
udev = hdev->children [port1-1];
|
||||
if (udev && udev->can_submit) {
|
||||
if (!(msg.event & PM_EVENT_AUTO))
|
||||
dev_dbg(&intf->dev, "port %d nyet suspended\n",
|
||||
port1);
|
||||
return -EBUSY;
|
||||
dev_warn(&intf->dev, "port %d nyet suspended\n", port1);
|
||||
if (msg.event & PM_EVENT_AUTO)
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1135,10 +1135,13 @@ void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf,
|
||||
* Deallocates hcd/hardware state for the endpoints (nuking all or most
|
||||
* pending urbs) and usbcore state for the interfaces, so that usbcore
|
||||
* must usb_set_configuration() before any interfaces could be used.
|
||||
*
|
||||
* Must be called with hcd->bandwidth_mutex held.
|
||||
*/
|
||||
void usb_disable_device(struct usb_device *dev, int skip_ep0)
|
||||
{
|
||||
int i;
|
||||
struct usb_hcd *hcd = bus_to_hcd(dev->bus);
|
||||
|
||||
/* getting rid of interfaces will disconnect
|
||||
* any drivers bound to them (a key side effect)
|
||||
@@ -1172,6 +1175,16 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
|
||||
|
||||
dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__,
|
||||
skip_ep0 ? "non-ep0" : "all");
|
||||
if (hcd->driver->check_bandwidth) {
|
||||
/* First pass: Cancel URBs, leave endpoint pointers intact. */
|
||||
for (i = skip_ep0; i < 16; ++i) {
|
||||
usb_disable_endpoint(dev, i, false);
|
||||
usb_disable_endpoint(dev, i + USB_DIR_IN, false);
|
||||
}
|
||||
/* Remove endpoints from the host controller internal state */
|
||||
usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
|
||||
/* Second pass: remove endpoint pointers */
|
||||
}
|
||||
for (i = skip_ep0; i < 16; ++i) {
|
||||
usb_disable_endpoint(dev, i, true);
|
||||
usb_disable_endpoint(dev, i + USB_DIR_IN, true);
|
||||
@@ -1727,6 +1740,7 @@ free_interfaces:
|
||||
/* if it's already configured, clear out old state first.
|
||||
* getting rid of old interfaces means unbinding their drivers.
|
||||
*/
|
||||
mutex_lock(hcd->bandwidth_mutex);
|
||||
if (dev->state != USB_STATE_ADDRESS)
|
||||
usb_disable_device(dev, 1); /* Skip ep0 */
|
||||
|
||||
@@ -1739,7 +1753,6 @@ free_interfaces:
|
||||
* host controller will not allow submissions to dropped endpoints. If
|
||||
* this call fails, the device state is unchanged.
|
||||
*/
|
||||
mutex_lock(hcd->bandwidth_mutex);
|
||||
ret = usb_hcd_alloc_bandwidth(dev, cp, NULL, NULL);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(hcd->bandwidth_mutex);
|
||||
|
Reference in New Issue
Block a user