# 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.475 -> 1.476
# drivers/usb/host/usb-ohci-sa1111.c 1.1 -> 1.2
# drivers/usb/host/ohci-hcd.c 1.12 -> 1.13
# drivers/usb/host/usb-ohci.c 1.35 -> 1.36
# drivers/usb/core/hcd.h 1.10 -> 1.11
# drivers/usb/core/hcd.c 1.24 -> 1.25
# drivers/usb/host/usb-ohci-pci.c 1.1 -> 1.2
# drivers/usb/host/ohci-mem.c 1.5 -> 1.6
# drivers/usb/host/ohci-q.c 1.8 -> 1.9
# drivers/usb/host/ohci.h 1.5 -> 1.6
# (new) -> 1.1 drivers/usb/host/ohci-sa1111.c
# (new) -> 1.1 drivers/usb/host/ohci-pci.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 02/06/08 [EMAIL PROTECTED] 1.476
# [PATCH] USB SA-1111 patch against usb-2.5 bitkeeper
#
# This adds SA-1111 support for ohci-hcd and fixes usb-ohci too.
# --------------------------------------------
#
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c Sat Jun 8 15:45:52 2002
+++ b/drivers/usb/core/hcd.c Sat Jun 8 15:45:52 2002
@@ -24,6 +24,7 @@
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/completion.h>
diff -Nru a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
--- a/drivers/usb/core/hcd.h Sat Jun 8 15:45:52 2002
+++ b/drivers/usb/core/hcd.h Sat Jun 8 15:45:52 2002
@@ -50,9 +50,9 @@
int irq; /* irq allocated */
void *regs; /* device memory/io */
-#ifdef CONFIG_PCI
/* a few non-PCI controllers exist, mostly for OHCI */
struct pci_dev *pdev; /* pci is typical */
+#ifdef CONFIG_PCI
int region; /* pci region for regs */
u32 pci_state [16]; /* for PM state save */
atomic_t resume_count; /* multiple resumes issue */
diff -Nru a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
--- a/drivers/usb/host/ohci-hcd.c Sat Jun 8 15:45:52 2002
+++ b/drivers/usb/host/ohci-hcd.c Sat Jun 8 15:45:52 2002
@@ -78,9 +78,9 @@
#include <linux/interrupt.h> /* for in_interrupt () */
#ifdef CONFIG_USB_DEBUG
- #define DEBUG
+# define DEBUG
#else
- #undef DEBUG
+# undef DEBUG
#endif
#include <linux/usb.h>
@@ -92,15 +92,6 @@
#include <asm/unaligned.h>
#include <asm/byteorder.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
-
/*
* TO DO:
*
@@ -226,7 +217,7 @@
case PIPE_ISOCHRONOUS:
if (urb->transfer_flags & USB_ISO_ASAP) {
urb->start_frame = ( (ed->state == ED_OPER)
- ? (ed->last_iso + 1)
+ ? (ed->intriso.last_iso + 1)
: (le16_to_cpu (ohci->hcca->frame_no)
+ 10)) & 0xffff;
}
@@ -411,7 +402,7 @@
__u32 mask;
unsigned int fminterval;
struct usb_device *udev;
-
+
spin_lock_init (&ohci->lock);
ohci->disabled = 1;
ohci->sleeping = 0;
@@ -462,7 +453,7 @@
usb_connect (udev);
udev->speed = USB_SPEED_FULL;
- if (usb_register_root_hub (udev, &ohci->hcd.pdev->dev) != 0) {
+ if (usb_register_root_hub (udev, ohci->parent_dev) != 0) {
usb_free_dev (udev);
ohci->disabled = 1;
// FIXME cleanup
@@ -545,167 +536,19 @@
ohci_mem_cleanup (ohci);
-#ifdef CONFIG_PCI
pci_free_consistent (ohci->hcd.pdev, sizeof *ohci->hcca,
ohci->hcca, ohci->hcca_dma);
-#endif
}
/*-------------------------------------------------------------------------*/
-static int __devinit
-ohci_start (struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int ret;
-
-#ifdef CONFIG_PCI
- if (hcd->pdev) {
- ohci->hcca = pci_alloc_consistent (hcd->pdev,
- sizeof *ohci->hcca, &ohci->hcca_dma);
- if (!ohci->hcca)
- return -ENOMEM;
-
- /* AMD 756, for most chips (early revs), corrupts register
- * values on read ... so enable the vendor workaround.
- */
- if (hcd->pdev->vendor == 0x1022
- && hcd->pdev->device == 0x740c) {
- ohci->flags = OHCI_QUIRK_AMD756;
- info ("%s: AMD756 erratum 4 workaround",
- hcd->self.bus_name);
- }
-
- /* Apple's OHCI driver has a lot of bizarre workarounds
- * for this chip. Evidently control and bulk lists
- * can get confused. (B&W G3 models, and ...)
- */
- else if (hcd->pdev->vendor == 0x1045
- && hcd->pdev->device == 0xc861) {
- info ("%s: WARNING: OPTi workarounds unavailable",
- hcd->self.bus_name);
- }
- }
-#else
-# error "where's hcca coming from?"
-#endif /* CONFIG_PCI */
-
- memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
- if ((ret = ohci_mem_init (ohci)) < 0) {
- ohci_stop (hcd);
- return ret;
- }
- ohci->regs = hcd->regs;
-
- if (hc_reset (ohci) < 0) {
- ohci_stop (hcd);
- return -ENODEV;
- }
-
- if (hc_start (ohci) < 0) {
- err ("can't start %s", ohci->hcd.self.bus_name);
- ohci_stop (hcd);
- return -EBUSY;
- }
-
-#ifdef DEBUG
- ohci_dump (ohci, 1);
-#endif
- return 0;
-}
-
-/*-------------------------------------------------------------------------*/
-
-#ifdef CONFIG_PM
-
-static int ohci_suspend (struct usb_hcd *hcd, u32 state)
-{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- unsigned long flags;
- u16 cmd;
-
- if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
- dbg ("can't suspend %s (state is %s)", hcd->self.bus_name,
- hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
- return -EIO;
- }
-
- /* act as if usb suspend can always be used */
- dbg ("%s: suspend to %d", hcd->self.bus_name, state);
- ohci->sleeping = 1;
-
- /* First stop processing */
- spin_lock_irqsave (&ohci->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 (&ohci->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 (hcd->pdev->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 ("%s suspend->reset ?", hcd->self.bus_name);
- break;
- case OHCI_USB_RESUME:
- dbg ("%s suspend->resume ?", hcd->self.bus_name);
- break;
- case OHCI_USB_OPER:
- dbg ("%s suspend->operational ?", hcd->self.bus_name);
- break;
- case OHCI_USB_SUSPEND:
- dbg ("%s suspended", hcd->self.bus_name);
- break;
- }
-
- /* In some rare situations, Apple's OHCI have happily trashed
- * memory during sleep. We disable its bus master bit during
- * suspend
- */
- pci_read_config_word (hcd->pdev, PCI_COMMAND, &cmd);
- cmd &= ~PCI_COMMAND_MASTER;
- pci_write_config_word (hcd->pdev, PCI_COMMAND, cmd);
-#ifdef CONFIG_PMAC_PBOOK
- {
- struct device_node *of_node;
-
- /* Disable USB PAD & cell clock */
- of_node = pci_device_to_OF_node (hcd->pdev);
- if (of_node)
- pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
- }
-#endif
- return 0;
-}
-
-
// FIXME: this restart logic should be generic,
// and handle full hcd state cleanup
/* controller died; cleanup debris, then restart */
/* must not be called from interrupt context */
+#ifdef CONFIG_PM
static int hc_restart (struct ohci_hcd *ohci)
{
int temp;
@@ -735,227 +578,26 @@
dbg ("restart %s completed", ohci->hcd.self.bus_name);
return 0;
}
-
-static int ohci_resume (struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci (hcd);
- int temp;
- int retval = 0;
- unsigned long flags;
-
-#ifdef CONFIG_PMAC_PBOOK
- {
- struct device_node *of_node;
-
- /* Re-enable USB PAD & cell clock */
- of_node = pci_device_to_OF_node (hcd->pdev);
- 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->hcd.pdev);
-
- switch (temp) {
-
- case OHCI_USB_RESET: // lost power
- info ("USB restart: %s", hcd->self.bus_name);
- retval = hc_restart (ohci);
- break;
-
- case OHCI_USB_SUSPEND: // host wakeup
- case OHCI_USB_RESUME: // remote wakeup
- info ("USB continue: %s from %s wakeup", hcd->self.bus_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 %s won't resume", hcd->self.bus_name);
- ohci->disabled = 1;
- retval = -EIO;
- break;
- }
-
- /* 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 (&ohci->lock, flags);
- ohci->disabled = 0;
- ohci->sleeping = 0;
- ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
- if (!ohci->ed_rm_list) {
- if (ohci->ed_controltail)
- ohci->hc_control |= OHCI_CTRL_CLE;
- if (ohci->ed_bulktail)
- ohci->hc_control |= OHCI_CTRL_BLE;
- }
- hcd->state = USB_STATE_READY;
- writel (ohci->hc_control, &ohci->regs->control);
-
- /* trigger a start-frame interrupt (why?) */
- 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 (&ohci->lock, flags);
-
- #ifdef CONFIG_PMAC_PBOOK
- if (_machine == _MACH_Pmac)
- enable_irq (hcd->pdev->irq);
- #endif
- if (ohci->hcca->done_head)
- dl_done_list (ohci, dl_reverse_done_list (ohci));
- writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
-
- /* assume there are TDs on the bulk and control lists */
- writel (OHCI_BLF | OHCI_CLF, &ohci->regs->cmdstatus);
-
-// ohci_dump_status (ohci);
-dbg ("sleeping = %d, disabled = %d", ohci->sleeping, ohci->disabled);
- break;
-
- default:
- warn ("odd PCI resume for %s", hcd->self.bus_name);
- }
- return retval;
-}
-
-#endif /* CONFIG_PM */
-
/*-------------------------------------------------------------------------*/
static const char hcd_name [] = "ohci-hcd";
-static const struct hc_driver ohci_driver = {
- description: hcd_name,
-
- /*
- * generic hardware linkage
- */
- irq: ohci_irq,
- flags: HCD_MEMORY | HCD_USB11,
-
- /*
- * basic lifecycle operations
- */
- start: ohci_start,
-#ifdef CONFIG_PM
- suspend: ohci_suspend,
- resume: ohci_resume,
-#endif
- stop: ohci_stop,
-
- /*
- * memory lifecycle (except per-request)
- */
- hcd_alloc: ohci_hcd_alloc,
- hcd_free: ohci_hcd_free,
-
- /*
- * managing i/o requests and associated device resources
- */
- urb_enqueue: ohci_urb_enqueue,
- urb_dequeue: ohci_urb_dequeue,
- free_config: ohci_free_config,
-
- /*
- * scheduling support
- */
- get_frame_number: ohci_get_frame,
-
- /*
- * root hub support
- */
- hub_status_data: ohci_hub_status_data,
- hub_control: ohci_hub_control,
-};
-
#define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
MODULE_AUTHOR (DRIVER_AUTHOR);
MODULE_DESCRIPTION (DRIVER_INFO);
MODULE_LICENSE ("GPL");
-/*-------------------------------------------------------------------------*/
-
#ifdef CONFIG_PCI
-
-/* There do exist non-PCI implementations of OHCI ...
- * Examples include the SA-1111 (ARM) and some MIPS
- * and related hardware.
- */
-
-static const struct pci_device_id __devinitdata pci_ids [] = { {
-
- /* handle any USB OHCI controller */
- class: (PCI_CLASS_SERIAL_USB << 8) | 0x10,
- class_mask: ~0,
- driver_data: (unsigned long) &ohci_driver,
-
- /* 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, pci_ids);
-
-/* pci driver glue; this is a "new style" PCI driver module */
-static struct pci_driver ohci_pci_driver = {
- name: (char *) hcd_name,
- id_table: pci_ids,
-
- probe: usb_hcd_pci_probe,
- remove: usb_hcd_pci_remove,
-
-#ifdef CONFIG_PM
- suspend: usb_hcd_pci_suspend,
- resume: usb_hcd_pci_resume,
+#include "ohci-pci.c"
#endif
-};
-
-
-static int __init ohci_hcd_init (void)
-{
- dbg (DRIVER_INFO);
- dbg ("block sizes: ed %d td %d",
- sizeof (struct ed), sizeof (struct td));
- return pci_module_init (&ohci_pci_driver);
-}
-module_init (ohci_hcd_init);
-/*-------------------------------------------------------------------------*/
-
-static void __exit ohci_hcd_cleanup (void)
-{
- pci_unregister_driver (&ohci_pci_driver);
-}
-module_exit (ohci_hcd_cleanup);
-
-#endif /* CONFIG_PCI */
+#ifdef CONFIG_SA1111
+#include "ohci-sa1111.c"
+#endif
+#if !(defined(CONFIG_PCI) || defined(CONFIG_SA1111))
+#error "missing bus glue for ohci-hcd"
+#endif
diff -Nru a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c
--- a/drivers/usb/host/ohci-mem.c Sat Jun 8 15:45:52 2002
+++ b/drivers/usb/host/ohci-mem.c Sat Jun 8 15:45:52 2002
@@ -42,12 +42,6 @@
/*-------------------------------------------------------------------------*/
-#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 inline void *
dma_to_ed_td (struct hash_list_t * entry, dma_addr_t dma)
diff -Nru a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/host/ohci-pci.c Sat Jun 8 15:45:52 2002
@@ -0,0 +1,380 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <[EMAIL PROTECTED]>
+ * (C) Copyright 2000-2002 David Brownell <[EMAIL PROTECTED]>
+ *
+ * [ Initialisation is based on Linus' ]
+ * [ uhci code and gregs ohci fragments ]
+ * [ (C) Copyright 1999 Linus Torvalds ]
+ * [ (C) Copyright 1999 Gregory P. Smith]
+ *
+ * PCI Bus Glue
+ *
+ * This file is licenced under the GPL.
+ */
+
+#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
+
+#ifndef CONFIG_PCI
+#error "This file is PCI bus glue. CONFIG_PCI must be defined."
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static int __devinit
+ohci_pci_start (struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ int ret;
+
+ if (hcd->pdev) {
+ ohci->hcca = pci_alloc_consistent (hcd->pdev,
+ sizeof *ohci->hcca, &ohci->hcca_dma);
+ if (!ohci->hcca)
+ return -ENOMEM;
+
+ /* AMD 756, for most chips (early revs), corrupts register
+ * values on read ... so enable the vendor workaround.
+ */
+ if (hcd->pdev->vendor == 0x1022
+ && hcd->pdev->device == 0x740c) {
+ ohci->flags = OHCI_QUIRK_AMD756;
+ info ("%s: AMD756 erratum 4 workaround",
+ hcd->self.bus_name);
+ }
+
+ /* Apple's OHCI driver has a lot of bizarre workarounds
+ * for this chip. Evidently control and bulk lists
+ * can get confused. (B&W G3 models, and ...)
+ */
+ else if (hcd->pdev->vendor == 0x1045
+ && hcd->pdev->device == 0xc861) {
+ info ("%s: WARNING: OPTi workarounds unavailable",
+ hcd->self.bus_name);
+ }
+ }
+
+ memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
+ if ((ret = ohci_mem_init (ohci)) < 0) {
+ ohci_stop (hcd);
+ return ret;
+ }
+ ohci->regs = hcd->regs;
+
+ ohci->parent_dev = &ohci->hcd.pdev->dev;
+
+ if (hc_reset (ohci) < 0) {
+ ohci_stop (hcd);
+ return -ENODEV;
+ }
+
+ if (hc_start (ohci) < 0) {
+ err ("can't start %s", ohci->hcd.self.bus_name);
+ ohci_stop (hcd);
+ return -EBUSY;
+ }
+
+#ifdef DEBUG
+ ohci_dump (ohci, 1);
+#endif
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ unsigned long flags;
+ u16 cmd;
+
+ if ((ohci->hc_control & OHCI_CTRL_HCFS) != OHCI_USB_OPER) {
+ dbg ("can't suspend %s (state is %s)", hcd->self.bus_name,
+ hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS));
+ return -EIO;
+ }
+
+ /* act as if usb suspend can always be used */
+ dbg ("%s: suspend to %d", hcd->self.bus_name, state);
+ ohci->sleeping = 1;
+
+ /* First stop processing */
+ spin_lock_irqsave (&ohci->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 (&ohci->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 (hcd->pdev->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 ("%s suspend->reset ?", hcd->self.bus_name);
+ break;
+ case OHCI_USB_RESUME:
+ dbg ("%s suspend->resume ?", hcd->self.bus_name);
+ break;
+ case OHCI_USB_OPER:
+ dbg ("%s suspend->operational ?", hcd->self.bus_name);
+ break;
+ case OHCI_USB_SUSPEND:
+ dbg ("%s suspended", hcd->self.bus_name);
+ break;
+ }
+
+ /* In some rare situations, Apple's OHCI have happily trashed
+ * memory during sleep. We disable its bus master bit during
+ * suspend
+ */
+ pci_read_config_word (hcd->pdev, PCI_COMMAND, &cmd);
+ cmd &= ~PCI_COMMAND_MASTER;
+ pci_write_config_word (hcd->pdev, PCI_COMMAND, cmd);
+#ifdef CONFIG_PMAC_PBOOK
+ {
+ struct device_node *of_node;
+
+ /* Disable USB PAD & cell clock */
+ of_node = pci_device_to_OF_node (hcd->pdev);
+ if (of_node)
+ pmac_call_feature(PMAC_FTR_USB_ENABLE, of_node, 0, 0);
+ }
+#endif
+ return 0;
+}
+
+
+static int ohci_pci_resume (struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ int temp;
+ int retval = 0;
+ unsigned long flags;
+
+#ifdef CONFIG_PMAC_PBOOK
+ {
+ struct device_node *of_node;
+
+ /* Re-enable USB PAD & cell clock */
+ of_node = pci_device_to_OF_node (hcd->pdev);
+ 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->hcd.pdev);
+
+ switch (temp) {
+
+ case OHCI_USB_RESET: // lost power
+ info ("USB restart: %s", hcd->self.bus_name);
+ retval = hc_restart (ohci);
+ break;
+
+ case OHCI_USB_SUSPEND: // host wakeup
+ case OHCI_USB_RESUME: // remote wakeup
+ info ("USB continue: %s from %s wakeup", hcd->self.bus_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 %s won't resume", hcd->self.bus_name);
+ ohci->disabled = 1;
+ retval = -EIO;
+ break;
+ }
+
+ /* 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 (&ohci->lock, flags);
+ ohci->disabled = 0;
+ ohci->sleeping = 0;
+ ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
+ if (!ohci->ed_rm_list) {
+ if (ohci->ed_controltail)
+ ohci->hc_control |= OHCI_CTRL_CLE;
+ if (ohci->ed_bulktail)
+ ohci->hc_control |= OHCI_CTRL_BLE;
+ }
+ hcd->state = USB_STATE_READY;
+ writel (ohci->hc_control, &ohci->regs->control);
+
+ /* trigger a start-frame interrupt (why?) */
+ 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 (&ohci->lock, flags);
+
+#ifdef CONFIG_PMAC_PBOOK
+ if (_machine == _MACH_Pmac)
+ enable_irq (hcd->pdev->irq);
+#endif
+ if (ohci->hcca->done_head)
+ dl_done_list (ohci, dl_reverse_done_list (ohci));
+ writel (OHCI_INTR_WDH, &ohci->regs->intrenable);
+
+ /* assume there are TDs on the bulk and control lists */
+ writel (OHCI_BLF | OHCI_CLF, &ohci->regs->cmdstatus);
+
+// ohci_dump_status (ohci);
+dbg ("sleeping = %d, disabled = %d", ohci->sleeping, ohci->disabled);
+ break;
+
+ default:
+ warn ("odd PCI resume for %s", hcd->self.bus_name);
+ }
+ return retval;
+}
+
+#endif /* CONFIG_PM */
+
+
+/*-------------------------------------------------------------------------*/
+
+static const struct hc_driver ohci_pci_hc_driver = {
+ description: hcd_name,
+
+ /*
+ * generic hardware linkage
+ */
+ irq: ohci_irq,
+ flags: HCD_MEMORY | HCD_USB11,
+
+ /*
+ * basic lifecycle operations
+ */
+ start: ohci_pci_start,
+#ifdef CONFIG_PM
+ suspend: ohci_pci_suspend,
+ resume: ohci_pci_resume,
+#endif
+ stop: ohci_stop,
+
+ /*
+ * memory lifecycle (except per-request)
+ */
+ hcd_alloc: ohci_hcd_alloc,
+ hcd_free: ohci_hcd_free,
+
+ /*
+ * managing i/o requests and associated device resources
+ */
+ urb_enqueue: ohci_urb_enqueue,
+ urb_dequeue: ohci_urb_dequeue,
+ free_config: ohci_free_config,
+
+ /*
+ * scheduling support
+ */
+ get_frame_number: ohci_get_frame,
+
+ /*
+ * root hub support
+ */
+ hub_status_data: ohci_hub_status_data,
+ hub_control: ohci_hub_control,
+};
+
+/*-------------------------------------------------------------------------*/
+
+
+static const struct pci_device_id __devinitdata pci_ids [] = { {
+
+ /* handle any USB OHCI controller */
+ class: (PCI_CLASS_SERIAL_USB << 8) | 0x10,
+ class_mask: ~0,
+ driver_data: (unsigned long) &ohci_pci_hc_driver,
+
+ /* 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, pci_ids);
+
+/* pci driver glue; this is a "new style" PCI driver module */
+static struct pci_driver ohci_pci_driver = {
+ name: (char *) hcd_name,
+ id_table: pci_ids,
+
+ probe: usb_hcd_pci_probe,
+ remove: usb_hcd_pci_remove,
+
+#ifdef CONFIG_PM
+ suspend: usb_hcd_pci_suspend,
+ resume: usb_hcd_pci_resume,
+#endif
+};
+
+
+static int __init ohci_hcd_pci_init (void)
+{
+ dbg (DRIVER_INFO " (PCI)");
+ dbg ("block sizes: ed %d td %d",
+ sizeof (struct ed), sizeof (struct td));
+ return pci_module_init (&ohci_pci_driver);
+}
+module_init (ohci_hcd_pci_init);
+
+/*-------------------------------------------------------------------------*/
+
+static void __exit ohci_hcd_pci_cleanup (void)
+{
+ pci_unregister_driver (&ohci_pci_driver);
+}
+module_exit (ohci_hcd_pci_cleanup);
diff -Nru a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
--- a/drivers/usb/host/ohci-q.c Sat Jun 8 15:45:52 2002
+++ b/drivers/usb/host/ohci-q.c Sat Jun 8 15:45:52 2002
@@ -15,7 +15,6 @@
if (last >= 0) {
int i;
struct td *td = urb_priv->td [0];
-#ifdef CONFIG_PCI
int len = td->urb->transfer_buffer_length;
int dir = usb_pipeout (td->urb->pipe)
? PCI_DMA_TODEVICE
@@ -36,10 +35,6 @@
if (len && td->data_dma)
pci_unmap_single (hc->hcd.pdev,
td->data_dma, len, dir);
-#else
-# warning "assuming no buffer unmapping is needed"
-#endif
-
for (i = 0; i <= last; i++) {
td = urb_priv->td [i];
if (td)
@@ -90,7 +85,6 @@
urb_priv_t *urb_priv = urb->hcpriv;
unsigned long flags;
-#ifdef CONFIG_PCI
// FIXME rewrite this resubmit path. use pci_dma_sync_single()
// and requeue more cheaply, and only if needed.
// Better yet ... abolish the notion of automagic resubmission.
@@ -100,7 +94,6 @@
usb_pipeout (urb->pipe)
? PCI_DMA_TODEVICE
: PCI_DMA_FROMDEVICE);
-#endif
/* FIXME: MP race. If another CPU partially unlinks
* this URB (urb->status was updated, hasn't yet told
* us to dequeue) before we call complete() here, an
@@ -236,11 +229,11 @@
break;
case PIPE_INTERRUPT:
- load = ed->int_load;
- interval = ep_2_n_interval (ed->int_period);
+ load = ed->intriso.intr_info.int_load;
+ interval = ep_2_n_interval (ed->intriso.intr_info.int_period);
ed->interval = interval;
int_branch = ep_int_balance (ohci, interval, load);
- ed->int_branch = int_branch;
+ ed->intriso.intr_info.int_branch = int_branch;
for (i = 0; i < ep_rev (6, interval); i += inter) {
inter = 1;
@@ -355,9 +348,9 @@
break;
case PIPE_INTERRUPT:
- periodic_unlink (ohci, ed, ed->int_branch, ed->interval);
- for (i = ed->int_branch; i < NUM_INTS; i += ed->interval)
- ohci->ohci_int_load [i] -= ed->int_load;
+ periodic_unlink (ohci, ed, ed->intriso.intr_info.int_branch,
+ed->interval);
+ for (i = ed->intriso.intr_info.int_branch; i < NUM_INTS; i +=
+ed->interval)
+ ohci->ohci_int_load [i] -= ed->intriso.intr_info.int_load;
#ifdef OHCI_VERBOSE_DEBUG
ohci_dump_periodic (ohci, "UNLINK_INT");
#endif
@@ -466,8 +459,8 @@
<< 16);
if (ed->type == PIPE_INTERRUPT && ed->state == ED_UNLINK) {
- ed->int_period = interval;
- ed->int_load = load;
+ ed->intriso.intr_info.int_period = interval;
+ ed->intriso.intr_info.int_load = load;
}
spin_unlock_irqrestore (&ohci->lock, flags);
@@ -563,7 +556,7 @@
td->hwINFO = cpu_to_le32 (info);
if ((td->ed->type) == PIPE_ISOCHRONOUS) {
td->hwCBP = cpu_to_le32 (data & 0xFFFFF000);
- td->ed->last_iso = info & 0xffff;
+ td->ed->intriso.last_iso = info & 0xffff;
} else {
td->hwCBP = cpu_to_le32 (data);
}
@@ -610,16 +603,11 @@
urb_priv->td_cnt = 0;
if (data_len) {
-#ifdef CONFIG_PCI
data = pci_map_single (ohci->hcd.pdev,
- urb->transfer_buffer, data_len,
- usb_pipeout (urb->pipe)
- ? PCI_DMA_TODEVICE
- : PCI_DMA_FROMDEVICE
- );
-#else
-# error "what dma addr to use"
-#endif
+ urb->transfer_buffer, data_len,
+ usb_pipeout (urb->pipe)
+ ? PCI_DMA_TODEVICE
+ : PCI_DMA_FROMDEVICE);
} else
data = 0;
@@ -667,14 +655,10 @@
/* control requests don't use toggle state */
info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
td_fill (ohci, info,
-#ifdef CONFIG_PCI
pci_map_single (ohci->hcd.pdev,
- urb->setup_packet, 8,
- PCI_DMA_TODEVICE),
-#else
-# error "what dma addr to use"
-#endif
- 8, urb, cnt++);
+ urb->setup_packet, 8,
+ PCI_DMA_TODEVICE),
+ 8, urb, cnt++);
if (data_len > 0) {
info = TD_CC | TD_R | TD_T_DATA1;
info |= usb_pipeout (urb->pipe)
diff -Nru a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/host/ohci-sa1111.c Sat Jun 8 15:45:52 2002
@@ -0,0 +1,358 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * (C) Copyright 1999 Roman Weissgaerber <[EMAIL PROTECTED]>
+ * (C) Copyright 2000-2002 David Brownell <[EMAIL PROTECTED]>
+ * (C) Hewlett-Packard Company
+ *
+ * SA1111 Bus Glue
+ *
+ * Written by Christopher Hoover <[EMAIL PROTECTED]>
+ * Based on fragments of previous driver by Rusell King et al.
+ *
+ * This file is licenced under the GPL.
+ */
+
+#include <asm/hardware.h>
+#include <asm/arch/assabet.h>
+#include <asm/arch/badge4.h>
+#include <asm/hardware/sa1111.h>
+
+#ifndef CONFIG_SA1111
+#error "This file is SA-1111 bus glue. CONFIG_SA1111 must be defined."
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static void sa1111_start_hc(void)
+{
+ unsigned int usb_rst = 0;
+
+ printk(KERN_DEBUG __FILE__
+ ": starting SA-1111 OHCI USB Controller\n");
+
+#ifdef CONFIG_SA1100_BADGE4
+ if (machine_is_badge4()) {
+ badge4_set_5V(BADGE4_5V_USB, 1);
+ }
+#endif
+
+ 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 void sa1111_stop_hc(void)
+{
+ printk(KERN_DEBUG __FILE__
+ ": stopping SA-1111 OHCI USB Controller\n");
+
+ /*
+ * Put the USB host controller into reset.
+ */
+ USB_RESET |= USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET;
+
+ /*
+ * Stop the USB clock.
+ */
+ SKPCR &= ~SKPCR_UCLKEN;
+
+#ifdef CONFIG_SA1100_BADGE4
+ if (machine_is_badge4()) {
+ /* Disable power to the USB bus */
+ badge4_set_5V(BADGE4_5V_USB, 0);
+ }
+#endif
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+#if 0
+static void dump_hci_status(const char *label)
+{
+ unsigned long status = USB_STATUS;
+
+ dbg ("%s USB_STATUS = { %s%s%s%s%s}", label,
+ ((status & USB_STATUS_IRQHCIRMTWKUP) ? "IRQHCIRMTWKUP " : ""),
+ ((status & USB_STATUS_IRQHCIBUFFACC) ? "IRQHCIBUFFACC " : ""),
+ ((status & USB_STATUS_NIRQHCIM) ? "" : "IRQHCIM "),
+ ((status & USB_STATUS_NHCIMFCLR) ? "" : "HCIMFCLR "),
+ ((status & USB_STATUS_USBPWRSENSE) ? "USBPWRSENSE " : ""));
+}
+#endif
+
+static void usb_hcd_sa1111_hcim_irq (int irq, void *__hcd, struct pt_regs * r)
+{
+ //dump_hci_status("irq");
+
+#if 0
+ /* may work better this way -- need to investigate further */
+ if (USB_STATUS & USB_STATUS_NIRQHCIM) {
+ //dbg ("not normal HC interrupt; ignoring");
+ return;
+ }
+#endif
+
+ usb_hcd_irq(irq, __hcd, r);
+}
+
+/*-------------------------------------------------------------------------*/
+
+void usb_hcd_sa1111_remove (struct usb_hcd *);
+
+/* configure so an HC device and id are always provided */
+/* always called with process context; sleeping is OK */
+
+
+/**
+ * usb_hcd_sa1111_probe - initialize SA-1111-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.
+ *
+ * Store this function in the HCD's struct pci_driver as probe().
+ */
+int usb_hcd_sa1111_probe (const struct hc_driver *driver, struct usb_hcd **hcd_out)
+{
+ int retval;
+ struct usb_hcd *hcd = 0;
+
+ if (!sa1111)
+ return -ENODEV;
+
+ if (!request_mem_region(_USB_OHCI_OP_BASE,
+ _USB_EXTENT, hcd_name)) {
+ dbg("request_mem_region failed");
+ return -EBUSY;
+ }
+
+ sa1111_start_hc();
+
+ hcd = driver->hcd_alloc ();
+ if (hcd == NULL){
+ dbg ("hcd_alloc failed");
+ retval = -ENOMEM;
+ goto err1;
+ }
+
+ hcd->driver = (struct hc_driver *) driver;
+ hcd->description = driver->description;
+ hcd->irq = NIRQHCIM;
+ hcd->regs = (void *) &USB_OHCI_OP_BASE;
+ hcd->pdev = SA1111_FAKE_PCIDEV;
+
+ set_irq_type(NIRQHCIM, IRQT_RISING);
+ retval = request_irq (NIRQHCIM, usb_hcd_sa1111_hcim_irq, SA_INTERRUPT,
+ hcd->description, hcd);
+ if (retval != 0) {
+ dbg("request_irq failed");
+ retval = -EBUSY;
+ goto err2;
+ }
+
+ info ("%s (SA-1111) at 0x%p, irq %d\n",
+ hcd->description, hcd->regs, hcd->irq);
+
+ usb_bus_init (&hcd->self);
+ hcd->self.op = &usb_hcd_operations;
+ hcd->self.hcpriv = (void *) hcd;
+ hcd->self.bus_name = "SA-1111";
+ hcd->product_desc = "SA-1111 OHCI";
+
+ INIT_LIST_HEAD (&hcd->dev_list);
+
+ usb_register_bus (&hcd->self);
+
+ if ((retval = driver->start (hcd)) < 0)
+ {
+ usb_hcd_sa1111_remove(hcd);
+ return retval;
+ }
+
+ *hcd_out = hcd;
+ return 0;
+
+ err2:
+ if (hcd) driver->hcd_free(hcd);
+ err1:
+ sa1111_stop_hc();
+ release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
+ return retval;
+}
+
+
+/* may be called without controller electrically present */
+/* may be called with controller, bus, and devices active */
+
+/**
+ * usb_hcd_sa1111_remove - shutdown processing for SA-1111-based HCDs
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_hcd_sa1111_probe(), first invoking
+ * the HCD's stop() method. It is always called from a thread
+ * context, normally "rmmod", "apmd", or something similar.
+ *
+ */
+void usb_hcd_sa1111_remove (struct usb_hcd *hcd)
+{
+ struct usb_device *hub;
+ void *base;
+
+ info ("remove: %s, state %x", hcd->self.bus_name, hcd->state);
+
+ if (in_interrupt ()) BUG ();
+
+ hub = hcd->self.root_hub;
+ hcd->state = USB_STATE_QUIESCING;
+
+ dbg ("%s: roothub graceful disconnect", hcd->self.bus_name);
+ usb_disconnect (&hub);
+
+ hcd->driver->stop (hcd);
+ hcd->state = USB_STATE_HALT;
+
+ free_irq (hcd->irq, hcd);
+
+ usb_deregister_bus (&hcd->self);
+ if (atomic_read (&hcd->self.refcnt) != 1)
+ err (__FUNCTION__ ": %s, count != 1", hcd->self.bus_name);
+
+ base = hcd->regs;
+ hcd->driver->hcd_free (hcd);
+
+ sa1111_stop_hc();
+ release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int __devinit
+ohci_sa1111_start (struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci (hcd);
+ int ret;
+
+ if (hcd->pdev) {
+ ohci->hcca = pci_alloc_consistent (hcd->pdev,
+ sizeof *ohci->hcca, &ohci->hcca_dma);
+ if (!ohci->hcca)
+ return -ENOMEM;
+ }
+
+ memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
+ if ((ret = ohci_mem_init (ohci)) < 0) {
+ ohci_stop (hcd);
+ return ret;
+ }
+ ohci->regs = hcd->regs;
+
+ ohci->parent_dev = &sa1111->dev;
+
+ if (hc_reset (ohci) < 0) {
+ ohci_stop (hcd);
+ return -ENODEV;
+ }
+
+ if (hc_start (ohci) < 0) {
+ err ("can't start %s", ohci->hcd.self.bus_name);
+ ohci_stop (hcd);
+ return -EBUSY;
+ }
+
+#ifdef DEBUG
+ ohci_dump (ohci, 1);
+#endif
+ return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static const struct hc_driver ohci_sa1111_hc_driver = {
+ description: hcd_name,
+
+ /*
+ * generic hardware linkage
+ */
+ irq: ohci_irq,
+ flags: HCD_USB11,
+
+ /*
+ * basic lifecycle operations
+ */
+ start: ohci_sa1111_start,
+#ifdef CONFIG_PM
+ /* suspend: ohci_sa1111_suspend, -- tbd */
+ /* resume: ohci_sa1111_resume, -- tbd */
+#endif
+ stop: ohci_stop,
+
+ /*
+ * memory lifecycle (except per-request)
+ */
+ hcd_alloc: ohci_hcd_alloc,
+ hcd_free: ohci_hcd_free,
+
+ /*
+ * managing i/o requests and associated device resources
+ */
+ urb_enqueue: ohci_urb_enqueue,
+ urb_dequeue: ohci_urb_dequeue,
+ free_config: ohci_free_config,
+
+ /*
+ * scheduling support
+ */
+ get_frame_number: ohci_get_frame,
+
+ /*
+ * root hub support
+ */
+ hub_status_data: ohci_hub_status_data,
+ hub_control: ohci_hub_control,
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* Only one SA-1111 ever exists. */
+static struct usb_hcd *the_sa1111_hcd;
+
+static int __init ohci_hcd_sa1111_init (void)
+{
+ dbg (DRIVER_INFO " (SA-1111)");
+ dbg ("block sizes: ed %d td %d",
+ sizeof (struct ed), sizeof (struct td));
+
+ the_sa1111_hcd = 0;
+ return usb_hcd_sa1111_probe(&ohci_sa1111_hc_driver, &the_sa1111_hcd);
+}
+module_init (ohci_hcd_sa1111_init);
+
+
+static void __exit ohci_hcd_sa1111_cleanup (void)
+{
+ if (the_sa1111_hcd) {
+ usb_hcd_sa1111_remove(the_sa1111_hcd);
+ the_sa1111_hcd = 0;
+ }
+}
+module_exit (ohci_hcd_sa1111_cleanup);
diff -Nru a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
--- a/drivers/usb/host/ohci.h Sat Jun 8 15:45:52 2002
+++ b/drivers/usb/host/ohci.h Sat Jun 8 15:45:52 2002
@@ -37,9 +37,9 @@
u8 int_period;
u8 int_branch;
u8 int_load;
- };
+ } intr_info;
u16 last_iso; /* isochronous */
- };
+ } intriso;
u8 state; /* ED_{NEW,UNLINK,OPER} */
#define ED_NEW 0x00 /* unused, no dummy td */
@@ -331,6 +331,11 @@
struct ohci_hcd {
spinlock_t lock;
+ /*
+ * parent device
+ */
+ struct device *parent_dev;
+
/*
* I/O memory used to communicate with the HC (uncached);
*/
@@ -348,12 +353,10 @@
struct ed *ed_controltail; /* last in ctrl list */
struct ed *ed_isotail; /* last in iso list */
-#ifdef CONFIG_PCI
struct pci_pool *td_cache;
struct pci_pool *ed_cache;
struct hash_list_t td_hash [TD_HASH_SIZE];
struct hash_list_t ed_hash [ED_HASH_SIZE];
-#endif
/*
* driver state
diff -Nru a/drivers/usb/host/usb-ohci-pci.c b/drivers/usb/host/usb-ohci-pci.c
--- a/drivers/usb/host/usb-ohci-pci.c Sat Jun 8 15:45:52 2002
+++ b/drivers/usb/host/usb-ohci-pci.c Sat Jun 8 15:45:52 2002
@@ -21,6 +21,12 @@
#endif
#endif
+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);
+extern int hc_start (ohci_t * ohci, struct device *parent_dev);
+extern int hc_reset (ohci_t * ohci);
/*-------------------------------------------------------------------------*/
@@ -103,7 +109,8 @@
ohci->ed_controltail = NULL;
ohci->ed_bulktail = NULL;
- if ((temp = hc_reset (ohci)) < 0 || (temp = hc_start (ohci)) < 0) {
+ if ((temp = hc_reset (ohci)) < 0 ||
+ (temp = hc_start (ohci, &ohci->ohci_dev->dev)) < 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);
@@ -171,6 +178,7 @@
ohci_pci_remove (struct pci_dev *dev)
{
ohci_t *ohci = (ohci_t *) pci_get_drvdata(dev);
+ void *membase = ohci->regs;
dbg ("remove %s controller usb-%s%s%s",
hcfs2string (ohci->hc_control & OHCI_CTRL_HCFS),
@@ -181,6 +189,9 @@
hc_remove_ohci(ohci);
+ /* unmap the IO address space */
+ iounmap (membase);
+
release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
}
diff -Nru a/drivers/usb/host/usb-ohci-sa1111.c b/drivers/usb/host/usb-ohci-sa1111.c
--- a/drivers/usb/host/usb-ohci-sa1111.c Sat Jun 8 15:45:52 2002
+++ b/drivers/usb/host/usb-ohci-sa1111.c Sat Jun 8 15:45:52 2002
@@ -12,6 +12,7 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/usb.h>
+#include <linux/pci.h>
#include <linux/errno.h>
#include <asm/hardware.h>
@@ -27,6 +28,9 @@
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);
+extern int hc_start (ohci_t * ohci, struct device *parent_dev);
+extern int hc_reset (ohci_t * ohci);
+
static ohci_t *sa1111_ohci;
@@ -34,6 +38,15 @@
{
unsigned int usb_rst = 0;
+ printk(KERN_DEBUG __FILE__
+ ": starting SA-1111 OHCI USB Controller\n");
+
+#ifdef CONFIG_SA1100_BADGE4
+ if (machine_is_badge4())
+ /* power the bus */
+ badge4_set_5V(BADGE4_5V_USB, 1);
+#endif
+
if (machine_is_xp860() ||
machine_has_neponset() ||
machine_is_pfs168() ||
@@ -55,6 +68,28 @@
USB_RESET = usb_rst;
}
+static void __exit sa1111_ohci_unconfigure(void)
+{
+ printk(KERN_DEBUG __FILE__
+ ": stopping SA-1111 OHCI USB Controller\n");
+
+ /*
+ * Put the USB host controller into reset.
+ */
+ USB_RESET |= USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET;
+
+ /*
+ * Stop the USB clock.
+ */
+ SKPCR &= ~SKPCR_UCLKEN;
+
+#ifdef CONFIG_SA1100_BADGE4
+ if (machine_is_badge4())
+ badge4_set_5V(BADGE4_5V_USB, 0);
+#endif
+}
+
+
static int __init sa1111_ohci_init(void)
{
int ret;
@@ -65,66 +100,54 @@
/*
* Request memory resources.
*/
-// if (!request_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT, "usb-ohci"))
-// return -EBUSY;
+ 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,
+ sa1111_ohci = 0;
+ ret = hc_add_ohci(SA1111_FAKE_PCIDEV, 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;
- }
+ if (ret || !sa1111_ohci) {
+ sa1111_ohci = 0;
+ sa1111_ohci_unconfigure();
+ release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
+ 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
+ if (hc_start (sa1111_ohci, &sa1111->dev) < 0) {
+ err ("can't start usb-%s", sa1111_ohci->slot_name);
+ hc_remove_ohci (sa1111_ohci);
+ sa1111_ohci = 0;
+ sa1111_ohci_unconfigure();
+ release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
+ return -EBUSY;
}
-// else
-// release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
- return ret;
+ return 0;
}
static void __exit sa1111_ohci_exit(void)
{
- hc_remove_ohci(sa1111_ohci);
+ printk(KERN_DEBUG __FUNCTION__ ": cleaning up\n");
- /*
- * Put the USB host controller into reset.
- */
- USB_RESET |= USB_RESET_FORCEIFRESET | USB_RESET_FORCEHCRESET;
-
- /*
- * Stop the USB clock.
- */
- SKPCR &= ~SKPCR_UCLKEN;
+ if (sa1111_ohci) {
+ hc_remove_ohci(sa1111_ohci);
+ sa1111_ohci = 0;
+ }
- /*
- * Release memory resources.
- */
-// release_mem_region(_USB_OHCI_OP_BASE, _USB_EXTENT);
+ sa1111_ohci_unconfigure();
+ 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
+ printk(KERN_DEBUG __FUNCTION__ ": exiting\n");
}
module_init(sa1111_ohci_init);
module_exit(sa1111_ohci_exit);
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/usb/host/usb-ohci.c b/drivers/usb/host/usb-ohci.c
--- a/drivers/usb/host/usb-ohci.c Sat Jun 8 15:45:52 2002
+++ b/drivers/usb/host/usb-ohci.c Sat Jun 8 15:45:52 2002
@@ -66,7 +66,12 @@
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h> /* for in_interrupt() */
-#undef DEBUG
+
+#ifdef CONFIG_USB_DEBUG
+# define DEBUG
+#else
+# undef DEBUG
+#endif
#include <linux/usb.h>
#include <asm/io.h>
@@ -2391,7 +2396,11 @@
return NULL;
}
ohci->bus->hcpriv = (void *) ohci;
+#ifdef CONFIG_PCI
ohci->bus->bus_name = dev->slot_name;
+#else
+ ohci->bus->bus_name = "ohci-hc";
+#endif
return ohci;
}
@@ -2430,9 +2439,6 @@
ohci_mem_cleanup (ohci);
- /* unmap the IO address space */
- iounmap (ohci->regs);
-
pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca,
ohci->hcca, ohci->hcca_dma);
kfree (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?source=osdntextlink
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel