# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
# ChangeSet 1.592 -> 1.592.2.1
# drivers/usb/host/usb-ohci.h 1.13 -> 1.14
# drivers/usb/host/Config.in 1.11 -> 1.12
# drivers/usb/host/usb-ohci.c 1.34 -> 1.35
# drivers/usb/Config.in 1.30 -> 1.31
# drivers/usb/Makefile 1.31 -> 1.32
# drivers/usb/host/Makefile 1.10 -> 1.11
# (new) -> 1.1 drivers/usb/host/usb-ohci-sa1111.c
# (new) -> 1.1 drivers/usb/host/usb-ohci-pci.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/05/29 [EMAIL PROTECTED] 1.592.2.1
# USB OHCI driver: Added SA1111 support
#
# Added the patch from Russell King <[EMAIL PROTECTED]> that splits
# the usb-ohci driver into two pieces, enabling the sa1111 hardware to
# work with the driver.
#
# I also added some changes to get the usb-ohci-pci.o module to build
# and run properly.
# --------------------------------------------
#
diff -Nru a/drivers/usb/Config.in b/drivers/usb/Config.in
--- a/drivers/usb/Config.in Fri May 31 00:41:19 2002
+++ b/drivers/usb/Config.in Fri May 31 00:41:19 2002
@@ -4,7 +4,13 @@
mainmenu_option next_comment
comment 'USB support'
-dep_tristate 'Support for USB' CONFIG_USB $CONFIG_PCI
+# ARM SA1111 chips have a non-PCI based "OHCI-compatible" USB host interface.
+if [ "$CONFIG_PCI" = "y" -o "$CONFIG_SA1111" = "y" ]; then
+ tristate 'Support for USB' CONFIG_USB
+else
+ define_bool CONFIG_USB n
+fi
+
if [ "$CONFIG_USB" = "y" -o "$CONFIG_USB" = "m" ]; then
source drivers/usb/core/Config.in
diff -Nru a/drivers/usb/Makefile b/drivers/usb/Makefile
--- a/drivers/usb/Makefile Fri May 31 00:41:19 2002
+++ b/drivers/usb/Makefile Fri May 31 00:41:19 2002
@@ -6,9 +6,11 @@
mod-subdirs := serial
obj-$(CONFIG_USB) += core/
+
obj-$(CONFIG_USB_EHCI_HCD) += host/
obj-$(CONFIG_USB_OHCI_HCD) += host/
obj-$(CONFIG_USB_OHCI) += host/
+obj-$(CONFIG_USB_OHCI_SA1111) += host/
obj-$(CONFIG_USB_SL811HS) += host/
obj-$(CONFIG_USB_UHCI_ALT) += host/
obj-$(CONFIG_USB_UHCI_HCD_ALT) += host/
diff -Nru a/drivers/usb/host/Config.in b/drivers/usb/host/Config.in
--- a/drivers/usb/host/Config.in Fri May 31 00:41:19 2002
+++ b/drivers/usb/host/Config.in Fri May 31 00:41:19 2002
@@ -20,5 +20,6 @@
#fi
#dep_tristate ' OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI
$CONFIG_USB
if [ "$CONFIG_ARM" = "y" ]; then
+ dep_tristate ' SA1111 OHCI-compatible host interface support'
+CONFIG_USB_OHCI_SA1111 $CONFIG_USB
dep_tristate ' SL811HS support' CONFIG_USB_SL811HS $CONFIG_USB
fi
diff -Nru a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
--- a/drivers/usb/host/Makefile Fri May 31 00:41:19 2002
+++ b/drivers/usb/host/Makefile Fri May 31 00:41:19 2002
@@ -3,6 +3,8 @@
# framework and drivers
#
+export-objs := usb-ohci.o
+
obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o
obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o
obj-$(CONFIG_USB_UHCI_HCD) += usb-uhci-hcd.o
@@ -10,7 +12,8 @@
obj-$(CONFIG_USB_UHCI) += usb-uhci.o
obj-$(CONFIG_USB_UHCI_ALT) += uhci.o
-obj-$(CONFIG_USB_OHCI) += usb-ohci.o
+obj-$(CONFIG_USB_OHCI) += usb-ohci.o usb-ohci-pci.o
+obj-$(CONFIG_USB_OHCI_SA1111) += usb-ohci.o usb-ohci-sa1111.o
obj-$(CONFIG_USB_SL811HS) += hc_sl811.o
include $(TOPDIR)/Rules.make
diff -Nru a/drivers/usb/host/usb-ohci-pci.c b/drivers/usb/host/usb-ohci-pci.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/host/usb-ohci-pci.c Fri May 31 00:41:19 2002
@@ -0,0 +1,445 @@
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h> /* for in_interrupt() */
+#undef DEBUG
+#include <linux/usb.h>
+
+#include "../core/hcd.h"
+#include "usb-ohci.h"
+
+#ifdef CONFIG_PMAC_PBOOK
+#include <asm/machdep.h>
+#include <asm/pmac_feature.h>
+#include <asm/pci-bridge.h>
+#ifndef CONFIG_PM
+#define CONFIG_PM
+#endif
+#endif
+
+
+/*-------------------------------------------------------------------------*/
+
+/* Increment the module usage count, start the control thread and
+ * return success. */
+
+static struct pci_driver ohci_pci_driver;
+
+static int __devinit
+hc_found_ohci (struct pci_dev *dev, int irq,
+ void *mem_base, const struct pci_device_id *id)
+{
+ u8 latency, limit;
+ ohci_t * ohci;
+ int ret;
+
+ printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
+
+ /* bad pci latencies can contribute to overruns */
+ pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
+ if (latency) {
+ pci_read_config_byte (dev, PCI_MAX_LAT, &limit);
+ if (limit && limit < latency) {
+ dbg ("PCI latency reduced to max %d", limit);
+ pci_write_config_byte (dev, PCI_LATENCY_TIMER, limit);
+ latency = limit;
+ }
+ }
+
+ ret = hc_add_ohci(dev, irq, mem_base, id->driver_data,
+ &ohci, ohci_pci_driver.name, dev->slot_name);
+
+ if (ret == 0) {
+ ohci->pci_latency = latency;
+
+ if (hc_start (ohci, &ohci->ohci_dev->dev) < 0) {
+ err ("can't start usb-%s", ohci->slot_name);
+ hc_remove_ohci(ohci);
+ return -EBUSY;
+ }
+
+#ifdef DEBUG
+ ohci_dump (ohci, 1);
+#endif
+ }
+
+ return ret;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef CONFIG_PM
+
+/* controller died; cleanup debris, then restart */
+/* must not be called from interrupt context */
+
+static void hc_restart (ohci_t *ohci)
+{
+ int temp;
+ int i;
+
+ if (ohci->pci_latency)
+ pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER,
+ohci->pci_latency);
+
+ ohci->disabled = 1;
+ ohci->sleeping = 0;
+ if (ohci->bus->root_hub)
+ usb_disconnect (&ohci->bus->root_hub);
+
+ /* empty the interrupt branches */
+ for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
+ for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0;
+
+ /* no EDs to remove */
+ ohci->ed_rm_list [0] = NULL;
+ ohci->ed_rm_list [1] = NULL;
+
+ /* empty control and bulk lists */
+ ohci->ed_isotail = NULL;
+ ohci->ed_controltail = NULL;
+ ohci->ed_bulktail = NULL;
+
+ if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
+ err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp);
+ } else
+ dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name);
+}
+
+#endif /* CONFIG_PM */
+
+/*-------------------------------------------------------------------------*/
+
+/* configured so that an OHCI device is always provided */
+/* always called with process context; sleeping is OK */
+
+static int __devinit
+ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
+{
+ unsigned long mem_resource, mem_len;
+ void *mem_base;
+ int status;
+
+ if (pci_enable_device(dev) < 0)
+ return -ENODEV;
+
+ if (!dev->irq) {
+ err("found OHCI device with no IRQ assigned. check BIOS settings!");
+ pci_disable_device (dev);
+ return -ENODEV;
+ }
+
+ /* we read its hardware registers as memory */
+ mem_resource = pci_resource_start(dev, 0);
+ mem_len = pci_resource_len(dev, 0);
+ if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) {
+ dbg ("controller already in use");
+ pci_disable_device (dev);
+ return -EBUSY;
+ }
+
+ mem_base = ioremap_nocache (mem_resource, mem_len);
+ if (!mem_base) {
+ err("Error mapping OHCI memory");
+ release_mem_region(mem_resource, mem_len);
+ pci_disable_device (dev);
+ return -EFAULT;
+ }
+
+ /* controller writes into our memory */
+ pci_set_master (dev);
+
+ status = hc_found_ohci (dev, dev->irq, mem_base, id);
+ if (status < 0) {
+ iounmap (mem_base);
+ release_mem_region(mem_resource, mem_len);
+ pci_disable_device (dev);
+ }
+ return status;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* may be called from interrupt context [interface spec] */
+/* may be called without controller present */
+/* may be called with controller, bus, and devices active */
+
+static void __devexit
+ohci_pci_remove (struct pci_dev *dev)
+{
+ ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev);
+
+ dbg ("remove %s controller usb-%s%s%s",
+ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
+ dev->slot_name,
+ ohci->disabled ? " (disabled)" : "",
+ in_interrupt () ? " in interrupt" : ""
+ );
+
+ hc_remove_ohci(ohci);
+
+ release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
+}
+
+
+#ifdef CONFIG_PM
+
+/*-------------------------------------------------------------------------*/
+
+static int
+ohci_pci_suspend (struct pci_dev *dev, u32 state)
+{
+ ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev);
+ unsigned long flags;
+ u16 cmd;
+
+ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
+ dbg ("can't suspend usb-%s (state is %s)", dev->slot_name,
+ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
+ return -EIO;
+ }
+
+ /* act as if usb suspend can always be used */
+ info ("USB suspend: usb-%s", dev->slot_name);
+ ohci->sleeping = 1;
+
+ /* First stop processing */
+ spin_lock_irqsave (&usb_ed_lock, flags);
+ ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
+ writel (ohci->hc_control, &ohci->regs->control);
+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
+ (void) readl (&ohci->regs->intrstatus);
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
+
+ /* Wait a frame or two */
+ mdelay(1);
+ if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
+ mdelay (1);
+
+#ifdef CONFIG_PMAC_PBOOK
+ if (_machine == _MACH_Pmac)
+ disable_irq (ohci->irq);
+ /* else, 2.4 assumes shared irqs -- don't disable */
+#endif
+ /* Enable remote wakeup */
+ writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD,
+&ohci->regs->intrenable);
+
+ /* Suspend chip and let things settle down a bit */
+ ohci->hc_control = OHCI_USB_SUSPEND;
+ writel (ohci->hc_control, &ohci->regs->control);
+ (void) readl (&ohci->regs->control);
+ mdelay (500); /* No schedule here ! */
+ switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
+ case OHCI_USB_RESET:
+ dbg("Bus in reset phase ???");
+ break;
+ case OHCI_USB_RESUME:
+ dbg("Bus in resume phase ???");
+ break;
+ case OHCI_USB_OPER:
+ dbg("Bus in operational phase ???");
+ break;
+ case OHCI_USB_SUSPEND:
+ dbg("Bus suspended");
+ break;
+ }
+ /* In some rare situations, Apple's OHCI have happily trashed
+ * memory during sleep. We disable it's bus master bit during
+ * suspend
+ */
+ pci_read_config_word (dev, PCI_COMMAND, &cmd);
+ cmd &= ~PCI_COMMAND_MASTER;
+ pci_write_config_word (dev, PCI_COMMAND, cmd);
+#ifdef CONFIG_PMAC_PBOOK
+ {
+ struct device_node *of_node;
+
+ /* Disable USB PAD & cell clock */
+ of_node = pci_device_to_OF_node (ohci->ohci_dev);
+ if (of_node && _machine == _MACH_Pmac)
+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
+ }
+#endif
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int
+ohci_pci_resume (struct pci_dev *dev)
+{
+ ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev);
+ int temp;
+ unsigned long flags;
+
+ /* guard against multiple resumes */
+ atomic_inc (&ohci->resume_count);
+ if (atomic_read (&ohci->resume_count) != 1) {
+ err ("concurrent PCI resumes for usb-%s", dev->slot_name);
+ atomic_dec (&ohci->resume_count);
+ return 0;
+ }
+
+#ifdef CONFIG_PMAC_PBOOK
+ {
+ struct device_node *of_node;
+
+ /* Re-enable USB PAD & cell clock */
+ of_node = pci_device_to_OF_node (ohci->ohci_dev);
+ if (of_node && _machine == _MACH_Pmac)
+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1);
+ }
+#endif
+
+ /* did we suspend, or were we powered off? */
+ ohci->hc_control = readl (&ohci->regs->control);
+ temp = ohci->hc_control & OHCI_CTRL_HCFS;
+
+#ifdef DEBUG
+ /* the registers may look crazy here */
+ ohci_dump_status (ohci);
+#endif
+
+ /* Re-enable bus mastering */
+ pci_set_master(ohci->ohci_dev);
+
+ switch (temp) {
+
+ case OHCI_USB_RESET: // lost power
+ info ("USB restart: usb-%s", dev->slot_name);
+ hc_restart (ohci);
+ break;
+
+ case OHCI_USB_SUSPEND: // host wakeup
+ case OHCI_USB_RESUME: // remote wakeup
+ info ("USB continue: usb-%s from %s wakeup", dev->slot_name,
+ (temp == OHCI_USB_SUSPEND)
+ ? "host" : "remote");
+ ohci->hc_control = OHCI_USB_RESUME;
+ writel (ohci->hc_control, &ohci->regs->control);
+ (void) readl (&ohci->regs->control);
+ mdelay (20); /* no schedule here ! */
+ /* Some controllers (lucent) need a longer delay here */
+ mdelay (15);
+ temp = readl (&ohci->regs->control);
+ temp = ohci->hc_control & OHCI_CTRL_HCFS;
+ if (temp != OHCI_USB_RESUME) {
+ err ("controller usb-%s won't resume", dev->slot_name);
+ ohci->disabled = 1;
+ return -EIO;
+ }
+
+ /* Some chips likes being resumed first */
+ writel (OHCI_USB_OPER, &ohci->regs->control);
+ (void) readl (&ohci->regs->control);
+ mdelay (3);
+
+ /* Then re-enable operations */
+ spin_lock_irqsave (&usb_ed_lock, flags);
+ ohci->disabled = 0;
+ ohci->sleeping = 0;
+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+ if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) {
+ if (ohci->ed_controltail)
+ ohci->hc_control |= OHCI_CTRL_CLE;
+ if (ohci->ed_bulktail)
+ ohci->hc_control |= OHCI_CTRL_BLE;
+ }
+ writel (ohci->hc_control, &ohci->regs->control);
+ writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
+ writel (OHCI_INTR_SF, &ohci->regs->intrenable);
+ /* Check for a pending done list */
+ writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
+ (void) readl (&ohci->regs->intrdisable);
+ spin_unlock_irqrestore (&usb_ed_lock, flags);
+#ifdef CONFIG_PMAC_PBOOK
+ if (_machine == _MACH_Pmac)
+ enable_irq (ohci->irq);
+#endif
+ if (ohci->hcca->done_head)
+ dl_done_list (ohci, dl_reverse_done_list (ohci));
+ writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
+ writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
+ writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
+ break;
+
+ default:
+ warn ("odd PCI resume for usb-%s", dev->slot_name);
+ }
+
+ /* controller is operational, extra resumes are harmless */
+ atomic_dec (&ohci->resume_count);
+
+ return 0;
+}
+
+#endif /* CONFIG_PM */
+
+
+/*-------------------------------------------------------------------------*/
+
+static const struct pci_device_id __devinitdata ohci_pci_ids [] = { {
+
+ /*
+ * AMD-756 [Viper] USB has a serious erratum when used with
+ * lowspeed devices like mice.
+ */
+ vendor: 0x1022,
+ device: 0x740c,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+
+ driver_data: OHCI_QUIRK_AMD756,
+
+} , {
+
+ /* handle any USB OHCI controller */
+ class: ((PCI_CLASS_SERIAL_USB << 8) | 0x10),
+ class_mask: ~0,
+
+ /* no matter who makes it */
+ vendor: PCI_ANY_ID,
+ device: PCI_ANY_ID,
+ subvendor: PCI_ANY_ID,
+ subdevice: PCI_ANY_ID,
+
+ }, { /* end: all zeroes */ }
+};
+
+MODULE_DEVICE_TABLE (pci, ohci_pci_ids);
+
+static struct pci_driver ohci_pci_driver = {
+ name: "usb-ohci",
+ id_table: &ohci_pci_ids [0],
+
+ probe: ohci_pci_probe,
+ remove: __devexit_p(ohci_pci_remove),
+
+#ifdef CONFIG_PM
+ suspend: ohci_pci_suspend,
+ resume: ohci_pci_resume,
+#endif /* PM */
+};
+
+
+/*-------------------------------------------------------------------------*/
+
+static int __init ohci_hcd_init (void)
+{
+ return pci_module_init (&ohci_pci_driver);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void __exit ohci_hcd_cleanup (void)
+{
+ pci_unregister_driver (&ohci_pci_driver);
+}
+
+module_init (ohci_hcd_init);
+module_exit (ohci_hcd_cleanup);
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/usb/host/usb-ohci-sa1111.c b/drivers/usb/host/usb-ohci-sa1111.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/host/usb-ohci-sa1111.c Fri May 31 00:41:19 2002
@@ -0,0 +1,130 @@
+/*
+ * linux/drivers/usb/usb-ohci-sa1111.c
+ *
+ * The outline of this code was taken from Brad Parkers <[EMAIL PROTECTED]>
+ * original OHCI driver modifications, and reworked into a cleaner form
+ * by Russell King <[EMAIL PROTECTED]>.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/usb.h>
+#include <linux/errno.h>
+
+#include <asm/hardware.h>
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/arch/assabet.h>
+#include <asm/arch/badge4.h>
+#include <asm/hardware/sa1111.h>
+
+#include "usb-ohci.h"
+
+int __devinit
+hc_add_ohci(struct pci_dev *dev, int irq, void *membase, unsigned long flags,
+ ohci_t **ohci, const char *name, const char *slot_name);
+extern void hc_remove_ohci(ohci_t *ohci);
+
+static ohci_t *sa1111_ohci;
+
+static void __init sa1111_ohci_configure(void)
+{
+ unsigned int usb_rst = 0;
+
+ if (machine_is_xp860() ||
+ machine_has_neponset() ||
+ machine_is_pfs168() ||
+ machine_is_badge4())
+ usb_rst = USB_RESET_PWRSENSELOW | USB_RESET_PWRCTRLLOW;
+
+ /*
+ * Configure the power sense and control lines. Place the USB
+ * host controller in reset.
+ */
+ USB_RESET = usb_rst | USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET;
+
+ /*
+ * Now, carefully enable the USB clock, and take
+ * the USB host controller out of reset.
+ */
+ SKPCR |= SKPCR_UCLKEN;
+ udelay(11);
+ USB_RESET = usb_rst;
+}
+
+static int __init sa1111_ohci_init(void)
+{
+ int ret;
+
+ if (!sa1111)
+ return -ENODEV;
+
+ /*
+ * Request memory resources.
+ */
+// if (!request_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT, "usb-ohci"))
+// return -EBUSY;
+
+ sa1111_ohci_configure();
+
+ /*
+ * Initialise the generic OHCI driver.
+ */
+ ret = hc_add_ohci((struct pci_dev *)1, NIRQHCIM,
+ (void *)&USB_OHCI_OP_BASE, 0, &sa1111_ohci,
+ "usb-ohci", "sa1111");
+
+ if (ret == 0) {
+ if (hc_start (sa1111_ohci, &sa1111->dev) < 0) {
+ err ("can't start usb-%s", sa1111_ohci->slot_name);
+ hc_remove_ohci (sa1111_ohci);
+ return -EBUSY;
+ }
+
+#ifdef DEBUG
+ ohci_dump (ohci, 1);
+#endif
+#ifdef CONFIG_SA1100_BADGE4
+ if (machine_is_badge4()) {
+ /* found the controller, so now power the bus */
+ badge4_set_5V(BADGE4_5V_USB, 1);
+ }
+#endif
+ }
+// else
+// release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
+
+ return ret;
+}
+
+static void __exit sa1111_ohci_exit(void)
+{
+ hc_remove_ohci(sa1111_ohci);
+
+ /*
+ * Put the USB host controller into reset.
+ */
+ USB_RESET |= USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET;
+
+ /*
+ * Stop the USB clock.
+ */
+ SKPCR &= ~SKPCR_UCLKEN;
+
+ /*
+ * Release memory resources.
+ */
+// release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
+
+#ifdef CONFIG_SA1100_BADGE4
+ if (machine_is_badge4()) {
+ badge4_set_5V(BADGE4_5V_USB, 0);
+ }
+#endif
+}
+
+module_init(sa1111_ohci_init);
+module_exit(sa1111_ohci_exit);
diff -Nru a/drivers/usb/host/usb-ohci.c b/drivers/usb/host/usb-ohci.c
--- a/drivers/usb/host/usb-ohci.c Fri May 31 00:41:19 2002
+++ b/drivers/usb/host/usb-ohci.c Fri May 31 00:41:19 2002
@@ -82,16 +82,6 @@
#include "usb-ohci.h"
-#ifdef CONFIG_PMAC_PBOOK
-#include <asm/machdep.h>
-#include <asm/pmac_feature.h>
-#include <asm/pci-bridge.h>
-#ifndef CONFIG_PM
-#define CONFIG_PM
-#endif
-#endif
-
-
/*
* Version Information
*/
@@ -99,14 +89,10 @@
#define DRIVER_AUTHOR "Roman Weissgaerber <[EMAIL PROTECTED]>, David Brownell"
#define DRIVER_DESC "USB OHCI Host Controller Driver"
-/* For initializing controller (mask in an HCFS mode too) */
-#define OHCI_CONTROL_INIT \
- (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
-
#define OHCI_UNLINK_TIMEOUT (HZ / 10)
static LIST_HEAD (ohci_hcd_list);
-static spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
+spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
/*-------------------------------------------------------------------------*/
@@ -443,7 +429,7 @@
static void ohci_dump (ohci_t *controller, int verbose)
{
- dbg ("OHCI controller usb-%s state", controller->ohci_dev->slot_name);
+ dbg ("OHCI controller usb-%s state", controller->slot_name);
// dumps some of the state we know about
ohci_dump_status (controller);
@@ -465,7 +451,7 @@
static int sohci_return_urb (struct ohci *hc, struct urb * urb)
{
urb_priv_t * urb_priv = urb->hcpriv;
- struct urb * urbt;
+ struct urb * urbt = NULL;
unsigned long flags;
int i;
@@ -499,7 +485,7 @@
break;
case PIPE_ISOCHRONOUS:
- for (urbt = urb->next; urbt && (urbt != urb); urbt =
urbt->next);
+ // for (urbt = urb->next; urbt && (urbt != urb); urbt =
+urbt->next);
if (urbt) { /* send the reply and requeue URB */
pci_unmap_single (hc->ohci_dev,
urb_priv->td [0]->data_dma,
@@ -865,7 +851,7 @@
if (ed->state == ED_OPER) {
/* driver on that interface didn't unlink an
urb */
dbg ("driver usb-%s dev %d ed 0x%x unfreed
URB",
- ohci->ohci_dev->slot_name,
usb_dev->devnum, i);
+ ohci->slot_name, usb_dev->devnum, i);
ep_unlink (ohci, ed);
}
ep_rm_ed (usb_dev, ed);
@@ -910,7 +896,7 @@
} else {
/* likely some interface's driver has a refcount bug */
err ("bus %s devnum %d deletion in interrupt",
- ohci->ohci_dev->slot_name, usb_dev->devnum);
+ ohci->slot_name, usb_dev->devnum);
BUG ();
}
}
@@ -1529,7 +1515,7 @@
/* replies to the request have to be on a FIFO basis so
* we reverse the reversed done-list */
-static td_t * dl_reverse_done_list (ohci_t * ohci)
+td_t * dl_reverse_done_list (ohci_t * ohci)
{
__u32 td_list_hc;
td_t * td_rev = NULL;
@@ -1677,7 +1663,7 @@
/* td done list */
-static void dl_done_list (ohci_t * ohci, td_t * td_list)
+void dl_done_list (ohci_t * ohci, td_t * td_list)
{
td_t * td_list_next = NULL;
ed_t * ed;
@@ -1822,7 +1808,7 @@
num_ports = roothub_a (ohci) & RH_A_NDP;
if (num_ports > MAX_ROOT_PORTS) {
err ("bogus NDP=%d for OHCI usb-%s", num_ports,
- ohci->ohci_dev->slot_name);
+ ohci->slot_name);
err ("rereads as NDP=%d",
readl (&ohci->regs->roothub.a) & RH_A_NDP);
/* retry later; "should not happen" */
@@ -2148,7 +2134,7 @@
/* reset the HC and BUS */
-static int hc_reset (ohci_t * ohci)
+int hc_reset (ohci_t * ohci)
{
int timeout = 30;
int smm_timeout = 50; /* 0,5 sec */
@@ -2169,7 +2155,7 @@
writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
dbg("USB HC reset_hc usb-%s: ctrl = 0x%x ;",
- ohci->ohci_dev->slot_name,
+ ohci->slot_name,
readl (&ohci->regs->control));
/* Reset USB (needed by some controllers) */
@@ -2193,7 +2179,7 @@
* enable interrupts
* connect the virtual root hub */
-static int hc_start (ohci_t * ohci)
+int hc_start (ohci_t * ohci, struct device *parent_dev)
{
__u32 mask;
unsigned int fminterval;
@@ -2247,7 +2233,7 @@
dev = usb_to_ohci (usb_dev);
ohci->bus->root_hub = usb_dev;
usb_connect (usb_dev);
- if (usb_register_root_hub (usb_dev, &ohci->ohci_dev->dev) != 0) {
+ if (usb_register_root_hub (usb_dev, parent_dev) != 0) {
usb_free_dev (usb_dev);
ohci->disabled = 1;
return -ENODEV;
@@ -2308,7 +2294,7 @@
if (ints & OHCI_INTR_UE) {
ohci->disabled++;
err ("OHCI Unrecoverable Error, controller usb-%s disabled",
- ohci->ohci_dev->slot_name);
+ ohci->slot_name);
// e.g. due to PCI Master/Target Abort
#ifdef DEBUG
@@ -2385,7 +2371,9 @@
ohci->regs = mem_base;
ohci->ohci_dev = dev;
+#ifdef CONFIG_PCI
pci_set_drvdata(dev, ohci);
+#endif
INIT_LIST_HEAD (&ohci->ohci_hcd_list);
list_add (&ohci->ohci_hcd_list, &ohci_hcd_list);
@@ -2394,7 +2382,9 @@
ohci->bus = usb_alloc_bus (&sohci_device_operations);
if (!ohci->bus) {
+#ifdef CONFIG_PCI
pci_set_drvdata (dev, NULL);
+#endif
pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca,
ohci->hcca, ohci->hcca_dma);
kfree (ohci);
@@ -2413,7 +2403,7 @@
static void hc_release_ohci (ohci_t * ohci)
{
- dbg ("USB HC release ohci usb-%s", ohci->ohci_dev->slot_name);
+ dbg ("USB HC release ohci usb-%s", ohci->slot_name);
/* disconnect all devices */
if (ohci->bus->root_hub)
@@ -2426,7 +2416,9 @@
free_irq (ohci->irq, ohci);
ohci->irq = -1;
}
+#ifdef CONFIG_PCI
pci_set_drvdata(ohci->ohci_dev, NULL);
+#endif
if (ohci->bus) {
if (ohci->bus->busnum)
usb_deregister_bus (ohci->bus);
@@ -2448,18 +2440,15 @@
/*-------------------------------------------------------------------------*/
-/* Increment the module usage count, start the control thread and
- * return success. */
-
-static struct pci_driver ohci_pci_driver;
-
-static int __devinit
-hc_found_ohci (struct pci_dev *dev, int irq,
- void *mem_base, const struct pci_device_id *id)
+/*
+ * Host bus independent add one OHCI host controller.
+ */
+int
+hc_add_ohci(struct pci_dev *dev, int irq, void *mem_base, unsigned long flags,
+ ohci_t **ohcip, const char *name, const char *slot_name)
{
- ohci_t * ohci;
- u8 latency, limit;
char buf[8], *bufp = buf;
+ ohci_t * ohci;
int ret;
#ifndef __sparc__
@@ -2469,34 +2458,20 @@
#endif
printk(KERN_INFO __FILE__ ": USB OHCI at membase 0x%lx, IRQ %s\n",
(unsigned long) mem_base, bufp);
- printk(KERN_INFO __FILE__ ": usb-%s, %s\n", dev->slot_name, dev->name);
ohci = hc_alloc_ohci (dev, mem_base);
if (!ohci) {
return -ENOMEM;
}
+ ohci->slot_name = slot_name;
if ((ret = ohci_mem_init (ohci)) < 0) {
hc_release_ohci (ohci);
return ret;
}
- ohci->flags = id->driver_data;
+ ohci->flags = flags;
if (ohci->flags & OHCI_QUIRK_AMD756)
printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
- /* bad pci latencies can contribute to overruns */
- pci_read_config_byte (dev, PCI_LATENCY_TIMER, &latency);
- if (latency) {
- pci_read_config_byte (dev, PCI_MAX_LAT, &limit);
- if (limit && limit < latency) {
- dbg ("PCI latency reduced to max %d", limit);
- pci_write_config_byte (dev, PCI_LATENCY_TIMER, limit);
- ohci->pci_latency = limit;
- } else {
- /* it might already have been reduced */
- ohci->pci_latency = latency;
- }
- }
-
if (hc_reset (ohci) < 0) {
hc_release_ohci (ohci);
return -ENODEV;
@@ -2508,134 +2483,23 @@
usb_register_bus (ohci->bus);
- if (request_irq (irq, hc_interrupt, SA_SHIRQ,
- ohci_pci_driver.name, ohci) != 0) {
+ if (request_irq (irq, hc_interrupt, SA_SHIRQ, name, ohci) != 0) {
err ("request interrupt %s failed", bufp);
hc_release_ohci (ohci);
return -EBUSY;
}
ohci->irq = irq;
- if (hc_start (ohci) < 0) {
- err ("can't start usb-%s", dev->slot_name);
- hc_release_ohci (ohci);
- return -EBUSY;
- }
+ *ohcip = ohci;
-#ifdef DEBUG
- ohci_dump (ohci, 1);
-#endif
return 0;
}
-/*-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_PM
-
-/* controller died; cleanup debris, then restart */
-/* must not be called from interrupt context */
-
-static void hc_restart (ohci_t *ohci)
-{
- int temp;
- int i;
-
- if (ohci->pci_latency)
- pci_write_config_byte (ohci->ohci_dev, PCI_LATENCY_TIMER,
ohci->pci_latency);
-
- ohci->disabled = 1;
- ohci->sleeping = 0;
- if (ohci->bus->root_hub)
- usb_disconnect (&ohci->bus->root_hub);
-
- /* empty the interrupt branches */
- for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
- for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table[i] = 0;
-
- /* no EDs to remove */
- ohci->ed_rm_list [0] = NULL;
- ohci->ed_rm_list [1] = NULL;
-
- /* empty control and bulk lists */
- ohci->ed_isotail = NULL;
- ohci->ed_controltail = NULL;
- ohci->ed_bulktail = NULL;
-
- if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
- err ("can't restart usb-%s, %d", ohci->ohci_dev->slot_name, temp);
- } else
- dbg ("restart usb-%s completed", ohci->ohci_dev->slot_name);
-}
-
-#endif /* CONFIG_PM */
-
-/*-------------------------------------------------------------------------*/
-
-/* configured so that an OHCI device is always provided */
-/* always called with process context; sleeping is OK */
-
-static int __devinit
-ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
+/*
+ * Host bus independent remove one OHCI host controller.
+ */
+void hc_remove_ohci(ohci_t *ohci)
{
- unsigned long mem_resource, mem_len;
- void *mem_base;
- int status;
-
- if (pci_enable_device(dev) < 0)
- return -ENODEV;
-
- if (!dev->irq) {
- err("found OHCI device with no IRQ assigned. check BIOS settings!");
- pci_disable_device (dev);
- return -ENODEV;
- }
-
- /* we read its hardware registers as memory */
- mem_resource = pci_resource_start(dev, 0);
- mem_len = pci_resource_len(dev, 0);
- if (!request_mem_region (mem_resource, mem_len, ohci_pci_driver.name)) {
- dbg ("controller already in use");
- pci_disable_device (dev);
- return -EBUSY;
- }
-
- mem_base = ioremap_nocache (mem_resource, mem_len);
- if (!mem_base) {
- err("Error mapping OHCI memory");
- release_mem_region (mem_resource, mem_len);
- pci_disable_device (dev);
- return -EFAULT;
- }
-
- /* controller writes into our memory */
- pci_set_master (dev);
-
- status = hc_found_ohci (dev, dev->irq, mem_base, id);
- if (status < 0) {
- iounmap (mem_base);
- release_mem_region (mem_resource, mem_len);
- pci_disable_device (dev);
- }
- return status;
-}
-
-/*-------------------------------------------------------------------------*/
-
-/* may be called from interrupt context [interface spec] */
-/* may be called without controller present */
-/* may be called with controller, bus, and devices active */
-
-static void __devexit
-ohci_pci_remove (struct pci_dev *dev)
-{
- ohci_t *ohci = pci_get_drvdata(dev);
-
- dbg ("remove %s controller usb-%s%s%s",
- hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
- dev->slot_name,
- ohci->disabled ? " (disabled)" : "",
- in_interrupt () ? " in interrupt" : ""
- );
#ifdef DEBUG
ohci_dump (ohci, 1);
#endif
@@ -2652,270 +2516,16 @@
&ohci->regs->control);
hc_release_ohci (ohci);
-
- release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
- pci_disable_device (dev);
-}
-
-
-#ifdef CONFIG_PM
-
-/*-------------------------------------------------------------------------*/
-
-static int
-ohci_pci_suspend (struct pci_dev *dev, u32 state)
-{
- ohci_t *ohci = pci_get_drvdata(dev);
- unsigned long flags;
- u16 cmd;
-
- if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
- dbg ("can't suspend usb-%s (state is %s)", dev->slot_name,
- hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
- return -EIO;
- }
-
- /* act as if usb suspend can always be used */
- info ("USB suspend: usb-%s", dev->slot_name);
- ohci->sleeping = 1;
-
- /* First stop processing */
- spin_lock_irqsave (&usb_ed_lock, flags);
- ohci->hc_control &= ~(OHCI_CTRL_PLE|OHCI_CTRL_CLE|OHCI_CTRL_BLE|OHCI_CTRL_IE);
- writel (ohci->hc_control, &ohci->regs->control);
- writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
- (void) readl (&ohci->regs->intrstatus);
- spin_unlock_irqrestore (&usb_ed_lock, flags);
-
- /* Wait a frame or two */
- mdelay(1);
- if (!readl (&ohci->regs->intrstatus) & OHCI_INTR_SF)
- mdelay (1);
-
-#ifdef CONFIG_PMAC_PBOOK
- if (_machine == _MACH_Pmac)
- disable_irq (ohci->irq);
- /* else, 2.4 assumes shared irqs -- don't disable */
-#endif
- /* Enable remote wakeup */
- writel (readl(&ohci->regs->intrenable) | OHCI_INTR_RD,
&ohci->regs->intrenable);
-
- /* Suspend chip and let things settle down a bit */
- ohci->hc_control = OHCI_USB_SUSPEND;
- writel (ohci->hc_control, &ohci->regs->control);
- (void) readl (&ohci->regs->control);
- mdelay (500); /* No schedule here ! */
- switch (readl (&ohci->regs->control) & OHCI_CTRL_HCFS) {
- case OHCI_USB_RESET:
- dbg("Bus in reset phase ???");
- break;
- case OHCI_USB_RESUME:
- dbg("Bus in resume phase ???");
- break;
- case OHCI_USB_OPER:
- dbg("Bus in operational phase ???");
- break;
- case OHCI_USB_SUSPEND:
- dbg("Bus suspended");
- break;
- }
- /* In some rare situations, Apple's OHCI have happily trashed
- * memory during sleep. We disable it's bus master bit during
- * suspend
- */
- pci_read_config_word (dev, PCI_COMMAND, &cmd);
- cmd &= ~PCI_COMMAND_MASTER;
- pci_write_config_word (dev, PCI_COMMAND, cmd);
-#ifdef CONFIG_PMAC_PBOOK
- {
- struct device_node *of_node;
-
- /* Disable USB PAD & cell clock */
- of_node = pci_device_to_OF_node (ohci->ohci_dev);
- if (of_node)
- pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
- }
-#endif
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-static int
-ohci_pci_resume (struct pci_dev *dev)
-{
- ohci_t *ohci = pci_get_drvdata(dev);
- int temp;
- unsigned long flags;
-
- /* guard against multiple resumes */
- atomic_inc (&ohci->resume_count);
- if (atomic_read (&ohci->resume_count) != 1) {
- err ("concurrent PCI resumes for usb-%s", dev->slot_name);
- atomic_dec (&ohci->resume_count);
- return 0;
- }
-
-#ifdef CONFIG_PMAC_PBOOK
- {
- struct device_node *of_node;
-
- /* Re-enable USB PAD & cell clock */
- of_node = pci_device_to_OF_node (ohci->ohci_dev);
- if (of_node)
- pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 1);
- }
-#endif
-
- /* did we suspend, or were we powered off? */
- ohci->hc_control = readl (&ohci->regs->control);
- temp = ohci->hc_control & OHCI_CTRL_HCFS;
-
-#ifdef DEBUG
- /* the registers may look crazy here */
- ohci_dump_status (ohci);
-#endif
-
- /* Re-enable bus mastering */
- pci_set_master(ohci->ohci_dev);
-
- switch (temp) {
-
- case OHCI_USB_RESET: // lost power
- info ("USB restart: usb-%s", dev->slot_name);
- hc_restart (ohci);
- break;
-
- case OHCI_USB_SUSPEND: // host wakeup
- case OHCI_USB_RESUME: // remote wakeup
- info ("USB continue: usb-%s from %s wakeup", dev->slot_name,
- (temp == OHCI_USB_SUSPEND)
- ? "host" : "remote");
- ohci->hc_control = OHCI_USB_RESUME;
- writel (ohci->hc_control, &ohci->regs->control);
- (void) readl (&ohci->regs->control);
- mdelay (20); /* no schedule here ! */
- /* Some controllers (lucent) need a longer delay here */
- mdelay (15);
- temp = readl (&ohci->regs->control);
- temp = ohci->hc_control & OHCI_CTRL_HCFS;
- if (temp != OHCI_USB_RESUME) {
- err ("controller usb-%s won't resume", dev->slot_name);
- ohci->disabled = 1;
- return -EIO;
- }
-
- /* Some chips likes being resumed first */
- writel (OHCI_USB_OPER, &ohci->regs->control);
- (void) readl (&ohci->regs->control);
- mdelay (3);
-
- /* Then re-enable operations */
- spin_lock_irqsave (&usb_ed_lock, flags);
- ohci->disabled = 0;
- ohci->sleeping = 0;
- ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
- if (!ohci->ed_rm_list[0] && !ohci->ed_rm_list[1]) {
- if (ohci->ed_controltail)
- ohci->hc_control |= OHCI_CTRL_CLE;
- if (ohci->ed_bulktail)
- ohci->hc_control |= OHCI_CTRL_BLE;
- }
- writel (ohci->hc_control, &ohci->regs->control);
- writel (OHCI_INTR_SF, &ohci->regs->intrstatus);
- writel (OHCI_INTR_SF, &ohci->regs->intrenable);
- /* Check for a pending done list */
- writel (OHCI_INTR_WDH, &ohci->regs->intrdisable);
- (void) readl (&ohci->regs->intrdisable);
- spin_unlock_irqrestore (&usb_ed_lock, flags);
-#ifdef CONFIG_PMAC_PBOOK
- if (_machine == _MACH_Pmac)
- enable_irq (ohci->irq);
-#endif
- if (ohci->hcca->done_head)
- dl_done_list (ohci, dl_reverse_done_list (ohci));
- writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
- writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
- writel (OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
- break;
-
- default:
- warn ("odd PCI resume for usb-%s", dev->slot_name);
- }
-
- /* controller is operational, extra resumes are harmless */
- atomic_dec (&ohci->resume_count);
-
- return 0;
-}
-
-#endif /* CONFIG_PM */
-
-
-/*-------------------------------------------------------------------------*/
-
-static const struct pci_device_id __devinitdata ohci_pci_ids [] = { {
-
- /*
- * AMD-756 [Viper] USB has a serious erratum when used with
- * lowspeed devices like mice.
- */
- vendor: 0x1022,
- device: 0x740c,
- subvendor: PCI_ANY_ID,
- subdevice: PCI_ANY_ID,
-
- driver_data: OHCI_QUIRK_AMD756,
-
-} , {
-
- /* handle any USB OHCI controller */
- class: ((PCI_CLASS_SERIAL_USB << 8) | 0x10),
- class_mask: ~0,
-
- /* no matter who makes it */
- vendor: PCI_ANY_ID,
- device: PCI_ANY_ID,
- subvendor: PCI_ANY_ID,
- subdevice: PCI_ANY_ID,
-
- }, { /* end: all zeroes */ }
-};
-
-MODULE_DEVICE_TABLE (pci, ohci_pci_ids);
-
-static struct pci_driver ohci_pci_driver = {
- name: "usb-ohci",
- id_table: &ohci_pci_ids [0],
-
- probe: ohci_pci_probe,
- remove: __devexit_p(ohci_pci_remove),
-
-#ifdef CONFIG_PM
- suspend: ohci_pci_suspend,
- resume: ohci_pci_resume,
-#endif /* PM */
-};
-
-
-/*-------------------------------------------------------------------------*/
-
-static int __init ohci_hcd_init (void)
-{
- return pci_module_init (&ohci_pci_driver);
}
-/*-------------------------------------------------------------------------*/
-
-static void __exit ohci_hcd_cleanup (void)
-{
- pci_unregister_driver (&ohci_pci_driver);
-}
-
-module_init (ohci_hcd_init);
-module_exit (ohci_hcd_cleanup);
-
-
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(hc_add_ohci);
+EXPORT_SYMBOL(hc_remove_ohci);
+EXPORT_SYMBOL(hc_start);
+EXPORT_SYMBOL(hc_reset);
+EXPORT_SYMBOL(dl_done_list);
+EXPORT_SYMBOL(dl_reverse_done_list);
+EXPORT_SYMBOL(usb_ed_lock);
diff -Nru a/drivers/usb/host/usb-ohci.h b/drivers/usb/host/usb-ohci.h
--- a/drivers/usb/host/usb-ohci.h Fri May 31 00:41:19 2002
+++ b/drivers/usb/host/usb-ohci.h Fri May 31 00:41:19 2002
@@ -403,6 +403,7 @@
/* PCI device handle, settings, ... */
struct pci_dev *ohci_dev;
+ const char *slot_name;
u8 pci_latency;
struct pci_pool *td_cache;
struct pci_pool *dev_cache;
@@ -423,6 +424,10 @@
// #define ohci_to_usb(ohci) ((ohci)->usb)
#define usb_to_ohci(usb) ((struct ohci_device *)(usb)->hcpriv)
+/* For initializing controller (mask in an HCFS mode too) */
+#define OHCI_CONTROL_INIT \
+ (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE
+
/* hcd */
/* endpoint */
static int ep_link(ohci_t * ohci, ed_t * ed);
@@ -447,11 +452,6 @@
# define OHCI_MEM_FLAGS 0
#endif
-#ifndef CONFIG_PCI
-# error "usb-ohci currently requires PCI-based controllers"
- /* to support non-PCI OHCIs, you need custom bus/mem/... glue */
-#endif
-
/* Recover a TD/ED using its collision chain */
static void *
@@ -640,4 +640,9 @@
{
pci_pool_free (hc->dev_cache, dev, dev->dma);
}
+
+extern spinlock_t usb_ed_lock;
+extern void dl_done_list (ohci_t * ohci, td_t * td_list);
+extern td_t * dl_reverse_done_list (ohci_t * ohci);
+
_______________________________________________________________
Don't miss the 2002 Sprint PCS Application Developer's Conference
August 25-28 in Las Vegas -- http://devcon.sprintpcs.com/adp/index.cfm
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel