diff -Naru linux/drivers/usb/host/Config.in linux-new/drivers/usb/host/Config.in --- linux/drivers/usb/host/Config.in 2003-11-16 20:07:42.000000000 -0500 +++ linux-new/drivers/usb/host/Config.in 2003-12-18 14:19:37.000000000 -0500 @@ -17,3 +17,4 @@ dep_tristate ' SL811HS Alternate (x86, StrongARM, isosynchronous mode)' CONFIG_USB_SL811HS_ALT $CONFIG_USB $CONFIG_EXPERIMENTAL dep_tristate ' SL811HS (x86, StrongARM) support, old driver' CONFIG_USB_SL811HS $CONFIG_USB $CONFIG_EXPERIMENTAL fi +dep_tristate ' Non-PCI OHCI support' CONFIG_USB_NON_PCI_OHCI $CONFIG_USB_OHCI diff -Naru linux/drivers/usb/host/usb-ohci.c linux-new/drivers/usb/host/usb-ohci.c --- linux/drivers/usb/host/usb-ohci.c 2003-08-13 13:19:23.000000000 -0400 +++ linux-new/drivers/usb/host/usb-ohci.c 2003-12-18 14:19:53.000000000 -0500 @@ -2517,6 +2517,7 @@ hc_release_ohci (ohci); return ret; } +#ifndef CONFIG_USB_NON_PCI_OHCI ohci->flags = id->driver_data; /* Check for NSC87560. We have to look at the bridge (fn1) to identify @@ -2535,6 +2536,7 @@ printk (KERN_INFO __FILE__ ": Using NSC SuperIO setup\n"); if (ohci->flags & OHCI_QUIRK_AMD756) printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n"); +#endif if (hc_reset (ohci) < 0) { hc_release_ohci (ohci); @@ -2580,8 +2582,10 @@ int temp; int i; +#ifndef CONFIG_USB_NON_PCI_OHCI if (ohci->pci_latency) pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER, ohci->pci_latency); +#endif ohci->disabled = 1; ohci->sleeping = 0; @@ -2611,6 +2615,7 @@ /*-------------------------------------------------------------------------*/ +#ifndef CONFIG_USB_NON_PCI_OHCI /* configured so that an OHCI device is always provided */ /* always called with process context; sleeping is OK */ @@ -2658,6 +2663,88 @@ } return status; } +#else /* CONFIG_USB_NON_PCI_OHCI */ + +// Boot options +static int ohci_base=0, ohci_len=0; +static int ohci_irq=-1; + +MODULE_PARM(ohci_base, "i"); +MODULE_PARM(ohci_len, "i"); +MODULE_PARM(ohci_irq, "i"); +MODULE_PARM_DESC(ohci_base, "IO Base address of OHCI Oper. registers"); +MODULE_PARM_DESC(ohci_len, "IO length of OHCI Oper. registers"); +MODULE_PARM_DESC(ohci_irq, "IRQ for OHCI interrupts"); + +// bogus pci_dev +static struct pci_dev bogus_pcidev; + +static struct pci_driver ohci_pci_driver = { + name: "usb-ohci", +}; + +static int __devinit +ohci_non_pci_init (void) +{ + void *mem_base; + + if (!ohci_base || !ohci_len || (ohci_irq < 0)) + return -ENODEV; + + if (!request_mem_region (ohci_base, ohci_len, ohci_pci_driver.name)) { + dbg ("controller already in use"); + return -EBUSY; + } + + mem_base = ioremap_nocache (ohci_base, ohci_len); + if (!mem_base) { + err("Error mapping OHCI memory"); + return -EFAULT; + } + + /* + * Fill in the bogus pci_dev. Only those members actually + * dereferenced in this driver are initialized. + */ + memset(&bogus_pcidev, 0, sizeof(struct pci_dev)); + strcpy(bogus_pcidev.name, "non-PCI OHCI"); + strcpy(bogus_pcidev.slot_name, "builtin"); + bogus_pcidev.resource[0].name = "OHCI Operational Registers"; + bogus_pcidev.resource[0].start = ohci_base; + bogus_pcidev.resource[0].end = ohci_base + ohci_len; + bogus_pcidev.resource[0].flags = 0; + bogus_pcidev.irq = ohci_irq; + + return hc_found_ohci (&bogus_pcidev, bogus_pcidev.irq, mem_base, NULL); +} + +#ifndef MODULE + +static int __init +ohci_setup (char* options) +{ + char* this_opt; + + if (!options || !*options) + return 0; + + for(this_opt=strtok(options,",");this_opt;this_opt=strtok(NULL,",")) { + if (!strncmp(this_opt, "base:", 5)) { + ohci_base = simple_strtoul(this_opt+5, NULL, 0); + } else if (!strncmp(this_opt, "len:", 4)) { + ohci_len = simple_strtoul(this_opt+4, NULL, 0); + } else if (!strncmp(this_opt, "irq:", 4)) { + ohci_irq = simple_strtoul(this_opt+4, NULL, 0); + } + } + return 0; +} + +__setup("usb_ohci=", ohci_setup); + +#endif /* !MODULE */ + +#endif /* CONFIG_USB_NON_PCI_OHCI */ /*-------------------------------------------------------------------------*/ @@ -2698,6 +2785,7 @@ } +#ifndef CONFIG_USB_NON_PCI_OHCI #ifdef CONFIG_PM /*-------------------------------------------------------------------------*/ @@ -2936,20 +3024,29 @@ resume: ohci_pci_resume, #endif /* PM */ }; +#endif /* CONFIG_USB_NON_PCI_OHCI */ /*-------------------------------------------------------------------------*/ static int __init ohci_hcd_init (void) { +#ifndef CONFIG_USB_NON_PCI_OHCI return pci_module_init (&ohci_pci_driver); +#else + return ohci_non_pci_init(); +#endif } /*-------------------------------------------------------------------------*/ static void __exit ohci_hcd_cleanup (void) { +#ifndef CONFIG_USB_NON_PCI_OHCI pci_unregister_driver (&ohci_pci_driver); +#else + ohci_pci_remove(&bogus_pcidev); +#endif } module_init (ohci_hcd_init);