summaryrefslogtreecommitdiffstats
path: root/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c
diff options
context:
space:
mode:
Diffstat (limited to 'uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c')
-rw-r--r--uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c499
1 files changed, 499 insertions, 0 deletions
diff --git a/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c b/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c
index b7c89c1..fc8911f 100644
--- a/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c
+++ b/uClinux-2.4.20-uc1/drivers/usb/usb-ohci.c
@@ -53,7 +53,9 @@
#include <linux/config.h>
#include <linux/module.h>
+#ifndef CONFIG_BOARD_W90N745
#include <linux/pci.h>
+#endif
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ioport.h>
@@ -78,12 +80,16 @@
#include "usb-ohci.h"
+#ifndef CONFIG_BOARD_W90N745
#include "hcd.h"
+#endif
#ifdef CONFIG_PMAC_PBOOK
#include <asm/machdep.h>
#include <asm/pmac_feature.h>
+#ifndef CONFIG_BOARD_W90N745
#include <asm/pci-bridge.h>
+#endif
#ifndef CONFIG_PM
#define CONFIG_PM
#endif
@@ -129,7 +135,253 @@ static inline u32 roothub_status (struct ohci *hc)
static u32 roothub_portstatus (struct ohci *hc, int i)
{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }
+#ifdef CONFIG_BOARD_W90N745
+
+
+extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb,
+ int bustime, int isoc);
+extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb,
+ int isoc);
+extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb);
+
+ /*pool support functions*/
+struct ohci_pool *
+ohci_pool_create (const char *name,
+ size_t size, size_t align, size_t allocation, int flags)
+{
+ struct ohci_pool *retval;
+
+ if (align == 0)
+ align = 1;
+ if (size == 0)
+ return 0;
+ else if (size < align)
+ size = align;
+ else if ((size % align) != 0) {
+ size += align + 1;
+ size &= ~(align - 1);
+ }
+
+ if (allocation == 0) {
+ if (PAGE_SIZE < size)
+ allocation = size;
+ else
+ allocation = PAGE_SIZE;
+ // FIXME: round up for less fragmentation
+ } else if (allocation < size)
+ return 0;
+
+ if (!(retval = kmalloc (sizeof *retval, flags)))
+ return retval;
+
+#ifdef CONFIG_PCIPOOL_DEBUG
+ flags |= SLAB_POISON;
+#endif
+
+ strncpy (retval->name, name, sizeof retval->name);
+ retval->name [sizeof retval->name - 1] = 0;
+
+ INIT_LIST_HEAD (&retval->page_list);
+ spin_lock_init (&retval->lock);
+ retval->size = size;
+ retval->flags = flags;
+ retval->allocation = allocation;
+ retval->blocks_per_page = allocation / size;
+ init_waitqueue_head (&retval->waitq);
+
+#ifdef CONFIG_PCIPOOL_DEBUG
+ printk (KERN_DEBUG "pcipool create%s size %d, %d/page (%d alloc)\n",
+ retval->name, size,
+ retval->blocks_per_page, allocation);
+#endif
+
+ return retval;
+}
+
+void *
+ohci_pool_alloc (struct ohci_pool *pool, int mem_flags, dma_addr_t *handle)
+{
+ unsigned long flags;
+ struct list_head *entry;
+ struct pci_page *page;
+ int map, block;
+ size_t offset;
+ void *retval;
+
+restart:
+ spin_lock_irqsave (&pool->lock, flags);
+ list_for_each (entry, &pool->page_list) {
+ int i;
+ page = list_entry (entry, struct pci_page, page_list);
+ /* only cachable accesses here ... */
+ for (map = 0, i = 0;
+ i < pool->blocks_per_page;
+ i += BITS_PER_LONG, map++) {
+ if (page->bitmap[map] == 0)
+ continue;
+ block = ffz (~ page->bitmap [map]);
+ if ((i + block) < pool->blocks_per_page) {
+ clear_bit (block, &page->bitmap [map]);
+ offset = (BITS_PER_LONG * map) + block;
+ offset *= pool->size;
+ goto ready;
+ }
+ }
+ }
+ if (!(page = pool_alloc_page (pool, mem_flags))) {
+ if (mem_flags == SLAB_KERNEL) {
+ DECLARE_WAITQUEUE (wait, current);
+
+ current->state = TASK_INTERRUPTIBLE;
+ add_wait_queue (&pool->waitq, &wait);
+ spin_unlock_irqrestore (&pool->lock, flags);
+
+ schedule_timeout (POOL_TIMEOUT_JIFFIES);
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue (&pool->waitq, &wait);
+ goto restart;
+ }
+ retval = 0;
+ goto done;
+ }
+
+ clear_bit (0, &page->bitmap [0]);
+ offset = 0;
+ready:
+ retval = offset + page->vaddr;
+ *handle = offset + page->dma;
+done:
+ spin_unlock_irqrestore (&pool->lock, flags);
+ return retval;
+}
+
+void
+ohci_pool_free (struct ohci_pool *pool, void *vaddr, dma_addr_t dma)
+{
+ struct pci_page *page;
+ unsigned long flags;
+ int map, block;
+
+ if ((page = pool_find_page (pool, dma)) == 0) {
+ printk (KERN_ERR "pci_pool_free %s, %p/%x (bad dma)\n",
+ pool->name, vaddr, (int) (dma & 0xffffffff));
+ return;
+ }
+
+ block = dma - page->dma;
+ block /= pool->size;
+ map = block / BITS_PER_LONG;
+ block %= BITS_PER_LONG;
+
+ if (pool->flags & SLAB_POISON)
+ memset (vaddr, POOL_POISON_BYTE, pool->size);
+
+ spin_lock_irqsave (&pool->lock, flags);
+ set_bit (block, &page->bitmap [map]);
+ if (waitqueue_active (&pool->waitq))
+ wake_up (&pool->waitq);
+ /*
+ * Resist a temptation to do
+ * if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page);
+ * it is not interrupt safe. Better have empty pages hang around.
+ */
+ spin_unlock_irqrestore (&pool->lock, flags);
+}
+
+static struct pci_page *
+pool_find_page (struct ohci_pool *pool, dma_addr_t dma)
+{
+ unsigned long flags;
+ struct list_head *entry;
+ struct pci_page *page;
+
+ spin_lock_irqsave (&pool->lock, flags);
+ list_for_each (entry, &pool->page_list) {
+ page = list_entry (entry, struct pci_page, page_list);
+ if (dma < page->dma)
+ continue;
+ if (dma < (page->dma + pool->allocation))
+ goto done;
+ }
+ page = 0;
+done:
+ spin_unlock_irqrestore (&pool->lock, flags);
+ return page;
+}
+
+void
+ohci_pool_destroy (struct ohci_pool *pool)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave (&pool->lock, flags);
+ while (!list_empty (&pool->page_list)) {
+ struct pci_page *page;
+ page = list_entry (pool->page_list.next,
+ struct pci_page, page_list);
+ if (is_page_busy (pool->blocks_per_page, page->bitmap)) {
+ /* leak the still-in-use consistent memory */
+ list_del (&page->page_list);
+ kfree ((void*)page);
+ } else
+ pool_free_page (pool, page);
+ }
+ spin_unlock_irqrestore (&pool->lock, flags);
+ kfree ((void*)pool);
+}
+
+static struct pci_page *
+pool_alloc_page (struct ohci_pool *pool, int mem_flags)
+{
+ struct pci_page *page;
+ int mapsize;
+
+ mapsize = pool->blocks_per_page;
+ mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG;
+ mapsize *= sizeof (long);
+
+ page = (struct pci_page *) kmalloc (mapsize + sizeof *page, mem_flags);
+ if (!page)
+ return 0;
+ page->vaddr = ohci_alloc_consistent (pool->allocation,
+ &page->dma);
+ if (page->vaddr) {
+ memset (page->bitmap, 0xff, mapsize); // bit set == free
+ if (pool->flags & SLAB_POISON)
+ memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+ list_add (&page->page_list, &pool->page_list);
+ } else {
+ kfree ((void*)page);
+ page = 0;
+ }
+ return page;
+}
+
+static void
+pool_free_page (struct ohci_pool *pool, struct pci_page *page)
+{
+ dma_addr_t dma = page->dma;
+
+ if (pool->flags & SLAB_POISON)
+ memset (page->vaddr, POOL_POISON_BYTE, pool->allocation);
+ ohci_free_consistent (pool->allocation, page->vaddr, dma);
+ list_del (&page->page_list);
+ kfree ((void*)page);
+}
+
+static inline int
+is_page_busy (int blocks, unsigned long *bitmap)
+{
+ while (blocks > 0) {
+ if (*bitmap++ != ~0UL)
+ return 1;
+ blocks -= BITS_PER_LONG;
+ }
+ return 0;
+}
+#endif
/*-------------------------------------------------------------------------*
* URB support functions
*-------------------------------------------------------------------------*/
@@ -157,17 +409,26 @@ static void urb_free_priv (struct ohci *hc, urb_priv_t * urb_priv)
/* unmap CTRL URB setup */
if (usb_pipecontrol (td->urb->pipe)) {
+#ifndef CONFIG_BOARD_W90N745
pci_unmap_single (hc->ohci_dev,
td->data_dma, 8, PCI_DMA_TODEVICE);
+#else
+ ohci_unmap_single(td->data_dma, 8, PCI_DMA_TODEVICE);
+#endif
/* CTRL data buffer starts at td 1 if len > 0 */
if (len && last > 0)
td = urb_priv->td [1];
}
+#ifndef CONFIG_BOARD_W90N745
/* unmap data buffer */
if (len && td->data_dma)
pci_unmap_single (hc->ohci_dev, td->data_dma, len, dir);
+#else
+ if (len && td->data_dma)
+ ohci_unmap_single(td->data_dma, 8, PCI_DMA_TODEVICE);
+#endif
for (i = 0; i <= last; i++) {
td = urb_priv->td [i];
@@ -442,7 +703,9 @@ static void ohci_dump_roothub (ohci_t *controller, int verbose)
static void ohci_dump (ohci_t *controller, int verbose)
{
+#ifndef CONFIG_BOARD_W90N745
dbg ("OHCI controller usb-%s state", controller->ohci_dev->slot_name);
+#endif
// dumps some of the state we know about
ohci_dump_status (controller);
@@ -483,12 +746,20 @@ static int sohci_return_urb (struct ohci *hc, struct urb * urb)
switch (usb_pipetype (urb->pipe)) {
case PIPE_INTERRUPT:
+#ifdef CONFIG_BOARD_W90N745
+ ohci_unmap_single(urb_priv->td [0]->data_dma,
+ urb->transfer_buffer_length,
+ usb_pipeout (urb->pipe)
+ ? PCI_DMA_TODEVICE
+ : PCI_DMA_FROMDEVICE);
+#else
pci_unmap_single (hc->ohci_dev,
urb_priv->td [0]->data_dma,
urb->transfer_buffer_length,
usb_pipeout (urb->pipe)
? PCI_DMA_TODEVICE
: PCI_DMA_FROMDEVICE);
+#endif
urb->complete (urb);
/* implicitly requeued */
@@ -500,12 +771,20 @@ static int sohci_return_urb (struct ohci *hc, struct urb * urb)
case PIPE_ISOCHRONOUS:
for (urbt = urb->next; urbt && (urbt != urb); urbt = urbt->next);
if (urbt) { /* send the reply and requeue URB */
+#ifdef CONFIG_BOARD_W90N745
+ ohci_unmap_single(urb_priv->td [0]->data_dma,
+ urb->transfer_buffer_length,
+ usb_pipeout (urb->pipe)
+ ? PCI_DMA_TODEVICE
+ : PCI_DMA_FROMDEVICE);
+#else
pci_unmap_single (hc->ohci_dev,
urb_priv->td [0]->data_dma,
urb->transfer_buffer_length,
usb_pipeout (urb->pipe)
? PCI_DMA_TODEVICE
: PCI_DMA_FROMDEVICE);
+#endif
urb->complete (urb);
spin_lock_irqsave (&usb_ed_lock, flags);
urb->actual_length = 0;
@@ -855,8 +1134,10 @@ static int sohci_free_dev (struct usb_device * usb_dev)
if (ed->state != ED_NEW) {
if (ed->state == ED_OPER) {
/* driver on that interface didn't unlink an urb */
+#ifndef CONFIG_BOARD_W90N745
dbg ("driver usb-%s dev %d ed 0x%x unfreed URB",
ohci->ohci_dev->slot_name, usb_dev->devnum, i);
+#endif
ep_unlink (ohci, ed);
}
ep_rm_ed (usb_dev, ed);
@@ -900,8 +1181,10 @@ static int sohci_free_dev (struct usb_device * usb_dev)
}
} else {
/* likely some interface's driver has a refcount bug */
+#ifndef CONFIG_BOARD_W90N745
err ("bus %s devnum %d deletion in interrupt",
ohci->ohci_dev->slot_name, usb_dev->devnum);
+#endif
BUG ();
}
}
@@ -1369,12 +1652,20 @@ static void td_submit_urb (struct urb * urb)
urb_priv->td_cnt = 0;
if (data_len) {
+#ifdef CONFIG_BOARD_W90N745
+ data = ohci_map_single(urb->transfer_buffer, data_len,
+ usb_pipeout (urb->pipe)
+ ? PCI_DMA_TODEVICE
+ : PCI_DMA_FROMDEVICE
+ );
+#else
data = pci_map_single (ohci->ohci_dev,
urb->transfer_buffer, data_len,
usb_pipeout (urb->pipe)
? PCI_DMA_TODEVICE
: PCI_DMA_FROMDEVICE
);
+#endif
} else
data = 0;
@@ -1417,11 +1708,18 @@ static void td_submit_urb (struct urb * urb)
case PIPE_CONTROL:
info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
+#ifdef CONFIG_BOARD_W90N745
+ td_fill (ohci, info,
+ ohci_map_single(urb->setup_packet, 8,
+ PCI_DMA_TODEVICE),
+ 8, urb, cnt++);
+#else
td_fill (ohci, info,
pci_map_single (ohci->ohci_dev,
urb->setup_packet, 8,
PCI_DMA_TODEVICE),
8, urb, cnt++);
+#endif
if (data_len > 0) {
info = usb_pipeout (urb->pipe)?
TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1 : TD_CC | TD_R | TD_DP_IN | TD_T_DATA1;
@@ -1814,8 +2112,10 @@ static int rh_send_irq (ohci_t * ohci, void * rh_data, int rh_len)
num_ports = roothub_a (ohci) & RH_A_NDP;
if (num_ports > MAX_ROOT_PORTS) {
+#ifndef CONFIG_BOARD_W90N745
err ("bogus NDP=%d for OHCI usb-%s", num_ports,
ohci->ohci_dev->slot_name);
+#endif
err ("rereads as NDP=%d",
readl (&ohci->regs->roothub.a) & RH_A_NDP);
/* retry later; "should not happen" */
@@ -2162,9 +2462,11 @@ static int hc_reset (ohci_t * ohci)
/* Disable HC interrupts */
writel (OHCI_INTR_MIE, &ohci->regs->intrdisable);
+#ifndef CONFIG_BOARD_W90N745
dbg("USB HC reset_hc usb-%s: ctrl = 0x%x ;",
ohci->ohci_dev->slot_name,
readl (&ohci->regs->control));
+#endif
/* Reset USB (needed by some controllers) */
writel (0, &ohci->regs->control);
@@ -2309,7 +2611,9 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r)
/* cardbus/... hardware gone before remove() */
} else if ((ints = readl (&regs->intrstatus)) == ~(u32)0) {
ohci->disabled++;
+#ifndef CONFIG_BOARD_W90N745
err ("%s device removed!", ohci->ohci_dev->slot_name);
+#endif
return;
/* interrupt for some other device? */
@@ -2321,8 +2625,10 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r)
if (ints & OHCI_INTR_UE) {
ohci->disabled++;
+#ifndef CONFIG_BOARD_W90N745
err ("OHCI Unrecoverable Error, controller usb-%s disabled",
ohci->ohci_dev->slot_name);
+#endif
// e.g. due to PCI Master/Target Abort
#ifdef DEBUG
@@ -2371,10 +2677,43 @@ static void hc_interrupt (int irq, void * __ohci, struct pt_regs * r)
writel (OHCI_INTR_MIE, &regs->intrenable);
}
+/*-------------alloc consistent not for pci-------------------------------------------*/
+#ifdef CONFIG_BOARD_W90N745
+void *ohci_alloc_consistent(size_t size, dma_addr_t *handle)
+{
+ void *__ret;
+ int __gfp = GFP_KERNEL;
+
+ __ret = (void*)((unsigned long)consistent_alloc(__gfp, (size), (handle))|0x80000000);
+ return __ret;
+}
+
+void ohci_free_consistent(size_t size, void *vaddr,
+ dma_addr_t dma_handle)
+{
+ consistent_free(vaddr, size, dma_handle);
+}
+
+inline dma_addr_t
+ohci_map_single(void *ptr, size_t size, int direction)
+{
+ consistent_sync(ptr, size, direction);
+ return virt_to_bus(ptr);
+}
+
+inline void
+ohci_unmap_single(dma_addr_t dma_addr, size_t size, int direction)
+{
+ /* nothing to do */
+}
+#endif
+
+
/*-------------------------------------------------------------------------*/
/* allocate OHCI */
+#ifndef CONFIG_BOARD_W90N745
static ohci_t * __devinit hc_alloc_ohci (struct pci_dev *dev, void * mem_base)
{
ohci_t * ohci;
@@ -2419,7 +2758,51 @@ static ohci_t * __devinit hc_alloc_ohci (struct pci_dev *dev, void * mem_base)
return ohci;
}
+#else
+static ohci_t * __devinit hc_alloc_ohci (void * mem_base)
+{
+ ohci_t * ohci;
+
+ ohci = (ohci_t *)kmalloc (sizeof *ohci, GFP_KERNEL);
+ if (!ohci)
+ return NULL;
+
+ memset (ohci, 0, sizeof (ohci_t));
+
+ ohci->hcca = ohci_alloc_consistent(sizeof *ohci->hcca,
+ &ohci->hcca_dma);
+
+ if (!ohci->hcca) {
+ kfree (ohci);
+ return NULL;
+ }
+
+ memset (ohci->hcca, 0, sizeof (struct ohci_hcca));
+
+ ohci->disabled = 1;
+ ohci->sleeping = 0;
+ ohci->irq = -1;
+ ohci->regs = mem_base;
+
+ INIT_LIST_HEAD (&ohci->ohci_hcd_list);
+ list_add (&ohci->ohci_hcd_list, &ohci_hcd_list);
+
+ INIT_LIST_HEAD (&ohci->timeout_list);
+
+ ohci->bus = usb_alloc_bus (&sohci_device_operations);
+
+
+ if (!ohci->bus) {
+ ohci_free_consistent (sizeof *ohci->hcca,
+ ohci->hcca, ohci->hcca_dma);
+ kfree (ohci);
+ return NULL;
+ }
+ ohci->bus->hcpriv = (void *) ohci;
+ return ohci;
+}
+#endif
/*-------------------------------------------------------------------------*/
@@ -2427,7 +2810,9 @@ static ohci_t * __devinit hc_alloc_ohci (struct pci_dev *dev, void * mem_base)
static void hc_release_ohci (ohci_t * ohci)
{
+#ifndef CONFIG_BOARD_W90N745
dbg ("USB HC release ohci usb-%s", ohci->ohci_dev->slot_name);
+#endif
/* disconnect all devices */
if (ohci->bus->root_hub)
@@ -2440,7 +2825,9 @@ static void hc_release_ohci (ohci_t * ohci)
free_irq (ohci->irq, ohci);
ohci->irq = -1;
}
+#ifndef CONFIG_BOARD_W90N745
pci_set_drvdata(ohci->ohci_dev, NULL);
+#endif
if (ohci->bus) {
if (ohci->bus->busnum != -1)
usb_deregister_bus (ohci->bus);
@@ -2456,8 +2843,13 @@ static void hc_release_ohci (ohci_t * ohci)
/* unmap the IO address space */
iounmap (ohci->regs);
+#ifndef CONFIG_BOARD_W90N745
pci_free_consistent (ohci->ohci_dev, sizeof *ohci->hcca,
ohci->hcca, ohci->hcca_dma);
+#else
+ ohci_free_consistent(sizeof*ohci->hcca,
+ ohci->hcca, ohci->hcca_dma);
+#endif
kfree (ohci);
}
@@ -2468,6 +2860,7 @@ static void hc_release_ohci (ohci_t * ohci)
static struct pci_driver ohci_pci_driver;
+#ifndef CONFIG_BOARD_W90N745
static int __devinit
hc_found_ohci (struct pci_dev *dev, int irq,
void *mem_base, const struct pci_device_id *id)
@@ -2542,7 +2935,69 @@ hc_found_ohci (struct pci_dev *dev, int irq,
#endif
return 0;
}
+#else
+static int __devinit
+hc_found_ohci (int irq,
+ void *mem_base, const struct pci_device_id *id)
+{
+ ohci_t * ohci;
+ //u8 latency, limit;
+ char buf[8], *bufp = buf;
+ int ret;
+
+#ifndef __sparc__
+ sprintf(buf, "%d", irq);
+#else
+ bufp = __irq_itoa(irq);
+#endif
+ printk(": USB OHCI at membase 0x%lx, IRQ %s\n",
+ (unsigned long) mem_base, bufp);
+
+ ohci = hc_alloc_ohci (mem_base);
+ if (!ohci) {
+ return -ENOMEM;
+ }
+ printk("hc_alloc_ohci\n");
+ if ((ret = ohci_mem_init (ohci)) < 0) {
+ hc_release_ohci (ohci);
+ return ret;
+ }
+ ohci->flags = id->driver_data;
+ if (ohci->flags & OHCI_QUIRK_AMD756)
+ printk (KERN_INFO __FILE__ ": AMD756 erratum 4 workaround\n");
+
+ printk("hc_reset\n");
+ if (hc_reset (ohci) < 0) {
+ hc_release_ohci (ohci);
+ return -ENODEV;
+ }
+ //printk("writel\n");
+ /* FIXME this is a second HC reset; why?? */
+ writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control);
+ wait_ms (10);
+
+ usb_register_bus (ohci->bus);
+ //CSR_WRITE (AIC_SCR9, 0x41); /* high-level sensitive, priority level 1 */
+ if (request_irq (irq, hc_interrupt, SA_SHIRQ,
+ ohci_pci_driver.name, ohci) != 0) {
+ err ("request interrupt %s failed", bufp);
+ hc_release_ohci (ohci);
+ return -EBUSY;
+ }
+ ohci->irq = irq;
+ //printk("irq:%d\n",ohci->irq);
+ if (hc_start (ohci) < 0) {
+ err ("can't start usb");
+ hc_release_ohci (ohci);
+ return -EBUSY;
+ }
+#ifdef DEBUG
+ ohci_dump (ohci, 1);
+#endif
+ return 0;
+}
+#endif
/*-------------------------------------------------------------------------*/
#ifdef CONFIG_PM
@@ -2589,6 +3044,7 @@ static void hc_restart (ohci_t *ohci)
/* configured so that an OHCI device is always provided */
/* always called with process context; sleeping is OK */
+#ifndef CONFIG_BOARD_W90N745
static int __devinit
ohci_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
@@ -2671,8 +3127,43 @@ ohci_pci_remove (struct pci_dev *dev)
release_mem_region (pci_resource_start (dev, 0), pci_resource_len (dev, 0));
pci_disable_device (dev);
}
+#else
+static int __devinit
+ohci_pci_probe (const struct pci_device_id *id)
+{
+ unsigned long mem_resource, mem_len;
+ void *mem_base;
+ int status;
+
+ mem_resource = USB_HOST;
+ mem_len = 0x5C;
+
+ mem_base = ioremap_nocache (mem_resource, mem_len);
+
+ if (!mem_base) {
+ err("Error mapping OHCI memory");
+ release_mem_region (mem_resource, mem_len);
+ return -EFAULT;
+ }
+ /* controller writes into our memory */
+ /*dev->resource[0].start=mem_resource;
+ dev->resource[0].end=mem_resource + mem_len;
+ dev->irq = 9;*/
+
+ status = hc_found_ohci(INT_USBINT0, mem_base, id);//lsshi 2005-4-20 15:38
+ if (status < 0) {
+ iounmap (mem_base);
+ release_mem_region (mem_resource, mem_len);
+ }
+ return status;
+}
+static void __devexit
+ohci_pci_remove (struct pci_dev *dev)
+{
+}
+#endif
#ifdef CONFIG_PM
/*-------------------------------------------------------------------------*/
@@ -2917,14 +3408,22 @@ static struct pci_driver ohci_pci_driver = {
static int __init ohci_hcd_init (void)
{
+#ifdef CONFIG_BOARD_W90N745
+ printk("add a static ohci host controller device\n");
+ ohci_pci_probe (ohci_pci_ids);
+ return 0;
+#else
return pci_module_init (&ohci_pci_driver);
+#endif
}
/*-------------------------------------------------------------------------*/
static void __exit ohci_hcd_cleanup (void)
{
+#ifndef CONFIG_BOARD_W90N745
pci_unregister_driver (&ohci_pci_driver);
+#endif
}
module_init (ohci_hcd_init);