Merge 3.2-rc1 into usb-linus
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Apr 2012 15:26:51 +0000 (08:26 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 8 Apr 2012 15:26:51 +0000 (08:26 -0700)
This is needed to catch the resume bug that was bothering lots of us from
testing some XHCI bug fixes in the suspend/resume path.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/usb/URB.txt
Documentation/usb/usbmon.txt
drivers/usb/Kconfig
drivers/usb/core/message.c
drivers/usb/core/urb.c
drivers/usb/gadget/inode.c
drivers/usb/storage/usb.c

index 8ffce746d496fc41de3cfadf7ad02af5f7fa6637..00d2c644068e9ae5d0e0044150289f0976a0ae9d 100644 (file)
@@ -168,6 +168,28 @@ that if the completion handler or anyone else tries to resubmit it
 they will get a -EPERM error.  Thus you can be sure that when
 usb_kill_urb() returns, the URB is totally idle.
 
+There is a lifetime issue to consider.  An URB may complete at any
+time, and the completion handler may free the URB.  If this happens
+while usb_unlink_urb or usb_kill_urb is running, it will cause a
+memory-access violation.  The driver is responsible for avoiding this,
+which often means some sort of lock will be needed to prevent the URB
+from being deallocated while it is still in use.
+
+On the other hand, since usb_unlink_urb may end up calling the
+completion handler, the handler must not take any lock that is held
+when usb_unlink_urb is invoked.  The general solution to this problem
+is to increment the URB's reference count while holding the lock, then
+drop the lock and call usb_unlink_urb or usb_kill_urb, and then
+decrement the URB's reference count.  You increment the reference
+count by calling
+
+       struct urb *usb_get_urb(struct urb *urb)
+
+(ignore the return value; it is the same as the argument) and
+decrement the reference count by calling usb_free_urb.  Of course,
+none of this is necessary if there's no danger of the URB being freed
+by the completion handler.
+
 
 1.7. What about the completion handler?
 
index 5335fa8b06eb4f2b632126bd9fd95878b6efdce0..c42bb9cd3b43749837f1c784a2571cb6d42bf03f 100644 (file)
@@ -183,10 +183,10 @@ An input control transfer to get a port status.
 d5ea89a0 3575914555 S Ci:1:001:0 s a3 00 0000 0003 0004 4 <
 d5ea89a0 3575914560 C Ci:1:001:0 0 4 = 01050000
 
-An output bulk transfer to send a SCSI command 0x5E in a 31-byte Bulk wrapper
-to a storage device at address 5:
+An output bulk transfer to send a SCSI command 0x28 (READ_10) in a 31-byte
+Bulk wrapper to a storage device at address 5:
 
-dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 5e000000 00000000 00000600 00000000 00000000 00000000 000000
+dd65f0e8 4128379752 S Bo:1:005:2 -115 31 = 55534243 ad000000 00800000 80010a28 20000000 20000040 00000000 000000
 dd65f0e8 4128379808 C Bo:1:005:2 0 31 >
 
 * Raw binary format and API
index cbd8f5f805962a2d1e6b87bce4f7c37137bb5e4c..76316a33061b91b48a62a60f6be1b921227c6ed8 100644 (file)
@@ -2,14 +2,6 @@
 # USB device configuration
 #
 
-menuconfig USB_SUPPORT
-       bool "USB support"
-       depends on HAS_IOMEM
-       default y
-       ---help---
-         This option adds core support for Universal Serial Bus (USB).
-         You will also need drivers from the following menu to make use of it.
-
 # many non-PCI SOC chips embed OHCI
 config USB_ARCH_HAS_OHCI
        boolean
@@ -63,6 +55,14 @@ config USB_ARCH_HAS_XHCI
        boolean
        default PCI
 
+menuconfig USB_SUPPORT
+       bool "USB support"
+       depends on HAS_IOMEM
+       default y
+       ---help---
+         This option adds core support for Universal Serial Bus (USB).
+         You will also need drivers from the following menu to make use of it.
+
 if USB_SUPPORT
 
 config USB_COMMON
index b3bdfede45e68721376c381a42950044da9625ad..aed3e07942d458b8f32b95defd766d30fd7d2ee9 100644 (file)
@@ -308,7 +308,8 @@ static void sg_complete(struct urb *urb)
                                retval = usb_unlink_urb(io->urbs [i]);
                                if (retval != -EINPROGRESS &&
                                    retval != -ENODEV &&
-                                   retval != -EBUSY)
+                                   retval != -EBUSY &&
+                                   retval != -EIDRM)
                                        dev_err(&io->dev->dev,
                                                "%s, unlink --> %d\n",
                                                __func__, retval);
@@ -317,7 +318,6 @@ static void sg_complete(struct urb *urb)
                }
                spin_lock(&io->lock);
        }
-       urb->dev = NULL;
 
        /* on the last completion, signal usb_sg_wait() */
        io->bytes += urb->actual_length;
@@ -524,7 +524,6 @@ void usb_sg_wait(struct usb_sg_request *io)
                case -ENXIO:    /* hc didn't queue this one */
                case -EAGAIN:
                case -ENOMEM:
-                       io->urbs[i]->dev = NULL;
                        retval = 0;
                        yield();
                        break;
@@ -542,7 +541,6 @@ void usb_sg_wait(struct usb_sg_request *io)
 
                        /* fail any uncompleted urbs */
                default:
-                       io->urbs[i]->dev = NULL;
                        io->urbs[i]->status = retval;
                        dev_dbg(&io->dev->dev, "%s, submit --> %d\n",
                                __func__, retval);
@@ -593,7 +591,10 @@ void usb_sg_cancel(struct usb_sg_request *io)
                        if (!io->urbs [i]->dev)
                                continue;
                        retval = usb_unlink_urb(io->urbs [i]);
-                       if (retval != -EINPROGRESS && retval != -EBUSY)
+                       if (retval != -EINPROGRESS
+                                       && retval != -ENODEV
+                                       && retval != -EBUSY
+                                       && retval != -EIDRM)
                                dev_warn(&io->dev->dev, "%s, unlink --> %d\n",
                                        __func__, retval);
                }
index 7239a73c1b8c840f89fb22ab19b351bec1dd2b53..cd9b3a2cd8a73cef173d19971213778343edad30 100644 (file)
@@ -539,6 +539,10 @@ EXPORT_SYMBOL_GPL(usb_submit_urb);
  * never submitted, or it was unlinked before, or the hardware is already
  * finished with it), even if the completion handler has not yet run.
  *
+ * The URB must not be deallocated while this routine is running.  In
+ * particular, when a driver calls this routine, it must insure that the
+ * completion handler cannot deallocate the URB.
+ *
  * Unlinking and Endpoint Queues:
  *
  * [The behaviors and guarantees described below do not apply to virtual
@@ -603,6 +607,10 @@ EXPORT_SYMBOL_GPL(usb_unlink_urb);
  * with error -EPERM.  Thus even if the URB's completion handler always
  * tries to resubmit, it will not succeed and the URB will become idle.
  *
+ * The URB must not be deallocated while this routine is running.  In
+ * particular, when a driver calls this routine, it must insure that the
+ * completion handler cannot deallocate the URB.
+ *
  * This routine may not be used in an interrupt context (such as a bottom
  * half or a completion handler), or when holding a spinlock, or in other
  * situations where the caller can't schedule().
@@ -640,6 +648,10 @@ EXPORT_SYMBOL_GPL(usb_kill_urb);
  * with error -EPERM.  Thus even if the URB's completion handler always
  * tries to resubmit, it will not succeed and the URB will become idle.
  *
+ * The URB must not be deallocated while this routine is running.  In
+ * particular, when a driver calls this routine, it must insure that the
+ * completion handler cannot deallocate the URB.
+ *
  * This routine may not be used in an interrupt context (such as a bottom
  * half or a completion handler), or when holding a spinlock, or in other
  * situations where the caller can't schedule().
index 8793f32bab113524fcd5f184c0fed016be0e189f..e58b1644297172a8c1136fc78b2aea802df17f41 100644 (file)
@@ -1574,7 +1574,6 @@ static void destroy_ep_files (struct dev_data *dev)
        DBG (dev, "%s %d\n", __func__, dev->state);
 
        /* dev->state must prevent interference */
-restart:
        spin_lock_irq (&dev->lock);
        while (!list_empty(&dev->epfiles)) {
                struct ep_data  *ep;
index c18538e4a6db1e0adeb26437b3b6f2de38b6b38c..2653e73db6233eabcf83f527019451820157e65d 100644 (file)
@@ -132,6 +132,35 @@ static struct us_unusual_dev for_dynamic_ids =
 #undef COMPLIANT_DEV
 #undef USUAL_DEV
 
+#ifdef CONFIG_LOCKDEP
+
+static struct lock_class_key us_interface_key[USB_MAXINTERFACES];
+
+static void us_set_lock_class(struct mutex *mutex,
+               struct usb_interface *intf)
+{
+       struct usb_device *udev = interface_to_usbdev(intf);
+       struct usb_host_config *config = udev->actconfig;
+       int i;
+
+       for (i = 0; i < config->desc.bNumInterfaces; i++) {
+               if (config->interface[i] == intf)
+                       break;
+       }
+
+       BUG_ON(i == config->desc.bNumInterfaces);
+
+       lockdep_set_class(mutex, &us_interface_key[i]);
+}
+
+#else
+
+static void us_set_lock_class(struct mutex *mutex,
+               struct usb_interface *intf)
+{
+}
+
+#endif
 
 #ifdef CONFIG_PM       /* Minimal support for suspend and resume */
 
@@ -895,6 +924,7 @@ int usb_stor_probe1(struct us_data **pus,
        *pus = us = host_to_us(host);
        memset(us, 0, sizeof(struct us_data));
        mutex_init(&(us->dev_mutex));
+       us_set_lock_class(&us->dev_mutex, intf);
        init_completion(&us->cmnd_ready);
        init_completion(&(us->notify));
        init_waitqueue_head(&us->delay_wait);