From a8edc42a11e1d7b7e158d4026670fd83854dfcc2 Mon Sep 17 00:00:00 2001
From: David Daney <david.daney@cavium.com>
Date: Thu, 22 Mar 2012 14:01:07 -0700
Subject: usb: Put USB Kconfig items back under USB.

commit 53c6bc24fdc8db87109a5760579cbb060fa644cf (usb: Don't make
USB_ARCH_HAS_{XHCI,OHCI,EHCI} depend on USB_SUPPORT.)  Removed the
dependency of the USB_ARCH_HAS_* symbols on USB_SUPPORT.  However the
resulting Kconfig somehow caused many of the USB configuration items
to appear under the top level devices menu.

To fix this we reunite the 'menuconfig USB_SUPPORT' with the 'if
USB_SUPPORT', and the config items magically go back to their desired
location.

Reported-by: Julian Wollrath <jwollrath@web.de>
Reported-by: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
Reported-by: Borislav Petkov <bp@alien8.de>
Reported-by: Rupesh Gujare <rgujare@ozmodevices.com>
Reported-by: Feng King <ronyjin@tencent.com>
Reported-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Signed-off-by: David Daney <david.daney@cavium.com>
Tested-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/Kconfig | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index cbd8f5f80596..76316a33061b 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -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
-- 
cgit v1.2.1


From c825bab0cef8b90bab8b63eb5686b8c8eb22e798 Mon Sep 17 00:00:00 2001
From: Ming Lei <tom.leiming@gmail.com>
Date: Mon, 19 Mar 2012 15:20:57 +0800
Subject: usb: storage: fix lockdep warning inside usb_stor_pre_reset(v2)

This patch fixes one lockdep warning[1] inside usb_stor_pre_reset.

If the current configuration includes multiple mass storage interfaces,
the 'AA' lockdep warning will be triggered since the lock class of
'us->dev_mutex' is acquired two times in .reset path. It isn't
a real deadlock, so just take the lockdep_set_class annotation to
remove the warning.

[1], lockdep warning log
:[ INFO: possible recursive locking detected ]
:3.3.0-0.rc5.git3.1.fc17.x86_64 #1 Tainted: G        W
:---------------------------------------------
:usb-storage/14846 is trying to acquire lock:
: (&(us->dev_mutex)){+.+.+.}, at: [<ffffffffa0481c0c>] usb_stor_pre_reset+0x1c/0x20 [usb_storage]
:but task is already holding lock:
: (&(us->dev_mutex)){+.+.+.}, at: [<ffffffffa0481c0c>] usb_stor_pre_reset+0x1c/0x20 [usb_storage]
:other info that might help us debug this:
: Possible unsafe locking scenario:
:       CPU0
:       ----
:  lock(&(us->dev_mutex));
:  lock(&(us->dev_mutex));
: *** DEADLOCK ***
: May be due to missing lock nesting notation
:2 locks held by usb-storage/14846:
: #0:  (&__lockdep_no_validate__){......}, at: [<ffffffff8147e6a5>] usb_lock_device_for_reset+0x95/0x100
: #1:  (&(us->dev_mutex)){+.+.+.}, at: [<ffffffffa0481c0c>] usb_stor_pre_reset+0x1c/0x20 [usb_storage]
:stack backtrace:
:Pid: 14846, comm: usb-storage Tainted: G        W 3.3.0-0.rc5.git3.1.fc17.x86_64 #1
:Call Trace:
: [<ffffffff810cbdaf>] __lock_acquire+0x168f/0x1bb0
: [<ffffffff81021083>] ? native_sched_clock+0x13/0x80
: [<ffffffff810210f9>] ? sched_clock+0x9/0x10
: [<ffffffff810210f9>] ? sched_clock+0x9/0x10
: [<ffffffff810a2975>] ? sched_clock_local+0x25/0xa0
: [<ffffffff810cc9a1>] lock_acquire+0xa1/0x1e0
: [<ffffffffa0481c0c>] ? usb_stor_pre_reset+0x1c/0x20 [usb_storage]
: [<ffffffff81699c86>] mutex_lock_nested+0x76/0x3a0
: [<ffffffffa0481c0c>] ? usb_stor_pre_reset+0x1c/0x20 [usb_storage]
: [<ffffffffa0481c0c>] ? usb_stor_pre_reset+0x1c/0x20 [usb_storage]
: [<ffffffffa0481c0c>] usb_stor_pre_reset+0x1c/0x20 [usb_storage]
: [<ffffffff8148184d>] usb_reset_device+0x7d/0x190
: [<ffffffffa048119c>] usb_stor_port_reset+0x7c/0x80 [usb_storage]
: [<ffffffffa0481234>] usb_stor_invoke_transport+0x94/0x560 [usb_storage]
: [<ffffffff810cd3b2>] ? mark_held_locks+0xb2/0x130
: [<ffffffff8169dbd0>] ? _raw_spin_unlock_irq+0x30/0x50
: [<ffffffffa047fe3e>] usb_stor_transparent_scsi_command+0xe/0x10 [usb_storage]
: [<ffffffffa0481ae3>] usb_stor_control_thread+0x173/0x280 [usb_storage]
: [<ffffffffa0481970>] ? fill_inquiry_response+0x20/0x20 [usb_storage]
: [<ffffffff8108a3f7>] kthread+0xb7/0xc0
: [<ffffffff816a7d34>] kernel_thread_helper+0x4/0x10
: [<ffffffff8169e0f4>] ? retint_restore_args+0x13/0x13
: [<ffffffff8108a340>] ? kthread_worker_fn+0x1a0/0x1a0
: [<ffffffff816a7d30>] ? gs_change+0x13/0x13

Reported-By: Dave Jones <davej@redhat.com>
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/storage/usb.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index c18538e4a6db..2653e73db623 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -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);
-- 
cgit v1.2.1


From bcf398537630bf20b4dbe59ba855b69f404c93cf Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Thu, 22 Mar 2012 11:00:21 -0400
Subject: USB: don't clear urb->dev in scatter-gather library

This patch (as1517b) fixes an error in the USB scatter-gather library.
The library code uses urb->dev to determine whether or nor an URB is
currently active; the completion handler sets urb->dev to NULL.
However the core unlinking routines need to use urb->dev.  Since
unlinking always racing with completion, the completion handler must
not clear urb->dev -- it can lead to invalid memory accesses when a
transfer has to be cancelled.

This patch fixes the problem by getting rid of the lines that clear
urb->dev after urb has been submitted.  As a result we may end up
trying to unlink an URB that failed in submission or that has already
completed, so an extra check is added after each unlink to avoid
printing an error message when this happens.  The checks are updated
in both sg_complete() and sg_cancel(), and the second is updated to
match the first (currently it prints out unnecessary warning messages
if a device is unplugged while a transfer is in progress).

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-and-tested-by: Illia Zaitsev <I.Zaitsev@adbglobal.com>
CC: Ming Lei <tom.leiming@gmail.com>
CC: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/core/message.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index b3bdfede45e6..aed3e07942d4 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -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);
 		}
-- 
cgit v1.2.1


From da8bfb090c2b30af9f3879443355f7eb1d0fe10a Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Wed, 28 Mar 2012 16:13:28 -0400
Subject: USB documentation: explain lifetime rules for unlinking URBs

This patch (as1534c) updates the documentation for usb_unlink_urb and
related functions.  It explains that the caller must prevent the URB
being unlinked from getting deallocated while the unlink is taking
place.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Ming Lei <tom.leiming@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/core/urb.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
index 7239a73c1b8c..cd9b3a2cd8a7 100644
--- a/drivers/usb/core/urb.c
+++ b/drivers/usb/core/urb.c
@@ -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().
-- 
cgit v1.2.1


From a2457ee691edeffb511dbff9a69008f480192197 Mon Sep 17 00:00:00 2001
From: Michael BRIGHT <mjbrightfr@gmail.com>
Date: Thu, 22 Mar 2012 18:42:52 +0100
Subject: USB: remove compile warning on gadget/inode.c

Removed unused "restart:" label, which was causing compiler warning.

Signed-off-by: Michael BRIGHT <mjbrightfr+git-kernel@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/gadget/inode.c | 1 -
 1 file changed, 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c
index 8793f32bab11..e58b16442971 100644
--- a/drivers/usb/gadget/inode.c
+++ b/drivers/usb/gadget/inode.c
@@ -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;
-- 
cgit v1.2.1


From ce5c9851855bab190c9a142761d54ba583ab094c Mon Sep 17 00:00:00 2001
From: Johan Hovold <jhovold@gmail.com>
Date: Fri, 23 Mar 2012 15:23:18 +0100
Subject: USB: pl2303: fix DTR/RTS being raised on baud rate change
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

DTR/RTS should only be raised when changing baudrate from B0 and not on
any baud rate change (> B0).

Reported-by: Søren Holm <sgh@sgh.dk>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/pl2303.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index ff4a174fa5de..a1a9062954c4 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -420,7 +420,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
 	control = priv->line_control;
 	if ((cflag & CBAUD) == B0)
 		priv->line_control &= ~(CONTROL_DTR | CONTROL_RTS);
-	else
+	else if ((old_termios->c_cflag & CBAUD) == B0)
 		priv->line_control |= (CONTROL_DTR | CONTROL_RTS);
 	if (control != priv->line_control) {
 		control = priv->line_control;
-- 
cgit v1.2.1


From 9ac2feb22b5b821d81463bef92698ef7682a3145 Mon Sep 17 00:00:00 2001
From: Santiago Garcia Mantinan <manty@debian.org>
Date: Mon, 19 Mar 2012 18:17:00 +0100
Subject: USB: option: re-add NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED to
 option_id array

Re-add NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED to option_id array

Signed-off-by: Santiago Garcia Mantinan <manty@debian.org>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/option.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 836cfa9a515f..f4465ccddc35 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -708,6 +708,7 @@ static const struct usb_device_id option_ids[] = {
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) },
+	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED3) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED4) },
 	{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED5) },
-- 
cgit v1.2.1


From 3a450850e2bb0f92cacb12da90fe98eccd105468 Mon Sep 17 00:00:00 2001
From: Aleksey Babahin <tamerlan311@gmail.com>
Date: Tue, 20 Mar 2012 00:46:31 +0400
Subject: USB: serial: metro-usb: Fix idProduct for Uni-Directional mode.

The right idProduct for Metrologic Bar Code Scanner
in Uni-Directional Serial Emulation mode is 0x0700.

Also rename idProduct for Bi-Directional mode to be a bit more informative.

Signed-off-by: Aleksey Babahin <tamerlan311@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/metro-usb.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c
index 6e1622f2a297..08d16e8c002d 100644
--- a/drivers/usb/serial/metro-usb.c
+++ b/drivers/usb/serial/metro-usb.c
@@ -27,8 +27,8 @@
 
 /* Product information. */
 #define FOCUS_VENDOR_ID			0x0C2E
-#define FOCUS_PRODUCT_ID		0x0720
-#define FOCUS_PRODUCT_ID_UNI		0x0710
+#define FOCUS_PRODUCT_ID_BI		0x0720
+#define FOCUS_PRODUCT_ID_UNI		0x0700
 
 #define METROUSB_SET_REQUEST_TYPE	0x40
 #define METROUSB_SET_MODEM_CTRL_REQUEST	10
@@ -47,7 +47,7 @@ struct metrousb_private {
 
 /* Device table list. */
 static struct usb_device_id id_table[] = {
-	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID) },
+	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_BI) },
 	{ USB_DEVICE(FOCUS_VENDOR_ID, FOCUS_PRODUCT_ID_UNI) },
 	{ }, /* Terminating entry. */
 };
-- 
cgit v1.2.1


From 891a3b1fddb24b4b53426685bd0390bb74c9b5b3 Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Wed, 28 Mar 2012 16:10:49 -0400
Subject: USB: fix bug in serial driver unregistration

This patch (as1536) fixes a bug in the USB serial core.  Unloading and
reloading a serial driver while a serial device is plugged in causes
errors because of the code in usb_serial_disconnect() that tries to
make sure the port_remove method is called.  With the new order of
driver registration introduced in the 3.4 kernel, this is definitely
not the right thing to do (if indeed it ever was).

The patch removes that whole section code, along with the mechanism
for keeping track of each port's registration state, which is no
longer needed.  The driver core can handle all that stuff for us.

Note: This has been tested only with one or two USB serial drivers.
In theory, other drivers might still run into trouble.  But if they
do, it will be the fault of the drivers, not of this patch -- that is,
the drivers will need to be fixed.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-and-tested-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/bus.c        |  5 -----
 drivers/usb/serial/usb-serial.c | 23 ++---------------------
 2 files changed, 2 insertions(+), 26 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index 7f547dc3a590..ed8adb052ca7 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -60,8 +60,6 @@ static int usb_serial_device_probe(struct device *dev)
 		retval = -ENODEV;
 		goto exit;
 	}
-	if (port->dev_state != PORT_REGISTERING)
-		goto exit;
 
 	driver = port->serial->type;
 	if (driver->port_probe) {
@@ -98,9 +96,6 @@ static int usb_serial_device_remove(struct device *dev)
 	if (!port)
 		return -ENODEV;
 
-	if (port->dev_state != PORT_UNREGISTERING)
-		return retval;
-
 	device_remove_file(&port->dev, &dev_attr_port_number);
 
 	driver = port->serial->type;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 69230f01056a..5413bd500781 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1070,17 +1070,12 @@ int usb_serial_probe(struct usb_interface *interface,
 		port = serial->port[i];
 		dev_set_name(&port->dev, "ttyUSB%d", port->number);
 		dbg ("%s - registering %s", __func__, dev_name(&port->dev));
-		port->dev_state = PORT_REGISTERING;
 		device_enable_async_suspend(&port->dev);
 
 		retval = device_add(&port->dev);
-		if (retval) {
+		if (retval)
 			dev_err(&port->dev, "Error registering port device, "
 				"continuing\n");
-			port->dev_state = PORT_UNREGISTERED;
-		} else {
-			port->dev_state = PORT_REGISTERED;
-		}
 	}
 
 	usb_serial_console_init(debug, minor);
@@ -1124,22 +1119,8 @@ void usb_serial_disconnect(struct usb_interface *interface)
 			}
 			kill_traffic(port);
 			cancel_work_sync(&port->work);
-			if (port->dev_state == PORT_REGISTERED) {
-
-				/* Make sure the port is bound so that the
-				 * driver's port_remove method is called.
-				 */
-				if (!port->dev.driver) {
-					int rc;
-
-					port->dev.driver =
-							&serial->type->driver;
-					rc = device_bind_driver(&port->dev);
-				}
-				port->dev_state = PORT_UNREGISTERING;
+			if (device_is_registered(&port->dev))
 				device_del(&port->dev);
-				port->dev_state = PORT_UNREGISTERED;
-			}
 		}
 	}
 	serial->type->disconnect(serial);
-- 
cgit v1.2.1


From cd4376e23a59a2adf3084cb5f4a523e6d5fd4e49 Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Wed, 28 Mar 2012 15:56:17 -0400
Subject: USB: don't ignore suspend errors for root hubs

This patch (as1532) fixes a mistake in the USB suspend code.  When the
system is going to sleep, we should ignore errors in powering down USB
devices, because they don't really matter.  The devices will go to low
power anyway when the entire USB bus gets suspended (except for
SuperSpeed devices; maybe they will need special treatment later).

However we should not ignore errors in suspending root hubs,
especially if the error indicates that the suspend raced with a wakeup
request.  Doing so might leave the bus powered on while the system was
supposed to be asleep, or it might cause the suspend of the root hub's
parent controller device to fail, or it might cause a wakeup request
to be ignored.

The patch fixes the problem by ignoring errors only when the device in
question is not a root hub.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-by: Chen Peter <B29397@freescale.com>
CC: <stable@vger.kernel.org>
Tested-by: Chen Peter <peter.chen@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/core/driver.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index f8e2d6d52e5c..9a56635dc19c 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -1189,8 +1189,13 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg)
 	if (status == 0) {
 		status = usb_suspend_device(udev, msg);
 
-		/* Again, ignore errors during system sleep transitions */
-		if (!PMSG_IS_AUTO(msg))
+		/*
+		 * Ignore errors from non-root-hub devices during
+		 * system sleep transitions.  For the most part,
+		 * these devices should go to low power anyway when
+		 * the entire bus is suspended.
+		 */
+		if (udev->parent && !PMSG_IS_AUTO(msg))
 			status = 0;
 	}
 
-- 
cgit v1.2.1


From fca5430d48d53eaf103498c33fd0d1984b9f448b Mon Sep 17 00:00:00 2001
From: Simon Arlott <simon@fire.lp0.eu>
Date: Mon, 26 Mar 2012 21:19:40 +0100
Subject: USB: ftdi_sio: fix status line change handling for TIOCMIWAIT and
 TIOCGICOUNT

Handling of TIOCMIWAIT was changed by commit 1d749f9afa657f6ee9336b2bc1fcd750a647d157
 USB: ftdi_sio.c: Use ftdi async_icount structure for TIOCMIWAIT, as in other drivers

FTDI_STATUS_B0_MASK does not indicate the changed modem status lines,
it indicates the value of the current modem status lines. An xor is
still required to determine which lines have changed.

The count was only being incremented if the line was high. The only
reason TIOCMIWAIT still worked was because the status packet is
repeated every 1ms, so the count was always changing. The wakeup
itself still ran based on the status lines changing.

This change fixes handling of updates to the modem status lines and
allows multiple processes to use TIOCMIWAIT concurrently.

Tested with two processes waiting on different status lines being
toggled independently.

Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
Cc: Uwe Bonnes <bon@elektron.ikp.physik.tu-darmstadt.de>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/ftdi_sio.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index ff8605b4b4be..c02e4602d90a 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -75,7 +75,7 @@ struct ftdi_private {
 	unsigned long last_dtr_rts;	/* saved modem control outputs */
 	struct async_icount	icount;
 	wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
-	char prev_status, diff_status;        /* Used for TIOCMIWAIT */
+	char prev_status;        /* Used for TIOCMIWAIT */
 	char transmit_empty;	/* If transmitter is empty or not */
 	struct usb_serial_port *port;
 	__u16 interface;	/* FT2232C, FT2232H or FT4232H port interface
@@ -1982,17 +1982,19 @@ static int ftdi_process_packet(struct tty_struct *tty,
 	   N.B. packet may be processed more than once, but differences
 	   are only processed once.  */
 	status = packet[0] & FTDI_STATUS_B0_MASK;
-	if (status & FTDI_RS0_CTS)
-		priv->icount.cts++;
-	if (status & FTDI_RS0_DSR)
-		priv->icount.dsr++;
-	if (status & FTDI_RS0_RI)
-		priv->icount.rng++;
-	if (status & FTDI_RS0_RLSD)
-		priv->icount.dcd++;
 	if (status != priv->prev_status) {
-		priv->diff_status |= status ^ priv->prev_status;
-		wake_up_interruptible(&priv->delta_msr_wait);
+		char diff_status = status ^ priv->prev_status;
+
+		if (diff_status & FTDI_RS0_CTS)
+			priv->icount.cts++;
+		if (diff_status & FTDI_RS0_DSR)
+			priv->icount.dsr++;
+		if (diff_status & FTDI_RS0_RI)
+			priv->icount.rng++;
+		if (diff_status & FTDI_RS0_RLSD)
+			priv->icount.dcd++;
+
+		wake_up_interruptible_all(&priv->delta_msr_wait);
 		priv->prev_status = status;
 	}
 
-- 
cgit v1.2.1


From 876ae50d94b02f3f523aa451b45ec5fb9c25d221 Mon Sep 17 00:00:00 2001
From: Simon Arlott <simon@fire.lp0.eu>
Date: Mon, 26 Mar 2012 23:27:59 +0100
Subject: USB: ftdi_sio: fix race condition in TIOCMIWAIT, and abort of
 TIOCMIWAIT when the device is removed
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

There are two issues here, one is that the device is generating
spurious very fast modem status line changes somewhere:

CTS becomes high then low 18µs later:
[121226.924373] ftdi_process_packet: prev rng=0 dsr=10 dcd=0 cts=6
[121226.924378] ftdi_process_packet: status=10 prev=00 diff=10
[121226.924382] ftdi_process_packet: now rng=0 dsr=10 dcd=0 cts=7
(wake_up_interruptible is called)
[121226.924391] ftdi_process_packet: prev rng=0 dsr=10 dcd=0 cts=7
[121226.924394] ftdi_process_packet: status=00 prev=10 diff=10
[121226.924397] ftdi_process_packet: now rng=0 dsr=10 dcd=0 cts=8
(wake_up_interruptible is called)

This wakes up the task in TIOCMIWAIT:
[121226.924405] ftdi_ioctl: 19451 rng=0->0 dsr=10->10 dcd=0->0 cts=6->8
(wait from 20:51:46 returns and observes both changes)

Which then calls TIOCMIWAIT again:
20:51:46.400239 ioctl(3, TIOCMIWAIT, 0x20) = 0
22:11:09.441818 ioctl(3, TIOCMGET, [TIOCM_DTR|TIOCM_RTS]) = 0
22:11:09.442812 ioctl(3, TIOCMIWAIT, 0x20) = -1 EIO (Input/output error)
(the second wake_up_interruptible takes effect and an I/O error occurs)

The other issue is that TIOCMIWAIT will wait forever (unless the task is
interrupted) if the device is removed.

This change removes the -EIO return that occurs if the counts don't
appear to have changed. Multiple counts may have been processed as
one or the waiting task may have started waiting after recording the
current count.

It adds a bool to indicate that the device has been removed so that
TIOCMIWAIT doesn't wait forever, and wakes up any tasks so that they can
return -EIO.

Signed-off-by: Simon Arlott <simon@fire.lp0.eu>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/ftdi_sio.c | 12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index c02e4602d90a..02e7f2d32d52 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -76,6 +76,7 @@ struct ftdi_private {
 	struct async_icount	icount;
 	wait_queue_head_t delta_msr_wait; /* Used for TIOCMIWAIT */
 	char prev_status;        /* Used for TIOCMIWAIT */
+	bool dev_gone;        /* Used to abort TIOCMIWAIT */
 	char transmit_empty;	/* If transmitter is empty or not */
 	struct usb_serial_port *port;
 	__u16 interface;	/* FT2232C, FT2232H or FT4232H port interface
@@ -1681,6 +1682,7 @@ static int ftdi_sio_port_probe(struct usb_serial_port *port)
 	init_waitqueue_head(&priv->delta_msr_wait);
 
 	priv->flags = ASYNC_LOW_LATENCY;
+	priv->dev_gone = false;
 
 	if (quirk && quirk->port_probe)
 		quirk->port_probe(priv);
@@ -1839,6 +1841,9 @@ static int ftdi_sio_port_remove(struct usb_serial_port *port)
 
 	dbg("%s", __func__);
 
+	priv->dev_gone = true;
+	wake_up_interruptible_all(&priv->delta_msr_wait);
+
 	remove_sysfs_attrs(port);
 
 	kref_put(&priv->kref, ftdi_sio_priv_release);
@@ -2397,15 +2402,12 @@ static int ftdi_ioctl(struct tty_struct *tty,
 	 */
 	case TIOCMIWAIT:
 		cprev = priv->icount;
-		while (1) {
+		while (!priv->dev_gone) {
 			interruptible_sleep_on(&priv->delta_msr_wait);
 			/* see if a signal did it */
 			if (signal_pending(current))
 				return -ERESTARTSYS;
 			cnow = priv->icount;
-			if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
-			    cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
-				return -EIO; /* no change => error */
 			if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
 			    ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
 			    ((arg & TIOCM_CD)  && (cnow.dcd != cprev.dcd)) ||
@@ -2414,7 +2416,7 @@ static int ftdi_ioctl(struct tty_struct *tty,
 			}
 			cprev = cnow;
 		}
-		/* not reached */
+		return -EIO;
 		break;
 	case TIOCSERGETLSR:
 		return get_lsr_info(port, (struct serial_struct __user *)arg);
-- 
cgit v1.2.1


From c5d703dcc776cb542b41665f2b7e2ba054efb4a7 Mon Sep 17 00:00:00 2001
From: Anton Samokhvalov <pg83@yandex.ru>
Date: Wed, 4 Apr 2012 22:26:01 +0400
Subject: USB: sierra: add support for Sierra Wireless MC7710

Just add new device id. 3G works fine, LTE not tested.

Signed-off-by: Anton Samokhvalov <pg83@yandex.ru>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/sierra.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index f14465a83dd1..fdd5aa2c8d82 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -289,6 +289,7 @@ static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x1199, 0x6856) },	/* Sierra Wireless AirCard 881 U */
 	{ USB_DEVICE(0x1199, 0x6859) },	/* Sierra Wireless AirCard 885 E */
 	{ USB_DEVICE(0x1199, 0x685A) },	/* Sierra Wireless AirCard 885 E */
+	{ USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */
 	/* Sierra Wireless C885 */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
 	/* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
-- 
cgit v1.2.1


From 879d38e6bc36d73b0ac40ec9b0d839fda9fa8b1a Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Tue, 3 Apr 2012 15:24:18 -0400
Subject: USB: fix race between root-hub suspend and remote wakeup

This patch (as1533) fixes a race between root-hub suspend and remote
wakeup.  If a wakeup event occurs while a root hub is suspending, it
might not cause the suspend to fail.  Although the host controller
drivers check for pending wakeup events at the start of their
bus_suspend routines, they generally do not check for wakeup events
while the routines are running.

In addition, if a wakeup event occurs any time after khubd is frozen
and before the root hub is fully suspended, it might not cause a
system sleep transition to fail.  For example, the host controller
drivers do not fail root-hub suspends when a connect-change event is
pending.

To fix both these issues, this patch causes hcd_bus_suspend() to query
the controller driver's hub_status_data method after a root hub is
suspended, if the root hub is enabled for wakeup.  Any pending status
changes will count as wakeup events, causing the root hub to be
resumed and the overall suspend to fail with -EBUSY.

A significant point is that not all events are reflected immediately
in the status bits.  Both EHCI and UHCI controllers notify the CPU
when remote wakeup begins on a port, but the port's suspend-change
status bit doesn't get set until after the port has completed the
transition out of the suspend state, some 25 milliseconds later.
Consequently, the patch will interpret any nonzero return value from
hub_status_data as indicating a pending event, even if none of the
status bits are set in the data buffer.  Follow-up patches make the
necessary changes to ehci-hcd and uhci-hcd.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Sarah Sharp <sarah.a.sharp@linux.intel.com>
CC: Chen Peter-B29397 <B29397@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/core/hcd.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 9d7fc9a39933..140d3e11f212 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -1978,6 +1978,18 @@ int hcd_bus_suspend(struct usb_device *rhdev, pm_message_t msg)
 	if (status == 0) {
 		usb_set_device_state(rhdev, USB_STATE_SUSPENDED);
 		hcd->state = HC_STATE_SUSPENDED;
+
+		/* Did we race with a root-hub wakeup event? */
+		if (rhdev->do_remote_wakeup) {
+			char	buffer[6];
+
+			status = hcd->driver->hub_status_data(hcd, buffer);
+			if (status != 0) {
+				dev_dbg(&rhdev->dev, "suspend raced with wakeup event\n");
+				hcd_bus_resume(rhdev, PMSG_AUTO_RESUME);
+				status = -EBUSY;
+			}
+		}
 	} else {
 		spin_lock_irq(&hcd_root_hub_lock);
 		if (!HCD_DEAD(hcd)) {
-- 
cgit v1.2.1


From a448e4dc25303fe551e4dafe16c8c7c34f1b9d82 Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Tue, 3 Apr 2012 15:24:30 -0400
Subject: EHCI: keep track of ports being resumed and indicate in
 hub_status_data

This patch (as1537) adds a bit-array to ehci-hcd for keeping track of
which ports are undergoing a resume transition.  If any of the bits
are set when ehci_hub_status_data() is called, the routine will return
a nonzero value even if no ports have any status changes pending.
This will allow usbcore to handle races between root-hub suspend and
port wakeup.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Sarah Sharp <sarah.a.sharp@linux.intel.com>
CC: Chen Peter-B29397 <B29397@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/host/ehci-hcd.c   |  3 +++
 drivers/usb/host/ehci-hub.c   | 31 ++++++++++++++++---------------
 drivers/usb/host/ehci-tegra.c |  2 ++
 drivers/usb/host/ehci.h       |  2 ++
 4 files changed, 23 insertions(+), 15 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 057cdda7a489..806cc95317aa 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -347,6 +347,8 @@ static int ehci_reset (struct ehci_hcd *ehci)
 	if (ehci->debug)
 		dbgp_external_startup();
 
+	ehci->port_c_suspend = ehci->suspended_ports =
+			ehci->resuming_ports = 0;
 	return retval;
 }
 
@@ -939,6 +941,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 			 * like usb_port_resume() does.
 			 */
 			ehci->reset_done[i] = jiffies + msecs_to_jiffies(25);
+			set_bit(i, &ehci->resuming_ports);
 			ehci_dbg (ehci, "port %d remote wakeup\n", i + 1);
 			mod_timer(&hcd->rh_timer, ehci->reset_done[i]);
 		}
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 256fbd42e48c..38fe07623152 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -223,15 +223,10 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
 	 * remote wakeup, we must fail the suspend.
 	 */
 	if (hcd->self.root_hub->do_remote_wakeup) {
-		port = HCS_N_PORTS(ehci->hcs_params);
-		while (port--) {
-			if (ehci->reset_done[port] != 0) {
-				spin_unlock_irq(&ehci->lock);
-				ehci_dbg(ehci, "suspend failed because "
-						"port %d is resuming\n",
-						port + 1);
-				return -EBUSY;
-			}
+		if (ehci->resuming_ports) {
+			spin_unlock_irq(&ehci->lock);
+			ehci_dbg(ehci, "suspend failed because a port is resuming\n");
+			return -EBUSY;
 		}
 	}
 
@@ -554,16 +549,12 @@ static int
 ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
 {
 	struct ehci_hcd	*ehci = hcd_to_ehci (hcd);
-	u32		temp, status = 0;
+	u32		temp, status;
 	u32		mask;
 	int		ports, i, retval = 1;
 	unsigned long	flags;
 	u32		ppcd = 0;
 
-	/* if !USB_SUSPEND, root hub timers won't get shut down ... */
-	if (ehci->rh_state != EHCI_RH_RUNNING)
-		return 0;
-
 	/* init status to no-changes */
 	buf [0] = 0;
 	ports = HCS_N_PORTS (ehci->hcs_params);
@@ -572,6 +563,11 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf)
 		retval++;
 	}
 
+	/* Inform the core about resumes-in-progress by returning
+	 * a non-zero value even if there are no status changes.
+	 */
+	status = ehci->resuming_ports;
+
 	/* Some boards (mostly VIA?) report bogus overcurrent indications,
 	 * causing massive log spam unless we completely ignore them.  It
 	 * may be relevant that VIA VT8235 controllers, where PORT_POWER is
@@ -846,6 +842,7 @@ static int ehci_hub_control (
 				ehci_writel(ehci,
 					temp & ~(PORT_RWC_BITS | PORT_RESUME),
 					status_reg);
+				clear_bit(wIndex, &ehci->resuming_ports);
 				retval = handshake(ehci, status_reg,
 					   PORT_RESUME, 0, 2000 /* 2msec */);
 				if (retval != 0) {
@@ -864,6 +861,7 @@ static int ehci_hub_control (
 					ehci->reset_done[wIndex])) {
 			status |= USB_PORT_STAT_C_RESET << 16;
 			ehci->reset_done [wIndex] = 0;
+			clear_bit(wIndex, &ehci->resuming_ports);
 
 			/* force reset to complete */
 			ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET),
@@ -884,8 +882,10 @@ static int ehci_hub_control (
 					ehci_readl(ehci, status_reg));
 		}
 
-		if (!(temp & (PORT_RESUME|PORT_RESET)))
+		if (!(temp & (PORT_RESUME|PORT_RESET))) {
 			ehci->reset_done[wIndex] = 0;
+			clear_bit(wIndex, &ehci->resuming_ports);
+		}
 
 		/* transfer dedicated ports to the companion hc */
 		if ((temp & PORT_CONNECT) &&
@@ -920,6 +920,7 @@ static int ehci_hub_control (
 			status |= USB_PORT_STAT_SUSPEND;
 		} else if (test_bit(wIndex, &ehci->suspended_ports)) {
 			clear_bit(wIndex, &ehci->suspended_ports);
+			clear_bit(wIndex, &ehci->resuming_ports);
 			ehci->reset_done[wIndex] = 0;
 			if (temp & PORT_PE)
 				set_bit(wIndex, &ehci->port_c_suspend);
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 3de48a2d7955..73544bd440bd 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -224,6 +224,7 @@ static int tegra_ehci_hub_control(
 		temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
 		/* start resume signalling */
 		ehci_writel(ehci, temp | PORT_RESUME, status_reg);
+		set_bit(wIndex-1, &ehci->resuming_ports);
 
 		spin_unlock_irqrestore(&ehci->lock, flags);
 		msleep(20);
@@ -236,6 +237,7 @@ static int tegra_ehci_hub_control(
 			pr_err("%s: timeout waiting for SUSPEND\n", __func__);
 
 		ehci->reset_done[wIndex-1] = 0;
+		clear_bit(wIndex-1, &ehci->resuming_ports);
 
 		tegra->port_resuming = 1;
 		goto done;
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 8f9acbc96fde..2694ed6558d2 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -117,6 +117,8 @@ struct ehci_hcd {			/* one per controller */
 			the change-suspend feature turned on */
 	unsigned long		suspended_ports;	/* which ports are
 			suspended */
+	unsigned long		resuming_ports;		/* which ports have
+			started to resume */
 
 	/* per-HC memory pools (could be per-bus, but ...) */
 	struct dma_pool		*qh_pool;	/* qh per active urb */
-- 
cgit v1.2.1


From b446b96fd11b69b7c4ecd47d869cff9094fd8802 Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Tue, 3 Apr 2012 15:24:43 -0400
Subject: UHCI: hub_status_data should indicate if ports are resuming

This patch (as1538) causes uhci_hub_status_data() to return a nonzero
value when any port is undergoing a resume transition while the root
hub is suspended.  This will allow usbcore to handle races between
root-hub suspend and port wakeup.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/host/uhci-hub.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c
index 045cde4cbc3d..768d54295a20 100644
--- a/drivers/usb/host/uhci-hub.c
+++ b/drivers/usb/host/uhci-hub.c
@@ -196,11 +196,12 @@ static int uhci_hub_status_data(struct usb_hcd *hcd, char *buf)
 	status = get_hub_status_data(uhci, buf);
 
 	switch (uhci->rh_state) {
-	    case UHCI_RH_SUSPENDING:
 	    case UHCI_RH_SUSPENDED:
 		/* if port change, ask to be resumed */
-		if (status || uhci->resuming_ports)
+		if (status || uhci->resuming_ports) {
+			status = 1;
 			usb_hcd_resume_root_hub(hcd);
+		}
 		break;
 
 	    case UHCI_RH_AUTO_STOPPED:
-- 
cgit v1.2.1


From 6d258a4c42089229b855fd706622029decf316d6 Mon Sep 17 00:00:00 2001
From: Felipe Balbi <balbi@ti.com>
Date: Thu, 15 Mar 2012 16:37:18 +0200
Subject: usb: gadget: udc-core: stop UDC on device-initiated disconnect

When we want to do device-initiated disconnect,
let's make sure we stop the UDC in order to
e.g. allow lower power states to be achieved by
turning off unnecessary clocks and/or stoping
PHYs.

When reconnecting, call ->udc_start() again to
make sure UDC is reinitialized.

Cc: stable@vger.kernel.org
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/udc-core.c | 4 ++++
 1 file changed, 4 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 56da49f31d6c..c261887e05ae 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -411,8 +411,12 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
 	struct usb_udc		*udc = container_of(dev, struct usb_udc, dev);
 
 	if (sysfs_streq(buf, "connect")) {
+		if (udc_is_newstyle(udc))
+			usb_gadget_udc_start(udc->gadget, udc->driver);
 		usb_gadget_connect(udc->gadget);
 	} else if (sysfs_streq(buf, "disconnect")) {
+		if (udc_is_newstyle(udc))
+			usb_gadget_udc_stop(udc->gadget, udc->driver);
 		usb_gadget_disconnect(udc->gadget);
 	} else {
 		dev_err(dev, "unsupported command '%s'\n", buf);
-- 
cgit v1.2.1


From 566ccdda07dc5898272b6fbad9c616fc44be305a Mon Sep 17 00:00:00 2001
From: Moiz Sonasath <m-sonasath@ti.com>
Date: Wed, 14 Mar 2012 00:44:56 -0500
Subject: usb: dwc3: ep0: Handle requests greater than wMaxPacketSize

To allow ep0 out transfers of upto bounce buffer size
instead of maxpacketsize, use the transfer size as multiple
of ep0 maxpacket size.

Cc: stable@vger.kernel.org
Signed-off-by: Moiz Sonasath <m-sonasath@ti.com>
Signed-off-by: Partha Basak <p-basak2@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/dwc3/ep0.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index 25910e251c04..a40d3bb0f1c2 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -559,8 +559,12 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 	length = trb->size & DWC3_TRB_SIZE_MASK;
 
 	if (dwc->ep0_bounced) {
+		unsigned transfer_size = ur->length;
+		unsigned maxp = ep0->endpoint.maxpacket;
+
+		transfer_size += (maxp - (transfer_size % maxp));
 		transferred = min_t(u32, ur->length,
-				ep0->endpoint.maxpacket - length);
+				transfer_size - length);
 		memcpy(ur->buf, dwc->ep0_bounce, transferred);
 		dwc->ep0_bounced = false;
 	} else {
-- 
cgit v1.2.1


From cd423dd3634a5232a3019eb372b144619a61cd16 Mon Sep 17 00:00:00 2001
From: Felipe Balbi <balbi@ti.com>
Date: Wed, 21 Mar 2012 11:44:00 +0200
Subject: usb: dwc3: ep0: increment "actual" on bounced ep0 case

due to a HW limitation we have a bounce buffer for ep0
out transfers which are not aligned with MaxPacketSize.

On such case we were not increment r->actual as we should.

This patch fixes that mistake.

Cc: stable@vger.kernel.org
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/dwc3/ep0.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index a40d3bb0f1c2..da43131be0e7 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -569,9 +569,10 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
 		dwc->ep0_bounced = false;
 	} else {
 		transferred = ur->length - length;
-		ur->actual += transferred;
 	}
 
+	ur->actual += transferred;
+
 	if ((epnum & 1) && ur->actual < ur->length) {
 		/* for some reason we did not get everything out */
 
-- 
cgit v1.2.1


From ecb07797ffc1c2aaa2e58d1ba1b5deea44ea5b9e Mon Sep 17 00:00:00 2001
From: Gerard Cauvy <g-cauvy1@ti.com>
Date: Fri, 16 Mar 2012 16:20:10 +0200
Subject: usb: dwc3: ep0: add a default case for SetFeature command

Without this default case returning an error,
thus replying with a stall, we would fail
USB30CV TD 9.11 Bad Feature test case.

Cc: stable@vger.kernel.org
Signed-off-by: Gerard Cauvy <g-cauvy1@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/dwc3/ep0.c | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index da43131be0e7..3584a169886f 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -353,6 +353,9 @@ static int dwc3_ep0_handle_feature(struct dwc3 *dwc,
 
 			dwc->test_mode_nr = wIndex >> 8;
 			dwc->test_mode = true;
+			break;
+		default:
+			return -EINVAL;
 		}
 		break;
 
-- 
cgit v1.2.1


From afb76df140823c57738598a876cd1d6568cd57c7 Mon Sep 17 00:00:00 2001
From: Vladimir Zapolskiy <vladimir.zapolskiy@nokia.com>
Date: Fri, 23 Dec 2011 18:37:18 +0200
Subject: usb: musb: fix oops on omap2430 module unload

This change prevents runtime suspend and resume actual execution, if
omap2430 controller driver is loaded after musb-hdrc, and therefore the
controller isn't initialized properly.

The problem is reproducible with 3.1.y and 3.2 kernels.

Kernel configuration of musb:

  % cat .config | egrep 'MUSB|GADGET'
  CONFIG_USB_MUSB_HDRC=y
  # CONFIG_USB_MUSB_TUSB6010 is not set
  CONFIG_USB_MUSB_OMAP2PLUS=m
  # CONFIG_USB_MUSB_AM35X is not set
  CONFIG_MUSB_PIO_ONLY=y
  CONFIG_USB_GADGET=y
  # CONFIG_USB_GADGET_DEBUG is not set
  # CONFIG_USB_GADGET_DEBUG_FILES is not set
  # CONFIG_USB_GADGET_DEBUG_FS is not set
  CONFIG_USB_GADGET_VBUS_DRAW=2
  CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
  CONFIG_USB_GADGET_MUSB_HDRC=m
  CONFIG_USB_GADGET_DUALSPEED=y
  CONFIG_USB_GADGETFS=m
  # CONFIG_USB_MIDI_GADGET is not set

Fixes the following oops on module unloading:

  Unable to handle kernel NULL pointer dereference at virtual address 00000220
  ----8<----
  [<bf162088>] (omap2430_runtime_resume+0x24/0x54 [omap2430]) from [<c0302e34>] (pm_generic_runtime_resume+0x3c/0x50)
  [<c0302e34>] (pm_generic_runtime_resume+0x3c/0x50) from [<c0031a24>] (_od_runtime_resume+0x28/0x2c)
  [<c0031a24>] (_od_runtime_resume+0x28/0x2c) from [<c0306cb0>] (__rpm_callback+0x60/0xa0)
  [<c0306cb0>] (__rpm_callback+0x60/0xa0) from [<c0307f2c>] (rpm_resume+0x3fc/0x6e4)
  [<c0307f2c>] (rpm_resume+0x3fc/0x6e4) from [<c030851c>] (__pm_runtime_resume+0x5c/0x90)
  [<c030851c>] (__pm_runtime_resume+0x5c/0x90) from [<c02fd0dc>] (__device_release_driver+0x2c/0xd0)
  [<c02fd0dc>] (__device_release_driver+0x2c/0xd0) from [<c02fda18>] (driver_detach+0xe8/0xf4)
  [<c02fda18>] (driver_detach+0xe8/0xf4) from [<c02fcf88>] (bus_remove_driver+0xa0/0x104)
  [<c02fcf88>] (bus_remove_driver+0xa0/0x104) from [<c02fde54>] (driver_unregister+0x60/0x80)
  [<c02fde54>] (driver_unregister+0x60/0x80) from [<c02ff2d4>] (platform_driver_unregister+0x1c/0x20)
  [<c02ff2d4>] (platform_driver_unregister+0x1c/0x20) from [<bf162928>] (omap2430_exit+0x14/0x1c [omap2430])
  [<bf162928>] (omap2430_exit+0x14/0x1c [omap2430]) from [<c007d8bc>] (sys_delete_module+0x1f4/0x264)
  [<c007d8bc>] (sys_delete_module+0x1f4/0x264) from [<c000f000>] (ret_fast_syscall+0x0/0x30)

Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@nokia.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: stable@vger.kernel.org # 3.1
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/musb/omap2430.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 2ae0bb309994..11b571ec22f2 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -491,11 +491,13 @@ static int omap2430_runtime_suspend(struct device *dev)
 	struct omap2430_glue		*glue = dev_get_drvdata(dev);
 	struct musb			*musb = glue_to_musb(glue);
 
-	musb->context.otg_interfsel = musb_readl(musb->mregs,
-						OTG_INTERFSEL);
+	if (musb) {
+		musb->context.otg_interfsel = musb_readl(musb->mregs,
+				OTG_INTERFSEL);
 
-	omap2430_low_level_exit(musb);
-	usb_phy_set_suspend(musb->xceiv, 1);
+		omap2430_low_level_exit(musb);
+		usb_phy_set_suspend(musb->xceiv, 1);
+	}
 
 	return 0;
 }
@@ -505,11 +507,13 @@ static int omap2430_runtime_resume(struct device *dev)
 	struct omap2430_glue		*glue = dev_get_drvdata(dev);
 	struct musb			*musb = glue_to_musb(glue);
 
-	omap2430_low_level_init(musb);
-	musb_writel(musb->mregs, OTG_INTERFSEL,
-					musb->context.otg_interfsel);
+	if (musb) {
+		omap2430_low_level_init(musb);
+		musb_writel(musb->mregs, OTG_INTERFSEL,
+				musb->context.otg_interfsel);
 
-	usb_phy_set_suspend(musb->xceiv, 0);
+		usb_phy_set_suspend(musb->xceiv, 0);
+	}
 
 	return 0;
 }
-- 
cgit v1.2.1


From c04352a590538123f8c93bd87ef1d4bb9e3a64c7 Mon Sep 17 00:00:00 2001
From: Grazvydas Ignotas <notasas@gmail.com>
Date: Sat, 4 Feb 2012 19:43:51 +0200
Subject: usb: musb: fix some runtime_pm issues

When runtime_pm was originally added, it was done in rather confusing
way: omap2430_musb_init() (called from musb_init_controller) would do
runtime_pm_get_sync() and musb_init_controller() itself would do
runtime_pm_put to balance it out. This is not only confusing but also
wrong if non-omap2430 glue layer is used.

This confusion resulted in commit 772aed45b604 "usb: musb: fix
pm_runtime mismatch", that removed runtime_pm_put() from
musb_init_controller as that looked unbalanced, and also happened to
fix unrelated isp1704_charger crash. However this broke runtime PM
functionality (musb is now always powered, even without gadget active).

Avoid these confusing runtime pm dependences by making
musb_init_controller() and omap2430_musb_init() do their own runtime
get/put pairs; also cover error paths. Remove unneeded runtime_pm_put
in omap2430_remove too. isp1704_charger crash that motivated
772aed45b604 will be fixed by following patch.

Cc: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/musb/musb_core.c | 9 ++++++++-
 drivers/usb/musb/omap2430.c  | 2 +-
 2 files changed, 9 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 0f8b82918a40..239214626ec5 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1904,7 +1904,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 
 	if (!musb->isr) {
 		status = -ENODEV;
-		goto fail3;
+		goto fail2;
 	}
 
 	if (!musb->xceiv->io_ops) {
@@ -1912,6 +1912,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 		musb->xceiv->io_ops = &musb_ulpi_access;
 	}
 
+	pm_runtime_get_sync(musb->controller);
+
 #ifndef CONFIG_MUSB_PIO_ONLY
 	if (use_dma && dev->dma_mask) {
 		struct dma_controller	*c;
@@ -2023,6 +2025,8 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 		goto fail5;
 #endif
 
+	pm_runtime_put(musb->controller);
+
 	dev_info(dev, "USB %s mode controller at %p using %s, IRQ %d\n",
 			({char *s;
 			 switch (musb->board_mode) {
@@ -2047,6 +2051,9 @@ fail4:
 		musb_gadget_cleanup(musb);
 
 fail3:
+	pm_runtime_put_sync(musb->controller);
+
+fail2:
 	if (musb->irq_wake)
 		device_init_wakeup(dev, 0);
 	musb_platform_exit(musb);
diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 11b571ec22f2..3dfd122266f4 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -333,6 +333,7 @@ static int omap2430_musb_init(struct musb *musb)
 
 	setup_timer(&musb_idle_timer, musb_do_idle, (unsigned long) musb);
 
+	pm_runtime_put_noidle(musb->controller);
 	return 0;
 
 err1:
@@ -478,7 +479,6 @@ static int __devexit omap2430_remove(struct platform_device *pdev)
 
 	platform_device_del(glue->musb);
 	platform_device_put(glue->musb);
-	pm_runtime_put(&pdev->dev);
 	kfree(glue);
 
 	return 0;
-- 
cgit v1.2.1


From f79a60b8785409f5a77767780315ce6d3ea04a44 Mon Sep 17 00:00:00 2001
From: Peter Chen <peter.chen@freescale.com>
Date: Wed, 29 Feb 2012 20:19:46 +0800
Subject: usb: fsl_udc_core: prime status stage once data stage has primed

- For Control Read transfer, the ACK handshake on an IN transaction
may be corrupted, so the device may not receive the ACK for data
stage, the complete irq will not occur at this situation.
Therefore, we need to move prime status stage from complete irq
routine to the place where the data stage has just primed, or the
host will never get ACK for status stage.
The above issue has been described at USB2.0 spec chapter 8.5.3.3.

- After adding prime status stage just after prime the data stage,
there is a potential problem when the status dTD is added before the data stage
has primed by hardware. The reason is the device's dTD descriptor has NO direction bit,
if data stage (IN) prime hasn't finished, the status stage(OUT)
dTD will be added at data stage dTD's Next dTD Pointer, so when the data stage
transfer has finished, the status dTD will be primed as IN by hardware,
then the host will never receive ACK from the device side for status stage.

- Delete below code at fsl_ep_queue:
       /* Update ep0 state */
       if ((ep_index(ep) == 0))
               udc->ep0_state = DATA_STATE_XMIT;
the udc->ep0_state will be updated again after udc->driver->setup
finishes.

It is tested at i.mx51 bbg board with g_mass_storage, g_ether, g_serial.

Signed-off-by: Peter Chen <peter.chen@freescale.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/fsl_udc_core.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c
index 5f94e79cd6b9..55abfb6bd612 100644
--- a/drivers/usb/gadget/fsl_udc_core.c
+++ b/drivers/usb/gadget/fsl_udc_core.c
@@ -730,7 +730,7 @@ static void fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
 		: (1 << (ep_index(ep)));
 
 	/* check if the pipe is empty */
-	if (!(list_empty(&ep->queue))) {
+	if (!(list_empty(&ep->queue)) && !(ep_index(ep) == 0)) {
 		/* Add td to the end */
 		struct fsl_req *lastreq;
 		lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
@@ -918,10 +918,6 @@ fsl_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags)
 		return -ENOMEM;
 	}
 
-	/* Update ep0 state */
-	if ((ep_index(ep) == 0))
-		udc->ep0_state = DATA_STATE_XMIT;
-
 	/* irq handler advances the queue */
 	if (req != NULL)
 		list_add_tail(&req->queue, &ep->queue);
@@ -1279,7 +1275,8 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction)
 		udc->ep0_dir = USB_DIR_OUT;
 
 	ep = &udc->eps[0];
-	udc->ep0_state = WAIT_FOR_OUT_STATUS;
+	if (udc->ep0_state != DATA_STATE_XMIT)
+		udc->ep0_state = WAIT_FOR_OUT_STATUS;
 
 	req->ep = ep;
 	req->req.length = 0;
@@ -1384,6 +1381,9 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value,
 
 	list_add_tail(&req->queue, &ep->queue);
 	udc->ep0_state = DATA_STATE_XMIT;
+	if (ep0_prime_status(udc, EP_DIR_OUT))
+		ep0stall(udc);
+
 	return;
 stall:
 	ep0stall(udc);
@@ -1492,6 +1492,14 @@ static void setup_received_irq(struct fsl_udc *udc,
 		spin_lock(&udc->lock);
 		udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
 				?  DATA_STATE_XMIT : DATA_STATE_RECV;
+		/*
+		 * If the data stage is IN, send status prime immediately.
+		 * See 2.0 Spec chapter 8.5.3.3 for detail.
+		 */
+		if (udc->ep0_state == DATA_STATE_XMIT)
+			if (ep0_prime_status(udc, EP_DIR_OUT))
+				ep0stall(udc);
+
 	} else {
 		/* No data phase, IN status from gadget */
 		udc->ep0_dir = USB_DIR_IN;
@@ -1520,9 +1528,8 @@ static void ep0_req_complete(struct fsl_udc *udc, struct fsl_ep *ep0,
 
 	switch (udc->ep0_state) {
 	case DATA_STATE_XMIT:
-		/* receive status phase */
-		if (ep0_prime_status(udc, EP_DIR_OUT))
-			ep0stall(udc);
+		/* already primed at setup_received_irq */
+		udc->ep0_state = WAIT_FOR_OUT_STATUS;
 		break;
 	case DATA_STATE_RECV:
 		/* send status phase */
-- 
cgit v1.2.1


From f7a83fe19336125d7eb26488788dc66c03f2c08e Mon Sep 17 00:00:00 2001
From: Anton Tikhomirov <av.tikhomirov@samsung.com>
Date: Tue, 6 Mar 2012 14:05:49 +0900
Subject: usb: s3c-hsotg: Fix TX FIFOs allocation

According to documentation, TX FIFO_number index starts from 1.
For IN endpoint FIFO 0 we use GNPTXFSIZ register for programming
the size and memory start address.

Signed-off-by: Anton Tikhomirov <av.tikhomirov@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/s3c-hsotg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 69295ba9d99a..e3fe5fd795f0 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -340,7 +340,7 @@ static void s3c_hsotg_init_fifo(struct s3c_hsotg *hsotg)
 	/* currently we allocate TX FIFOs for all possible endpoints,
 	 * and assume that they are all the same size. */
 
-	for (ep = 0; ep <= 15; ep++) {
+	for (ep = 1; ep <= 15; ep++) {
 		val = addr;
 		val |= size << S3C_DPTXFSIZn_DPTxFSize_SHIFT;
 		addr += size;
-- 
cgit v1.2.1


From 659ad60cb9128345d0a6b9093dda9b0e366b7937 Mon Sep 17 00:00:00 2001
From: Anton Tikhomirov <av.tikhomirov@samsung.com>
Date: Tue, 6 Mar 2012 14:07:29 +0900
Subject: usb: s3c-hsotg: Fix maximum patcket size setting for EP0

MPS field of DOEPCTL0 is read only.

Signed-off-by: Anton Tikhomirov <av.tikhomirov@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/s3c-hsotg.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index e3fe5fd795f0..03de169ab365 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -1696,10 +1696,12 @@ static void s3c_hsotg_set_ep_maxpacket(struct s3c_hsotg *hsotg,
 	reg |= mpsval;
 	writel(reg, regs + S3C_DIEPCTL(ep));
 
-	reg = readl(regs + S3C_DOEPCTL(ep));
-	reg &= ~S3C_DxEPCTL_MPS_MASK;
-	reg |= mpsval;
-	writel(reg, regs + S3C_DOEPCTL(ep));
+	if (ep) {
+		reg = readl(regs + S3C_DOEPCTL(ep));
+		reg &= ~S3C_DxEPCTL_MPS_MASK;
+		reg |= mpsval;
+		writel(reg, regs + S3C_DOEPCTL(ep));
+	}
 
 	return;
 
-- 
cgit v1.2.1


From 70fa030ffb652ace81dd5bcab01255b49723caec Mon Sep 17 00:00:00 2001
From: Anton Tikhomirov <av.tikhomirov@samsung.com>
Date: Tue, 6 Mar 2012 14:08:29 +0900
Subject: usb: s3c-hsotg: Avoid TxFIFO corruption in DMA mode

Writing to TxFIFO relates only to Slave mode and leads to
TxFIFO corruption in DMA mode.

Signed-off-by: Anton Tikhomirov <av.tikhomirov@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/s3c-hsotg.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 03de169ab365..8db23660b5e2 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -1921,7 +1921,8 @@ static void s3c_hsotg_epint(struct s3c_hsotg *hsotg, unsigned int idx,
 		    ints & S3C_DIEPMSK_TxFIFOEmpty) {
 			dev_dbg(hsotg->dev, "%s: ep%d: TxFIFOEmpty\n",
 				__func__, idx);
-			s3c_hsotg_trytx(hsotg, hs_ep);
+			if (!using_dma(hsotg))
+				s3c_hsotg_trytx(hsotg, hs_ep);
 		}
 	}
 }
-- 
cgit v1.2.1


From db1d8ba36551bf55222c7961d9e9a1195a612fde Mon Sep 17 00:00:00 2001
From: Anton Tikhomirov <av.tikhomirov@samsung.com>
Date: Tue, 6 Mar 2012 14:09:19 +0900
Subject: usb: s3c-hsotg: Fix big buffers transfer in DMA mode

DMA address register shouldn't be updated manually if transfer size
requires multiple packets.

Signed-off-by: Anton Tikhomirov <av.tikhomirov@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/s3c-hsotg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c
index 8db23660b5e2..105b206cd844 100644
--- a/drivers/usb/gadget/s3c-hsotg.c
+++ b/drivers/usb/gadget/s3c-hsotg.c
@@ -741,7 +741,7 @@ static void s3c_hsotg_start_req(struct s3c_hsotg *hsotg,
 	/* write size / packets */
 	writel(epsize, hsotg->regs + epsize_reg);
 
-	if (using_dma(hsotg)) {
+	if (using_dma(hsotg) && !continuing) {
 		unsigned int dma_reg;
 
 		/* write DMA address to control register, buffer already
-- 
cgit v1.2.1


From 64b6c8a7019acc38cc6b37f8e72c1e915593b1bb Mon Sep 17 00:00:00 2001
From: Anton Tikhomirov <av.tikhomirov@samsung.com>
Date: Tue, 6 Mar 2012 17:05:15 +0900
Subject: usb: dwc3: Free event buffers array

Array should be freed together with event buffers, since it was
allocated dynamically.

Signed-off-by: Anton Tikhomirov <av.tikhomirov@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/dwc3/core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 7bd815a507e8..99b58d84553a 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -206,11 +206,11 @@ static void dwc3_free_event_buffers(struct dwc3 *dwc)
 
 	for (i = 0; i < dwc->num_event_buffers; i++) {
 		evt = dwc->ev_buffs[i];
-		if (evt) {
+		if (evt)
 			dwc3_free_one_event_buffer(dwc, evt);
-			dwc->ev_buffs[i] = NULL;
-		}
 	}
+
+	kfree(dwc->ev_buffs);
 }
 
 /**
-- 
cgit v1.2.1


From e2190a97c6d493eef1f180b9dadfd5ffd4706051 Mon Sep 17 00:00:00 2001
From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Date: Mon, 12 Mar 2012 12:55:41 +0100
Subject: usb: gadget: FunctionFS: clear FFS_FL_BOUND flag on unbind (bugfix)

clear FFS_FL_BOUND flag on unbind (bugfix)

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/f_fs.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index 1cbba70836bc..d187ae73262b 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -1382,6 +1382,7 @@ static void functionfs_unbind(struct ffs_data *ffs)
 		ffs->ep0req = NULL;
 		ffs->gadget = NULL;
 		ffs_data_put(ffs);
+		clear_bit(FFS_FL_BOUND, &ffs->flags);
 	}
 }
 
-- 
cgit v1.2.1


From 8545e6031a719675da9f3d21f1c8ce143dac7fe5 Mon Sep 17 00:00:00 2001
From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Date: Mon, 12 Mar 2012 12:55:42 +0100
Subject: usb: gadget: FunctionFS: make module init & exit __init & __exit

make module init & exit __init & __exit

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Acked-by: Michal Nazarewicz <mina86@mina86.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/g_ffs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c
index 331cd6729d3c..a85eaf40b948 100644
--- a/drivers/usb/gadget/g_ffs.c
+++ b/drivers/usb/gadget/g_ffs.c
@@ -161,7 +161,7 @@ static struct usb_composite_driver gfs_driver = {
 static struct ffs_data *gfs_ffs_data;
 static unsigned long gfs_registered;
 
-static int  gfs_init(void)
+static int __init gfs_init(void)
 {
 	ENTER();
 
@@ -169,7 +169,7 @@ static int  gfs_init(void)
 }
 module_init(gfs_init);
 
-static void  gfs_exit(void)
+static void __exit gfs_exit(void)
 {
 	ENTER();
 
-- 
cgit v1.2.1


From 692933b2ccfce02400dc8360a97acde2846e8541 Mon Sep 17 00:00:00 2001
From: Ajay Kumar Gupta <ajay.gupta@ti.com>
Date: Wed, 14 Mar 2012 17:33:35 +0530
Subject: usb: musb: fix bug in musb_cleanup_urb

Control transfers with data expected from device to host will use usb_rcvctrlpipe()
for urb->pipe so for such urbs 'is_in' will be set causing control urb to fall
into the first "if" condition in musb_cleanup_urb().

Fixed by adding logic to check for non control endpoints.

Signed-off-by: Ajay Kumar Gupta <ajay.gupta@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/musb/musb_host.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 79cb0af779fa..ef8d744800ac 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2098,7 +2098,7 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
 	}
 
 	/* turn off DMA requests, discard state, stop polling ... */
-	if (is_in) {
+	if (ep->epnum && is_in) {
 		/* giveback saves bulk toggle */
 		csr = musb_h_flush_rxfifo(ep, 0);
 
-- 
cgit v1.2.1


From bf070bc14178f1458e7eccd76316ac24f76f1890 Mon Sep 17 00:00:00 2001
From: Grazvydas Ignotas <notasas@gmail.com>
Date: Wed, 21 Mar 2012 16:35:52 +0200
Subject: usb: musb: wake the device before ulpi transfers

musb can be suspended at the time some other driver wants to do ulpi
transfers using usb_phy_io_* functions, and that can cause data abort,
as it happened with isp1704_charger:
http://article.gmane.org/gmane.linux.kernel/1226122

Add pm_runtime to ulpi functions to rectify this. This also adds io_dev
to usb_phy so that pm_runtime_* functions can be used.

Cc: Felipe Contreras <felipe.contreras@gmail.com>
Signed-off-by: Grazvydas Ignotas <notasas@gmail.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/musb/musb_core.c | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 239214626ec5..66aaccf04490 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -137,6 +137,9 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
 	int	i = 0;
 	u8	r;
 	u8	power;
+	int	ret;
+
+	pm_runtime_get_sync(phy->io_dev);
 
 	/* Make sure the transceiver is not in low power mode */
 	power = musb_readb(addr, MUSB_POWER);
@@ -154,15 +157,22 @@ static int musb_ulpi_read(struct usb_phy *phy, u32 offset)
 	while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
 				& MUSB_ULPI_REG_CMPLT)) {
 		i++;
-		if (i == 10000)
-			return -ETIMEDOUT;
+		if (i == 10000) {
+			ret = -ETIMEDOUT;
+			goto out;
+		}
 
 	}
 	r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
 	r &= ~MUSB_ULPI_REG_CMPLT;
 	musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
 
-	return musb_readb(addr, MUSB_ULPI_REG_DATA);
+	ret = musb_readb(addr, MUSB_ULPI_REG_DATA);
+
+out:
+	pm_runtime_put(phy->io_dev);
+
+	return ret;
 }
 
 static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
@@ -171,6 +181,9 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
 	int	i = 0;
 	u8	r = 0;
 	u8	power;
+	int	ret = 0;
+
+	pm_runtime_get_sync(phy->io_dev);
 
 	/* Make sure the transceiver is not in low power mode */
 	power = musb_readb(addr, MUSB_POWER);
@@ -184,15 +197,20 @@ static int musb_ulpi_write(struct usb_phy *phy, u32 offset, u32 data)
 	while (!(musb_readb(addr, MUSB_ULPI_REG_CONTROL)
 				& MUSB_ULPI_REG_CMPLT)) {
 		i++;
-		if (i == 10000)
-			return -ETIMEDOUT;
+		if (i == 10000) {
+			ret = -ETIMEDOUT;
+			goto out;
+		}
 	}
 
 	r = musb_readb(addr, MUSB_ULPI_REG_CONTROL);
 	r &= ~MUSB_ULPI_REG_CMPLT;
 	musb_writeb(addr, MUSB_ULPI_REG_CONTROL, r);
 
-	return 0;
+out:
+	pm_runtime_put(phy->io_dev);
+
+	return ret;
 }
 #else
 #define musb_ulpi_read		NULL
@@ -1908,6 +1926,7 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 	}
 
 	if (!musb->xceiv->io_ops) {
+		musb->xceiv->io_dev = musb->controller;
 		musb->xceiv->io_priv = musb->mregs;
 		musb->xceiv->io_ops = &musb_ulpi_access;
 	}
-- 
cgit v1.2.1


From 3006dc8c627d738693e910c159630e4368c9e86c Mon Sep 17 00:00:00 2001
From: Kishon Vijay Abraham I <kishon@ti.com>
Date: Wed, 21 Mar 2012 21:30:20 +0530
Subject: usb: musb: omap: fix crash when musb glue (omap) gets initialized

pm_runtime_enable is being called after omap2430_musb_init. Hence
pm_runtime_get_sync in omap2430_musb_init does not have any effect (does
not enable clocks) resulting in a crash during register access. It is
fixed here.

Cc: stable@vger.kernel.org # v3.0, v3.1, v3.2, v3.3
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/musb/omap2430.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 3dfd122266f4..0fb4ce84d17e 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -453,14 +453,14 @@ static int __devinit omap2430_probe(struct platform_device *pdev)
 		goto err2;
 	}
 
+	pm_runtime_enable(&pdev->dev);
+
 	ret = platform_device_add(musb);
 	if (ret) {
 		dev_err(&pdev->dev, "failed to register musb device\n");
 		goto err2;
 	}
 
-	pm_runtime_enable(&pdev->dev);
-
 	return 0;
 
 err2:
-- 
cgit v1.2.1


From 8ae8090c82eb407267001f75b3d256b3bd4ae691 Mon Sep 17 00:00:00 2001
From: Kishon Vijay Abraham I <kishon@ti.com>
Date: Wed, 21 Mar 2012 21:34:30 +0530
Subject: usb: gadget: udc-core: fix asymmetric calls in remove_driver

During modprobe of gadget driver, pullup is called after
udc_start. In order to make the exit path symmetric when
removing a gadget driver, call pullup before ->udc_stop.

This is needed to avoid issues with PM where udc_stop
disables the module completely (put IP in reset state,
cut functional and interface clocks, and so on), which
prevents us from accessing the IP's address space,
thus creating the possibility of an abort exception
when we try to access IP's address space after clocks
are off.

Cc: stable@vger.kernel.org
Signed-off-by: Partha Basak <p-basak2@ti.com>
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/udc-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index c261887e05ae..2fa9865babed 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -264,8 +264,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
 	if (udc_is_newstyle(udc)) {
 		udc->driver->disconnect(udc->gadget);
 		udc->driver->unbind(udc->gadget);
-		usb_gadget_udc_stop(udc->gadget, udc->driver);
 		usb_gadget_disconnect(udc->gadget);
+		usb_gadget_udc_stop(udc->gadget, udc->driver);
 	} else {
 		usb_gadget_stop(udc->gadget, udc->driver);
 	}
-- 
cgit v1.2.1


From ad579699c4f0274bf522a9252ff9b20c72197e48 Mon Sep 17 00:00:00 2001
From: Shubhrajyoti D <shubhrajyoti@ti.com>
Date: Thu, 22 Mar 2012 12:48:06 +0530
Subject: usb: musb: omap: fix the error check for pm_runtime_get_sync

pm_runtime_get_sync returns a signed integer. In case of errors
it returns a negative value. This patch fixes the error check
by making it signed instead of unsigned thus preventing register
access if get_sync_fails. Also passes the error cause to the
debug message.

Cc: stable@vger.kernel.org
Cc:  Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Shubhrajyoti D <shubhrajyoti@ti.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/musb/omap2430.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
index 0fb4ce84d17e..c7785e81254c 100644
--- a/drivers/usb/musb/omap2430.c
+++ b/drivers/usb/musb/omap2430.c
@@ -282,7 +282,8 @@ static void musb_otg_notifier_work(struct work_struct *data_notifier_work)
 
 static int omap2430_musb_init(struct musb *musb)
 {
-	u32 l, status = 0;
+	u32 l;
+	int status = 0;
 	struct device *dev = musb->controller;
 	struct musb_hdrc_platform_data *plat = dev->platform_data;
 	struct omap_musb_board_data *data = plat->board_data;
@@ -301,7 +302,7 @@ static int omap2430_musb_init(struct musb *musb)
 
 	status = pm_runtime_get_sync(dev);
 	if (status < 0) {
-		dev_err(dev, "pm_runtime_get_sync FAILED");
+		dev_err(dev, "pm_runtime_get_sync FAILED %d\n", status);
 		goto err1;
 	}
 
-- 
cgit v1.2.1


From f135617224b4a1113b26b8ee5877e94f38e40d1e Mon Sep 17 00:00:00 2001
From: Lukasz Majewski <l.majewski@samsung.com>
Date: Fri, 10 Feb 2012 09:54:51 +0100
Subject: usb: gadget: rndis: fix Missing req->context assignment

It is crucial to assign each req->context value to struct rndis.

The problem happens for multi function gadget (g_multi) when multiple
functions are calling common usb_composite_dev control request.

It might happen that *_setup method from one usb function will
alter some fields of this common request issued by other USB
function.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/f_rndis.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c
index 7b1cf18df5e3..52343654f5df 100644
--- a/drivers/usb/gadget/f_rndis.c
+++ b/drivers/usb/gadget/f_rndis.c
@@ -500,6 +500,7 @@ rndis_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
 			if (buf) {
 				memcpy(req->buf, buf, n);
 				req->complete = rndis_response_complete;
+				req->context = rndis;
 				rndis_free_response(rndis->config, buf);
 				value = n;
 			}
-- 
cgit v1.2.1


From 6190c79df861d2c78a7448fe6d4260e5fa53b9b9 Mon Sep 17 00:00:00 2001
From: Bhupesh Sharma <bhupesh.sharma@st.com>
Date: Fri, 23 Mar 2012 22:23:13 +0530
Subject: usb: gadget: uvc: Remove non-required locking from
 'uvc_queue_next_buffer' routine

This patch removes the non-required spinlock acquire/release calls on
'queue->irqlock' from 'uvc_queue_next_buffer' routine.

This routine is called from 'video->encode' function (which translates to
either 'uvc_video_encode_bulk' or 'uvc_video_encode_isoc') in 'uvc_video.c'.
As, the 'video->encode' routines are called with 'queue->irqlock' already held,
so acquiring a 'queue->irqlock' again in 'uvc_queue_next_buffer' routine causes
a spin lock recursion.

Signed-off-by: Bhupesh Sharma <bhupesh.sharma@st.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/uvc_queue.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/uvc_queue.c b/drivers/usb/gadget/uvc_queue.c
index d776adb2da67..0cdf89d32a15 100644
--- a/drivers/usb/gadget/uvc_queue.c
+++ b/drivers/usb/gadget/uvc_queue.c
@@ -543,11 +543,11 @@ done:
 	return ret;
 }
 
+/* called with queue->irqlock held.. */
 static struct uvc_buffer *
 uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
 {
 	struct uvc_buffer *nextbuf;
-	unsigned long flags;
 
 	if ((queue->flags & UVC_QUEUE_DROP_INCOMPLETE) &&
 	    buf->buf.length != buf->buf.bytesused) {
@@ -556,14 +556,12 @@ uvc_queue_next_buffer(struct uvc_video_queue *queue, struct uvc_buffer *buf)
 		return buf;
 	}
 
-	spin_lock_irqsave(&queue->irqlock, flags);
 	list_del(&buf->queue);
 	if (!list_empty(&queue->irqqueue))
 		nextbuf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
 					   queue);
 	else
 		nextbuf = NULL;
-	spin_unlock_irqrestore(&queue->irqlock, flags);
 
 	buf->buf.sequence = queue->sequence++;
 	do_gettimeofday(&buf->buf.timestamp);
-- 
cgit v1.2.1


From 92b0abf80c5c5f0e0d71d1309688a330fd74731b Mon Sep 17 00:00:00 2001
From: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Date: Wed, 28 Mar 2012 09:30:50 +0200
Subject: usb: gadget: eliminate NULL pointer dereference (bugfix)

usb: gadget: eliminate NULL pointer dereference (bugfix)

This patch fixes a bug which causes NULL pointer dereference in
ffs_ep0_ioctl. The bug happens when the FunctionFS is not bound (either
has not been bound yet or has been bound and then unbound) and can be
reproduced with running the following commands:

$ insmod g_ffs.ko
$ mount -t functionfs func /dev/usbgadget
$ ./null

where null.c is:

#include <fcntl.h>
#include <linux/usb/functionfs.h>

int main(void)
{
	int fd = open("/dev/usbgadget/ep0", O_RDWR);
	ioctl(fd, FUNCTIONFS_CLEAR_HALT);

	return 0;
}

Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: stable@vger.kernel.org
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/f_fs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c
index d187ae73262b..f52cb1ae45d9 100644
--- a/drivers/usb/gadget/f_fs.c
+++ b/drivers/usb/gadget/f_fs.c
@@ -712,7 +712,7 @@ static long ffs_ep0_ioctl(struct file *file, unsigned code, unsigned long value)
 	if (code == FUNCTIONFS_INTERFACE_REVMAP) {
 		struct ffs_function *func = ffs->func;
 		ret = func ? ffs_func_revmap_intf(func, value) : -ENODEV;
-	} else if (gadget->ops->ioctl) {
+	} else if (gadget && gadget->ops->ioctl) {
 		ret = gadget->ops->ioctl(gadget, code, value);
 	} else {
 		ret = -ENOTTY;
-- 
cgit v1.2.1


From a65a6f14dc24a90bde3f5d0073ba2364476200bf Mon Sep 17 00:00:00 2001
From: Johan Hovold <jhovold@gmail.com>
Date: Tue, 20 Mar 2012 16:59:33 +0100
Subject: USB: serial: fix race between probe and open

Fix race between probe and open by making sure that the disconnected
flag is not cleared until all ports have been registered.

A call to tty_open while probe is running may get a reference to the
serial structure in serial_install before its ports have been
registered. This may lead to usb_serial_core calling driver open before
port is fully initialised.

With ftdi_sio this result in the following NULL-pointer dereference as
the private data has not been initialised at open:

[  199.698286] IP: [<f811a089>] ftdi_open+0x59/0xe0 [ftdi_sio]
[  199.698297] *pde = 00000000
[  199.698303] Oops: 0000 [#1] PREEMPT SMP
[  199.698313] Modules linked in: ftdi_sio usbserial
[  199.698323]
[  199.698327] Pid: 1146, comm: ftdi_open Not tainted 3.2.11 #70 Dell Inc. Vostro 1520/0T816J
[  199.698339] EIP: 0060:[<f811a089>] EFLAGS: 00010286 CPU: 0
[  199.698344] EIP is at ftdi_open+0x59/0xe0 [ftdi_sio]
[  199.698348] EAX: 0000003e EBX: f5067000 ECX: 00000000 EDX: 80000600
[  199.698352] ESI: f48d8800 EDI: 00000001 EBP: f515dd54 ESP: f515dcfc
[  199.698356]  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
[  199.698361] Process ftdi_open (pid: 1146, ti=f515c000 task=f481e040 task.ti=f515c000)
[  199.698364] Stack:
[  199.698368]  f811a9fe f811a9e0 f811b3ef 00000000 00000000 00001388 00000000 f4a86800
[  199.698387]  00000002 00000000 f806e68e 00000000 f532765c f481e040 00000246 22222222
[  199.698479]  22222222 22222222 22222222 f5067004 f5327600 f5327638 f515dd74 f806e6ab
[  199.698496] Call Trace:
[  199.698504]  [<f806e68e>] ? serial_activate+0x2e/0x70 [usbserial]
[  199.698511]  [<f806e6ab>] serial_activate+0x4b/0x70 [usbserial]
[  199.698521]  [<c126380c>] tty_port_open+0x7c/0xd0
[  199.698527]  [<f806e660>] ? serial_set_termios+0xa0/0xa0 [usbserial]
[  199.698534]  [<f806e76f>] serial_open+0x2f/0x70 [usbserial]
[  199.698540]  [<c125d07c>] tty_open+0x20c/0x510
[  199.698546]  [<c10e9eb7>] chrdev_open+0xe7/0x230
[  199.698553]  [<c10e48f2>] __dentry_open+0x1f2/0x390
[  199.698559]  [<c144bfec>] ? _raw_spin_unlock+0x2c/0x50
[  199.698565]  [<c10e4b76>] nameidata_to_filp+0x66/0x80
[  199.698570]  [<c10e9dd0>] ? cdev_put+0x20/0x20
[  199.698576]  [<c10f3e08>] do_last+0x198/0x730
[  199.698581]  [<c10f4440>] path_openat+0xa0/0x350
[  199.698587]  [<c10f47d5>] do_filp_open+0x35/0x80
[  199.698593]  [<c144bfec>] ? _raw_spin_unlock+0x2c/0x50
[  199.698599]  [<c10ff110>] ? alloc_fd+0xc0/0x100
[  199.698605]  [<c10f0b72>] ? getname_flags+0x72/0x120
[  199.698611]  [<c10e4450>] do_sys_open+0xf0/0x1c0
[  199.698617]  [<c11fcc08>] ? trace_hardirqs_on_thunk+0xc/0x10
[  199.698623]  [<c10e458e>] sys_open+0x2e/0x40
[  199.698628]  [<c144c990>] sysenter_do_call+0x12/0x36
[  199.698632] Code: 85 89 00 00 00 8b 16 8b 4d c0 c1 e2 08 c7 44 24 14 88 13 00 00 81 ca 00 00 00 80 c7 44 24 10 00 00 00 00 c7 44 24 0c 00 00 00 00 <0f> b7 41 78 31 c9 89 44 24 08 c7 44 24 04 00 00 00 00 c7 04 24
[  199.698884] EIP: [<f811a089>] ftdi_open+0x59/0xe0 [ftdi_sio] SS:ESP 0068:f515dcfc
[  199.698893] CR2: 0000000000000078
[  199.698925] ---[ end trace 77c43ec023940cff ]---

Reported-and-tested-by: Ken Huang <csuhgw@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/usb-serial.c | 8 ++++++++
 1 file changed, 8 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 5413bd500781..97355a15bbea 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1059,6 +1059,12 @@ int usb_serial_probe(struct usb_interface *interface,
 		serial->attached = 1;
 	}
 
+	/* Avoid race with tty_open and serial_install by setting the
+	 * disconnected flag and not clearing it until all ports have been
+	 * registered.
+	 */
+	serial->disconnected = 1;
+
 	if (get_free_serial(serial, num_ports, &minor) == NULL) {
 		dev_err(&interface->dev, "No more free serial devices\n");
 		goto probe_error;
@@ -1078,6 +1084,8 @@ int usb_serial_probe(struct usb_interface *interface,
 				"continuing\n");
 	}
 
+	serial->disconnected = 0;
+
 	usb_serial_console_init(debug, minor);
 
 exit:
-- 
cgit v1.2.1


From bb334e90cc3a2913906665ea966abd7f462b67c2 Mon Sep 17 00:00:00 2001
From: Alex He <alex.he@amd.com>
Date: Thu, 22 Mar 2012 15:06:59 +0800
Subject: xHCI: correct to print the true HSEE of USBCMD

Correct the print of HSEE of USBCMD in xhci-dbg.c.

Signed-off-by: Alex He <alex.he@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
---
 drivers/usb/host/xhci-dbg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index e9b0f043455d..4b436f5a4171 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -119,7 +119,7 @@ static void xhci_print_command_reg(struct xhci_hcd *xhci)
 	xhci_dbg(xhci, "  Event Interrupts %s\n",
 			(temp & CMD_EIE) ? "enabled " : "disabled");
 	xhci_dbg(xhci, "  Host System Error Interrupts %s\n",
-			(temp & CMD_EIE) ? "enabled " : "disabled");
+			(temp & CMD_HSEIE) ? "enabled " : "disabled");
 	xhci_dbg(xhci, "  HC has %sfinished light reset\n",
 			(temp & CMD_LRESET) ? "not " : "");
 }
-- 
cgit v1.2.1


From a46c46a1d752756ba159dd454b746a3fb735c4f5 Mon Sep 17 00:00:00 2001
From: Gerard Snitselaar <dev@snitselaar.org>
Date: Fri, 16 Mar 2012 11:34:11 -0700
Subject: usb: xhci: fix section mismatch in linux-next

xhci_unregister_pci() is called in xhci_hcd_init().

Signed-off-by: Gerard Snitselaar <dev@snitselaar.org>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
---
 drivers/usb/host/xhci-pci.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index ef98b38626fb..0d7b85135965 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -326,7 +326,7 @@ int __init xhci_register_pci(void)
 	return pci_register_driver(&xhci_pci_driver);
 }
 
-void __exit xhci_unregister_pci(void)
+void xhci_unregister_pci(void)
 {
 	pci_unregister_driver(&xhci_pci_driver);
 }
-- 
cgit v1.2.1


From 4e833c0b87a30798e67f06120cecebef6ee9644c Mon Sep 17 00:00:00 2001
From: Felipe Balbi <balbi@ti.com>
Date: Thu, 15 Mar 2012 16:37:08 +0200
Subject: xhci: don't re-enable IE constantly

While we're at that, define IMAN bitfield to aid readability.

The interrupt enable bit should be set once on driver init, and we
shouldn't need to continually re-enable it.  Commit c21599a3 introduced
a read of the irq_pending register, and that allows us to preserve the
state of the IE bit.  Before that commit, we were blindly writing 0x3 to
the register.

This patch should be backported to kernels as old as 2.6.36, or ones
that contain the commit c21599a36165dbc78b380846b254017a548b9de5 "USB:
xhci: Reduce reads and writes of interrupter registers".

Signed-off-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable@vger.kernel.org
---
 drivers/usb/host/xhci-ring.c | 2 +-
 drivers/usb/host/xhci.h      | 4 ++++
 2 files changed, 5 insertions(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 6bd9d53062eb..5ddc4ae85499 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2417,7 +2417,7 @@ hw_died:
 		u32 irq_pending;
 		/* Acknowledge the PCI interrupt */
 		irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
-		irq_pending |= 0x3;
+		irq_pending |= IMAN_IP;
 		xhci_writel(xhci, irq_pending, &xhci->ir_set->irq_pending);
 	}
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 91074fdab3eb..3d69c4b2b542 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -205,6 +205,10 @@ struct xhci_op_regs {
 #define CMD_PM_INDEX	(1 << 11)
 /* bits 12:31 are reserved (and should be preserved on writes). */
 
+/* IMAN - Interrupt Management Register */
+#define IMAN_IP		(1 << 1)
+#define IMAN_IE		(1 << 0)
+
 /* USBSTS - USB status - status bitmasks */
 /* HC not running - set to 1 when run/stop bit is cleared. */
 #define STS_HALT	XHCI_STS_HALT
-- 
cgit v1.2.1


From 5af98bb06dee79d28c805f9fd0805ce791121784 Mon Sep 17 00:00:00 2001
From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Date: Fri, 16 Mar 2012 12:58:20 -0700
Subject: xhci: Warn when hosts don't halt.

Eric Fu reports a problem with his VIA host controller fetching a zeroed
event ring pointer on resume from suspend.  The host should have been
halted, but we can't be sure because that code ignores the return value
from xhci_halt().  Print a warning when the host controller refuses to
halt within XHCI_MAX_HALT_USEC (currently 16 seconds).

(Update: it turns out that the VIA host controller is reporting a halted
state when it fetches the zeroed event ring pointer.  However, we still
need this warning for other host controllers.)

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
---
 drivers/usb/host/xhci.c | 3 +++
 1 file changed, 3 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index e1963d4a430f..f68bc15d21e8 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -106,6 +106,9 @@ int xhci_halt(struct xhci_hcd *xhci)
 			STS_HALT, STS_HALT, XHCI_MAX_HALT_USEC);
 	if (!ret)
 		xhci->xhc_state |= XHCI_STATE_HALTED;
+	else
+		xhci_warn(xhci, "Host not halted after %u microseconds.\n",
+				XHCI_MAX_HALT_USEC);
 	return ret;
 }
 
-- 
cgit v1.2.1


From 159e1fcc9a60fc7daba23ee8fcdb99799de3fe84 Mon Sep 17 00:00:00 2001
From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Date: Fri, 16 Mar 2012 13:09:39 -0700
Subject: xhci: Don't write zeroed pointers to xHC registers.

When xhci_mem_cleanup() is called, we can't be sure if the xHC is
actually halted.  We can ask the xHC to halt by writing to the RUN bit
in the command register, but that might timeout due to a HW hang.

If the host controller is still running, we should not write zeroed
values to the event ring dequeue pointers or base tables, the DCBAA
pointers, or the command ring pointers.  Eric Fu reports his VIA VL800
host accesses the event ring pointers after a failed register restore on
resume from suspend.  The hypothesis is that the host never actually
halted before the register write to change the event ring pointer to
zero.

Remove all writes of zeroed values to pointer registers in
xhci_mem_cleanup().  Instead, make all callers of the function reset the
host controller first, which will reset those registers to zero.
xhci_mem_init() is the only caller that doesn't first halt and reset the
host controller before calling xhci_mem_cleanup().

This should be backported to kernels as old as 2.6.32.

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Tested-by: Elric Fu <elricfu1@gmail.com>
Cc: stable@vger.kernel.org
---
 drivers/usb/host/xhci-mem.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index cae4c6f2845a..68eaa908ac8e 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1796,11 +1796,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 	int i;
 
 	/* Free the Event Ring Segment Table and the actual Event Ring */
-	if (xhci->ir_set) {
-		xhci_writel(xhci, 0, &xhci->ir_set->erst_size);
-		xhci_write_64(xhci, 0, &xhci->ir_set->erst_base);
-		xhci_write_64(xhci, 0, &xhci->ir_set->erst_dequeue);
-	}
 	size = sizeof(struct xhci_erst_entry)*(xhci->erst.num_entries);
 	if (xhci->erst.entries)
 		dma_free_coherent(&pdev->dev, size,
@@ -1812,7 +1807,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 	xhci->event_ring = NULL;
 	xhci_dbg(xhci, "Freed event ring\n");
 
-	xhci_write_64(xhci, 0, &xhci->op_regs->cmd_ring);
 	if (xhci->cmd_ring)
 		xhci_ring_free(xhci, xhci->cmd_ring);
 	xhci->cmd_ring = NULL;
@@ -1841,7 +1835,6 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)
 	xhci->medium_streams_pool = NULL;
 	xhci_dbg(xhci, "Freed medium stream array pool\n");
 
-	xhci_write_64(xhci, 0, &xhci->op_regs->dcbaa_ptr);
 	if (xhci->dcbaa)
 		dma_free_coherent(&pdev->dev, sizeof(*xhci->dcbaa),
 				xhci->dcbaa, xhci->dcbaa->dma);
@@ -2459,6 +2452,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
 
 fail:
 	xhci_warn(xhci, "Couldn't initialize memory\n");
+	xhci_halt(xhci);
+	xhci_reset(xhci);
 	xhci_mem_cleanup(xhci);
 	return -ENOMEM;
 }
-- 
cgit v1.2.1


From fb3d85bc7193f23c9a564502df95564c49a32c91 Mon Sep 17 00:00:00 2001
From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Date: Fri, 16 Mar 2012 13:27:39 -0700
Subject: xhci: Restore event ring dequeue pointer on resume.

The xhci_save_registers() function saved the event ring dequeue pointer
in the s3 register structure, but xhci_restore_registers() never
restored it.  No other code in the xHCI successful resume path would
ever restore it either.  Fix that.

This should be backported to kernels as old as 2.6.37, that contain the
commit 5535b1d5f8885695c6ded783c692e3c0d0eda8ca "USB: xHCI: PCI power
management implementation".

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Tested-by: Elric Fu <elricfu1@gmail.com>
Cc: Andiry Xu <andiry.xu@amd.com>
Cc: stable@vger.kernel.org
---
 drivers/usb/host/xhci.c | 1 +
 1 file changed, 1 insertion(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index f68bc15d21e8..d2222dc2f82e 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -684,6 +684,7 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)
 	xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);
 	xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size);
 	xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base);
+	xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue);
 }
 
 static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
-- 
cgit v1.2.1


From c7713e736526d8c9f6f87716fb90562a8ffaff2c Mon Sep 17 00:00:00 2001
From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Date: Fri, 16 Mar 2012 13:19:35 -0700
Subject: xhci: Fix register save/restore order.

The xHCI 1.0 spec errata released on June 13, 2011, changes the ordering
that the xHCI registers are saved and restored in.  It moves the
interrupt pending (IMAN) and interrupt control (IMOD) registers to be
saved and restored last.  I believe that's because the host controller
may attempt to fetch the event ring table when interrupts are
re-enabled.  Therefore we need to restore the event ring registers
before we re-enable interrupts.

This should be backported to kernels as old as 2.6.37, that contain the
commit 5535b1d5f8885695c6ded783c692e3c0d0eda8ca "USB: xHCI: PCI power
management implementation"

Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Tested-by: Elric Fu <elricfu1@gmail.com>
Cc: Andiry Xu <andiry.xu@amd.com>
Cc: stable@vger.kernel.org
---
 drivers/usb/host/xhci.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d2222dc2f82e..36641a7f2371 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -667,11 +667,11 @@ static void xhci_save_registers(struct xhci_hcd *xhci)
 	xhci->s3.dev_nt = xhci_readl(xhci, &xhci->op_regs->dev_notification);
 	xhci->s3.dcbaa_ptr = xhci_read_64(xhci, &xhci->op_regs->dcbaa_ptr);
 	xhci->s3.config_reg = xhci_readl(xhci, &xhci->op_regs->config_reg);
-	xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
-	xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control);
 	xhci->s3.erst_size = xhci_readl(xhci, &xhci->ir_set->erst_size);
 	xhci->s3.erst_base = xhci_read_64(xhci, &xhci->ir_set->erst_base);
 	xhci->s3.erst_dequeue = xhci_read_64(xhci, &xhci->ir_set->erst_dequeue);
+	xhci->s3.irq_pending = xhci_readl(xhci, &xhci->ir_set->irq_pending);
+	xhci->s3.irq_control = xhci_readl(xhci, &xhci->ir_set->irq_control);
 }
 
 static void xhci_restore_registers(struct xhci_hcd *xhci)
@@ -680,11 +680,11 @@ static void xhci_restore_registers(struct xhci_hcd *xhci)
 	xhci_writel(xhci, xhci->s3.dev_nt, &xhci->op_regs->dev_notification);
 	xhci_write_64(xhci, xhci->s3.dcbaa_ptr, &xhci->op_regs->dcbaa_ptr);
 	xhci_writel(xhci, xhci->s3.config_reg, &xhci->op_regs->config_reg);
-	xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending);
-	xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);
 	xhci_writel(xhci, xhci->s3.erst_size, &xhci->ir_set->erst_size);
 	xhci_write_64(xhci, xhci->s3.erst_base, &xhci->ir_set->erst_base);
 	xhci_write_64(xhci, xhci->s3.erst_dequeue, &xhci->ir_set->erst_dequeue);
+	xhci_writel(xhci, xhci->s3.irq_pending, &xhci->ir_set->irq_pending);
+	xhci_writel(xhci, xhci->s3.irq_control, &xhci->ir_set->irq_control);
 }
 
 static void xhci_set_cmd_ring_deq(struct xhci_hcd *xhci)
-- 
cgit v1.2.1


From d8aec3dbdfd02627e198e7956ab4aaeba2a349fa Mon Sep 17 00:00:00 2001
From: Elric Fu <elricfu1@gmail.com>
Date: Mon, 26 Mar 2012 21:16:02 +0800
Subject: USB: fix bug of device descriptor got from superspeed device

When the Seagate Goflex USB3.0 device is attached to VIA xHCI
host, sometimes the device will downgrade mode to high speed.
By the USB analyzer, I found the device finished the link
training process and worked at superspeed mode. But the device
descriptor got from the device shows the device works at 2.1.
It is very strange and seems like the device controller of
Seagate Goflex has a little confusion.

The first 8 bytes of device descriptor should be:
12 01 00 03 00 00 00 09

But the first 8 bytes of wrong device descriptor are:
12 01 10 02 00 00 00 40

The wrong device descriptor caused the initialization of mass
storage failed. After a while, the device would be recognized
as a high speed device and works fine.

This patch will warm reset the device to fix the issue after
finding the bcdUSB field of device descriptor isn't 0x0300
but the speed mode of device is superspeed.

This patch should be backported to kernels as old as 3.2, or ones that
contain the commit 75d7cf72ab9fa01dc70877aa5c68e8ef477229dc "usbcore:
refine warm reset logic".

Signed-off-by: Elric Fu <elricfu1@gmail.com>
Acked-by: Andiry Xu <Andiry.Xu@amd.com>
Acked-by: Sergei Shtylyov <sshtylyov@mvista.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable@vger.kernel.org
---
 drivers/usb/core/hub.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 28664eb7f555..a2aa9d652c67 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -3163,6 +3163,22 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1,
 	if (retval)
 		goto fail;
 
+	/*
+	 * Some superspeed devices have finished the link training process
+	 * and attached to a superspeed hub port, but the device descriptor
+	 * got from those devices show they aren't superspeed devices. Warm
+	 * reset the port attached by the devices can fix them.
+	 */
+	if ((udev->speed == USB_SPEED_SUPER) &&
+			(le16_to_cpu(udev->descriptor.bcdUSB) < 0x0300)) {
+		dev_err(&udev->dev, "got a wrong device descriptor, "
+				"warm reset device\n");
+		hub_port_reset(hub, port1, udev,
+				HUB_BH_RESET_TIME, true);
+		retval = -EINVAL;
+		goto fail;
+	}
+
 	if (udev->descriptor.bMaxPacketSize0 == 0xff ||
 			udev->speed == USB_SPEED_SUPER)
 		i = 512;
-- 
cgit v1.2.1


From 457a4f61f9bfc3ae76e5b49f30f25d86bb696f67 Mon Sep 17 00:00:00 2001
From: Elric Fu <elricfu1@gmail.com>
Date: Thu, 29 Mar 2012 15:47:50 +0800
Subject: xHCI: add XHCI_RESET_ON_RESUME quirk for VIA xHCI host

The suspend operation of VIA xHCI host have some issues and
hibernate operation works fine, so The XHCI_RESET_ON_RESUME
quirk is added for it.

This patch should base on "xHCI: Don't write zeroed pointer
to xHC registers" that is released by Sarah. Otherwise, the
host system error will ocurr in the hibernate operation
process.

This should be backported to stable kernels as old as 2.6.37,
that contain the commit c877b3b2ad5cb9d4fe523c5496185cc328ff3ae9
"xhci: Add reset on resume quirk for asrock p67 host".

Signed-off-by: Elric Fu <elricfu1@gmail.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable@vger.kernel.org
---
 drivers/usb/host/xhci-pci.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
index 0d7b85135965..7a856a767e77 100644
--- a/drivers/usb/host/xhci-pci.c
+++ b/drivers/usb/host/xhci-pci.c
@@ -95,6 +95,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
 		xhci->quirks |= XHCI_RESET_ON_RESUME;
 		xhci_dbg(xhci, "QUIRK: Resetting on resume\n");
 	}
+	if (pdev->vendor == PCI_VENDOR_ID_VIA)
+		xhci->quirks |= XHCI_RESET_ON_RESUME;
 }
 
 /* called during probe() after chip reset completes */
-- 
cgit v1.2.1


From 3fc8206d3dca1550eb0a1f6e2a350881835954ba Mon Sep 17 00:00:00 2001
From: Dan Carpenter <dan.carpenter@oracle.com>
Date: Wed, 28 Mar 2012 10:30:26 +0300
Subject: xHCI: use gfp flags from caller instead of GFP_ATOMIC

The caller is allowed to specify the GFP flags for these functions.
We should prefer their flags unless we have good reason.  For
example, if we take a spin_lock ourselves we'd need to use
GFP_ATOMIC.  But in this case it's safe to use the callers GFP
flags.

The callers all pass GFP_ATOMIC here, so this change doesn't affect
how the kernel behaves but we may add other callers later and this
is a cleanup.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
---
 drivers/usb/host/xhci-ring.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 5ddc4ae85499..3d9422f16a20 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -2734,7 +2734,7 @@ int xhci_queue_intr_tx(struct xhci_hcd *xhci, gfp_t mem_flags,
 				urb->dev->speed == USB_SPEED_FULL)
 			urb->interval /= 8;
 	}
-	return xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
+	return xhci_queue_bulk_tx(xhci, mem_flags, urb, slot_id, ep_index);
 }
 
 /*
@@ -3514,7 +3514,7 @@ int xhci_queue_isoc_tx_prepare(struct xhci_hcd *xhci, gfp_t mem_flags,
 	}
 	ep_ring->num_trbs_free_temp = ep_ring->num_trbs_free;
 
-	return xhci_queue_isoc_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index);
+	return xhci_queue_isoc_tx(xhci, mem_flags, urb, slot_id, ep_index);
 }
 
 /****		Command Ring Operations		****/
-- 
cgit v1.2.1


From 95018a53f7653e791bba1f54c8d75d9cb700d1bd Mon Sep 17 00:00:00 2001
From: Alex He <alex.he@amd.com>
Date: Fri, 30 Mar 2012 10:21:38 +0800
Subject: xHCI: Correct the #define XHCI_LEGACY_DISABLE_SMI

Re-define XHCI_LEGACY_DISABLE_SMI and used it in right way. All SMI enable
bits will be cleared to zero and flag bits 29:31 are also cleared to zero.
Other bits should be presvered as Table 146.

This patch should be backported to kernels as old as 2.6.31.

Signed-off-by: Alex He <alex.he@amd.com>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable@vger.kernel.org
---
 drivers/usb/host/pci-quirks.c    | 10 +++++++---
 drivers/usb/host/xhci-ext-caps.h |  5 +++--
 2 files changed, 10 insertions(+), 5 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 11de5f1be981..32dada8c8b4f 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -825,9 +825,13 @@ static void __devinit quirk_usb_handoff_xhci(struct pci_dev *pdev)
 		}
 	}
 
-	/* Disable any BIOS SMIs */
-	writel(XHCI_LEGACY_DISABLE_SMI,
-			base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
+	val = readl(base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
+	/* Mask off (turn off) any enabled SMIs */
+	val &= XHCI_LEGACY_DISABLE_SMI;
+	/* Mask all SMI events bits, RW1C */
+	val |= XHCI_LEGACY_SMI_EVENTS;
+	/* Disable any BIOS SMIs and clear all SMI events*/
+	writel(val, base + ext_cap_offset + XHCI_LEGACY_CONTROL_OFFSET);
 
 	if (usb_is_intel_switchable_xhci(pdev))
 		usb_enable_xhci_ports(pdev);
diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h
index c7f33123d4c0..377f4242dabb 100644
--- a/drivers/usb/host/xhci-ext-caps.h
+++ b/drivers/usb/host/xhci-ext-caps.h
@@ -62,8 +62,9 @@
 /* USB Legacy Support Control and Status Register  - section 7.1.2 */
 /* Add this offset, plus the value of xECP in HCCPARAMS to the base address */
 #define XHCI_LEGACY_CONTROL_OFFSET	(0x04)
-/* bits 1:2, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */
-#define	XHCI_LEGACY_DISABLE_SMI		((0x3 << 1) + (0xff << 5) + (0x7 << 17))
+/* bits 1:3, 5:12, and 17:19 need to be preserved; bits 21:28 should be zero */
+#define	XHCI_LEGACY_DISABLE_SMI		((0x7 << 1) + (0xff << 5) + (0x7 << 17))
+#define XHCI_LEGACY_SMI_EVENTS		(0x7 << 29)
 
 /* USB 2.0 xHCI 0.96 L1C capability - section 7.2.2.1.3.2 */
 #define XHCI_L1C               (1 << 16)
-- 
cgit v1.2.1


From 662c738d9946de521dcece2b146dced335242389 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Heiko=20St=C3=BCbner?= <heiko@sntech.de>
Date: Wed, 29 Feb 2012 23:03:11 +0100
Subject: usb: otg: gpio_vbus: Add otg transceiver events and notifiers

Commit 9ad63986c606 (pda_power: Add support for using otg transceiver events)
converted the pda-power driver to use otg events to determine the status
of the power supply.

As gpio-vbus didn't use otg events until now, this change breaks setups
of pda-power with a gpio-vbus transceiver.

This patch adds the necessary otg events and notifiers to gpio-vbus.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Dima Zavin <dima@android.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/otg/gpio_vbus.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c
index 3ece43a2e4c1..a0a2178974fe 100644
--- a/drivers/usb/otg/gpio_vbus.c
+++ b/drivers/usb/otg/gpio_vbus.c
@@ -96,7 +96,7 @@ static void gpio_vbus_work(struct work_struct *work)
 	struct gpio_vbus_data *gpio_vbus =
 		container_of(work, struct gpio_vbus_data, work);
 	struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data;
-	int gpio;
+	int gpio, status;
 
 	if (!gpio_vbus->phy.otg->gadget)
 		return;
@@ -108,7 +108,9 @@ static void gpio_vbus_work(struct work_struct *work)
 	 */
 	gpio = pdata->gpio_pullup;
 	if (is_vbus_powered(pdata)) {
+		status = USB_EVENT_VBUS;
 		gpio_vbus->phy.state = OTG_STATE_B_PERIPHERAL;
+		gpio_vbus->phy.last_event = status;
 		usb_gadget_vbus_connect(gpio_vbus->phy.otg->gadget);
 
 		/* drawing a "unit load" is *always* OK, except for OTG */
@@ -117,6 +119,9 @@ static void gpio_vbus_work(struct work_struct *work)
 		/* optionally enable D+ pullup */
 		if (gpio_is_valid(gpio))
 			gpio_set_value(gpio, !pdata->gpio_pullup_inverted);
+
+		atomic_notifier_call_chain(&gpio_vbus->phy.notifier,
+					   status, gpio_vbus->phy.otg->gadget);
 	} else {
 		/* optionally disable D+ pullup */
 		if (gpio_is_valid(gpio))
@@ -125,7 +130,12 @@ static void gpio_vbus_work(struct work_struct *work)
 		set_vbus_draw(gpio_vbus, 0);
 
 		usb_gadget_vbus_disconnect(gpio_vbus->phy.otg->gadget);
+		status = USB_EVENT_NONE;
 		gpio_vbus->phy.state = OTG_STATE_B_IDLE;
+		gpio_vbus->phy.last_event = status;
+
+		atomic_notifier_call_chain(&gpio_vbus->phy.notifier,
+					   status, gpio_vbus->phy.otg->gadget);
 	}
 }
 
@@ -287,6 +297,9 @@ static int __init gpio_vbus_probe(struct platform_device *pdev)
 			irq, err);
 		goto err_irq;
 	}
+
+	ATOMIC_INIT_NOTIFIER_HEAD(&gpio_vbus->phy.notifier);
+
 	INIT_WORK(&gpio_vbus->work, gpio_vbus_work);
 
 	gpio_vbus->vbus_draw = regulator_get(&pdev->dev, "vbus_draw");
-- 
cgit v1.2.1


From c85dcdac5852295cf6822f5c4331a6ddab72581f Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Wed, 11 Apr 2012 16:09:10 -0400
Subject: USB: gadget: storage gadgets send wrong error code for unknown
 commands

This patch (as1539) fixes a minor bug in the mass-storage gadget
drivers.  When an unknown command is received, the error code sent
back is "Invalid Field in CDB" rather than "Invalid Command".  This is
because the bitmask of CDB bytes allowed to be nonzero is incorrect.

When handling an unknown command, we don't care which command bytes
are nonzero.  All the bits in the mask should be set, not just eight
of them.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: <Michal Nazarewicz <mina86@mina86.com>
CC: <stable@vger.kernel.org>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/f_mass_storage.c | 2 +-
 drivers/usb/gadget/file_storage.c   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index a371e966425f..cb8c162cae5a 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2189,7 +2189,7 @@ unknown_cmnd:
 		common->data_size_from_cmnd = 0;
 		sprintf(unknown, "Unknown x%02x", common->cmnd[0]);
 		reply = check_command(common, common->cmnd_size,
-				      DATA_DIR_UNKNOWN, 0xff, 0, unknown);
+				      DATA_DIR_UNKNOWN, ~0, 0, unknown);
 		if (reply == 0) {
 			common->curlun->sense_data = SS_INVALID_COMMAND;
 			reply = -EINVAL;
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index 4fac56927741..a896d73f7a93 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -2579,7 +2579,7 @@ static int do_scsi_command(struct fsg_dev *fsg)
 		fsg->data_size_from_cmnd = 0;
 		sprintf(unknown, "Unknown x%02x", fsg->cmnd[0]);
 		if ((reply = check_command(fsg, fsg->cmnd_size,
-				DATA_DIR_UNKNOWN, 0xff, 0, unknown)) == 0) {
+				DATA_DIR_UNKNOWN, ~0, 0, unknown)) == 0) {
 			fsg->curlun->sense_data = SS_INVALID_COMMAND;
 			reply = -EINVAL;
 		}
-- 
cgit v1.2.1


From 1fcb57d0f6e1150003d222051aaaf4bc4a9ccc94 Mon Sep 17 00:00:00 2001
From: Keshava Munegowda <Keshava_mgowda@ti.com>
Date: Mon, 19 Mar 2012 12:12:47 +0530
Subject: ARM: OMAP3: USB: Fix the EHCI ULPI PHY reset issue

It is observed that the echi ports of 3430 sdp board
are not working due to the random timing of programming
the associated GPIOs of the ULPI PHYs of the EHCI for reset.
If the PHYs are reset at during usbhs core driver, host ports will
not work because EHCI driver is loaded after the resetting PHYs.
The PHYs should be in reset state while initializing the EHCI
controller.
The code which does the GPIO pins associated with the PHYs
are programmed to reset is moved from the USB host core driver
to EHCI driver.

Signed-off-by: Keshava Munegowda <keshava_mgowda@ti.com>
Reviewed-by: Partha Basak <parthab@india.ti.com>
Acked-by: Felipe Balbi <balbi@ti.com>
Tested-by: Igor Grinberg <grinberg@compulab.co.il>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
---
 drivers/usb/host/ehci-omap.c | 39 +++++++++++++++++++++++++++++++++++++--
 1 file changed, 37 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c
index bba9850f32f0..5c78f9e71466 100644
--- a/drivers/usb/host/ehci-omap.c
+++ b/drivers/usb/host/ehci-omap.c
@@ -42,6 +42,7 @@
 #include <plat/usb.h>
 #include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
+#include <linux/gpio.h>
 
 /* EHCI Register Set */
 #define EHCI_INSNREG04					(0xA0)
@@ -191,6 +192,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
 		}
 	}
 
+	if (pdata->phy_reset) {
+		if (gpio_is_valid(pdata->reset_gpio_port[0]))
+			gpio_request_one(pdata->reset_gpio_port[0],
+					 GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
+
+		if (gpio_is_valid(pdata->reset_gpio_port[1]))
+			gpio_request_one(pdata->reset_gpio_port[1],
+					 GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
+
+		/* Hold the PHY in RESET for enough time till DIR is high */
+		udelay(10);
+	}
+
 	pm_runtime_enable(dev);
 	pm_runtime_get_sync(dev);
 
@@ -237,6 +251,19 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev)
 	/* root ports should always stay powered */
 	ehci_port_power(omap_ehci, 1);
 
+	if (pdata->phy_reset) {
+		/* Hold the PHY in RESET for enough time till
+		 * PHY is settled and ready
+		 */
+		udelay(10);
+
+		if (gpio_is_valid(pdata->reset_gpio_port[0]))
+			gpio_set_value(pdata->reset_gpio_port[0], 1);
+
+		if (gpio_is_valid(pdata->reset_gpio_port[1]))
+			gpio_set_value(pdata->reset_gpio_port[1], 1);
+	}
+
 	return 0;
 
 err_add_hcd:
@@ -259,8 +286,9 @@ err_io:
  */
 static int ehci_hcd_omap_remove(struct platform_device *pdev)
 {
-	struct device *dev	= &pdev->dev;
-	struct usb_hcd *hcd	= dev_get_drvdata(dev);
+	struct device *dev				= &pdev->dev;
+	struct usb_hcd *hcd				= dev_get_drvdata(dev);
+	struct ehci_hcd_omap_platform_data *pdata	= dev->platform_data;
 
 	usb_remove_hcd(hcd);
 	disable_put_regulator(dev->platform_data);
@@ -269,6 +297,13 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev)
 	pm_runtime_put_sync(dev);
 	pm_runtime_disable(dev);
 
+	if (pdata->phy_reset) {
+		if (gpio_is_valid(pdata->reset_gpio_port[0]))
+			gpio_free(pdata->reset_gpio_port[0]);
+
+		if (gpio_is_valid(pdata->reset_gpio_port[1]))
+			gpio_free(pdata->reset_gpio_port[1]);
+	}
 	return 0;
 }
 
-- 
cgit v1.2.1


From b548a27b2e92ad171cc8b8d00bac5e15bb2d2956 Mon Sep 17 00:00:00 2001
From: Nicolas Ferre <nicolas.ferre@atmel.com>
Date: Fri, 6 Apr 2012 14:35:38 +0200
Subject: USB: ohci-at91: change annotations for probe/remove functions

Add __devinit and __devexit on *_probe() and *_remove() functions
with proper modification of struct platform_driver.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Cc: linux-usb@vger.kernel.org
---
 drivers/usb/host/ohci-at91.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 09f597ad6e00..13ebeca8e73e 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -94,7 +94,7 @@ static void at91_stop_hc(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
+static void __devexit usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
 
 /* configure so an HC device and id are always provided */
 /* always called with process context; sleeping is OK */
@@ -108,7 +108,7 @@ static void usb_hcd_at91_remove (struct usb_hcd *, struct platform_device *);
  * then invokes the start() method for the HCD associated with it
  * through the hotplug entry's driver_data.
  */
-static int usb_hcd_at91_probe(const struct hc_driver *driver,
+static int __devinit usb_hcd_at91_probe(const struct hc_driver *driver,
 			struct platform_device *pdev)
 {
 	int retval;
@@ -203,7 +203,7 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
  * context, "rmmod" or something similar.
  *
  */
-static void usb_hcd_at91_remove(struct usb_hcd *hcd,
+static void __devexit usb_hcd_at91_remove(struct usb_hcd *hcd,
 				struct platform_device *pdev)
 {
 	usb_remove_hcd(hcd);
@@ -545,7 +545,7 @@ static int __devinit ohci_at91_of_init(struct platform_device *pdev)
 
 /*-------------------------------------------------------------------------*/
 
-static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
+static int __devinit ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 {
 	struct at91_usbh_data	*pdata;
 	int			i;
@@ -620,7 +620,7 @@ static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
 	return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
 }
 
-static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
+static int __devexit ohci_hcd_at91_drv_remove(struct platform_device *pdev)
 {
 	struct at91_usbh_data	*pdata = pdev->dev.platform_data;
 	int			i;
@@ -696,7 +696,7 @@ MODULE_ALIAS("platform:at91_ohci");
 
 static struct platform_driver ohci_hcd_at91_driver = {
 	.probe		= ohci_hcd_at91_drv_probe,
-	.remove		= ohci_hcd_at91_drv_remove,
+	.remove		= __devexit_p(ohci_hcd_at91_drv_remove),
 	.shutdown	= usb_hcd_platform_shutdown,
 	.suspend	= ohci_hcd_at91_drv_suspend,
 	.resume		= ohci_hcd_at91_drv_resume,
-- 
cgit v1.2.1


From 70756027b0a01cb0bebf2e20d8d28e8103025734 Mon Sep 17 00:00:00 2001
From: Nicolas Ferre <nicolas.ferre@atmel.com>
Date: Mon, 16 Apr 2012 10:58:12 +0200
Subject: USB: gadget/at91_udc: add gpio_to_irq() function to vbus interrupt

Now that we are using irqdomains, we need to convert GPIO pins to Linux
IRQ numbers using the gpio_to_irq() function.
This call is added to request/free_irq calls.

Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Felipe Balbi <balbi@ti.com>
Cc: linux-usb@vger.kernel.org
---
 drivers/usb/gadget/at91_udc.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 0c935d7c65bd..9d7bcd910074 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -1863,8 +1863,8 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
 			mod_timer(&udc->vbus_timer,
 				  jiffies + VBUS_POLL_TIMEOUT);
 		} else {
-			if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
-					0, driver_name, udc)) {
+			if (request_irq(gpio_to_irq(udc->board.vbus_pin),
+					at91_vbus_irq, 0, driver_name, udc)) {
 				DBG("request vbus irq %d failed\n",
 				    udc->board.vbus_pin);
 				retval = -EBUSY;
@@ -1886,7 +1886,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
 	return 0;
 fail4:
 	if (gpio_is_valid(udc->board.vbus_pin) && !udc->board.vbus_polled)
-		free_irq(udc->board.vbus_pin, udc);
+		free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
 fail3:
 	if (gpio_is_valid(udc->board.vbus_pin))
 		gpio_free(udc->board.vbus_pin);
@@ -1924,7 +1924,7 @@ static int __exit at91udc_remove(struct platform_device *pdev)
 	device_init_wakeup(&pdev->dev, 0);
 	remove_debug_file(udc);
 	if (gpio_is_valid(udc->board.vbus_pin)) {
-		free_irq(udc->board.vbus_pin, udc);
+		free_irq(gpio_to_irq(udc->board.vbus_pin), udc);
 		gpio_free(udc->board.vbus_pin);
 	}
 	free_irq(udc->udp_irq, udc);
-- 
cgit v1.2.1


From 8963c487a80b4688c9e68dcc504a90074aacc145 Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Tue, 17 Apr 2012 15:22:39 -0400
Subject: USB: fix deadlock in bConfigurationValue attribute method

This patch (as154) fixes a self-deadlock that occurs when userspace
writes to the bConfigurationValue sysfs attribute for a hub with
children.  The task tries to lock the bandwidth_mutex at a time when
it already owns the lock:

	The attribute's method calls usb_set_configuration(),
	which calls usb_disable_device() with the bandwidth_mutex
	held.

	usb_disable_device() unregisters the existing interfaces,
	which causes the hub driver to be unbound.

	The hub_disconnect() routine calls hub_quiesce(), which
	calls usb_disconnect() for each of the hub's children.

	usb_disconnect() attempts to acquire the bandwidth_mutex
	around a call to usb_disable_device().

The solution is to make usb_disable_device() acquire the mutex for
itself instead of requiring the caller to hold it.  Then the mutex can
cover only the bandwidth deallocation operation and not the region
where the interfaces are unregistered.

This has the potential to change system behavior slightly when a
config change races with another config or altsetting change.  Some of
the bandwidth released from the old config might get claimed by the
other config or altsetting, make it impossible to restore the old
config in case of a failure.  But since we don't try to recover from
config-change failures anyway, this doesn't matter.

[This should be marked for stable kernels that contain the commit
fccf4e86200b8f5edd9a65da26f150e32ba79808 "USB: Free bandwidth when
usb_disable_device is called."
That commit was marked for stable kernels as old as 2.6.32.]

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/core/hub.c     | 3 ---
 drivers/usb/core/message.c | 6 +++---
 2 files changed, 3 insertions(+), 6 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a2aa9d652c67..ec6c97dadbe4 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1667,7 +1667,6 @@ void usb_disconnect(struct usb_device **pdev)
 {
 	struct usb_device	*udev = *pdev;
 	int			i;
-	struct usb_hcd		*hcd = bus_to_hcd(udev->bus);
 
 	/* mark the device as inactive, so any further urb submissions for
 	 * this device (and any of its children) will fail immediately.
@@ -1690,9 +1689,7 @@ 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);
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index aed3e07942d4..ca717da3be95 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1136,8 +1136,6 @@ 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)
 {
@@ -1190,7 +1188,9 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
 			usb_disable_endpoint(dev, i + USB_DIR_IN, false);
 		}
 		/* Remove endpoints from the host controller internal state */
+		mutex_lock(hcd->bandwidth_mutex);
 		usb_hcd_alloc_bandwidth(dev, NULL, NULL, NULL);
+		mutex_unlock(hcd->bandwidth_mutex);
 		/* Second pass: remove endpoint pointers */
 	}
 	for (i = skip_ep0; i < 16; ++i) {
@@ -1750,7 +1750,6 @@ 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 */
 
@@ -1763,6 +1762,7 @@ 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);
-- 
cgit v1.2.1


From e65cdfae71cecec0fcd43a3f9ac8b5e4ae52db08 Mon Sep 17 00:00:00 2001
From: Xi Wang <xi.wang@gmail.com>
Date: Mon, 9 Apr 2012 15:48:55 -0400
Subject: usb: usbtest: avoid integer overflow in test_ctrl_queue()

Avoid overflowing context.count = param->sglen * param->iterations,
where both `sglen' and `iterations' are from userspace.

| test_ctrl_queue()
| usbtest_ioctl()

Keep -EOPNOTSUPP for error code.

Signed-off-by: Xi Wang <xi.wang@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/misc/usbtest.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 959145baf3cf..967254afb6e8 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -904,6 +904,9 @@ test_ctrl_queue(struct usbtest_dev *dev, struct usbtest_param *param)
 	struct ctrl_ctx		context;
 	int			i;
 
+	if (param->sglen == 0 || param->iterations > UINT_MAX / param->sglen)
+		return -EOPNOTSUPP;
+
 	spin_lock_init(&context.lock);
 	context.dev = dev;
 	init_completion(&context.complete);
@@ -1981,8 +1984,6 @@ usbtest_ioctl(struct usb_interface *intf, unsigned int code, void *buf)
 
 	/* queued control messaging */
 	case 10:
-		if (param->sglen == 0)
-			break;
 		retval = 0;
 		dev_info(&intf->dev,
 				"TEST 10:  queue %d control calls, %d times\n",
-- 
cgit v1.2.1


From 8bde9a62ee74afa89f593c563e926d163b1f6ada Mon Sep 17 00:00:00 2001
From: Xi Wang <xi.wang@gmail.com>
Date: Mon, 9 Apr 2012 15:48:45 -0400
Subject: usb: usbtest: avoid integer overflow in alloc_sglist()

A large `nents' from userspace could overflow the allocation size,
leading to memory corruption.

| alloc_sglist()
| usbtest_ioctl()

Use kmalloc_array() to avoid the overflow.

Signed-off-by: Xi Wang <xi.wang@gmail.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/misc/usbtest.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index 967254afb6e8..cac67dea2bac 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -423,7 +423,7 @@ alloc_sglist(int nents, int max, int vary)
 	unsigned		i;
 	unsigned		size = max;
 
-	sg = kmalloc(nents * sizeof *sg, GFP_KERNEL);
+	sg = kmalloc_array(nents, sizeof *sg, GFP_KERNEL);
 	if (!sg)
 		return NULL;
 	sg_init_table(sg, nents);
-- 
cgit v1.2.1


From 749541d19e70905e3971f2a08335a206a98e4d0c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
Date: Tue, 17 Apr 2012 21:37:29 +0200
Subject: USB: sierra: avoid QMI/wwan interface on MC77xx
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

These devices have a number of non serial interfaces as well.  Use
the existing "Direct IP" blacklist to prevent binding to interfaces
which are handled by other drivers.

We also extend the "Direct IP" blacklist with with interfaces only
seen in "QMI" mode, assuming that these devices use the same
interface numbers for serial interfaces both in "Direct IP" and in
"QMI" mode.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/sierra.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index fdd5aa2c8d82..8c8bf806f6fa 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -221,7 +221,7 @@ static const struct sierra_iface_info typeB_interface_list = {
 };
 
 /* 'blacklist' of interfaces not served by this driver */
-static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11 };
+static const u8 direct_ip_non_serial_ifaces[] = { 7, 8, 9, 10, 11, 19, 20 };
 static const struct sierra_iface_info direct_ip_interface_blacklist = {
 	.infolen = ARRAY_SIZE(direct_ip_non_serial_ifaces),
 	.ifaceinfo = direct_ip_non_serial_ifaces,
@@ -289,7 +289,6 @@ static const struct usb_device_id id_table[] = {
 	{ USB_DEVICE(0x1199, 0x6856) },	/* Sierra Wireless AirCard 881 U */
 	{ USB_DEVICE(0x1199, 0x6859) },	/* Sierra Wireless AirCard 885 E */
 	{ USB_DEVICE(0x1199, 0x685A) },	/* Sierra Wireless AirCard 885 E */
-	{ USB_DEVICE(0x1199, 0x68A2) }, /* Sierra Wireless MC7710 */
 	/* Sierra Wireless C885 */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6880, 0xFF, 0xFF, 0xFF)},
 	/* Sierra Wireless C888, Air Card 501, USB 303, USB 304 */
@@ -299,6 +298,9 @@ static const struct usb_device_id id_table[] = {
 	/* Sierra Wireless HSPA Non-Composite Device */
 	{ USB_DEVICE_AND_INTERFACE_INFO(0x1199, 0x6892, 0xFF, 0xFF, 0xFF)},
 	{ USB_DEVICE(0x1199, 0x6893) },	/* Sierra Wireless Device */
+	{ USB_DEVICE(0x1199, 0x68A2),   /* Sierra Wireless MC77xx in QMI mode */
+	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
+	},
 	{ USB_DEVICE(0x1199, 0x68A3), 	/* Sierra Wireless Direct IP modems */
 	  .driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
 	},
-- 
cgit v1.2.1


From dc75ce9d929aabeb0843a6b1a4ab320e58ba1597 Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Tue, 17 Apr 2012 15:24:15 -0400
Subject: EHCI: fix criterion for resuming the root hub

This patch (as1542) changes the criterion ehci-hcd uses to tell when
it needs to resume the controller's root hub.  A resume is needed when
a port status change is detected, obviously, but only if the root hub
is currently suspended.

Right now the driver tests whether the root hub is running, and that
is not the correct test.  In particular, if the controller has died
then the root hub should not be restarted.  In addition, some buggy
hardware occasionally requires the root hub to be running and
sending out SOF packets even while it is nominally supposed to be
suspended.

In the end, the test needs to be changed.  Rather than checking whether
the root hub is currently running, the driver will now check whether
the root hub is currently suspended.  This will yield the correct
behavior in all cases.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
CC: Peter Chen <B29397@freescale.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/host/ehci-hcd.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 806cc95317aa..95ca07a8e1b5 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -910,7 +910,7 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 		pcd_status = status;
 
 		/* resume root hub? */
-		if (!(cmd & CMD_RUN))
+		if (ehci->rh_state == EHCI_RH_SUSPENDED)
 			usb_hcd_resume_root_hub(hcd);
 
 		/* get per-port change detect bits */
-- 
cgit v1.2.1


From fc87e080e19fdeb1120ce274423fea7b2ec2f63e Mon Sep 17 00:00:00 2001
From: Felipe Balbi <balbi@ti.com>
Date: Wed, 18 Apr 2012 13:49:20 +0300
Subject: usb: musb: drop __deprecated flag

Looks like we cannot live without that double_buffer_not_ok
flag due to many HW bugs this MUSB core has.

So, let's drop the __deprecated flag to avoid annoying
compile warnings.

Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/musb/musb_core.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 93de517a32a0..f4a40f001c88 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -449,7 +449,7 @@ struct musb {
 	 * We added this flag to forcefully disable double
 	 * buffering until we get it working.
 	 */
-	unsigned                double_buffer_not_ok:1 __deprecated;
+	unsigned                double_buffer_not_ok:1;
 
 	struct musb_hdrc_config	*config;
 
-- 
cgit v1.2.1


From c67dd31c5cc745e72d033c0e7d4a2da67c90cd88 Mon Sep 17 00:00:00 2001
From: Julia Lawall <Julia.Lawall@lip6.fr>
Date: Mon, 16 Apr 2012 17:03:10 +0200
Subject: usb: musb: davinci.c: add missing unregister

usb_nop_xceiv_unregister is needed on failure of usb_get_transceiver, as
done in other error-handling code in the same function.

Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/musb/davinci.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c
index 97ab975fa442..768b4b55c816 100644
--- a/drivers/usb/musb/davinci.c
+++ b/drivers/usb/musb/davinci.c
@@ -386,7 +386,7 @@ static int davinci_musb_init(struct musb *musb)
 	usb_nop_xceiv_register();
 	musb->xceiv = usb_get_transceiver();
 	if (!musb->xceiv)
-		return -ENODEV;
+		goto unregister;
 
 	musb->mregs += DAVINCI_BASE_OFFSET;
 
@@ -444,6 +444,7 @@ static int davinci_musb_init(struct musb *musb)
 
 fail:
 	usb_put_transceiver(musb->xceiv);
+unregister:
 	usb_nop_xceiv_unregister();
 	return -ENODEV;
 }
-- 
cgit v1.2.1


From 2fbe2bf1fd37f9d99950bd8d8093623cf22cf08b Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Wed, 18 Apr 2012 11:33:00 -0400
Subject: EHCI: always clear the STS_FLR status bit

This patch (as1544) fixes a problem affecting some EHCI controllers.
They can generate interrupts whenever the STS_FLR status bit is turned
on, even though that bit is masked out in the Interrupt Enable
register.

Since the driver doesn't use STS_FLR anyway, the patch changes the
interrupt routine to clear that bit whenever it is set, rather than
leaving it alone.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Reported-and-tested-by: Tomoya MORINAGA <tomoya.rohm@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/host/ehci-hcd.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 95ca07a8e1b5..4a3bc5b7a06f 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -858,8 +858,13 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
 		goto dead;
 	}
 
+	/*
+	 * We don't use STS_FLR, but some controllers don't like it to
+	 * remain on, so mask it out along with the other status bits.
+	 */
+	masked_status = status & (INTR_MASK | STS_FLR);
+
 	/* Shared IRQ? */
-	masked_status = status & INTR_MASK;
 	if (!masked_status || unlikely(ehci->rh_state == EHCI_RH_HALTED)) {
 		spin_unlock(&ehci->lock);
 		return IRQ_NONE;
-- 
cgit v1.2.1


From f941f6922533316556d4dc6eee9c19d4a832c560 Mon Sep 17 00:00:00 2001
From: Anatolij Gustschin <agust@denx.de>
Date: Tue, 10 Apr 2012 10:48:11 +0200
Subject: USB: ehci-fsl: Fix kernel crash on mpc5121e

Since commit 28c56ea1431421dec51b7b229369e991481453df
(powerpc/usb: fix bug of kernel hang when initializing usb)
the kernel crashes on mpc5121e. mpc5121e doesn't have system interface
registers, accessing this register address space cause the machine check
exception and a kernel crash:
...
[    1.294596] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver
[    1.316491] fsl-ehci fsl-ehci.0: Freescale On-Chip EHCI Host Controller
[    1.337334] fsl-ehci fsl-ehci.0: new USB bus registered, assigned bus number 1
[    1.358548] Machine check in kernel mode.
[    1.375917] Caused by (from SRR1=49030): Transfer error ack signal
[    1.395505] Oops: Machine check, sig: 7 [#1]
[    1.413113] MPC5121 ADS
[    1.428718] Modules linked in:
[    1.444841] NIP: c026efc4 LR: c0278b50 CTR: 00000000
[    1.463342] REGS: df837ba0 TRAP: 0200   Not tainted  (3.3.0-08839-gb5174fa)
[    1.484083] MSR: 00049030 <EE,ME,IR,DR>  CR: 42042022  XER: 20000000
[    1.504099] TASK = df834000[1] 'swapper' THREAD: df836000
[    1.509667] GPR00: 1c000000 df837c50 df834000 df9d74e0 00000003 00000010 00000000 00000000
[    1.531650] GPR08: 00000020 00000000 c037cdd8 e1088000 22042028 1001a69c 00000000 00000000
[    1.553762] GPR16: 1ffbce70 00000000 1fef5b28 1fef3e08 00000000 00000000 1ffcbc7c c045b264
[    1.575824] GPR24: 0000008b 00000002 c04a7dd0 e1088000 df33c960 df9d74e0 00000000 df9d7400
[    1.612295] NIP [c026efc4] ehci_fsl_setup_phy+0x110/0x124
[    1.632454] LR [c0278b50] ehci_fsl_setup+0x29c/0x304
[    1.652065] Call Trace:
[    1.668923] [df837c50] [c0278a40] ehci_fsl_setup+0x18c/0x304 (unreliable)
[    1.690332] [df837c70] [c025cba4] usb_add_hcd+0x1f0/0x66c
[    1.710377] [df837cb0] [c0277ab8] ehci_fsl_drv_probe+0x180/0x308
[    1.731322] [df837ce0] [c01fc7a8] platform_drv_probe+0x20/0x30
[    1.752202] [df837cf0] [c01fb0ac] driver_probe_device+0x8c/0x214
[    1.773491] [df837d10] [c01f956c] bus_for_each_drv+0x6c/0xa8
[    1.794279] [df837d40] [c01fafdc] device_attach+0xb4/0xd8
[    1.814574] [df837d60] [c01fa44c] bus_probe_device+0xa4/0xb4
[    1.835343] [df837d80] [c01f87a8] device_add+0x52c/0x5dc
[    1.855462] [df837dd0] [c01fcd58] platform_device_add+0x124/0x1d0
[    1.876558] [df837df0] [c036dcec] fsl_usb2_device_register+0xa0/0xd4
[    1.897512] [df837e10] [c036df28] fsl_usb2_mph_dr_of_probe+0x208/0x264
[    1.918253] [df837e90] [c01fc7a8] platform_drv_probe+0x20/0x30
[    1.938300] [df837ea0] [c01fb0ac] driver_probe_device+0x8c/0x214
[    1.958511] [df837ec0] [c01fb2f0] __driver_attach+0xbc/0xc0
[    1.978088] [df837ee0] [c01f9608] bus_for_each_dev+0x60/0x9c
[    1.997589] [df837f10] [c01fab88] driver_attach+0x24/0x34
[    2.016757] [df837f20] [c01fa744] bus_add_driver+0x1ac/0x274
[    2.036339] [df837f50] [c01fb898] driver_register+0x88/0x150
[    2.056052] [df837f70] [c01fcabc] platform_driver_register+0x68/0x78
[    2.076650] [df837f80] [c0446500] fsl_usb2_mph_dr_driver_init+0x18/0x28
[    2.097734] [df837f90] [c0003988] do_one_initcall+0x148/0x1b0
[    2.117934] [df837fc0] [c042d89c] kernel_init+0xfc/0x190
[    2.137667] [df837ff0] [c000d2c4] kernel_thread+0x4c/0x68
[    2.157240] Instruction dump:
[    2.174119] 90050004 4e800020 2f840003 419e0014 2f840004 409eff64 6400c000 4bffff5c
[    2.196000] 64001000 7c0004ac 812b0500 0c090000 <4c00012c> 61290200 7c0004ac 912b0500
[    2.218100] ---[ end trace 21659aedb84ad816 ]---
[    2.237089]
[    3.232940] Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000007
[    3.232954]
[    3.271575] Rebooting in 1 seconds..

Check pdata->have_sysif_regs flag before accessing system interface
registers.

Signed-off-by: Anatolij Gustschin <agust@denx.de>
Cc: Shengzhou Liu <Shengzhou.Liu@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/host/ehci-fsl.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c
index 3e7345172e03..d0a84bd3f3eb 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -218,6 +218,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
 	u32 portsc;
 	struct usb_hcd *hcd = ehci_to_hcd(ehci);
 	void __iomem *non_ehci = hcd->regs;
+	struct fsl_usb2_platform_data *pdata;
+
+	pdata = hcd->self.controller->platform_data;
 
 	portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
 	portsc &= ~(PORT_PTS_MSK | PORT_PTS_PTW);
@@ -234,7 +237,9 @@ static void ehci_fsl_setup_phy(struct ehci_hcd *ehci,
 		/* fall through */
 	case FSL_USB2_PHY_UTMI:
 		/* enable UTMI PHY */
-		setbits32(non_ehci + FSL_SOC_USB_CTRL, CTRL_UTMI_PHY_EN);
+		if (pdata->have_sysif_regs)
+			setbits32(non_ehci + FSL_SOC_USB_CTRL,
+				  CTRL_UTMI_PHY_EN);
 		portsc |= PORT_PTS_UTMI;
 		break;
 	case FSL_USB2_PHY_NONE:
-- 
cgit v1.2.1


From f4a728d09a96d6a83d9c3f39035b1aa7726892ea Mon Sep 17 00:00:00 2001
From: Julia Lawall <Julia.Lawall@lip6.fr>
Date: Sun, 25 Mar 2012 21:08:32 +0200
Subject: drivers/usb/misc/usbtest.c: add kfrees

Free the two previously allocated buffers before exiting the function in an
error case.

Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/misc/usbtest.c | 2 ++
 1 file changed, 2 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index cac67dea2bac..9dcb68f04f03 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -2277,6 +2277,8 @@ usbtest_probe(struct usb_interface *intf, const struct usb_device_id *id)
 			if (status < 0) {
 				WARNING(dev, "couldn't get endpoints, %d\n",
 						status);
+				kfree(dev->buf);
+				kfree(dev);
 				return status;
 			}
 			/* may find bulk or ISO pipes */
-- 
cgit v1.2.1


From 523fc5c14f6cad283e5a266eba0e343aed6e73d5 Mon Sep 17 00:00:00 2001
From: Tomoki Sekiyama <tomoki.sekiyama@gmail.com>
Date: Fri, 30 Mar 2012 08:51:28 +0900
Subject: USB: yurex: Remove allocation of coherent buffer for setup-packet
 buffer

Removes allocation of coherent buffer for the control-request setup-packet
buffer from the yurex driver. Using coherent buffers for setup-packet is
obsolete and does not work with some USB host implementations.

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/misc/yurex.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c
index 897edda42270..a4a76fcd41cd 100644
--- a/drivers/usb/misc/yurex.c
+++ b/drivers/usb/misc/yurex.c
@@ -99,9 +99,7 @@ static void yurex_delete(struct kref *kref)
 	usb_put_dev(dev->udev);
 	if (dev->cntl_urb) {
 		usb_kill_urb(dev->cntl_urb);
-		if (dev->cntl_req)
-			usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
-				dev->cntl_req, dev->cntl_urb->setup_dma);
+		kfree(dev->cntl_req);
 		if (dev->cntl_buffer)
 			usb_free_coherent(dev->udev, YUREX_BUF_SIZE,
 				dev->cntl_buffer, dev->cntl_urb->transfer_dma);
@@ -234,9 +232,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
 	}
 
 	/* allocate buffer for control req */
-	dev->cntl_req = usb_alloc_coherent(dev->udev, YUREX_BUF_SIZE,
-					   GFP_KERNEL,
-					   &dev->cntl_urb->setup_dma);
+	dev->cntl_req = kmalloc(YUREX_BUF_SIZE, GFP_KERNEL);
 	if (!dev->cntl_req) {
 		err("Could not allocate cntl_req");
 		goto error;
-- 
cgit v1.2.1


From 532f17b5d59bf0deb6f1ff9bc1fb27d5b5011c09 Mon Sep 17 00:00:00 2001
From: Tomoki Sekiyama <tomoki.sekiyama@gmail.com>
Date: Fri, 30 Mar 2012 08:51:36 +0900
Subject: USB: yurex: Fix missing URB_NO_TRANSFER_DMA_MAP flag in urb

Current probing code is setting URB_NO_TRANSFER_DMA_MAP flag into a wrong urb
structure, and this causes BUG_ON with some USB host implementations.
This patch fixes the issue.

Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/misc/yurex.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/misc/yurex.c b/drivers/usb/misc/yurex.c
index a4a76fcd41cd..70201462e19c 100644
--- a/drivers/usb/misc/yurex.c
+++ b/drivers/usb/misc/yurex.c
@@ -282,7 +282,7 @@ static int yurex_probe(struct usb_interface *interface, const struct usb_device_
 			 usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),
 			 dev->int_buffer, YUREX_BUF_SIZE, yurex_interrupt,
 			 dev, 1);
-	dev->cntl_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+	dev->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	if (usb_submit_urb(dev->urb, GFP_KERNEL)) {
 		retval = -EIO;
 		err("Could not submitting URB");
-- 
cgit v1.2.1


From 8034761c219ce545a9f4d3b23cfda47a0027cc8c Mon Sep 17 00:00:00 2001
From: Stephen Warren <swarren@nvidia.com>
Date: Wed, 18 Apr 2012 14:43:40 -0600
Subject: USB: ehci-tegra: don't call set_irq_flags(IRQF_VALID)

This call is not needed; the IRQ controller should (and does) set up
interrupts correctly. set_irq_flags() isn't exported to modules, to
this also fixes compilation of ehci-tegra.c as a module.

Signed-off-by: Stephen Warren <swarren@nvidia.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/host/ehci-tegra.c | 1 -
 1 file changed, 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 73544bd440bd..86183366647f 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -731,7 +731,6 @@ static int tegra_ehci_probe(struct platform_device *pdev)
 		err = -ENODEV;
 		goto fail;
 	}
-	set_irq_flags(irq, IRQF_VALID);
 
 #ifdef CONFIG_USB_OTG_UTILS
 	if (pdata->operating_mode == TEGRA_USB_OTG) {
-- 
cgit v1.2.1


From 15b120d67019d691e4389372967332d74a80522a Mon Sep 17 00:00:00 2001
From: Felipe Balbi <balbi@ti.com>
Date: Wed, 18 Apr 2012 13:59:30 +0300
Subject: usb: gadget: dummy: do not call pullup() on udc_stop()

pullup() is already called properly by udc-core.c and
there's no need to call it from udc_stop(), in fact that
will cause issues.

Cc: stable@vger.kernel.org
Reviewed-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Acked-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/dummy_hcd.c | 1 -
 1 file changed, 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c
index a6dfd2164166..170cbe89d9f8 100644
--- a/drivers/usb/gadget/dummy_hcd.c
+++ b/drivers/usb/gadget/dummy_hcd.c
@@ -927,7 +927,6 @@ static int dummy_udc_stop(struct usb_gadget *g,
 
 	dum->driver = NULL;
 
-	dummy_pullup(&dum->gadget, 0);
 	return 0;
 }
 
-- 
cgit v1.2.1


From 2d5733fcd33dd451022d197cb6b476e970519ca7 Mon Sep 17 00:00:00 2001
From: Yuri Matylitski <ym@tekinsoft.com>
Date: Fri, 20 Apr 2012 12:38:32 +0300
Subject: USB: serial: cp210x: Fixed usb_control_msg timeout values

Fixed too small hardcoded timeout values for usb_control_msg
in driver for SiliconLabs cp210x-based usb-to-serial adapters.
Replaced with USB_CTRL_GET_TIMEOUT/USB_CTRL_SET_TIMEOUT.

Signed-off-by: Yuri Matylitski <ym@tekinsoft.com>
Acked-by: Kirill A. Shutemov <kirill@shutemov.name>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/serial/cp210x.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 0310e2df59f5..ec30f95ef399 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -287,7 +287,8 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
 	/* Issue the request, attempting to read 'size' bytes */
 	result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
 				request, REQTYPE_DEVICE_TO_HOST, 0x0000,
-				port_priv->bInterfaceNumber, buf, size, 300);
+				port_priv->bInterfaceNumber, buf, size,
+				USB_CTRL_GET_TIMEOUT);
 
 	/* Convert data into an array of integers */
 	for (i = 0; i < length; i++)
@@ -340,12 +341,14 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
 		result = usb_control_msg(serial->dev,
 				usb_sndctrlpipe(serial->dev, 0),
 				request, REQTYPE_HOST_TO_DEVICE, 0x0000,
-				port_priv->bInterfaceNumber, buf, size, 300);
+				port_priv->bInterfaceNumber, buf, size,
+				USB_CTRL_SET_TIMEOUT);
 	} else {
 		result = usb_control_msg(serial->dev,
 				usb_sndctrlpipe(serial->dev, 0),
 				request, REQTYPE_HOST_TO_DEVICE, data[0],
-				port_priv->bInterfaceNumber, NULL, 0, 300);
+				port_priv->bInterfaceNumber, NULL, 0,
+				USB_CTRL_SET_TIMEOUT);
 	}
 
 	kfree(buf);
-- 
cgit v1.2.1


From 6f6543f53f9ce136e01d7114bf6f0818ca54fb41 Mon Sep 17 00:00:00 2001
From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Date: Tue, 24 Apr 2012 11:29:42 +0200
Subject: usb gadget: uvc: uvc_request_data::length field must be signed

The field is used to pass the UVC request data length, but can also be
used to signal an error when setting it to a negative value. Switch from
unsigned int to __s32.

Reported-by: Fernandez Gonzalo <gfernandez@copreci.es>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/gadget/uvc.h      | 2 +-
 drivers/usb/gadget/uvc_v4l2.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h
index bc78c606c12b..ca4e03a1c73a 100644
--- a/drivers/usb/gadget/uvc.h
+++ b/drivers/usb/gadget/uvc.h
@@ -28,7 +28,7 @@
 
 struct uvc_request_data
 {
-	unsigned int length;
+	__s32 length;
 	__u8 data[60];
 };
 
diff --git a/drivers/usb/gadget/uvc_v4l2.c b/drivers/usb/gadget/uvc_v4l2.c
index f6e083b50191..54d7ca559cb2 100644
--- a/drivers/usb/gadget/uvc_v4l2.c
+++ b/drivers/usb/gadget/uvc_v4l2.c
@@ -39,7 +39,7 @@ uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)
 	if (data->length < 0)
 		return usb_ep_set_halt(cdev->gadget->ep0);
 
-	req->length = min(uvc->event_length, data->length);
+	req->length = min_t(unsigned int, uvc->event_length, data->length);
 	req->zero = data->length < uvc->event_length;
 	req->dma = DMA_ADDR_INVALID;
 
-- 
cgit v1.2.1


From 151b61284776be2d6f02d48c23c3625678960b97 Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Tue, 24 Apr 2012 14:07:22 -0400
Subject: USB: EHCI: fix crash during suspend on ASUS computers

This patch (as1545) fixes a problem affecting several ASUS computers:
The machine crashes or corrupts memory when going into suspend if the
ehci-hcd driver is bound to any controllers.  Users have been forced
to unbind or unload ehci-hcd before putting their systems to sleep.

After extensive testing, it was determined that the machines don't
like going into suspend when any EHCI controllers are in the PCI D3
power state.  Presumably this is a firmware bug, but there's nothing
we can do about it except to avoid putting the controllers in D3
during system sleep.

The patch adds a new flag to indicate whether the problem is present,
and avoids changing the controller's power state if the flag is set.
Runtime suspend is unaffected; this matters only for system suspend.
However as a side effect, the controller will not respond to remote
wakeup requests while the system is asleep.  Hence USB wakeup is not
functional -- but of course, this is already true in the current state
of affairs.

This fixes Bugzilla #42728.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Tested-by: Steven Rostedt <rostedt@goodmis.org>
Tested-by: Andrey Rahmatullin <wrar@wrar.name>
Tested-by: Oleksij Rempel (fishor) <bug-track@fisher-privat.net>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/core/hcd-pci.c  | 9 +++++++++
 drivers/usb/host/ehci-pci.c | 8 ++++++++
 2 files changed, 17 insertions(+)

(limited to 'drivers/usb')

diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index 622b4a48e732..57ed9e400c06 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -493,6 +493,15 @@ static int hcd_pci_suspend_noirq(struct device *dev)
 
 	pci_save_state(pci_dev);
 
+	/*
+	 * Some systems crash if an EHCI controller is in D3 during
+	 * a sleep transition.  We have to leave such controllers in D0.
+	 */
+	if (hcd->broken_pci_sleep) {
+		dev_dbg(dev, "Staying in PCI D0\n");
+		return retval;
+	}
+
 	/* If the root hub is dead rather than suspended, disallow remote
 	 * wakeup.  usb_hc_died() should ensure that both hosts are marked as
 	 * dying, so we only need to check the primary roothub.
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c
index 01bb7241d6ef..fe8dc069164e 100644
--- a/drivers/usb/host/ehci-pci.c
+++ b/drivers/usb/host/ehci-pci.c
@@ -144,6 +144,14 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
 			hcd->has_tt = 1;
 			tdi_reset(ehci);
 		}
+		if (pdev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK) {
+			/* EHCI #1 or #2 on 6 Series/C200 Series chipset */
+			if (pdev->device == 0x1c26 || pdev->device == 0x1c2d) {
+				ehci_info(ehci, "broken D3 during system sleep on ASUS\n");
+				hcd->broken_pci_sleep = 1;
+				device_set_wakeup_capable(&pdev->dev, false);
+			}
+		}
 		break;
 	case PCI_VENDOR_ID_TDI:
 		if (pdev->device == PCI_DEVICE_ID_TDI_EHCI) {
-- 
cgit v1.2.1


From 5c22837adca7c30b66121cf18ad3e160134268d4 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oliver@neukum.org>
Date: Thu, 26 Apr 2012 21:59:10 +0200
Subject: USB: cdc-wdm: fix race leading leading to memory corruption
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch fixes a race whereby a pointer to a buffer
would be overwritten while the buffer was in use leading
to a double free and a memory leak. This causes crashes.
This bug was introduced in 2.6.34

Signed-off-by: Oliver Neukum <oneukum@suse.de>
Tested-by: Bjørn Mork <bjorn@mork.no>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/class/cdc-wdm.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c
index c6f6560d436c..0bb2b3248dad 100644
--- a/drivers/usb/class/cdc-wdm.c
+++ b/drivers/usb/class/cdc-wdm.c
@@ -157,8 +157,9 @@ static void wdm_out_callback(struct urb *urb)
 	spin_lock(&desc->iuspin);
 	desc->werr = urb->status;
 	spin_unlock(&desc->iuspin);
-	clear_bit(WDM_IN_USE, &desc->flags);
 	kfree(desc->outbuf);
+	desc->outbuf = NULL;
+	clear_bit(WDM_IN_USE, &desc->flags);
 	wake_up(&desc->wait);
 }
 
@@ -338,7 +339,7 @@ static ssize_t wdm_write
 	if (we < 0)
 		return -EIO;
 
-	desc->outbuf = buf = kmalloc(count, GFP_KERNEL);
+	buf = kmalloc(count, GFP_KERNEL);
 	if (!buf) {
 		rv = -ENOMEM;
 		goto outnl;
@@ -406,10 +407,12 @@ static ssize_t wdm_write
 	req->wIndex = desc->inum;
 	req->wLength = cpu_to_le16(count);
 	set_bit(WDM_IN_USE, &desc->flags);
+	desc->outbuf = buf;
 
 	rv = usb_submit_urb(desc->command, GFP_KERNEL);
 	if (rv < 0) {
 		kfree(buf);
+		desc->outbuf = NULL;
 		clear_bit(WDM_IN_USE, &desc->flags);
 		dev_err(&desc->intf->dev, "Tx URB error: %d\n", rv);
 	} else {
-- 
cgit v1.2.1


From 83a787a71e034244a9fd1d5988fe18f226341417 Mon Sep 17 00:00:00 2001
From: Felipe Balbi <balbi@ti.com>
Date: Fri, 27 Apr 2012 11:02:15 +0300
Subject: usb: gadget: udc-core: fix wrong call order

commit 6d258a4 (usb: gadget: udc-core: stop UDC on device-initiated
disconnect) introduced another case of asymmetric calls when issuing
a device-initiated disconnect. Fix it.

Reported-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/udc-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index 2fa9865babed..df1bd87232dd 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -415,9 +415,9 @@ static ssize_t usb_udc_softconn_store(struct device *dev,
 			usb_gadget_udc_start(udc->gadget, udc->driver);
 		usb_gadget_connect(udc->gadget);
 	} else if (sysfs_streq(buf, "disconnect")) {
+		usb_gadget_disconnect(udc->gadget);
 		if (udc_is_newstyle(udc))
 			usb_gadget_udc_stop(udc->gadget, udc->driver);
-		usb_gadget_disconnect(udc->gadget);
 	} else {
 		dev_err(dev, "unsupported command '%s'\n", buf);
 		return -EINVAL;
-- 
cgit v1.2.1


From 320cd1e750f1bf3e47eb41209dcb2be07264cb76 Mon Sep 17 00:00:00 2001
From: Alan Stern <stern@rowland.harvard.edu>
Date: Thu, 26 Apr 2012 11:31:57 -0400
Subject: usb: gadget: udc-core: fix incompatibility with dummy-hcd

This patch (as1548) fixes a recently-introduced incompatibility
between the UDC core and the dummy-hcd driver.  Commit
8ae8090c82eb407267001f75b3d256b3bd4ae691 (usb: gadget: udc-core: fix
asymmetric calls in remove_driver) moved the usb_gadget_udc_stop()
call in usb_gadget_remove_driver() below the usb_gadget_disconnect()
call.

As a result, usb_gadget_disconnect() gets called at a time when the
gadget driver believes it has been unbound but dummy-hcd believes
it has not.  A nasty error ensues when dummy-hcd calls the gadget
driver's disconnect method a second time.

To fix the problem, this patch moves the gadget driver's unbind
notification after the usb_gadget_disconnect() call.  Now nothing
happens between the two unbind notifications, so nothing goes wrong.

Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Tested-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
---
 drivers/usb/gadget/udc-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'drivers/usb')

diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c
index df1bd87232dd..e5e44f8cde9a 100644
--- a/drivers/usb/gadget/udc-core.c
+++ b/drivers/usb/gadget/udc-core.c
@@ -263,8 +263,8 @@ static void usb_gadget_remove_driver(struct usb_udc *udc)
 
 	if (udc_is_newstyle(udc)) {
 		udc->driver->disconnect(udc->gadget);
-		udc->driver->unbind(udc->gadget);
 		usb_gadget_disconnect(udc->gadget);
+		udc->driver->unbind(udc->gadget);
 		usb_gadget_udc_stop(udc->gadget, udc->driver);
 	} else {
 		usb_gadget_stop(udc->gadget, udc->driver);
-- 
cgit v1.2.1