aboutsummaryrefslogtreecommitdiffstats
path: root/usb
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-01-26 21:33:29 -0800
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-26 21:33:29 -0800
commitace1b9a23d60628c91662ff8259acc439a4f7392 (patch)
tree320dfd8efba9a3716cc53b9a59dc4d631b6613fc /usb
parent102a09d5962619353ce7935f4ea3f78e59ea427b (diff)
downloadpatches-ace1b9a23d60628c91662ff8259acc439a4f7392.tar.gz
more usb patches
Diffstat (limited to 'usb')
-rw-r--r--usb/usb-ehci-and-freescale-83xx-quirk.patch94
-rw-r--r--usb/usb-ehci-and-nf2-quirk.patch120
-rw-r--r--usb/usb-ehci-for-au1200.patch425
-rw-r--r--usb/usb-ehci-for-freescale-83xx.patch503
-rw-r--r--usb/usb-ehci-full-speed-iso-bugfixes.patch68
-rw-r--r--usb/usb-ehci-unlink-tweaks.patch44
-rw-r--r--usb/usb-gadget-zero-and-dma-coherent-buffers.patch44
-rw-r--r--usb/usb-ohci-for-au1200.patch241
-rw-r--r--usb/usb-usb-authentication-states.patch38
9 files changed, 1577 insertions, 0 deletions
diff --git a/usb/usb-ehci-and-freescale-83xx-quirk.patch b/usb/usb-ehci-and-freescale-83xx-quirk.patch
new file mode 100644
index 00000000000000..dcd4bf5cd741d7
--- /dev/null
+++ b/usb/usb-ehci-and-freescale-83xx-quirk.patch
@@ -0,0 +1,94 @@
+From david-b@pacbell.net Fri Jan 20 17:25:17 2006
+From: David Brownell <david-b@pacbell.net>
+To: Greg KH <greg@kroah.com>
+Subject: USB: EHCI and Freescale 83xx quirk
+Date: Fri, 20 Jan 2006 13:57:52 -0800
+Message-Id: <200601201357.52344.david-b@pacbell.net>
+
+From: Kumar Gala <galak@gate.crashing.org>
+
+On the MPC834x processors the multiport host (MPH) EHCI controller has an
+erratum in which the port number in the queue head expects to be 0..N-1
+instead of 1..N. If we are on one of these chips we subtract one from
+the port number before putting it into the queue head.
+
+Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-fsl.c | 10 ++++++++++
+ drivers/usb/host/ehci-q.c | 9 ++++++++-
+ drivers/usb/host/ehci.h | 15 +++++++++++++++
+ 3 files changed, 33 insertions(+), 1 deletion(-)
+
+--- gregkh-2.6.orig/drivers/usb/host/ehci-fsl.c
++++ gregkh-2.6/drivers/usb/host/ehci-fsl.c
+@@ -198,6 +198,16 @@ static void mpc83xx_usb_setup(struct usb
+ mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
+
+ if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
++ unsigned int chip, rev, svr;
++
++ svr = mfspr(SPRN_SVR);
++ chip = svr >> 16;
++ rev = (svr >> 4) & 0xf;
++
++ /* Deal with USB Erratum #14 on MPC834x Rev 1.0 & 1.1 chips */
++ if ((rev == 1) && (chip >= 0x8050) && (chip <= 0x8055))
++ ehci->has_fsl_port_bug = 1;
++
+ if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
+ mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
+ if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
+--- gregkh-2.6.orig/drivers/usb/host/ehci-q.c
++++ gregkh-2.6/drivers/usb/host/ehci-q.c
+@@ -721,7 +721,14 @@ qh_make (
+ info1 |= maxp << 16;
+
+ info2 |= (EHCI_TUNE_MULT_TT << 30);
+- info2 |= urb->dev->ttport << 23;
++
++ /* Some Freescale processors have an erratum in which the
++ * port number in the queue head was 0..N-1 instead of 1..N.
++ */
++ if (ehci_has_fsl_portno_bug(ehci))
++ info2 |= (urb->dev->ttport-1) << 23;
++ else
++ info2 |= urb->dev->ttport << 23;
+
+ /* set the address of the TT; for TDI's integrated
+ * root hub tt, leave it zeroed.
+--- gregkh-2.6.orig/drivers/usb/host/ehci.h
++++ gregkh-2.6/drivers/usb/host/ehci.h
+@@ -88,8 +88,11 @@ struct ehci_hcd { /* one per controlle
+ unsigned long next_statechange;
+ u32 command;
+
++ /* SILICON QUIRKS */
+ unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */
+ unsigned no_selective_suspend:1;
++ unsigned has_fsl_port_bug:1; /* FreeScale */
++
+ u8 sbrn; /* packed release number */
+
+ /* irq statistics */
+@@ -639,6 +642,18 @@ ehci_port_speed(struct ehci_hcd *ehci, u
+
+ /*-------------------------------------------------------------------------*/
+
++#ifdef CONFIG_PPC_83xx
++/* Some Freescale processors have an erratum in which the TT
++ * port number in the queue head was 0..N-1 instead of 1..N.
++ */
++#define ehci_has_fsl_portno_bug(e) ((e)->has_fsl_port_bug)
++#else
++#define ehci_has_fsl_portno_bug(e) (0)
++#endif
++
++
++/*-------------------------------------------------------------------------*/
++
+ #ifndef DEBUG
+ #define STUB_DEBUG_FILES
+ #endif /* DEBUG */
diff --git a/usb/usb-ehci-and-nf2-quirk.patch b/usb/usb-ehci-and-nf2-quirk.patch
new file mode 100644
index 00000000000000..e9d8d664f975a7
--- /dev/null
+++ b/usb/usb-ehci-and-nf2-quirk.patch
@@ -0,0 +1,120 @@
+From david-b@pacbell.net Fri Jan 20 17:25:17 2006
+From: David Brownell <david-b@pacbell.net>
+Subject: USB: EHCI and NF2 quirk
+To: Greg KH <greg@kroah.com>
+Date: Fri, 20 Jan 2006 13:55:14 -0800
+Message-Id: <200601201355.14378.david-b@pacbell.net>
+
+This teaches the EHCI driver about a quirk seen in older NForce2 chips,
+adding a workaround to ignore selective suspend requests. Bus-wide
+(so-called "global") suspend still works, as does USB wakeup of a
+root hub that's globally suspended.
+
+There's still a hole in this support though. Strictly speaking, this
+should _fail_ selective suspend requests, rather than ignoring them,
+since doing it this way means that devices which should be able to issue
+remote wakeup are not going to be able to do that. For now, we'll just
+live with that problem ... since usbcore expects to do selective suspend
+on the way towards a full bus suspend, and usbcore needs to be able to
+do full bus suspend.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-hub.c | 4 ++++
+ drivers/usb/host/ehci-pci.c | 25 ++++++++++++++++++++++++-
+ drivers/usb/host/ehci.h | 3 ++-
+ 3 files changed, 30 insertions(+), 2 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/host/ehci-pci.c
++++ gregkh-2.6/drivers/usb/host/ehci-pci.c
+@@ -106,11 +106,11 @@ static int ehci_pci_setup(struct usb_hcd
+ }
+ break;
+ case PCI_VENDOR_ID_NVIDIA:
++ switch (pdev->device) {
+ /* NVidia reports that certain chips don't handle
+ * QH, ITD, or SITD addresses above 2GB. (But TD,
+ * data buffer, and periodic schedule are normal.)
+ */
+- switch (pdev->device) {
+ case 0x003c: /* MCP04 */
+ case 0x005b: /* CK804 */
+ case 0x00d8: /* CK8 */
+@@ -120,6 +120,14 @@ static int ehci_pci_setup(struct usb_hcd
+ ehci_warn(ehci, "can't enable NVidia "
+ "workaround for >2GB RAM\n");
+ break;
++ /* Some NForce2 chips have problems with selective suspend;
++ * fixed in newer silicon.
++ */
++ case 0x0068:
++ pci_read_config_dword(pdev, PCI_REVISION_ID, &temp);
++ if ((temp & 0xff) < 0xa4)
++ ehci->no_selective_suspend = 1;
++ break;
+ }
+ break;
+ }
+@@ -163,6 +171,21 @@ static int ehci_pci_setup(struct usb_hcd
+ device_init_wakeup(&pdev->dev, 1);
+ }
+
++#ifdef CONFIG_USB_SUSPEND
++ /* REVISIT: the controller works fine for wakeup iff the root hub
++ * itself is "globally" suspended, but usbcore currently doesn't
++ * understand such things.
++ *
++ * System suspend currently expects to be able to suspend the entire
++ * device tree, device-at-a-time. If we failed selective suspend
++ * reports, system suspend would fail; so the root hub code must claim
++ * success. That's lying to usbcore, and it matters for for runtime
++ * PM scenarios with selective suspend and remote wakeup...
++ */
++ if (ehci->no_selective_suspend && device_can_wakeup(&pdev->dev))
++ ehci_warn(ehci, "selective suspend/wakeup unavailable\n");
++#endif
++
+ retval = ehci_pci_reinit(ehci, pdev);
+ done:
+ return retval;
+--- gregkh-2.6.orig/drivers/usb/host/ehci-hub.c
++++ gregkh-2.6/drivers/usb/host/ehci-hub.c
+@@ -359,6 +359,8 @@ static int ehci_hub_control (
+ case USB_PORT_FEAT_SUSPEND:
+ if (temp & PORT_RESET)
+ goto error;
++ if (ehci->no_selective_suspend)
++ break;
+ if (temp & PORT_SUSPEND) {
+ if ((temp & PORT_PE) == 0)
+ goto error;
+@@ -514,6 +516,8 @@ static int ehci_hub_control (
+ temp &= ~PORT_RWC_BITS;
+ switch (wValue) {
+ case USB_PORT_FEAT_SUSPEND:
++ if (ehci->no_selective_suspend)
++ break;
+ if ((temp & PORT_PE) == 0
+ || (temp & PORT_RESET) != 0)
+ goto error;
+--- gregkh-2.6.orig/drivers/usb/host/ehci.h
++++ gregkh-2.6/drivers/usb/host/ehci.h
+@@ -89,6 +89,8 @@ struct ehci_hcd { /* one per controlle
+ u32 command;
+
+ unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */
++ unsigned no_selective_suspend:1;
++ u8 sbrn; /* packed release number */
+
+ /* irq statistics */
+ #ifdef EHCI_STATS
+@@ -97,7 +99,6 @@ struct ehci_hcd { /* one per controlle
+ #else
+ # define COUNT(x) do {} while (0)
+ #endif
+- u8 sbrn; /* packed release number */
+ };
+
+ /* convert between an HCD pointer and the corresponding EHCI_HCD */
diff --git a/usb/usb-ehci-for-au1200.patch b/usb/usb-ehci-for-au1200.patch
new file mode 100644
index 00000000000000..7ab53dc8f9d121
--- /dev/null
+++ b/usb/usb-ehci-for-au1200.patch
@@ -0,0 +1,425 @@
+From david-b@pacbell.net Fri Jan 20 17:25:17 2006
+From: Jordan Crouse <jordan.crouse@amd.com>
+To: Greg KH <greg@kroah.com>
+Subject: USB: EHCI for AU1200
+Date: Fri, 20 Jan 2006 14:06:09 -0800
+Message-Id: <200601201406.10265.david-b@pacbell.net>
+
+
+ALCHEMY: Add EHCI support for AU1200
+
+Updated by removing the OHCI support
+
+Signed-off-by: Jordan Crouse <jordan.crouse@amd.com>
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ arch/mips/au1000/common/cputable.c | 2
+ arch/mips/au1000/common/platform.c | 2
+ drivers/usb/Kconfig | 9
+ drivers/usb/host/Kconfig | 2
+ drivers/usb/host/ehci-au1xxx.c | 297 +++++++++++++++++++++
+ drivers/usb/host/ehci-hcd.c | 11
+ include/asm-mips/mach-mips/cpu-feature-overrides.h | 4
+ 7 files changed, 319 insertions(+), 8 deletions(-)
+
+--- gregkh-2.6.orig/arch/mips/au1000/common/cputable.c
++++ gregkh-2.6/arch/mips/au1000/common/cputable.c
+@@ -38,7 +38,7 @@ struct cpu_spec cpu_specs[] = {
+ { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1 },
+ { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1 },
+ { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0 },
+- { 0xffffffff, 0x04030201, "Au1200 AC", 0, 1 },
++ { 0xffffffff, 0x04030201, "Au1200 AC", 1, 0 },
+ { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0 },
+ };
+
+--- gregkh-2.6.orig/arch/mips/au1000/common/platform.c
++++ gregkh-2.6/arch/mips/au1000/common/platform.c
+@@ -278,9 +278,7 @@ static struct platform_device *au1xxx_pl
+ &au1100_lcd_device,
+ #endif
+ #ifdef CONFIG_SOC_AU1200
+-#if 0 /* fixme */
+ &au1xxx_usb_ehci_device,
+-#endif
+ &au1xxx_usb_gdt_device,
+ &au1xxx_usb_otg_device,
+ &au1200_lcd_device,
+--- gregkh-2.6.orig/drivers/usb/Kconfig
++++ gregkh-2.6/drivers/usb/Kconfig
+@@ -10,8 +10,8 @@ menu "USB support"
+ config USB_ARCH_HAS_HCD
+ boolean
+ default y if USB_ARCH_HAS_OHCI
++ default y if USB_ARCH_HAS_EHCI
+ default y if ARM # SL-811
+- default y if PPC_83xx
+ default PCI
+
+ # many non-PCI SOC chips embed OHCI
+@@ -31,6 +31,13 @@ config USB_ARCH_HAS_OHCI
+ # more:
+ default PCI
+
++# some non-PCI hcds implement EHCI
++config USB_ARCH_HAS_EHCI
++ boolean
++ default y if PPC_83xx
++ default y if SOC_AU1200
++ default PCI
++
+ # ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
+ config USB
+ tristate "Support for Host-side USB"
+--- gregkh-2.6.orig/drivers/usb/host/Kconfig
++++ gregkh-2.6/drivers/usb/host/Kconfig
+@@ -6,7 +6,7 @@ comment "USB Host Controller Drivers"
+
+ config USB_EHCI_HCD
+ tristate "EHCI HCD (USB 2.0) support"
+- depends on USB && (PCI || PPC_83xx)
++ depends on USB && USB_ARCH_HAS_EHCI
+ ---help---
+ The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
+ "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
+--- /dev/null
++++ gregkh-2.6/drivers/usb/host/ehci-au1xxx.c
+@@ -0,0 +1,297 @@
++/*
++ * EHCI HCD (Host Controller Driver) for USB.
++ *
++ * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
++ *
++ * Bus Glue for AMD Alchemy Au1xxx
++ *
++ * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org>
++ *
++ * Modified for AMD Alchemy Au1200 EHC
++ * by K.Boge <karsten.boge@amd.com>
++ *
++ * This file is licenced under the GPL.
++ */
++
++#include <linux/platform_device.h>
++#include <asm/mach-au1x00/au1000.h>
++
++#ifndef CONFIG_SOC_AU1200
++#error "this Alchemy chip doesn't have EHCI"
++#else /* Au1200 */
++
++#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG)
++#define USB_MCFG_PFEN (1<<31)
++#define USB_MCFG_RDCOMB (1<<30)
++#define USB_MCFG_SSDEN (1<<23)
++#define USB_MCFG_PHYPLLEN (1<<19)
++#define USB_MCFG_EHCCLKEN (1<<17)
++#define USB_MCFG_UCAM (1<<7)
++#define USB_MCFG_EBMEN (1<<3)
++#define USB_MCFG_EMEMEN (1<<2)
++
++#define USBH_ENABLE_CE (USB_MCFG_PHYPLLEN | USB_MCFG_EHCCLKEN)
++
++#ifdef CONFIG_DMA_COHERENT
++#define USBH_ENABLE_INIT (USBH_ENABLE_CE \
++ | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
++ | USB_MCFG_SSDEN | USB_MCFG_UCAM \
++ | USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
++#else
++#define USBH_ENABLE_INIT (USBH_ENABLE_CE \
++ | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
++ | USB_MCFG_SSDEN \
++ | USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
++#endif
++#define USBH_DISABLE (USB_MCFG_EBMEN | USB_MCFG_EMEMEN)
++
++#endif /* Au1200 */
++
++extern int usb_disabled(void);
++
++/*-------------------------------------------------------------------------*/
++
++static void au1xxx_start_ehc(struct platform_device *dev)
++{
++ pr_debug(__FILE__ ": starting Au1xxx EHCI USB Controller\n");
++
++ /* write HW defaults again in case Yamon cleared them */
++ if (au_readl(USB_HOST_CONFIG) == 0) {
++ au_writel(0x00d02000, USB_HOST_CONFIG);
++ au_readl(USB_HOST_CONFIG);
++ udelay(1000);
++ }
++ /* enable host controller */
++ au_writel(USBH_ENABLE_CE | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
++ au_readl(USB_HOST_CONFIG);
++ udelay(1000);
++ au_writel(USBH_ENABLE_INIT | au_readl(USB_HOST_CONFIG),
++ USB_HOST_CONFIG);
++ au_readl(USB_HOST_CONFIG);
++ udelay(1000);
++
++ pr_debug(__FILE__ ": Clock to USB host has been enabled\n");
++}
++
++static void au1xxx_stop_ehc(struct platform_device *dev)
++{
++ pr_debug(__FILE__ ": stopping Au1xxx EHCI USB Controller\n");
++
++ /* Disable mem */
++ au_writel(~USBH_DISABLE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
++ udelay(1000);
++ /* Disable clock */
++ au_writel(~USB_MCFG_EHCCLKEN & au_readl(USB_HOST_CONFIG),
++ USB_HOST_CONFIG);
++ au_readl(USB_HOST_CONFIG);
++}
++
++/*-------------------------------------------------------------------------*/
++
++/* configure so an HC device and id are always provided */
++/* always called with process context; sleeping is OK */
++
++/**
++ * usb_ehci_au1xxx_probe - initialize Au1xxx-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_ehci_au1xxx_probe(const struct hc_driver *driver,
++ struct usb_hcd **hcd_out, struct platform_device *dev)
++{
++ int retval;
++ struct usb_hcd *hcd;
++ struct ehci_hcd *ehci;
++
++#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
++
++ /* Au1200 AB USB does not support coherent memory */
++ if (!(read_c0_prid() & 0xff)) {
++ pr_info("%s: this is chip revision AB!\n", dev->dev.name);
++ pr_info("%s: update your board or re-configure the kernel\n",
++ dev->dev.name);
++ return -ENODEV;
++ }
++#endif
++
++ au1xxx_start_ehc(dev);
++
++ if (dev->resource[1].flags != IORESOURCE_IRQ) {
++ pr_debug("resource[1] is not IORESOURCE_IRQ");
++ retval = -ENOMEM;
++ }
++ hcd = usb_create_hcd(driver, &dev->dev, "Au1xxx");
++ if (!hcd)
++ return -ENOMEM;
++ hcd->rsrc_start = dev->resource[0].start;
++ hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
++
++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
++ pr_debug("request_mem_region failed");
++ retval = -EBUSY;
++ goto err1;
++ }
++
++ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
++ if (!hcd->regs) {
++ pr_debug("ioremap failed");
++ retval = -ENOMEM;
++ goto err2;
++ }
++
++ ehci = hcd_to_ehci(hcd);
++ ehci->caps = hcd->regs;
++ ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase));
++ /* cache this readonly data; minimize chip reads */
++ ehci->hcs_params = readl(&ehci->caps->hcs_params);
++
++ /* ehci_hcd_init(hcd_to_ehci(hcd)); */
++
++ retval =
++ usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT | SA_SHIRQ);
++ if (retval == 0)
++ return retval;
++
++ au1xxx_stop_ehc(dev);
++ iounmap(hcd->regs);
++err2:
++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++err1:
++ usb_put_hcd(hcd);
++ return retval;
++}
++
++/* may be called without controller electrically present */
++/* may be called with controller, bus, and devices active */
++
++/**
++ * usb_ehci_hcd_au1xxx_remove - shutdown processing for Au1xxx-based HCDs
++ * @dev: USB Host Controller being removed
++ * Context: !in_interrupt()
++ *
++ * Reverses the effect of usb_ehci_hcd_au1xxx_probe(), first invoking
++ * the HCD's stop() method. It is always called from a thread
++ * context, normally "rmmod", "apmd", or something similar.
++ *
++ */
++void usb_ehci_au1xxx_remove(struct usb_hcd *hcd, struct platform_device *dev)
++{
++ usb_remove_hcd(hcd);
++ iounmap(hcd->regs);
++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++ usb_put_hcd(hcd);
++ au1xxx_stop_ehc(dev);
++}
++
++/*-------------------------------------------------------------------------*/
++
++static const struct hc_driver ehci_au1xxx_hc_driver = {
++ .description = hcd_name,
++ .product_desc = "Au1xxx EHCI",
++ .hcd_priv_size = sizeof(struct ehci_hcd),
++
++ /*
++ * generic hardware linkage
++ */
++ .irq = ehci_irq,
++ .flags = HCD_MEMORY | HCD_USB2,
++
++ /*
++ * basic lifecycle operations
++ */
++ .reset = ehci_init,
++ .start = ehci_run,
++ .stop = ehci_stop,
++
++ /*
++ * managing i/o requests and associated device resources
++ */
++ .urb_enqueue = ehci_urb_enqueue,
++ .urb_dequeue = ehci_urb_dequeue,
++ .endpoint_disable = ehci_endpoint_disable,
++
++ /*
++ * scheduling support
++ */
++ .get_frame_number = ehci_get_frame,
++
++ /*
++ * root hub support
++ */
++ .hub_status_data = ehci_hub_status_data,
++ .hub_control = ehci_hub_control,
++#ifdef CONFIG_PM
++ .hub_suspend = ehci_hub_suspend,
++ .hub_resume = ehci_hub_resume,
++#endif
++};
++
++/*-------------------------------------------------------------------------*/
++
++static int ehci_hcd_au1xxx_drv_probe(struct device *dev)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct usb_hcd *hcd = NULL;
++ int ret;
++
++ pr_debug("In ehci_hcd_au1xxx_drv_probe\n");
++
++ if (usb_disabled())
++ return -ENODEV;
++
++ ret = usb_ehci_au1xxx_probe(&ehci_au1xxx_hc_driver, &hcd, pdev);
++ return ret;
++}
++
++static int ehci_hcd_au1xxx_drv_remove(struct device *dev)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct usb_hcd *hcd = dev_get_drvdata(dev);
++
++ usb_ehci_au1xxx_remove(hcd, pdev);
++ return 0;
++}
++
++ /*TBD*/
++/*static int ehci_hcd_au1xxx_drv_suspend(struct device *dev)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct usb_hcd *hcd = dev_get_drvdata(dev);
++
++ return 0;
++}
++static int ehci_hcd_au1xxx_drv_resume(struct device *dev)
++{
++ struct platform_device *pdev = to_platform_device(dev);
++ struct usb_hcd *hcd = dev_get_drvdata(dev);
++
++ return 0;
++}
++*/
++static struct device_driver ehci_hcd_au1xxx_driver = {
++ .name = "au1xxx-ehci",
++ .bus = &platform_bus_type,
++ .probe = ehci_hcd_au1xxx_drv_probe,
++ .remove = ehci_hcd_au1xxx_drv_remove,
++ /*.suspend = ehci_hcd_au1xxx_drv_suspend, */
++ /*.resume = ehci_hcd_au1xxx_drv_resume, */
++};
++
++static int __init ehci_hcd_au1xxx_init(void)
++{
++ pr_debug(DRIVER_INFO " (Au1xxx)\n");
++
++ return driver_register(&ehci_hcd_au1xxx_driver);
++}
++
++static void __exit ehci_hcd_au1xxx_cleanup(void)
++{
++ driver_unregister(&ehci_hcd_au1xxx_driver);
++}
++
++module_init(ehci_hcd_au1xxx_init);
++module_exit(ehci_hcd_au1xxx_cleanup);
+--- gregkh-2.6.orig/drivers/usb/host/ehci-hcd.c
++++ gregkh-2.6/drivers/usb/host/ehci-hcd.c
+@@ -889,14 +889,19 @@ MODULE_LICENSE ("GPL");
+
+ #ifdef CONFIG_PCI
+ #include "ehci-pci.c"
++#define EHCI_BUS_GLUED
+ #endif
+
+ #ifdef CONFIG_PPC_83xx
+ #include "ehci-fsl.c"
++#define EHCI_BUS_GLUED
+ #endif
+
+-#if !(defined(CONFIG_PCI) || \
+- defined(CONFIG_PPC_83xx) \
+- )
++#ifdef CONFIG_SOC_AU1X00
++#include "ehci-au1xxx.c"
++#define EHCI_BUS_GLUED
++#endif
++
++#ifndef EHCI_BUS_GLUED
+ #error "missing bus glue for ehci-hcd"
+ #endif
+--- gregkh-2.6.orig/include/asm-mips/mach-mips/cpu-feature-overrides.h
++++ gregkh-2.6/include/asm-mips/mach-mips/cpu-feature-overrides.h
+@@ -29,7 +29,11 @@
+ /* #define cpu_has_prefetch ? */
+ #define cpu_has_mcheck 1
+ /* #define cpu_has_ejtag ? */
++#ifdef CONFIG_CPU_HAS_LLSC
+ #define cpu_has_llsc 1
++#else
++#define cpu_has_llsc 0
++#endif
+ /* #define cpu_has_vtag_icache ? */
+ /* #define cpu_has_dc_aliases ? */
+ /* #define cpu_has_ic_fills_f_dc ? */
diff --git a/usb/usb-ehci-for-freescale-83xx.patch b/usb/usb-ehci-for-freescale-83xx.patch
new file mode 100644
index 00000000000000..9d29889daa8dfc
--- /dev/null
+++ b/usb/usb-ehci-for-freescale-83xx.patch
@@ -0,0 +1,503 @@
+From david-b@pacbell.net Fri Jan 20 17:25:17 2006
+From: David Brownell <david-b@pacbell.net>
+To: Greg KH <greg@kroah.com>
+Subject: USB: EHCI for Freescale 83xx
+Date: Fri, 20 Jan 2006 13:53:38 -0800
+Cc: linux-usb-devel@lists.sourceforge.net
+Message-Id: <200601201353.38733.david-b@pacbell.net>
+
+From: Randy Vinson <rvinson@mvista.com>
+
+Adding a Host Mode USB driver for the Freescale 83xx.
+
+This driver supports both the Dual-Role (DR) controller and the
+Multi-Port-Host (MPH) controller present in the Freescale MPC8349. It has
+been tested with the MPC8349CDS reference system. This driver depends on
+platform support code for setting up the pins on the device package in a
+manner appropriate for the board in use. Note that this patch requires
+selecting the EHCI controller option under the USB Host menu.
+
+Signed-off-by: Randy Vinson <rvinson@mvista.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/Kconfig | 1
+ drivers/usb/host/Kconfig | 2
+ drivers/usb/host/ehci-fsl.c | 357 ++++++++++++++++++++++++++++++++++++++++++++
+ drivers/usb/host/ehci-fsl.h | 37 ++++
+ drivers/usb/host/ehci-hcd.c | 8
+ include/linux/fsl_devices.h | 27 +++
+ 6 files changed, 430 insertions(+), 2 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/Kconfig
++++ gregkh-2.6/drivers/usb/Kconfig
+@@ -11,6 +11,7 @@ config USB_ARCH_HAS_HCD
+ boolean
+ default y if USB_ARCH_HAS_OHCI
+ default y if ARM # SL-811
++ default y if PPC_83xx
+ default PCI
+
+ # many non-PCI SOC chips embed OHCI
+--- gregkh-2.6.orig/drivers/usb/host/Kconfig
++++ gregkh-2.6/drivers/usb/host/Kconfig
+@@ -6,7 +6,7 @@ comment "USB Host Controller Drivers"
+
+ config USB_EHCI_HCD
+ tristate "EHCI HCD (USB 2.0) support"
+- depends on USB && PCI
++ depends on USB && (PCI || PPC_83xx)
+ ---help---
+ The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0
+ "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware.
+--- /dev/null
++++ gregkh-2.6/drivers/usb/host/ehci-fsl.c
+@@ -0,0 +1,357 @@
++/*
++ * (C) Copyright David Brownell 2000-2002
++ * Copyright (c) 2005 MontaVista Software
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
++ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
++ * for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software Foundation,
++ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
++ *
++ * Ported to 834x by Randy Vinson <rvinson@mvista.com> using code provided
++ * by Hunter Wu.
++ */
++
++#include <linux/platform_device.h>
++#include <linux/fsl_devices.h>
++
++#include "ehci-fsl.h"
++
++/* FIXME: Power Managment is un-ported so temporarily disable it */
++#undef CONFIG_PM
++
++/* PCI-based HCs are common, but plenty of non-PCI HCs are used too */
++
++/* configure so an HC device and id are always provided */
++/* always called with process context; sleeping is OK */
++
++/**
++ * usb_hcd_fsl_probe - initialize FSL-based HCDs
++ * @drvier: Driver to be used for this HCD
++ * @pdev: USB Host Controller being probed
++ * Context: !in_interrupt()
++ *
++ * Allocates basic resources for this USB host controller.
++ *
++ */
++int usb_hcd_fsl_probe(const struct hc_driver *driver,
++ struct platform_device *pdev)
++{
++ struct fsl_usb2_platform_data *pdata;
++ struct usb_hcd *hcd;
++ struct resource *res;
++ int irq;
++ int retval;
++ unsigned int temp;
++
++ pr_debug("initializing FSL-SOC USB Controller\n");
++
++ /* Need platform data for setup */
++ pdata = (struct fsl_usb2_platform_data *)pdev->dev.platform_data;
++ if (!pdata) {
++ dev_err(&pdev->dev,
++ "No platform data for %s.\n", pdev->dev.bus_id);
++ return -ENODEV;
++ }
++
++ /*
++ * This is a host mode driver, verify that we're supposed to be
++ * in host mode.
++ */
++ if (!((pdata->operating_mode == FSL_USB2_DR_HOST) ||
++ (pdata->operating_mode == FSL_USB2_MPH_HOST))) {
++ dev_err(&pdev->dev,
++ "Non Host Mode configured for %s. Wrong driver linked.\n",
++ pdev->dev.bus_id);
++ return -ENODEV;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
++ if (!res) {
++ dev_err(&pdev->dev,
++ "Found HC with no IRQ. Check %s setup!\n",
++ pdev->dev.bus_id);
++ return -ENODEV;
++ }
++ irq = res->start;
++
++ hcd = usb_create_hcd(driver, &pdev->dev, pdev->dev.bus_id);
++ if (!hcd) {
++ retval = -ENOMEM;
++ goto err1;
++ }
++
++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
++ if (!res) {
++ dev_err(&pdev->dev,
++ "Found HC with no register addr. Check %s setup!\n",
++ pdev->dev.bus_id);
++ retval = -ENODEV;
++ goto err2;
++ }
++ hcd->rsrc_start = res->start;
++ hcd->rsrc_len = res->end - res->start + 1;
++ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len,
++ driver->description)) {
++ dev_dbg(&pdev->dev, "controller already in use\n");
++ retval = -EBUSY;
++ goto err2;
++ }
++ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
++
++ if (hcd->regs == NULL) {
++ dev_dbg(&pdev->dev, "error mapping memory\n");
++ retval = -EFAULT;
++ goto err3;
++ }
++
++ /* Enable USB controller */
++ temp = in_be32(hcd->regs + 0x500);
++ out_be32(hcd->regs + 0x500, temp | 0x4);
++
++ /* Set to Host mode */
++ temp = in_le32(hcd->regs + 0x1a8);
++ out_le32(hcd->regs + 0x1a8, temp | 0x3);
++
++ retval = usb_add_hcd(hcd, irq, SA_SHIRQ);
++ if (retval != 0)
++ goto err4;
++ return retval;
++
++ err4:
++ iounmap(hcd->regs);
++ err3:
++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++ err2:
++ usb_put_hcd(hcd);
++ err1:
++ dev_err(&pdev->dev, "init %s fail, %d\n", pdev->dev.bus_id, retval);
++ return retval;
++}
++
++/* may be called without controller electrically present */
++/* may be called with controller, bus, and devices active */
++
++/**
++ * usb_hcd_fsl_remove - shutdown processing for FSL-based HCDs
++ * @dev: USB Host Controller being removed
++ * Context: !in_interrupt()
++ *
++ * Reverses the effect of usb_hcd_fsl_probe().
++ *
++ */
++void usb_hcd_fsl_remove(struct usb_hcd *hcd, struct platform_device *pdev)
++{
++ usb_remove_hcd(hcd);
++ iounmap(hcd->regs);
++ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
++ usb_put_hcd(hcd);
++}
++
++static void mpc83xx_setup_phy(struct ehci_hcd *ehci,
++ enum fsl_usb2_phy_modes phy_mode,
++ unsigned int port_offset)
++{
++ u32 portsc = readl(&ehci->regs->port_status[port_offset]);
++ portsc &= ~PORT_PTS_MSK;
++ switch (phy_mode) {
++ case FSL_USB2_PHY_ULPI:
++ portsc |= PORT_PTS_ULPI;
++ break;
++ case FSL_USB2_PHY_SERIAL:
++ portsc |= PORT_PTS_SERIAL;
++ break;
++ case FSL_USB2_PHY_UTMI_WIDE:
++ portsc |= PORT_PTS_PTW;
++ /* fall through */
++ case FSL_USB2_PHY_UTMI:
++ portsc |= PORT_PTS_UTMI;
++ break;
++ case FSL_USB2_PHY_NONE:
++ break;
++ }
++ writel(portsc, &ehci->regs->port_status[port_offset]);
++}
++
++static void mpc83xx_usb_setup(struct usb_hcd *hcd)
++{
++ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++ struct fsl_usb2_platform_data *pdata;
++ void __iomem *non_ehci = hcd->regs;
++
++ pdata =
++ (struct fsl_usb2_platform_data *)hcd->self.controller->
++ platform_data;
++ /* Enable PHY interface in the control reg. */
++ out_be32(non_ehci + FSL_SOC_USB_CTRL, 0x00000004);
++ out_be32(non_ehci + FSL_SOC_USB_SNOOP1, 0x0000001b);
++
++ if (pdata->operating_mode == FSL_USB2_DR_HOST)
++ mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
++
++ if (pdata->operating_mode == FSL_USB2_MPH_HOST) {
++ if (pdata->port_enables & FSL_USB2_PORT0_ENABLED)
++ mpc83xx_setup_phy(ehci, pdata->phy_mode, 0);
++ if (pdata->port_enables & FSL_USB2_PORT1_ENABLED)
++ mpc83xx_setup_phy(ehci, pdata->phy_mode, 1);
++ }
++
++ /* put controller in host mode. */
++ writel(0x00000003, non_ehci + FSL_SOC_USB_USBMODE);
++ out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c);
++ out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040);
++ out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001);
++}
++
++/* called after powerup, by probe or system-pm "wakeup" */
++static int ehci_fsl_reinit(struct ehci_hcd *ehci)
++{
++ mpc83xx_usb_setup(ehci_to_hcd(ehci));
++ ehci_port_power(ehci, 0);
++
++ return 0;
++}
++
++/* called during probe() after chip reset completes */
++static int ehci_fsl_setup(struct usb_hcd *hcd)
++{
++ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
++ int retval;
++
++ /* EHCI registers start at offset 0x100 */
++ ehci->caps = hcd->regs + 0x100;
++ ehci->regs = hcd->regs + 0x100 +
++ HC_LENGTH(readl(&ehci->caps->hc_capbase));
++ dbg_hcs_params(ehci, "reset");
++ dbg_hcc_params(ehci, "reset");
++
++ /* cache this readonly data; minimize chip reads */
++ ehci->hcs_params = readl(&ehci->caps->hcs_params);
++
++ retval = ehci_halt(ehci);
++ if (retval)
++ return retval;
++
++ /* data structure init */
++ retval = ehci_init(hcd);
++ if (retval)
++ return retval;
++
++ ehci->is_tdi_rh_tt = 1;
++
++ ehci->sbrn = 0x20;
++
++ ehci_reset(ehci);
++
++ retval = ehci_fsl_reinit(ehci);
++ return retval;
++}
++
++static const struct hc_driver ehci_fsl_hc_driver = {
++ .description = hcd_name,
++ .product_desc = "Freescale On-Chip EHCI Host Controller",
++ .hcd_priv_size = sizeof(struct ehci_hcd),
++
++ /*
++ * generic hardware linkage
++ */
++ .irq = ehci_irq,
++ .flags = HCD_USB2,
++
++ /*
++ * basic lifecycle operations
++ */
++ .reset = ehci_fsl_setup,
++ .start = ehci_run,
++#ifdef CONFIG_PM
++ .suspend = ehci_bus_suspend,
++ .resume = ehci_bus_resume,
++#endif
++ .stop = ehci_stop,
++
++ /*
++ * managing i/o requests and associated device resources
++ */
++ .urb_enqueue = ehci_urb_enqueue,
++ .urb_dequeue = ehci_urb_dequeue,
++ .endpoint_disable = ehci_endpoint_disable,
++
++ /*
++ * scheduling support
++ */
++ .get_frame_number = ehci_get_frame,
++
++ /*
++ * root hub support
++ */
++ .hub_status_data = ehci_hub_status_data,
++ .hub_control = ehci_hub_control,
++ .bus_suspend = ehci_bus_suspend,
++ .bus_resume = ehci_bus_resume,
++};
++
++static int ehci_fsl_drv_probe(struct platform_device *pdev)
++{
++ if (usb_disabled())
++ return -ENODEV;
++
++ return usb_hcd_fsl_probe(&ehci_fsl_hc_driver, pdev);
++}
++
++static int ehci_fsl_drv_remove(struct platform_device *pdev)
++{
++ struct usb_hcd *hcd = platform_get_drvdata(pdev);
++
++ usb_hcd_fsl_remove(hcd, pdev);
++
++ return 0;
++}
++
++static struct platform_driver ehci_fsl_dr_driver = {
++ .probe = ehci_fsl_drv_probe,
++ .remove = ehci_fsl_drv_remove,
++ .driver = {
++ .name = "fsl-usb2-dr",
++ },
++};
++
++static struct platform_driver ehci_fsl_mph_driver = {
++ .probe = ehci_fsl_drv_probe,
++ .remove = ehci_fsl_drv_remove,
++ .driver = {
++ .name = "fsl-usb2-mph",
++ },
++};
++
++static int __init ehci_fsl_init(void)
++{
++ int retval;
++
++ pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
++ hcd_name,
++ sizeof(struct ehci_qh), sizeof(struct ehci_qtd),
++ sizeof(struct ehci_itd), sizeof(struct ehci_sitd));
++
++ retval = platform_driver_register(&ehci_fsl_dr_driver);
++ if (retval)
++ return retval;
++
++ return platform_driver_register(&ehci_fsl_mph_driver);
++}
++
++static void __exit ehci_fsl_cleanup(void)
++{
++ platform_driver_unregister(&ehci_fsl_mph_driver);
++ platform_driver_unregister(&ehci_fsl_dr_driver);
++}
++
++module_init(ehci_fsl_init);
++module_exit(ehci_fsl_cleanup);
+--- /dev/null
++++ gregkh-2.6/drivers/usb/host/ehci-fsl.h
+@@ -0,0 +1,37 @@
++/* Copyright (c) 2005 freescale semiconductor
++ * Copyright (c) 2005 MontaVista Software
++ *
++ * This program is free software; you can redistribute it and/or modify it
++ * under the terms of the GNU General Public License as published by the
++ * Free Software Foundation; either version 2 of the License, or (at your
++ * option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful, but
++ * WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 675 Mass Ave, Cambridge, MA 02139, USA.
++ */
++#ifndef _EHCI_FSL_H
++#define _EHCI_FSL_H
++
++/* offsets for the non-ehci registers in the FSL SOC USB controller */
++#define FSL_SOC_USB_ULPIVP 0x170
++#define FSL_SOC_USB_PORTSC1 0x184
++#define PORT_PTS_MSK (3<<30)
++#define PORT_PTS_UTMI (0<<30)
++#define PORT_PTS_ULPI (2<<30)
++#define PORT_PTS_SERIAL (3<<30)
++#define PORT_PTS_PTW (1<<28)
++#define FSL_SOC_USB_PORTSC2 0x188
++#define FSL_SOC_USB_USBMODE 0x1a8
++#define FSL_SOC_USB_SNOOP1 0x400 /* NOTE: big-endian */
++#define FSL_SOC_USB_SNOOP2 0x404 /* NOTE: big-endian */
++#define FSL_SOC_USB_AGECNTTHRSH 0x408 /* NOTE: big-endian */
++#define FSL_SOC_USB_SICTRL 0x40c /* NOTE: big-endian */
++#define FSL_SOC_USB_PRICTRL 0x410 /* NOTE: big-endian */
++#define FSL_SOC_USB_CTRL 0x500 /* NOTE: big-endian */
++#endif /* _EHCI_FSL_H */
+--- gregkh-2.6.orig/drivers/usb/host/ehci-hcd.c
++++ gregkh-2.6/drivers/usb/host/ehci-hcd.c
+@@ -891,6 +891,12 @@ MODULE_LICENSE ("GPL");
+ #include "ehci-pci.c"
+ #endif
+
+-#if !defined(CONFIG_PCI)
++#ifdef CONFIG_PPC_83xx
++#include "ehci-fsl.c"
++#endif
++
++#if !(defined(CONFIG_PCI) || \
++ defined(CONFIG_PPC_83xx) \
++ )
+ #error "missing bus glue for ehci-hcd"
+ #endif
+--- gregkh-2.6.orig/include/linux/fsl_devices.h
++++ gregkh-2.6/include/linux/fsl_devices.h
+@@ -83,5 +83,32 @@ struct fsl_i2c_platform_data {
+ #define FSL_I2C_DEV_SEPARATE_DFSRR 0x00000001
+ #define FSL_I2C_DEV_CLOCK_5200 0x00000002
+
++
++enum fsl_usb2_operating_modes {
++ FSL_USB2_MPH_HOST,
++ FSL_USB2_DR_HOST,
++ FSL_USB2_DR_DEVICE,
++ FSL_USB2_DR_OTG,
++};
++
++enum fsl_usb2_phy_modes {
++ FSL_USB2_PHY_NONE,
++ FSL_USB2_PHY_ULPI,
++ FSL_USB2_PHY_UTMI,
++ FSL_USB2_PHY_UTMI_WIDE,
++ FSL_USB2_PHY_SERIAL,
++};
++
++struct fsl_usb2_platform_data {
++ /* board specific information */
++ enum fsl_usb2_operating_modes operating_mode;
++ enum fsl_usb2_phy_modes phy_mode;
++ unsigned int port_enables;
++};
++
++/* Flags in fsl_usb2_mph_platform_data */
++#define FSL_USB2_PORT0_ENABLED 0x00000001
++#define FSL_USB2_PORT1_ENABLED 0x00000002
++
+ #endif /* _FSL_DEVICE_H_ */
+ #endif /* __KERNEL__ */
diff --git a/usb/usb-ehci-full-speed-iso-bugfixes.patch b/usb/usb-ehci-full-speed-iso-bugfixes.patch
new file mode 100644
index 00000000000000..5c2091449a28e5
--- /dev/null
+++ b/usb/usb-ehci-full-speed-iso-bugfixes.patch
@@ -0,0 +1,68 @@
+From david-b@pacbell.net Fri Jan 20 17:25:14 2006
+From: Clemens Ladisch <clemens@ladisch.de>
+To: Greg KH <greg@kroah.com>
+Subject: USB: EHCI full speed ISO bugfixes
+Date: Fri, 20 Jan 2006 13:49:10 -0800
+Cc: <clemens@ladisch.de>
+Message-Id: <200601201349.10841.david-b@pacbell.net>
+
+
+This patch replaces the split ISO raw_mask calculation code in the
+iso_stream_init() function that computed incorrect numbers of high
+speed transactions for both input and output transfers.
+
+In the output case, it added a superfluous start-split transaction for
+all maxmimum packet sizes that are a multiple of 188.
+
+In the input case, it forgot to add complete-split transactions for all
+microframes covered by the full speed transaction, and the additional
+complete-split transaction needed for the case when full speed data
+starts arriving near the end of a microframe.
+
+These changes don't affect the lack of full speed bandwidth, but at
+least it removes the MMF errors that the HC raised with some input
+streams.
+
+Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-sched.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/host/ehci-sched.c
++++ gregkh-2.6/drivers/usb/host/ehci-sched.c
+@@ -707,6 +707,7 @@ iso_stream_init (
+ } else {
+ u32 addr;
+ int think_time;
++ int hs_transfers;
+
+ addr = dev->ttport << 24;
+ if (!ehci_is_TDI(ehci)
+@@ -719,6 +720,7 @@ iso_stream_init (
+ think_time = dev->tt ? dev->tt->think_time : 0;
+ stream->tt_usecs = NS_TO_US (think_time + usb_calc_bus_time (
+ dev->speed, is_input, 1, maxp));
++ hs_transfers = max (1u, (maxp + 187) / 188);
+ if (is_input) {
+ u32 tmp;
+
+@@ -727,12 +729,11 @@ iso_stream_init (
+ stream->usecs = HS_USECS_ISO (1);
+ stream->raw_mask = 1;
+
+- /* pessimistic c-mask */
+- tmp = usb_calc_bus_time (USB_SPEED_FULL, 1, 0, maxp)
+- / (125 * 1000);
+- stream->raw_mask |= 3 << (tmp + 9);
++ /* c-mask as specified in USB 2.0 11.18.4 3.c */
++ tmp = (1 << (hs_transfers + 2)) - 1;
++ stream->raw_mask |= tmp << (8 + 2);
+ } else
+- stream->raw_mask = smask_out [maxp / 188];
++ stream->raw_mask = smask_out [hs_transfers - 1];
+ bandwidth = stream->usecs + stream->c_usecs;
+ bandwidth /= 1 << (interval + 2);
+
diff --git a/usb/usb-ehci-unlink-tweaks.patch b/usb/usb-ehci-unlink-tweaks.patch
new file mode 100644
index 00000000000000..ea676fd543258c
--- /dev/null
+++ b/usb/usb-ehci-unlink-tweaks.patch
@@ -0,0 +1,44 @@
+From david-b@pacbell.net Fri Jan 20 17:25:17 2006
+From: David Brownell <david-b@pacbell.net>
+To: Greg KH <greg@kroah.com>
+Subject: USB: EHCI unlink tweaks
+Date: Fri, 20 Jan 2006 14:35:55 -0800
+Message-Id: <200601201435.56129.david-b@pacbell.net>
+
+This patch modifies the behavior of the EHCI driver in an unlink path
+that seems to be causing various issues on some systems. Those problems
+have included issues with disconnection, driver unbinding, and similar
+cases where urb unlinking would just not work right.
+
+This patch should help avoid those problems by not turning off the async
+(control/bulk) schedule until it's not expecting an "async advance" IRQ,
+which comes from the processing passing the schedule head. Whether the
+driver attempts to do such things is dependent on system timings, so
+many folk would never have seen these problems.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/host/ehci-q.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/host/ehci-q.c
++++ gregkh-2.6/drivers/usb/host/ehci-q.c
+@@ -1022,12 +1022,14 @@ static void start_unlink_async (struct e
+ /* stop async schedule right now? */
+ if (unlikely (qh == ehci->async)) {
+ /* can't get here without STS_ASS set */
+- if (ehci_to_hcd(ehci)->state != HC_STATE_HALT) {
++ if (ehci_to_hcd(ehci)->state != HC_STATE_HALT
++ && !ehci->reclaim) {
++ /* ... and CMD_IAAD clear */
+ writel (cmd & ~CMD_ASE, &ehci->regs->command);
+ wmb ();
+ // handshake later, if we need to
++ timer_action_done (ehci, TIMER_ASYNC_OFF);
+ }
+- timer_action_done (ehci, TIMER_ASYNC_OFF);
+ return;
+ }
+
diff --git a/usb/usb-gadget-zero-and-dma-coherent-buffers.patch b/usb/usb-gadget-zero-and-dma-coherent-buffers.patch
new file mode 100644
index 00000000000000..61608d855edfc7
--- /dev/null
+++ b/usb/usb-gadget-zero-and-dma-coherent-buffers.patch
@@ -0,0 +1,44 @@
+From david-b@pacbell.net Fri Jan 20 17:25:17 2006
+From: David Brownell <david-b@pacbell.net>
+To: Greg KH <greg@kroah.com>
+Subject: USB: gadget zero and dma-coherent buffers
+Date: Fri, 20 Jan 2006 14:38:49 -0800
+Message-Id: <200601201438.49982.david-b@pacbell.net>
+
+This makes sure that the correct length is reported when freeing
+a dma-coherent buffer; some platforms complain if that's wrong.
+It also makes two parameters readonly in sysfs, as they're not
+safe to change while tests are running.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ drivers/usb/gadget/zero.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- gregkh-2.6.orig/drivers/usb/gadget/zero.c
++++ gregkh-2.6/drivers/usb/gadget/zero.c
+@@ -165,8 +165,8 @@ static unsigned buflen = 4096;
+ static unsigned qlen = 32;
+ static unsigned pattern = 0;
+
+-module_param (buflen, uint, S_IRUGO|S_IWUSR);
+-module_param (qlen, uint, S_IRUGO|S_IWUSR);
++module_param (buflen, uint, S_IRUGO);
++module_param (qlen, uint, S_IRUGO);
+ module_param (pattern, uint, S_IRUGO|S_IWUSR);
+
+ /*
+@@ -1127,8 +1127,10 @@ zero_unbind (struct usb_gadget *gadget)
+ DBG (dev, "unbind\n");
+
+ /* we've already been disconnected ... no i/o is active */
+- if (dev->req)
++ if (dev->req) {
++ dev->req->length = USB_BUFSIZ;
+ free_ep_req (gadget->ep0, dev->req);
++ }
+ del_timer_sync (&dev->resume);
+ kfree (dev);
+ set_gadget_data (gadget, NULL);
diff --git a/usb/usb-ohci-for-au1200.patch b/usb/usb-ohci-for-au1200.patch
new file mode 100644
index 00000000000000..c2f058ef71d610
--- /dev/null
+++ b/usb/usb-ohci-for-au1200.patch
@@ -0,0 +1,241 @@
+From david-b@pacbell.net Fri Jan 20 17:25:17 2006
+From: Jordan Crouse <jordan.crouse@amd.com>
+To: Greg KH <greg@kroah.com>
+Subject: USB: OHCI for AU1200
+Date: Fri, 20 Jan 2006 14:09:54 -0800
+Message-Id: <200601201409.54293.david-b@pacbell.net>
+
+ALCHEMY: Add OHCI support for AU1200
+
+Updated by moving the OHCI support out of the EHCI patch.
+
+Signed-off-by: Jordan Crouse <jordan.crouse@amd.com>
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+
+---
+ arch/mips/au1000/common/platform.c | 2
+ drivers/usb/host/ohci-au1xxx.c | 102 +++++++++++++++++++++++++++++++------
+ 2 files changed, 88 insertions(+), 16 deletions(-)
+
+--- gregkh-2.6.orig/arch/mips/au1000/common/platform.c
++++ gregkh-2.6/arch/mips/au1000/common/platform.c
+@@ -20,7 +20,7 @@
+ static struct resource au1xxx_usb_ohci_resources[] = {
+ [0] = {
+ .start = USB_OHCI_BASE,
+- .end = USB_OHCI_BASE + USB_OHCI_LEN,
++ .end = USB_OHCI_BASE + USB_OHCI_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+--- gregkh-2.6.orig/drivers/usb/host/ohci-au1xxx.c
++++ gregkh-2.6/drivers/usb/host/ohci-au1xxx.c
+@@ -23,6 +23,8 @@
+
+ #include <asm/mach-au1x00/au1000.h>
+
++#ifndef CONFIG_SOC_AU1200
++
+ #define USBH_ENABLE_BE (1<<0)
+ #define USBH_ENABLE_C (1<<1)
+ #define USBH_ENABLE_E (1<<2)
+@@ -37,21 +39,68 @@
+ #error not byte order defined
+ #endif
+
++#else /* Au1200 */
++
++#define USB_HOST_CONFIG (USB_MSR_BASE + USB_MSR_MCFG)
++#define USB_MCFG_PFEN (1<<31)
++#define USB_MCFG_RDCOMB (1<<30)
++#define USB_MCFG_SSDEN (1<<23)
++#define USB_MCFG_OHCCLKEN (1<<16)
++#define USB_MCFG_UCAM (1<<7)
++#define USB_MCFG_OBMEN (1<<1)
++#define USB_MCFG_OMEMEN (1<<0)
++
++#define USBH_ENABLE_CE USB_MCFG_OHCCLKEN
++#ifdef CONFIG_DMA_COHERENT
++#define USBH_ENABLE_INIT (USB_MCFG_OHCCLKEN \
++ | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
++ | USB_MCFG_SSDEN | USB_MCFG_UCAM \
++ | USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
++#else
++#define USBH_ENABLE_INIT (USB_MCFG_OHCCLKEN \
++ | USB_MCFG_PFEN | USB_MCFG_RDCOMB \
++ | USB_MCFG_SSDEN \
++ | USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
++#endif
++#define USBH_DISABLE (USB_MCFG_OBMEN | USB_MCFG_OMEMEN)
++
++#endif /* Au1200 */
++
+ extern int usb_disabled(void);
+
+ /*-------------------------------------------------------------------------*/
+
+-static void au1xxx_start_hc(struct platform_device *dev)
++static void au1xxx_start_ohc(struct platform_device *dev)
+ {
+ printk(KERN_DEBUG __FILE__
+ ": starting Au1xxx OHCI USB Controller\n");
+
+ /* enable host controller */
++
++#ifndef CONFIG_SOC_AU1200
++
+ au_writel(USBH_ENABLE_CE, USB_HOST_CONFIG);
+ udelay(1000);
+ au_writel(USBH_ENABLE_INIT, USB_HOST_CONFIG);
+ udelay(1000);
+
++#else /* Au1200 */
++
++ /* write HW defaults again in case Yamon cleared them */
++ if (au_readl(USB_HOST_CONFIG) == 0) {
++ au_writel(0x00d02000, USB_HOST_CONFIG);
++ au_readl(USB_HOST_CONFIG);
++ udelay(1000);
++ }
++ au_writel(USBH_ENABLE_CE | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
++ au_readl(USB_HOST_CONFIG);
++ udelay(1000);
++ au_writel(USBH_ENABLE_INIT | au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
++ au_readl(USB_HOST_CONFIG);
++ udelay(1000);
++
++#endif /* Au1200 */
++
+ /* wait for reset complete (read register twice; see au1500 errata) */
+ while (au_readl(USB_HOST_CONFIG),
+ !(au_readl(USB_HOST_CONFIG) & USBH_ENABLE_RD))
+@@ -61,13 +110,25 @@ static void au1xxx_start_hc(struct platf
+ ": Clock to USB host has been enabled \n");
+ }
+
+-static void au1xxx_stop_hc(struct platform_device *dev)
++static void au1xxx_stop_ohc(struct platform_device *dev)
+ {
+ printk(KERN_DEBUG __FILE__
+ ": stopping Au1xxx OHCI USB Controller\n");
+
++#ifndef CONFIG_SOC_AU1200
++
+ /* Disable clock */
+ au_writel(au_readl(USB_HOST_CONFIG) & ~USBH_ENABLE_CE, USB_HOST_CONFIG);
++
++#else /* Au1200 */
++
++ /* Disable mem */
++ au_writel(~USBH_DISABLE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
++ udelay(1000);
++ /* Disable clock */
++ au_writel(~USBH_ENABLE_CE & au_readl(USB_HOST_CONFIG), USB_HOST_CONFIG);
++ au_readl(USB_HOST_CONFIG);
++#endif /* Au1200 */
+ }
+
+
+@@ -78,7 +139,7 @@ static void au1xxx_stop_hc(struct platfo
+
+
+ /**
+- * usb_hcd_au1xxx_probe - initialize Au1xxx-based HCDs
++ * usb_ohci_au1xxx_probe - initialize Au1xxx-based HCDs
+ * Context: !in_interrupt()
+ *
+ * Allocates basic resources for this USB host controller, and
+@@ -86,14 +147,25 @@ static void au1xxx_stop_hc(struct platfo
+ * through the hotplug entry's driver_data.
+ *
+ */
+-int usb_hcd_au1xxx_probe (const struct hc_driver *driver,
++static int usb_ohci_au1xxx_probe(const struct hc_driver *driver,
+ struct platform_device *dev)
+ {
+ int retval;
+ struct usb_hcd *hcd;
+
+- if(dev->resource[1].flags != IORESOURCE_IRQ) {
+- pr_debug ("resource[1] is not IORESOURCE_IRQ");
++#if defined(CONFIG_SOC_AU1200) && defined(CONFIG_DMA_COHERENT)
++ /* Au1200 AB USB does not support coherent memory */
++ if (!(read_c0_prid() & 0xff)) {
++ pr_info("%s: this is chip revision AB !!\n",
++ dev->dev.name);
++ pr_info("%s: update your board or re-configure the kernel\n",
++ dev->dev.name);
++ return -ENODEV;
++ }
++#endif
++
++ if (dev->resource[1].flags != IORESOURCE_IRQ) {
++ pr_debug("resource[1] is not IORESOURCE_IRQ\n");
+ return -ENOMEM;
+ }
+
+@@ -104,26 +176,26 @@ int usb_hcd_au1xxx_probe (const struct h
+ hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+- pr_debug("request_mem_region failed");
++ pr_debug("request_mem_region failed\n");
+ retval = -EBUSY;
+ goto err1;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+- pr_debug("ioremap failed");
++ pr_debug("ioremap failed\n");
+ retval = -ENOMEM;
+ goto err2;
+ }
+
+- au1xxx_start_hc(dev);
++ au1xxx_start_ohc(dev);
+ ohci_hcd_init(hcd_to_ohci(hcd));
+
+- retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT);
++ retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT | SA_SHIRQ);
+ if (retval == 0)
+ return retval;
+
+- au1xxx_stop_hc(dev);
++ au1xxx_stop_ohc(dev);
+ iounmap(hcd->regs);
+ err2:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+@@ -146,10 +218,10 @@ int usb_hcd_au1xxx_probe (const struct h
+ * context, normally "rmmod", "apmd", or something similar.
+ *
+ */
+-void usb_hcd_au1xxx_remove (struct usb_hcd *hcd, struct platform_device *dev)
++static void usb_ohci_au1xxx_remove(struct usb_hcd *hcd, struct platform_device *dev)
+ {
+ usb_remove_hcd(hcd);
+- au1xxx_stop_hc(dev);
++ au1xxx_stop_ohc(dev);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+@@ -235,7 +307,7 @@ static int ohci_hcd_au1xxx_drv_probe(str
+ if (usb_disabled())
+ return -ENODEV;
+
+- ret = usb_hcd_au1xxx_probe(&ohci_au1xxx_hc_driver, pdev);
++ ret = usb_ohci_au1xxx_probe(&ohci_au1xxx_hc_driver, pdev);
+ return ret;
+ }
+
+@@ -243,7 +315,7 @@ static int ohci_hcd_au1xxx_drv_remove(st
+ {
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+- usb_hcd_au1xxx_remove(hcd, pdev);
++ usb_ohci_au1xxx_remove(hcd, pdev);
+ return 0;
+ }
+ /*TBD*/
diff --git a/usb/usb-usb-authentication-states.patch b/usb/usb-usb-authentication-states.patch
new file mode 100644
index 00000000000000..34a6d402c315d2
--- /dev/null
+++ b/usb/usb-usb-authentication-states.patch
@@ -0,0 +1,38 @@
+From david-b@pacbell.net Fri Jan 20 17:25:21 2006
+From: David Brownell <david-b@pacbell.net>
+To: Greg KH <greg@kroah.com>
+Subject: USB: USB authentication states
+Date: Fri, 20 Jan 2006 14:44:12 -0800
+Message-Id: <200601201444.13184.david-b@pacbell.net>
+
+Another hook needed for wireless USB: there are states associated with the
+device authentication protocol. Wireless devices must authenticate using
+the host system's keystore.
+
+Note that wired connections could also use this authentication protocol, if
+for no other reason than to support the most secure "simple" key exchange
+protocols for wireless devices.
+
+Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
+
+---
+ include/linux/usb_ch9.h | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- gregkh-2.6.orig/include/linux/usb_ch9.h
++++ gregkh-2.6/include/linux/usb_ch9.h
+@@ -535,9 +535,11 @@ enum usb_device_state {
+ */
+ USB_STATE_NOTATTACHED = 0,
+
+- /* the chapter 9 device states */
++ /* chapter 9 and authentication (wireless) device states */
+ USB_STATE_ATTACHED,
+- USB_STATE_POWERED,
++ USB_STATE_POWERED, /* wired */
++ USB_STATE_UNAUTHENTICATED, /* auth */
++ USB_STATE_RECONNECTING, /* auth */
+ USB_STATE_DEFAULT, /* limited function */
+ USB_STATE_ADDRESS,
+ USB_STATE_CONFIGURED, /* most functions */