Kumar, I've attached a patch file that demonstrates the changes to the EHCI code that I described. Please note that while the patched code compiles cleanly it is completely untested. Also the text in drivers/usb/host/Kconfig could use some more work. The patch file is for the 2.6.16 kernel.
Best Regards, Craig Nadler Craig W. Nadler wrote: >Kumar, > >This past summer I proposed some restructuring of the EHCI driver to >allow for OTG drivers that use EHCI for host mode. It would also handle >your situation. Instead of including other *.c files into ehci-hcd.c the >C files would be included into the platform specific file. So for >example ehci-pci.c would include the other ehci C files that it needed >(including ehci-hcd.c). Not only would this allow for EHCI in an OTG >core and non-PCI EHCI but it would also allow an EHCI driver to replace >any of the C files such as ehci-mem.c. > >Best Regards, > >Craig Nadler > >Kumar Gala wrote: > > > >>On Mar 23, 2006, at 7:11 PM, Craig W. Nadler wrote: >> >> >> >>>Kumar, >>> >>>If I understand you correctly you have both an embedded/localbus EHCI >>>core and EHCI on the PCI bus. If this is the case then you could clone >>>ehci-hcd.c and use it as the basis for a driver for the embedded EHCI >>>core. Instead of including ehci-pci.c in the cloned code you would >>>include the platform specific code for your embedded EHCI. You would >>>need to change the "Kconfig" file and "makefile" in drivers/usb/ host to >>>compile the module for the embedded EHCI under a different name. >>> >>> >>Thanks. I was looking for a solution that we could push upstream. I >>can handle hacking it so it builds :) >> >>One possiblity would be to move the code related to module_init/ >>module_exit into their own files that get build as separate objects >>from ehci-hcd.c. >> >> >> >>>>I was trying to build the USB EHCI host controller support as modules >>>>for a PowerPC 834x which also has an embedded EHCI (and PCI enabled). >>>> >>>>I get the following build error: >>>> >>>>In file included from drivers/usb/host/ehci-hcd.c:895: >>>>drivers/usb/host/ehci-fsl.c:365: error: redefinition of '__inittest' >>>>drivers/usb/host/ehci-pci.c:363: error: previous definition of >>>>'__inittest' was here >>>>drivers/usb/host/ehci-fsl.c:365: error: redefinition of 'init_module' >>>>drivers/usb/host/ehci-pci.c:363: error: previous definition of >>>>'init_module' was here >>>>drivers/usb/host/ehci-fsl.c:365: error: redefinition of 'init_module' >>>>drivers/usb/host/ehci-pci.c:363: error: previous definition of >>>>'init_module' was here >>>>drivers/usb/host/ehci-fsl.c:366: error: redefinition of '__exittest' >>>>drivers/usb/host/ehci-pci.c:369: error: previous definition of >>>>'__exittest' was here >>>>drivers/usb/host/ehci-fsl.c:366: error: redefinition of >>>>'cleanup_module' >>>>drivers/usb/host/ehci-pci.c:369: error: previous definition of >>>>'cleanup_module' was here >>>>drivers/usb/host/ehci-fsl.c:366: error: redefinition of >>>>'cleanup_module' >>>>drivers/usb/host/ehci-pci.c:369: error: previous definition of >>>>'cleanup_module' was here >>>> >>>>Which makes sense based on how ehci-hcd.c includes "ehci-fsl.c" and >>>>"ehci-pci.c". I was wondering if there were an thoughts on how to >>>>address this so I can build as a module.. >>>> >>>>- kumar >>>> >>>> >> >> >> > > > >
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h --- a/drivers/usb/host/ehci.h 2006-03-20 00:53:29.000000000 -0500 +++ b/drivers/usb/host/ehci.h 2006-03-23 21:16:39.000000000 -0500 @@ -644,4 +644,12 @@ /*-------------------------------------------------------------------------*/ +static void ehci_quiesce (struct ehci_hcd *ehci); +static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec); +static void ehci_work (struct ehci_hcd *ehci, struct pt_regs *regs); +static int ehci_halt (struct ehci_hcd *ehci); + +/*-------------------------------------------------------------------------*/ + + #endif /* __LINUX_EHCI_HCD_H */ diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c --- a/drivers/usb/host/ehci-hcd.c 2006-03-20 00:53:29.000000000 -0500 +++ b/drivers/usb/host/ehci-hcd.c 2006-03-23 21:05:02.000000000 -0500 @@ -16,126 +16,8 @@ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include <linux/config.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/dmapool.h> -#include <linux/kernel.h> -#include <linux/delay.h> -#include <linux/ioport.h> -#include <linux/sched.h> -#include <linux/slab.h> -#include <linux/smp_lock.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/timer.h> -#include <linux/list.h> -#include <linux/interrupt.h> -#include <linux/reboot.h> -#include <linux/usb.h> -#include <linux/moduleparam.h> -#include <linux/dma-mapping.h> - -#include "../core/hcd.h" - -#include <asm/byteorder.h> -#include <asm/io.h> -#include <asm/irq.h> -#include <asm/system.h> -#include <asm/unaligned.h> -/*-------------------------------------------------------------------------*/ - -/* - * EHCI hc_driver implementation ... experimental, incomplete. - * Based on the final 1.0 register interface specification. - * - * USB 2.0 shows up in upcoming www.pcmcia.org technology. - * First was PCMCIA, like ISA; then CardBus, which is PCI. - * Next comes "CardBay", using USB 2.0 signals. - * - * Contains additional contributions by Brad Hards, Rory Bolt, and others. - * Special thanks to Intel and VIA for providing host controllers to - * test this driver on, and Cypress (including In-System Design) for - * providing early devices for those host controllers to talk to! - * - * HISTORY: - * - * 2004-05-10 Root hub and PCI suspend/resume support; remote wakeup. (db) - * 2004-02-24 Replace pci_* with generic dma_* API calls ([EMAIL PROTECTED]) - * 2003-12-29 Rewritten high speed iso transfer support (by Michal Sojka, - * <[EMAIL PROTECTED]>, updates by DB). - * - * 2002-11-29 Correct handling for hw async_next register. - * 2002-08-06 Handling for bulk and interrupt transfers is mostly shared; - * only scheduling is different, no arbitrary limitations. - * 2002-07-25 Sanity check PCI reads, mostly for better cardbus support, - * clean up HC run state handshaking. - * 2002-05-24 Preliminary FS/LS interrupts, using scheduling shortcuts - * 2002-05-11 Clear TT errors for FS/LS ctrl/bulk. Fill in some other - * missing pieces: enabling 64bit dma, handoff from BIOS/SMM. - * 2002-05-07 Some error path cleanups to report better errors; wmb(); - * use non-CVS version id; better iso bandwidth claim. - * 2002-04-19 Control/bulk/interrupt submit no longer uses giveback() on - * errors in submit path. Bugfixes to interrupt scheduling/processing. - * 2002-03-05 Initial high-speed ISO support; reduce ITD memory; shift - * more checking to generic hcd framework (db). Make it work with - * Philips EHCI; reduce PCI traffic; shorten IRQ path (Rory Bolt). - * 2002-01-14 Minor cleanup; version synch. - * 2002-01-08 Fix roothub handoff of FS/LS to companion controllers. - * 2002-01-04 Control/Bulk queuing behaves. - * - * 2001-12-12 Initial patch version for Linux 2.5.1 kernel. - * 2001-June Works with usb-storage and NEC EHCI on 2.4 - */ - -#define DRIVER_VERSION "10 Dec 2004" -#define DRIVER_AUTHOR "David Brownell" -#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" - -static const char hcd_name [] = "ehci_hcd"; - - -#undef EHCI_VERBOSE_DEBUG -#undef EHCI_URB_TRACE - -#ifdef DEBUG -#define EHCI_STATS -#endif - -/* magic numbers that can affect system performance */ -#define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ -#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ -#define EHCI_TUNE_RL_TT 0 -#define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ -#define EHCI_TUNE_MULT_TT 1 -#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ - -#define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ -#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ -#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ -#define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ - -/* Initial IRQ latency: faster than hw default */ -static int log2_irq_thresh = 0; // 0 to 6 -module_param (log2_irq_thresh, int, S_IRUGO); -MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes"); - -/* initial park setting: slower than hw default */ -static unsigned park = 0; -module_param (park, uint, S_IRUGO); -MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets"); - -#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) - -/*-------------------------------------------------------------------------*/ - -#include "ehci.h" -#include "ehci-dbg.c" - -/*-------------------------------------------------------------------------*/ - /* * handshake - spin reading hc until handshake completes or fails * @ptr: address of hc register to be read @@ -255,15 +137,6 @@ /*-------------------------------------------------------------------------*/ -static void ehci_work(struct ehci_hcd *ehci, struct pt_regs *regs); - -#include "ehci-hub.c" -#include "ehci-mem.c" -#include "ehci-q.c" -#include "ehci-sched.c" - -/*-------------------------------------------------------------------------*/ - static void ehci_watchdog (unsigned long param) { struct ehci_hcd *ehci = (struct ehci_hcd *) param; @@ -878,19 +751,3 @@ struct ehci_hcd *ehci = hcd_to_ehci (hcd); return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; } - -/*-------------------------------------------------------------------------*/ - -#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC - -MODULE_DESCRIPTION (DRIVER_INFO); -MODULE_AUTHOR (DRIVER_AUTHOR); -MODULE_LICENSE ("GPL"); - -#ifdef CONFIG_PCI -#include "ehci-pci.c" -#endif - -#if !defined(CONFIG_PCI) -#error "missing bus glue for ehci-hcd" -#endif diff -Nru a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c --- a/drivers/usb/host/ehci-pci.c 2006-03-20 00:53:29.000000000 -0500 +++ b/drivers/usb/host/ehci-pci.c 2006-03-23 21:44:10.000000000 -0500 @@ -22,6 +22,84 @@ #error "This file is PCI bus glue. CONFIG_PCI must be defined." #endif +#include <linux/config.h> +#include <linux/module.h> +#include <linux/pci.h> +#include <linux/dmapool.h> +#include <linux/kernel.h> +#include <linux/delay.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/smp_lock.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/timer.h> +#include <linux/list.h> +#include <linux/interrupt.h> +#include <linux/reboot.h> +#include <linux/usb.h> +#include <linux/moduleparam.h> +#include <linux/dma-mapping.h> + +#include "../core/hcd.h" + +#include <asm/byteorder.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/system.h> +#include <asm/unaligned.h> + + +#define DRIVER_VERSION "10 Dec 2004" +#define DRIVER_AUTHOR "David Brownell" +#define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver" + +static const char hcd_name [] = "ehci_hcd_pci"; + + +#undef EHCI_VERBOSE_DEBUG +#undef EHCI_URB_TRACE + +#ifdef DEBUG +#define EHCI_STATS +#endif + +/* magic numbers that can affect system performance */ +#define EHCI_TUNE_CERR 3 /* 0-3 qtd retries; 0 == don't stop */ +#define EHCI_TUNE_RL_HS 4 /* nak throttle; see 4.9 */ +#define EHCI_TUNE_RL_TT 0 +#define EHCI_TUNE_MULT_HS 1 /* 1-3 transactions/uframe; 4.10.3 */ +#define EHCI_TUNE_MULT_TT 1 +#define EHCI_TUNE_FLS 2 /* (small) 256 frame schedule */ + +#define EHCI_IAA_JIFFIES (HZ/100) /* arbitrary; ~10 msec */ +#define EHCI_IO_JIFFIES (HZ/10) /* io watchdog > irq_thresh */ +#define EHCI_ASYNC_JIFFIES (HZ/20) /* async idle timeout */ +#define EHCI_SHRINK_JIFFIES (HZ/200) /* async qh unlink delay */ + +/* Initial IRQ latency: faster than hw default */ +static int log2_irq_thresh = 0; // 0 to 6 +module_param (log2_irq_thresh, int, S_IRUGO); +MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes"); + +/* initial park setting: slower than hw default */ +static unsigned park = 0; +module_param (park, uint, S_IRUGO); +MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets"); + +#define INTR_MASK (STS_IAA | STS_FATAL | STS_PCD | STS_ERR | STS_INT) + +/*-------------------------------------------------------------------------*/ + +#include "ehci.h" +#include "ehci-dbg.c" +#include "ehci-hub.c" +#include "ehci-mem.c" +#include "ehci-q.c" +#include "ehci-sched.c" +#include "ehci-hcd.c" + /*-------------------------------------------------------------------------*/ /* called after powerup, by probe or system-pm "wakeup" */ @@ -367,3 +445,11 @@ pci_unregister_driver(&ehci_pci_driver); } module_exit(ehci_hcd_pci_cleanup); + + +#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC + +MODULE_DESCRIPTION (DRIVER_INFO); +MODULE_AUTHOR (DRIVER_AUTHOR); +MODULE_LICENSE ("GPL"); + diff -Nru a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig --- a/drivers/usb/host/Kconfig 2006-03-20 00:53:29.000000000 -0500 +++ b/drivers/usb/host/Kconfig 2006-03-23 21:47:12.000000000 -0500 @@ -5,8 +5,8 @@ depends on USB config USB_EHCI_HCD - tristate "EHCI HCD (USB 2.0) support" - depends on USB && PCI + boolean "EHCI HCD (USB 2.0) support" + depends on USB ---help--- The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware. @@ -26,8 +26,15 @@ You may want to read <file:Documentation/usb/ehci.txt>. +config USB_EHCI_HCD_PCI + tristate "Support for EHCI on PCI bus" + depends on USB_EHCI_HCD && PCI + default n + ---help--- + Compile support for EHCI on the PCI bus. + To compile this driver as a module, choose M here: the - module will be called ehci-hcd. + module will be called ehci-hcd-pci. config USB_EHCI_SPLIT_ISO bool "Full speed ISO transactions (EXPERIMENTAL)" diff -Nru a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile --- a/drivers/usb/host/Makefile 2006-03-20 00:53:29.000000000 -0500 +++ b/drivers/usb/host/Makefile 2006-03-23 21:26:13.000000000 -0500 @@ -8,7 +8,7 @@ obj-$(CONFIG_PCI) += pci-quirks.o -obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o +obj-$(CONFIG_USB_EHCI_HCD_PCI) += ehci-pci.o obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o diff -Nru a/drivers/usb/Makefile b/drivers/usb/Makefile --- a/drivers/usb/Makefile 2006-03-20 00:53:29.000000000 -0500 +++ b/drivers/usb/Makefile 2006-03-23 21:35:16.000000000 -0500 @@ -9,7 +9,7 @@ obj-$(CONFIG_USB_MON) += mon/ obj-$(CONFIG_PCI) += host/ -obj-$(CONFIG_USB_EHCI_HCD) += host/ +obj-$(CONFIG_USB_EHCI_HCD_PCI) += host/ obj-$(CONFIG_USB_ISP116X_HCD) += host/ obj-$(CONFIG_USB_OHCI_HCD) += host/ obj-$(CONFIG_USB_UHCI_HCD) += host/