diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-26 21:33:29 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-01-26 21:33:29 -0800 |
commit | ace1b9a23d60628c91662ff8259acc439a4f7392 (patch) | |
tree | 320dfd8efba9a3716cc53b9a59dc4d631b6613fc /usb | |
parent | 102a09d5962619353ce7935f4ea3f78e59ea427b (diff) | |
download | patches-ace1b9a23d60628c91662ff8259acc439a4f7392.tar.gz |
more usb patches
Diffstat (limited to 'usb')
-rw-r--r-- | usb/usb-ehci-and-freescale-83xx-quirk.patch | 94 | ||||
-rw-r--r-- | usb/usb-ehci-and-nf2-quirk.patch | 120 | ||||
-rw-r--r-- | usb/usb-ehci-for-au1200.patch | 425 | ||||
-rw-r--r-- | usb/usb-ehci-for-freescale-83xx.patch | 503 | ||||
-rw-r--r-- | usb/usb-ehci-full-speed-iso-bugfixes.patch | 68 | ||||
-rw-r--r-- | usb/usb-ehci-unlink-tweaks.patch | 44 | ||||
-rw-r--r-- | usb/usb-gadget-zero-and-dma-coherent-buffers.patch | 44 | ||||
-rw-r--r-- | usb/usb-ohci-for-au1200.patch | 241 | ||||
-rw-r--r-- | usb/usb-usb-authentication-states.patch | 38 |
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 */ |