aboutsummaryrefslogtreecommitdiffstats
path: root/usb.current
diff options
authorGreg Kroah-Hartman <gregkh@suse.de>2008-08-06 17:04:07 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2008-08-06 17:04:07 -0700
commit3e82bf52d32c3ce70099ef520b7eaa4ba7a1f89b (patch)
tree1a6d033bf39960e98ab6f1789bbd366563d3fc7c /usb.current
parent0f3e1982ff77f54a59c9a3e1e99a3b11001c8c70 (diff)
downloadpatches-3e82bf52d32c3ce70099ef520b7eaa4ba7a1f89b.tar.gz
usb patches added
Diffstat (limited to 'usb.current')
-rw-r--r--usb.current/usb-bandrich-bandluxe-c150-c250-hspa-data-card-driver.patch72
-rw-r--r--usb.current/usb-cdc-acm.c-fix-compile-warnings.patch34
-rw-r--r--usb.current/usb-ftdi_sio-add-support-for-phi-fisco-data-cable.patch42
-rw-r--r--usb.current/usb-hook-start_hnp-into-ohci-struct.patch60
-rw-r--r--usb.current/usb-isp1760-don-t-be-noisy-about-short-packets.patch54
-rw-r--r--usb.current/usb-isp1760-improve-pre-fetch-timing.patch143
-rw-r--r--usb.current/usb-ohci-make-distrust_firmware-a-quirk.patch65
-rw-r--r--usb.current/usb-omap_udc-fix-compilation-with-debug-enabled.patch37
-rw-r--r--usb.current/usb-quirk-pll-power-down-mode.patch260
-rw-r--r--usb.current/usb-return-error-code-instead-of-0-in-the-enqueue-function.patch32
-rw-r--r--usb.current/usb-serial-gadget-rx-path-data-loss-fixes.patch391
-rw-r--r--usb.current/usb-update-to-documentation.patch35
12 files changed, 1225 insertions, 0 deletions
diff --git a/usb.current/usb-bandrich-bandluxe-c150-c250-hspa-data-card-driver.patch b/usb.current/usb-bandrich-bandluxe-c150-c250-hspa-data-card-driver.patch
new file mode 100644
index 00000000000000..1b4d9c3508b718
--- /dev/null
+++ b/usb.current/usb-bandrich-bandluxe-c150-c250-hspa-data-card-driver.patch
@@ -0,0 +1,72 @@
+From upleong@bandrich.com Wed Aug 6 16:53:26 2008
+From: Leon Leong <upleong@bandrich.com>
+Date: Fri, 1 Aug 2008 11:40:12 +0800
+Subject: USB: BandRich BandLuxe C150/C250 HSPA Data Card Driver
+To: smurf@smurf.noris.de
+Cc: linux-kernel@vger.kernel.org, linux-usb@vger.kernel.org
+Message-ID: <5ECB2A60-5E13-4DE1-86A1-6FA12DBCEF66@bandrich.com>
+
+
+From: Leon Leong <upleong@bandrich.com>
+
+This patch adds the Product ID for the BandLuxe C150/C250 3.5G data
+card series from BandRich Inc.
+After detection, the data card works fine.
+
+It was patched against kernel 2.6.27-rc1 with -mm patch
+
+Signed-off-by: Leon Leong <upleong@bandrich.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/option.c | 32 ++++++++++++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -186,6 +186,23 @@ static int option_send_setup(struct tty
+ #define BANDRICH_VENDOR_ID 0x1A8D
+ #define BANDRICH_PRODUCT_C100_1 0x1002
+ #define BANDRICH_PRODUCT_C100_2 0x1003
++#define BANDRICH_PRODUCT_1004 0x1004
++#define BANDRICH_PRODUCT_1005 0x1005
++#define BANDRICH_PRODUCT_1006 0x1006
++#define BANDRICH_PRODUCT_1007 0x1007
++#define BANDRICH_PRODUCT_1008 0x1008
++#define BANDRICH_PRODUCT_1009 0x1009
++#define BANDRICH_PRODUCT_100A 0x100a
++
++#define BANDRICH_PRODUCT_100B 0x100b
++#define BANDRICH_PRODUCT_100C 0x100c
++#define BANDRICH_PRODUCT_100D 0x100d
++#define BANDRICH_PRODUCT_100E 0x100e
++
++#define BANDRICH_PRODUCT_100F 0x100f
++#define BANDRICH_PRODUCT_1010 0x1010
++#define BANDRICH_PRODUCT_1011 0x1011
++#define BANDRICH_PRODUCT_1012 0x1012
+
+ #define AMOI_VENDOR_ID 0x1614
+ #define AMOI_PRODUCT_9508 0x0800
+@@ -302,6 +319,21 @@ static struct usb_device_id option_ids[]
+ { USB_DEVICE(ONDA_VENDOR_ID, ONDA_PRODUCT_ET502HS) },
+ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
+ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1004) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1005) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1006) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1007) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1008) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1009) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100A) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100B) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100C) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100D) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100E) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_100F) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1010) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1011) },
++ { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_1012) },
+ { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC650) },
+ { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
+ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6000)}, /* ZTE AC8700 */
diff --git a/usb.current/usb-cdc-acm.c-fix-compile-warnings.patch b/usb.current/usb-cdc-acm.c-fix-compile-warnings.patch
new file mode 100644
index 00000000000000..33acdffb284b2c
--- /dev/null
+++ b/usb.current/usb-cdc-acm.c-fix-compile-warnings.patch
@@ -0,0 +1,34 @@
+From tiwai@suse.de Wed Aug 6 16:54:23 2008
+From: Takashi Iwai <tiwai@suse.de>
+Date: Thu, 31 Jul 2008 19:06:13 +0200
+Subject: USB: cdc-acm.c: Fix compile warnings
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: Andrew Morton <akpm@linux-foundation.org>, linux-kernel@vger.kernel.org
+Message-ID: <s5hmyjyj856.wl%tiwai@suse.de>
+
+
+The irq flags should be unsigned long.
+
+ CC [M] drivers/usb/class/cdc-acm.o
+drivers/usb/class/cdc-acm.c: In function 'acm_waker':
+drivers/usb/class/cdc-acm.c:527: warning: comparison of distinct pointer types lacks a cast
+drivers/usb/class/cdc-acm.c:529: warning: comparison of distinct pointer types lacks a cast
+
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/class/cdc-acm.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -512,7 +512,7 @@ static void acm_softint(struct work_stru
+ static void acm_waker(struct work_struct *waker)
+ {
+ struct acm *acm = container_of(waker, struct acm, waker);
+- long flags;
++ unsigned long flags;
+ int rv;
+
+ rv = usb_autopm_get_interface(acm->control);
diff --git a/usb.current/usb-ftdi_sio-add-support-for-phi-fisco-data-cable.patch b/usb.current/usb-ftdi_sio-add-support-for-phi-fisco-data-cable.patch
new file mode 100644
index 00000000000000..0192abf0ea7c3b
--- /dev/null
+++ b/usb.current/usb-ftdi_sio-add-support-for-phi-fisco-data-cable.patch
@@ -0,0 +1,42 @@
+From lross@mail.ru Wed Aug 6 16:52:44 2008
+From: Lex Ross <lross@mail.ru>
+Date: Wed, 06 Aug 2008 16:25:08 +0400
+Subject: USB: ftdi_sio: add support for PHI Fisco data cable (FT232BM based, VID/PID 0403:e40b)
+To: linux-usb@vger.kernel.org
+Message-ID: <E1KQi4i-0000Bj-00.lross-mail-ru@f102.mail.ru>
+
+
+Support for PHI Fisco USB to Serial data cable (FTDI FT232BM based).
+PHI Fisco cable is supplied for connecting Philips Xenium 9@9++ mobile phones.
+PIDs were missing.
+
+Tested successfully with PHI Fisco Data Cable (VID/PID 0403:e40b)
+
+Signed-off-by: Lex V. Ross <lross@mail.ru>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 1 +
+ drivers/usb/serial/ftdi_sio.h | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -638,6 +638,7 @@ static struct usb_device_id id_table_com
+ { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) },
+ { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) },
++ { USB_DEVICE(FTDI_VID, FTDI_PHI_FISCO_PID) },
+ { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_ELSTER_UNICOM_PID) },
+ { USB_DEVICE(FTDI_VID, FTDI_PROPOX_JTAGCABLEII_PID) },
+--- a/drivers/usb/serial/ftdi_sio.h
++++ b/drivers/usb/serial/ftdi_sio.h
+@@ -526,6 +526,7 @@
+ #define FTDI_ELV_WS500_PID 0xE0E9 /* PC-Wetterstation (WS 500) */
+ #define FTDI_ELV_HS485_PID 0xE0EA /* USB to RS-485 adapter */
+ #define FTDI_ELV_EM1010PC_PID 0xE0EF /* Engery monitor EM 1010 PC */
++#define FTDI_PHI_FISCO_PID 0xE40B /* PHI Fisco USB to Serial cable */
+
+ /*
+ * Definitions for ID TECH (www.idt-net.com) devices
diff --git a/usb.current/usb-hook-start_hnp-into-ohci-struct.patch b/usb.current/usb-hook-start_hnp-into-ohci-struct.patch
new file mode 100644
index 00000000000000..a27209425485e7
--- /dev/null
+++ b/usb.current/usb-hook-start_hnp-into-ohci-struct.patch
@@ -0,0 +1,60 @@
+From dbaryshkov@gmail.com Wed Aug 6 16:42:44 2008
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Sun, 6 Jul 2008 14:26:30 +0400
+Subject: USB: Hook start_hnp into ohci struct
+To: linux-usb@vger.kernel.org
+Message-ID: <20080706102630.GA29934@doriath.ww600.siemens.net>
+Content-Disposition: inline
+
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Acked-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/host/ohci-hub.c | 4 +---
+ drivers/usb/host/ohci-omap.c | 1 +
+ drivers/usb/host/ohci.h | 1 +
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/ohci.h
++++ b/drivers/usb/host/ohci.h
+@@ -371,6 +371,7 @@ struct ohci_hcd {
+ * other external transceivers should be software-transparent
+ */
+ struct otg_transceiver *transceiver;
++ void (*start_hnp)(struct ohci_hcd *ohci);
+
+ /*
+ * memory management for queue data structures
+--- a/drivers/usb/host/ohci-hub.c
++++ b/drivers/usb/host/ohci-hub.c
+@@ -579,8 +579,6 @@ static int ohci_start_port_reset (struct
+ return 0;
+ }
+
+-static void start_hnp(struct ohci_hcd *ohci);
+-
+ #else
+
+ #define ohci_start_port_reset NULL
+@@ -767,7 +765,7 @@ static int ohci_hub_control (
+ #ifdef CONFIG_USB_OTG
+ if (hcd->self.otg_port == (wIndex + 1)
+ && hcd->self.b_hnp_enable)
+- start_hnp(ohci);
++ ohci->start_hnp(ohci);
+ else
+ #endif
+ ohci_writel (ohci, RH_PS_PSS,
+--- a/drivers/usb/host/ohci-omap.c
++++ b/drivers/usb/host/ohci-omap.c
+@@ -225,6 +225,7 @@ static int ohci_omap_init(struct usb_hcd
+ dev_err(hcd->self.controller, "can't find transceiver\n");
+ return -ENODEV;
+ }
++ ohci->start_hnp = start_hnp;
+ }
+ #endif
+
diff --git a/usb.current/usb-isp1760-don-t-be-noisy-about-short-packets.patch b/usb.current/usb-isp1760-don-t-be-noisy-about-short-packets.patch
new file mode 100644
index 00000000000000..ec1caf48c9d904
--- /dev/null
+++ b/usb.current/usb-isp1760-don-t-be-noisy-about-short-packets.patch
@@ -0,0 +1,54 @@
+From sebastian@breakpoint.cc Wed Aug 6 16:48:32 2008
+From: Sebastian Siewior <sebastian@breakpoint.cc>
+Date: Thu, 17 Jul 2008 20:09:29 +0200
+Subject: usb: isp1760: don't be noisy about short packets.
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: linux-usb@vger.kernel.org, Sebastian Siewior <sebastian@breakpoint.cc>, Alan Stern <stern@rowland.harvard.edu>
+Message-ID: <1216318170-23126-2-git-send-email-sebastian@breakpoint.cc>
+
+
+According to Alan Stern, short packets are quite normal under
+certain circumstances. This printk was triggered by usb to
+serial converters on every packet and some usb sticks triggered
+a few of those while plugging the stick.
+This printks are now hidden unless USB debug mode is activated.
+
+Cc: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Sebastian Siewior <sebastian@breakpoint.cc>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/host/isp1760-hcd.c | 6 +++---
+ drivers/usb/host/isp1760-hcd.h | 3 +++
+ 2 files changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/host/isp1760-hcd.c
++++ b/drivers/usb/host/isp1760-hcd.c
+@@ -1128,11 +1128,11 @@ static void do_atl_int(struct usb_hcd *u
+ } else if (usb_pipebulk(urb->pipe) && (length < qtd->length)) {
+ /* short BULK received */
+
+- printk(KERN_ERR "short bulk, %d instead %zu\n", length,
+- qtd->length);
+ if (urb->transfer_flags & URB_SHORT_NOT_OK) {
+ urb->status = -EREMOTEIO;
+- printk(KERN_ERR "not okey\n");
++ isp1760_dbg(priv, "short bulk, %d instead %zu "
++ "with URB_SHORT_NOT_OK flag.\n",
++ length, qtd->length);
+ }
+
+ if (urb->status == -EINPROGRESS)
+--- a/drivers/usb/host/isp1760-hcd.h
++++ b/drivers/usb/host/isp1760-hcd.h
+@@ -121,6 +121,9 @@ struct inter_packet_info {
+ typedef void (packet_enqueue)(struct usb_hcd *hcd, struct isp1760_qh *qh,
+ struct isp1760_qtd *qtd);
+
++#define isp1760_dbg(priv, fmt, args...) \
++ dev_dbg(priv_to_hcd(priv)->self.controller, fmt, ##args)
++
+ #define isp1760_info(priv, fmt, args...) \
+ dev_info(priv_to_hcd(priv)->self.controller, fmt, ##args)
+
diff --git a/usb.current/usb-isp1760-improve-pre-fetch-timing.patch b/usb.current/usb-isp1760-improve-pre-fetch-timing.patch
new file mode 100644
index 00000000000000..dd4abb2203accf
--- /dev/null
+++ b/usb.current/usb-isp1760-improve-pre-fetch-timing.patch
@@ -0,0 +1,143 @@
+From sebastian@breakpoint.cc Wed Aug 6 16:48:19 2008
+From: Sebastian Siewior <sebastian@breakpoint.cc>
+Date: Thu, 17 Jul 2008 20:09:30 +0200
+Subject: usb: ISP1760: improve pre-fetch timing
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: linux-usb@vger.kernel.org, Enrico Scholz <enrico.scholz@sigma-chemnitz.de>, Sebastian Siewior <bigeasy@linutronix.de>
+Message-ID: <1216318170-23126-3-git-send-email-sebastian@breakpoint.cc>
+
+
+From: Enrico Scholz <enrico.scholz@sigma-chemnitz.de>
+
+ISP1760 requires a delay of 90ns between programming the address and
+reading the data. Current driver solves this by a mdelay(1) which is
+very heavy weighted and slow. This patch applies the workaround from
+the ISP1760 FAQ by using two different banks for PTD and payload data
+and using a common wait for them. This wait is done by an additional
+ISP1760 access (whose timing constraints guarantee the 90ns delay).
+This improves speed when reading from an USB stick from:
+
+ $ time dd if=/dev/sda of=/dev/zero bs=65536 count=1638
+ real 1m 15.43s
+ user 0m 0.44s
+ sys 0m 39.46s
+
+to
+
+ $ time dd if=/dev/sda of=/dev/zero bs=65536 count=1638
+ real 0m 18.53s
+ user 0m 0.16s
+ sys 0m 12.97s
+
+[bigeasy@linutronix.de: fixed comment formating, moved define into
+ header file, obey 80 char rule]
+
+Signed-off-by: Enrico Scholz <enrico.scholz@sigma-chemnitz.de>
+Signed-off-by: Sebastian Siewior <bigeasy@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/isp1760-hcd.c | 44 ++++++++++++++++++++++++++++-------------
+ drivers/usb/host/isp1760-hcd.h | 2 +
+ 2 files changed, 33 insertions(+), 13 deletions(-)
+
+--- a/drivers/usb/host/isp1760-hcd.c
++++ b/drivers/usb/host/isp1760-hcd.c
+@@ -126,9 +126,8 @@ static void isp1760_writel(const unsigne
+ * doesn't quite work because some people have to enforce 32-bit access
+ */
+ static void priv_read_copy(struct isp1760_hcd *priv, u32 *src,
+- __u32 __iomem *dst, u32 offset, u32 len)
++ __u32 __iomem *dst, u32 len)
+ {
+- struct usb_hcd *hcd = priv_to_hcd(priv);
+ u32 val;
+ u8 *buff8;
+
+@@ -136,11 +135,6 @@ static void priv_read_copy(struct isp176
+ printk(KERN_ERR "ERROR: buffer: %p len: %d\n", src, len);
+ return;
+ }
+- isp1760_writel(offset, hcd->regs + HC_MEMORY_REG);
+- /* XXX
+- * 90nsec delay, the spec says something how this could be avoided.
+- */
+- mdelay(1);
+
+ while (len >= 4) {
+ *src = __raw_readl(dst);
+@@ -987,8 +981,20 @@ static void do_atl_int(struct usb_hcd *u
+ printk(KERN_ERR "qh is 0\n");
+ continue;
+ }
+- priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + atl_regs,
+- atl_regs, sizeof(ptd));
++ isp1760_writel(atl_regs + ISP_BANK(0), usb_hcd->regs +
++ HC_MEMORY_REG);
++ isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs +
++ HC_MEMORY_REG);
++ /*
++ * write bank1 address twice to ensure the 90ns delay (time
++ * between BANK0 write and the priv_read_copy() call is at
++ * least 3*t_WHWL + 2*t_w11 = 3*25ns + 2*17ns = 92ns)
++ */
++ isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs +
++ HC_MEMORY_REG);
++
++ priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + atl_regs +
++ ISP_BANK(0), sizeof(ptd));
+
+ dw1 = le32_to_cpu(ptd.dw1);
+ dw2 = le32_to_cpu(ptd.dw2);
+@@ -1091,7 +1097,7 @@ static void do_atl_int(struct usb_hcd *u
+ case IN_PID:
+ priv_read_copy(priv,
+ priv->atl_ints[queue_entry].data_buffer,
+- usb_hcd->regs + payload, payload,
++ usb_hcd->regs + payload + ISP_BANK(1),
+ length);
+
+ case OUT_PID:
+@@ -1206,8 +1212,20 @@ static void do_intl_int(struct usb_hcd *
+ continue;
+ }
+
+- priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + int_regs,
+- int_regs, sizeof(ptd));
++ isp1760_writel(int_regs + ISP_BANK(0), usb_hcd->regs +
++ HC_MEMORY_REG);
++ isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs +
++ HC_MEMORY_REG);
++ /*
++ * write bank1 address twice to ensure the 90ns delay (time
++ * between BANK0 write and the priv_read_copy() call is at
++ * least 3*t_WHWL + 2*t_w11 = 3*25ns + 2*17ns = 92ns)
++ */
++ isp1760_writel(payload + ISP_BANK(1), usb_hcd->regs +
++ HC_MEMORY_REG);
++
++ priv_read_copy(priv, (u32 *)&ptd, usb_hcd->regs + int_regs +
++ ISP_BANK(0), sizeof(ptd));
+ dw1 = le32_to_cpu(ptd.dw1);
+ dw3 = le32_to_cpu(ptd.dw3);
+ check_int_err_status(le32_to_cpu(ptd.dw4));
+@@ -1242,7 +1260,7 @@ static void do_intl_int(struct usb_hcd *
+ case IN_PID:
+ priv_read_copy(priv,
+ priv->int_ints[queue_entry].data_buffer,
+- usb_hcd->regs + payload , payload,
++ usb_hcd->regs + payload + ISP_BANK(1),
+ length);
+ case OUT_PID:
+
+--- a/drivers/usb/host/isp1760-hcd.h
++++ b/drivers/usb/host/isp1760-hcd.h
+@@ -54,6 +54,8 @@ void deinit_kmem_cache(void);
+ #define BUFFER_MAP 0x7
+
+ #define HC_MEMORY_REG 0x33c
++#define ISP_BANK(x) ((x) << 16)
++
+ #define HC_PORT1_CTRL 0x374
+ #define PORT1_POWER (3 << 3)
+ #define PORT1_INIT1 (1 << 7)
diff --git a/usb.current/usb-ohci-make-distrust_firmware-a-quirk.patch b/usb.current/usb-ohci-make-distrust_firmware-a-quirk.patch
new file mode 100644
index 00000000000000..177a8358a2bed9
--- /dev/null
+++ b/usb.current/usb-ohci-make-distrust_firmware-a-quirk.patch
@@ -0,0 +1,65 @@
+From dbaryshkov@gmail.com Wed Aug 6 16:42:01 2008
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Sun, 6 Jul 2008 23:35:01 +0400
+Subject: USB: ohci: make distrust_firmware a quirk
+To: Alan Stern <stern@rowland.harvard.edu>
+Cc: linux-usb@vger.kernel.org
+Message-ID: <20080706193501.GA14976@doriath.ww600.siemens.net>
+Content-Disposition: inline
+
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Acked-by: 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/ohci-hcd.c | 6 +++++-
+ drivers/usb/host/ohci-omap.c | 2 +-
+ drivers/usb/host/ohci.h | 1 +
+ 3 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/host/ohci.h
++++ b/drivers/usb/host/ohci.h
+@@ -399,6 +399,7 @@ struct ohci_hcd {
+ #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/
+ #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */
+ #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */
++#define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */
+ // there are also chip quirks/bugs in init logic
+
+ struct work_struct nec_work; /* Worker for NEC quirk */
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -483,6 +483,9 @@ static int ohci_init (struct ohci_hcd *o
+ int ret;
+ struct usb_hcd *hcd = ohci_to_hcd(ohci);
+
++ if (distrust_firmware)
++ ohci->flags |= OHCI_QUIRK_HUB_POWER;
++
+ disable (ohci);
+ ohci->regs = hcd->regs;
+
+@@ -689,7 +692,8 @@ retry:
+ temp |= RH_A_NOCP;
+ temp &= ~(RH_A_POTPGT | RH_A_NPS);
+ ohci_writel (ohci, temp, &ohci->regs->roothub.a);
+- } else if ((ohci->flags & OHCI_QUIRK_AMD756) || distrust_firmware) {
++ } else if ((ohci->flags & OHCI_QUIRK_AMD756) ||
++ (ohci->flags & OHCI_QUIRK_HUB_POWER)) {
+ /* hub power always on; required for AMD-756 and some
+ * Mac platforms. ganged overcurrent reporting, if any.
+ */
+--- a/drivers/usb/host/ohci-omap.c
++++ b/drivers/usb/host/ohci-omap.c
+@@ -260,7 +260,7 @@ static int ohci_omap_init(struct usb_hcd
+ omap_cfg_reg(W4_USB_HIGHZ);
+ }
+ ohci_writel(ohci, rh, &ohci->regs->roothub.a);
+- distrust_firmware = 0;
++ ohci->flags &= ~OHCI_QUIRK_HUB_POWER;
+ } else if (machine_is_nokia770()) {
+ /* We require a self-powered hub, which should have
+ * plenty of power. */
diff --git a/usb.current/usb-omap_udc-fix-compilation-with-debug-enabled.patch b/usb.current/usb-omap_udc-fix-compilation-with-debug-enabled.patch
new file mode 100644
index 00000000000000..f158748d723b92
--- /dev/null
+++ b/usb.current/usb-omap_udc-fix-compilation-with-debug-enabled.patch
@@ -0,0 +1,37 @@
+From dbaryshkov@gmail.com Wed Aug 6 16:41:16 2008
+From: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Date: Sun, 6 Jul 2008 14:25:53 +0400
+Subject: USB: omap_udc: fix compilation with debug enabled
+To: linux-usb@vger.kernel.org
+Message-ID: <20080706102553.GA29914@doriath.ww600.siemens.net>
+Content-Disposition: inline
+
+
+Signed-off-by: Dmitry Baryshkov <dbaryshkov@gmail.com>
+Acked-by: David Brownell <dbrownell@users.sourceforge.net>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/omap_udc.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/gadget/omap_udc.c
++++ b/drivers/usb/gadget/omap_udc.c
+@@ -54,6 +54,7 @@
+
+ #include <asm/arch/dma.h>
+ #include <asm/arch/usb.h>
++#include <asm/arch/control.h>
+
+ #include "omap_udc.h"
+
+@@ -2313,7 +2314,7 @@ static int proc_otg_show(struct seq_file
+ tmp = OTG_REV_REG;
+ if (cpu_is_omap24xx()) {
+ ctrl_name = "control_devconf";
+- trans = CONTROL_DEVCONF_REG;
++ trans = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+ } else {
+ ctrl_name = "tranceiver_ctrl";
+ trans = omap_readw(USB_TRANSCEIVER_CTRL);
diff --git a/usb.current/usb-quirk-pll-power-down-mode.patch b/usb.current/usb-quirk-pll-power-down-mode.patch
new file mode 100644
index 00000000000000..24f292073ed2a8
--- /dev/null
+++ b/usb.current/usb-quirk-pll-power-down-mode.patch
@@ -0,0 +1,260 @@
+From Libin.Yang@amd.com Wed Aug 6 16:45:35 2008
+From: Libin Yang <Libin.Yang@amd.com>
+Date: Thu, 31 Jul 2008 10:31:50 +0800
+Subject: USB: quirk PLL power down mode
+To: David Brownell <david-b@pacbell.net>
+Cc: Greg KH <gregkh@suse.de>, linux-usb@vger.kernel.org, oliver@neukum.org, stern@rowland.harvard.edu
+Message-ID: <1217471510.5418.3.camel@crane-laptop>
+
+
+On some AMD 700 series southbridges, ISO OUT transfers (such as audio
+playback through speakers) on the USB OHCI controller may be corrupted
+when an A-Link express power saving feature is active.
+
+PLL power down mode in conjunction with link power management feature
+L1 being enabled is the bad combination ... this patch prevents them
+from being enabled when ISO transfers are pending.
+
+Signed-off-by: Crane Cai <crane.cai@amd.com>
+Signed-off-by: Libin Yang <libin.yang@amd.com>
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ohci-hcd.c | 2
+ drivers/usb/host/ohci-pci.c | 132 ++++++++++++++++++++++++++++++++++++++++++++
+ drivers/usb/host/ohci-q.c | 6 ++
+ drivers/usb/host/ohci.h | 20 ++++++
+ 4 files changed, 160 insertions(+)
+
+--- a/drivers/usb/host/ohci.h
++++ b/drivers/usb/host/ohci.h
+@@ -401,6 +401,7 @@ struct ohci_hcd {
+ #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */
+ #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */
+ #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */
++#define OHCI_QUIRK_AMD_ISO 0x200 /* ISO transfers*/
+ // there are also chip quirks/bugs in init logic
+
+ struct work_struct nec_work; /* Worker for NEC quirk */
+@@ -428,6 +429,12 @@ static inline int quirk_zfmicro(struct o
+ {
+ return ohci->flags & OHCI_QUIRK_ZFMICRO;
+ }
++static inline int quirk_amdiso(struct ohci_hcd *ohci)
++{
++ return ohci->flags & OHCI_QUIRK_AMD_ISO;
++}
++static void quirk_amd_pll(int state);
++static void amd_iso_dev_put(void);
+ #else
+ static inline int quirk_nec(struct ohci_hcd *ohci)
+ {
+@@ -437,6 +444,19 @@ static inline int quirk_zfmicro(struct o
+ {
+ return 0;
+ }
++static inline int quirk_amdiso(struct ohci_hcd *ohci)
++{
++ return 0;
++}
++
++static inline void quirk_amd_pll(int state)
++{
++ return;
++}
++static inline void amd_iso_dev_put(void)
++{
++ return;
++}
+ #endif
+
+ /* convert between an hcd pointer and the corresponding ohci_hcd */
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -886,6 +886,8 @@ static void ohci_stop (struct usb_hcd *h
+
+ if (quirk_zfmicro(ohci))
+ del_timer(&ohci->unlink_watchdog);
++ if (quirk_amdiso(ohci))
++ amd_iso_dev_put();
+
+ remove_debug_files (ohci);
+ ohci_mem_cleanup (ohci);
+--- a/drivers/usb/host/ohci-pci.c
++++ b/drivers/usb/host/ohci-pci.c
+@@ -18,6 +18,28 @@
+ #error "This file is PCI bus glue. CONFIG_PCI must be defined."
+ #endif
+
++#include <linux/pci.h>
++#include <linux/io.h>
++
++
++/* constants used to work around PM-related transfer
++ * glitches in some AMD 700 series southbridges
++ */
++#define AB_REG_BAR 0xf0
++#define AB_INDX(addr) ((addr) + 0x00)
++#define AB_DATA(addr) ((addr) + 0x04)
++#define AX_INDXC 0X30
++#define AX_DATAC 0x34
++
++#define NB_PCIE_INDX_ADDR 0xe0
++#define NB_PCIE_INDX_DATA 0xe4
++#define PCIE_P_CNTL 0x10040
++#define BIF_NB 0x10002
++
++static struct pci_dev *amd_smbus_dev;
++static struct pci_dev *amd_hb_dev;
++static int amd_ohci_iso_count;
++
+ /*-------------------------------------------------------------------------*/
+
+ static int broken_suspend(struct usb_hcd *hcd)
+@@ -143,6 +165,103 @@ static int ohci_quirk_nec(struct usb_hcd
+ return 0;
+ }
+
++static int ohci_quirk_amd700(struct usb_hcd *hcd)
++{
++ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++ u8 rev = 0;
++
++ if (!amd_smbus_dev)
++ amd_smbus_dev = pci_get_device(PCI_VENDOR_ID_ATI,
++ PCI_DEVICE_ID_ATI_SBX00_SMBUS, NULL);
++ if (!amd_smbus_dev)
++ return 0;
++
++ pci_read_config_byte(amd_smbus_dev, PCI_REVISION_ID, &rev);
++ if ((rev > 0x3b) || (rev < 0x30)) {
++ pci_dev_put(amd_smbus_dev);
++ amd_smbus_dev = NULL;
++ return 0;
++ }
++
++ amd_ohci_iso_count++;
++
++ if (!amd_hb_dev)
++ amd_hb_dev = pci_get_device(PCI_VENDOR_ID_AMD, 0x9600, NULL);
++
++ ohci->flags |= OHCI_QUIRK_AMD_ISO;
++ ohci_dbg(ohci, "enabled AMD ISO transfers quirk\n");
++
++ return 0;
++}
++
++/*
++ * The hardware normally enables the A-link power management feature, which
++ * lets the system lower the power consumption in idle states.
++ *
++ * Assume the system is configured to have USB 1.1 ISO transfers going
++ * to or from a USB device. Without this quirk, that stream may stutter
++ * or have breaks occasionally. For transfers going to speakers, this
++ * makes a very audible mess...
++ *
++ * That audio playback corruption is due to the audio stream getting
++ * interrupted occasionally when the link goes in lower power state
++ * This USB quirk prevents the link going into that lower power state
++ * during audio playback or other ISO operations.
++ */
++static void quirk_amd_pll(int on)
++{
++ u32 addr;
++ u32 val;
++ u32 bit = (on > 0) ? 1 : 0;
++
++ pci_read_config_dword(amd_smbus_dev, AB_REG_BAR, &addr);
++
++ /* BIT names/meanings are NDA-protected, sorry ... */
++
++ outl(AX_INDXC, AB_INDX(addr));
++ outl(0x40, AB_DATA(addr));
++ outl(AX_DATAC, AB_INDX(addr));
++ val = inl(AB_DATA(addr));
++ val &= ~((1 << 3) | (1 << 4) | (1 << 9));
++ val |= (bit << 3) | ((!bit) << 4) | ((!bit) << 9);
++ outl(val, AB_DATA(addr));
++
++ if (amd_hb_dev) {
++ addr = PCIE_P_CNTL;
++ pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr);
++
++ pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val);
++ val &= ~(1 | (1 << 3) | (1 << 4) | (1 << 9) | (1 << 12));
++ val |= bit | (bit << 3) | (bit << 12);
++ val |= ((!bit) << 4) | ((!bit) << 9);
++ pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val);
++
++ addr = BIF_NB;
++ pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_ADDR, addr);
++
++ pci_read_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, &val);
++ val &= ~(1 << 8);
++ val |= bit << 8;
++ pci_write_config_dword(amd_hb_dev, NB_PCIE_INDX_DATA, val);
++ }
++}
++
++static void amd_iso_dev_put(void)
++{
++ amd_ohci_iso_count--;
++ if (amd_ohci_iso_count == 0) {
++ if (amd_smbus_dev) {
++ pci_dev_put(amd_smbus_dev);
++ amd_smbus_dev = NULL;
++ }
++ if (amd_hb_dev) {
++ pci_dev_put(amd_hb_dev);
++ amd_hb_dev = NULL;
++ }
++ }
++
++}
++
+ /* List of quirks for OHCI */
+ static const struct pci_device_id ohci_pci_quirks[] = {
+ {
+@@ -181,6 +300,19 @@ static const struct pci_device_id ohci_p
+ PCI_DEVICE(PCI_VENDOR_ID_ITE, 0x8152),
+ .driver_data = (unsigned long) broken_suspend,
+ },
++ {
++ PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4397),
++ .driver_data = (unsigned long)ohci_quirk_amd700,
++ },
++ {
++ PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4398),
++ .driver_data = (unsigned long)ohci_quirk_amd700,
++ },
++ {
++ PCI_DEVICE(PCI_VENDOR_ID_ATI, 0x4399),
++ .driver_data = (unsigned long)ohci_quirk_amd700,
++ },
++
+ /* FIXME for some of the early AMD 760 southbridges, OHCI
+ * won't work at all. blacklist them.
+ */
+--- a/drivers/usb/host/ohci-q.c
++++ b/drivers/usb/host/ohci-q.c
+@@ -49,6 +49,9 @@ __acquires(ohci->lock)
+ switch (usb_pipetype (urb->pipe)) {
+ case PIPE_ISOCHRONOUS:
+ ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs--;
++ if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
++ && quirk_amdiso(ohci))
++ quirk_amd_pll(1);
+ break;
+ case PIPE_INTERRUPT:
+ ohci_to_hcd(ohci)->self.bandwidth_int_reqs--;
+@@ -677,6 +680,9 @@ static void td_submit_urb (
+ data + urb->iso_frame_desc [cnt].offset,
+ urb->iso_frame_desc [cnt].length, urb, cnt);
+ }
++ if (ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs == 0
++ && quirk_amdiso(ohci))
++ quirk_amd_pll(0);
+ periodic = ohci_to_hcd(ohci)->self.bandwidth_isoc_reqs++ == 0
+ && ohci_to_hcd(ohci)->self.bandwidth_int_reqs == 0;
+ break;
diff --git a/usb.current/usb-return-error-code-instead-of-0-in-the-enqueue-function.patch b/usb.current/usb-return-error-code-instead-of-0-in-the-enqueue-function.patch
new file mode 100644
index 00000000000000..c1554780d7c265
--- /dev/null
+++ b/usb.current/usb-return-error-code-instead-of-0-in-the-enqueue-function.patch
@@ -0,0 +1,32 @@
+From sebastian@breakpoint.cc Wed Aug 6 16:48:04 2008
+From: Sebastian Siewior <sebastian@breakpoint.cc>
+Date: Thu, 17 Jul 2008 20:09:28 +0200
+Subject: usb: return error code instead of 0 in the enqueue function.
+To: Greg Kroah-Hartman <gregkh@suse.de>
+Cc: linux-usb@vger.kernel.org, Sebastian Siewior <sebastian@breakpoint.cc>
+Message-ID: <1216318170-23126-1-git-send-email-sebastian@breakpoint.cc>
+
+
+if the enqueue function returns -ESHUTDOWN or -ENOMEM then
+we return 0 instead of an error. This leads to a timeout and
+then to a dequeue request of an not enqueued urb.
+
+Signed-off-by: Sebastian Siewior <sebastian@breakpoint.cc>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/isp1760-hcd.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/usb/host/isp1760-hcd.c
++++ b/drivers/usb/host/isp1760-hcd.c
+@@ -1615,8 +1615,7 @@ static int isp1760_urb_enqueue(struct us
+ return -EPIPE;
+ }
+
+- isp1760_prepare_enqueue(priv, urb, &qtd_list, mem_flags, pe);
+- return 0;
++ return isp1760_prepare_enqueue(priv, urb, &qtd_list, mem_flags, pe);
+ }
+
+ static int isp1760_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
diff --git a/usb.current/usb-serial-gadget-rx-path-data-loss-fixes.patch b/usb.current/usb-serial-gadget-rx-path-data-loss-fixes.patch
new file mode 100644
index 00000000000000..71978257a053d4
--- /dev/null
+++ b/usb.current/usb-serial-gadget-rx-path-data-loss-fixes.patch
@@ -0,0 +1,391 @@
+From david-b@pacbell.net Wed Aug 6 16:44:52 2008
+From: David Brownell <david-b@pacbell.net>
+Date: Mon, 7 Jul 2008 12:16:08 -0700
+Subject: USB: serial gadget: rx path data loss fixes
+To: Greg KH <greg@kroah.com>
+Cc: linux-usb@vger.kernel.org, Alan Cox <alan@lxorguk.ukuu.org.uk>, Matthieu CASTET <matthieu.castet@parrot.com>
+Message-ID: <200807071216.09106.david-b@pacbell.net>
+Content-Disposition: inline
+
+
+From: David Brownell <dbrownell@users.sourceforge.net>
+
+Update RX path handling in new serial gadget code to cope better with
+RX blockage: queue every RX packet until its contents can safely be
+passed up to the ldisc. Most of the RX path work is now done in the
+RX tasklet, instead of just the final "push to ldisc" step. This
+addresses some cases of data loss:
+
+ - A longstanding serial gadget bug: when tty_insert_flip_string()
+ didn't copy the entire buffer, the rest of the characters were
+ dropped! Now that packet stays queued until the rest of its data
+ is pushed to the ldisc.
+
+ - Another longstanding issue: in the unlikely case that an RX
+ transfer returns data and also reports a fault, that data is
+ no longer discarded.
+
+ - In the recently added RX throttling logic: it needs to stop
+ pushing data into the TTY layer, instead of just not submitting
+ new USB read requests. When the TTY is throttled long enough,
+ backpressure will eventually make the OUT endpoint NAK.
+
+Also: an #ifdef is removed (no longer necessary); and start switching
+to a better convention for debug messages (prefix them with tty name).
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/u_serial.c | 236 +++++++++++++++++++++++++-----------------
+ 1 file changed, 146 insertions(+), 90 deletions(-)
+
+--- a/drivers/usb/gadget/u_serial.c
++++ b/drivers/usb/gadget/u_serial.c
+@@ -52,6 +52,8 @@
+ * is managed in userspace ... OBEX, PTP, and MTP have been mentioned.
+ */
+
++#define PREFIX "ttyGS"
++
+ /*
+ * gserial is the lifecycle interface, used by USB functions
+ * gs_port is the I/O nexus, used by the tty driver
+@@ -100,6 +102,8 @@ struct gs_port {
+ wait_queue_head_t close_wait; /* wait for last close */
+
+ struct list_head read_pool;
++ struct list_head read_queue;
++ unsigned n_read;
+ struct tasklet_struct push;
+
+ struct list_head write_pool;
+@@ -367,11 +371,9 @@ __acquires(&port->port_lock)
+ req->length = len;
+ list_del(&req->list);
+
+-#ifdef VERBOSE_DEBUG
+- pr_debug("%s: %s, len=%d, 0x%02x 0x%02x 0x%02x ...\n",
+- __func__, in->name, len, *((u8 *)req->buf),
++ pr_vdebug(PREFIX "%d: tx len=%d, 0x%02x 0x%02x 0x%02x ...\n",
++ port->port_num, len, *((u8 *)req->buf),
+ *((u8 *)req->buf+1), *((u8 *)req->buf+2));
+-#endif
+
+ /* Drop lock while we call out of driver; completions
+ * could be issued while we do so. Disconnection may
+@@ -401,56 +403,6 @@ __acquires(&port->port_lock)
+ return status;
+ }
+
+-static void gs_rx_push(unsigned long _port)
+-{
+- struct gs_port *port = (void *)_port;
+- struct tty_struct *tty = port->port_tty;
+-
+- /* With low_latency, tty_flip_buffer_push() doesn't put its
+- * real work through a workqueue, so the ldisc has a better
+- * chance to keep up with peak USB data rates.
+- */
+- if (tty) {
+- tty_flip_buffer_push(tty);
+- wake_up_interruptible(&tty->read_wait);
+- }
+-}
+-
+-/*
+- * gs_recv_packet
+- *
+- * Called for each USB packet received. Reads the packet
+- * header and stuffs the data in the appropriate tty buffer.
+- * Returns 0 if successful, or a negative error number.
+- *
+- * Called during USB completion routine, on interrupt time.
+- * With port_lock.
+- */
+-static int gs_recv_packet(struct gs_port *port, char *packet, unsigned size)
+-{
+- unsigned len;
+- struct tty_struct *tty;
+-
+- /* I/O completions can continue for a while after close(), until the
+- * request queue empties. Just discard any data we receive, until
+- * something reopens this TTY ... as if there were no HW flow control.
+- */
+- tty = port->port_tty;
+- if (tty == NULL) {
+- pr_vdebug("%s: ttyGS%d, after close\n",
+- __func__, port->port_num);
+- return -EIO;
+- }
+-
+- len = tty_insert_flip_string(tty, packet, size);
+- if (len > 0)
+- tasklet_schedule(&port->push);
+- if (len < size)
+- pr_debug("%s: ttyGS%d, drop %d bytes\n",
+- __func__, port->port_num, size - len);
+- return 0;
+-}
+-
+ /*
+ * Context: caller owns port_lock, and port_usb is set
+ */
+@@ -469,9 +421,9 @@ __acquires(&port->port_lock)
+ int status;
+ struct tty_struct *tty;
+
+- /* no more rx if closed or throttled */
++ /* no more rx if closed */
+ tty = port->port_tty;
+- if (!tty || test_bit(TTY_THROTTLED, &tty->flags))
++ if (!tty)
+ break;
+
+ req = list_entry(pool->next, struct usb_request, list);
+@@ -500,36 +452,134 @@ __acquires(&port->port_lock)
+ return started;
+ }
+
+-static void gs_read_complete(struct usb_ep *ep, struct usb_request *req)
++/*
++ * RX tasklet takes data out of the RX queue and hands it up to the TTY
++ * layer until it refuses to take any more data (or is throttled back).
++ * Then it issues reads for any further data.
++ *
++ * If the RX queue becomes full enough that no usb_request is queued,
++ * the OUT endpoint may begin NAKing as soon as its FIFO fills up.
++ * So QUEUE_SIZE packets plus however many the FIFO holds (usually two)
++ * can be buffered before the TTY layer's buffers (currently 64 KB).
++ */
++static void gs_rx_push(unsigned long _port)
+ {
+- int status;
+- struct gs_port *port = ep->driver_data;
++ struct gs_port *port = (void *)_port;
++ struct tty_struct *tty;
++ struct list_head *queue = &port->read_queue;
++ bool disconnect = false;
++ bool do_push = false;
+
+- spin_lock(&port->port_lock);
+- list_add(&req->list, &port->read_pool);
++ /* hand any queued data to the tty */
++ spin_lock_irq(&port->port_lock);
++ tty = port->port_tty;
++ while (!list_empty(queue)) {
++ struct usb_request *req;
+
+- switch (req->status) {
+- case 0:
+- /* normal completion */
+- status = gs_recv_packet(port, req->buf, req->actual);
+- if (status && status != -EIO)
+- pr_debug("%s: %s %s err %d\n",
+- __func__, "recv", ep->name, status);
+- gs_start_rx(port);
+- break;
++ req = list_first_entry(queue, struct usb_request, list);
+
+- case -ESHUTDOWN:
+- /* disconnect */
+- pr_vdebug("%s: %s shutdown\n", __func__, ep->name);
+- break;
++ /* discard data if tty was closed */
++ if (!tty)
++ goto recycle;
+
+- default:
+- /* presumably a transient fault */
+- pr_warning("%s: unexpected %s status %d\n",
+- __func__, ep->name, req->status);
+- gs_start_rx(port);
+- break;
++ /* leave data queued if tty was rx throttled */
++ if (test_bit(TTY_THROTTLED, &tty->flags))
++ break;
++
++ switch (req->status) {
++ case -ESHUTDOWN:
++ disconnect = true;
++ pr_vdebug(PREFIX "%d: shutdown\n", port->port_num);
++ break;
++
++ default:
++ /* presumably a transient fault */
++ pr_warning(PREFIX "%d: unexpected RX status %d\n",
++ port->port_num, req->status);
++ /* FALLTHROUGH */
++ case 0:
++ /* normal completion */
++ break;
++ }
++
++ /* push data to (open) tty */
++ if (req->actual) {
++ char *packet = req->buf;
++ unsigned size = req->actual;
++ unsigned n;
++ int count;
++
++ /* we may have pushed part of this packet already... */
++ n = port->n_read;
++ if (n) {
++ packet += n;
++ size -= n;
++ }
++
++ count = tty_insert_flip_string(tty, packet, size);
++ if (count)
++ do_push = true;
++ if (count != size) {
++ /* stop pushing; TTY layer can't handle more */
++ port->n_read += count;
++ pr_vdebug(PREFIX "%d: rx block %d/%d\n",
++ port->port_num,
++ count, req->actual);
++ break;
++ }
++ port->n_read = 0;
++ }
++recycle:
++ list_move(&req->list, &port->read_pool);
++ }
++
++ /* Push from tty to ldisc; this is immediate with low_latency, and
++ * may trigger callbacks to this driver ... so drop the spinlock.
++ */
++ if (tty && do_push) {
++ spin_unlock_irq(&port->port_lock);
++ tty_flip_buffer_push(tty);
++ wake_up_interruptible(&tty->read_wait);
++ spin_lock_irq(&port->port_lock);
++
++ /* tty may have been closed */
++ tty = port->port_tty;
+ }
++
++
++ /* We want our data queue to become empty ASAP, keeping data
++ * in the tty and ldisc (not here). If we couldn't push any
++ * this time around, there may be trouble unless there's an
++ * implicit tty_unthrottle() call on its way...
++ *
++ * REVISIT we should probably add a timer to keep the tasklet
++ * from starving ... but it's not clear that case ever happens.
++ */
++ if (!list_empty(queue) && tty) {
++ if (!test_bit(TTY_THROTTLED, &tty->flags)) {
++ if (do_push)
++ tasklet_schedule(&port->push);
++ else
++ pr_warning(PREFIX "%d: RX not scheduled?\n",
++ port->port_num);
++ }
++ }
++
++ /* If we're still connected, refill the USB RX queue. */
++ if (!disconnect && port->port_usb)
++ gs_start_rx(port);
++
++ spin_unlock_irq(&port->port_lock);
++}
++
++static void gs_read_complete(struct usb_ep *ep, struct usb_request *req)
++{
++ struct gs_port *port = ep->driver_data;
++
++ /* Queue all received data until the tty layer is ready for it. */
++ spin_lock(&port->port_lock);
++ list_add_tail(&req->list, &port->read_queue);
++ tasklet_schedule(&port->push);
+ spin_unlock(&port->port_lock);
+ }
+
+@@ -625,6 +675,7 @@ static int gs_start_io(struct gs_port *p
+ }
+
+ /* queue read requests */
++ port->n_read = 0;
+ started = gs_start_rx(port);
+
+ /* unblock any pending writes into our circular buffer */
+@@ -633,9 +684,10 @@ static int gs_start_io(struct gs_port *p
+ } else {
+ gs_free_requests(ep, head);
+ gs_free_requests(port->port_usb->in, &port->write_pool);
++ status = -EIO;
+ }
+
+- return started ? 0 : status;
++ return status;
+ }
+
+ /*-------------------------------------------------------------------------*/
+@@ -809,8 +861,6 @@ static void gs_close(struct tty_struct *
+ else
+ gs_buf_clear(&port->port_write_buf);
+
+- tasklet_kill(&port->push);
+-
+ tty->driver_data = NULL;
+ port->port_tty = NULL;
+
+@@ -911,15 +961,17 @@ static void gs_unthrottle(struct tty_str
+ {
+ struct gs_port *port = tty->driver_data;
+ unsigned long flags;
+- unsigned started = 0;
+
+ spin_lock_irqsave(&port->port_lock, flags);
+- if (port->port_usb)
+- started = gs_start_rx(port);
++ if (port->port_usb) {
++ /* Kickstart read queue processing. We don't do xon/xoff,
++ * rts/cts, or other handshaking with the host, but if the
++ * read queue backs up enough we'll be NAKing OUT packets.
++ */
++ tasklet_schedule(&port->push);
++ pr_vdebug(PREFIX "%d: unthrottle\n", port->port_num);
++ }
+ spin_unlock_irqrestore(&port->port_lock, flags);
+-
+- pr_vdebug("gs_unthrottle: ttyGS%d, %d packets\n",
+- port->port_num, started);
+ }
+
+ static const struct tty_operations gs_tty_ops = {
+@@ -953,6 +1005,7 @@ gs_port_alloc(unsigned port_num, struct
+ tasklet_init(&port->push, gs_rx_push, (unsigned long) port);
+
+ INIT_LIST_HEAD(&port->read_pool);
++ INIT_LIST_HEAD(&port->read_queue);
+ INIT_LIST_HEAD(&port->write_pool);
+
+ port->port_num = port_num;
+@@ -997,7 +1050,7 @@ int __init gserial_setup(struct usb_gadg
+
+ gs_tty_driver->owner = THIS_MODULE;
+ gs_tty_driver->driver_name = "g_serial";
+- gs_tty_driver->name = "ttyGS";
++ gs_tty_driver->name = PREFIX;
+ /* uses dynamically assigned dev_t values */
+
+ gs_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
+@@ -1104,6 +1157,8 @@ void gserial_cleanup(void)
+ ports[i].port = NULL;
+ mutex_unlock(&ports[i].lock);
+
++ tasklet_kill(&port->push);
++
+ /* wait for old opens to finish */
+ wait_event(port->close_wait, gs_closed(port));
+
+@@ -1241,6 +1296,7 @@ void gserial_disconnect(struct gserial *
+ if (port->open_count == 0 && !port->openclose)
+ gs_buf_free(&port->port_write_buf);
+ gs_free_requests(gser->out, &port->read_pool);
++ gs_free_requests(gser->out, &port->read_queue);
+ gs_free_requests(gser->in, &port->write_pool);
+ spin_unlock_irqrestore(&port->port_lock, flags);
+ }
diff --git a/usb.current/usb-update-to-documentation.patch b/usb.current/usb-update-to-documentation.patch
new file mode 100644
index 00000000000000..5798c3c88dc072
--- /dev/null
+++ b/usb.current/usb-update-to-documentation.patch
@@ -0,0 +1,35 @@
+From oliver@neukum.org Wed Aug 6 16:39:58 2008
+From: Oliver Neukum <oliver@neukum.org>
+Date: Fri, 4 Jul 2008 10:10:53 +0200
+Subject: USB: update to Documentation
+To: Alan Stern <stern@rowland.harvard.edu>
+Cc: Greg KH <greg@kroah.com>, linux-usb@vger.kernel.org
+Message-ID: <200807041010.53563.oliver@neukum.org>
+Content-Disposition: inline
+
+
+this mentions a new deadlock due to advanced power management.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ Documentation/usb/power-management.txt | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/Documentation/usb/power-management.txt
++++ b/Documentation/usb/power-management.txt
+@@ -436,7 +436,12 @@ post_reset; the USB core guarantees that
+ suspend/resume events as well.
+
+ If a driver wants to block all suspend/resume calls during some
+-critical section, it can simply acquire udev->pm_mutex.
++critical section, it can simply acquire udev->pm_mutex. Note that
++calls to resume may be triggered indirectly. Block IO due to memory
++allocations can make the vm subsystem resume a device. Thus while
++holding this lock you must not allocate memory with GFP_KERNEL or
++GFP_NOFS.
++
+ Alternatively, if the critical section might call some of the
+ usb_autopm_* routines, the driver can avoid deadlock by doing:
+