aboutsummaryrefslogtreecommitdiffstats
path: root/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-06-30 16:21:36 -0700
committerGreg Kroah-Hartman <gregkh@suse.de>2006-06-30 16:21:36 -0700
commitdc49a952fd6cbbdce6aacd9f1efb3ace6f64c4bc (patch)
tree1ce208bd0a9c4a02596da4b95b6272625dd669b7 /usb
parenta5363843f6fde193b61d6b06779229390eb4071c (diff)
downloadpatches-dc49a952fd6cbbdce6aacd9f1efb3ace6f64c4bc.tar.gz
loads of new patches
Diffstat (limited to 'usb')
-rw-r--r--usb/usb-add-driver-for-non-composite-sierra-wireless-devices.patch132
-rw-r--r--usb/usb-allow-compile-in-g_ether-fix-typo.patch40
-rw-r--r--usb/usb-at91-ohci-updates-mostly-power-management.patch299
-rw-r--r--usb/usb-at91-udc-updates-mostly-power-management.patch405
-rw-r--r--usb/usb-fix-pointer-dereference-in-drivers-usb-misc-usblcd.patch32
-rw-r--r--usb/usb-kill-compiler-warning-in-quirk_usb_handoff_ohci.patch53
-rw-r--r--usb/usb-move-linux-usb_otg.h-to-linux-usb-otg.h.patch333
-rw-r--r--usb/usb-ohci-controller-support-for-pnx4008.patch545
-rw-r--r--usb/usb-ohci-s3c2410.c-clock-now-usb-bus-host.patch40
-rw-r--r--usb/usb-pxa2xx_udc-understands-gpio-based-vbus-sensing.patch231
-rw-r--r--usb/usb-serial-ftdi_sio-prevent-userspace-dos.patch234
-rw-r--r--usb/usb-serial-visor-fix-race-in-open-close.patch45
-rw-r--r--usb/usb-storage-uname-in-pr-sc-unneeded-message.patch48
-rw-r--r--usb/usb-storage-us_fl_max_sectors_64-flag.patch109
-rw-r--r--usb/usb-unusual_devs-entry-for-samsung-mp3-player.patch39
-rw-r--r--usb/usbcore-fixes-for-hub_port_resume.patch37
-rw-r--r--usb/usbip.patch2
17 files changed, 2623 insertions, 1 deletions
diff --git a/usb/usb-add-driver-for-non-composite-sierra-wireless-devices.patch b/usb/usb-add-driver-for-non-composite-sierra-wireless-devices.patch
new file mode 100644
index 0000000000000..08036c7b0f3dd
--- /dev/null
+++ b/usb/usb-add-driver-for-non-composite-sierra-wireless-devices.patch
@@ -0,0 +1,132 @@
+From klloyd@airprime.com Fri Jun 30 11:18:46 2006
+From: "Kevin Lloyd" <klloyd@sierrawireless.com>
+Subject: USB: add driver for non-composite Sierra Wireless devices
+Date: Fri, 30 Jun 2006 11:17:55 -0700
+Message-ID: <3415E2A2AB26944B9159CDB22001004D2C90EC@nestea.sierrawireless.local>
+To: "Greg KH" <gregkh@suse.de>
+Cc: "Kevin Lloyd" <klloyd@sierrawireless.com>
+
+From: Kevin Lloyd <linux@sierrawireless.com>
+
+This patch creates a new driver, sierra.c, that supports the new
+non-composite Sierra Wireless WWAN devices. The older Sierra
+Wireless and Airprime devices are supported in airprime.c.
+
+Signed-off-by: Kevin Lloyd <linux@sierrawireless.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/serial/Kconfig | 11 ++++++
+ drivers/usb/serial/Makefile | 1
+ drivers/usb/serial/sierra.c | 75 ++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 87 insertions(+)
+
+--- gregkh-2.6.orig/drivers/usb/serial/Kconfig
++++ gregkh-2.6/drivers/usb/serial/Kconfig
+@@ -456,6 +456,17 @@ config USB_SERIAL_SAFE_PADDED
+ bool "USB Secure Encapsulated Driver - Padded"
+ depends on USB_SERIAL_SAFE
+
++config USB_SERIAL_SIERRAWIRELESS
++ tristate "USB Sierra Wireless Driver"
++ depends on USB_SERIAL
++ help
++ Say M here if you want to use a Sierra Wireless device (if
++ using an PC 5220 or AC580 please use the Airprime driver
++ instead).
++
++ To compile this driver as a module, choose M here: the
++ module will be called sierra.
++
+ config USB_SERIAL_TI
+ tristate "USB TI 3410/5052 Serial Driver"
+ depends on USB_SERIAL
+--- gregkh-2.6.orig/drivers/usb/serial/Makefile
++++ gregkh-2.6/drivers/usb/serial/Makefile
+@@ -39,6 +39,7 @@ obj-$(CONFIG_USB_SERIAL_OMNINET) += omn
+ obj-$(CONFIG_USB_SERIAL_OPTION) += option.o
+ obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o
+ obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o
++obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o
+ obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o
+ obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o
+ obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o
+--- /dev/null
++++ gregkh-2.6/drivers/usb/serial/sierra.c
+@@ -0,0 +1,75 @@
++/*
++ * Sierra Wireless CDMA Wireless Serial USB driver
++ *
++ * Current Copy modified by: Kevin Lloyd <linux@sierrawireless.com>
++ * Original Copyright (C) 2005-2006 Greg Kroah-Hartman <gregkh@suse.de>
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License version
++ * 2 as published by the Free Software Foundation.
++ */
++
++#include <linux/kernel.h>
++#include <linux/init.h>
++#include <linux/tty.h>
++#include <linux/module.h>
++#include <linux/usb.h>
++#include "usb-serial.h"
++
++static struct usb_device_id id_table [] = {
++ { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */
++ { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */
++ { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */
++ { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */
++ { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */
++ { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
++ { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */
++ { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
++ /* Following devices are supported in the airprime.c driver */
++ /* { USB_DEVICE(0x1199, 0x0112) }, */ /* Sierra Wireless AirCard 580 */
++ /* { USB_DEVICE(0x0F3D, 0x0112) }, */ /* AirPrime/Sierra PC 5220 */
++ { }
++};
++MODULE_DEVICE_TABLE(usb, id_table);
++
++static struct usb_driver sierra_driver = {
++ .name = "sierra_wireless",
++ .probe = usb_serial_probe,
++ .disconnect = usb_serial_disconnect,
++ .id_table = id_table,
++};
++
++static struct usb_serial_driver sierra_device = {
++ .driver = {
++ .owner = THIS_MODULE,
++ .name = "Sierra_Wireless",
++ },
++ .id_table = id_table,
++ .num_interrupt_in = NUM_DONT_CARE,
++ .num_bulk_in = NUM_DONT_CARE,
++ .num_bulk_out = NUM_DONT_CARE,
++ .num_ports = 3,
++};
++
++static int __init sierra_init(void)
++{
++ int retval;
++
++ retval = usb_serial_register(&sierra_device);
++ if (retval)
++ return retval;
++ retval = usb_register(&sierra_driver);
++ if (retval)
++ usb_serial_deregister(&sierra_device);
++ return retval;
++}
++
++static void __exit sierra_exit(void)
++{
++ usb_deregister(&sierra_driver);
++ usb_serial_deregister(&sierra_device);
++}
++
++module_init(sierra_init);
++module_exit(sierra_exit);
++MODULE_LICENSE("GPL");
diff --git a/usb/usb-allow-compile-in-g_ether-fix-typo.patch b/usb/usb-allow-compile-in-g_ether-fix-typo.patch
new file mode 100644
index 0000000000000..023fb1713c590
--- /dev/null
+++ b/usb/usb-allow-compile-in-g_ether-fix-typo.patch
@@ -0,0 +1,40 @@
+From david-b@pacbell.net Thu Jun 29 22:27:40 2006
+From: Tony Lindgren <tony@atomide.com>
+Subject: USB: Allow compile in g_ether, fix typo
+Date: Thu, 29 Jun 2006 22:27:36 -0700
+To: Greg KH <greg@kroah.com>
+Cc: Tony Lindgren <tony@atomide.com>
+Message-Id: <200606292227.36598.david-b@pacbell.net>
+
+From: Tony Lindgren <tony@atomide.com>
+
+Allows compiling g_ether in and fixes a typo with MUSB_HDRC
+
+Signed-off-by: Tony Lindgren <tony@atomide.com>
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/ether.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/gadget/ether.c
++++ gregkh-2.6/drivers/usb/gadget/ether.c
+@@ -261,7 +261,7 @@ MODULE_PARM_DESC(host_addr, "Host Ethern
+ #define DEV_CONFIG_CDC
+ #endif
+
+-#ifdef CONFIG_USB_GADGET_MUSBHDRC
++#ifdef CONFIG_USB_GADGET_MUSB_HDRC
+ #define DEV_CONFIG_CDC
+ #endif
+
+@@ -2548,7 +2548,7 @@ static struct usb_gadget_driver eth_driv
+
+ .function = (char *) driver_desc,
+ .bind = eth_bind,
+- .unbind = __exit_p(eth_unbind),
++ .unbind = eth_unbind,
+
+ .setup = eth_setup,
+ .disconnect = eth_disconnect,
diff --git a/usb/usb-at91-ohci-updates-mostly-power-management.patch b/usb/usb-at91-ohci-updates-mostly-power-management.patch
new file mode 100644
index 0000000000000..9d8b0efb3ad0b
--- /dev/null
+++ b/usb/usb-at91-ohci-updates-mostly-power-management.patch
@@ -0,0 +1,299 @@
+From david-b@pacbell.net Mon Jun 19 14:31:06 2006
+From: David Brownell <david-b@pacbell.net>
+To: Greg KH <greg@kroah.com>
+Subject: USB: AT91 OHCI updates, mostly power management
+Date: Mon, 19 Jun 2006 14:27:20 -0700
+Cc: Andrew Victor <andrew@sanpeople.com>
+Message-Id: <200606191427.20871.david-b@pacbell.net>
+
+OHCI updates for AT91 series processors:
+
+ - Get ready for at91sam926x processors (ARMv5tej not ARMv4t)
+
+ - Suspend/resume support now behaves properly
+
+ - In "standby" mode, OHCI can be a source of system wakeup events
+ (remote wakeup, device connect/disconnect, etc)
+
+And minor cleanups.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Andrew Victor <andrew@sanpeople.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/Kconfig | 2
+ drivers/usb/host/ohci-at91.c | 88 ++++++++++++++++++++++++++++---------------
+ drivers/usb/host/ohci-hcd.c | 3 -
+ 3 files changed, 62 insertions(+), 31 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/Kconfig
++++ gregkh-2.6/drivers/usb/Kconfig
+@@ -24,7 +24,7 @@ config USB_ARCH_HAS_OHCI
+ default y if ARCH_S3C2410
+ default y if PXA27x
+ default y if ARCH_EP93XX
+- default y if ARCH_AT91RM9200
++ default y if (ARCH_AT91RM9200 || ARCH_AT91SAM9261)
+ # PPC:
+ default y if STB03xxx
+ default y if PPC_MPC52xx
+--- gregkh-2.6.orig/drivers/usb/host/ohci-at91.c
++++ gregkh-2.6/drivers/usb/host/ohci-at91.c
+@@ -4,7 +4,7 @@
+ * Copyright (C) 2004 SAN People (Pty) Ltd.
+ * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
+ *
+- * AT91RM9200 Bus Glue
++ * AT91 Bus Glue
+ *
+ * Based on fragments of 2.4 driver by Rick Bronson.
+ * Based on ohci-omap.c
+@@ -19,12 +19,13 @@
+ #include <asm/hardware.h>
+ #include <asm/arch/board.h>
+
+-#ifndef CONFIG_ARCH_AT91RM9200
+-#error "CONFIG_ARCH_AT91RM9200 must be defined."
++#ifndef CONFIG_ARCH_AT91
++#error "CONFIG_ARCH_AT91 must be defined."
+ #endif
+
+ /* interface and function clocks */
+ static struct clk *iclk, *fclk;
++static int clocked;
+
+ extern int usb_disabled(void);
+
+@@ -35,13 +36,14 @@ static void at91_start_hc(struct platfor
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct ohci_regs __iomem *regs = hcd->regs;
+
+- dev_dbg(&pdev->dev, "starting AT91RM9200 OHCI USB Controller\n");
++ dev_dbg(&pdev->dev, "start\n");
+
+ /*
+ * Start the USB clocks.
+ */
+ clk_enable(iclk);
+ clk_enable(fclk);
++ clocked = 1;
+
+ /*
+ * The USB host controller must remain in reset.
+@@ -54,7 +56,7 @@ static void at91_stop_hc(struct platform
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ struct ohci_regs __iomem *regs = hcd->regs;
+
+- dev_dbg(&pdev->dev, "stopping AT91RM9200 OHCI USB Controller\n");
++ dev_dbg(&pdev->dev, "stop\n");
+
+ /*
+ * Put the USB host controller into reset.
+@@ -66,6 +68,7 @@ static void at91_stop_hc(struct platform
+ */
+ clk_disable(fclk);
+ clk_disable(iclk);
++ clocked = 0;
+ }
+
+
+@@ -78,14 +81,15 @@ static int usb_hcd_at91_remove (struct u
+
+
+ /**
+- * usb_hcd_at91_probe - initialize AT91RM9200-based HCDs
++ * usb_hcd_at91_probe - initialize AT91-based HCDs
+ * Context: !in_interrupt()
+ *
+ * Allocates basic resources for this USB host controller, and
+ * then invokes the start() method for the HCD associated with it
+ * through the hotplug entry's driver_data.
+ */
+-int usb_hcd_at91_probe (const struct hc_driver *driver, struct platform_device *pdev)
++static int usb_hcd_at91_probe(const struct hc_driver *driver,
++ struct platform_device *pdev)
+ {
+ int retval;
+ struct usb_hcd *hcd = NULL;
+@@ -95,12 +99,13 @@ int usb_hcd_at91_probe (const struct hc_
+ return -ENODEV;
+ }
+
+- if ((pdev->resource[0].flags != IORESOURCE_MEM) || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
++ if ((pdev->resource[0].flags != IORESOURCE_MEM)
++ || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
+ pr_debug("hcd probe: invalid resource type\n");
+ return -ENODEV;
+ }
+
+- hcd = usb_create_hcd(driver, &pdev->dev, "at91rm9200");
++ hcd = usb_create_hcd(driver, &pdev->dev, "at91");
+ if (!hcd)
+ return -ENOMEM;
+ hcd->rsrc_start = pdev->resource[0].start;
+@@ -149,21 +154,23 @@ int usb_hcd_at91_probe (const struct hc_
+ /* may be called with controller, bus, and devices active */
+
+ /**
+- * usb_hcd_at91_remove - shutdown processing for AT91RM9200-based HCDs
++ * usb_hcd_at91_remove - shutdown processing for AT91-based HCDs
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_hcd_at91_probe(), first invoking
+ * the HCD's stop() method. It is always called from a thread
+- * context, normally "rmmod", "apmd", or something similar.
++ * context, "rmmod" or something similar.
+ *
+ */
+-static int usb_hcd_at91_remove (struct usb_hcd *hcd, struct platform_device *pdev)
++static int usb_hcd_at91_remove(struct usb_hcd *hcd,
++ struct platform_device *pdev)
+ {
+ usb_remove_hcd(hcd);
+ at91_stop_hc(pdev);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++ disable_irq_wake(hcd->irq);
+
+ clk_put(fclk);
+ clk_put(iclk);
+@@ -178,19 +185,21 @@ static int usb_hcd_at91_remove (struct u
+ static int __devinit
+ ohci_at91_start (struct usb_hcd *hcd)
+ {
+-// struct at91_ohci_data *board = hcd->self.controller->platform_data;
++ struct at91_usbh_data *board = hcd->self.controller->platform_data;
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
++ struct usb_device *root = hcd->self.root_hub;
+ int ret;
+
+ if ((ret = ohci_init(ohci)) < 0)
+ return ret;
+
++ root->maxchild = board->ports;
++
+ if ((ret = ohci_run(ohci)) < 0) {
+ err("can't start %s", hcd->self.bus_name);
+ ohci_stop(hcd);
+ return ret;
+ }
+-// hcd->self.root_hub->maxchild = board->ports;
+ return 0;
+ }
+
+@@ -198,7 +207,7 @@ ohci_at91_start (struct usb_hcd *hcd)
+
+ static const struct hc_driver ohci_at91_hc_driver = {
+ .description = hcd_name,
+- .product_desc = "AT91RM9200 OHCI",
++ .product_desc = "AT91 OHCI",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
+
+ /*
+@@ -240,33 +249,54 @@ static const struct hc_driver ohci_at91_
+
+ /*-------------------------------------------------------------------------*/
+
+-static int ohci_hcd_at91_drv_probe(struct platform_device *dev)
++static int ohci_hcd_at91_drv_probe(struct platform_device *pdev)
+ {
+- return usb_hcd_at91_probe(&ohci_at91_hc_driver, dev);
++ device_init_wakeup(&pdev->dev, 1);
++ return usb_hcd_at91_probe(&ohci_at91_hc_driver, pdev);
+ }
+
+-static int ohci_hcd_at91_drv_remove(struct platform_device *dev)
++static int ohci_hcd_at91_drv_remove(struct platform_device *pdev)
+ {
+- return usb_hcd_at91_remove(platform_get_drvdata(dev), dev);
++ device_init_wakeup(&pdev->dev, 0);
++ return usb_hcd_at91_remove(platform_get_drvdata(pdev), pdev);
+ }
+
+ #ifdef CONFIG_PM
+
+-/* REVISIT suspend/resume look "too" simple here */
+-
+ static int
+-ohci_hcd_at91_drv_suspend(struct platform_device *dev, pm_message_t mesg)
++ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
+ {
+- clk_disable(fclk);
+- clk_disable(iclk);
++ struct usb_hcd *hcd = platform_get_drvdata(pdev);
++ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++
++ if (device_may_wakeup(&pdev->dev))
++ enable_irq_wake(hcd->irq);
++ else
++ disable_irq_wake(hcd->irq);
++
++ /*
++ * The integrated transceivers seem unable to notice disconnect,
++ * reconnect, or wakeup without the 48 MHz clock active. so for
++ * correctness, always discard connection state (using reset).
++ *
++ * REVISIT: some boards will be able to turn VBUS off...
++ */
++ if (at91_suspend_entering_slow_clock()) {
++ ohci_usb_reset (ohci);
++ clk_disable(fclk);
++ clk_disable(iclk);
++ clocked = 0;
++ }
+
+ return 0;
+ }
+
+-static int ohci_hcd_at91_drv_resume(struct platform_device *dev)
++static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
+ {
+- clk_enable(iclk);
+- clk_enable(fclk);
++ if (!clocked) {
++ clk_enable(iclk);
++ clk_enable(fclk);
++ }
+
+ return 0;
+ }
+@@ -275,7 +305,7 @@ static int ohci_hcd_at91_drv_resume(stru
+ #define ohci_hcd_at91_drv_resume NULL
+ #endif
+
+-MODULE_ALIAS("at91rm9200-ohci");
++MODULE_ALIAS("at91_ohci");
+
+ static struct platform_driver ohci_hcd_at91_driver = {
+ .probe = ohci_hcd_at91_drv_probe,
+@@ -283,7 +313,7 @@ static struct platform_driver ohci_hcd_a
+ .suspend = ohci_hcd_at91_drv_suspend,
+ .resume = ohci_hcd_at91_drv_resume,
+ .driver = {
+- .name = "at91rm9200-ohci",
++ .name = "at91_ohci",
+ .owner = THIS_MODULE,
+ },
+ };
+--- gregkh-2.6.orig/drivers/usb/host/ohci-hcd.c
++++ gregkh-2.6/drivers/usb/host/ohci-hcd.c
+@@ -924,7 +924,7 @@ MODULE_LICENSE ("GPL");
+ #include "ohci-ppc-soc.c"
+ #endif
+
+-#ifdef CONFIG_ARCH_AT91RM9200
++#if defined(CONFIG_ARCH_AT91RM9200) || defined(CONFIG_ARCH_AT91SAM9261)
+ #include "ohci-at91.c"
+ #endif
+
+@@ -938,6 +938,7 @@ MODULE_LICENSE ("GPL");
+ || defined (CONFIG_SOC_AU1X00) \
+ || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
+ || defined (CONFIG_ARCH_AT91RM9200) \
++ || defined (CONFIG_ARCH_AT91SAM9261) \
+ )
+ #error "missing bus glue for ohci-hcd"
+ #endif
diff --git a/usb/usb-at91-udc-updates-mostly-power-management.patch b/usb/usb-at91-udc-updates-mostly-power-management.patch
new file mode 100644
index 0000000000000..1d0a3bc25adc4
--- /dev/null
+++ b/usb/usb-at91-udc-updates-mostly-power-management.patch
@@ -0,0 +1,405 @@
+From david-b@pacbell.net Mon Jun 19 14:31:06 2006
+From: David Brownell <david-b@pacbell.net>
+To: Greg KH <greg@kroah.com>
+Subject: USB: AT91 UDC updates, mostly power management
+Date: Mon, 19 Jun 2006 14:25:11 -0700
+Cc: Andrew Victor <andrew@sanpeople.com>
+Message-Id: <200606191425.11737.david-b@pacbell.net>
+
+
+UDC updates for AT91 series processors:
+
+ - Get ready for at91sam926x processors (ARMv5tej not ARMv4t)
+
+ - Suspend/resume support now behaves properly
+
+ - In "standby" mode, UDC can be a source of system wakeup events
+ (host resume, device connect/disconnect, etc)
+
+ - Fix a startup problem that crept in with the initial merge
+
+And minor cleanups, especially whitespace.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Andrew Victor <andrew@sanpeople.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/gadget/at91_udc.c | 157 +++++++++++++++++++++++++-----------------
+ drivers/usb/gadget/at91_udc.h | 1
+ 2 files changed, 98 insertions(+), 60 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/gadget/at91_udc.c
++++ gregkh-2.6/drivers/usb/gadget/at91_udc.c
+@@ -70,7 +70,7 @@
+ * power. During USB suspend, the 48 MHz clock is gated off.
+ */
+
+-#define DRIVER_VERSION "8 March 2005"
++#define DRIVER_VERSION "3 May 2006"
+
+ static const char driver_name [] = "at91_udc";
+ static const char ep0name[] = "ep0";
+@@ -319,7 +319,8 @@ static void done(struct at91_ep *ep, str
+ * that shouldn't normally be changed.
+ */
+ #define SET_FX (AT91_UDP_TXPKTRDY)
+-#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)
++#define CLR_FX (RX_DATA_READY | AT91_UDP_RXSETUP \
++ | AT91_UDP_STALLSENT | AT91_UDP_TXCOMP)
+
+ /* pull OUT packet data from the endpoint's fifo */
+ static int read_fifo (struct at91_ep *ep, struct at91_request *req)
+@@ -473,7 +474,8 @@ static void nuke(struct at91_ep *ep, int
+
+ /*-------------------------------------------------------------------------*/
+
+-static int at91_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
++static int at91_ep_enable(struct usb_ep *_ep,
++ const struct usb_endpoint_descriptor *desc)
+ {
+ struct at91_ep *ep = container_of(_ep, struct at91_ep, ep);
+ struct at91_udc *dev = ep->udc;
+@@ -583,11 +585,12 @@ static int at91_ep_disable (struct usb_e
+ * interesting for request or buffer allocation.
+ */
+
+-static struct usb_request *at91_ep_alloc_request (struct usb_ep *_ep, unsigned int gfp_flags)
++static struct usb_request *
++at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags)
+ {
+ struct at91_request *req;
+
+- req = kcalloc(1, sizeof (struct at91_request), SLAB_KERNEL);
++ req = kcalloc(1, sizeof (struct at91_request), gfp_flags);
+ if (!req)
+ return NULL;
+
+@@ -890,8 +893,8 @@ static void clk_off(struct at91_udc *udc
+ return;
+ udc->clocked = 0;
+ udc->gadget.speed = USB_SPEED_UNKNOWN;
+- clk_disable(udc->iclk);
+ clk_disable(udc->fclk);
++ clk_disable(udc->iclk);
+ }
+
+ /*
+@@ -912,9 +915,6 @@ static void pullup(struct at91_udc *udc,
+ at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
+ at91_set_gpio_value(udc->board.pullup_pin, 0);
+ clk_off(udc);
+-
+- // REVISIT: with transceiver disabled, will D- float
+- // so that a host would falsely detect a device?
+ }
+ }
+
+@@ -1291,7 +1291,8 @@ static void handle_ep0(struct at91_udc *
+ if (udc->wait_for_addr_ack) {
+ u32 tmp;
+
+- at91_udp_write(AT91_UDP_FADDR, AT91_UDP_FEN | udc->addr);
++ at91_udp_write(AT91_UDP_FADDR,
++ AT91_UDP_FEN | udc->addr);
+ tmp = at91_udp_read(AT91_UDP_GLB_STAT);
+ tmp &= ~AT91_UDP_FADDEN;
+ if (udc->addr)
+@@ -1362,9 +1363,10 @@ static irqreturn_t at91_udc_irq (int irq
+ u32 rescans = 5;
+
+ while (rescans--) {
+- u32 status = at91_udp_read(AT91_UDP_ISR);
++ u32 status;
+
+- status &= at91_udp_read(AT91_UDP_IMR);
++ status = at91_udp_read(AT91_UDP_ISR)
++ & at91_udp_read(AT91_UDP_IMR);
+ if (!status)
+ break;
+
+@@ -1380,18 +1382,17 @@ static irqreturn_t at91_udc_irq (int irq
+ stop_activity(udc);
+
+ /* enable ep0 */
+- at91_udp_write(AT91_UDP_CSR(0), AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
++ at91_udp_write(AT91_UDP_CSR(0),
++ AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL);
+ udc->gadget.speed = USB_SPEED_FULL;
+ udc->suspended = 0;
+ at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0));
+
+ /*
+ * NOTE: this driver keeps clocks off unless the
+- * USB host is present. That saves power, and also
+- * eliminates IRQs (reset, resume, suspend) that can
+- * otherwise flood from the controller. If your
+- * board doesn't support VBUS detection, suspend and
+- * resume irq logic may need more attention...
++ * USB host is present. That saves power, but for
++ * boards that don't support VBUS detection, both
++ * clocks need to be active most of the time.
+ */
+
+ /* host initiated suspend (3+ms bus idle) */
+@@ -1453,13 +1454,19 @@ static irqreturn_t at91_udc_irq (int irq
+
+ /*-------------------------------------------------------------------------*/
+
++static void nop_release(struct device *dev)
++{
++ /* nothing to free */
++}
++
+ static struct at91_udc controller = {
+ .gadget = {
+- .ops = &at91_udc_ops,
+- .ep0 = &controller.ep[0].ep,
+- .name = driver_name,
+- .dev = {
+- .bus_id = "gadget"
++ .ops = &at91_udc_ops,
++ .ep0 = &controller.ep[0].ep,
++ .name = driver_name,
++ .dev = {
++ .bus_id = "gadget",
++ .release = nop_release,
+ }
+ },
+ .ep[0] = {
+@@ -1469,7 +1476,8 @@ static struct at91_udc controller = {
+ },
+ .udc = &controller,
+ .maxpacket = 8,
+- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(0)),
++ .creg = (void __iomem *)(AT91_VA_BASE_UDP
++ + AT91_UDP_CSR(0)),
+ .int_mask = 1 << 0,
+ },
+ .ep[1] = {
+@@ -1480,7 +1488,8 @@ static struct at91_udc controller = {
+ .udc = &controller,
+ .is_pingpong = 1,
+ .maxpacket = 64,
+- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(1)),
++ .creg = (void __iomem *)(AT91_VA_BASE_UDP
++ + AT91_UDP_CSR(1)),
+ .int_mask = 1 << 1,
+ },
+ .ep[2] = {
+@@ -1491,7 +1500,8 @@ static struct at91_udc controller = {
+ .udc = &controller,
+ .is_pingpong = 1,
+ .maxpacket = 64,
+- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(2)),
++ .creg = (void __iomem *)(AT91_VA_BASE_UDP
++ + AT91_UDP_CSR(2)),
+ .int_mask = 1 << 2,
+ },
+ .ep[3] = {
+@@ -1502,7 +1512,8 @@ static struct at91_udc controller = {
+ },
+ .udc = &controller,
+ .maxpacket = 8,
+- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(3)),
++ .creg = (void __iomem *)(AT91_VA_BASE_UDP
++ + AT91_UDP_CSR(3)),
+ .int_mask = 1 << 3,
+ },
+ .ep[4] = {
+@@ -1513,7 +1524,8 @@ static struct at91_udc controller = {
+ .udc = &controller,
+ .is_pingpong = 1,
+ .maxpacket = 256,
+- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(4)),
++ .creg = (void __iomem *)(AT91_VA_BASE_UDP
++ + AT91_UDP_CSR(4)),
+ .int_mask = 1 << 4,
+ },
+ .ep[5] = {
+@@ -1524,10 +1536,11 @@ static struct at91_udc controller = {
+ .udc = &controller,
+ .is_pingpong = 1,
+ .maxpacket = 256,
+- .creg = (void __iomem *)(AT91_VA_BASE_UDP + AT91_UDP_CSR(5)),
++ .creg = (void __iomem *)(AT91_VA_BASE_UDP
++ + AT91_UDP_CSR(5)),
+ .int_mask = 1 << 5,
+ },
+- /* ep6 and ep7 are also reserved */
++ /* ep6 and ep7 are also reserved (custom silicon might use them) */
+ };
+
+ static irqreturn_t at91_vbus_irq(int irq, void *_udc, struct pt_regs *r)
+@@ -1625,6 +1638,16 @@ static int __devinit at91udc_probe(struc
+ return -ENODEV;
+ }
+
++ if (pdev->num_resources != 2) {
++ DBG("invalid num_resources");
++ return -ENODEV;
++ }
++ if ((pdev->resource[0].flags != IORESOURCE_MEM)
++ || (pdev->resource[1].flags != IORESOURCE_IRQ)) {
++ DBG("invalid resource type");
++ return -ENODEV;
++ }
++
+ if (!request_mem_region(AT91_BASE_UDP, SZ_16K, driver_name)) {
+ DBG("someone's using UDC memory\n");
+ return -EBUSY;
+@@ -1650,19 +1673,26 @@ static int __devinit at91udc_probe(struc
+ if (retval < 0)
+ goto fail0;
+
+- /* disable everything until there's a gadget driver and vbus */
+- pullup(udc, 0);
++ /* don't do anything until we have both gadget driver and VBUS */
++ clk_enable(udc->iclk);
++ at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
++ at91_udp_write(AT91_UDP_IDR, 0xffffffff);
++ clk_disable(udc->iclk);
+
+ /* request UDC and maybe VBUS irqs */
+- if (request_irq(AT91_ID_UDP, at91_udc_irq, SA_INTERRUPT, driver_name, udc)) {
+- DBG("request irq %d failed\n", AT91_ID_UDP);
++ udc->udp_irq = platform_get_irq(pdev, 0);
++ if (request_irq(udc->udp_irq, at91_udc_irq,
++ SA_INTERRUPT, driver_name, udc)) {
++ DBG("request irq %d failed\n", udc->udp_irq);
+ retval = -EBUSY;
+ goto fail1;
+ }
+ if (udc->board.vbus_pin > 0) {
+- if (request_irq(udc->board.vbus_pin, at91_vbus_irq, SA_INTERRUPT, driver_name, udc)) {
+- DBG("request vbus irq %d failed\n", udc->board.vbus_pin);
+- free_irq(AT91_ID_UDP, udc);
++ if (request_irq(udc->board.vbus_pin, at91_vbus_irq,
++ SA_INTERRUPT, driver_name, udc)) {
++ DBG("request vbus irq %d failed\n",
++ udc->board.vbus_pin);
++ free_irq(udc->udp_irq, udc);
+ retval = -EBUSY;
+ goto fail1;
+ }
+@@ -1671,6 +1701,7 @@ static int __devinit at91udc_probe(struc
+ udc->vbus = 1;
+ }
+ dev_set_drvdata(dev, udc);
++ device_init_wakeup(dev, 1);
+ create_debug_file(udc);
+
+ INFO("%s version %s\n", driver_name, DRIVER_VERSION);
+@@ -1679,14 +1710,14 @@ static int __devinit at91udc_probe(struc
+ fail1:
+ device_unregister(&udc->gadget.dev);
+ fail0:
+- release_mem_region(AT91_VA_BASE_UDP, SZ_16K);
++ release_mem_region(AT91_BASE_UDP, SZ_16K);
+ DBG("%s probe failed, %d\n", driver_name, retval);
+ return retval;
+ }
+
+-static int __devexit at91udc_remove(struct platform_device *dev)
++static int __devexit at91udc_remove(struct platform_device *pdev)
+ {
+- struct at91_udc *udc = platform_get_drvdata(dev);
++ struct at91_udc *udc = platform_get_drvdata(pdev);
+
+ DBG("remove\n");
+
+@@ -1695,10 +1726,11 @@ static int __devexit at91udc_remove(stru
+ if (udc->driver != 0)
+ usb_gadget_unregister_driver(udc->driver);
+
++ device_init_wakeup(&pdev->dev, 0);
+ remove_debug_file(udc);
+ if (udc->board.vbus_pin > 0)
+ free_irq(udc->board.vbus_pin, udc);
+- free_irq(AT91_ID_UDP, udc);
++ free_irq(udc->udp_irq, udc);
+ device_unregister(&udc->gadget.dev);
+ release_mem_region(AT91_BASE_UDP, SZ_16K);
+
+@@ -1709,31 +1741,36 @@ static int __devexit at91udc_remove(stru
+ }
+
+ #ifdef CONFIG_PM
+-static int at91udc_suspend(struct platform_device *dev, pm_message_t mesg)
++static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg)
+ {
+- struct at91_udc *udc = platform_get_drvdata(dev);
++ struct at91_udc *udc = platform_get_drvdata(pdev);
++ int wake = udc->driver && device_may_wakeup(&pdev->dev);
+
+- /*
+- * The "safe" suspend transitions are opportunistic ... e.g. when
+- * the USB link is suspended (48MHz clock autogated off), or when
+- * it's disconnected (programmatically gated off, elsewhere).
+- * Then we can suspend, and the chip can enter slow clock mode.
+- *
+- * The problem case is some component (user mode?) suspending this
+- * device while it's active, with the 48 MHz clock in use. There
+- * are two basic approaches: (a) veto suspend levels involving slow
+- * clock mode, (b) disconnect, so 48 MHz will no longer be in use
+- * and we can enter slow clock mode. This uses (b) for now, since
+- * it's simplest until AT91 PM exists and supports the other option.
++ /* Unless we can act normally to the host (letting it wake us up
++ * whenever it has work for us) force disconnect. Wakeup requires
++ * PLLB for USB events (signaling for reset, wakeup, or incoming
++ * tokens) and VBUS irqs (on systems which support them).
+ */
+- if (udc->vbus && !udc->suspended)
++ if ((!udc->suspended && udc->addr)
++ || !wake
++ || at91_suspend_entering_slow_clock()) {
+ pullup(udc, 0);
++ disable_irq_wake(udc->udp_irq);
++ } else
++ enable_irq_wake(udc->udp_irq);
++
++ if (udc->board.vbus_pin > 0) {
++ if (wake)
++ enable_irq_wake(udc->board.vbus_pin);
++ else
++ disable_irq_wake(udc->board.vbus_pin);
++ }
+ return 0;
+ }
+
+-static int at91udc_resume(struct platform_device *dev)
++static int at91udc_resume(struct platform_device *pdev)
+ {
+- struct at91_udc *udc = platform_get_drvdata(dev);
++ struct at91_udc *udc = platform_get_drvdata(pdev);
+
+ /* maybe reconnect to host; if so, clocks on */
+ pullup(udc, 1);
+@@ -1749,7 +1786,7 @@ static struct platform_driver at91_udc =
+ .remove = __devexit_p(at91udc_remove),
+ .shutdown = at91udc_shutdown,
+ .suspend = at91udc_suspend,
+- .resume = at91udc_resume,
++ .resume = at91udc_resume,
+ .driver = {
+ .name = (char *) driver_name,
+ .owner = THIS_MODULE,
+@@ -1768,6 +1805,6 @@ static void __devexit udc_exit_module(vo
+ }
+ module_exit(udc_exit_module);
+
+-MODULE_DESCRIPTION("AT91RM9200 udc driver");
++MODULE_DESCRIPTION("AT91 udc driver");
+ MODULE_AUTHOR("Thomas Rathbone, David Brownell");
+ MODULE_LICENSE("GPL");
+--- gregkh-2.6.orig/drivers/usb/gadget/at91_udc.h
++++ gregkh-2.6/drivers/usb/gadget/at91_udc.h
+@@ -141,6 +141,7 @@ struct at91_udc {
+ struct clk *iclk, *fclk;
+ struct platform_device *pdev;
+ struct proc_dir_entry *pde;
++ int udp_irq;
+ };
+
+ static inline struct at91_udc *to_udc(struct usb_gadget *g)
diff --git a/usb/usb-fix-pointer-dereference-in-drivers-usb-misc-usblcd.patch b/usb/usb-fix-pointer-dereference-in-drivers-usb-misc-usblcd.patch
new file mode 100644
index 0000000000000..d4c86c4c4ddd3
--- /dev/null
+++ b/usb/usb-fix-pointer-dereference-in-drivers-usb-misc-usblcd.patch
@@ -0,0 +1,32 @@
+From linux-kernel-owner+greg=40kroah.com-S933309AbWFZW6V@vger.kernel.org Mon Jun 26 16:19:13 2006
+From: Eric Sesterhenn <snakebyte@gmx.de>
+Subject: USB: fix pointer dereference in drivers/usb/misc/usblcd
+Cc: <g.toth@e-biz.lu>
+Date: Tue, 27 Jun 2006 00:57:42 +0200
+Message-Id: <1151362662.15204.7.camel@alice>
+
+coverity spotted (id #185) that we still use urb, if the allocation
+fails in the error path. This patch fixes this by returning directly.
+
+Signed-off-by: Eric Sesterhenn <snakebyte@gmx.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/misc/usblcd.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/misc/usblcd.c
++++ gregkh-2.6/drivers/usb/misc/usblcd.c
+@@ -200,10 +200,8 @@ static ssize_t lcd_write(struct file *fi
+
+ /* create a urb, and a buffer for it, and copy the data to the urb */
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+- if (!urb) {
+- retval = -ENOMEM;
+- goto error;
+- }
++ if (!urb)
++ return -ENOMEM;
+
+ buf = usb_buffer_alloc(dev->udev, count, GFP_KERNEL, &urb->transfer_dma);
+ if (!buf) {
diff --git a/usb/usb-kill-compiler-warning-in-quirk_usb_handoff_ohci.patch b/usb/usb-kill-compiler-warning-in-quirk_usb_handoff_ohci.patch
new file mode 100644
index 0000000000000..e290f4ce265f3
--- /dev/null
+++ b/usb/usb-kill-compiler-warning-in-quirk_usb_handoff_ohci.patch
@@ -0,0 +1,53 @@
+From kyle@athena.road.mcmartin.ca Tue Jun 27 09:11:48 2006
+Date: Sun, 25 Jun 2006 18:45:29 -0400
+From: Kyle McMartin <kyle@mcmartin.ca>
+To: gregkh@suse.de
+Subject: USB: Kill compiler warning in quirk_usb_handoff_ohci
+Message-ID: <20060625224529.GB2837@athena.road.mcmartin.ca>
+Content-Disposition: inline
+
+From: Kyle McMartin <kyle@parisc-linux.org>
+
+Move variables only used on !__hppa__ into that #ifndef section. This
+cleans up a compiler warning on parisc. Problem pointed out by
+Joel Soete.
+
+Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/pci-quirks.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/host/pci-quirks.c
++++ gregkh-2.6/drivers/usb/host/pci-quirks.c
+@@ -168,8 +168,6 @@ static int __devinit mmio_resource_enabl
+ static void __devinit quirk_usb_handoff_ohci(struct pci_dev *pdev)
+ {
+ void __iomem *base;
+- int wait_time;
+- u32 control;
+
+ if (!mmio_resource_enabled(pdev, 0))
+ return;
+@@ -180,9 +178,10 @@ static void __devinit quirk_usb_handoff_
+
+ /* On PA-RISC, PDC can leave IR set incorrectly; ignore it there. */
+ #ifndef __hppa__
+- control = readl(base + OHCI_CONTROL);
++{
++ u32 control = readl(base + OHCI_CONTROL);
+ if (control & OHCI_CTRL_IR) {
+- wait_time = 500; /* arbitrary; 5 seconds */
++ int wait_time = 500; /* arbitrary; 5 seconds */
+ writel(OHCI_INTR_OC, base + OHCI_INTRENABLE);
+ writel(OHCI_OCR, base + OHCI_CMDSTATUS);
+ while (wait_time > 0 &&
+@@ -199,6 +198,7 @@ static void __devinit quirk_usb_handoff_
+ /* reset controller, preserving RWC */
+ writel(control & OHCI_CTRL_RWC, base + OHCI_CONTROL);
+ }
++}
+ #endif
+
+ /*
diff --git a/usb/usb-move-linux-usb_otg.h-to-linux-usb-otg.h.patch b/usb/usb-move-linux-usb_otg.h-to-linux-usb-otg.h.patch
new file mode 100644
index 0000000000000..b07d5522c46b9
--- /dev/null
+++ b/usb/usb-move-linux-usb_otg.h-to-linux-usb-otg.h.patch
@@ -0,0 +1,333 @@
+From david-b@pacbell.net Thu Jun 29 14:02:38 2006
+From: David Brownell <david-b@pacbell.net>
+To: Greg KH <greg@kroah.com>
+Subject: USB: move <linux/usb_otg.h> to <linux/usb/otg.h>
+Date: Thu, 29 Jun 2006 12:27:23 -0700
+Message-Id: <200606291227.24267.david-b@pacbell.net>
+
+Move <linux/usb_otg.h> to <linux/usb/otg.h>.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/arm/plat-omap/usb.c | 2
+ drivers/i2c/chips/isp1301_omap.c | 2
+ drivers/usb/gadget/omap_udc.c | 2
+ drivers/usb/host/ohci-hcd.c | 2
+ include/linux/usb/otg.h | 131 +++++++++++++++++++++++++++++++++++++++
+ include/linux/usb_otg.h | 131 ---------------------------------------
+ 6 files changed, 135 insertions(+), 135 deletions(-)
+
+--- gregkh-2.6.orig/arch/arm/plat-omap/usb.c
++++ gregkh-2.6/arch/arm/plat-omap/usb.c
+@@ -27,7 +27,7 @@
+ #include <linux/errno.h>
+ #include <linux/init.h>
+ #include <linux/platform_device.h>
+-#include <linux/usb_otg.h>
++#include <linux/usb/otg.h>
+
+ #include <asm/io.h>
+ #include <asm/irq.h>
+--- gregkh-2.6.orig/drivers/i2c/chips/isp1301_omap.c
++++ gregkh-2.6/drivers/i2c/chips/isp1301_omap.c
+@@ -31,7 +31,7 @@
+ #include <linux/usb_ch9.h>
+ #include <linux/usb_gadget.h>
+ #include <linux/usb.h>
+-#include <linux/usb_otg.h>
++#include <linux/usb/otg.h>
+ #include <linux/i2c.h>
+ #include <linux/workqueue.h>
+
+--- gregkh-2.6.orig/drivers/usb/gadget/omap_udc.c
++++ gregkh-2.6/drivers/usb/gadget/omap_udc.c
+@@ -41,7 +41,7 @@
+ #include <linux/platform_device.h>
+ #include <linux/usb_ch9.h>
+ #include <linux/usb_gadget.h>
+-#include <linux/usb_otg.h>
++#include <linux/usb/otg.h>
+ #include <linux/dma-mapping.h>
+
+ #include <asm/byteorder.h>
+--- gregkh-2.6.orig/drivers/usb/host/ohci-hcd.c
++++ gregkh-2.6/drivers/usb/host/ohci-hcd.c
+@@ -89,7 +89,7 @@
+ #include <linux/timer.h>
+ #include <linux/list.h>
+ #include <linux/usb.h>
+-#include <linux/usb_otg.h>
++#include <linux/usb/otg.h>
+ #include <linux/dma-mapping.h>
+ #include <linux/dmapool.h>
+ #include <linux/reboot.h>
+--- /dev/null
++++ gregkh-2.6/include/linux/usb/otg.h
+@@ -0,0 +1,131 @@
++// include/linux/usb/otg.h
++
++/*
++ * These APIs may be used between USB controllers. USB device drivers
++ * (for either host or peripheral roles) don't use these calls; they
++ * continue to use just usb_device and usb_gadget.
++ */
++
++
++/* OTG defines lots of enumeration states before device reset */
++enum usb_otg_state {
++ OTG_STATE_UNDEFINED = 0,
++
++ /* single-role peripheral, and dual-role default-b */
++ OTG_STATE_B_IDLE,
++ OTG_STATE_B_SRP_INIT,
++ OTG_STATE_B_PERIPHERAL,
++
++ /* extra dual-role default-b states */
++ OTG_STATE_B_WAIT_ACON,
++ OTG_STATE_B_HOST,
++
++ /* dual-role default-a */
++ OTG_STATE_A_IDLE,
++ OTG_STATE_A_WAIT_VRISE,
++ OTG_STATE_A_WAIT_BCON,
++ OTG_STATE_A_HOST,
++ OTG_STATE_A_SUSPEND,
++ OTG_STATE_A_PERIPHERAL,
++ OTG_STATE_A_WAIT_VFALL,
++ OTG_STATE_A_VBUS_ERR,
++};
++
++/*
++ * the otg driver needs to interact with both device side and host side
++ * usb controllers. it decides which controller is active at a given
++ * moment, using the transceiver, ID signal, HNP and sometimes static
++ * configuration information (including "board isn't wired for otg").
++ */
++struct otg_transceiver {
++ struct device *dev;
++ const char *label;
++
++ u8 default_a;
++ enum usb_otg_state state;
++
++ struct usb_bus *host;
++ struct usb_gadget *gadget;
++
++ /* to pass extra port status to the root hub */
++ u16 port_status;
++ u16 port_change;
++
++ /* bind/unbind the host controller */
++ int (*set_host)(struct otg_transceiver *otg,
++ struct usb_bus *host);
++
++ /* bind/unbind the peripheral controller */
++ int (*set_peripheral)(struct otg_transceiver *otg,
++ struct usb_gadget *gadget);
++
++ /* effective for B devices, ignored for A-peripheral */
++ int (*set_power)(struct otg_transceiver *otg,
++ unsigned mA);
++
++ /* for non-OTG B devices: set transceiver into suspend mode */
++ int (*set_suspend)(struct otg_transceiver *otg,
++ int suspend);
++
++ /* for B devices only: start session with A-Host */
++ int (*start_srp)(struct otg_transceiver *otg);
++
++ /* start or continue HNP role switch */
++ int (*start_hnp)(struct otg_transceiver *otg);
++
++};
++
++
++/* for board-specific init logic */
++extern int otg_set_transceiver(struct otg_transceiver *);
++
++
++/* for usb host and peripheral controller drivers */
++extern struct otg_transceiver *otg_get_transceiver(void);
++
++static inline int
++otg_start_hnp(struct otg_transceiver *otg)
++{
++ return otg->start_hnp(otg);
++}
++
++
++/* for HCDs */
++static inline int
++otg_set_host(struct otg_transceiver *otg, struct usb_bus *host)
++{
++ return otg->set_host(otg, host);
++}
++
++
++/* for usb peripheral controller drivers */
++static inline int
++otg_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *periph)
++{
++ return otg->set_peripheral(otg, periph);
++}
++
++static inline int
++otg_set_power(struct otg_transceiver *otg, unsigned mA)
++{
++ return otg->set_power(otg, mA);
++}
++
++static inline int
++otg_set_suspend(struct otg_transceiver *otg, int suspend)
++{
++ if (otg->set_suspend != NULL)
++ return otg->set_suspend(otg, suspend);
++ else
++ return 0;
++}
++
++static inline int
++otg_start_srp(struct otg_transceiver *otg)
++{
++ return otg->start_srp(otg);
++}
++
++
++/* for OTG controller drivers (and maybe other stuff) */
++extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);
+--- gregkh-2.6.orig/include/linux/usb_otg.h
++++ /dev/null
+@@ -1,131 +0,0 @@
+-// include/linux/usb_otg.h
+-
+-/*
+- * These APIs may be used between USB controllers. USB device drivers
+- * (for either host or peripheral roles) don't use these calls; they
+- * continue to use just usb_device and usb_gadget.
+- */
+-
+-
+-/* OTG defines lots of enumeration states before device reset */
+-enum usb_otg_state {
+- OTG_STATE_UNDEFINED = 0,
+-
+- /* single-role peripheral, and dual-role default-b */
+- OTG_STATE_B_IDLE,
+- OTG_STATE_B_SRP_INIT,
+- OTG_STATE_B_PERIPHERAL,
+-
+- /* extra dual-role default-b states */
+- OTG_STATE_B_WAIT_ACON,
+- OTG_STATE_B_HOST,
+-
+- /* dual-role default-a */
+- OTG_STATE_A_IDLE,
+- OTG_STATE_A_WAIT_VRISE,
+- OTG_STATE_A_WAIT_BCON,
+- OTG_STATE_A_HOST,
+- OTG_STATE_A_SUSPEND,
+- OTG_STATE_A_PERIPHERAL,
+- OTG_STATE_A_WAIT_VFALL,
+- OTG_STATE_A_VBUS_ERR,
+-};
+-
+-/*
+- * the otg driver needs to interact with both device side and host side
+- * usb controllers. it decides which controller is active at a given
+- * moment, using the transceiver, ID signal, HNP and sometimes static
+- * configuration information (including "board isn't wired for otg").
+- */
+-struct otg_transceiver {
+- struct device *dev;
+- const char *label;
+-
+- u8 default_a;
+- enum usb_otg_state state;
+-
+- struct usb_bus *host;
+- struct usb_gadget *gadget;
+-
+- /* to pass extra port status to the root hub */
+- u16 port_status;
+- u16 port_change;
+-
+- /* bind/unbind the host controller */
+- int (*set_host)(struct otg_transceiver *otg,
+- struct usb_bus *host);
+-
+- /* bind/unbind the peripheral controller */
+- int (*set_peripheral)(struct otg_transceiver *otg,
+- struct usb_gadget *gadget);
+-
+- /* effective for B devices, ignored for A-peripheral */
+- int (*set_power)(struct otg_transceiver *otg,
+- unsigned mA);
+-
+- /* for non-OTG B devices: set transceiver into suspend mode */
+- int (*set_suspend)(struct otg_transceiver *otg,
+- int suspend);
+-
+- /* for B devices only: start session with A-Host */
+- int (*start_srp)(struct otg_transceiver *otg);
+-
+- /* start or continue HNP role switch */
+- int (*start_hnp)(struct otg_transceiver *otg);
+-
+-};
+-
+-
+-/* for board-specific init logic */
+-extern int otg_set_transceiver(struct otg_transceiver *);
+-
+-
+-/* for usb host and peripheral controller drivers */
+-extern struct otg_transceiver *otg_get_transceiver(void);
+-
+-static inline int
+-otg_start_hnp(struct otg_transceiver *otg)
+-{
+- return otg->start_hnp(otg);
+-}
+-
+-
+-/* for HCDs */
+-static inline int
+-otg_set_host(struct otg_transceiver *otg, struct usb_bus *host)
+-{
+- return otg->set_host(otg, host);
+-}
+-
+-
+-/* for usb peripheral controller drivers */
+-static inline int
+-otg_set_peripheral(struct otg_transceiver *otg, struct usb_gadget *periph)
+-{
+- return otg->set_peripheral(otg, periph);
+-}
+-
+-static inline int
+-otg_set_power(struct otg_transceiver *otg, unsigned mA)
+-{
+- return otg->set_power(otg, mA);
+-}
+-
+-static inline int
+-otg_set_suspend(struct otg_transceiver *otg, int suspend)
+-{
+- if (otg->set_suspend != NULL)
+- return otg->set_suspend(otg, suspend);
+- else
+- return 0;
+-}
+-
+-static inline int
+-otg_start_srp(struct otg_transceiver *otg)
+-{
+- return otg->start_srp(otg);
+-}
+-
+-
+-/* for OTG controller drivers (and maybe other stuff) */
+-extern int usb_bus_start_enum(struct usb_bus *bus, unsigned port_num);
diff --git a/usb/usb-ohci-controller-support-for-pnx4008.patch b/usb/usb-ohci-controller-support-for-pnx4008.patch
new file mode 100644
index 0000000000000..dd604573d993c
--- /dev/null
+++ b/usb/usb-ohci-controller-support-for-pnx4008.patch
@@ -0,0 +1,545 @@
+From linux-usb-devel-bounces@lists.sourceforge.net Thu Jun 29 07:28:31 2006
+Date: Thu, 29 Jun 2006 18:28:18 +0400
+From: Vitaly Wool <vwool@ru.mvista.com>
+Message-Id: <20060629182818.bc0f77f8.vwool@ru.mvista.com>
+Subject: USB OHCI controller support for PNX4008
+
+
+inlined is the patch that adds basic support for USB OHCI controller
+support for PNX4008 Philips PNX4008 ARM board. Due to HW design, it
+depends on I2C driver for PNX4008 which I've recetnly posted to LKML and
+i2c at lm-sensors.
+
+Signed-off-by: Vitaly Wool <vitalywool@gmail.com>
+Cc: David Brownell <david-b@pacbell.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/Kconfig | 1
+ drivers/usb/host/Kconfig | 2
+ drivers/usb/host/ohci-hcd.c | 5
+ drivers/usb/host/ohci-pnx4008.c | 476 ++++++++++++++++++++++++++++++++++++++++
+ 4 files changed, 484 insertions(+)
+
+--- gregkh-2.6.orig/drivers/usb/Kconfig
++++ gregkh-2.6/drivers/usb/Kconfig
+@@ -25,6 +25,7 @@ config USB_ARCH_HAS_OHCI
+ default y if PXA27x
+ default y if ARCH_EP93XX
+ default y if (ARCH_AT91RM9200 || ARCH_AT91SAM9261)
++ default y if ARCH_PNX4008
+ # PPC:
+ default y if STB03xxx
+ default y if PPC_MPC52xx
+--- gregkh-2.6.orig/drivers/usb/host/Kconfig
++++ gregkh-2.6/drivers/usb/host/Kconfig
+@@ -83,6 +83,8 @@ config USB_OHCI_HCD
+ tristate "OHCI HCD support"
+ depends on USB && USB_ARCH_HAS_OHCI
+ select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3
++ select I2C if ARCH_PNX4008
++ select I2C_PNX if ARCH_PNX4008
+ ---help---
+ The Open Host Controller Interface (OHCI) is a standard for accessing
+ USB 1.1 host controller hardware. It does more in hardware than Intel's
+--- gregkh-2.6.orig/drivers/usb/host/ohci-hcd.c
++++ gregkh-2.6/drivers/usb/host/ohci-hcd.c
+@@ -928,6 +928,10 @@ MODULE_LICENSE ("GPL");
+ #include "ohci-at91.c"
+ #endif
+
++#ifdef CONFIG_ARCH_PNX4008
++#include "ohci-pnx4008.c"
++#endif
++
+ #if !(defined(CONFIG_PCI) \
+ || defined(CONFIG_SA1111) \
+ || defined(CONFIG_ARCH_S3C2410) \
+@@ -939,6 +943,7 @@ MODULE_LICENSE ("GPL");
+ || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \
+ || defined (CONFIG_ARCH_AT91RM9200) \
+ || defined (CONFIG_ARCH_AT91SAM9261) \
++ || defined (CONFIG_ARCH_PNX4008) \
+ )
+ #error "missing bus glue for ohci-hcd"
+ #endif
+--- /dev/null
++++ gregkh-2.6/drivers/usb/host/ohci-pnx4008.c
+@@ -0,0 +1,476 @@
++/*
++ * drivers/usb/host/ohci-pnx4008.c
++ *
++ * driver for Philips PNX4008 USB Host
++ *
++ * Authors: Dmitry Chigirev <source@mvista.com>
++ * Vitaly Wool <vitalywool@gmail.com>
++ *
++ * register initialization is based on code examples provided by Philips
++ * Copyright (c) 2005 Koninklijke Philips Electronics N.V.
++ *
++ * NOTE: This driver does not have suspend/resume functionality
++ * This driver is intended for engineering development purposes only
++ *
++ * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
++ * the terms of the GNU General Public License version 2. This program
++ * is licensed "as is" without any warranty of any kind, whether express
++ * or implied.
++ */
++#include <linux/clk.h>
++#include <linux/platform_device.h>
++#include <linux/i2c.h>
++
++#include <asm/hardware.h>
++#include <asm/io.h>
++#include <asm/mach-types.h>
++
++#include <asm/arch/platform.h>
++#include <asm/arch/irqs.h>
++#include <asm/arch/gpio.h>
++
++#define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64)
++
++/* USB_CTRL bit defines */
++#define USB_SLAVE_HCLK_EN (1 << 24)
++#define USB_HOST_NEED_CLK_EN (1 << 21)
++
++#define USB_OTG_CLK_CTRL IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0xFF4)
++#define USB_OTG_CLK_STAT IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0xFF8)
++
++/* USB_OTG_CLK_CTRL bit defines */
++#define AHB_M_CLOCK_ON (1 << 4)
++#define OTG_CLOCK_ON (1 << 3)
++#define I2C_CLOCK_ON (1 << 2)
++#define DEV_CLOCK_ON (1 << 1)
++#define HOST_CLOCK_ON (1 << 0)
++
++#define USB_OTG_STAT_CONTROL IO_ADDRESS(PNX4008_USB_CONFIG_BASE + 0x110)
++
++/* USB_OTG_STAT_CONTROL bit defines */
++#define TRANSPARENT_I2C_EN (1 << 7)
++#define HOST_EN (1 << 0)
++
++/* ISP1301 USB transceiver I2C registers */
++#define ISP1301_MODE_CONTROL_1 0x04 /* u8 read, set, +1 clear */
++
++#define MC1_SPEED_REG (1 << 0)
++#define MC1_SUSPEND_REG (1 << 1)
++#define MC1_DAT_SE0 (1 << 2)
++#define MC1_TRANSPARENT (1 << 3)
++#define MC1_BDIS_ACON_EN (1 << 4)
++#define MC1_OE_INT_EN (1 << 5)
++#define MC1_UART_EN (1 << 6)
++#define MC1_MASK 0x7f
++
++#define ISP1301_MODE_CONTROL_2 0x12 /* u8 read, set, +1 clear */
++
++#define MC2_GLOBAL_PWR_DN (1 << 0)
++#define MC2_SPD_SUSP_CTRL (1 << 1)
++#define MC2_BI_DI (1 << 2)
++#define MC2_TRANSP_BDIR0 (1 << 3)
++#define MC2_TRANSP_BDIR1 (1 << 4)
++#define MC2_AUDIO_EN (1 << 5)
++#define MC2_PSW_EN (1 << 6)
++#define MC2_EN2V7 (1 << 7)
++
++#define ISP1301_OTG_CONTROL_1 0x06 /* u8 read, set, +1 clear */
++# define OTG1_DP_PULLUP (1 << 0)
++# define OTG1_DM_PULLUP (1 << 1)
++# define OTG1_DP_PULLDOWN (1 << 2)
++# define OTG1_DM_PULLDOWN (1 << 3)
++# define OTG1_ID_PULLDOWN (1 << 4)
++# define OTG1_VBUS_DRV (1 << 5)
++# define OTG1_VBUS_DISCHRG (1 << 6)
++# define OTG1_VBUS_CHRG (1 << 7)
++#define ISP1301_OTG_STATUS 0x10 /* u8 readonly */
++# define OTG_B_SESS_END (1 << 6)
++# define OTG_B_SESS_VLD (1 << 7)
++
++#define ISP1301_I2C_ADDR 0x2C
++
++#define ISP1301_I2C_MODE_CONTROL_1 0x4
++#define ISP1301_I2C_MODE_CONTROL_2 0x12
++#define ISP1301_I2C_OTG_CONTROL_1 0x6
++#define ISP1301_I2C_OTG_CONTROL_2 0x10
++#define ISP1301_I2C_INTERRUPT_SOURCE 0x8
++#define ISP1301_I2C_INTERRUPT_LATCH 0xA
++#define ISP1301_I2C_INTERRUPT_FALLING 0xC
++#define ISP1301_I2C_INTERRUPT_RISING 0xE
++#define ISP1301_I2C_REG_CLEAR_ADDR 1
++
++struct i2c_driver isp1301_driver;
++struct i2c_client *isp1301_i2c_client;
++
++extern int usb_disabled(void);
++extern int ocpi_enable(void);
++
++static struct clk *usb_clk;
++
++static int isp1301_probe(struct i2c_adapter *adap);
++static int isp1301_detach(struct i2c_client *client);
++static int isp1301_command(struct i2c_client *client, unsigned int cmd,
++ void *arg);
++
++static unsigned short normal_i2c[] =
++ { ISP1301_I2C_ADDR, ISP1301_I2C_ADDR + 1, I2C_CLIENT_END };
++static unsigned short dummy_i2c_addrlist[] = { I2C_CLIENT_END };
++
++static struct i2c_client_address_data addr_data = {
++ .normal_i2c = normal_i2c,
++ .probe = dummy_i2c_addrlist,
++ .ignore = dummy_i2c_addrlist,
++};
++
++struct i2c_driver isp1301_driver = {
++ .id = I2C_DRIVERID_I2CDEV, /* Fake Id */
++ .class = I2C_CLASS_HWMON,
++ .attach_adapter = isp1301_probe,
++ .detach_client = isp1301_detach,
++ .command = isp1301_command
++};
++
++static int isp1301_attach(struct i2c_adapter *adap, int addr, int kind)
++{
++ struct i2c_client *c;
++
++ c = (struct i2c_client *)kzalloc(sizeof(*c), SLAB_KERNEL);
++
++ if (!c)
++ return -ENOMEM;
++
++ strcpy(c->name, "isp1301");
++ c->flags = 0;
++ c->addr = addr;
++ c->adapter = adap;
++ c->driver = &isp1301_driver;
++
++ isp1301_i2c_client = c;
++
++ return i2c_attach_client(c);
++}
++
++static int isp1301_probe(struct i2c_adapter *adap)
++{
++ return i2c_probe(adap, &addr_data, isp1301_attach);
++}
++
++static int isp1301_detach(struct i2c_client *client)
++{
++ i2c_detach_client(client);
++ kfree(isp1301_i2c_client);
++ return 0;
++}
++
++/* No commands defined */
++static int isp1301_command(struct i2c_client *client, unsigned int cmd,
++ void *arg)
++{
++ return 0;
++}
++
++static void i2c_write(u8 buf, u8 subaddr)
++{
++ char tmpbuf[2];
++
++ tmpbuf[0] = subaddr; /*register number */
++ tmpbuf[1] = buf; /*register data */
++ i2c_master_send(isp1301_i2c_client, &tmpbuf[0], 2);
++}
++
++static void isp1301_configure(void)
++{
++ /* PNX4008 only supports DAT_SE0 USB mode */
++ /* PNX4008 R2A requires setting the MAX603 to output 3.6V */
++ /* Power up externel charge-pump */
++
++ i2c_write(MC1_DAT_SE0 | MC1_SPEED_REG, ISP1301_I2C_MODE_CONTROL_1);
++ i2c_write(~(MC1_DAT_SE0 | MC1_SPEED_REG),
++ ISP1301_I2C_MODE_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR);
++ i2c_write(MC2_BI_DI | MC2_PSW_EN | MC2_SPD_SUSP_CTRL,
++ ISP1301_I2C_MODE_CONTROL_2);
++ i2c_write(~(MC2_BI_DI | MC2_PSW_EN | MC2_SPD_SUSP_CTRL),
++ ISP1301_I2C_MODE_CONTROL_2 | ISP1301_I2C_REG_CLEAR_ADDR);
++ i2c_write(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN,
++ ISP1301_I2C_OTG_CONTROL_1);
++ i2c_write(~(OTG1_DM_PULLDOWN | OTG1_DP_PULLDOWN),
++ ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR);
++ i2c_write(0xFF,
++ ISP1301_I2C_INTERRUPT_LATCH | ISP1301_I2C_REG_CLEAR_ADDR);
++ i2c_write(0xFF,
++ ISP1301_I2C_INTERRUPT_FALLING | ISP1301_I2C_REG_CLEAR_ADDR);
++ i2c_write(0xFF,
++ ISP1301_I2C_INTERRUPT_RISING | ISP1301_I2C_REG_CLEAR_ADDR);
++
++}
++
++static inline void isp1301_vbus_on(void)
++{
++ i2c_write(OTG1_VBUS_DRV, ISP1301_I2C_OTG_CONTROL_1);
++}
++
++static inline void isp1301_vbus_off(void)
++{
++ i2c_write(OTG1_VBUS_DRV,
++ ISP1301_I2C_OTG_CONTROL_1 | ISP1301_I2C_REG_CLEAR_ADDR);
++}
++
++static void pnx4008_start_hc(void)
++{
++ unsigned long tmp = __raw_readl(USB_OTG_STAT_CONTROL) | HOST_EN;
++ __raw_writel(tmp, USB_OTG_STAT_CONTROL);
++ isp1301_vbus_on();
++}
++
++static void pnx4008_stop_hc(void)
++{
++ unsigned long tmp;
++ isp1301_vbus_off();
++ tmp = __raw_readl(USB_OTG_STAT_CONTROL) & ~HOST_EN;
++ __raw_writel(tmp, USB_OTG_STAT_CONTROL);
++}
++
++static int __devinit ohci_pnx4008_start(struct usb_hcd *hcd)
++{
++ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
++ int ret;
++
++ if ((ret = ohci_init(ohci)) < 0)
++ return ret;
++
++ if ((ret = ohci_run(ohci)) < 0) {
++ dev_err(hcd->self.controller, "can't start\n");
++ ohci_stop(hcd);
++ return ret;
++ }
++ return 0;
++}
++
++static const struct hc_driver ohci_pnx4008_hc_driver = {
++ .description = hcd_name,
++ .product_desc = "pnx4008 OHCI",
++
++ /*
++ * generic hardware linkage
++ */
++ .irq = ohci_irq,
++ .flags = HCD_USB11 | HCD_MEMORY,
++
++ .hcd_priv_size = sizeof(struct ohci_hcd),
++ /*
++ * basic lifecycle operations
++ */
++ .start = ohci_pnx4008_start,
++ .stop = ohci_stop,
++
++ /*
++ * managing i/o requests and associated device resources
++ */
++ .urb_enqueue = ohci_urb_enqueue,
++ .urb_dequeue = ohci_urb_dequeue,
++ .endpoint_disable = ohci_endpoint_disable,
++
++ /*
++ * scheduling support
++ */
++ .get_frame_number = ohci_get_frame,
++
++ /*
++ * root hub support
++ */
++ .hub_status_data = ohci_hub_status_data,
++ .hub_control = ohci_hub_control,
++
++ .start_port_reset = ohci_start_port_reset,
++};
++
++#define USB_CLOCK_MASK (AHB_M_CLOCK_ON| OTG_CLOCK_ON | HOST_CLOCK_ON | I2C_CLOCK_ON)
++
++static void pnx4008_set_usb_bits(void)
++{
++ start_int_set_falling_edge(SE_USB_OTG_ATX_INT_N);
++ start_int_ack(SE_USB_OTG_ATX_INT_N);
++ start_int_umask(SE_USB_OTG_ATX_INT_N);
++
++ start_int_set_rising_edge(SE_USB_OTG_TIMER_INT);
++ start_int_ack(SE_USB_OTG_TIMER_INT);
++ start_int_umask(SE_USB_OTG_TIMER_INT);
++
++ start_int_set_rising_edge(SE_USB_I2C_INT);
++ start_int_ack(SE_USB_I2C_INT);
++ start_int_umask(SE_USB_I2C_INT);
++
++ start_int_set_rising_edge(SE_USB_INT);
++ start_int_ack(SE_USB_INT);
++ start_int_umask(SE_USB_INT);
++
++ start_int_set_rising_edge(SE_USB_NEED_CLK_INT);
++ start_int_ack(SE_USB_NEED_CLK_INT);
++ start_int_umask(SE_USB_NEED_CLK_INT);
++
++ start_int_set_rising_edge(SE_USB_AHB_NEED_CLK_INT);
++ start_int_ack(SE_USB_AHB_NEED_CLK_INT);
++ start_int_umask(SE_USB_AHB_NEED_CLK_INT);
++}
++
++static void pnx4008_unset_usb_bits(void)
++{
++ start_int_mask(SE_USB_OTG_ATX_INT_N);
++ start_int_mask(SE_USB_OTG_TIMER_INT);
++ start_int_mask(SE_USB_I2C_INT);
++ start_int_mask(SE_USB_INT);
++ start_int_mask(SE_USB_NEED_CLK_INT);
++ start_int_mask(SE_USB_AHB_NEED_CLK_INT);
++}
++
++static int __devinit usb_hcd_pnx4008_probe(struct platform_device *pdev)
++{
++ struct usb_hcd *hcd = 0;
++ struct ohci_hcd *ohci;
++ const struct hc_driver *driver = &ohci_pnx4008_hc_driver;
++
++ int ret = 0, irq;
++
++ dev_dbg(&pdev->dev, "%s: " DRIVER_INFO " (pnx4008)\n", hcd_name);
++ if (usb_disabled()) {
++ err("USB is disabled");
++ ret = -ENODEV;
++ goto out;
++ }
++
++ if (pdev->num_resources != 2
++ || pdev->resource[0].flags != IORESOURCE_MEM
++ || pdev->resource[1].flags != IORESOURCE_IRQ) {
++ err("Invalid resource configuration");
++ ret = -ENODEV;
++ goto out;
++ }
++
++ /* Enable AHB slave USB clock, needed for further USB clock control */
++ __raw_writel(USB_SLAVE_HCLK_EN | (1 << 19), USB_CTRL);
++
++ ret = i2c_add_driver(&isp1301_driver);
++ if (ret < 0) {
++ err("failed to connect I2C to ISP1301 USB Transceiver");
++ goto out;
++ }
++
++ isp1301_configure();
++
++ /* Enable USB PLL */
++ usb_clk = clk_get(&pdev->dev, "ck_pll5");
++ if (IS_ERR(usb_clk)) {
++ err("failed to acquire USB PLL");
++ ret = PTR_ERR(usb_clk);
++ goto out1;
++ }
++
++ ret = clk_enable(usb_clk);
++ if (ret < 0) {
++ err("failed to start USB PLL");
++ goto out2;
++ }
++
++ ret = clk_set_rate(usb_clk, 48000);
++ if (ret < 0) {
++ err("failed to set USB clock rate");
++ goto out3;
++ }
++
++ __raw_writel(__raw_readl(USB_CTRL) | USB_HOST_NEED_CLK_EN, USB_CTRL);
++
++ /* Set to enable all needed USB clocks */
++ __raw_writel(USB_CLOCK_MASK, USB_OTG_CLK_CTRL);
++
++ while ((__raw_readl(USB_OTG_CLK_STAT) & USB_CLOCK_MASK) !=
++ USB_CLOCK_MASK) ;
++
++ hcd = usb_create_hcd (driver, &pdev->dev, pdev->dev.bus_id);
++ if (!hcd) {
++ err("Failed to allocate HC buffer");
++ ret = -ENOMEM;
++ goto out3;
++ }
++
++ /* Set all USB bits in the Start Enable register */
++ pnx4008_set_usb_bits();
++
++ hcd->rsrc_start = pdev->resource[0].start;
++ hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1;
++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
++ dev_dbg(&pdev->dev, "request_mem_region failed\n");
++ ret = -ENOMEM;
++ goto out4;
++ }
++ hcd->regs = (void __iomem *)pdev->resource[0].start;
++
++ irq = platform_get_irq(pdev, 0);
++ if (irq < 0) {
++ ret = -ENXIO;
++ goto out4;
++ }
++
++ hcd->self.hcpriv = (void *)hcd;
++
++ pnx4008_start_hc();
++ platform_set_drvdata(pdev, hcd);
++ ohci = hcd_to_ohci(hcd);
++ ohci_hcd_init(ohci);
++
++ dev_info(&pdev->dev, "at 0x%p, irq %d\n", hcd->regs, hcd->irq);
++ ret = usb_add_hcd(hcd, irq, SA_INTERRUPT);
++ if (ret == 0)
++ return ret;
++
++ pnx4008_stop_hc();
++out4:
++ pnx4008_unset_usb_bits();
++ usb_put_hcd(hcd);
++out3:
++ clk_disable(usb_clk);
++out2:
++ clk_put(usb_clk);
++out1:
++ i2c_del_driver(&isp1301_driver);
++out:
++ return ret;
++}
++
++static int usb_hcd_pnx4008_remove(struct platform_device *pdev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(pdev);
++
++ usb_remove_hcd(hcd);
++ pnx4008_stop_hc();
++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++ usb_put_hcd(hcd);
++ pnx4008_unset_usb_bits();
++ clk_disable(usb_clk);
++ clk_put(usb_clk);
++ i2c_del_driver(&isp1301_driver);
++
++ platform_set_drvdata(pdev, NULL);
++
++ return 0;
++}
++
++static struct platform_driver usb_hcd_pnx4008_driver = {
++ .driver = {
++ .name = "usb-ohci",
++ },
++ .probe = usb_hcd_pnx4008_probe,
++ .remove = usb_hcd_pnx4008_remove,
++};
++
++static int __init usb_hcd_pnx4008_init(void)
++{
++ return platform_driver_register(&usb_hcd_pnx4008_driver);
++}
++
++static void __exit usb_hcd_pnx4008_cleanup(void)
++{
++ return platform_driver_unregister(&usb_hcd_pnx4008_driver);
++}
++
++module_init(usb_hcd_pnx4008_init);
++module_exit(usb_hcd_pnx4008_cleanup);
diff --git a/usb/usb-ohci-s3c2410.c-clock-now-usb-bus-host.patch b/usb/usb-ohci-s3c2410.c-clock-now-usb-bus-host.patch
new file mode 100644
index 0000000000000..c13c05a65b142
--- /dev/null
+++ b/usb/usb-ohci-s3c2410.c-clock-now-usb-bus-host.patch
@@ -0,0 +1,40 @@
+From ben@fluff.org.uk Mon Jun 26 15:37:21 2006
+Date: Mon, 26 Jun 2006 23:36:07 +0100
+From: Ben Dooks <ben-linux@fluff.org>
+Cc: gregkh@suse.de
+Subject: USB: ohci-s3c2410.c: clock now usb-bus-host
+Message-ID: <20060626223607.GA1788@home.fluff.org>
+Content-Disposition: inline
+
+With the newer Samsung S3C2412 and S3C2413 SoC devices,
+the 48MHz USB clock has been given an individual gate
+into the USB OHCI and gadget blocks.
+
+This clock is called usb-bus-clock, and we need to
+replace the old use of the USB PLL (upll) directly
+with the new usb-bus-host.
+
+The S3C2410 clock driver has been updated already to
+provide a virtual clock which is a child of the UPLL
+to maintain compatibility. The S3C2412 clock driver
+correctly enables the PLL when either usb-bus clock
+is active.
+
+Signed-off-by: Ben Dooks <ben-linux@fluff.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ohci-s3c2410.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- gregkh-2.6.orig/drivers/usb/host/ohci-s3c2410.c
++++ gregkh-2.6/drivers/usb/host/ohci-s3c2410.c
+@@ -370,7 +370,7 @@ static int usb_hcd_s3c2410_probe (const
+ goto err_mem;
+ }
+
+- usb_clk = clk_get(&dev->dev, "upll");
++ usb_clk = clk_get(&dev->dev, "usb-bus-host");
+ if (IS_ERR(usb_clk)) {
+ dev_err(&dev->dev, "cannot get usb-host clock\n");
+ retval = -ENOENT;
diff --git a/usb/usb-pxa2xx_udc-understands-gpio-based-vbus-sensing.patch b/usb/usb-pxa2xx_udc-understands-gpio-based-vbus-sensing.patch
new file mode 100644
index 0000000000000..70896d80002f0
--- /dev/null
+++ b/usb/usb-pxa2xx_udc-understands-gpio-based-vbus-sensing.patch
@@ -0,0 +1,231 @@
+From david-b@pacbell.net Thu Jun 29 14:02:38 2006
+From: David Brownell <david-b@pacbell.net>
+To: Greg KH <greg@kroah.com>
+Subject: USB: pxa2xx_udc understands GPIO based VBUS sensing
+Date: Thu, 29 Jun 2006 12:25:39 -0700
+Cc: linux-usb-devel@lists.sourceforge.net, Dave Hylands <dhylands@gmail.com>
+Message-Id: <200606291225.39983.david-b@pacbell.net>
+
+This updates the PXA 25x UDC board-independent infrastructure for VBUS sensing
+and the D+ pullup. The original code evolved from rather bizarre support on
+Intel's "Lubbock" reference hardware, so that on more sensible hardware it
+doesn't work as well as it could/should.
+
+The change is just to teach the UDC driver how to use built-in PXA GPIO pins
+directly. This reduces the amount of board-specfic object code needed, and
+enables the use of a VBUS sensing IRQ on boards (like Gumstix) that have one.
+With VBUS sensing, the UDC is unclocked until a host is actually connected.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/arm/mach-pxa/corgi.c | 15 --------
+ drivers/usb/gadget/pxa2xx_udc.c | 70 ++++++++++++++++++++++++++++++++++++++--
+ drivers/usb/gadget/pxa2xx_udc.h | 24 ++++---------
+ include/asm-arm/arch-pxa/udc.h | 8 ++++
+ 4 files changed, 85 insertions(+), 32 deletions(-)
+
+--- gregkh-2.6.orig/arch/arm/mach-pxa/corgi.c
++++ gregkh-2.6/arch/arm/mach-pxa/corgi.c
+@@ -284,21 +284,9 @@ static struct pxaficp_platform_data corg
+ /*
+ * USB Device Controller
+ */
+-static void corgi_udc_command(int cmd)
+-{
+- switch(cmd) {
+- case PXA2XX_UDC_CMD_CONNECT:
+- GPSR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP);
+- break;
+- case PXA2XX_UDC_CMD_DISCONNECT:
+- GPCR(CORGI_GPIO_USB_PULLUP) = GPIO_bit(CORGI_GPIO_USB_PULLUP);
+- break;
+- }
+-}
+-
+ static struct pxa2xx_udc_mach_info udc_info __initdata = {
+ /* no connect GPIO; corgi can't tell connection status */
+- .udc_command = corgi_udc_command,
++ .gpio_pullup = CORGI_GPIO_USB_PULLUP,
+ };
+
+
+@@ -350,7 +338,6 @@ static void __init corgi_init(void)
+ corgi_ssp_set_machinfo(&corgi_ssp_machinfo);
+
+ pxa_gpio_mode(CORGI_GPIO_IR_ON | GPIO_OUT);
+- pxa_gpio_mode(CORGI_GPIO_USB_PULLUP | GPIO_OUT);
+ pxa_gpio_mode(CORGI_GPIO_HSYNC | GPIO_IN);
+
+ pxa_set_udc_info(&udc_info);
+--- gregkh-2.6.orig/drivers/usb/gadget/pxa2xx_udc.c
++++ gregkh-2.6/drivers/usb/gadget/pxa2xx_udc.c
+@@ -151,6 +151,39 @@ MODULE_PARM_DESC (fifo_mode, "pxa2xx udc
+ static void pxa2xx_ep_fifo_flush (struct usb_ep *ep);
+ static void nuke (struct pxa2xx_ep *, int status);
+
++/* one GPIO should be used to detect VBUS from the host */
++static int is_vbus_present(void)
++{
++ struct pxa2xx_udc_mach_info *mach = the_controller->mach;
++
++ if (mach->gpio_vbus)
++ return pxa_gpio_get(mach->gpio_vbus);
++ if (mach->udc_is_connected)
++ return mach->udc_is_connected();
++ return 1;
++}
++
++/* one GPIO should control a D+ pullup, so host sees this device (or not) */
++static void pullup_off(void)
++{
++ struct pxa2xx_udc_mach_info *mach = the_controller->mach;
++
++ if (mach->gpio_pullup)
++ pxa_gpio_set(mach->gpio_pullup, 0);
++ else if (mach->udc_command)
++ mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
++}
++
++static void pullup_on(void)
++{
++ struct pxa2xx_udc_mach_info *mach = the_controller->mach;
++
++ if (mach->gpio_pullup)
++ pxa_gpio_set(mach->gpio_pullup, 1);
++ else if (mach->udc_command)
++ mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
++}
++
+ static void pio_irq_enable(int bEndpointAddress)
+ {
+ bEndpointAddress &= 0xf;
+@@ -1722,6 +1755,16 @@ lubbock_vbus_irq(int irq, void *_dev, st
+
+ #endif
+
++static irqreturn_t
++udc_vbus_irq(int irq, void *_dev, struct pt_regs *r)
++{
++ struct pxa2xx_udc *dev = _dev;
++ int vbus = pxa_gpio_get(dev->mach->gpio_vbus);
++
++ pxa2xx_udc_vbus_session(&dev->gadget, vbus);
++ return IRQ_HANDLED;
++}
++
+
+ /*-------------------------------------------------------------------------*/
+
+@@ -2439,7 +2482,7 @@ static struct pxa2xx_udc memory = {
+ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
+ {
+ struct pxa2xx_udc *dev = &memory;
+- int retval, out_dma = 1;
++ int retval, out_dma = 1, vbus_irq;
+ u32 chiprev;
+
+ /* insist on Intel/ARM/XScale */
+@@ -2503,6 +2546,16 @@ static int __init pxa2xx_udc_probe(struc
+ /* other non-static parts of init */
+ dev->dev = &pdev->dev;
+ dev->mach = pdev->dev.platform_data;
++ if (dev->mach->gpio_vbus) {
++ vbus_irq = IRQ_GPIO(dev->mach->gpio_vbus & GPIO_MD_MASK_NR);
++ pxa_gpio_mode((dev->mach->gpio_vbus & GPIO_MD_MASK_NR)
++ | GPIO_IN);
++ set_irq_type(vbus_irq, IRQT_BOTHEDGE);
++ } else
++ vbus_irq = 0;
++ if (dev->mach->gpio_pullup)
++ pxa_gpio_mode((dev->mach->gpio_pullup & GPIO_MD_MASK_NR)
++ | GPIO_OUT | GPIO_DFLT_LOW);
+
+ init_timer(&dev->timer);
+ dev->timer.function = udc_watchdog;
+@@ -2558,8 +2611,19 @@ lubbock_fail0:
+ HEX_DISPLAY(dev->stats.irqs);
+ LUB_DISC_BLNK_LED &= 0xff;
+ #endif
+- }
++ } else
+ #endif
++ if (vbus_irq) {
++ retval = request_irq(vbus_irq, udc_vbus_irq,
++ SA_INTERRUPT | SA_SAMPLE_RANDOM,
++ driver_name, dev);
++ if (retval != 0) {
++ printk(KERN_ERR "%s: can't get irq %i, err %d\n",
++ driver_name, vbus_irq, retval);
++ free_irq(IRQ_USB, dev);
++ return -EBUSY;
++ }
++ }
+ create_proc_files();
+
+ return 0;
+@@ -2588,6 +2652,8 @@ static int __exit pxa2xx_udc_remove(stru
+ free_irq(LUBBOCK_USB_IRQ, dev);
+ }
+ #endif
++ if (dev->mach->gpio_vbus)
++ free_irq(IRQ_GPIO(dev->mach->gpio_vbus), dev);
+ platform_set_drvdata(pdev, NULL);
+ the_controller = NULL;
+ return 0;
+--- gregkh-2.6.orig/drivers/usb/gadget/pxa2xx_udc.h
++++ gregkh-2.6/drivers/usb/gadget/pxa2xx_udc.h
+@@ -177,27 +177,19 @@ struct pxa2xx_udc {
+
+ static struct pxa2xx_udc *the_controller;
+
+-/* one GPIO should be used to detect VBUS from the host */
+-static inline int is_vbus_present(void)
++static inline int pxa_gpio_get(unsigned gpio)
+ {
+- if (!the_controller->mach->udc_is_connected)
+- return 1;
+- return the_controller->mach->udc_is_connected();
++ return (GPLR(gpio) & GPIO_bit(gpio)) != 0;
+ }
+
+-/* one GPIO should control a D+ pullup, so host sees this device (or not) */
+-static inline void pullup_off(void)
++static inline void pxa_gpio_set(unsigned gpio, int is_on)
+ {
+- if (!the_controller->mach->udc_command)
+- return;
+- the_controller->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
+-}
++ int mask = GPIO_bit(gpio);
+
+-static inline void pullup_on(void)
+-{
+- if (!the_controller->mach->udc_command)
+- return;
+- the_controller->mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
++ if (is_on)
++ GPSR(gpio) = mask;
++ else
++ GPCR(gpio) = mask;
+ }
+
+ /*-------------------------------------------------------------------------*/
+--- gregkh-2.6.orig/include/asm-arm/arch-pxa/udc.h
++++ gregkh-2.6/include/asm-arm/arch-pxa/udc.h
+@@ -12,6 +12,14 @@ struct pxa2xx_udc_mach_info {
+ void (*udc_command)(int cmd);
+ #define PXA2XX_UDC_CMD_CONNECT 0 /* let host see us */
+ #define PXA2XX_UDC_CMD_DISCONNECT 1 /* so host won't see us */
++
++ /* Boards following the design guidelines in the developer's manual,
++ * with on-chip GPIOs not Lubbock's wierd hardware, can have a sane
++ * VBUS IRQ and omit the methods above. Store the GPIO number
++ * here; for GPIO 0, also mask in one of the pxa_gpio_mode() bits.
++ */
++ u16 gpio_vbus; /* high == vbus present */
++ u16 gpio_pullup; /* high == pullup activated */
+ };
+
+ extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
diff --git a/usb/usb-serial-ftdi_sio-prevent-userspace-dos.patch b/usb/usb-serial-ftdi_sio-prevent-userspace-dos.patch
new file mode 100644
index 0000000000000..a61e99ce6349a
--- /dev/null
+++ b/usb/usb-serial-ftdi_sio-prevent-userspace-dos.patch
@@ -0,0 +1,234 @@
+From ian.abbott@mev.co.uk Mon Jun 26 04:59:49 2006
+Message-ID: <449FCC15.3020903@mev.co.uk>
+Date: Mon, 26 Jun 2006 12:59:17 +0100
+From: Ian Abbott <abbotti@mev.co.uk>
+To: linux-usb-devel@lists.sourceforge.net
+Cc: Greg KH <greg@kroah.com>, Guillaume Autran <gautran@mrv.com>
+Subject: USB serial ftdi_sio: Prevent userspace DoS
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+This patch limits the amount of outstanding 'write' data that can be
+queued up for the ftdi_sio driver, to prevent userspace DoS attacks (or
+simple accidents) that use up all the system memory by writing lots of
+data to the serial port.
+
+The original patch was by Guillaume Autran, who in turn based it on the
+same mechanism implemented in the 'visor' driver. I (Ian Abbott)
+re-targeted the patch to the latest sources, fixed a couple of errors,
+renamed his new structure members, and updated the implementations of
+the 'write_room' and 'chars_in_buffer' methods to take account of the
+number of outstanding 'write' bytes. It seems to work fine, though at
+low baud rates it is still possible to queue up an amount of data that
+takes an age to shift (a job for another day!).
+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/ftdi_sio.c | 103 ++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 90 insertions(+), 13 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/serial/ftdi_sio.c
++++ gregkh-2.6/drivers/usb/serial/ftdi_sio.c
+@@ -551,11 +551,17 @@ struct ftdi_private {
+ spinlock_t rx_lock; /* spinlock for receive state */
+ struct work_struct rx_work;
+ int rx_processed;
++ unsigned long rx_bytes;
+
+ __u16 interface; /* FT2232C port interface (0 for FT232/245) */
+
+ int force_baud; /* if non-zero, force the baud rate to this value */
+ int force_rtscts; /* if non-zero, force RTS-CTS to always be enabled */
++
++ spinlock_t tx_lock; /* spinlock for transmit state */
++ unsigned long tx_bytes;
++ unsigned long tx_outstanding_bytes;
++ unsigned long tx_outstanding_urbs;
+ };
+
+ /* Used for TIOCMIWAIT */
+@@ -629,6 +635,9 @@ static struct usb_serial_driver ftdi_sio
+ #define HIGH 1
+ #define LOW 0
+
++/* number of outstanding urbs to prevent userspace DoS from happening */
++#define URB_UPPER_LIMIT 42
++
+ /*
+ * ***************************************************************************
+ * Utlity functions
+@@ -1159,6 +1168,7 @@ static int ftdi_sio_attach (struct usb_s
+ }
+
+ spin_lock_init(&priv->rx_lock);
++ spin_lock_init(&priv->tx_lock);
+ init_waitqueue_head(&priv->delta_msr_wait);
+ /* This will push the characters through immediately rather
+ than queue a task to deliver them */
+@@ -1273,6 +1283,13 @@ static int ftdi_open (struct usb_serial
+
+ dbg("%s", __FUNCTION__);
+
++ spin_lock_irqsave(&priv->tx_lock, flags);
++ priv->tx_bytes = 0;
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
++ spin_lock_irqsave(&priv->rx_lock, flags);
++ priv->rx_bytes = 0;
++ spin_unlock_irqrestore(&priv->rx_lock, flags);
++
+ if (port->tty)
+ port->tty->low_latency = (priv->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+
+@@ -1375,6 +1392,7 @@ static int ftdi_write (struct usb_serial
+ int data_offset ; /* will be 1 for the SIO and 0 otherwise */
+ int status;
+ int transfer_size;
++ unsigned long flags;
+
+ dbg("%s port %d, %d bytes", __FUNCTION__, port->number, count);
+
+@@ -1382,6 +1400,13 @@ static int ftdi_write (struct usb_serial
+ dbg("write request of 0 bytes");
+ return 0;
+ }
++ spin_lock_irqsave(&priv->tx_lock, flags);
++ if (priv->tx_outstanding_urbs > URB_UPPER_LIMIT) {
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
++ dbg("%s - write limit hit\n", __FUNCTION__);
++ return 0;
++ }
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
+
+ data_offset = priv->write_offset;
+ dbg("data_offset set to %d",data_offset);
+@@ -1448,6 +1473,12 @@ static int ftdi_write (struct usb_serial
+ err("%s - failed submitting write urb, error %d", __FUNCTION__, status);
+ count = status;
+ kfree (buffer);
++ } else {
++ spin_lock_irqsave(&priv->tx_lock, flags);
++ ++priv->tx_outstanding_urbs;
++ priv->tx_outstanding_bytes += count;
++ priv->tx_bytes += count;
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
+ }
+
+ /* we are done with this urb, so let the host driver
+@@ -1463,7 +1494,11 @@ static int ftdi_write (struct usb_serial
+
+ static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs)
+ {
++ unsigned long flags;
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
++ struct ftdi_private *priv;
++ int data_offset; /* will be 1 for the SIO and 0 otherwise */
++ unsigned long countback;
+
+ /* free up the transfer buffer, as usb_free_urb() does not do this */
+ kfree (urb->transfer_buffer);
+@@ -1475,34 +1510,67 @@ static void ftdi_write_bulk_callback (st
+ return;
+ }
+
++ priv = usb_get_serial_port_data(port);
++ if (!priv) {
++ dbg("%s - bad port private data pointer - exiting", __FUNCTION__);
++ return;
++ }
++ /* account for transferred data */
++ countback = urb->actual_length;
++ data_offset = priv->write_offset;
++ if (data_offset > 0) {
++ /* Subtract the control bytes */
++ countback -= (data_offset * ((countback + (PKTSZ - 1)) / PKTSZ));
++ }
++ spin_lock_irqsave(&priv->tx_lock, flags);
++ --priv->tx_outstanding_urbs;
++ priv->tx_outstanding_bytes -= countback;
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
++
+ usb_serial_port_softint(port);
+ } /* ftdi_write_bulk_callback */
+
+
+ static int ftdi_write_room( struct usb_serial_port *port )
+ {
++ struct ftdi_private *priv = usb_get_serial_port_data(port);
++ int room;
++ unsigned long flags;
++
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+- /*
+- * We really can take anything the user throws at us
+- * but let's pick a nice big number to tell the tty
+- * layer that we have lots of free space
+- */
+- return 2048;
++ spin_lock_irqsave(&priv->tx_lock, flags);
++ if (priv->tx_outstanding_urbs < URB_UPPER_LIMIT) {
++ /*
++ * We really can take anything the user throws at us
++ * but let's pick a nice big number to tell the tty
++ * layer that we have lots of free space
++ */
++ room = 2048;
++ } else {
++ room = 0;
++ }
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
++ return room;
+ } /* ftdi_write_room */
+
+
+ static int ftdi_chars_in_buffer (struct usb_serial_port *port)
+ { /* ftdi_chars_in_buffer */
++ struct ftdi_private *priv = usb_get_serial_port_data(port);
++ int buffered;
++ unsigned long flags;
++
+ dbg("%s - port %d", __FUNCTION__, port->number);
+
+- /*
+- * We can't really account for how much data we
+- * have sent out, but hasn't made it through to the
+- * device, so just tell the tty layer that everything
+- * is flushed.
+- */
+- return 0;
++ spin_lock_irqsave(&priv->tx_lock, flags);
++ buffered = (int)priv->tx_outstanding_bytes;
++ spin_unlock_irqrestore(&priv->tx_lock, flags);
++ if (buffered < 0) {
++ err("%s outstanding tx bytes is negative!", __FUNCTION__);
++ buffered = 0;
++ }
++ return buffered;
+ } /* ftdi_chars_in_buffer */
+
+
+@@ -1512,6 +1580,8 @@ static void ftdi_read_bulk_callback (str
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+ struct tty_struct *tty;
+ struct ftdi_private *priv;
++ unsigned long countread;
++ unsigned long flags;
+
+ if (urb->number_of_packets > 0) {
+ err("%s transfer_buffer_length %d actual_length %d number of packets %d",__FUNCTION__,
+@@ -1546,6 +1616,13 @@ static void ftdi_read_bulk_callback (str
+ return;
+ }
+
++ /* count data bytes, but not status bytes */
++ countread = urb->actual_length;
++ countread -= 2 * ((countread + (PKTSZ - 1)) / PKTSZ);
++ spin_lock_irqsave(&priv->rx_lock, flags);
++ priv->rx_bytes += countread;
++ spin_unlock_irqrestore(&priv->rx_lock, flags);
++
+ ftdi_process_read(port);
+
+ } /* ftdi_read_bulk_callback */
diff --git a/usb/usb-serial-visor-fix-race-in-open-close.patch b/usb/usb-serial-visor-fix-race-in-open-close.patch
new file mode 100644
index 0000000000000..c6482430c49d1
--- /dev/null
+++ b/usb/usb-serial-visor-fix-race-in-open-close.patch
@@ -0,0 +1,45 @@
+From ian.abbott@mev.co.uk Mon Jun 26 03:44:29 2006
+Message-ID: <449FBA86.5070800@mev.co.uk>
+Date: Mon, 26 Jun 2006 11:44:22 +0100
+From: Ian Abbott <abbotti@mev.co.uk>
+Cc: Greg KH <greg@kroah.com>
+Subject: USB serial visor: fix race in open/close
+
+From: Ian Abbott <abbotti@mev.co.uk>
+
+The anti user-DoS mechanism in the USB serial 'visor' driver can fail in
+the following way:
+
+visor_open: priv->outstanding_urbs = 0
+visor_write: ++priv->outstanding_urbs
+visor_close:
+visor_open: priv->outstanding_urbs = 0
+visor_write_bulk_callback: --priv->outstanding_urbs
+
+So priv->outstanding_urbs ends up as (unsigned long)(-1). Not good!
+
+I haven't seen this happen with the visor driver as I don't have the
+hardware, but I have seen it while testing a patch to implement the same
+functionality in the ftdi_sio driver (patch not yet submitted).
+
+The fix is pretty simple: don't reinitialize outstanding_urbs in
+visor_open. (Again, I haven't tested the fix in visor, but I have
+tested it in ftdi_sio.)
+
+Signed-off-by: Ian Abbott <abbotti@mev.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/serial/visor.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- gregkh-2.6.orig/drivers/usb/serial/visor.c
++++ gregkh-2.6/drivers/usb/serial/visor.c
+@@ -303,7 +303,6 @@ static int visor_open (struct usb_serial
+ spin_lock_irqsave(&priv->lock, flags);
+ priv->bytes_in = 0;
+ priv->bytes_out = 0;
+- priv->outstanding_urbs = 0;
+ priv->throttled = 0;
+ spin_unlock_irqrestore(&priv->lock, flags);
+
diff --git a/usb/usb-storage-uname-in-pr-sc-unneeded-message.patch b/usb/usb-storage-uname-in-pr-sc-unneeded-message.patch
new file mode 100644
index 0000000000000..a28d047e25cba
--- /dev/null
+++ b/usb/usb-storage-uname-in-pr-sc-unneeded-message.patch
@@ -0,0 +1,48 @@
+From phil@ipom.com Sat Jun 24 17:27:58 2006
+Message-ID: <449DD88A.8040003@ipom.com>
+Date: Sat, 24 Jun 2006 17:27:54 -0700
+From: Phil Dibowitz <phil@ipom.com>
+To: Greg KH <greg@kroah.com>
+Subject: USB Storage: Uname in PR/SC Unneeded message
+
+This patch adds the kernel version to the usb-storage Protocol/SubClass
+unneeded message in order to help us troubleshoot such problems.
+
+Signed-off-by: Phil Dibowitz <phil@ipom.com>
+Signed-off-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/storage/usb.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/storage/usb.c
++++ gregkh-2.6/drivers/usb/storage/usb.c
+@@ -47,6 +47,7 @@
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
++#include <linux/version.h>
+ #include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/errno.h>
+@@ -529,7 +530,8 @@ static void get_device_info(struct us_da
+ if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE))
+ printk(KERN_NOTICE USB_STORAGE "This device "
+ "(%04x,%04x,%04x S %02x P %02x)"
+- " has %s in unusual_devs.h\n"
++ " has %s in unusual_devs.h (kernel"
++ " %s)\n"
+ " Please send a copy of this message to "
+ "<linux-usb-devel@lists.sourceforge.net>\n",
+ le16_to_cpu(ddesc->idVendor),
+@@ -537,7 +539,8 @@ static void get_device_info(struct us_da
+ le16_to_cpu(ddesc->bcdDevice),
+ idesc->bInterfaceSubClass,
+ idesc->bInterfaceProtocol,
+- msgs[msg]);
++ msgs[msg],
++ UTS_RELEASE);
+ }
+ }
+
diff --git a/usb/usb-storage-us_fl_max_sectors_64-flag.patch b/usb/usb-storage-us_fl_max_sectors_64-flag.patch
new file mode 100644
index 0000000000000..59811c57f4f42
--- /dev/null
+++ b/usb/usb-storage-us_fl_max_sectors_64-flag.patch
@@ -0,0 +1,109 @@
+From phil@ipom.com Sat Jun 24 17:27:17 2006
+Message-ID: <449DD85E.7080503@ipom.com>
+Date: Sat, 24 Jun 2006 17:27:10 -0700
+From: Phil Dibowitz <phil@ipom.com>
+To: Greg KH <greg@kroah.com>
+Subject: USB Storage: US_FL_MAX_SECTORS_64 flag
+
+
+This patch adds a US_FL_MAX_SECTORS_64 and removes the Genesys special-cases
+for this that were in scsiglue.c. It also adds the flag to other devices
+reported to need it.
+
+Signed-off-by: Phil Dibowitz <phil@ipom.com>
+Signed-off-by: Matthew Dharm <mdharm-usb@one-eyed-alien.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ drivers/usb/storage/scsiglue.c | 12 +++++-------
+ drivers/usb/storage/unusual_devs.h | 16 ++++++++++++++--
+ drivers/usb/storage/usb.h | 4 ----
+ include/linux/usb_usual.h | 2 ++
+ 4 files changed, 21 insertions(+), 13 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/storage/scsiglue.c
++++ gregkh-2.6/drivers/usb/storage/scsiglue.c
+@@ -112,13 +112,11 @@ static int slave_configure(struct scsi_d
+ if (sdev->scsi_level < SCSI_2)
+ sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2;
+
+- /* According to the technical support people at Genesys Logic,
+- * devices using their chips have problems transferring more than
+- * 32 KB at a time. In practice people have found that 64 KB
+- * works okay and that's what Windows does. But we'll be
+- * conservative; people can always use the sysfs interface to
+- * increase max_sectors. */
+- if (le16_to_cpu(us->pusb_dev->descriptor.idVendor) == USB_VENDOR_ID_GENESYS &&
++ /* Many devices have trouble transfering more than 32KB at a time,
++ * while others have trouble with more than 64K. At this time we
++ * are limiting both to 32K (64 sectores).
++ */
++ if ((us->flags & US_FL_MAX_SECTORS_64) &&
+ sdev->request_queue->max_sectors > 64)
+ blk_queue_max_sectors(sdev->request_queue, 64);
+
+--- gregkh-2.6.orig/drivers/usb/storage/unusual_devs.h
++++ gregkh-2.6/drivers/usb/storage/unusual_devs.h
+@@ -716,18 +716,22 @@ UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x
+ * They were originally reported by Alexander Oltu
+ * <alexander@all-2.com> and Peter Marks <peter.marks@turner.com>
+ * respectively.
++ *
++ * US_FL_GO_SLOW and US_FL_MAX_SECTORS_64 added by Phil Dibowitz
++ * <phil@ipom.com> as these flags were made and hard-coded
++ * special-cases were pulled from scsiglue.c.
+ */
+ UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff,
+ "Genesys Logic",
+ "USB to IDE Optical",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+- US_FL_GO_SLOW ),
++ US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
+
+ UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff,
+ "Genesys Logic",
+ "USB to IDE Disk",
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+- US_FL_GO_SLOW ),
++ US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ),
+
+ /* Reported by Hanno Boeck <hanno@gmx.de>
+ * Taken from the Lycoris Kernel */
+@@ -1204,6 +1208,14 @@ UNUSUAL_DEV( 0x0ea0, 0x6828, 0x0110, 0x
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_IGNORE_RESIDUE ),
+
++/* Reported by Benjamin Schiller <sbenni@gmx.de>
++ * It is also sold by Easylite as DJ 20 */
++UNUSUAL_DEV( 0x0ed1, 0x7636, 0x0103, 0x0103,
++ "Typhoon",
++ "My DJ 1820",
++ US_SC_DEVICE, US_PR_DEVICE, NULL,
++ US_FL_IGNORE_RESIDUE | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64),
++
+ /* Reported by Michael Stattmann <michael@stattmann.com> */
+ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
+ "Sony Ericsson",
+--- gregkh-2.6.orig/drivers/usb/storage/usb.h
++++ gregkh-2.6/drivers/usb/storage/usb.h
+@@ -176,8 +176,4 @@ extern void fill_inquiry_response(struct
+ #define scsi_unlock(host) spin_unlock_irq(host->host_lock)
+ #define scsi_lock(host) spin_lock_irq(host->host_lock)
+
+-
+-/* Vendor ID list for devices that require special handling */
+-#define USB_VENDOR_ID_GENESYS 0x05e3 /* Genesys Logic */
+-
+ #endif
+--- gregkh-2.6.orig/include/linux/usb_usual.h
++++ gregkh-2.6/include/linux/usb_usual.h
+@@ -43,6 +43,8 @@
+ /* Need delay after Command phase */ \
+ US_FLAG(NO_WP_DETECT, 0x00000200) \
+ /* Don't check for write-protect */ \
++ US_FLAG(MAX_SECTORS_64, 0x00000400) \
++ /* Sets max_sectors to 64 */
+
+ #define US_FLAG(name, value) US_FL_##name = value ,
+ enum { US_DO_ALL_FLAGS };
diff --git a/usb/usb-unusual_devs-entry-for-samsung-mp3-player.patch b/usb/usb-unusual_devs-entry-for-samsung-mp3-player.patch
new file mode 100644
index 0000000000000..36cc096f352df
--- /dev/null
+++ b/usb/usb-unusual_devs-entry-for-samsung-mp3-player.patch
@@ -0,0 +1,39 @@
+From stern@rowland.harvard.edu Mon Jun 26 13:02:49 2006
+Date: Mon, 26 Jun 2006 16:02:43 -0400 (EDT)
+From: Alan Stern <stern@rowland.harvard.edu>
+To: Greg KH <greg@kroah.com>
+cc: Ernis <ernisv@gmail.com>, Phil Dibowitz <phil@ipom.com>, USB Storage list <usb-storage@lists.one-eyed-alien.net>
+Subject: USB: unusual_devs entry for Samsung MP3 player
+Message-ID: <Pine.LNX.4.44L0.0606261559590.14025-100000@iolanthe.rowland.org>
+
+From: Ernis <ernisv@gmail.com>
+
+This patch (as730) contains an unusual_devs entry for a Samsung MP3
+device.
+
+From: Ernis <ernisv@gmail.com>
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+
+---
+ drivers/usb/storage/unusual_devs.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- gregkh-2.6.orig/drivers/usb/storage/unusual_devs.h
++++ gregkh-2.6/drivers/usb/storage/unusual_devs.h
+@@ -113,6 +113,13 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x
+ US_SC_DEVICE, US_PR_DEVICE, NULL,
+ US_FL_FIX_INQUIRY ),
+
++/* Submitted by Ernestas Vaiciukevicius <ernisv@gmail.com> */
++UNUSUAL_DEV( 0x0419, 0x0100, 0x0100, 0x0100,
++ "Samsung Info. Systems America, Inc.",
++ "MP3 Player",
++ US_SC_DEVICE, US_PR_DEVICE, NULL,
++ US_FL_IGNORE_RESIDUE ),
++
+ /* Reported by Christian Leber <christian@leber.de> */
+ UNUSUAL_DEV( 0x0419, 0xaaf5, 0x0100, 0x0100,
+ "TrekStor",
diff --git a/usb/usbcore-fixes-for-hub_port_resume.patch b/usb/usbcore-fixes-for-hub_port_resume.patch
new file mode 100644
index 0000000000000..cb7b77b8fb52f
--- /dev/null
+++ b/usb/usbcore-fixes-for-hub_port_resume.patch
@@ -0,0 +1,37 @@
+From stern@rowland.harvard.edu Wed Jun 28 08:20:42 2006
+Date: Wed, 28 Jun 2006 11:20:41 -0400 (EDT)
+From: Alan Stern <stern@rowland.harvard.edu>
+To: Greg KH <greg@kroah.com>
+Subject: usbcore: fixes for hub_port_resume
+Message-ID: <Pine.LNX.4.44L0.0606281116010.6790-100000@iolanthe.rowland.org>
+
+This patch (as731) makes a couple of small fixes to the hub_port_resume
+routine:
+
+ Don't return status >= 0 when an error occurs;
+
+ Clear the port-change-suspend status indicator after
+ resuming a device.
+
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/core/hub.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- gregkh-2.6.orig/drivers/usb/core/hub.c
++++ gregkh-2.6/drivers/usb/core/hub.c
+@@ -1883,7 +1883,12 @@ hub_port_resume(struct usb_hub *hub, int
+ dev_dbg(hub->intfdev,
+ "port %d status %04x.%04x after resume, %d\n",
+ port1, portchange, devstatus, status);
++ if (status >= 0)
++ status = -ENODEV;
+ } else {
++ if (portchange & USB_PORT_STAT_C_SUSPEND)
++ clear_port_feature(hub->hdev, port1,
++ USB_PORT_FEAT_C_SUSPEND);
+ /* TRSMRCY = 10 msec */
+ msleep(10);
+ if (udev)
diff --git a/usb/usbip.patch b/usb/usbip.patch
index 215db582687ed..78da15bd294dc 100644
--- a/usb/usbip.patch
+++ b/usb/usbip.patch
@@ -29,7 +29,7 @@ a link to the userspace tools needed to get this to work.
--- gregkh-2.6.orig/drivers/usb/Kconfig
+++ gregkh-2.6/drivers/usb/Kconfig
-@@ -80,6 +80,8 @@ source "drivers/usb/core/Kconfig"
+@@ -81,6 +81,8 @@ source "drivers/usb/core/Kconfig"
source "drivers/usb/host/Kconfig"