--- zzzz-none-000/linux-2.4.17/drivers/usb/usb-ohci.c 2001-12-21 17:41:55.000000000 +0000 +++ sangam-fb-322/linux-2.4.17/drivers/usb/usb-ohci.c 2004-11-24 13:23:42.000000000 +0000 @@ -75,15 +75,6 @@ #include "usb-ohci.h" -#ifdef CONFIG_PMAC_PBOOK -#include -#include -#ifndef CONFIG_PM -#define CONFIG_PM -#endif -#endif - - /* * Version Information */ @@ -434,7 +425,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); @@ -848,7 +839,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); @@ -893,7 +884,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 (); } } @@ -1304,7 +1295,7 @@ err("internal OHCI error: TD index > length"); return; } - + /* use this td as the next dummy */ td_pt = urb_priv->td [index]; td_pt->hwNextTD = 0; @@ -1810,7 +1801,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" */ @@ -2138,7 +2129,9 @@ { int timeout = 30; int smm_timeout = 50; /* 0,5 sec */ - + + printk (KERN_INFO "OHCI Revision %lx\n", readl (&ohci->regs->revision)); + if (readl (&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ writel (OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */ dbg("USB HC TakeOver from SMM"); @@ -2155,7 +2148,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) */ @@ -2287,14 +2280,14 @@ ints = OHCI_INTR_WDH; } else if ((ints = (readl (®s->intrstatus) & readl (®s->intrenable))) == 0) { return; - } + } // dbg("Interrupt: %x frame: %x", ints, le16_to_cpu (ohci->hcca->frame_no)); 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 @@ -2369,10 +2362,12 @@ ohci->disabled = 1; ohci->sleeping = 0; ohci->irq = -1; - ohci->regs = mem_base; + ohci->regs = mem_base; // <<<<< CHECKIT! 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); @@ -2398,7 +2393,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) @@ -2411,7 +2406,9 @@ free_irq (ohci->irq, ohci); ohci->irq = -1; } - pci_set_drvdata(ohci->ohci_dev, NULL); +#ifdef CONFIG_PCI + pci_set_drvdata(ohci->ohci_dev, 0); +#endif usb_deregister_bus (ohci->bus); usb_free_bus (ohci->bus); @@ -2431,18 +2428,19 @@ /*-------------------------------------------------------------------------*/ -/* 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. + */ +/* Fixed Bug in argument being passed to hc_add_ohci + * Both ohci_t **ohci and local ohci_t *ohci share the same name + * Modified ohci_t **ohci to ohci_t **ohciptr to fix this. + * Also,stored the allocated ohci structure in ohciptr*/ +int __devinit +hc_add_ohci(struct pci_dev *dev, int irq, void *mem_base, unsigned long flags, + ohci_t **ohciptr, 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__ @@ -2452,34 +2450,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; @@ -2491,16 +2475,26 @@ usb_register_bus (ohci->bus); - if (request_irq (irq, hc_interrupt, SA_SHIRQ, - ohci_pci_driver.name, ohci) != 0) { +#if defined (CONFIG_USB_PSP_HOST11_VLYNQ) + if (request_irq (irq, hc_interrupt, 0, name, ohci) != 0) { + err ("Could not claim interrupt %s", bufp); + hc_release_ohci (ohci); + return -EBUSY; + } else { + printk (KERN_INFO __FILE__ ": IRQ 0x%02x claimed.\n", irq); + } +#else + if (request_irq (irq, hc_interrupt, SA_SHIRQ, name, ohci) != 0) { err ("request interrupt %s failed", bufp); hc_release_ohci (ohci); return -EBUSY; } +#endif + ohci->irq = irq; if (hc_start (ohci) < 0) { - err ("can't start usb-%s", dev->slot_name); + err ("can't start usb-%s", ohci->slot_name); hc_release_ohci (ohci); return -EBUSY; } @@ -2508,106 +2502,16 @@ #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); + *ohciptr = ohci; + return 0; } -#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 __devexit hc_remove_ohci(ohci_t *ohci) { - unsigned long mem_resource, mem_len; - void *mem_base; - - if (pci_enable_device(dev) < 0) - return -ENODEV; - - if (!dev->irq) { - err("found OHCI device with no IRQ assigned. check BIOS settings!"); - 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"); - return -EBUSY; - } - - mem_base = ioremap_nocache (mem_resource, mem_len); - if (!mem_base) { - err("Error mapping OHCI memory"); - return -EFAULT; - } - - /* controller writes into our memory */ - pci_set_master (dev); - - return hc_found_ohci (dev, dev->irq, mem_base, id); -} - -/*-------------------------------------------------------------------------*/ - -/* 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 @@ -2624,269 +2528,13 @@ &ohci->regs->control); hc_release_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 = 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) - feature_set_usb_power (of_node, 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 && _machine == _MACH_Pmac) - feature_set_usb_power (of_node, 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"); + +/* Hack until usb-ohci-pci is made completely independent */ +#if !defined(CONFIG_USB_OHCI_SA1111) && !defined(CONFIG_USB_NON_PCI_OHCI) && !defined(CONFIG_USB_PSP_HOST11) && !defined(CONFIG_USB_PSP_HOST11_MODULE) +#include "usb-ohci-pci.c" +#endif