aboutsummaryrefslogtreecommitdiffstats
path: root/usb
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2009-04-21 16:21:22 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2009-04-21 16:21:22 -0700
commit2fe52c5cf2dc0865e1c9e9d832c10ccd3aa44538 (patch)
treedfa6686ba19843ceee484b4bf206098c8531f6e4 /usb
parentafe10e41302767d5a803ebab04792df02920214a (diff)
downloadpatches-2fe52c5cf2dc0865e1c9e9d832c10ccd3aa44538.tar.gz
more patches
Diffstat (limited to 'usb')
-rw-r--r--usb/usb-gadget-mips-ci13xxx-udc-bugfixes.patch43
-rw-r--r--usb/usb-musb-fix-build-when-config_pm.patch30
-rw-r--r--usb/usb-musb-remove-my-email-address-from-few-musb-related-drivers.patch51
-rw-r--r--usb/usb-serial-fix-lifetime-and-locking-problems.patch263
-rw-r--r--usb/usb-serial-ftdi-add-high-speed-device-support.patch238
-rw-r--r--usb/usb-unusual-device-support-for-gold-mp3-player-energy.patch49
6 files changed, 674 insertions, 0 deletions
diff --git a/usb/usb-gadget-mips-ci13xxx-udc-bugfixes.patch b/usb/usb-gadget-mips-ci13xxx-udc-bugfixes.patch
new file mode 100644
index 00000000000000..9735e1c2fc60a7
--- /dev/null
+++ b/usb/usb-gadget-mips-ci13xxx-udc-bugfixes.patch
@@ -0,0 +1,43 @@
+From david-b@pacbell.net Tue Apr 21 16:12:32 2009
+From: David Lopo <dlopo@chipidea.mips.com>
+Date: Thu, 16 Apr 2009 14:35:24 -0700
+Subject: USB: Gadget: MIPS CI13xxx UDC bugfixes
+To: dlopo@chipidea.mips.com
+Cc: linux-usb@vger.kernel.org
+Message-ID: <200904161435.24617.david-b@pacbell.net>
+Content-Disposition: inline
+
+
+From: David Lopo <dlopo@chipidea.mips.com>
+
+Bug Fix: high speed detection in LPM mode
+Bug Fix: max packet size configuration when switching between HS and FS
+
+Signed-off-by: David Lopo <dlopo@chipidea.mips.com>
+Acked-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/ci13xxx_udc.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/ci13xxx_udc.c
++++ b/drivers/usb/gadget/ci13xxx_udc.c
+@@ -142,7 +142,7 @@ static struct {
+ #define CAP_DEVICEADDR (0x014UL)
+ #define CAP_ENDPTLISTADDR (0x018UL)
+ #define CAP_PORTSC (0x044UL)
+-#define CAP_DEVLC (0x0B4UL)
++#define CAP_DEVLC (0x084UL)
+ #define CAP_USBMODE (hw_bank.lpm ? 0x0C8UL : 0x068UL)
+ #define CAP_ENDPTSETUPSTAT (hw_bank.lpm ? 0x0D8UL : 0x06CUL)
+ #define CAP_ENDPTPRIME (hw_bank.lpm ? 0x0DCUL : 0x070UL)
+@@ -1986,6 +1986,8 @@ static int ep_enable(struct usb_ep *ep,
+ do {
+ dbg_event(_usb_addr(mEp), "ENABLE", 0);
+
++ mEp->qh[mEp->dir].ptr->cap = 0;
++
+ if (mEp->type == USB_ENDPOINT_XFER_CONTROL)
+ mEp->qh[mEp->dir].ptr->cap |= QH_IOS;
+ else if (mEp->type == USB_ENDPOINT_XFER_ISOC)
diff --git a/usb/usb-musb-fix-build-when-config_pm.patch b/usb/usb-musb-fix-build-when-config_pm.patch
new file mode 100644
index 00000000000000..d3814c206426a7
--- /dev/null
+++ b/usb/usb-musb-fix-build-when-config_pm.patch
@@ -0,0 +1,30 @@
+From a.beregalov@gmail.com Tue Apr 21 16:13:43 2009
+From: Alexander Beregalov <a.beregalov@gmail.com>
+Date: Fri, 17 Apr 2009 15:19:14 +0400
+Subject: USB: musb: fix build when !CONFIG_PM
+To: gregkh@suse.de
+Message-ID: <20090417111914.GA31310@orion>
+Content-Disposition: inline
+
+
+Fix this build error when CONFIG_PM is not set:
+drivers/usb/musb/musb_core.c:2232: error: 'musb_resume_early' undeclared here
+
+Signed-off-by: Alexander Beregalov <a.beregalov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/musb_core.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -2217,7 +2217,7 @@ static int musb_resume_early(struct plat
+
+ #else
+ #define musb_suspend NULL
+-#define musb_resume NULL
++#define musb_resume_early NULL
+ #endif
+
+ static struct platform_driver musb_driver = {
diff --git a/usb/usb-musb-remove-my-email-address-from-few-musb-related-drivers.patch b/usb/usb-musb-remove-my-email-address-from-few-musb-related-drivers.patch
new file mode 100644
index 00000000000000..f5cf67e4acd78d
--- /dev/null
+++ b/usb/usb-musb-remove-my-email-address-from-few-musb-related-drivers.patch
@@ -0,0 +1,51 @@
+From jarkko.nikula@nokia.com Tue Apr 21 16:13:19 2009
+From: Jarkko Nikula <jarkko.nikula@nokia.com>
+Date: Fri, 17 Apr 2009 13:52:00 +0300
+Subject: USB: musb: Remove my email address from few musb related drivers
+Cc: Jarkko Nikula <jarkko.nikula@nokia.com>, Felipe Balbi <felipe.balbi@nokia.com>
+Message-ID: <1239965520-23749-1-git-send-email-jarkko.nikula@nokia.com>
+
+
+This email address is going to expire soon and my contribution to musb
+is next to zero so remove it.
+
+Signed-off-by: Jarkko Nikula <jarkko.nikula@nokia.com>
+Cc: Felipe Balbi <felipe.balbi@nokia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/musb/omap2430.c | 1 -
+ drivers/usb/musb/tusb6010.c | 1 -
+ drivers/usb/musb/tusb6010.h | 1 -
+ 3 files changed, 3 deletions(-)
+
+--- a/drivers/usb/musb/omap2430.c
++++ b/drivers/usb/musb/omap2430.c
+@@ -3,7 +3,6 @@
+ * Some code has been taken from tusb6010.c
+ * Copyrights for that are attributable to:
+ * Copyright (C) 2006 Nokia Corporation
+- * Jarkko Nikula <jarkko.nikula@nokia.com>
+ * Tony Lindgren <tony@atomide.com>
+ *
+ * This file is part of the Inventra Controller Driver for Linux.
+--- a/drivers/usb/musb/tusb6010.c
++++ b/drivers/usb/musb/tusb6010.c
+@@ -2,7 +2,6 @@
+ * TUSB6010 USB 2.0 OTG Dual Role controller
+ *
+ * Copyright (C) 2006 Nokia Corporation
+- * Jarkko Nikula <jarkko.nikula@nokia.com>
+ * Tony Lindgren <tony@atomide.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+--- a/drivers/usb/musb/tusb6010.h
++++ b/drivers/usb/musb/tusb6010.h
+@@ -2,7 +2,6 @@
+ * Definitions for TUSB6010 USB 2.0 OTG Dual Role controller
+ *
+ * Copyright (C) 2006 Nokia Corporation
+- * Jarkko Nikula <jarkko.nikula@nokia.com>
+ * Tony Lindgren <tony@atomide.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
diff --git a/usb/usb-serial-fix-lifetime-and-locking-problems.patch b/usb/usb-serial-fix-lifetime-and-locking-problems.patch
new file mode 100644
index 00000000000000..a29dfeac0d82eb
--- /dev/null
+++ b/usb/usb-serial-fix-lifetime-and-locking-problems.patch
@@ -0,0 +1,263 @@
+From stern@rowland.harvard.edu Tue Apr 21 15:50:59 2009
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Tue, 14 Apr 2009 11:31:02 -0400 (EDT)
+Subject: USB: serial: fix lifetime and locking problems
+To: Greg KH <greg@kroah.com>
+Cc: Dan Williams <dcbw@redhat.com>
+Message-ID: <Pine.LNX.4.44L0.0904141125470.3576-100000@iolanthe.rowland.org>
+
+
+This patch (as1229) fixes a few lifetime and locking problems in the
+usb-serial driver. The main symptom is that an invalid kevent is
+created when the serial device is unplugged while a connection is
+active.
+
+ Ports should be unregistered when device is disconnected,
+ not when the parent usb_serial structure is deallocated.
+
+ Each open file should hold a reference to the corresponding
+ port structure, and the reference should be released when
+ the file is closed.
+
+ serial->disc_mutex should be acquired in serial_open(), to
+ resolve the classic race between open and disconnect.
+
+ serial_close() doesn't need to hold both serial->disc_mutex
+ and port->mutex at the same time.
+
+ Release the subdriver's module reference only after releasing
+ all the other references, in case one of the release routines
+ needs to invoke some code in the subdriver module.
+
+ Replace a call to flush_scheduled_work() (which is prone to
+ deadlocks) with cancel_work_sync(). Also, add a call to
+ cancel_work_sync() in the disconnect routine.
+
+ Reduce the scope of serial->disc_mutex in serial_disconnect().
+ The only place it really needs to protect is where the
+ "disconnected" flag is set.
+
+This fixes the bug reported in
+
+ http://bugs.freedesktop.org/show_bug.cgi?id=20703
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Tested-by: Dan Williams <dcbw@redhat.com>
+Reviewed-by: Oliver Neukum <oliver@neukum.org>
+Acked-by: Alan Cox <alan@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/serial/usb-serial.c | 90 ++++++++++++++++++++++++----------------
+ 1 file changed, 56 insertions(+), 34 deletions(-)
+
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -143,16 +143,6 @@ static void destroy_serial(struct kref *
+ if (serial->minor != SERIAL_TTY_NO_MINOR)
+ return_serial(serial);
+
+- for (i = 0; i < serial->num_ports; ++i)
+- serial->port[i]->port.count = 0;
+-
+- /* the ports are cleaned up and released in port_release() */
+- for (i = 0; i < serial->num_ports; ++i)
+- if (serial->port[i]->dev.parent != NULL) {
+- device_unregister(&serial->port[i]->dev);
+- serial->port[i] = NULL;
+- }
+-
+ /* If this is a "fake" port, we have to clean it up here, as it will
+ * not get cleaned up in port_release() as it was never registered with
+ * the driver core */
+@@ -187,7 +177,7 @@ static int serial_open (struct tty_struc
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
+ unsigned int portNumber;
+- int retval;
++ int retval = 0;
+
+ dbg("%s", __func__);
+
+@@ -198,21 +188,24 @@ static int serial_open (struct tty_struc
+ return -ENODEV;
+ }
+
++ mutex_lock(&serial->disc_mutex);
+ portNumber = tty->index - serial->minor;
+ port = serial->port[portNumber];
+- if (!port) {
+- retval = -ENODEV;
+- goto bailout_kref_put;
+- }
+-
+- if (port->serial->disconnected) {
++ if (!port || serial->disconnected)
+ retval = -ENODEV;
+- goto bailout_kref_put;
+- }
++ else
++ get_device(&port->dev);
++ /*
++ * Note: Our locking order requirement does not allow port->mutex
++ * to be acquired while serial->disc_mutex is held.
++ */
++ mutex_unlock(&serial->disc_mutex);
++ if (retval)
++ goto bailout_serial_put;
+
+ if (mutex_lock_interruptible(&port->mutex)) {
+ retval = -ERESTARTSYS;
+- goto bailout_kref_put;
++ goto bailout_port_put;
+ }
+
+ ++port->port.count;
+@@ -232,14 +225,20 @@ static int serial_open (struct tty_struc
+ goto bailout_mutex_unlock;
+ }
+
+- retval = usb_autopm_get_interface(serial->interface);
++ mutex_lock(&serial->disc_mutex);
++ if (serial->disconnected)
++ retval = -ENODEV;
++ else
++ retval = usb_autopm_get_interface(serial->interface);
+ if (retval)
+ goto bailout_module_put;
++
+ /* only call the device specific open if this
+ * is the first time the port is opened */
+ retval = serial->type->open(tty, port, filp);
+ if (retval)
+ goto bailout_interface_put;
++ mutex_unlock(&serial->disc_mutex);
+ }
+
+ mutex_unlock(&port->mutex);
+@@ -248,13 +247,16 @@ static int serial_open (struct tty_struc
+ bailout_interface_put:
+ usb_autopm_put_interface(serial->interface);
+ bailout_module_put:
++ mutex_unlock(&serial->disc_mutex);
+ module_put(serial->type->driver.owner);
+ bailout_mutex_unlock:
+ port->port.count = 0;
+ tty->driver_data = NULL;
+ tty_port_tty_set(&port->port, NULL);
+ mutex_unlock(&port->mutex);
+-bailout_kref_put:
++bailout_port_put:
++ put_device(&port->dev);
++bailout_serial_put:
+ usb_serial_put(serial);
+ return retval;
+ }
+@@ -262,6 +264,9 @@ bailout_kref_put:
+ static void serial_close(struct tty_struct *tty, struct file *filp)
+ {
+ struct usb_serial_port *port = tty->driver_data;
++ struct usb_serial *serial;
++ struct module *owner;
++ int count;
+
+ if (!port)
+ return;
+@@ -269,6 +274,8 @@ static void serial_close(struct tty_stru
+ dbg("%s - port %d", __func__, port->number);
+
+ mutex_lock(&port->mutex);
++ serial = port->serial;
++ owner = serial->type->driver.owner;
+
+ if (port->port.count == 0) {
+ mutex_unlock(&port->mutex);
+@@ -281,7 +288,7 @@ static void serial_close(struct tty_stru
+ * this before we drop the port count. The call is protected
+ * by the port mutex
+ */
+- port->serial->type->close(tty, port, filp);
++ serial->type->close(tty, port, filp);
+
+ if (port->port.count == (port->console ? 2 : 1)) {
+ struct tty_struct *tty = tty_port_tty_get(&port->port);
+@@ -295,17 +302,23 @@ static void serial_close(struct tty_stru
+ }
+ }
+
+- if (port->port.count == 1) {
+- mutex_lock(&port->serial->disc_mutex);
+- if (!port->serial->disconnected)
+- usb_autopm_put_interface(port->serial->interface);
+- mutex_unlock(&port->serial->disc_mutex);
+- module_put(port->serial->type->driver.owner);
+- }
+ --port->port.count;
+-
++ count = port->port.count;
+ mutex_unlock(&port->mutex);
+- usb_serial_put(port->serial);
++ put_device(&port->dev);
++
++ /* Mustn't dereference port any more */
++ if (count == 0) {
++ mutex_lock(&serial->disc_mutex);
++ if (!serial->disconnected)
++ usb_autopm_put_interface(serial->interface);
++ mutex_unlock(&serial->disc_mutex);
++ }
++ usb_serial_put(serial);
++
++ /* Mustn't dereference serial any more */
++ if (count == 0)
++ module_put(owner);
+ }
+
+ static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+@@ -549,7 +562,13 @@ static void kill_traffic(struct usb_seri
+
+ static void port_free(struct usb_serial_port *port)
+ {
++ /*
++ * Stop all the traffic before cancelling the work, so that
++ * nobody will restart it by calling usb_serial_port_softint.
++ */
+ kill_traffic(port);
++ cancel_work_sync(&port->work);
++
+ usb_free_urb(port->read_urb);
+ usb_free_urb(port->write_urb);
+ usb_free_urb(port->interrupt_in_urb);
+@@ -558,7 +577,6 @@ static void port_free(struct usb_serial_
+ kfree(port->bulk_out_buffer);
+ kfree(port->interrupt_in_buffer);
+ kfree(port->interrupt_out_buffer);
+- flush_scheduled_work(); /* port->work */
+ kfree(port);
+ }
+
+@@ -1043,6 +1061,8 @@ void usb_serial_disconnect(struct usb_in
+ usb_set_intfdata(interface, NULL);
+ /* must set a flag, to signal subdrivers */
+ serial->disconnected = 1;
++ mutex_unlock(&serial->disc_mutex);
++
+ for (i = 0; i < serial->num_ports; ++i) {
+ port = serial->port[i];
+ if (port) {
+@@ -1052,11 +1072,13 @@ void usb_serial_disconnect(struct usb_in
+ tty_kref_put(tty);
+ }
+ kill_traffic(port);
++ cancel_work_sync(&port->work);
++ device_unregister(&port->dev);
++ serial->port[i] = NULL;
+ }
+ }
+ /* let the last holder of this object
+ * cause it to be cleaned up */
+- mutex_unlock(&serial->disc_mutex);
+ usb_serial_put(serial);
+ dev_info(dev, "device disconnected\n");
+ }
diff --git a/usb/usb-serial-ftdi-add-high-speed-device-support.patch b/usb/usb-serial-ftdi-add-high-speed-device-support.patch
new file mode 100644
index 00000000000000..971f8a5bfa144d
--- /dev/null
+++ b/usb/usb-serial-ftdi-add-high-speed-device-support.patch
@@ -0,0 +1,238 @@
+From mark.adamson@ftdichip.com Tue Apr 21 15:41:34 2009
+From: Mark Adamson <mark.adamson@ftdichip.com>
+Date: Thu, 9 Apr 2009 15:03:09 +0100
+Subject: USB: serial: FTDI: add high speed device support
+To: Greg KH <greg@kroah.com>
+Cc: Gordon Lunn <gordon.lunn@ftdichip.com>
+Message-ID: <8D2B66FD8A5723429FEFCD40CC13CDD1F9422D050D@GLAEXSV2.ftdi.local>
+
+
+Added support for FTDI's USB 2.0 hi-speed devices - FT2232H (2
+interfaces) and FT4232H (4 interfaces), including a new baud rate
+calculation for these devices which can now achieve up to 12Mbaud by
+turning off a divide by 2.5 in the baud rate generator of the chips. In
+order to achieve baud rates of <1200 baud, the divide by 2.5 must be
+active. The default product ID of the FT2232H is 0x6010 (same as the
+FT2232C IC). The default PID of the FT4232H is 0x6011.
+
+
+Signed-off-by: Mark J. Adamson <mark.adamson@ftdichip.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/serial/ftdi_sio.c | 90 +++++++++++++++++++++++++++++++++++++-----
+ drivers/usb/serial/ftdi_sio.h | 10 ++++
+ 2 files changed, 89 insertions(+), 11 deletions(-)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -47,7 +47,7 @@
+ /*
+ * Version Information
+ */
+-#define DRIVER_VERSION "v1.4.3"
++#define DRIVER_VERSION "v1.5.0"
+ #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>"
+ #define DRIVER_DESC "USB FTDI Serial Converters Driver"
+
+@@ -81,7 +81,8 @@ struct ftdi_private {
+ int rx_processed;
+ unsigned long rx_bytes;
+
+- __u16 interface; /* FT2232C port interface (0 for FT232/245) */
++ __u16 interface; /* FT2232C, FT2232H or FT4232H port interface
++ (0 for FT232/245) */
+
+ speed_t force_baud; /* if non-zero, force the baud rate to
+ this value */
+@@ -162,6 +163,7 @@ static struct usb_device_id id_table_com
+ { USB_DEVICE(FTDI_VID, FTDI_8U232AM_ALT_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_232RL_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_4232H_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MICRO_CHAMELEON_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_OPENDCC_PID) },
+@@ -689,6 +691,8 @@ static const char *ftdi_chip_name[] = {
+ [FT232BM] = "FT232BM",
+ [FT2232C] = "FT2232C",
+ [FT232RL] = "FT232RL",
++ [FT2232H] = "FT2232H",
++ [FT4232H] = "FT4232H"
+ };
+
+
+@@ -740,6 +744,8 @@ static unsigned short int ftdi_232am_bau
+ static unsigned short int ftdi_232am_baud_to_divisor(int baud);
+ static __u32 ftdi_232bm_baud_base_to_divisor(int baud, int base);
+ static __u32 ftdi_232bm_baud_to_divisor(int baud);
++static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base);
++static __u32 ftdi_2232h_baud_to_divisor(int baud);
+
+ static struct usb_serial_driver ftdi_sio_device = {
+ .driver = {
+@@ -833,6 +839,36 @@ static __u32 ftdi_232bm_baud_to_divisor(
+ return ftdi_232bm_baud_base_to_divisor(baud, 48000000);
+ }
+
++static __u32 ftdi_2232h_baud_base_to_divisor(int baud, int base)
++{
++ static const unsigned char divfrac[8] = { 0, 3, 2, 4, 1, 5, 6, 7 };
++ __u32 divisor;
++ int divisor3;
++
++ /* hi-speed baud rate is 10-bit sampling instead of 16-bit */
++ divisor3 = (base / 10 / baud) * 8;
++
++ divisor = divisor3 >> 3;
++ divisor |= (__u32)divfrac[divisor3 & 0x7] << 14;
++ /* Deal with special cases for highest baud rates. */
++ if (divisor == 1)
++ divisor = 0;
++ else if (divisor == 0x4001)
++ divisor = 1;
++ /*
++ * Set this bit to turn off a divide by 2.5 on baud rate generator
++ * This enables baud rates up to 12Mbaud but cannot reach below 1200
++ * baud with this bit set
++ */
++ divisor |= 0x00020000;
++ return divisor;
++}
++
++static __u32 ftdi_2232h_baud_to_divisor(int baud)
++{
++ return ftdi_2232h_baud_base_to_divisor(baud, 120000000);
++}
++
+ #define set_mctrl(port, set) update_mctrl((port), (set), 0)
+ #define clear_mctrl(port, clear) update_mctrl((port), 0, (clear))
+
+@@ -991,6 +1027,19 @@ static __u32 get_ftdi_divisor(struct tty
+ baud = 9600;
+ }
+ break;
++ case FT2232H: /* FT2232H chip */
++ case FT4232H: /* FT4232H chip */
++ if ((baud <= 12000000) & (baud >= 1200)) {
++ div_value = ftdi_2232h_baud_to_divisor(baud);
++ } else if (baud < 1200) {
++ div_value = ftdi_232bm_baud_to_divisor(baud);
++ } else {
++ dbg("%s - Baud rate too high!", __func__);
++ div_value = ftdi_232bm_baud_to_divisor(9600);
++ div_okay = 0;
++ baud = 9600;
++ }
++ break;
+ } /* priv->chip_type */
+
+ if (div_okay) {
+@@ -1143,14 +1192,29 @@ static void ftdi_determine_type(struct u
+ if (interfaces > 1) {
+ int inter;
+
+- /* Multiple interfaces. Assume FT2232C. */
+- priv->chip_type = FT2232C;
++ /* Multiple interfaces.*/
++ if (version == 0x0800) {
++ priv->chip_type = FT4232H;
++ /* Hi-speed - baud clock runs at 120MHz */
++ priv->baud_base = 120000000 / 2;
++ } else if (version == 0x0700) {
++ priv->chip_type = FT2232H;
++ /* Hi-speed - baud clock runs at 120MHz */
++ priv->baud_base = 120000000 / 2;
++ } else
++ priv->chip_type = FT2232C;
++
+ /* Determine interface code. */
+ inter = serial->interface->altsetting->desc.bInterfaceNumber;
+- if (inter == 0)
+- priv->interface = PIT_SIOA;
+- else
+- priv->interface = PIT_SIOB;
++ if (inter == 0) {
++ priv->interface = INTERFACE_A;
++ } else if (inter == 1) {
++ priv->interface = INTERFACE_B;
++ } else if (inter == 2) {
++ priv->interface = INTERFACE_C;
++ } else if (inter == 3) {
++ priv->interface = INTERFACE_D;
++ }
+ /* BM-type devices have a bug where bcdDevice gets set
+ * to 0x200 when iSerialNumber is 0. */
+ if (version < 0x500) {
+@@ -1287,7 +1351,9 @@ static int create_sysfs_attrs(struct usb
+ if ((!retval) &&
+ (priv->chip_type == FT232BM ||
+ priv->chip_type == FT2232C ||
+- priv->chip_type == FT232RL)) {
++ priv->chip_type == FT232RL ||
++ priv->chip_type == FT2232H ||
++ priv->chip_type == FT4232H)) {
+ retval = device_create_file(&port->dev,
+ &dev_attr_latency_timer);
+ }
+@@ -1306,7 +1372,9 @@ static void remove_sysfs_attrs(struct us
+ device_remove_file(&port->dev, &dev_attr_event_char);
+ if (priv->chip_type == FT232BM ||
+ priv->chip_type == FT2232C ||
+- priv->chip_type == FT232RL) {
++ priv->chip_type == FT232RL ||
++ priv->chip_type == FT2232H ||
++ priv->chip_type == FT4232H) {
+ device_remove_file(&port->dev, &dev_attr_latency_timer);
+ }
+ }
+@@ -2300,6 +2368,8 @@ static int ftdi_tiocmget(struct tty_stru
+ case FT232BM:
+ case FT2232C:
+ case FT232RL:
++ case FT2232H:
++ case FT4232H:
+ /* the 8U232AM returns a two byte value (the sio is a 1 byte
+ value) - in the same format as the data returned from the in
+ point */
+--- a/drivers/usb/serial/ftdi_sio.h
++++ b/drivers/usb/serial/ftdi_sio.h
+@@ -10,7 +10,7 @@
+ * The device is based on the FTDI FT8U100AX chip. It has a DB25 on one side,
+ * USB on the other.
+ *
+- * Thanx to FTDI (http://www.ftdi.co.uk) for so kindly providing details
++ * Thanx to FTDI (http://www.ftdichip.com) for so kindly providing details
+ * of the protocol required to talk to the device and ongoing assistence
+ * during development.
+ *
+@@ -28,6 +28,7 @@
+ #define FTDI_8U232AM_ALT_PID 0x6006 /* FTDI's alternate PID for above */
+ #define FTDI_8U2232C_PID 0x6010 /* Dual channel device */
+ #define FTDI_232RL_PID 0xFBFA /* Product ID for FT232RL */
++#define FTDI_4232H_PID 0x6011 /* Quad channel hi-speed device */
+ #define FTDI_RELAIS_PID 0xFA10 /* Relais device from Rudolf Gugler */
+ #define FTDI_NF_RIC_VID 0x0DCD /* Vendor Id */
+ #define FTDI_NF_RIC_PID 0x0001 /* Product Id */
+@@ -873,6 +874,11 @@
+ #define FTDI_SIO_SET_LATENCY_TIMER 9 /* Set the latency timer */
+ #define FTDI_SIO_GET_LATENCY_TIMER 10 /* Get the latency timer */
+
++/* Interface indicies for FT2232, FT2232H and FT4232H devices*/
++#define INTERFACE_A 1
++#define INTERFACE_B 2
++#define INTERFACE_C 3
++#define INTERFACE_D 4
+
+ /*
+ * FIC / OpenMoko, Inc. http://wiki.openmoko.org/wiki/Neo1973_Debug_Board_v3
+@@ -1030,6 +1036,8 @@ typedef enum {
+ FT232BM = 3,
+ FT2232C = 4,
+ FT232RL = 5,
++ FT2232H = 6,
++ FT4232H = 7
+ } ftdi_chip_type_t;
+
+ typedef enum {
diff --git a/usb/usb-unusual-device-support-for-gold-mp3-player-energy.patch b/usb/usb-unusual-device-support-for-gold-mp3-player-energy.patch
new file mode 100644
index 00000000000000..4a058d1470fe07
--- /dev/null
+++ b/usb/usb-unusual-device-support-for-gold-mp3-player-energy.patch
@@ -0,0 +1,49 @@
+From stefan.bader@canonical.com Tue Apr 21 15:52:31 2009
+From: Chuck Short <zulcss@ubuntu.com>
+Date: Tue, 14 Apr 2009 20:50:31 +0200
+Subject: USB: Unusual Device support for Gold MP3 Player Energy
+To: USB Storage List <usb-storage@lists.one-eyed-alien.net>
+Cc: gregkh@novell.com
+Message-ID: <49E4DAF7.6070007@canonical.com>
+
+
+From: Chuck Short <zulcss@ubuntu.com>
+
+Reported by Alessio Treglia on
+https://bugs.launchpad.net/ubuntu/+source/linux/+bug/125250
+
+User was getting the following errors in dmesg:
+
+[ 2158.139386] sd 5:0:0:1: ioctl_internal_command return code = 8000002
+[ 2158.139390] : Current: sense key: No Sense
+[ 2158.139393] Additional sense: No additional sense information
+
+Adds unusual device support.
+
+modified: drivers/usb/storage/unusual_devs.h
+
+Signed-off-by: Chuck Short <zulcss@ubuntu.com>
+Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
+Signed-off-by: Stefan Bader <stefan.bader@canonical.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/storage/unusual_devs.h | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1851,6 +1851,12 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_CAPACITY_HEURISTICS),
+
++/* Reported by Alessio Treglia <quadrispro@ubuntu.com> */
++UNUSUAL_DEV( 0xed10, 0x7636, 0x0001, 0x0001,
++ "TGE",
++ "Digital MP3 Audio Player",
++ US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ),
++
+ /* Control/Bulk transport for all SubClass values */
+ USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
+ USUAL_DEV(US_SC_8020, US_PR_CB, USB_US_TYPE_STOR),