--- /dev/null
+From 94d0bbe849190255b93fede8eb46809a38f9b8bf Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@googlemail.com>
+Date: Tue, 13 Apr 2010 18:10:26 +0200
+Subject: ar9170usb: add a couple more USB IDs
+
+From: Christian Lamparter <chunkeey@googlemail.com>
+
+commit 94d0bbe849190255b93fede8eb46809a38f9b8bf upstream.
+
+This patch adds the following 5 entries to the usbid device table:
+
+ * Netgear WNA1000
+ * Proxim ORiNOCO Dual Band 802.11n USB Adapter
+ * 3Com Dual Band 802.11n USB Adapter
+ * H3C Dual Band 802.11n USB Adapter
+ * WNC Generic 11n USB dongle
+
+Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/ath/ar9170/usb.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/drivers/net/wireless/ath/ar9170/usb.c
++++ b/drivers/net/wireless/ath/ar9170/usb.c
+@@ -67,18 +67,28 @@ static struct usb_device_id ar9170_usb_i
+ { USB_DEVICE(0x0cf3, 0x1001) },
+ /* TP-Link TL-WN821N v2 */
+ { USB_DEVICE(0x0cf3, 0x1002) },
++ /* 3Com Dual Band 802.11n USB Adapter */
++ { USB_DEVICE(0x0cf3, 0x1010) },
++ /* H3C Dual Band 802.11n USB Adapter */
++ { USB_DEVICE(0x0cf3, 0x1011) },
+ /* Cace Airpcap NX */
+ { USB_DEVICE(0xcace, 0x0300) },
+ /* D-Link DWA 160 A1 */
+ { USB_DEVICE(0x07d1, 0x3c10) },
+ /* D-Link DWA 160 A2 */
+ { USB_DEVICE(0x07d1, 0x3a09) },
++ /* Netgear WNA1000 */
++ { USB_DEVICE(0x0846, 0x9040) },
+ /* Netgear WNDA3100 */
+ { USB_DEVICE(0x0846, 0x9010) },
+ /* Netgear WN111 v2 */
+ { USB_DEVICE(0x0846, 0x9001) },
+ /* Zydas ZD1221 */
+ { USB_DEVICE(0x0ace, 0x1221) },
++ /* Proxim ORiNOCO 802.11n USB */
++ { USB_DEVICE(0x1435, 0x0804) },
++ /* WNC Generic 11n USB Dongle */
++ { USB_DEVICE(0x1435, 0x0326) },
+ /* ZyXEL NWD271N */
+ { USB_DEVICE(0x0586, 0x3417) },
+ /* Z-Com UB81 BG */
--- /dev/null
+From 879999cec9489f8942ebce3ec1b5f23ef948dda7 Mon Sep 17 00:00:00 2001
+From: Christian Lamparter <chunkeey@googlemail.com>
+Date: Tue, 23 Mar 2010 21:51:14 +0100
+Subject: ar9170usb: fix panic triggered by undersized rxstream buffer
+
+From: Christian Lamparter <chunkeey@googlemail.com>
+
+commit 879999cec9489f8942ebce3ec1b5f23ef948dda7 upstream.
+
+While ar9170's USB transport packet size is currently set to 8KiB,
+the PHY is capable of receiving AMPDUs with up to 64KiB.
+Such a large frame will be split over several rx URBs and
+exceed the previously allocated space for rx stream reconstruction.
+
+This patch increases the buffer size to 64KiB which is
+in fact the phy & rx stream designed size limit.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=15591
+Reported-by: Christian Mehlis <mehlis@inf.fu-berlin.de>
+Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/net/wireless/ath/ar9170/hw.h | 1 +
+ drivers/net/wireless/ath/ar9170/main.c | 2 +-
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/ath/ar9170/hw.h
++++ b/drivers/net/wireless/ath/ar9170/hw.h
+@@ -425,5 +425,6 @@ enum ar9170_txq {
+
+ #define AR9170_TXQ_DEPTH 32
+ #define AR9170_TX_MAX_PENDING 128
++#define AR9170_RX_STREAM_MAX_SIZE 65535
+
+ #endif /* __AR9170_HW_H */
+--- a/drivers/net/wireless/ath/ar9170/main.c
++++ b/drivers/net/wireless/ath/ar9170/main.c
+@@ -2516,7 +2516,7 @@ void *ar9170_alloc(size_t priv_size)
+ * tends to split the streams into separate rx descriptors.
+ */
+
+- skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL);
++ skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL);
+ if (!skb)
+ goto err_nomem;
+
--- /dev/null
+From e1695307e6b85477afd2421d3b4891ca5bea8300 Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <w.sang@pengutronix.de>
+Date: Sat, 15 May 2010 11:25:35 +0100
+Subject: ARM: 6135/1: mx21/devices: fix USBOTG resource
+
+From: Wolfram Sang <w.sang@pengutronix.de>
+
+commit e1695307e6b85477afd2421d3b4891ca5bea8300 upstream.
+
+It got a typo from 988addf82e4c03739375279de73929580a2d4a6a.
+
+Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
+Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/arm/mach-mx2/devices.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/arm/mach-mx2/devices.c
++++ b/arch/arm/mach-mx2/devices.c
+@@ -483,8 +483,8 @@ int __init mxc_register_gpios(void)
+ #ifdef CONFIG_MACH_MX21
+ static struct resource mx21_usbhc_resources[] = {
+ {
+- .start = MX21_BASE_ADDR,
+- .end = MX21_BASE_ADDR + 0x1FFF,
++ .start = MX21_USBOTG_BASE_ADDR,
++ .end = MX21_USBOTG_BASE_ADDR + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
--- /dev/null
+From c2fd1a4ebf9127c280d227acb635eb1df213439c Mon Sep 17 00:00:00 2001
+From: Cory Maccarrone <darkstar6262@gmail.com>
+Date: Sat, 22 May 2010 13:00:28 -0700
+Subject: HID: Add the GYR4101US USB ID to hid-gyration
+
+From: Cory Maccarrone <darkstar6262@gmail.com>
+
+commit c2fd1a4ebf9127c280d227acb635eb1df213439c upstream.
+
+This change adds in the USB product ID for the Gyration
+GYR4101US USB media center remote control. This remote
+is similar enough to the other two devices that this driver
+can be used without any other changes to get full support
+for the remote.
+
+Signed-off-by: Cory Maccarrone <darkstar6262@gmail.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/hid/hid-core.c | 1 +
+ drivers/hid/hid-gyration.c | 1 +
+ drivers/hid/hid-ids.h | 1 +
+ 3 files changed, 3 insertions(+)
+
+--- a/drivers/hid/hid-core.c
++++ b/drivers/hid/hid-core.c
+@@ -1305,6 +1305,7 @@ static const struct hid_device_id hid_bl
+ { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
+--- a/drivers/hid/hid-gyration.c
++++ b/drivers/hid/hid-gyration.c
+@@ -73,6 +73,7 @@ static int gyration_event(struct hid_dev
+ static const struct hid_device_id gyration_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
++ { HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_3) },
+ { }
+ };
+ MODULE_DEVICE_TABLE(hid, gyration_devices);
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -267,6 +267,7 @@
+ #define USB_VENDOR_ID_GYRATION 0x0c16
+ #define USB_DEVICE_ID_GYRATION_REMOTE 0x0002
+ #define USB_DEVICE_ID_GYRATION_REMOTE_2 0x0003
++#define USB_DEVICE_ID_GYRATION_REMOTE_3 0x0008
+
+ #define USB_VENDOR_ID_HAPP 0x078b
+ #define USB_DEVICE_ID_UGCI_DRIVING 0x0010
alsa-hda-use-lpib-for-sony-vpcs11v9e.patch
alsa-hda-use-lpib-for-a-shuttle-device.patch
acpi-video-fix-acpi_backlight-video.patch
+hid-add-the-gyr4101us-usb-id-to-hid-gyration.patch
+ar9170usb-add-a-couple-more-usb-ids.patch
+ar9170usb-fix-panic-triggered-by-undersized-rxstream-buffer.patch
+arm-6135-1-mx21-devices-fix-usbotg-resource.patch
+usb-visor-fix-memory-leak.patch
+usb-cp210x-new-device-ids-11-new-device-ids.patch
+usb-kobil-fix-memory-leak.patch
+usb-tty-fix-incorrect-use-of-tty_insert_flip_string_fixed_flag.patch
+usb-option-add-pid-for-zte-product.patch
+usb-option.c-olivetti-olicard100-support.patch
+usb-ir-usb-fix-double-free.patch
+usb-kl5usb105-fix-memory-leak.patch
+usb-qcaux-add-samsung-u520-device-id.patch
+usb-mxc-gadget-fix-bitfield-for-calculating-maximum-packet-size.patch
+usb-unusual-dev-add-bad-sense-flag-for-appotech-ax203-based-picture-frames.patch
+usb-fix-usbmon-and-dma-mapping-for-scatter-gather-urbs.patch
+usb-fhci-cq_get-should-check-kfifo_out-s-return-value.patch
+usb-ehci-clear-phcd-before-resuming.patch
+usb-ehci-fix-controller-wakeup-flag-settings-during-suspend.patch
+usb-xhci-fix-issue-with-set-interface-after-stall.patch
+usb-xhci-limit-bus-sg_tablesize-to-62-trbs.patch
+usb-xhci-fix-check-for-room-on-the-ring.patch
+usb-xhci-fix-wrong-usage-of-macro-trb_type.patch
--- /dev/null
+From eefd9029fde4d90d59804eeb54880ab8db5c1866 Mon Sep 17 00:00:00 2001
+From: Craig Shelley <craig@microtron.org.uk>
+Date: Sat, 15 May 2010 13:36:38 +0100
+Subject: USB: CP210x New Device IDs 11 New device IDs
+
+From: Craig Shelley <craig@microtron.org.uk>
+
+commit eefd9029fde4d90d59804eeb54880ab8db5c1866 upstream.
+
+Signed-off-by: Craig Shelley <craig@microtron.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/cp210x.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -61,6 +61,8 @@ static const struct usb_device_id id_tab
+ { USB_DEVICE(0x0745, 0x1000) }, /* CipherLab USB CCD Barcode Scanner 1000 */
+ { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */
+ { USB_DEVICE(0x08FD, 0x000A) }, /* Digianswer A/S , ZigBee/802.15.4 MAC Device */
++ { USB_DEVICE(0x0BED, 0x1100) }, /* MEI (TM) Cashflow-SC Bill/Voucher Acceptor */
++ { USB_DEVICE(0x0BED, 0x1101) }, /* MEI series 2000 Combo Acceptor */
+ { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */
+ { USB_DEVICE(0x0FCF, 0x1004) }, /* Dynastream ANT2USB */
+ { USB_DEVICE(0x0FCF, 0x1006) }, /* Dynastream ANT development board */
+@@ -72,9 +74,12 @@ static const struct usb_device_id id_tab
+ { USB_DEVICE(0x10C4, 0x1601) }, /* Arkham Technology DS101 Adapter */
+ { USB_DEVICE(0x10C4, 0x800A) }, /* SPORTident BSM7-D-USB main station */
+ { USB_DEVICE(0x10C4, 0x803B) }, /* Pololu USB-serial converter */
++ { USB_DEVICE(0x10C4, 0x8044) }, /* Cygnal Debug Adapter */
++ { USB_DEVICE(0x10C4, 0x804E) }, /* Software Bisque Paramount ME build-in converter */
+ { USB_DEVICE(0x10C4, 0x8053) }, /* Enfora EDG1228 */
+ { USB_DEVICE(0x10C4, 0x8054) }, /* Enfora GSM2228 */
+ { USB_DEVICE(0x10C4, 0x8066) }, /* Argussoft In-System Programmer */
++ { USB_DEVICE(0x10C4, 0x806F) }, /* IMS USB to RS422 Converter Cable */
+ { USB_DEVICE(0x10C4, 0x807A) }, /* Crumb128 board */
+ { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */
+ { USB_DEVICE(0x10C4, 0x80DD) }, /* Tracient RFID */
+@@ -82,12 +87,15 @@ static const struct usb_device_id id_tab
+ { USB_DEVICE(0x10C4, 0x8115) }, /* Arygon NFC/Mifare Reader */
+ { USB_DEVICE(0x10C4, 0x813D) }, /* Burnside Telecom Deskmobile */
+ { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */
++ { USB_DEVICE(0x10C4, 0x8149) }, /* West Mountain Radio Computerized Battery Analyzer */
+ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */
+ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */
+ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */
++ { USB_DEVICE(0x10C4, 0x818B) }, /* AVIT Research USB to TTL */
+ { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */
+ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */
+ { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */
++ { USB_DEVICE(0x10C4, 0x81AD) }, /* INSYS USB Modem */
+ { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */
+ { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */
+ { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */
+@@ -105,6 +113,7 @@ static const struct usb_device_id id_tab
+ { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
+ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
+ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
++ { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
+ { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
+ { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
+ { USB_DEVICE(0x10C4, 0xF003) }, /* Elan Digital Systems USBpulse100 */
+@@ -115,6 +124,8 @@ static const struct usb_device_id id_tab
+ { USB_DEVICE(0x1555, 0x0004) }, /* Owen AC4 USB-RS485 Converter */
+ { USB_DEVICE(0x166A, 0x0303) }, /* Clipsal 5500PCU C-Bus USB interface */
+ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
++ { USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
++ { USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
+ { USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
+ { USB_DEVICE(0x413C, 0x9500) }, /* DW700 GPS USB interface */
+ { } /* Terminating Entry */
--- /dev/null
+From eab80de01cb398419ef3305f35abcb367c647c8b Mon Sep 17 00:00:00 2001
+From: Alek Du <alek.du@intel.com>
+Date: Mon, 10 May 2010 11:17:49 +0800
+Subject: USB: EHCI: clear PHCD before resuming
+
+From: Alek Du <alek.du@intel.com>
+
+commit eab80de01cb398419ef3305f35abcb367c647c8b upstream.
+
+This is a bug fix for PHCD (phy clock disable) low power feature:
+After PHCD is set, any write to PORTSC register is illegal, so when
+resume ports, clear PHCD bit first.
+
+Signed-off-by: Alek Du <alek.du@intel.com>
+Cc: David Brownell <dbrownell@users.sourceforge.net>
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-hub.c | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -294,6 +294,16 @@ static int ehci_bus_resume (struct usb_h
+ /* manually resume the ports we suspended during bus_suspend() */
+ i = HCS_N_PORTS (ehci->hcs_params);
+ while (i--) {
++ /* clear phy low power mode before resume */
++ if (ehci->has_hostpc) {
++ u32 __iomem *hostpc_reg =
++ (u32 __iomem *)((u8 *)ehci->regs
++ + HOSTPC0 + 4 * (i & 0xff));
++ temp = ehci_readl(ehci, hostpc_reg);
++ ehci_writel(ehci, temp & ~HOSTPC_PHCD,
++ hostpc_reg);
++ mdelay(5);
++ }
+ temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
+ temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
+ if (test_bit(i, &ehci->bus_suspended) &&
+@@ -678,6 +688,13 @@ static int ehci_hub_control (
+ if (temp & PORT_SUSPEND) {
+ if ((temp & PORT_PE) == 0)
+ goto error;
++ /* clear phy low power mode before resume */
++ if (hostpc_reg) {
++ temp1 = ehci_readl(ehci, hostpc_reg);
++ ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
++ hostpc_reg);
++ mdelay(5);
++ }
+ /* resume signaling for 20 msec */
+ temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
+ ehci_writel(ehci, temp | PORT_RESUME,
--- /dev/null
+From 16032c4f5b291af541e9114a09ea20ff5a0dc474 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Wed, 12 May 2010 18:21:35 -0400
+Subject: USB: EHCI: fix controller wakeup flag settings during suspend
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 16032c4f5b291af541e9114a09ea20ff5a0dc474 upstream.
+
+This patch (as1380) fixes a bug in the wakeup settings for EHCI host
+controllers. When the controller is suspended, if it isn't enabled
+for remote wakeup then we have to turn off all the port wakeup flags.
+Disabling PCI PME# isn't good enough, because some systems (Intel)
+evidently use alternate wakeup signalling paths.
+
+In addition, the patch improves the handling of the Intel Moorestown
+hardware by performing various power-up and power-down delays just
+once instead of once for each port (i.e., the delays are moved outside
+of the port loops). This requires extra code, but the total delay
+time is reduced.
+
+There are also a few additional minor cleanups.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Reported-by: Ondrej Zary <linux@rainbow-software.org>
+CC: Alek Du <alek.du@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-au1xxx.c | 16 ---
+ drivers/usb/host/ehci-fsl.c | 2
+ drivers/usb/host/ehci-hub.c | 173 +++++++++++++++++++++++++++++------------
+ drivers/usb/host/ehci-pci.c | 15 ---
+ drivers/usb/host/ehci.h | 10 ++
+ 5 files changed, 145 insertions(+), 71 deletions(-)
+
+--- a/drivers/usb/host/ehci-au1xxx.c
++++ b/drivers/usb/host/ehci-au1xxx.c
+@@ -215,26 +215,17 @@ static int ehci_hcd_au1xxx_drv_suspend(s
+ msleep(10);
+
+ /* Root hub was already suspended. Disable irq emission and
+- * mark HW unaccessible, bail out if RH has been resumed. Use
+- * the spinlock to properly synchronize with possible pending
+- * RH suspend or resume activity.
+- *
+- * This is still racy as hcd->state is manipulated outside of
+- * any locks =P But that will be a different fix.
++ * mark HW unaccessible. The PM and USB cores make sure that
++ * the root hub is either suspended or stopped.
+ */
+ spin_lock_irqsave(&ehci->lock, flags);
+- if (hcd->state != HC_STATE_SUSPENDED) {
+- rc = -EINVAL;
+- goto bail;
+- }
++ ehci_prepare_ports_for_controller_suspend(ehci);
+ ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+ (void)ehci_readl(ehci, &ehci->regs->intr_enable);
+
+ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+
+ au1xxx_stop_ehc();
+-
+-bail:
+ spin_unlock_irqrestore(&ehci->lock, flags);
+
+ // could save FLADJ in case of Vaux power loss
+@@ -264,6 +255,7 @@ static int ehci_hcd_au1xxx_drv_resume(st
+ if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) {
+ int mask = INTR_MASK;
+
++ ehci_prepare_ports_for_controller_resume(ehci);
+ if (!hcd->self.root_hub->do_remote_wakeup)
+ mask &= ~STS_PCD;
+ ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+--- a/drivers/usb/host/ehci-fsl.c
++++ b/drivers/usb/host/ehci-fsl.c
+@@ -313,6 +313,7 @@ static int ehci_fsl_drv_suspend(struct d
+ struct ehci_fsl *ehci_fsl = hcd_to_ehci_fsl(hcd);
+ void __iomem *non_ehci = hcd->regs;
+
++ ehci_prepare_ports_for_controller_suspend(hcd_to_ehci(hcd));
+ if (!fsl_deep_sleep())
+ return 0;
+
+@@ -327,6 +328,7 @@ static int ehci_fsl_drv_resume(struct de
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ void __iomem *non_ehci = hcd->regs;
+
++ ehci_prepare_ports_for_controller_resume(ehci);
+ if (!fsl_deep_sleep())
+ return 0;
+
+--- a/drivers/usb/host/ehci-hub.c
++++ b/drivers/usb/host/ehci-hub.c
+@@ -106,12 +106,75 @@ static void ehci_handover_companion_port
+ ehci->owned_ports = 0;
+ }
+
++static void ehci_adjust_port_wakeup_flags(struct ehci_hcd *ehci,
++ bool suspending)
++{
++ int port;
++ u32 temp;
++
++ /* If remote wakeup is enabled for the root hub but disabled
++ * for the controller, we must adjust all the port wakeup flags
++ * when the controller is suspended or resumed. In all other
++ * cases they don't need to be changed.
++ */
++ if (!ehci_to_hcd(ehci)->self.root_hub->do_remote_wakeup ||
++ device_may_wakeup(ehci_to_hcd(ehci)->self.controller))
++ return;
++
++ /* clear phy low-power mode before changing wakeup flags */
++ if (ehci->has_hostpc) {
++ port = HCS_N_PORTS(ehci->hcs_params);
++ while (port--) {
++ u32 __iomem *hostpc_reg;
++
++ hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
++ + HOSTPC0 + 4 * port);
++ temp = ehci_readl(ehci, hostpc_reg);
++ ehci_writel(ehci, temp & ~HOSTPC_PHCD, hostpc_reg);
++ }
++ msleep(5);
++ }
++
++ port = HCS_N_PORTS(ehci->hcs_params);
++ while (port--) {
++ u32 __iomem *reg = &ehci->regs->port_status[port];
++ u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
++ u32 t2 = t1 & ~PORT_WAKE_BITS;
++
++ /* If we are suspending the controller, clear the flags.
++ * If we are resuming the controller, set the wakeup flags.
++ */
++ if (!suspending) {
++ if (t1 & PORT_CONNECT)
++ t2 |= PORT_WKOC_E | PORT_WKDISC_E;
++ else
++ t2 |= PORT_WKOC_E | PORT_WKCONN_E;
++ }
++ ehci_vdbg(ehci, "port %d, %08x -> %08x\n",
++ port + 1, t1, t2);
++ ehci_writel(ehci, t2, reg);
++ }
++
++ /* enter phy low-power mode again */
++ if (ehci->has_hostpc) {
++ port = HCS_N_PORTS(ehci->hcs_params);
++ while (port--) {
++ u32 __iomem *hostpc_reg;
++
++ hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
++ + HOSTPC0 + 4 * port);
++ temp = ehci_readl(ehci, hostpc_reg);
++ ehci_writel(ehci, temp | HOSTPC_PHCD, hostpc_reg);
++ }
++ }
++}
++
+ static int ehci_bus_suspend (struct usb_hcd *hcd)
+ {
+ struct ehci_hcd *ehci = hcd_to_ehci (hcd);
+ int port;
+ int mask;
+- u32 __iomem *hostpc_reg = NULL;
++ int changed;
+
+ ehci_dbg(ehci, "suspend root hub\n");
+
+@@ -155,15 +218,13 @@ static int ehci_bus_suspend (struct usb_
+ */
+ ehci->bus_suspended = 0;
+ ehci->owned_ports = 0;
++ changed = 0;
+ port = HCS_N_PORTS(ehci->hcs_params);
+ while (port--) {
+ u32 __iomem *reg = &ehci->regs->port_status [port];
+ u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS;
+- u32 t2 = t1;
++ u32 t2 = t1 & ~PORT_WAKE_BITS;
+
+- if (ehci->has_hostpc)
+- hostpc_reg = (u32 __iomem *)((u8 *)ehci->regs
+- + HOSTPC0 + 4 * (port & 0xff));
+ /* keep track of which ports we suspend */
+ if (t1 & PORT_OWNER)
+ set_bit(port, &ehci->owned_ports);
+@@ -172,40 +233,45 @@ static int ehci_bus_suspend (struct usb_
+ set_bit(port, &ehci->bus_suspended);
+ }
+
+- /* enable remote wakeup on all ports */
++ /* enable remote wakeup on all ports, if told to do so */
+ if (hcd->self.root_hub->do_remote_wakeup) {
+ /* only enable appropriate wake bits, otherwise the
+ * hardware can not go phy low power mode. If a race
+ * condition happens here(connection change during bits
+ * set), the port change detection will finally fix it.
+ */
+- if (t1 & PORT_CONNECT) {
++ if (t1 & PORT_CONNECT)
+ t2 |= PORT_WKOC_E | PORT_WKDISC_E;
+- t2 &= ~PORT_WKCONN_E;
+- } else {
++ else
+ t2 |= PORT_WKOC_E | PORT_WKCONN_E;
+- t2 &= ~PORT_WKDISC_E;
+- }
+- } else
+- t2 &= ~PORT_WAKE_BITS;
++ }
+
+ if (t1 != t2) {
+ ehci_vdbg (ehci, "port %d, %08x -> %08x\n",
+ port + 1, t1, t2);
+ ehci_writel(ehci, t2, reg);
+- if (hostpc_reg) {
+- u32 t3;
++ changed = 1;
++ }
++ }
+
+- spin_unlock_irq(&ehci->lock);
+- msleep(5);/* 5ms for HCD enter low pwr mode */
+- spin_lock_irq(&ehci->lock);
+- t3 = ehci_readl(ehci, hostpc_reg);
+- ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
+- t3 = ehci_readl(ehci, hostpc_reg);
+- ehci_dbg(ehci, "Port%d phy low pwr mode %s\n",
++ if (changed && ehci->has_hostpc) {
++ spin_unlock_irq(&ehci->lock);
++ msleep(5); /* 5 ms for HCD to enter low-power mode */
++ spin_lock_irq(&ehci->lock);
++
++ port = HCS_N_PORTS(ehci->hcs_params);
++ while (port--) {
++ u32 __iomem *hostpc_reg;
++ u32 t3;
++
++ hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
++ + HOSTPC0 + 4 * port);
++ t3 = ehci_readl(ehci, hostpc_reg);
++ ehci_writel(ehci, t3 | HOSTPC_PHCD, hostpc_reg);
++ t3 = ehci_readl(ehci, hostpc_reg);
++ ehci_dbg(ehci, "Port %d phy low-power mode %s\n",
+ port, (t3 & HOSTPC_PHCD) ?
+ "succeeded" : "failed");
+- }
+ }
+ }
+
+@@ -291,19 +357,28 @@ static int ehci_bus_resume (struct usb_h
+ msleep(8);
+ spin_lock_irq(&ehci->lock);
+
++ /* clear phy low-power mode before resume */
++ if (ehci->bus_suspended && ehci->has_hostpc) {
++ i = HCS_N_PORTS(ehci->hcs_params);
++ while (i--) {
++ if (test_bit(i, &ehci->bus_suspended)) {
++ u32 __iomem *hostpc_reg;
++
++ hostpc_reg = (u32 __iomem *)((u8 *) ehci->regs
++ + HOSTPC0 + 4 * i);
++ temp = ehci_readl(ehci, hostpc_reg);
++ ehci_writel(ehci, temp & ~HOSTPC_PHCD,
++ hostpc_reg);
++ }
++ }
++ spin_unlock_irq(&ehci->lock);
++ msleep(5);
++ spin_lock_irq(&ehci->lock);
++ }
++
+ /* manually resume the ports we suspended during bus_suspend() */
+ i = HCS_N_PORTS (ehci->hcs_params);
+ while (i--) {
+- /* clear phy low power mode before resume */
+- if (ehci->has_hostpc) {
+- u32 __iomem *hostpc_reg =
+- (u32 __iomem *)((u8 *)ehci->regs
+- + HOSTPC0 + 4 * (i & 0xff));
+- temp = ehci_readl(ehci, hostpc_reg);
+- ehci_writel(ehci, temp & ~HOSTPC_PHCD,
+- hostpc_reg);
+- mdelay(5);
+- }
+ temp = ehci_readl(ehci, &ehci->regs->port_status [i]);
+ temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
+ if (test_bit(i, &ehci->bus_suspended) &&
+@@ -685,23 +760,25 @@ static int ehci_hub_control (
+ goto error;
+ if (ehci->no_selective_suspend)
+ break;
+- if (temp & PORT_SUSPEND) {
+- if ((temp & PORT_PE) == 0)
+- goto error;
+- /* clear phy low power mode before resume */
+- if (hostpc_reg) {
+- temp1 = ehci_readl(ehci, hostpc_reg);
+- ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
++ if (!(temp & PORT_SUSPEND))
++ break;
++ if ((temp & PORT_PE) == 0)
++ goto error;
++
++ /* clear phy low-power mode before resume */
++ if (hostpc_reg) {
++ temp1 = ehci_readl(ehci, hostpc_reg);
++ ehci_writel(ehci, temp1 & ~HOSTPC_PHCD,
+ hostpc_reg);
+- mdelay(5);
+- }
+- /* resume signaling for 20 msec */
+- temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
+- ehci_writel(ehci, temp | PORT_RESUME,
+- status_reg);
+- ehci->reset_done [wIndex] = jiffies
+- + msecs_to_jiffies (20);
++ spin_unlock_irqrestore(&ehci->lock, flags);
++ msleep(5);/* wait to leave low-power mode */
++ spin_lock_irqsave(&ehci->lock, flags);
+ }
++ /* resume signaling for 20 msec */
++ temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS);
++ ehci_writel(ehci, temp | PORT_RESUME, status_reg);
++ ehci->reset_done[wIndex] = jiffies
++ + msecs_to_jiffies(20);
+ break;
+ case USB_PORT_FEAT_C_SUSPEND:
+ clear_bit(wIndex, &ehci->port_c_suspend);
+--- a/drivers/usb/host/ehci-pci.c
++++ b/drivers/usb/host/ehci-pci.c
+@@ -284,23 +284,15 @@ static int ehci_pci_suspend(struct usb_h
+ msleep(10);
+
+ /* Root hub was already suspended. Disable irq emission and
+- * mark HW unaccessible, bail out if RH has been resumed. Use
+- * the spinlock to properly synchronize with possible pending
+- * RH suspend or resume activity.
+- *
+- * This is still racy as hcd->state is manipulated outside of
+- * any locks =P But that will be a different fix.
++ * mark HW unaccessible. The PM and USB cores make sure that
++ * the root hub is either suspended or stopped.
+ */
+ spin_lock_irqsave (&ehci->lock, flags);
+- if (hcd->state != HC_STATE_SUSPENDED) {
+- rc = -EINVAL;
+- goto bail;
+- }
++ ehci_prepare_ports_for_controller_suspend(ehci);
+ ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+ (void)ehci_readl(ehci, &ehci->regs->intr_enable);
+
+ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags);
+- bail:
+ spin_unlock_irqrestore (&ehci->lock, flags);
+
+ // could save FLADJ in case of Vaux power loss
+@@ -330,6 +322,7 @@ static int ehci_pci_resume(struct usb_hc
+ !hibernated) {
+ int mask = INTR_MASK;
+
++ ehci_prepare_ports_for_controller_resume(ehci);
+ if (!hcd->self.root_hub->do_remote_wakeup)
+ mask &= ~STS_PCD;
+ ehci_writel(ehci, mask, &ehci->regs->intr_enable);
+--- a/drivers/usb/host/ehci.h
++++ b/drivers/usb/host/ehci.h
+@@ -536,6 +536,16 @@ struct ehci_fstn {
+
+ /*-------------------------------------------------------------------------*/
+
++/* Prepare the PORTSC wakeup flags during controller suspend/resume */
++
++#define ehci_prepare_ports_for_controller_suspend(ehci) \
++ ehci_adjust_port_wakeup_flags(ehci, true);
++
++#define ehci_prepare_ports_for_controller_resume(ehci) \
++ ehci_adjust_port_wakeup_flags(ehci, false);
++
++/*-------------------------------------------------------------------------*/
++
+ #ifdef CONFIG_USB_EHCI_ROOT_HUB_TT
+
+ /*
--- /dev/null
+From 7f1cccd3ec8789e52897bc34420ca81a5e2edeab Mon Sep 17 00:00:00 2001
+From: Anton Vorontsov <avorontsov@mvista.com>
+Date: Fri, 14 May 2010 18:33:18 +0400
+Subject: USB: FHCI: cq_get() should check kfifo_out()'s return value
+
+From: Anton Vorontsov <avorontsov@mvista.com>
+
+commit 7f1cccd3ec8789e52897bc34420ca81a5e2edeab upstream.
+
+Since commit 7acd72eb85f1c7a15e8b5eb554994949241737f1 ("kfifo: rename
+kfifo_put... into kfifo_in... and kfifo_get... into kfifo_out..."),
+kfifo_out() is marked __must_check, and that causes gcc to produce
+lots of warnings like this:
+
+ CC drivers/usb/host/fhci-mem.o
+In file included from drivers/usb/host/fhci-hcd.c:34:
+drivers/usb/host/fhci.h: In function 'cq_get':
+drivers/usb/host/fhci.h:520: warning: ignoring return value of 'kfifo_out', declared with attribute warn_unused_result
+...
+
+This patch fixes the issue by properly checking the return value.
+
+Signed-off-by: Anton Vorontsov <avorontsov@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/fhci.h | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/fhci.h
++++ b/drivers/usb/host/fhci.h
+@@ -20,6 +20,7 @@
+
+ #include <linux/kernel.h>
+ #include <linux/types.h>
++#include <linux/bug.h>
+ #include <linux/spinlock.h>
+ #include <linux/interrupt.h>
+ #include <linux/kfifo.h>
+@@ -515,9 +516,13 @@ static inline int cq_put(struct kfifo *k
+
+ static inline void *cq_get(struct kfifo *kfifo)
+ {
+- void *p = NULL;
++ unsigned int sz;
++ void *p;
++
++ sz = kfifo_out(kfifo, (void *)&p, sizeof(p));
++ if (sz != sizeof(p))
++ return NULL;
+
+- kfifo_out(kfifo, (void *)&p, sizeof(p));
+ return p;
+ }
+
--- /dev/null
+From ff9c895f07d36193c75533bda8193bde8ca99d02 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Fri, 2 Apr 2010 13:27:28 -0400
+Subject: USB: fix usbmon and DMA mapping for scatter-gather URBs
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit ff9c895f07d36193c75533bda8193bde8ca99d02 upstream.
+
+This patch (as1368) fixes a rather obscure bug in usbmon: When tracing
+URBs sent by the scatter-gather library, it accesses the data buffers
+while they are still mapped for DMA.
+
+The solution is to move the mapping and unmapping out of the s-g
+library and into the usual place in hcd.c. This requires the addition
+of new URB flag bits to describe the kind of mapping needed, since we
+have to call dma_map_sg() if the HCD supports native scatter-gather
+operation and dma_map_page() if it doesn't. The nice thing about
+having the new flags is that they simplify the testing for unmapping.
+
+The patch removes the only caller of usb_buffer_[un]map_sg(), so those
+functions are #if'ed out. A later patch will remove them entirely.
+
+As a result of this change, urb->sg will be set in situations where
+it wasn't set previously. Hence the xhci and whci drivers are
+adjusted to test urb->num_sgs instead, which retains its original
+meaning and is nonzero only when the HCD has to handle a scatterlist.
+
+Finally, even when a submission error occurs we don't want to hand
+URBs to usbmon before they are unmapped. The submission path is
+rearranged so that map_urb_for_dma() is called only for non-root-hub
+URBs and unmap_urb_for_dma() is called immediately after a submission
+error. This simplifies the error handling.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/hcd.c | 169 ++++++++++++++++++++++++++-----------------
+ drivers/usb/core/message.c | 45 ++---------
+ drivers/usb/core/urb.c | 9 +-
+ drivers/usb/core/usb.c | 4 +
+ drivers/usb/host/whci/qset.c | 2
+ drivers/usb/host/xhci-ring.c | 2
+ drivers/usb/mon/mon_bin.c | 2
+ drivers/usb/mon/mon_text.c | 4 -
+ include/linux/usb.h | 9 ++
+ 9 files changed, 138 insertions(+), 108 deletions(-)
+
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -1261,6 +1261,51 @@ static void hcd_free_coherent(struct usb
+ *dma_handle = 0;
+ }
+
++static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
++{
++ enum dma_data_direction dir;
++
++ if (urb->transfer_flags & URB_SETUP_MAP_SINGLE)
++ dma_unmap_single(hcd->self.controller,
++ urb->setup_dma,
++ sizeof(struct usb_ctrlrequest),
++ DMA_TO_DEVICE);
++ else if (urb->transfer_flags & URB_SETUP_MAP_LOCAL)
++ hcd_free_coherent(urb->dev->bus,
++ &urb->setup_dma,
++ (void **) &urb->setup_packet,
++ sizeof(struct usb_ctrlrequest),
++ DMA_TO_DEVICE);
++
++ dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
++ if (urb->transfer_flags & URB_DMA_MAP_SG)
++ dma_unmap_sg(hcd->self.controller,
++ urb->sg->sg,
++ urb->num_sgs,
++ dir);
++ else if (urb->transfer_flags & URB_DMA_MAP_PAGE)
++ dma_unmap_page(hcd->self.controller,
++ urb->transfer_dma,
++ urb->transfer_buffer_length,
++ dir);
++ else if (urb->transfer_flags & URB_DMA_MAP_SINGLE)
++ dma_unmap_single(hcd->self.controller,
++ urb->transfer_dma,
++ urb->transfer_buffer_length,
++ dir);
++ else if (urb->transfer_flags & URB_MAP_LOCAL)
++ hcd_free_coherent(urb->dev->bus,
++ &urb->transfer_dma,
++ &urb->transfer_buffer,
++ urb->transfer_buffer_length,
++ dir);
++
++ /* Make it safe to call this routine more than once */
++ urb->transfer_flags &= ~(URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL |
++ URB_DMA_MAP_SG | URB_DMA_MAP_PAGE |
++ URB_DMA_MAP_SINGLE | URB_MAP_LOCAL);
++}
++
+ static int map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
+ gfp_t mem_flags)
+ {
+@@ -1272,8 +1317,6 @@ static int map_urb_for_dma(struct usb_hc
+ * unless it uses pio or talks to another transport,
+ * or uses the provided scatter gather list for bulk.
+ */
+- if (is_root_hub(urb->dev))
+- return 0;
+
+ if (usb_endpoint_xfer_control(&urb->ep->desc)
+ && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
+@@ -1286,6 +1329,7 @@ static int map_urb_for_dma(struct usb_hc
+ if (dma_mapping_error(hcd->self.controller,
+ urb->setup_dma))
+ return -EAGAIN;
++ urb->transfer_flags |= URB_SETUP_MAP_SINGLE;
+ } else if (hcd->driver->flags & HCD_LOCAL_MEM)
+ ret = hcd_alloc_coherent(
+ urb->dev->bus, mem_flags,
+@@ -1293,20 +1337,57 @@ static int map_urb_for_dma(struct usb_hc
+ (void **)&urb->setup_packet,
+ sizeof(struct usb_ctrlrequest),
+ DMA_TO_DEVICE);
++ if (ret)
++ return ret;
++ urb->transfer_flags |= URB_SETUP_MAP_LOCAL;
+ }
+
+ dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+- if (ret == 0 && urb->transfer_buffer_length != 0
++ if (urb->transfer_buffer_length != 0
+ && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
+ if (hcd->self.uses_dma) {
+- urb->transfer_dma = dma_map_single (
+- hcd->self.controller,
+- urb->transfer_buffer,
+- urb->transfer_buffer_length,
+- dir);
+- if (dma_mapping_error(hcd->self.controller,
++ if (urb->num_sgs) {
++ int n = dma_map_sg(
++ hcd->self.controller,
++ urb->sg->sg,
++ urb->num_sgs,
++ dir);
++ if (n <= 0)
++ ret = -EAGAIN;
++ else
++ urb->transfer_flags |= URB_DMA_MAP_SG;
++ if (n != urb->num_sgs) {
++ urb->num_sgs = n;
++ urb->transfer_flags |=
++ URB_DMA_SG_COMBINED;
++ }
++ } else if (urb->sg) {
++ struct scatterlist *sg;
++
++ sg = (struct scatterlist *) urb->sg;
++ urb->transfer_dma = dma_map_page(
++ hcd->self.controller,
++ sg_page(sg),
++ sg->offset,
++ urb->transfer_buffer_length,
++ dir);
++ if (dma_mapping_error(hcd->self.controller,
+ urb->transfer_dma))
+- return -EAGAIN;
++ ret = -EAGAIN;
++ else
++ urb->transfer_flags |= URB_DMA_MAP_PAGE;
++ } else {
++ urb->transfer_dma = dma_map_single(
++ hcd->self.controller,
++ urb->transfer_buffer,
++ urb->transfer_buffer_length,
++ dir);
++ if (dma_mapping_error(hcd->self.controller,
++ urb->transfer_dma))
++ ret = -EAGAIN;
++ else
++ urb->transfer_flags |= URB_DMA_MAP_SINGLE;
++ }
+ } else if (hcd->driver->flags & HCD_LOCAL_MEM) {
+ ret = hcd_alloc_coherent(
+ urb->dev->bus, mem_flags,
+@@ -1314,55 +1395,16 @@ static int map_urb_for_dma(struct usb_hc
+ &urb->transfer_buffer,
+ urb->transfer_buffer_length,
+ dir);
+-
+- if (ret && usb_endpoint_xfer_control(&urb->ep->desc)
+- && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
+- hcd_free_coherent(urb->dev->bus,
+- &urb->setup_dma,
+- (void **)&urb->setup_packet,
+- sizeof(struct usb_ctrlrequest),
+- DMA_TO_DEVICE);
++ if (ret == 0)
++ urb->transfer_flags |= URB_MAP_LOCAL;
+ }
++ if (ret && (urb->transfer_flags & (URB_SETUP_MAP_SINGLE |
++ URB_SETUP_MAP_LOCAL)))
++ unmap_urb_for_dma(hcd, urb);
+ }
+ return ret;
+ }
+
+-static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+-{
+- enum dma_data_direction dir;
+-
+- if (is_root_hub(urb->dev))
+- return;
+-
+- if (usb_endpoint_xfer_control(&urb->ep->desc)
+- && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) {
+- if (hcd->self.uses_dma)
+- dma_unmap_single(hcd->self.controller, urb->setup_dma,
+- sizeof(struct usb_ctrlrequest),
+- DMA_TO_DEVICE);
+- else if (hcd->driver->flags & HCD_LOCAL_MEM)
+- hcd_free_coherent(urb->dev->bus, &urb->setup_dma,
+- (void **)&urb->setup_packet,
+- sizeof(struct usb_ctrlrequest),
+- DMA_TO_DEVICE);
+- }
+-
+- dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+- if (urb->transfer_buffer_length != 0
+- && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) {
+- if (hcd->self.uses_dma)
+- dma_unmap_single(hcd->self.controller,
+- urb->transfer_dma,
+- urb->transfer_buffer_length,
+- dir);
+- else if (hcd->driver->flags & HCD_LOCAL_MEM)
+- hcd_free_coherent(urb->dev->bus, &urb->transfer_dma,
+- &urb->transfer_buffer,
+- urb->transfer_buffer_length,
+- dir);
+- }
+-}
+-
+ /*-------------------------------------------------------------------------*/
+
+ /* may be called in any context with a valid urb->dev usecount
+@@ -1391,21 +1433,20 @@ int usb_hcd_submit_urb (struct urb *urb,
+ * URBs must be submitted in process context with interrupts
+ * enabled.
+ */
+- status = map_urb_for_dma(hcd, urb, mem_flags);
+- if (unlikely(status)) {
+- usbmon_urb_submit_error(&hcd->self, urb, status);
+- goto error;
+- }
+
+- if (is_root_hub(urb->dev))
++ if (is_root_hub(urb->dev)) {
+ status = rh_urb_enqueue(hcd, urb);
+- else
+- status = hcd->driver->urb_enqueue(hcd, urb, mem_flags);
++ } else {
++ status = map_urb_for_dma(hcd, urb, mem_flags);
++ if (likely(status == 0)) {
++ status = hcd->driver->urb_enqueue(hcd, urb, mem_flags);
++ if (unlikely(status))
++ unmap_urb_for_dma(hcd, urb);
++ }
++ }
+
+ if (unlikely(status)) {
+ usbmon_urb_submit_error(&hcd->self, urb, status);
+- unmap_urb_for_dma(hcd, urb);
+- error:
+ urb->hcpriv = NULL;
+ INIT_LIST_HEAD(&urb->urb_list);
+ atomic_dec(&urb->use_count);
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -259,9 +259,6 @@ static void sg_clean(struct usb_sg_reque
+ kfree(io->urbs);
+ io->urbs = NULL;
+ }
+- if (io->dev->dev.dma_mask != NULL)
+- usb_buffer_unmap_sg(io->dev, usb_pipein(io->pipe),
+- io->sg, io->nents);
+ io->dev = NULL;
+ }
+
+@@ -364,7 +361,6 @@ int usb_sg_init(struct usb_sg_request *i
+ {
+ int i;
+ int urb_flags;
+- int dma;
+ int use_sg;
+
+ if (!io || !dev || !sg
+@@ -378,21 +374,9 @@ int usb_sg_init(struct usb_sg_request *i
+ io->pipe = pipe;
+ io->sg = sg;
+ io->nents = nents;
+-
+- /* not all host controllers use DMA (like the mainstream pci ones);
+- * they can use PIO (sl811) or be software over another transport.
+- */
+- dma = (dev->dev.dma_mask != NULL);
+- if (dma)
+- io->entries = usb_buffer_map_sg(dev, usb_pipein(pipe),
+- sg, nents);
+- else
+- io->entries = nents;
++ io->entries = nents;
+
+ /* initialize all the urbs we'll use */
+- if (io->entries <= 0)
+- return io->entries;
+-
+ if (dev->bus->sg_tablesize > 0) {
+ io->urbs = kmalloc(sizeof *io->urbs, mem_flags);
+ use_sg = true;
+@@ -404,8 +388,6 @@ int usb_sg_init(struct usb_sg_request *i
+ goto nomem;
+
+ urb_flags = 0;
+- if (dma)
+- urb_flags |= URB_NO_TRANSFER_DMA_MAP;
+ if (usb_pipein(pipe))
+ urb_flags |= URB_SHORT_NOT_OK;
+
+@@ -423,12 +405,13 @@ int usb_sg_init(struct usb_sg_request *i
+
+ io->urbs[0]->complete = sg_complete;
+ io->urbs[0]->context = io;
++
+ /* A length of zero means transfer the whole sg list */
+ io->urbs[0]->transfer_buffer_length = length;
+ if (length == 0) {
+ for_each_sg(sg, sg, io->entries, i) {
+ io->urbs[0]->transfer_buffer_length +=
+- sg_dma_len(sg);
++ sg->length;
+ }
+ }
+ io->urbs[0]->sg = io;
+@@ -454,26 +437,16 @@ int usb_sg_init(struct usb_sg_request *i
+ io->urbs[i]->context = io;
+
+ /*
+- * Some systems need to revert to PIO when DMA is temporarily
+- * unavailable. For their sakes, both transfer_buffer and
+- * transfer_dma are set when possible.
+- *
+- * Note that if IOMMU coalescing occurred, we cannot
+- * trust sg_page anymore, so check if S/G list shrunk.
++ * Some systems can't use DMA; they use PIO instead.
++ * For their sakes, transfer_buffer is set whenever
++ * possible.
+ */
+- if (io->nents == io->entries && !PageHighMem(sg_page(sg)))
++ if (!PageHighMem(sg_page(sg)))
+ io->urbs[i]->transfer_buffer = sg_virt(sg);
+ else
+ io->urbs[i]->transfer_buffer = NULL;
+
+- if (dma) {
+- io->urbs[i]->transfer_dma = sg_dma_address(sg);
+- len = sg_dma_len(sg);
+- } else {
+- /* hc may use _only_ transfer_buffer */
+- len = sg->length;
+- }
+-
++ len = sg->length;
+ if (length) {
+ len = min_t(unsigned, len, length);
+ length -= len;
+@@ -481,6 +454,8 @@ int usb_sg_init(struct usb_sg_request *i
+ io->entries = i + 1;
+ }
+ io->urbs[i]->transfer_buffer_length = len;
++
++ io->urbs[i]->sg = (struct usb_sg_request *) sg;
+ }
+ io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT;
+ }
+--- a/drivers/usb/core/urb.c
++++ b/drivers/usb/core/urb.c
+@@ -333,9 +333,12 @@ int usb_submit_urb(struct urb *urb, gfp_
+ is_out = usb_endpoint_dir_out(&ep->desc);
+ }
+
+- /* Cache the direction for later use */
+- urb->transfer_flags = (urb->transfer_flags & ~URB_DIR_MASK) |
+- (is_out ? URB_DIR_OUT : URB_DIR_IN);
++ /* Clear the internal flags and cache the direction for later use */
++ urb->transfer_flags &= ~(URB_DIR_MASK | URB_DMA_MAP_SINGLE |
++ URB_DMA_MAP_PAGE | URB_DMA_MAP_SG | URB_MAP_LOCAL |
++ URB_SETUP_MAP_SINGLE | URB_SETUP_MAP_LOCAL |
++ URB_DMA_SG_COMBINED);
++ urb->transfer_flags |= (is_out ? URB_DIR_OUT : URB_DIR_IN);
+
+ if (xfertype != USB_ENDPOINT_XFER_CONTROL &&
+ dev->state < USB_STATE_CONFIGURED)
+--- a/drivers/usb/core/usb.c
++++ b/drivers/usb/core/usb.c
+@@ -893,6 +893,7 @@ void usb_buffer_unmap(struct urb *urb)
+ EXPORT_SYMBOL_GPL(usb_buffer_unmap);
+ #endif /* 0 */
+
++#if 0
+ /**
+ * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint
+ * @dev: device to which the scatterlist will be mapped
+@@ -936,6 +937,7 @@ int usb_buffer_map_sg(const struct usb_d
+ is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE) ? : -ENOMEM;
+ }
+ EXPORT_SYMBOL_GPL(usb_buffer_map_sg);
++#endif
+
+ /* XXX DISABLED, no users currently. If you wish to re-enable this
+ * XXX please determine whether the sync is to transfer ownership of
+@@ -972,6 +974,7 @@ void usb_buffer_dmasync_sg(const struct
+ EXPORT_SYMBOL_GPL(usb_buffer_dmasync_sg);
+ #endif
+
++#if 0
+ /**
+ * usb_buffer_unmap_sg - free DMA mapping(s) for a scatterlist
+ * @dev: device to which the scatterlist will be mapped
+@@ -997,6 +1000,7 @@ void usb_buffer_unmap_sg(const struct us
+ is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ }
+ EXPORT_SYMBOL_GPL(usb_buffer_unmap_sg);
++#endif
+
+ /* To disable USB, kernel command line is 'nousb' not 'usbcore.nousb' */
+ #ifdef MODULE
+--- a/drivers/usb/host/whci/qset.c
++++ b/drivers/usb/host/whci/qset.c
+@@ -646,7 +646,7 @@ int qset_add_urb(struct whc *whc, struct
+ wurb->urb = urb;
+ INIT_WORK(&wurb->dequeue_work, urb_dequeue_work);
+
+- if (urb->sg) {
++ if (urb->num_sgs) {
+ ret = qset_add_urb_sg(whc, qset, urb, mem_flags);
+ if (ret == -EINVAL) {
+ qset_free_stds(qset, urb);
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -1938,7 +1938,7 @@ int xhci_queue_bulk_tx(struct xhci_hcd *
+ int running_total, trb_buff_len, ret;
+ u64 addr;
+
+- if (urb->sg)
++ if (urb->num_sgs)
+ return queue_bulk_sg_tx(xhci, mem_flags, urb, slot_id, ep_index);
+
+ ep_ring = xhci->devs[slot_id]->eps[ep_index].ring;
+--- a/drivers/usb/mon/mon_bin.c
++++ b/drivers/usb/mon/mon_bin.c
+@@ -416,7 +416,7 @@ static unsigned int mon_bin_get_data(con
+
+ } else {
+ /* If IOMMU coalescing occurred, we cannot trust sg_page */
+- if (urb->sg->nents != urb->num_sgs) {
++ if (urb->transfer_flags & URB_DMA_SG_COMBINED) {
+ *flag = 'D';
+ return length;
+ }
+--- a/drivers/usb/mon/mon_text.c
++++ b/drivers/usb/mon/mon_text.c
+@@ -161,9 +161,7 @@ static inline char mon_text_get_data(str
+ } else {
+ struct scatterlist *sg = urb->sg->sg;
+
+- /* If IOMMU coalescing occurred, we cannot trust sg_page */
+- if (urb->sg->nents != urb->num_sgs ||
+- PageHighMem(sg_page(sg)))
++ if (PageHighMem(sg_page(sg)))
+ return 'D';
+
+ /* For the text interface we copy only the first sg buffer */
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -965,10 +965,19 @@ extern int usb_disabled(void);
+ * needed */
+ #define URB_FREE_BUFFER 0x0100 /* Free transfer buffer with the URB */
+
++/* The following flags are used internally by usbcore and HCDs */
+ #define URB_DIR_IN 0x0200 /* Transfer from device to host */
+ #define URB_DIR_OUT 0
+ #define URB_DIR_MASK URB_DIR_IN
+
++#define URB_DMA_MAP_SINGLE 0x00010000 /* Non-scatter-gather mapping */
++#define URB_DMA_MAP_PAGE 0x00020000 /* HCD-unsupported S-G */
++#define URB_DMA_MAP_SG 0x00040000 /* HCD-supported S-G */
++#define URB_MAP_LOCAL 0x00080000 /* HCD-local-memory mapping */
++#define URB_SETUP_MAP_SINGLE 0x00100000 /* Setup packet DMA mapped */
++#define URB_SETUP_MAP_LOCAL 0x00200000 /* HCD-local setup packet */
++#define URB_DMA_SG_COMBINED 0x00400000 /* S-G entries were combined */
++
+ struct usb_iso_packet_descriptor {
+ unsigned int offset;
+ unsigned int length; /* expected length */
--- /dev/null
+From 2ff78c0c2b67120c8e503268da3f177cae2228a2 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Thu, 13 May 2010 21:02:00 +0200
+Subject: USB: ir-usb: fix double free
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 2ff78c0c2b67120c8e503268da3f177cae2228a2 upstream.
+
+If the user specifies a custom bulk buffer size we get a double free at
+port release.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/ir-usb.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/ir-usb.c
++++ b/drivers/usb/serial/ir-usb.c
+@@ -312,6 +312,7 @@ static int ir_open(struct tty_struct *tt
+ kfree(port->read_urb->transfer_buffer);
+ port->read_urb->transfer_buffer = buffer;
+ port->read_urb->transfer_buffer_length = buffer_size;
++ port->bulk_in_buffer = buffer;
+
+ buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!buffer) {
+@@ -321,6 +322,7 @@ static int ir_open(struct tty_struct *tt
+ kfree(port->write_urb->transfer_buffer);
+ port->write_urb->transfer_buffer = buffer;
+ port->write_urb->transfer_buffer_length = buffer_size;
++ port->bulk_out_buffer = buffer;
+ port->bulk_out_size = buffer_size;
+ }
+
--- /dev/null
+From 313b0d80c1717ffe8f64b455a4d323996748b91a Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Wed, 19 May 2010 00:01:38 +0200
+Subject: USB: kl5usb105: fix memory leak
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 313b0d80c1717ffe8f64b455a4d323996748b91a upstream.
+
+Private data was not freed on error path in startup.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/kl5kusb105.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/kl5kusb105.c
++++ b/drivers/usb/serial/kl5kusb105.c
+@@ -321,6 +321,7 @@ err_cleanup:
+ usb_free_urb(priv->write_urb_pool[j]);
+ }
+ }
++ kfree(priv);
+ usb_set_serial_port_data(serial->port[i], NULL);
+ }
+ return -ENOMEM;
--- /dev/null
+From c0f631d1948658b27349545b2cbcb4b32f010c7a Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Sat, 15 May 2010 17:53:43 +0200
+Subject: USB: kobil: fix memory leak
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit c0f631d1948658b27349545b2cbcb4b32f010c7a upstream.
+
+An urb transfer buffer is allocated at every open but was never freed.
+
+This driver is a bit of a mess...
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/kobil_sct.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/serial/kobil_sct.c
++++ b/drivers/usb/serial/kobil_sct.c
+@@ -345,7 +345,8 @@ static void kobil_close(struct usb_seria
+
+ /* FIXME: Add rts/dtr methods */
+ if (port->write_urb) {
+- usb_kill_urb(port->write_urb);
++ usb_poison_urb(port->write_urb);
++ kfree(port->write_urb->transfer_buffer);
+ usb_free_urb(port->write_urb);
+ port->write_urb = NULL;
+ }
--- /dev/null
+From 88e3b59b5adce5b12e205af0e34d518ba0dcdc0c Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <Dinh.Nguyen@freescale.com>
+Date: Tue, 4 May 2010 10:03:01 -0500
+Subject: USB: mxc: gadget: Fix bitfield for calculating maximum packet size
+
+From: Dinh Nguyen <Dinh.Nguyen@freescale.com>
+
+commit 88e3b59b5adce5b12e205af0e34d518ba0dcdc0c upstream.
+
+The max packet length bit mask used for isochronous endpoints
+should be 0x7FF instead of 0x8FF. 0x8FF will actually clear
+higher-order bits in the max packet length field.
+
+This patch applies to 2.6.34-rc6.
+
+Signed-off-by: Dinh Nguyen <Dinh.Nguyen@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/fsl_udc_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/fsl_udc_core.c
++++ b/drivers/usb/gadget/fsl_udc_core.c
+@@ -489,7 +489,7 @@ static int fsl_ep_enable(struct usb_ep *
+ case USB_ENDPOINT_XFER_ISOC:
+ /* Calculate transactions needed for high bandwidth iso */
+ mult = (unsigned char)(1 + ((max >> 11) & 0x03));
+- max = max & 0x8ff; /* bit 0~10 */
++ max = max & 0x7ff; /* bit 0~10 */
+ /* 3 transactions at most */
+ if (mult > 3)
+ goto en_done;
--- /dev/null
+From a71ee85e1d74e862d68cc9b2f2ab6a806d2550c9 Mon Sep 17 00:00:00 2001
+From: zhao1980ming <zhao1980ming@163.com>
+Date: Mon, 3 May 2010 00:06:37 +0800
+Subject: USB: option: add PID for ZTE product
+
+From: zhao1980ming <zhao1980ming@163.com>
+
+commit a71ee85e1d74e862d68cc9b2f2ab6a806d2550c9 upstream.
+
+this patch adds ZTE modem devices
+
+Signed-off-by: Joey <zhao.ming9@zte.com.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 174 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 174 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -675,6 +675,180 @@ static const struct usb_device_id option
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1060, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1061, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1062, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1063, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1064, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1065, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1066, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1067, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1068, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1069, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1070, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1071, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1072, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1073, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1074, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1075, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1076, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1077, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1078, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1079, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1080, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1081, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1082, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1083, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1084, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1085, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1086, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1087, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1088, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1089, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1090, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1091, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1092, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1093, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1094, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1095, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1096, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1097, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1098, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1099, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1100, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1101, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1102, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1103, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1104, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1105, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1106, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1107, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1108, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1109, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1110, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1111, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1112, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1113, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1114, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1115, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1116, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1117, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1118, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1119, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1120, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1121, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1122, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1123, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1124, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1125, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1126, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1127, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1128, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1129, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1130, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1131, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1132, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1133, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1134, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1135, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1136, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1137, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1138, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1139, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1140, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1141, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1142, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1143, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1144, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1145, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1146, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1147, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1148, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1149, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1150, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1151, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1152, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1153, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1154, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1155, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1156, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1157, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1158, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1159, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1160, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1161, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1162, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1163, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1164, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1165, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1166, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1167, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1168, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1260, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1261, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1262, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1263, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1264, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1265, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1266, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1267, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1268, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1269, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1270, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1271, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1272, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1273, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1274, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1275, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1276, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1277, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1278, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1279, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1280, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1281, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1282, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1283, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1284, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1285, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1286, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1287, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1288, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1289, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1290, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1291, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1292, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1293, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1294, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1295, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1296, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1297, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) },
++ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
--- /dev/null
+From 86234d4975ce084d14711283a3bfc69305f97602 Mon Sep 17 00:00:00 2001
+From: Nils Radtke <lkml@Think-Future.de>
+Date: Mon, 17 May 2010 14:14:11 +0200
+Subject: USB: option.c: OLIVETTI OLICARD100 support
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Nils Radtke <lkml@Think-Future.de>
+
+commit 86234d4975ce084d14711283a3bfc69305f97602 upstream.
+
+This patch adds support for an olivetti olicard100 HЅDPA usb-stick.
+
+This device is a zeroCD one with ID 0b3c:c700 that needs switching via
+eject or usb-modeswitch with
+MessageContent="5553424312345678000000000000061b000000030000000000000000000000".
+After switching it has ID 0b3c:c000 and provides 5 serial ports ttyUSB[0-4].
+Port 0 (modem) and 4 are interrupt ports.
+
+Signed-off-by: Nils Radtke <lkml@Think-Future.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -380,6 +380,10 @@ static int option_resume(struct usb_ser
+
+ #define CINTERION_VENDOR_ID 0x0681
+
++/* Olivetti products */
++#define OLIVETTI_VENDOR_ID 0x0b3c
++#define OLIVETTI_PRODUCT_OLICARD100 0xc000
++
+ /* some devices interfaces need special handling due to a number of reasons */
+ enum option_blacklist_reason {
+ OPTION_BLACKLIST_NONE = 0,
+@@ -900,6 +904,8 @@ static const struct usb_device_id option
+ { USB_DEVICE(PIRELLI_VENDOR_ID, PIRELLI_PRODUCT_1012)},
+
+ { USB_DEVICE(CINTERION_VENDOR_ID, 0x0047) },
++
++ { USB_DEVICE(OLIVETTI_VENDOR_ID, OLIVETTI_PRODUCT_OLICARD100) },
+ { } /* Terminating entry */
+ };
+ MODULE_DEVICE_TABLE(usb, option_ids);
--- /dev/null
+From f5cddcd0995366f15d2b6b0df556a2cd99fa806e Mon Sep 17 00:00:00 2001
+From: Dan Williams <dcbw@redhat.com>
+Date: Mon, 3 May 2010 13:41:01 -0700
+Subject: USB: qcaux: add Samsung U520 device ID
+
+From: Dan Williams <dcbw@redhat.com>
+
+commit f5cddcd0995366f15d2b6b0df556a2cd99fa806e upstream.
+
+Another CDC-ACM + vendor specific interface layout.
+
+Signed-off-by: Dan Williams <dcbw@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/qcaux.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/serial/qcaux.c
++++ b/drivers/usb/serial/qcaux.c
+@@ -50,6 +50,10 @@
+ #define SANYO_VENDOR_ID 0x0474
+ #define SANYO_PRODUCT_KATANA_LX 0x0754 /* SCP-3800 (Katana LX) */
+
++/* Samsung devices */
++#define SAMSUNG_VENDOR_ID 0x04e8
++#define SAMSUNG_PRODUCT_U520 0x6640 /* SCH-U520 */
++
+ static struct usb_device_id id_table[] = {
+ { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5740, 0xff, 0x00, 0x00) },
+ { USB_DEVICE_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, UTSTARCOM_PRODUCT_PC5750, 0xff, 0x00, 0x00) },
+@@ -61,6 +65,7 @@ static struct usb_device_id id_table[] =
+ { USB_DEVICE_AND_INTERFACE_INFO(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CDX650, 0xff, 0xff, 0x00) },
+ { USB_DEVICE_AND_INTERFACE_INFO(LG_VENDOR_ID, LG_PRODUCT_VX4400_6000, 0xff, 0xff, 0x00) },
+ { USB_DEVICE_AND_INTERFACE_INFO(SANYO_VENDOR_ID, SANYO_PRODUCT_KATANA_LX, 0xff, 0xff, 0x00) },
++ { USB_DEVICE_AND_INTERFACE_INFO(SAMSUNG_VENDOR_ID, SAMSUNG_PRODUCT_U520, 0xff, 0x00, 0x00) },
+ { },
+ };
+ MODULE_DEVICE_TABLE(usb, id_table);
--- /dev/null
+From 70ced221cc9f041481f129e63cc5b1dedb0ff959 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Fri, 7 May 2010 19:46:56 +0200
+Subject: USB: tty: fix incorrect use of tty_insert_flip_string_fixed_flag
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 70ced221cc9f041481f129e63cc5b1dedb0ff959 upstream.
+
+Fix regression introduced by commit
+a108bfcb372d8c4452701039308fb95747911c59 (USB: tty: Prune uses of
+tty_request_room in the USB layer) which broke three drivers
+(cypress_m8, digi_acceleport and spcp8x5) through incorrect use of
+tty_insert_flip_string_fixed_flag.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/cypress_m8.c | 2 +-
+ drivers/usb/serial/digi_acceleport.c | 4 ++--
+ drivers/usb/serial/spcp8x5.c | 4 ++--
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/usb/serial/cypress_m8.c
++++ b/drivers/usb/serial/cypress_m8.c
+@@ -1309,7 +1309,7 @@ static void cypress_read_int_callback(st
+ /* process read if there is data other than line status */
+ if (tty && bytes > i) {
+ tty_insert_flip_string_fixed_flag(tty, data + i,
+- bytes - i, tty_flag);
++ tty_flag, bytes - i);
+ tty_flip_buffer_push(tty);
+ }
+
+--- a/drivers/usb/serial/digi_acceleport.c
++++ b/drivers/usb/serial/digi_acceleport.c
+@@ -1703,8 +1703,8 @@ static int digi_read_inb_callback(struct
+ /* data length is len-1 (one byte of len is port_status) */
+ --len;
+ if (len > 0) {
+- tty_insert_flip_string_fixed_flag(tty, data, len,
+- flag);
++ tty_insert_flip_string_fixed_flag(tty, data, flag,
++ len);
+ tty_flip_buffer_push(tty);
+ }
+ }
+--- a/drivers/usb/serial/spcp8x5.c
++++ b/drivers/usb/serial/spcp8x5.c
+@@ -726,8 +726,8 @@ static void spcp8x5_read_bulk_callback(s
+ /* overrun is special, not associated with a char */
+ if (status & UART_OVERRUN_ERROR)
+ tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+- tty_insert_flip_string_fixed_flag(tty, data,
+- urb->actual_length, tty_flag);
++ tty_insert_flip_string_fixed_flag(tty, data, tty_flag,
++ urb->actual_length);
+ tty_flip_buffer_push(tty);
+ }
+ tty_kref_put(tty);
--- /dev/null
+From a78f4f1a16d87f3d33158d036af94e48e32f8aad Mon Sep 17 00:00:00 2001
+From: Hans de Goede <hdegoede@redhat.com>
+Date: Thu, 29 Apr 2010 12:59:04 +0200
+Subject: USB: unusual-dev: Add bad sense flag for Appotech ax203 based picture frames
+
+From: Hans de Goede <hdegoede@redhat.com>
+
+commit a78f4f1a16d87f3d33158d036af94e48e32f8aad upstream.
+
+These Appotech controllers are found in Picture Frames, they provide a
+(buggy) emulation of a cdrom drive which contains the windows software
+Uploading of pictures happens over the corresponding /dev/sg device.
+
+Signed-off-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/storage/unusual_devs.h | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1853,6 +1853,21 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
++/* Reported by Hans de Goede <hdegoede@redhat.com>
++ * These Appotech controllers are found in Picture Frames, they provide a
++ * (buggy) emulation of a cdrom drive which contains the windows software
++ * Uploading of pictures happens over the corresponding /dev/sg device. */
++UNUSUAL_DEV( 0x1908, 0x1315, 0x0000, 0x0000,
++ "BUILDWIN",
++ "Photo Frame",
++ US_SC_DEVICE, US_PR_DEVICE, NULL,
++ US_FL_BAD_SENSE ),
++UNUSUAL_DEV( 0x1908, 0x1320, 0x0000, 0x0000,
++ "BUILDWIN",
++ "Photo Frame",
++ US_SC_DEVICE, US_PR_DEVICE, NULL,
++ US_FL_BAD_SENSE ),
++
+ UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001,
+ "ST",
+ "2A",
--- /dev/null
+From 199b113978015309dd02c69844c19a1be3f4dbcf Mon Sep 17 00:00:00 2001
+From: Johan Hovold <jhovold@gmail.com>
+Date: Sat, 15 May 2010 17:53:48 +0200
+Subject: USB: visor: fix memory leak
+
+From: Johan Hovold <jhovold@gmail.com>
+
+commit 199b113978015309dd02c69844c19a1be3f4dbcf upstream.
+
+Fix memory leak for some devices (Sony Clie 3.5) due to port private
+data not being freed on release.
+
+Signed-off-by: Johan Hovold <jhovold@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/visor.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/usb/serial/visor.c
++++ b/drivers/usb/serial/visor.c
+@@ -249,6 +249,7 @@ static struct usb_serial_driver clie_3_5
+ .throttle = visor_throttle,
+ .unthrottle = visor_unthrottle,
+ .attach = clie_3_5_startup,
++ .release = visor_release,
+ .write = visor_write,
+ .write_room = visor_write_room,
+ .write_bulk_callback = visor_write_bulk_callback,
--- /dev/null
+From 44ebd037c54f80db3121ac9f5fe6e677b76e11d5 Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Tue, 18 May 2010 16:05:26 -0700
+Subject: USB: xhci: Fix check for room on the ring.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 44ebd037c54f80db3121ac9f5fe6e677b76e11d5 upstream.
+
+The length of the scatter gather list a driver can enqueue is limited by
+the bus' sg_tablesize to 62 entries. Each entry will be described by at
+least one transfer request block (TRB). If the entry's buffer crosses a
+64KB boundary, then that entry will have to be described by two or more
+TRBs. So even if the USB device driver respects sg_tablesize, the whole
+scatter list may take more than 62 TRBs to describe, and won't fit on
+the ring.
+
+Don't assume that an empty ring means there is enough room on the
+transfer ring. The old code would unconditionally queue this too-large
+transfer, and over write the beginning of the transfer. This would mean
+the cycle bit was unchanged in those overwritten transfers, causing the
+hardware to think it didn't own the TRBs, and the host would seem to
+hang.
+
+Now drivers may see submit_urb() fail with -ENOMEM if the transfers are
+too big to fit on the ring.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -242,10 +242,27 @@ static int room_on_ring(struct xhci_hcd
+ int i;
+ union xhci_trb *enq = ring->enqueue;
+ struct xhci_segment *enq_seg = ring->enq_seg;
++ struct xhci_segment *cur_seg;
++ unsigned int left_on_ring;
+
+ /* Check if ring is empty */
+- if (enq == ring->dequeue)
++ if (enq == ring->dequeue) {
++ /* Can't use link trbs */
++ left_on_ring = TRBS_PER_SEGMENT - 1;
++ for (cur_seg = enq_seg->next; cur_seg != enq_seg;
++ cur_seg = cur_seg->next)
++ left_on_ring += TRBS_PER_SEGMENT - 1;
++
++ /* Always need one TRB free in the ring. */
++ left_on_ring -= 1;
++ if (num_trbs > left_on_ring) {
++ xhci_warn(xhci, "Not enough room on ring; "
++ "need %u TRBs, %u TRBs left\n",
++ num_trbs, left_on_ring);
++ return 0;
++ }
+ return 1;
++ }
+ /* Make sure there's an extra empty TRB available */
+ for (i = 0; i <= num_trbs; ++i) {
+ if (enq == ring->dequeue)
--- /dev/null
+From 1624ae1c19e227096ba85bfc389d9b99cb6f7dde Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Thu, 6 May 2010 13:40:08 -0700
+Subject: USB: xhci: Fix issue with set interface after stall.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit 1624ae1c19e227096ba85bfc389d9b99cb6f7dde upstream.
+
+When the USB core installs a new interface, it unconditionally clears the
+halts on all the endpoints on the new interface. Usually the xHCI host
+needs to know when an endpoint is reset, so it can change its internal
+endpoint state. In this case, it doesn't care, because the endpoints were
+never halted in the first place.
+
+To avoid issuing a redundant Reset Endpoint command, the xHCI driver looks
+at xhci_virt_ep->stopped_td to determine if the endpoint was actually
+halted. However, the functions that handle the stall never set that
+variable to NULL after it dealt with the stall. So if an endpoint stalled
+and a Reset Endpoint command completed, and then the class driver tried to
+install a new alternate setting, the xHCI driver would access the old
+xhci_virt_ep->stopped_td pointer. A similar problem occurs if the
+endpoint has been stopped to cancel a transfer.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c | 7 +++++++
+ drivers/usb/host/xhci.c | 2 ++
+ 2 files changed, 9 insertions(+)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -578,6 +578,8 @@ static void handle_stopped_endpoint(stru
+ /* Otherwise just ring the doorbell to restart the ring */
+ ring_ep_doorbell(xhci, slot_id, ep_index);
+ }
++ ep->stopped_td = NULL;
++ ep->stopped_trb = NULL;
+
+ /*
+ * Drop the lock and complete the URBs in the cancelled TD list.
+@@ -1061,8 +1063,13 @@ static void xhci_cleanup_halted_endpoint
+ ep->ep_state |= EP_HALTED;
+ ep->stopped_td = td;
+ ep->stopped_trb = event_trb;
++
+ xhci_queue_reset_ep(xhci, slot_id, ep_index);
+ xhci_cleanup_stalled_ring(xhci, td->urb->dev, ep_index);
++
++ ep->stopped_td = NULL;
++ ep->stopped_trb = NULL;
++
+ xhci_ring_cmd_db(xhci);
+ }
+
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -1438,6 +1438,8 @@ void xhci_endpoint_reset(struct usb_hcd
+ kfree(virt_ep->stopped_td);
+ xhci_ring_cmd_db(xhci);
+ }
++ virt_ep->stopped_td = NULL;
++ virt_ep->stopped_trb = NULL;
+ spin_unlock_irqrestore(&xhci->lock, flags);
+
+ if (ret)
--- /dev/null
+From 54b5acf3acb7a1f83ec281d111d3e2812cd7ad9d Mon Sep 17 00:00:00 2001
+From: Andiry Xu <andiry.xu@amd.com>
+Date: Mon, 10 May 2010 19:57:17 -0700
+Subject: USB: xHCI: Fix wrong usage of macro TRB_TYPE
+
+From: Andiry Xu <andiry.xu@amd.com>
+
+commit 54b5acf3acb7a1f83ec281d111d3e2812cd7ad9d upstream.
+
+Macro TRB_TYPE is misused in some places. Fix the wrong usage.
+
+
+Signed-off-by: Andiry Xu <andiry.xu@amd.com>
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-ring.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -351,7 +351,8 @@ static struct xhci_segment *find_trb_seg
+ while (cur_seg->trbs > trb ||
+ &cur_seg->trbs[TRBS_PER_SEGMENT - 1] < trb) {
+ generic_trb = &cur_seg->trbs[TRBS_PER_SEGMENT - 1].generic;
+- if (TRB_TYPE(generic_trb->field[3]) == TRB_LINK &&
++ if ((generic_trb->field[3] & TRB_TYPE_BITMASK) ==
++ TRB_TYPE(TRB_LINK) &&
+ (generic_trb->field[3] & LINK_TOGGLE))
+ *cycle_state = ~(*cycle_state) & 0x1;
+ cur_seg = cur_seg->next;
+@@ -407,7 +408,7 @@ void xhci_find_new_dequeue_state(struct
+ BUG();
+
+ trb = &state->new_deq_ptr->generic;
+- if (TRB_TYPE(trb->field[3]) == TRB_LINK &&
++ if ((trb->field[3] & TRB_TYPE_BITMASK) == TRB_TYPE(TRB_LINK) &&
+ (trb->field[3] & LINK_TOGGLE))
+ state->new_cycle_state = ~(state->new_cycle_state) & 0x1;
+ next_trb(xhci, ep_ring, &state->new_deq_seg, &state->new_deq_ptr);
+@@ -1414,8 +1415,10 @@ static int handle_tx_event(struct xhci_h
+ for (cur_trb = ep_ring->dequeue, cur_seg = ep_ring->deq_seg;
+ cur_trb != event_trb;
+ next_trb(xhci, ep_ring, &cur_seg, &cur_trb)) {
+- if (TRB_TYPE(cur_trb->generic.field[3]) != TRB_TR_NOOP &&
+- TRB_TYPE(cur_trb->generic.field[3]) != TRB_LINK)
++ if ((cur_trb->generic.field[3] &
++ TRB_TYPE_BITMASK) != TRB_TYPE(TRB_TR_NOOP) &&
++ (cur_trb->generic.field[3] &
++ TRB_TYPE_BITMASK) != TRB_TYPE(TRB_LINK))
+ td->urb->actual_length +=
+ TRB_LEN(cur_trb->generic.field[2]);
+ }
--- /dev/null
+From bc88d2eba5e19d10dd546e428314909d889b3b6a Mon Sep 17 00:00:00 2001
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Date: Tue, 18 May 2010 16:05:21 -0700
+Subject: USB: xhci: Limit bus sg_tablesize to 62 TRBs.
+
+From: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+
+commit bc88d2eba5e19d10dd546e428314909d889b3b6a upstream.
+
+When a scatter-gather list is enqueued to the xHCI driver, it translates
+each entry into a transfer request block (TRB). Only 63 TRBs can be
+used per ring segment, and there must be one additional TRB reserved to
+make sure the hardware does not think the ring is empty (so the enqueue
+pointer doesn't equal the dequeue pointer). Limit the bus sg_tablesize
+to 62 TRBs.
+
+Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/xhci-pci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -54,7 +54,7 @@ static int xhci_pci_setup(struct usb_hcd
+ struct pci_dev *pdev = to_pci_dev(hcd->self.controller);
+ int retval;
+
+- hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 1;
++ hcd->self.sg_tablesize = TRBS_PER_SEGMENT - 2;
+
+ xhci->cap_regs = hcd->regs;
+ xhci->op_regs = hcd->regs +